Commit 35c99564 by Maarten L. Hekkelman

Fix importing sugars from PDB files

parent 1d8fe334
...@@ -525,12 +525,12 @@ class Sugar : public Residue ...@@ -525,12 +525,12 @@ class Sugar : public Residue
{ {
public: public:
Sugar(const Branch &branch, const std::string &compoundID, Sugar(const Branch &branch, const std::string &compoundID,
const std::string &asymID, int authSeqID, int number); const std::string &asymID, int authSeqID);
Sugar(Sugar &&rhs); Sugar(Sugar &&rhs);
Sugar &operator=(Sugar &&rhs); Sugar &operator=(Sugar &&rhs);
int num() const { return mNumber; } int num() const { return std::stoi(mAuthSeqID); }
std::string name() const; std::string name() const;
/// \brief Return the atom the C1 is linked to /// \brief Return the atom the C1 is linked to
...@@ -545,7 +545,6 @@ class Sugar : public Residue ...@@ -545,7 +545,6 @@ class Sugar : public Residue
private: private:
const Branch *mBranch; const Branch *mBranch;
int mNumber;
Atom mLink; Atom mLink;
}; };
......
...@@ -1077,6 +1077,7 @@ class PDBFileParser ...@@ -1077,6 +1077,7 @@ class PDBFileParser
std::map<std::string, std::string> mBranch2EntityID; std::map<std::string, std::string> mBranch2EntityID;
std::map<std::string, std::string> mAsymID2EntityID; std::map<std::string, std::string> mAsymID2EntityID;
std::map<std::string, std::string> mMod2parent; std::map<std::string, std::string> mMod2parent;
std::set<std::string> mSugarEntities;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -3776,6 +3777,10 @@ void PDBFileParser::ConstructEntities() ...@@ -3776,6 +3777,10 @@ void PDBFileParser::ConstructEntities()
for (auto &chain : mChains) for (auto &chain : mChains)
{ {
std::string asymID = cif::cifIdForNumber(asymNr++); std::string asymID = cif::cifIdForNumber(asymNr++);
if (mMolID2EntityID.count(chain.mMolID) == 0)
continue;
std::string entityID = mMolID2EntityID[chain.mMolID]; std::string entityID = mMolID2EntityID[chain.mMolID];
mAsymID2EntityID[asymID] = entityID; mAsymID2EntityID[asymID] = entityID;
...@@ -4601,14 +4606,20 @@ void PDBFileParser::ConstructSugarTrees(int &asymNr) ...@@ -4601,14 +4606,20 @@ void PDBFileParser::ConstructSugarTrees(int &asymNr)
} }
} }
mSugarEntities.insert(entityID);
// create an asym for this sugar tree // create an asym for this sugar tree
std::string asymID = cif::cifIdForNumber(asymNr++); std::string asymID = cif::cifIdForNumber(asymNr++);
getCategory("struct_asym")->emplace({{"id", asymID}, mAsymID2EntityID[asymID] = entityID;
{"pdbx_blank_PDB_chainid_flag", si->chainID == ' ' ? "Y" : "N"},
{"pdbx_modified", "N"}, getCategory("struct_asym")->emplace({
{"entity_id", entityID}}); {"id", asymID},
{"pdbx_blank_PDB_chainid_flag", si->chainID == ' ' ? "Y" : "N"},
{"pdbx_modified", "N"},
{"entity_id", entityID}
});
std::string iCode{si->iCode}; std::string iCode{si->iCode};
ba::trim(iCode); ba::trim(iCode);
...@@ -5107,40 +5118,42 @@ void PDBFileParser::ParseConnectivtyAnnotation() ...@@ -5107,40 +5118,42 @@ void PDBFileParser::ParseConnectivtyAnnotation()
continue; continue;
} }
getCategory("struct_conn")->emplace({{"id", type + std::to_string(linkNr)}, getCategory("struct_conn")->emplace({
{"conn_type_id", type}, {"id", type + std::to_string(linkNr)},
{"conn_type_id", type},
// { "ccp4_link_id", ccp4LinkID },
// { "ccp4_link_id", ccp4LinkID },
{"ptnr1_label_asym_id", p1Asym},
{"ptnr1_label_comp_id", vS(18, 20)}, {"ptnr1_label_asym_id", p1Asym},
{"ptnr1_label_seq_id", (isResseq1 and p1Seq) ? std::to_string(p1Seq) : "."}, {"ptnr1_label_comp_id", vS(18, 20)},
{"ptnr1_label_atom_id", vS(13, 16)}, {"ptnr1_label_seq_id", (isResseq1 and p1Seq) ? std::to_string(p1Seq) : "."},
{"pdbx_ptnr1_label_alt_id", vS(17, 17)}, {"ptnr1_label_atom_id", vS(13, 16)},
{"pdbx_ptnr1_PDB_ins_code", vS(27, 27)}, {"pdbx_ptnr1_label_alt_id", vS(17, 17)},
{"pdbx_ptnr1_standard_comp_id", ""}, {"pdbx_ptnr1_PDB_ins_code", vS(27, 27)},
{"ptnr1_symmetry", sym1}, {"pdbx_ptnr1_standard_comp_id", ""},
{"ptnr1_symmetry", sym1},
{"ptnr2_label_asym_id", p2Asym},
{"ptnr2_label_comp_id", vS(48, 50)}, {"ptnr2_label_asym_id", p2Asym},
{"ptnr2_label_seq_id", (isResseq2 and p2Seq) ? std::to_string(p2Seq) : "."}, {"ptnr2_label_comp_id", vS(48, 50)},
{"ptnr2_label_atom_id", vS(43, 46)}, {"ptnr2_label_seq_id", (isResseq2 and p2Seq) ? std::to_string(p2Seq) : "."},
{"pdbx_ptnr2_label_alt_id", vS(47, 47)}, {"ptnr2_label_atom_id", vS(43, 46)},
{"pdbx_ptnr2_PDB_ins_code", vS(57, 57)}, {"pdbx_ptnr2_label_alt_id", vS(47, 47)},
{"pdbx_ptnr2_PDB_ins_code", vS(57, 57)},
{"ptnr1_auth_asym_id", vS(22, 22)},
{"ptnr1_auth_comp_id", vS(18, 20)}, {"ptnr1_auth_asym_id", vS(22, 22)},
{"ptnr1_auth_seq_id", vI(23, 26)}, {"ptnr1_auth_comp_id", vS(18, 20)},
{"ptnr2_auth_asym_id", vS(52, 52)}, {"ptnr1_auth_seq_id", vI(23, 26)},
{"ptnr2_auth_comp_id", vS(48, 50)}, {"ptnr2_auth_asym_id", vS(52, 52)},
{"ptnr2_auth_seq_id", vI(53, 56)}, {"ptnr2_auth_comp_id", vS(48, 50)},
{"ptnr2_auth_seq_id", vI(53, 56)},
// { "ptnr1_auth_atom_id", vS(13, 16) },
// { "ptnr2_auth_atom_id", vS(43, 46) }, // { "ptnr1_auth_atom_id", vS(13, 16) },
// { "ptnr2_auth_atom_id", vS(43, 46) },
{"ptnr2_symmetry", sym2},
{"ptnr2_symmetry", sym2},
{"pdbx_dist_value", distance}});
{"pdbx_dist_value", distance}
});
continue; continue;
} }
...@@ -5181,24 +5194,26 @@ void PDBFileParser::ParseConnectivtyAnnotation() ...@@ -5181,24 +5194,26 @@ void PDBFileParser::ParseConnectivtyAnnotation()
std::string iCode1str = iCode1 == ' ' ? std::string() : std::string{iCode1}; std::string iCode1str = iCode1 == ' ' ? std::string() : std::string{iCode1};
std::string iCode2str = iCode2 == ' ' ? std::string() : std::string{iCode2}; std::string iCode2str = iCode2 == ' ' ? std::string() : std::string{iCode2};
getCategory("struct_mon_prot_cis")->emplace({{"pdbx_id", serNum}, getCategory("struct_mon_prot_cis")->emplace({
{"label_comp_id", pep1}, {"pdbx_id", serNum},
{"label_seq_id", lResSeq1}, {"label_comp_id", pep1},
{"label_asym_id", lAsym1}, {"label_seq_id", lResSeq1},
{"label_alt_id", "."}, {"label_asym_id", lAsym1},
{"pdbx_PDB_ins_code", iCode1str}, {"label_alt_id", "."},
{"auth_comp_id", pep1}, {"pdbx_PDB_ins_code", iCode1str},
{"auth_seq_id", seqNum1}, {"auth_comp_id", pep1},
{"auth_asym_id", std::string{chainID1}}, {"auth_seq_id", seqNum1},
{"pdbx_label_comp_id_2", pep2}, {"auth_asym_id", std::string{chainID1}},
{"pdbx_label_seq_id_2", lResSeq2}, {"pdbx_label_comp_id_2", pep2},
{"pdbx_label_asym_id_2", lAsym2}, {"pdbx_label_seq_id_2", lResSeq2},
{"pdbx_PDB_ins_code_2", iCode2str}, {"pdbx_label_asym_id_2", lAsym2},
{"pdbx_auth_comp_id_2", pep2}, {"pdbx_PDB_ins_code_2", iCode2str},
{"pdbx_auth_seq_id_2", seqNum2}, {"pdbx_auth_comp_id_2", pep2},
{"pdbx_auth_asym_id_2", std::string{chainID2}}, {"pdbx_auth_seq_id_2", seqNum2},
{"pdbx_PDB_model_num", modNum}, {"pdbx_auth_asym_id_2", std::string{chainID2}},
{"pdbx_omega_angle", measure}}); {"pdbx_PDB_model_num", modNum},
{"pdbx_omega_angle", measure}
});
continue; continue;
} }
...@@ -5557,27 +5572,38 @@ void PDBFileParser::ParseCoordinate(int modelNr) ...@@ -5557,27 +5572,38 @@ void PDBFileParser::ParseCoordinate(int modelNr)
} }
} }
getCategory("atom_site")->emplace({{"group_PDB", groupPDB}, // if the atom is part of a sugar, we need to replace the auth_seq_id/resSeq
{"id", mAtomID}, if (mSugarEntities.count(entityID))
{"type_symbol", element}, {
{"label_atom_id", name}, using namespace cif::literals;
{"label_alt_id", altLoc != ' ' ? std::string{altLoc} : "."},
{"label_comp_id", resName}, auto &branch_scheme = *getCategory("pdbx_branch_scheme");
{"label_asym_id", asymID}, resSeq = branch_scheme.find1<int>("asym_id"_key == asymID and "auth_seq_num"_key == resSeq, "pdb_seq_num");
{"label_entity_id", entityID}, }
{"label_seq_id", (isResseq and seqID > 0) ? std::to_string(seqID) : "."},
{"pdbx_PDB_ins_code", iCode == ' ' ? "" : std::string{iCode}}, getCategory("atom_site")->emplace({
{"Cartn_x", x}, {"group_PDB", groupPDB},
{"Cartn_y", y}, {"id", mAtomID},
{"Cartn_z", z}, {"type_symbol", element},
{"occupancy", occupancy}, {"label_atom_id", name},
{"B_iso_or_equiv", tempFactor}, {"label_alt_id", altLoc != ' ' ? std::string{altLoc} : "."},
{"pdbx_formal_charge", charge}, {"label_comp_id", resName},
{"auth_seq_id", resSeq}, {"label_asym_id", asymID},
{"auth_comp_id", resName}, {"label_entity_id", entityID},
{"auth_asym_id", std::string{chainID}}, {"label_seq_id", (isResseq and seqID > 0) ? std::to_string(seqID) : "."},
{"auth_atom_id", name}, {"pdbx_PDB_ins_code", iCode == ' ' ? "" : std::string{iCode}},
{"pdbx_PDB_model_num", modelNr}}); {"Cartn_x", x},
{"Cartn_y", y},
{"Cartn_z", z},
{"occupancy", occupancy},
{"B_iso_or_equiv", tempFactor},
{"pdbx_formal_charge", charge},
{"auth_seq_id", resSeq},
{"auth_comp_id", resName},
{"auth_asym_id", std::string{chainID}},
{"auth_atom_id", name},
{"pdbx_PDB_model_num", modelNr}
});
InsertAtomType(element); InsertAtomType(element);
......
...@@ -1123,17 +1123,15 @@ int Polymer::Distance(const Monomer &a, const Monomer &b) const ...@@ -1123,17 +1123,15 @@ int Polymer::Distance(const Monomer &a, const Monomer &b) const
// -------------------------------------------------------------------- // --------------------------------------------------------------------
Sugar::Sugar(const Branch &branch, const std::string &compoundID, Sugar::Sugar(const Branch &branch, const std::string &compoundID,
const std::string &asymID, int authSeqID, int number) const std::string &asymID, int authSeqID)
: Residue(branch.structure(), compoundID, asymID, 0, std::to_string(authSeqID)) : Residue(branch.structure(), compoundID, asymID, 0, std::to_string(authSeqID))
, mBranch(&branch) , mBranch(&branch)
, mNumber(number)
{ {
} }
Sugar::Sugar(Sugar &&rhs) Sugar::Sugar(Sugar &&rhs)
: Residue(std::forward<Residue>(rhs)) : Residue(std::forward<Residue>(rhs))
, mBranch(rhs.mBranch) , mBranch(rhs.mBranch)
, mNumber(rhs.mNumber)
{ {
} }
...@@ -1144,7 +1142,6 @@ Sugar &Sugar::operator=(Sugar &&rhs) ...@@ -1144,7 +1142,6 @@ Sugar &Sugar::operator=(Sugar &&rhs)
{ {
Residue::operator=(std::forward<Residue>(rhs)); Residue::operator=(std::forward<Residue>(rhs));
mBranch = rhs.mBranch; mBranch = rhs.mBranch;
mNumber = rhs.mNumber;
} }
return *this; return *this;
...@@ -1206,10 +1203,10 @@ Branch::Branch(Structure &structure, const std::string &asymID) ...@@ -1206,10 +1203,10 @@ Branch::Branch(Structure &structure, const std::string &asymID)
for (const auto &[entity_id] : struct_asym.find<std::string>("id"_key == asymID, "entity_id")) for (const auto &[entity_id] : struct_asym.find<std::string>("id"_key == asymID, "entity_id"))
{ {
for (const auto &[comp_id, number, auth_seq_num] : branch_scheme.find<std::string, int, int>( for (const auto &[comp_id, num] : branch_scheme.find<std::string, int>(
"asym_id"_key == asymID, "mon_id", "pdb_seq_num", "auth_seq_num")) "asym_id"_key == asymID, "mon_id", "pdb_seq_num"))
{ {
emplace_back(*this, comp_id, asymID, auth_seq_num, number); emplace_back(*this, comp_id, asymID, num);
} }
for (const auto &[num1, num2, atom1, atom2] : branch_link.find<size_t, size_t, std::string, std::string>( for (const auto &[num1, num2, atom1, atom2] : branch_link.find<size_t, size_t, std::string, std::string>(
...@@ -2260,11 +2257,13 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve ...@@ -2260,11 +2257,13 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
auto &struct_asym = db["struct_asym"]; auto &struct_asym = db["struct_asym"];
std::string asym_id = struct_asym.getUniqueID(); std::string asym_id = struct_asym.getUniqueID();
struct_asym.emplace({{"id", asym_id}, struct_asym.emplace({
{"id", asym_id},
{"pdbx_blank_PDB_chainid_flag", "N"}, {"pdbx_blank_PDB_chainid_flag", "N"},
{"pdbx_modified", "N"}, {"pdbx_modified", "N"},
{"entity_id", entity_id}, {"entity_id", entity_id},
{"details", "?"}}); {"details", "?"}
});
std::string comp_id = db["pdbx_entity_nonpoly"].find1<std::string>("entity_id"_key == entity_id, "comp_id"); std::string comp_id = db["pdbx_entity_nonpoly"].find1<std::string>("entity_id"_key == entity_id, "comp_id");
...@@ -2276,7 +2275,8 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve ...@@ -2276,7 +2275,8 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
{ {
auto atom_id = atom_site.getUniqueID(""); auto atom_id = atom_site.getUniqueID("");
auto &&[row, inserted] = atom_site.emplace({{"group_PDB", atom.get_property<std::string>("group_PDB")}, auto &&[row, inserted] = atom_site.emplace({
{"group_PDB", atom.get_property<std::string>("group_PDB")},
{"id", atom_id}, {"id", atom_id},
{"type_symbol", atom.get_property<std::string>("type_symbol")}, {"type_symbol", atom.get_property<std::string>("type_symbol")},
{"label_atom_id", atom.get_property<std::string>("label_atom_id")}, {"label_atom_id", atom.get_property<std::string>("label_atom_id")},
...@@ -2296,7 +2296,8 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve ...@@ -2296,7 +2296,8 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
{"auth_comp_id", comp_id}, {"auth_comp_id", comp_id},
{"auth_asym_id", asym_id}, {"auth_asym_id", asym_id},
{"auth_atom_id", atom.get_property<std::string>("label_atom_id")}, {"auth_atom_id", atom.get_property<std::string>("label_atom_id")},
{"pdbx_PDB_model_num", 1}}); {"pdbx_PDB_model_num", 1}
});
auto &newAtom = emplace_atom(std::make_shared<Atom::AtomImpl>(db, atom_id, row)); auto &newAtom = emplace_atom(std::make_shared<Atom::AtomImpl>(db, atom_id, row));
res.addAtom(newAtom); res.addAtom(newAtom);
...@@ -2328,11 +2329,13 @@ std::string Structure::createNonpoly(const std::string &entity_id, std::vector<s ...@@ -2328,11 +2329,13 @@ std::string Structure::createNonpoly(const std::string &entity_id, std::vector<s
auto &struct_asym = db["struct_asym"]; auto &struct_asym = db["struct_asym"];
std::string asym_id = struct_asym.getUniqueID(); std::string asym_id = struct_asym.getUniqueID();
struct_asym.emplace({{"id", asym_id}, struct_asym.emplace({
{"id", asym_id},
{"pdbx_blank_PDB_chainid_flag", "N"}, {"pdbx_blank_PDB_chainid_flag", "N"},
{"pdbx_modified", "N"}, {"pdbx_modified", "N"},
{"entity_id", entity_id}, {"entity_id", entity_id},
{"details", "?"}}); {"details", "?"}
});
std::string comp_id = db["pdbx_entity_nonpoly"].find1<std::string>("entity_id"_key == entity_id, "comp_id"); std::string comp_id = db["pdbx_entity_nonpoly"].find1<std::string>("entity_id"_key == entity_id, "comp_id");
...@@ -2406,7 +2409,7 @@ Branch &Structure::createBranch(std::vector<std::vector<cif::Item>> &nag_atoms) ...@@ -2406,7 +2409,7 @@ Branch &Structure::createBranch(std::vector<std::vector<cif::Item>> &nag_atoms)
std::string asym_id = struct_asym.getUniqueID(); std::string asym_id = struct_asym.getUniqueID();
auto &branch = mBranches.emplace_back(*this, asym_id); auto &branch = mBranches.emplace_back(*this, asym_id);
auto &sugar = branch.emplace_back(branch, "NAG", asym_id, 1, 1); auto &sugar = branch.emplace_back(branch, "NAG", asym_id, 1);
auto tmp_entity_id = db["entity"].getUniqueID(""); auto tmp_entity_id = db["entity"].getUniqueID("");
auto &atom_site = db["atom_site"]; auto &atom_site = db["atom_site"];
...@@ -2520,7 +2523,7 @@ Branch &Structure::extendBranch(const std::string &asym_id, std::vector<std::vec ...@@ -2520,7 +2523,7 @@ Branch &Structure::extendBranch(const std::string &asym_id, std::vector<std::vec
int sugarNum = branch.size() + 1; int sugarNum = branch.size() + 1;
auto &sugar = branch.emplace_back(branch, compoundID, asym_id, sugarNum, sugarNum); auto &sugar = branch.emplace_back(branch, compoundID, asym_id, sugarNum);
for (auto &atom : atom_info) for (auto &atom : atom_info)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment