diff --git a/modules/io/src/mol/CMakeLists.txt b/modules/io/src/mol/CMakeLists.txt index 8d242c3e75422c451d2b9a9b8d13a7b0063a9434..f281e45a35fef883c3720eb30cf6adf7d2f07523 100644 --- a/modules/io/src/mol/CMakeLists.txt +++ b/modules/io/src/mol/CMakeLists.txt @@ -31,7 +31,6 @@ PARENT_SCOPE set(OST_IO_MOL_HEADERS chemdict_parser.hh -star_base.hh star_parser.hh star_writer.hh mmcif_reader.hh diff --git a/modules/io/src/mol/mmcif_writer.cc b/modules/io/src/mol/mmcif_writer.cc index b5e6bb56f75fb31314f264c73179ae019bb1becf..8398f4c0ec26b5378b0f23ab89ded228cf138e52 100644 --- a/modules/io/src/mol/mmcif_writer.cc +++ b/modules/io/src/mol/mmcif_writer.cc @@ -18,10 +18,8 @@ //------------------------------------------------------------------------------ #include <ost/mol/chem_class.hh> - #include <ost/io/mol/mmcif_writer.hh> - namespace { // generates as many chain names as you want (potentially multiple characters) @@ -286,7 +284,7 @@ namespace { String type; }; - inline String chem_class_to_chem_comp_type(char chem_class) { + inline String ChemClassToChemCompType(char chem_class) { String type = ""; switch(chem_class) { case 'P': { @@ -342,7 +340,7 @@ namespace { return type; } - inline String mon_id_to_olc(char chem_class, + inline String MonIDToOLC(char chem_class, const String& mon_id) { // hardcoded table according @@ -527,11 +525,11 @@ namespace { return "(" + mon_id + ")"; } - void Setup_chem_comp_(const ost::mol::ResidueHandleList& res_list, + void SetupChemComp(const ost::mol::ResidueHandleList& res_list, std::map<String, CompInfo>& comp_infos) { for(auto res: res_list) { String res_name = res.GetName(); - String type = chem_class_to_chem_comp_type(res.GetChemClass()); + String type = ChemClassToChemCompType(res.GetChemClass()); auto it = comp_infos.find(res_name); if(it != comp_infos.end()) { // check whether type is consistent @@ -546,9 +544,9 @@ namespace { } } - bool Match_entity_resnum(const ost::mol::ResidueHandleList& res_list, - const ost::io::MMCifWriterEntity& info, - Real beyond_frac = 0.05) { + bool MatchEntityResnum(const ost::mol::ResidueHandleList& res_list, + const ost::io::MMCifWriterEntity& info, + Real beyond_frac = 0.05) { // Checks if res_list matches SEQRES given in info.mon_ids // It may be that res_list defines residues beyond this SEQRES or // has residues that are not yet defined, i.e. the respective mon_id is "-". @@ -583,7 +581,7 @@ namespace { } } - bool Match_entity(const ost::mol::ResidueHandleList& res_list, + bool MatchEntity(const ost::mol::ResidueHandleList& res_list, const ost::io::MMCifWriterEntity& info) { // checks if the residue names in res_list are an exact match // with mon_ids in info @@ -594,7 +592,7 @@ namespace { return mon_ids == info.mon_ids; } - void Add_asym(const String& asym_chain_name, + void AddAsym(const String& asym_chain_name, ost::io::MMCifWriterEntity& info) { // adds asym_chain_name to info under the assumption that mon_ids // exactly match => just add a copy of mon_ids to asym_alns @@ -602,13 +600,13 @@ namespace { info.asym_alns.push_back(info.mon_ids); } - void Add_asym_resnum(const String& asym_chain_name, + void AddAsymResnum(const String& asym_chain_name, const ost::mol::ResidueHandleList& res_list, ost::io::MMCifWriterEntity& info) { if(!info.is_poly) { // no need for SEQRES alignment vodoo - Add_asym(asym_chain_name, info); + AddAsym(asym_chain_name, info); return; } @@ -618,7 +616,7 @@ namespace { for(auto res: res_list) { int num = res.GetNumber().GetNum(); - // assumes that Match_entity_resnum has already been run to check for + // assumes that MatchEntityResnum has already been run to check for // resnum < 1 mon_ids.push_back(res.GetName()); resnums.push_back(num); @@ -647,8 +645,8 @@ namespace { if(info.mon_ids[resnums[i]-1] == "-") { info.mon_ids[resnums[i]-1] = mon_ids[i]; const ost::mol::ResidueHandle& res = res_list[i]; - info.seq_olcs[resnums[i]-1] = mon_id_to_olc(res.GetChemClass(), - mon_ids[i]); + info.seq_olcs[resnums[i]-1] = MonIDToOLC(res.GetChemClass(), + mon_ids[i]); char olc = res.GetOneLetterCode(); if(olc < 'A' || olc > 'Z') { info.seq_can_olcs[resnums[i]-1] = "X"; @@ -663,12 +661,12 @@ namespace { info.asym_alns.push_back(aln_mon_ids); } - int Setup_entity(const String& asym_chain_name, - const String& type, - const String& poly_type, - const ost::mol::ResidueHandleList& res_list, - bool resnum_alignment, - std::vector<ost::io::MMCifWriterEntity>& entity_infos) { + int SetupEntity(const String& asym_chain_name, + const String& type, + const String& poly_type, + const ost::mol::ResidueHandleList& res_list, + bool resnum_alignment, + std::vector<ost::io::MMCifWriterEntity>& entity_infos) { bool is_poly = type == "polymer"; @@ -684,13 +682,13 @@ namespace { if(entity_infos[i].type == type && entity_infos[i].poly_type == poly_type) { if(is_poly && resnum_alignment) { - if(Match_entity_resnum(res_list, entity_infos[i])) { - Add_asym_resnum(asym_chain_name, res_list, entity_infos[i]); + if(MatchEntityResnum(res_list, entity_infos[i])) { + AddAsymResnum(asym_chain_name, res_list, entity_infos[i]); return i; } } else { - if(Match_entity(res_list, entity_infos[i])) { - Add_asym(asym_chain_name, entity_infos[i]); + if(MatchEntity(res_list, entity_infos[i])) { + AddAsym(asym_chain_name, entity_infos[i]); return i; } } @@ -721,8 +719,8 @@ namespace { for(size_t i = 0; i < res_mon_ids.size(); ++i) { mon_ids[resnums[i]-1] = res_mon_ids[i]; const ost::mol::ResidueHandle& res = res_list[i]; - seq[resnums[i]-1] = mon_id_to_olc(res.GetChemClass(), - mon_ids[resnums[i]-1]); + seq[resnums[i]-1] = MonIDToOLC(res.GetChemClass(), + mon_ids[resnums[i]-1]); char olc = res.GetOneLetterCode(); if(olc < 'A' || olc > 'Z') { seq_can[resnums[i]-1] = "X"; @@ -733,7 +731,7 @@ namespace { } else { for(auto res: res_list) { mon_ids.push_back(res.GetName()); - seq.push_back(mon_id_to_olc(res.GetChemClass(), res.GetName())); + seq.push_back(MonIDToOLC(res.GetChemClass(), res.GetName())); char olc = res.GetOneLetterCode(); if(olc < 'A' || olc > 'Z') { seq_can.push_back("X"); @@ -743,7 +741,6 @@ namespace { } } - int entity_idx = entity_infos.size(); entity_infos.push_back(ost::io::MMCifWriterEntity()); entity_infos.back().type = type; @@ -754,18 +751,18 @@ namespace { entity_infos.back().is_poly = is_poly; if(is_poly && resnum_alignment) { - Add_asym_resnum(asym_chain_name, res_list, entity_infos.back()); + AddAsymResnum(asym_chain_name, res_list, entity_infos.back()); } else { - Add_asym(asym_chain_name, entity_infos.back()); + AddAsym(asym_chain_name, entity_infos.back()); } return entity_idx; } - int Setup_entity_(const String& asym_chain_name, - const ost::mol::ResidueHandleList& res_list, - bool resnum_alignment, - std::vector<ost::io::MMCifWriterEntity>& entity_infos) { + int SetupEntity(const String& asym_chain_name, + const ost::mol::ResidueHandleList& res_list, + bool resnum_alignment, + std::vector<ost::io::MMCifWriterEntity>& entity_infos) { String type = GuessEntityType(res_list); bool is_poly = type == "polymer"; @@ -773,15 +770,15 @@ namespace { if(is_poly) { poly_type = GuessEntityPolyType(res_list); } - return Setup_entity(asym_chain_name, type, poly_type, res_list, - resnum_alignment, entity_infos); + return SetupEntity(asym_chain_name, type, poly_type, res_list, + resnum_alignment, entity_infos); } - int Setup_entity_(const String& asym_chain_name, - ost::mol::ChainType chain_type, - const ost::mol::ResidueHandleList& res_list, - bool resnum_alignment, - std::vector<ost::io::MMCifWriterEntity>& entity_infos) { + int SetupEntity(const String& asym_chain_name, + ost::mol::ChainType chain_type, + const ost::mol::ResidueHandleList& res_list, + bool resnum_alignment, + std::vector<ost::io::MMCifWriterEntity>& entity_infos) { // use chain_type info attached to chain to determine // _entity.type and _entity_poly.type String type = GuessEntityType(chain_type); @@ -801,20 +798,20 @@ namespace { throw ost::io::IOException(ss.str()); } } - return Setup_entity(asym_chain_name, type, poly_type, res_list, - resnum_alignment, entity_infos); + return SetupEntity(asym_chain_name, type, poly_type, res_list, + resnum_alignment, entity_infos); } - ost::io::StarLoop* Setup_atom_type_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_atom_type_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_atom_type"); desc.Add("symbol"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_atom_site_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_atom_site_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_atom_site"); desc.Add("group_PDB"); desc.Add("type_symbol"); @@ -833,12 +830,12 @@ namespace { desc.Add("auth_asym_id"); desc.Add("id"); desc.Add("pdbx_PDB_ins_code"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_pdbx_poly_seq_scheme_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_pdbx_poly_seq_scheme_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_pdbx_poly_seq_scheme"); desc.Add("asym_id"); desc.Add("entity_id"); @@ -847,92 +844,92 @@ namespace { desc.Add("pdb_strand_id"); desc.Add("pdb_seq_num"); desc.Add("pdb_ins_code"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_entity_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_entity_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_entity"); desc.Add("id"); desc.Add("type"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_struct_asym_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_struct_asym_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_struct_asym"); desc.Add("id"); desc.Add("entity_id"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_entity_poly_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_entity_poly_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_entity_poly"); desc.Add("entity_id"); desc.Add("type"); desc.Add("pdbx_seq_one_letter_code"); desc.Add("pdbx_seq_one_letter_code_can"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_entity_poly_seq_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_entity_poly_seq_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_entity_poly_seq"); desc.Add("entity_id"); desc.Add("mon_id"); desc.Add("num"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - ost::io::StarLoop* Setup_chem_comp_ptr() { - ost::io::StarLoopDesc desc; + ost::io::StarWriterLoopPtr Setup_chem_comp_ptr() { + ost::io::StarWriterLoopDesc desc; desc.SetCategory("_chem_comp"); desc.Add("id"); desc.Add("type"); - ost::io::StarLoop* sl = new ost::io::StarLoop(desc); + ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc)); return sl; } - void Feed_atom_type_(ost::io::StarLoop* atom_type_ptr, - ost::io::StarLoop* atom_site_ptr) { + void Feed_atom_type(ost::io::StarWriterLoopPtr atom_type_ptr, + ost::io::StarWriterLoopPtr atom_site_ptr) { // we're just extracting every type_symbol that we observed // in atom_site (this is a bit of circular stupidity...) std::set<String> symbols; int desc_size = atom_site_ptr->GetDesc().GetSize(); int type_symbol_idx = atom_site_ptr->GetDesc().GetIndex("type_symbol"); int N = atom_site_ptr->GetN(); - const std::vector<ost::io::StarLoopDataItemDO>& data = atom_site_ptr->GetData(); + const std::vector<ost::io::StarWriterLoopDataItem>& data = atom_site_ptr->GetData(); for(int i = 0; i < N; ++i) { symbols.insert(data[i*desc_size + type_symbol_idx].GetValue()); } - std::vector<ost::io::StarLoopDataItemDO> atom_type_data; - atom_type_data.push_back(ost::io::StarLoopDataItemDO("")); + std::vector<ost::io::StarWriterLoopDataItem> atom_type_data; + atom_type_data.push_back(ost::io::StarWriterLoopDataItem("")); for(auto symbol: symbols) { - atom_type_data[0] = ost::io::StarLoopDataItemDO(symbol); + atom_type_data[0] = ost::io::StarWriterLoopDataItem(symbol); atom_type_ptr->AddData(atom_type_data); } } - void Feed_pdbx_poly_seq_scheme(ost::io::StarLoop* pdbx_poly_seq_scheme_ptr, + void Feed_pdbx_poly_seq_scheme(ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme_ptr, const String& label_asym_id, int label_entity_id, ost::io::MMCifWriterEntity& entity_info, const ost::mol::ResidueHandleList& res_list) { - std::vector<ost::io::StarLoopDataItemDO> data; - data.push_back(ost::io::StarLoopDataItemDO(label_asym_id)); - data.push_back(ost::io::StarLoopDataItemDO(label_entity_id)); - data.push_back(ost::io::StarLoopDataItemDO("")); - data.push_back(ost::io::StarLoopDataItemDO(0)); - data.push_back(ost::io::StarLoopDataItemDO("")); - data.push_back(ost::io::StarLoopDataItemDO(0)); - data.push_back(ost::io::StarLoopDataItemDO("")); + std::vector<ost::io::StarWriterLoopDataItem> data; + data.push_back(ost::io::StarWriterLoopDataItem(label_asym_id)); + data.push_back(ost::io::StarWriterLoopDataItem(label_entity_id)); + data.push_back(ost::io::StarWriterLoopDataItem("")); + data.push_back(ost::io::StarWriterLoopDataItem(0)); + data.push_back(ost::io::StarWriterLoopDataItem("")); + data.push_back(ost::io::StarWriterLoopDataItem(0)); + data.push_back(ost::io::StarWriterLoopDataItem("")); int asym_idx = entity_info.GetAsymIdx(label_asym_id); const std::vector<String>& aln = entity_info.asym_alns[asym_idx]; @@ -948,35 +945,35 @@ namespace { throw "ksajdhfgjkaljshdfsfgd"; } - data[2] = ost::io::StarLoopDataItemDO(res_name); - data[3] = ost::io::StarLoopDataItemDO(label_seq_id + 1); + data[2] = ost::io::StarWriterLoopDataItem(res_name); + data[3] = ost::io::StarWriterLoopDataItem(label_seq_id + 1); // the remaining data items honor String properties if set: // pdb_auth_chain_name, pdb_auth_resnum and pdb_auth_ins_code if(res.GetChain().HasProp("pdb_auth_chain_name")) { data[4] = - ost::io::StarLoopDataItemDO(res.GetChain().GetStringProp("pdb_auth_chain_name")); + ost::io::StarWriterLoopDataItem(res.GetChain().GetStringProp("pdb_auth_chain_name")); } else { - data[4] = ost::io::StarLoopDataItemDO(res.GetChain().GetName()); + data[4] = ost::io::StarWriterLoopDataItem(res.GetChain().GetName()); } if(res.HasProp("pdb_auth_resnum")) { - data[5] = ost::io::StarLoopDataItemDO(res.GetStringProp("pdb_auth_resnum")); + data[5] = ost::io::StarWriterLoopDataItem(res.GetStringProp("pdb_auth_resnum")); } else { - data[5] = ost::io::StarLoopDataItemDO(res.GetNumber().GetNum()); + data[5] = ost::io::StarWriterLoopDataItem(res.GetNumber().GetNum()); } if(res.HasProp("pdb_auth_ins_code")) { - data[6] = ost::io::StarLoopDataItemDO(res.GetStringProp("pdb_auth_ins_code")); + data[6] = ost::io::StarWriterLoopDataItem(res.GetStringProp("pdb_auth_ins_code")); } else { char ins_code = res.GetNumber().GetInsCode(); if(ins_code == '\0') { - data[6] = ost::io::StarLoopDataItemDO(""); + data[6] = ost::io::StarWriterLoopDataItem(""); } else { String tmp = " "; tmp[0] = ins_code; - data[6] = ost::io::StarLoopDataItemDO(tmp); + data[6] = ost::io::StarWriterLoopDataItem(tmp); } } pdbx_poly_seq_scheme_ptr->AddData(data); @@ -984,11 +981,11 @@ namespace { } } - void Feed_atom_site_(ost::io::StarLoop* atom_site_ptr, - const String& label_asym_id, - int label_entity_id, - const ost::io::MMCifWriterEntity& entity_info, - const ost::mol::ResidueHandleList& res_list) { + void Feed_atom_site(ost::io::StarWriterLoopPtr atom_site_ptr, + const String& label_asym_id, + int label_entity_id, + const ost::io::MMCifWriterEntity& entity_info, + const ost::mol::ResidueHandleList& res_list) { int asym_idx = entity_info.GetAsymIdx(label_asym_id); const std::vector<String>& aln = entity_info.asym_alns[asym_idx]; @@ -1023,110 +1020,110 @@ namespace { auth_seq_id = ss.str(); } for(auto at: at_list) { - std::vector<ost::io::StarLoopDataItemDO> at_data; + std::vector<ost::io::StarWriterLoopDataItem> at_data; // group_PDB if(at.IsHetAtom()) { - at_data.push_back(ost::io::StarLoopDataItemDO("HETATM")); + at_data.push_back(ost::io::StarWriterLoopDataItem("HETATM")); } else { - at_data.push_back(ost::io::StarLoopDataItemDO("ATOM")); + at_data.push_back(ost::io::StarWriterLoopDataItem("ATOM")); } // type_symbol - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetElement())); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetElement())); // label_atom_id - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetName())); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetName())); // label_comp_id - at_data.push_back(ost::io::StarLoopDataItemDO(comp_id)); + at_data.push_back(ost::io::StarWriterLoopDataItem(comp_id)); // label_asym_id - at_data.push_back(ost::io::StarLoopDataItemDO(label_asym_id)); + at_data.push_back(ost::io::StarWriterLoopDataItem(label_asym_id)); // label_entity_id - at_data.push_back(ost::io::StarLoopDataItemDO(label_entity_id)); + at_data.push_back(ost::io::StarWriterLoopDataItem(label_entity_id)); // label_seq_id if(entity_info.is_poly) { - at_data.push_back(ost::io::StarLoopDataItemDO(label_seq_id+1)); + at_data.push_back(ost::io::StarWriterLoopDataItem(label_seq_id+1)); } else { - at_data.push_back(ost::io::StarLoopDataItemDO(".")); + at_data.push_back(ost::io::StarWriterLoopDataItem(".")); } // label_alt_id - at_data.push_back(ost::io::StarLoopDataItemDO(".")); + at_data.push_back(ost::io::StarWriterLoopDataItem(".")); // Cartn_x - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetX(), 3)); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetX(), 3)); // Cartn_y - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetY(), 3)); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetY(), 3)); // Cartn_z - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetZ(), 3)); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetZ(), 3)); // occupancy - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetOccupancy(), 2)); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetOccupancy(), 2)); // B_iso_or_equiv - at_data.push_back(ost::io::StarLoopDataItemDO(at.GetBFactor(), 2)); + at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetBFactor(), 2)); // auth_seq_id - at_data.push_back(ost::io::StarLoopDataItemDO(auth_seq_id)); + at_data.push_back(ost::io::StarWriterLoopDataItem(auth_seq_id)); // auth_asym_id - at_data.push_back(ost::io::StarLoopDataItemDO(auth_asym_id)); + at_data.push_back(ost::io::StarWriterLoopDataItem(auth_asym_id)); // id - at_data.push_back(ost::io::StarLoopDataItemDO(atom_site_ptr->GetN())); + at_data.push_back(ost::io::StarWriterLoopDataItem(atom_site_ptr->GetN())); // pdbx_PDB_ins_code - at_data.push_back(ost::io::StarLoopDataItemDO("")); // CHECK THIS, ADD STUFF FROM AUTH_SEQ_ID? + at_data.push_back(ost::io::StarWriterLoopDataItem("")); // CHECK THIS, ADD STUFF FROM AUTH_SEQ_ID? atom_site_ptr->AddData(at_data); } ++label_seq_id; } } - void Feed_entity_(ost::io::StarLoop* entity_ptr, - const std::vector<ost::io::MMCifWriterEntity>& entity_info) { + void Feed_entity(ost::io::StarWriterLoopPtr entity_ptr, + const std::vector<ost::io::MMCifWriterEntity>& entity_info) { for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) { - std::vector<ost::io::StarLoopDataItemDO> ent_data; - ent_data.push_back(ost::io::StarLoopDataItemDO(entity_idx)); - ent_data.push_back(ost::io::StarLoopDataItemDO(entity_info[entity_idx].type)); + std::vector<ost::io::StarWriterLoopDataItem> ent_data; + ent_data.push_back(ost::io::StarWriterLoopDataItem(entity_idx)); + ent_data.push_back(ost::io::StarWriterLoopDataItem(entity_info[entity_idx].type)); entity_ptr->AddData(ent_data); } } - void Feed_struct_asym_(ost::io::StarLoop* struct_asym_ptr, - const std::vector<ost::io::MMCifWriterEntity>& entity_info) { + void Feed_struct_asym(ost::io::StarWriterLoopPtr struct_asym_ptr, + const std::vector<ost::io::MMCifWriterEntity>& entity_info) { for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) { for(auto asym_id : entity_info[entity_idx].asym_ids) { - std::vector<ost::io::StarLoopDataItemDO> asym_data; - asym_data.push_back(ost::io::StarLoopDataItemDO(asym_id)); - asym_data.push_back(ost::io::StarLoopDataItemDO(entity_idx)); + std::vector<ost::io::StarWriterLoopDataItem> asym_data; + asym_data.push_back(ost::io::StarWriterLoopDataItem(asym_id)); + asym_data.push_back(ost::io::StarWriterLoopDataItem(entity_idx)); struct_asym_ptr->AddData(asym_data); } } } - void Feed_entity_poly_seq_(ost::io::StarLoop* entity_poly_seq_ptr, - const std::vector<ost::io::MMCifWriterEntity>& entity_info) { + void Feed_entity_poly_seq(ost::io::StarWriterLoopPtr entity_poly_seq_ptr, + const std::vector<ost::io::MMCifWriterEntity>& entity_info) { // reuse data vector for efficiency - std::vector<ost::io::StarLoopDataItemDO> entity_poly_seq_data; - entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO(0)); - entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO("ALA")); - entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO(1)); + std::vector<ost::io::StarWriterLoopDataItem> entity_poly_seq_data; + entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem(0)); + entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem("ALA")); + entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem(1)); for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) { if(entity_info[entity_idx].is_poly) { const std::vector<String>& mon_ids = entity_info[entity_idx].mon_ids; for(size_t mon_idx = 0; mon_idx < mon_ids.size(); ++mon_idx) { - entity_poly_seq_data[0] = ost::io::StarLoopDataItemDO(entity_idx); - entity_poly_seq_data[1] = ost::io::StarLoopDataItemDO(mon_ids[mon_idx]); - entity_poly_seq_data[2] = ost::io::StarLoopDataItemDO(mon_idx+1); + entity_poly_seq_data[0] = ost::io::StarWriterLoopDataItem(entity_idx); + entity_poly_seq_data[1] = ost::io::StarWriterLoopDataItem(mon_ids[mon_idx]); + entity_poly_seq_data[2] = ost::io::StarWriterLoopDataItem(mon_idx+1); entity_poly_seq_ptr->AddData(entity_poly_seq_data); } } } } - void Feed_entity_poly_(ost::io::StarLoop* entity_poly_ptr, - const std::vector<ost::io::MMCifWriterEntity>& entity_info) { + void Feed_entity_poly(ost::io::StarWriterLoopPtr entity_poly_ptr, + const std::vector<ost::io::MMCifWriterEntity>& entity_info) { // reuse data vector for efficiency - std::vector<ost::io::StarLoopDataItemDO> entity_poly_data; - entity_poly_data.push_back(ost::io::StarLoopDataItemDO(0)); - entity_poly_data.push_back(ost::io::StarLoopDataItemDO("other")); - entity_poly_data.push_back(ost::io::StarLoopDataItemDO("A")); - entity_poly_data.push_back(ost::io::StarLoopDataItemDO("A")); + std::vector<ost::io::StarWriterLoopDataItem> entity_poly_data; + entity_poly_data.push_back(ost::io::StarWriterLoopDataItem(0)); + entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("other")); + entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("A")); + entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("A")); for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) { if(entity_info[entity_idx].is_poly) { - entity_poly_data[0] = ost::io::StarLoopDataItemDO(entity_idx); - entity_poly_data[1] = ost::io::StarLoopDataItemDO(entity_info[entity_idx].poly_type); + entity_poly_data[0] = ost::io::StarWriterLoopDataItem(entity_idx); + entity_poly_data[1] = ost::io::StarWriterLoopDataItem(entity_info[entity_idx].poly_type); std::stringstream seq; std::stringstream seq_can; for(size_t idx = 0; idx < entity_info[entity_idx].mon_ids.size(); ++idx) { @@ -1150,11 +1147,11 @@ namespace { } } - void Feed_chem_comp_(ost::io::StarLoop* chem_comp_ptr, - const std::map<String, CompInfo>& comp_infos) { - std::vector<ost::io::StarLoopDataItemDO> comp_data; - comp_data.push_back(ost::io::StarLoopDataItemDO("ALA")); - comp_data.push_back(ost::io::StarLoopDataItemDO("L-peptide linking")); + void Feed_chem_comp(ost::io::StarWriterLoopPtr chem_comp_ptr, + const std::map<String, CompInfo>& comp_infos) { + std::vector<ost::io::StarWriterLoopDataItem> comp_data; + comp_data.push_back(ost::io::StarWriterLoopDataItem("ALA")); + comp_data.push_back(ost::io::StarWriterLoopDataItem("L-peptide linking")); for(auto it = comp_infos.begin(); it != comp_infos.end(); ++it) { comp_data[0] = it->first; comp_data[1] = it->second.type; @@ -1162,25 +1159,25 @@ namespace { } } - void SetStructure_(const ost::mol::EntityHandle& ent, - std::map<String, CompInfo>& comp_infos, - std::vector<ost::io::MMCifWriterEntity>& entity_info, - ost::io::StarLoop* atom_site, - ost::io::StarLoop* pdbx_poly_seq_scheme) { + void ProcessEnt(const ost::mol::EntityHandle& ent, + std::map<String, CompInfo>& comp_infos, + std::vector<ost::io::MMCifWriterEntity>& entity_info, + ost::io::StarWriterLoopPtr atom_site, + ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme) { ost::mol::ChainHandleList chain_list = ent.GetChainList(); for(auto ch: chain_list) { ost::mol::ResidueHandleList res_list = ch.GetResidueList(); - Setup_chem_comp_(res_list, comp_infos); + SetupChemComp(res_list, comp_infos); String chain_name = ch.GetName(); - int entity_id = Setup_entity_(chain_name, - ch.GetType(), - res_list, - true, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + ch.GetType(), + res_list, + true, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1188,11 +1185,11 @@ namespace { } } - void SetStructuremmCIFify_(const ost::mol::EntityHandle& ent, - std::map<String, CompInfo>& comp_infos, - std::vector<ost::io::MMCifWriterEntity>& entity_info, - ost::io::StarLoop* atom_site, - ost::io::StarLoop* pdbx_poly_seq_scheme) { + void ProcessEntmmCIFify(const ost::mol::EntityHandle& ent, + std::map<String, CompInfo>& comp_infos, + std::vector<ost::io::MMCifWriterEntity>& entity_info, + ost::io::StarWriterLoopPtr atom_site, + ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme) { std::vector<std::vector<ost::mol::ResidueHandle> > L_chains; // L_PEPTIDE_LINKING std::vector<std::vector<ost::mol::ResidueHandle> > D_chains; // D_PEPTIDE_LINKING @@ -1209,7 +1206,7 @@ namespace { ost::mol::ResidueHandleList res_list = ch.GetResidueList(); - Setup_chem_comp_(res_list, comp_infos); + SetupChemComp(res_list, comp_infos); // we don't just go for chain type here... // just think of PDB entries that have a polypeptide, water and a ligand @@ -1340,12 +1337,12 @@ namespace { // process L_PEPTIDE_LINKING for(auto res_list: L_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1355,12 +1352,12 @@ namespace { // process D_PEPTIDE_LINKING for(auto res_list: D_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1370,12 +1367,12 @@ namespace { // process PEPTIDE_LINKING for(auto res_list: P_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1385,12 +1382,12 @@ namespace { // process RNA_LINKING for(auto res_list: R_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1400,12 +1397,12 @@ namespace { // process DNA_LINKING for(auto res_list: S_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1415,12 +1412,12 @@ namespace { // process SACHARIDE for(auto res_list: Z_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1430,12 +1427,12 @@ namespace { // process WATER for(auto res_list: W_chains) { String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1447,12 +1444,12 @@ namespace { ost::mol::ResidueHandleList res_list; res_list.push_back(res); String chain_name = chain_name_gen.Get(); - int entity_id = Setup_entity_(chain_name, - res_list, - false, - entity_info); - Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id], - res_list); + int entity_id = SetupEntity(chain_name, + res_list, + false, + entity_info); + Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id], + res_list); if(entity_info[entity_id].is_poly) { Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name, entity_id, entity_info[entity_id], res_list); @@ -1482,70 +1479,35 @@ int MMCifWriterEntity::GetAsymIdx(const String& asym_id) const { MMCifWriter::MMCifWriter(const String& filename, const IOProfile& profile): StarWriter(filename), - profile_(profile), - atom_type_(NULL), - atom_site_(NULL), - pdbx_poly_seq_scheme_(NULL), - entity_(NULL), - struct_asym_(NULL), - entity_poly_(NULL), - entity_poly_seq_(NULL), - chem_comp_(NULL) { } - -MMCifWriter::~MMCifWriter() { - if(atom_type_ != NULL) { - delete atom_type_; - } - if(atom_site_ != NULL) { - delete atom_site_; - } - if(pdbx_poly_seq_scheme_ != NULL) { - delete pdbx_poly_seq_scheme_; - } - if(entity_ != NULL) { - delete entity_; - } - if(struct_asym_ != NULL) { - delete struct_asym_; - } - if(entity_poly_ != NULL) { - delete entity_poly_; - } - if(entity_poly_seq_ != NULL) { - delete entity_poly_seq_; - } - if(chem_comp_ != NULL) { - delete chem_comp_; - } -} + profile_(profile) { } void MMCifWriter::SetStructure(const ost::mol::EntityHandle& ent, bool mmcif_conform) { // tabula rasa - if(atom_type_ != NULL) { - delete atom_type_; + if(atom_type_) { + atom_type_.reset(); } - if(atom_site_ != NULL) { - delete atom_site_; + if(atom_site_) { + atom_site_.reset(); } - if(pdbx_poly_seq_scheme_ != NULL) { - delete pdbx_poly_seq_scheme_; + if(pdbx_poly_seq_scheme_) { + pdbx_poly_seq_scheme_.reset(); } - if(entity_ != NULL) { - delete entity_; + if(entity_) { + entity_.reset(); } - if(struct_asym_ != NULL) { - delete struct_asym_; + if(struct_asym_) { + struct_asym_.reset(); } - if(entity_poly_ != NULL) { - delete entity_poly_; + if(entity_poly_) { + entity_poly_.reset(); } - if(entity_poly_seq_ != NULL) { - delete entity_poly_seq_; + if(entity_poly_seq_) { + entity_poly_seq_.reset(); } - if(chem_comp_ != NULL) { - delete chem_comp_; + if(chem_comp_) { + chem_comp_.reset(); } atom_type_ = Setup_atom_type_ptr(); @@ -1559,29 +1521,27 @@ void MMCifWriter::SetStructure(const ost::mol::EntityHandle& ent, std::map<String, CompInfo> comp_infos; - // The SetStructure functions fill comp_info and entity_info_, i.e. gather + // The ProcessEnt functions fill comp_info and entity_info_, i.e. gather // info on all unique compounds and entities observed in ent and relate the // entities with asym chain names that are directly written to // atom_site_/pdbx_poly_seq_scheme_. if(mmcif_conform) { // chains are assumed to be mmCIF conform - that means water in separate // chains, ligands in separate chains etc. Chain types are inferred from - // chain type property set to the chains in ent. If any of the residues in - // the respective chains is incompatible with the set chain type, an error - // is thrown. - SetStructure_(ent, comp_infos, entity_info_, - atom_site_, pdbx_poly_seq_scheme_); + // chain type property set to the chains in ent. + ProcessEnt(ent, comp_infos, entity_info_, + atom_site_, pdbx_poly_seq_scheme_); } else { // rule based splitting of chains into mmCIF conform chains - SetStructuremmCIFify_(ent, comp_infos, entity_info_, - atom_site_, pdbx_poly_seq_scheme_); + ProcessEntmmCIFify(ent, comp_infos, entity_info_, + atom_site_, pdbx_poly_seq_scheme_); } - Feed_entity_(entity_, entity_info_); - Feed_struct_asym_(struct_asym_, entity_info_); - Feed_entity_poly_(entity_poly_, entity_info_); - Feed_entity_poly_seq_(entity_poly_seq_, entity_info_); - Feed_chem_comp_(chem_comp_, comp_infos); - Feed_atom_type_(atom_type_, atom_site_); + Feed_entity(entity_, entity_info_); + Feed_struct_asym(struct_asym_, entity_info_); + Feed_entity_poly(entity_poly_, entity_info_); + Feed_entity_poly_seq(entity_poly_seq_, entity_info_); + Feed_chem_comp(chem_comp_, comp_infos); + Feed_atom_type(atom_type_, atom_site_); // finalize this->Push(chem_comp_); diff --git a/modules/io/src/mol/mmcif_writer.hh b/modules/io/src/mol/mmcif_writer.hh index fd91f67499927c8a580354f95f14ac16bb7a5175..be110936480178a3db6a8b378871d787d68fdae2 100644 --- a/modules/io/src/mol/mmcif_writer.hh +++ b/modules/io/src/mol/mmcif_writer.hh @@ -70,21 +70,21 @@ public: MMCifWriter(const String& filename, const IOProfile& profile); - virtual ~MMCifWriter(); + virtual ~MMCifWriter() { } void SetStructure(const ost::mol::EntityHandle& ent, bool mmcif_conform=true); private: IOProfile profile_; std::vector<MMCifWriterEntity> entity_info_; - StarLoop* atom_type_; - StarLoop* atom_site_; - StarLoop* pdbx_poly_seq_scheme_; - StarLoop* entity_; - StarLoop* struct_asym_; - StarLoop* entity_poly_; - StarLoop* entity_poly_seq_; - StarLoop* chem_comp_; + StarWriterLoopPtr atom_type_; + StarWriterLoopPtr atom_site_; + StarWriterLoopPtr pdbx_poly_seq_scheme_; + StarWriterLoopPtr entity_; + StarWriterLoopPtr struct_asym_; + StarWriterLoopPtr entity_poly_; + StarWriterLoopPtr entity_poly_seq_; + StarWriterLoopPtr chem_comp_; }; }} // ns diff --git a/modules/io/src/mol/star_base.hh b/modules/io/src/mol/star_base.hh deleted file mode 100644 index 1441d2db6672b71e72205ef2d9b0d787ad1f20e0..0000000000000000000000000000000000000000 --- a/modules/io/src/mol/star_base.hh +++ /dev/null @@ -1,323 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2023 by the OpenStructure authors -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License as published by the Free -// Software Foundation; either version 3.0 of the License, or (at your option) -// any later version. -// This library is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -// details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this library; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -//------------------------------------------------------------------------------ -#ifndef OST_IO_STAR_BASE_HH -#define OST_IO_STAR_BASE_HH - -#include <map> -#include <algorithm> -#include <ost/string_ref.hh> -#include <ost/io/io_exception.hh> - -namespace{ - // float to string with specified number of decimals - void fts(Real f, int decimals, String& s) { - char data[20]; - size_t len; - switch(decimals){ - case 0: - len = std::snprintf(data, sizeof(data), "%.0f", f); - break; - case 1: - len = std::snprintf(data, sizeof(data), "%.1f", f); - break; - case 2: - len = std::snprintf(data, sizeof(data), "%.2f", f); - break; - case 3: - len = std::snprintf(data, sizeof(data), "%.3f", f); - break; - case 4: - len = std::snprintf(data, sizeof(data), "%.4f", f); - break; - case 5: - len = std::snprintf(data, sizeof(data), "%.5f", f); - break; - case 6: - len = std::snprintf(data, sizeof(data), "%.6f", f); - break; - default: - throw ost::io::IOException("Max decimals in float conversion: 6"); - } - - if(len < 0 || len > 20) { - throw ost::io::IOException("float conversion failed"); - } - s.assign(data, len); - } -} - -namespace ost { namespace io { - - -typedef enum { - STAR_DIAG_WARNING, - STAR_DIAG_ERROR -} StarDiagType; - - -class DLLEXPORT_OST_IO StarObject { -public: - virtual ~StarObject() { } - virtual void ToStream(std::ostream& s) = 0; -}; - -class DLLEXPORT_OST_IO StarDataItem : public StarObject{ -public: - StarDataItem(const StringRef& category, const StringRef& name, - const StringRef& value): - category_(category), name_(name), value_(value) - { } - - virtual void ToStream(std::ostream& s) { - s << category_ << '.' << name_ << ' ' << value_ << std::endl; - } - - const StringRef& GetCategory() const { return category_; } - const StringRef& GetName() const { return name_; } - const StringRef& GetValue() const { return value_; } -private: - StringRef category_; - StringRef name_; - StringRef value_; -}; - - -class DLLEXPORT_OST_IO StarDataItemDO : public StarObject{ - // basically a copy of StarDataItem but with data ownership - // Problem with StringRef: It's purely pointer based - // => data needs to reside elsewhere -public: - StarDataItemDO(const String& category, const String& name, - const String& value): - category_(category), name_(name) - { - // cases we still need to deal with: - // - special characters in strings (put in quotation marks) - // - long strings (semicolon based syntax) - // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html - if(value == "") { - value_ = "."; - } else { - value_ = value; - } - } - - StarDataItemDO(const String& category, const String& name, - Real value, int decimals): - category_(category), name_(name) - { - fts(value, decimals, value_); - } - - StarDataItemDO(const String& category, const String& name, - int value): - category_(category), name_(name) - { - value_ = std::to_string(value); - } - - virtual void ToStream(std::ostream& s) { - s << category_ << '.' << name_ << ' ' << value_ << std::endl; - } - - const String& GetCategory() const { return category_; } - const String& GetName() const { return name_; } - const String& GetValue() const { return value_; } -private: - String category_; - String name_; - String value_; -}; - -class DLLEXPORT_OST_IO StarDataCategoryDO : public StarObject { -public: - StarDataCategoryDO(const String& category): category_(category) {} - - void Add(const StarDataItemDO& data_item) { - if(data_item.GetCategory() != category_) { - throw ost::io::IOException("category mismatch"); - } - data_items_.push_back(data_item); - } - - virtual void ToStream(std::ostream& s) { - for(auto it = data_items_.begin(); it != data_items_.end(); ++it) { - it->ToStream(s); - } - } - -private: - String category_; - std::vector<StarDataItemDO> data_items_; -}; - -class DLLEXPORT_OST_IO StarLoopDesc : public StarObject { -public: - StarLoopDesc(): - category_("") - { } - - int GetIndex(const String& name) const - { - std::map<String, int>::const_iterator i=index_map_.find(name); - return i==index_map_.end() ? -1 : i->second; - } - - void SetCategory(const StringRef& category) - { - category_=category.str(); - } - - void SetCategory(const String& category) - { - category_=category; - } - - void Add(const StringRef& name) - { - index_map_.insert(std::make_pair(name.str(), index_map_.size())); - } - void Add(const String& name) - { - index_map_.insert(std::make_pair(name, index_map_.size())); - } - size_t GetSize() const - { - return index_map_.size(); - } - void Clear() - { - category_.clear(); - index_map_.clear(); - } - - virtual void ToStream(std::ostream& s) { - std::vector<std::pair<int, String> > tmp; - for(auto it = index_map_.begin(); it != index_map_.end(); ++it) { - tmp.push_back(std::make_pair(it->second, it->first)); - } - std::sort(tmp.begin(), tmp.end()); - for(auto it = tmp.begin(); it != tmp.end(); ++it) { - s << category_ << "." << it->second << std::endl; - } - } - - const String& GetCategory() const { return category_; } -private: - String category_; - std::map<String, int> index_map_; -}; - -class DLLEXPORT_OST_IO StarLoopDataItemDO{ -public: - - StarLoopDataItemDO(const String& value) { - // cases we still need to deal with: - // - special characters in strings (put in quotation marks) - // - long strings (semicolon based syntax) - // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html - - - bool has_space = false; - for(char c: value) { - if(isspace(c)) { - has_space = true; - break; - } - } - if(value == "") { - value_ = "."; - } else if(has_space) { - value_ = "'" + value + "'"; - } - else { - value_ = value; - } - } - - StarLoopDataItemDO(Real value, int decimals) { - fts(value, decimals, value_); - } - - StarLoopDataItemDO(int value) { - value_ = std::to_string(value); - } - - const String& GetValue() const { return value_; } - - virtual void ToStream(std::ostream& s) { - s << value_; - } - -private: - String value_; -}; - -class DLLEXPORT_OST_IO StarLoop: public StarObject { -public: - - StarLoop() { } - - StarLoop(const StarLoopDesc& desc): desc_(desc) { } - - void SetDesc(const StarLoopDesc& desc) { - if(!data_.empty()) { - throw ost::io::IOException("Can only set new StarLoop desc in " - "in empty loop"); - } - desc_ = desc; - } - - const StarLoopDesc& GetDesc() { return desc_; } - - void AddData(const std::vector<StarLoopDataItemDO>& data) { - if(data.size() != desc_.GetSize()) { - throw ost::io::IOException("Invalid data size when adding to StarLoop"); - } - data_.insert(data_.end(), data.begin(), data.end()); - } - - const std::vector<StarLoopDataItemDO>& GetData() { return data_; } - - int GetN() { - return data_.size() / desc_.GetSize(); - } - - virtual void ToStream(std::ostream& s) { - s << "loop_" << std::endl; - desc_.ToStream(s); - int desc_size = desc_.GetSize(); - for(size_t i = 0; i < data_.size(); ++i) { - data_[i].ToStream(s); - if((i+1) % desc_size == 0) { - s << std::endl; - } else { - s << ' '; - } - } - } - -private: - StarLoopDesc desc_; - std::vector<StarLoopDataItemDO> data_; -}; - -}} // ns - -#endif diff --git a/modules/io/src/mol/star_parser.hh b/modules/io/src/mol/star_parser.hh index 0d13b1a50ab4be12b2da85c72adf725f4bee4d59..bc6a3947a6694ec83e8e3fd699d30223cc87359f 100644 --- a/modules/io/src/mol/star_parser.hh +++ b/modules/io/src/mol/star_parser.hh @@ -31,10 +31,70 @@ #include <map> #include <ost/string_ref.hh> #include <ost/io/module_config.hh> -#include <ost/io/mol/star_base.hh> namespace ost { namespace io { + +typedef enum { + STAR_DIAG_WARNING, + STAR_DIAG_ERROR +} StarDiagType; + + +class DLLEXPORT_OST_IO StarDataItem { +public: + StarDataItem(const StringRef& category, const StringRef& name, + const StringRef& value): + category_(category), name_(name), value_(value) + { } + const StringRef& GetCategory() const { return category_; } + const StringRef& GetName() const { return name_; } + const StringRef& GetValue() const { return value_; } +private: + StringRef category_; + StringRef name_; + StringRef value_; +}; + +class DLLEXPORT_OST_IO StarLoopDesc { +public: + StarLoopDesc(): + category_("") + { } + + int GetIndex(const String& name) const + { + std::map<String, int>::const_iterator i=index_map_.find(name); + return i==index_map_.end() ? -1 : i->second; + } + + void SetCategory(const StringRef& category) + { + category_=category.str(); + } + + + + void Add(const StringRef& name) + { + index_map_.insert(std::make_pair(name.str(), index_map_.size())); + } + size_t GetSize() const + { + return index_map_.size(); + } + void Clear() + { + category_.clear(); + index_map_.clear(); + } + + const String& GetCategory() const { return category_; } +private: + String category_; + std::map<String, int> index_map_; +}; + /// \brief parser for the STAR file format /// /// \section star_format STAR format description diff --git a/modules/io/src/mol/star_writer.hh b/modules/io/src/mol/star_writer.hh index f858e021a81ff6e0e012dd29c7c6f4291258c1ac..3ef9c64c06cbc64baad51867828acc8378caf445 100644 --- a/modules/io/src/mol/star_writer.hh +++ b/modules/io/src/mol/star_writer.hh @@ -23,26 +23,283 @@ #include <fstream> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filter/gzip.hpp> +#include <boost/shared_ptr.hpp> #include <ost/string_ref.hh> -#include <ost/io/mol/star_base.hh> +#include <ost/io/io_exception.hh> +namespace{ + // float to string with specified number of decimals + void fts(Real f, int decimals, String& s) { + char data[20]; + size_t len; + switch(decimals){ + case 0: + len = std::snprintf(data, sizeof(data), "%.0f", f); + break; + case 1: + len = std::snprintf(data, sizeof(data), "%.1f", f); + break; + case 2: + len = std::snprintf(data, sizeof(data), "%.2f", f); + break; + case 3: + len = std::snprintf(data, sizeof(data), "%.3f", f); + break; + case 4: + len = std::snprintf(data, sizeof(data), "%.4f", f); + break; + case 5: + len = std::snprintf(data, sizeof(data), "%.5f", f); + break; + case 6: + len = std::snprintf(data, sizeof(data), "%.6f", f); + break; + default: + throw ost::io::IOException("Max decimals in float conversion: 6"); + } + + if(len < 0 || len > 20) { + throw ost::io::IOException("float conversion failed"); + } + s.assign(data, len); + } +} namespace ost { namespace io { +class StarWriterObject; +class StarWriterDataItem; +class StarWriterDataCategory; +class StarWriterLoopDesc; +class StarWriterLoopDataItem; +class StarWriterLoop; +typedef boost::shared_ptr<StarWriterObject> StarWriterObjectPtr; +typedef boost::shared_ptr<StarWriterDataItem> StarWriterDataItemPtr; +typedef boost::shared_ptr<StarWriterDataCategory> StarWriterDataCategoryPtr; +typedef boost::shared_ptr<StarWriterLoopDesc> StarWriterLoopDescPtr; +typedef boost::shared_ptr<StarWriterLoopDataItem> StarWriterLoopDataItemPtr; +typedef boost::shared_ptr<StarWriterLoop> StarWriterLoopPtr; + +class DLLEXPORT_OST_IO StarWriterObject { +public: + virtual ~StarWriterObject() { } + virtual void ToStream(std::ostream& s) = 0; +}; + +class DLLEXPORT_OST_IO StarWriterDataItem : public StarWriterObject { + +public: + StarWriterDataItem(const String& category, const String& name, + const String& value): category_(category), name_(name) { + // cases we still need to deal with: + // - special characters in strings (put in quotation marks) + // - long strings (semicolon based syntax) + // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html + if(value == "") { + value_ = "."; + } else { + value_ = value; + } + } + + StarWriterDataItem(const String& category, const String& name, + Real value, int decimals): category_(category), + name_(name) { + fts(value, decimals, value_); + } + + StarWriterDataItem(const String& category, const String& name, + int value): category_(category), name_(name) { + value_ = std::to_string(value); + } + + virtual void ToStream(std::ostream& s) { + s << category_ << '.' << name_ << ' ' << value_ << std::endl; + } + + const String& GetCategory() const { return category_; } + const String& GetName() const { return name_; } + const String& GetValue() const { return value_; } +private: + String category_; + String name_; + String value_; +}; + +class DLLEXPORT_OST_IO StarWriterDataCategory : public StarWriterObject { +public: + StarWriterDataCategory(const String& category): category_(category) { } + + void Add(const StarWriterDataItem& data_item) { + if(data_item.GetCategory() != category_) { + throw ost::io::IOException("category mismatch"); + } + data_items_.push_back(data_item); + } + + virtual void ToStream(std::ostream& s) { + for(auto it = data_items_.begin(); it != data_items_.end(); ++it) { + it->ToStream(s); + } + } + +private: + String category_; + std::vector<StarWriterDataItem> data_items_; +}; + +class DLLEXPORT_OST_IO StarWriterLoopDesc : public StarWriterObject { +public: + StarWriterLoopDesc(): category_("") { } + + int GetIndex(const String& name) const { + std::map<String, int>::const_iterator i=index_map_.find(name); + return i==index_map_.end() ? -1 : i->second; + } + + void SetCategory(const String& category) { + category_=category; + } + + void Add(const String& name) { + index_map_.insert(std::make_pair(name, index_map_.size())); + } + + size_t GetSize() const { + return index_map_.size(); + } + + void Clear() { + category_.clear(); + index_map_.clear(); + } + + virtual void ToStream(std::ostream& s) { + std::vector<std::pair<int, String> > tmp; + for(auto it = index_map_.begin(); it != index_map_.end(); ++it) { + tmp.push_back(std::make_pair(it->second, it->first)); + } + std::sort(tmp.begin(), tmp.end()); + for(auto it = tmp.begin(); it != tmp.end(); ++it) { + s << category_ << "." << it->second << std::endl; + } + } + + const String& GetCategory() const { return category_; } +private: + String category_; + std::map<String, int> index_map_; +}; + +class DLLEXPORT_OST_IO StarWriterLoopDataItem{ +public: + + StarWriterLoopDataItem(const String& value) { + // cases we still need to deal with: + // - special characters in strings (put in quotation marks) + // - long strings (semicolon based syntax) + // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html + + + bool has_space = false; + for(char c: value) { + if(isspace(c)) { + has_space = true; + break; + } + } + if(value == "") { + value_ = "."; + } else if(has_space) { + value_ = "'" + value + "'"; + } + else { + value_ = value; + } + } + + StarWriterLoopDataItem(Real value, int decimals) { + fts(value, decimals, value_); + } + + StarWriterLoopDataItem(int value) { + value_ = std::to_string(value); + } + + const String& GetValue() const { return value_; } + + virtual void ToStream(std::ostream& s) { + s << value_; + } + +private: + String value_; +}; + +class DLLEXPORT_OST_IO StarWriterLoop: public StarWriterObject { +public: + + StarWriterLoop() { } + + StarWriterLoop(const StarWriterLoopDesc& desc): desc_(desc) { } + + void SetDesc(const StarWriterLoopDesc& desc) { + if(!data_.empty()) { + throw ost::io::IOException("Can only set new StarLoop desc in " + "in empty loop"); + } + desc_ = desc; + } + + const StarWriterLoopDesc& GetDesc() { return desc_; } + + void AddData(const std::vector<StarWriterLoopDataItem>& data) { + if(data.size() != desc_.GetSize()) { + throw ost::io::IOException("Invalid data size when adding to StarLoop"); + } + data_.insert(data_.end(), data.begin(), data.end()); + } + + const std::vector<StarWriterLoopDataItem>& GetData() { return data_; } + + int GetN() { + return data_.size() / desc_.GetSize(); + } + + virtual void ToStream(std::ostream& s) { + s << "loop_" << std::endl; + desc_.ToStream(s); + int desc_size = desc_.GetSize(); + for(size_t i = 0; i < data_.size(); ++i) { + data_[i].ToStream(s); + if((i+1) % desc_size == 0) { + s << std::endl; + } else { + s << ' '; + } + } + } + +private: + StarWriterLoopDesc desc_; + std::vector<StarWriterLoopDataItem> data_; +}; + + class DLLEXPORT_OST_IO StarWriter { public: StarWriter(std::ostream& stream); StarWriter(const String& filename); virtual ~StarWriter() { } - void Push(StarObject* obj) { categories_to_write_.push_back(obj); } + void Push(StarWriterObjectPtr obj) { categories_to_write_.push_back(obj); } void Write(const String& data_name); private: String filename_; bool file_open_; std::ofstream fstream_; boost::iostreams::filtering_stream<boost::iostreams::output> stream_; - std::vector<StarObject*> categories_to_write_; + std::vector<StarWriterObjectPtr> categories_to_write_; }; }} // ns