static bool FindHELMAtom(std::vector<AtomPDBResidueInfo*> *seq, AtomPDBResidueInfo *info, std::string &id, std::string &pos) { char buffer[32]; char ch; const char *ptr = info->getName().c_str(); if (ptr[0]==' ' && ptr[1]=='S' && ptr[2]=='G' && ptr[3]==' ') ch = '3'; else if (ptr[0]==' ' && ptr[1]=='N' && ptr[2]==' ' && ptr[3]==' ') ch = '1'; else if (ptr[0]==' ' && ptr[1]=='C' && ptr[2]==' ' && ptr[3]==' ') ch = '2'; else return false; int resno = info->getResidueNumber(); for (unsigned int i=1; i<10; i++) { unsigned int len = (unsigned int)seq[i].size(); for (unsigned int j=0; j<len; j++) { AtomPDBResidueInfo *targ = seq[i][j]; if (targ->getResidueNumber() == resno && targ->getResidueName() == info->getResidueName() && targ->getChainId() == info->getChainId() && targ->getInsertionCode() == info->getInsertionCode()) { id = "PEPTIDE"; id += (char)(i+'0'); sprintf(buffer,"%u:R%c",j+1,ch); pos = buffer; return true; } } } return false; }
static bool StandardPDBDoubleBond(RWMol *mol, Atom *beg, Atom *end) { AtomPDBResidueInfo *bInfo = (AtomPDBResidueInfo*)beg->getMonomerInfo(); if (!bInfo || bInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE) return false; AtomPDBResidueInfo *eInfo = (AtomPDBResidueInfo*)end->getMonomerInfo(); if (!eInfo || eInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE) return false; if (!SamePDBResidue(bInfo,eInfo)) return false; if (bInfo->getIsHeteroAtom() || eInfo->getIsHeteroAtom()) return false; const char *ptr = bInfo->getResidueName().c_str(); unsigned int rescode = BCNAM(ptr[0],ptr[1],ptr[2]); ptr = bInfo->getName().c_str(); unsigned int atm1 = BCATM(ptr[0],ptr[1],ptr[2],ptr[3]); ptr = eInfo->getName().c_str(); unsigned int atm2 = BCATM(ptr[0],ptr[1],ptr[2],ptr[3]); if (!StandardPDBDoubleBond(rescode,atm1,atm2)) return false; // Check that neither end already has a double bond ROMol::OBOND_ITER_PAIR bp; for (bp=mol->getAtomBonds(beg); bp.first!=bp.second; ++bp.first) if ((*mol)[*bp.first].get()->getBondType() == Bond::DOUBLE) return false; for (bp=mol->getAtomBonds(end); bp.first!=bp.second; ++bp.first) if ((*mol)[*bp.first].get()->getBondType() == Bond::DOUBLE) return false; return true; }
std::string MolToHELM(const ROMol &mol) { std::vector<AtomPDBResidueInfo*> seq[10]; std::string result; bool first = true; std::string chain; int id = 1; /* First pass: Monomers */ for (ROMol::ConstAtomIterator atomIt=mol.beginAtoms(); atomIt!=mol.endAtoms();++atomIt){ const Atom *atom = *atomIt; AtomPDBResidueInfo *info = (AtomPDBResidueInfo*)(atom->getMonomerInfo()); // We can only write HELM if all atoms have PDB residue information if (!info || info->getMonomerType()!=AtomMonomerInfo::PDBRESIDUE) return ""; if (info->getName() == " CA ") { const char *mono = getHELMMonomer(info); if (!mono) return ""; if (first) { chain = info->getChainId(); result = "PEPTIDE1{"; first = false; } else if (info->getChainId() != chain) { // Nine chains should be enough? if (id == 9) return ""; id++; chain = info->getChainId(); result += "}|PEPTIDE"; result += (char)(id+'0'); result += "{"; } else result += "."; result += mono; seq[id].push_back(info); } else if (info->getResidueName() == "NH2" && info->getName() == " N ") { if (first) return ""; result += ".[am]"; } else if (info->getResidueName() == "ACE" && info->getName() == " C ") { if (first) { chain = info->getChainId(); result = "PEPTIDE1{[ac]"; first = false; } else if (info->getChainId() != chain) { // Nine chains should be enough? if (id == 9) return ""; id++; chain = info->getChainId(); result += "}|PEPTIDE"; result += (char)(id+'0'); result += "{[ac]"; } else return ""; seq[id].push_back(info); } } if (first) return ""; result += "}$"; first = true; for (ROMol::ConstBondIterator bondIt=mol.beginBonds(); bondIt!=mol.endBonds(); ++bondIt){ const Bond *bond = *bondIt; Atom *beg = bond->getBeginAtom(); Atom *end = bond->getEndAtom(); if (!beg || !end) continue; AtomPDBResidueInfo *binfo = (AtomPDBResidueInfo*)(beg->getMonomerInfo()); AtomPDBResidueInfo *einfo = (AtomPDBResidueInfo*)(end->getMonomerInfo()); if (!binfo || !einfo) continue; // Test if this is an uninteresting intra-residue bond if (binfo->getResidueNumber() == einfo->getResidueNumber() && binfo->getResidueName() == einfo->getResidueName() && binfo->getChainId() == einfo->getChainId() && binfo->getInsertionCode() == einfo->getInsertionCode()) continue; if (bond->getBondType() != Bond::SINGLE) return ""; if (IsEupeptideBond(binfo,einfo)) continue; if (!IsSupportedHELMBond(binfo,einfo)) return ""; std::string tmp = NameHELMBond(seq,binfo,einfo); if (tmp.empty()) return ""; if (!first) result += "|"; else first = false; result += tmp; } result += "$$$"; return result; }