Coordinate _hDonCalcNormal(OpenBabel::OBAtom* a) { int nbrBonds(0); Coordinate normal; std::vector<OpenBabel::OBBond*>::iterator bi; for (OpenBabel::OBBond* b = a->BeginBond(bi); b; b = a->NextBond(bi)) { OpenBabel::OBAtom* aa = b->GetNbrAtom(a); if (aa->GetAtomicNum() == 1) { continue; } ++nbrBonds; normal.x += (aa->x() - a->x()); normal.y += (aa->y() - a->y()); normal.z += (aa->z() - a->z()); } double length(sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z)); normal.x /= length; normal.y /= length; normal.z /= length; normal.x = -normal.x; normal.y = -normal.y; normal.z = -normal.z; normal.x += a->x(); normal.y += a->y(); normal.z += a->z(); return normal; }
void FilterRings::Calculate(OpenBabel::OBMol* mol) { // Are there rings? bool rings(false); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { std::vector<OpenBabel::OBRing* > nrings = mol->GetSSSR(); _result = nrings.size(); } else { _result = 0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
extern "C" int write_output_(char *out_filename, double *A, int *n) { std::ofstream ofs(out_filename); OpenBabel::OBConversion ob(NULL, &ofs); OpenBabel::OBAtom atom; OpenBabel::OBMol mol; int i; ob.SetOutFormat("CML"); /* Atom is Iridium */ atom.SetAtomicNum(77); for (i = 0; i < *n; i++) { atom.SetVector(A[i*3], A[i*3+1], A[i*3+2]); mol.AddAtom(atom); } //for (i=0; i < *n; i++) //{ //for (int j=i; j < *n; j++) //{ //mol.AddBond(i+1, j+1, 0); //} //} ob.Write(&mol); ob.CloseOutFile(); }
void FilterNonaromaticRingFraction::Calculate(OpenBabel::OBMol* mol) { // Are there atoms and rings? unsigned int rings(0); unsigned int natoms(0); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsHydrogen()) continue; if (atom->IsInRing()) ++rings; ++natoms; } if (!natoms) { _result = 0.0; _passed = false; return; } std::set<int> uniqRingIdx; if (rings) { std::vector<OpenBabel::OBRing*> nrings = mol->GetSSSR(); uniqRingIdx.clear(); std::vector<int>::iterator path; std::vector<OpenBabel::OBRing*>::iterator ri; for (ri = nrings.begin(); ri != nrings.end(); ++ri) { if (!(*ri)->IsAromatic()) { for (path = (*ri)->_path.begin(); path != (*ri)->_path.end(); ++path) { uniqRingIdx.insert(*path); } } } } unsigned int ar(uniqRingIdx.size()); if (ar) { _result = (double) ar / (double) natoms; } else { _result = 0.0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void FilterCores::Calculate(OpenBabel::OBMol* mol) { // Any rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { // Make workcopy of original mol OpenBabel::OBMol m = *mol; m.DeleteHydrogens(); // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } if (m.NumAtoms()) _result = 1; else _result = 0; } else { _result = 0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void ReadFileThread::detectConformers(unsigned int c, const OpenBabel::OBMol &first, const OpenBabel::OBMol ¤t) { if (!c) { // this is the first molecule read m_moleculeFile->setConformerFile(true); addConformer(current); return; } if (!m_moleculeFile->isConformerFile()) return; // as long as we are not sure if this really is a // conformer/trajectory file, add the conformers addConformer(current); // performance: check only certain molecule 1-10,20,50 switch (c) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 20: case 50: break; default: return; } if (first.NumAtoms() != current.NumAtoms()) { m_moleculeFile->setConformerFile(false); m_moleculeFile->m_conformers.clear(); return; } for (unsigned int i = 0; i < first.NumAtoms(); ++i) { OpenBabel::OBAtom *firstAtom = first.GetAtom(i+1); OpenBabel::OBAtom *currentAtom = current.GetAtom(i+1); if (firstAtom->GetAtomicNum() != currentAtom->GetAtomicNum()) { m_moleculeFile->setConformerFile(false); m_moleculeFile->m_conformers.clear(); return; } } }
void StereoCenterItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Molecule *mol = molecule(); painter->save(); painter->setPen(Qt::green); if (!mol) { // not connected: default behaviour (draw connectable box) MolInputItem::paint(painter, option, widget); painter->restore(); return; } const QList<Atom*> &atoms = mol->atoms(); OpenBabel::OBMol *obmol = mol->OBMol(); QPointF offset(-5.0, 5.0); #ifdef OPENBABEL2_TRUNK // need to calculate symmetry first std::vector<unsigned int> symmetry_classes; OpenBabel::OBGraphSym graphsym(obmol); graphsym.GetSymmetry(symmetry_classes); //std::vector<unsigned long> atomIds = FindTetrahedralAtoms(obmol, symmetry_classes); std::vector<OpenBabel::StereogenicUnit> units = FindStereogenicUnits(obmol, symmetry_classes); for (unsigned int i = 0; i < units.size(); ++i) { if (units.at(i).type == OpenBabel::OBStereo::Tetrahedral) { OpenBabel::OBAtom *obatom = obmol->GetAtomById(units.at(i).id); painter->drawEllipse(mapFromItem(mol, atoms[obatom->GetIndex()]->pos()), 10, 10); } else if (units.at(i).type == OpenBabel::OBStereo::CisTrans) { OpenBabel::OBBond *obbond = obmol->GetBondById(units.at(i).id); OpenBabel::OBAtom *obatom1 = obbond->GetBeginAtom(); OpenBabel::OBAtom *obatom2 = obbond->GetEndAtom(); painter->drawEllipse(mapFromItem(mol, atoms[obatom1->GetIndex()]->pos()), 10, 10); painter->drawEllipse(mapFromItem(mol, atoms[obatom2->GetIndex()]->pos()), 10, 10); } } #else using OpenBabel::OBMolAtomIter; FOR_ATOMS_OF_MOL(atom, obmol) if (atom->IsChiral()) painter->drawEllipse(mapFromItem(mol, atoms[atom->GetIdx()-1]->pos()), 10, 10); #endif // default behavious (draw the label()) MolInputItem::paint(painter, option, widget); painter->restore(); }
std::list<OpenBabel::OBAtom*> _hAccGetNeighbors(OpenBabel::OBAtom* a) { std::list<OpenBabel::OBAtom*> aList; OpenBabel::OBMol* parent(a->GetParent()); double r; OpenBabel::OBElementTable et; std::vector<OpenBabel::OBAtom*>::iterator ai; for (OpenBabel::OBAtom* aa = parent->BeginAtom(ai); aa; aa = parent->NextAtom(ai)) { if (*aa == a) { continue; } r = et.GetVdwRad(aa->GetAtomicNum()); double delta(H_BOND_DIST + H_RADIUS + r); double maxDistSq(delta*delta); double distSq((a->x() - aa->x()) * (a->x() - aa->x()) + (a->y() - aa->y()) * (a->y() - aa->y()) + (a->z() - aa->z()) * (a->z() - aa->z())); if (distSq <= maxDistSq) { aList.push_back(aa); } } return aList; }
OpenBabel::OBMol Schuffenhauer::Rule_1(OpenBabel::OBMol& oldMol) { if (oldMol.GetSSSR().size() <= _ringsToBeRetained) { return oldMol; } OpenBabel::OBMol newMol(oldMol); std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBBondIterator bi; OpenBabel::OBAtom* atom; OpenBabel::OBAtom* nbrAtom[2]; for (atom = newMol.BeginAtom(avi); atom; atom = newMol.NextAtom(avi)) { if ((atom->MemberOfRingSize() == 3) && (atom->IsNitrogen() || atom->IsOxygen()) && (atom->MemberOfRingCount() == 1) && (atom->GetHvyValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { newMol.DeleteAtom(atom); newMol.GetBond(nbrAtom[0], nbrAtom[1])->SetBondOrder(2); } } } return newMol; }
void Fingerprint::_getFragments(std::vector<int> levels, std::vector<int>curfrag, int level, OpenBabel::OBAtom* patom, OpenBabel::OBBond* pbond) { const int MaxFragSize = 7; int bo(0); if (pbond) bo = pbond->IsAromatic() ? 5 : pbond->GetBondOrder(); curfrag.push_back(bo); curfrag.push_back(patom->GetAtomicNum()); levels[patom->GetIdx()] = level; std::vector<OpenBabel::OBBond*>::iterator i; OpenBabel::OBBond* pnewbond; for (pnewbond = patom->BeginBond(i); pnewbond; pnewbond = patom->NextBond(i)) { if (pnewbond == pbond) { continue; } OpenBabel::OBAtom* pnxtat = pnewbond->GetNbrAtom(patom); int atlevel = levels[pnxtat->GetIdx()]; if (atlevel) { if (atlevel == 1) { curfrag[0] = bo; _ringset.insert(curfrag); } } else { if (level < MaxFragSize) { _getFragments(levels, curfrag, level + 1, pnxtat, pnewbond); } } } if ((curfrag[0] == 0) && ((level > 1) || (patom->GetAtomicNum() > 8) || (patom->GetAtomicNum() < 6))) { _fragset.insert(curfrag); } }
void hAccFuncCalc(OpenBabel::OBMol* mol, Pharmacophore* pharmacophore) { // Create for every hydrogen acceptor a pharmacophore point std::vector<OpenBabel::OBAtom*>::iterator ai; for (OpenBabel::OBAtom* atom = mol->BeginAtom(ai); atom; atom = mol->NextAtom(ai)) { if (atom->GetAtomicNum() == 7 || atom->GetAtomicNum() == 8) { if (atom->GetFormalCharge() <= 0) { if(_hAccDelocalized(atom) || (_hAccCalcAccSurf(atom) < 0.02)) { continue; } PharmacophorePoint p; p.func = HACC; p.point.x = atom->x(); p.point.y = atom->y(); p.point.z = atom->z(); p.hasNormal = true; p.alpha = funcSigma[HACC]; p.normal = _hAccCalcNormal(atom); pharmacophore->push_back(p); } } } }
//-- // [rad] generate path and ident for bond void RelationBond::GetPathAndIdentBond(const std::string& refMoleculeId, std::string& refPath, std::string& refIdent) { refPath = m_vecSatisfiedClasses.front()->GetPrefix() + ":" + m_vecSatisfiedClasses.front()->GetName(); std::stringstream ssConv; OpenBabel::OBBond* pBond = m_pBond; OpenBabel::OBAtom* pAtomStart = pBond->GetBeginAtom(); OpenBabel::OBAtom* pAtomEnd = pBond->GetEndAtom(); ssConv << m_vecSatisfiedClasses.front()->GetName() << "_" << refMoleculeId << "_" << pAtomStart->GetIdx() << "_" << pAtomEnd->GetIdx(); refIdent = ""; ssConv >> refIdent; }
void FilterAtomsInLargestNonaromaticRing::Calculate(OpenBabel::OBMol* mol) { // Are there rings? bool rings(false); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { std::vector<OpenBabel::OBRing*> nrings = mol->GetSSSR(); _result = 0; std::vector<OpenBabel::OBRing*>::iterator ri; for (ri = nrings.begin(); ri != nrings.end(); ++ri) { if ( !(*ri)->IsAromatic() && ((*ri)->Size() > _result)) { _result = (*ri)->Size(); } } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } } else { _result = 0; _passed = true; } }
// [rad] generate path and ident for bond void RelationBond::GetObjectPropertyPathAndIdentBond(int iPosition, const std::string& refMoleculeId, std::string& refPath, std::string& refIdent) { refPath = m_vecSatisfiedObjectPropertiesBond[iPosition].first->GetPrefix() + ":" + m_vecSatisfiedObjectPropertiesBond[iPosition].first->GetName(); std::stringstream ssConv; OpenBabel::OBAtom* pAtomStart = m_vecSatisfiedObjectPropertiesBond[iPosition].second->m_pBond->GetBeginAtom(); OpenBabel::OBAtom* pAtomEnd = m_vecSatisfiedObjectPropertiesBond[iPosition].second->m_pBond->GetEndAtom(); ssConv << m_vecSatisfiedObjectPropertiesBond[iPosition].second->m_vecSatisfiedClasses.front()->GetName() << "_" << refMoleculeId << "_" << pAtomStart->GetIdx() << "_" << pAtomEnd->GetIdx(); refIdent = ""; ssConv >> refIdent; }
unsigned int Schuffenhauer::CalculateHeteroAtoms(OpenBabel::OBMol& mol, OpenBabel::OBRing* ring, int a = 0) { unsigned int n(0); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator avi; for (atom = mol.BeginAtom(avi); atom; atom = mol.NextAtom(avi)) { if (ring->IsMember(atom) && (atom->GetAtomicNum() == a)) { ++n; } if (!a && ring->IsMember(atom)) { if ((atom->GetAtomicNum() == 7) || (atom->GetAtomicNum() == 8) || (atom->GetAtomicNum() == 16)) { ++n; } } } return n; }
void hDonFuncCalc(OpenBabel::OBMol* mol, Pharmacophore* pharmacophore) { // Create for every hydrogen donor a pharmacophore point std::vector<OpenBabel::OBAtom*>::iterator ai; for (OpenBabel::OBAtom* a = mol->BeginAtom(ai); a; a = mol->NextAtom(ai)) { if (a->GetAtomicNum() == 7 || a->GetAtomicNum() == 8) { if (a->GetFormalCharge() >= 0 && ((a->GetImplicitValence() - a->GetHvyValence()) !=0)) { PharmacophorePoint p; p.func = HDON; p.point.x = a->x(); p.point.y = a->y(); p.point.z = a->z(); p.hasNormal = true; p.alpha = funcSigma[HDON]; p.normal = _hDonCalcNormal(a); pharmacophore->push_back(p); } } } }
static int extract_thermo(OpenBabel::OBMol *mol,string method,double temperature, double ezpe,double Hcorr,double Gcorr,double E0,double CV, int RotSymNum,std::vector<double> Scomponents) { // Initiate correction database OpenBabel::OBAtomicHeatOfFormationTable *ahof = new OpenBabel::OBAtomicHeatOfFormationTable(); OpenBabel::OBAtomIterator OBai; OpenBabel::OBAtom *OBa; OpenBabel::OBElementTable *OBet; char valbuf[128]; int ii,atomid,atomicnumber,found,foundall; double dhofM0, dhofMT, S0MT, DeltaSMT; double eFactor = HARTEE_TO_KCALPERMOL; OBet = new OpenBabel::OBElementTable(); // Now loop over atoms in order to correct the Delta H formation OBai = mol->BeginAtoms(); atomid = 0; foundall = 0; dhofM0 = E0*eFactor; dhofMT = dhofM0+(Hcorr-ezpe)*eFactor; S0MT = 0; if (temperature > 0) { // Multiply by 1000 to make the unit cal/mol K S0MT += 1000*eFactor*(Hcorr-Gcorr)/temperature; } // Check for symmetry OBPointGroup obPG; obPG.Setup(mol); const char *pg = obPG.IdentifyPointGroup(); double Rgas = 1.9872041; // cal/mol K http://en.wikipedia.org/wiki/Gas_constant double Srot = -Rgas * log(RotSymNum); //printf("DHf(M,0) = %g, DHf(M,T) = %g, S0(M,T) = %g\nPoint group = %s RotSymNum = %d Srot = %g\n", // dhofM0, dhofMT, S0MT, pg, RotSymNum, Srot); if (RotSymNum > 1) { // We assume Gaussian has done this correctly! Srot = 0; } S0MT += Srot; DeltaSMT = S0MT; for (OBa = mol->BeginAtom(OBai); (NULL != OBa); OBa = mol->NextAtom(OBai)) { double dhfx0, dhfxT, S0xT; atomicnumber = OBa->GetAtomicNum(); found = ahof->GetHeatOfFormation(OBet->GetSymbol(atomicnumber), 0, method, temperature, &dhfx0, &dhfxT, &S0xT); if (1 == found) { dhofM0 += dhfx0; dhofMT += dhfxT; DeltaSMT += S0xT; foundall ++; } atomid++; } if (foundall == atomid) { std::string attr[5]; double result[5]; char buf[32]; attr[0].assign("DeltaHform(0K)"); result[0] = dhofM0; snprintf(buf, sizeof(buf), "DeltaHform(%gK)", temperature); attr[1].assign(buf); result[1] = dhofMT; snprintf(buf, sizeof(buf), "DeltaSform(%gK)", temperature); attr[2].assign(buf); result[2] = DeltaSMT; snprintf(buf, sizeof(buf), "DeltaGform(%gK)", temperature); attr[3].assign(buf); result[3] = dhofMT - temperature*result[2]/1000; snprintf(buf, sizeof(buf), "S0(%gK)", temperature); attr[4].assign(buf); result[4] = S0MT; add_unique_pairdata_to_mol(mol, "method", method, 0); for(ii=0; (ii<5); ii++) { // Add to molecule properties sprintf(valbuf,"%f", result[ii]); add_unique_pairdata_to_mol(mol, attr[ii], valbuf, 0); } sprintf(valbuf, "%f", CV); add_unique_pairdata_to_mol(mol, "cv", valbuf, 0); sprintf(valbuf, "%f", CV+Rgas); add_unique_pairdata_to_mol(mol, "cp", valbuf, 0); // Entropy components if (Scomponents.size() == 3) { const char *comps[3] = { "Strans", "Srot", "Svib" }; for(int i=0; (i<3); i++) { sprintf(valbuf, "%f", Scomponents[i]); add_unique_pairdata_to_mol(mol, comps[i], valbuf, 0); } } // Finally store the energy in internal data structures as well. mol->SetEnergy(dhofMT); } else { // Debug message? } // Clean up delete OBet; delete ahof; if (foundall == atomid) return 1; else return 0; }
OpenBabel::OBMol Schuffenhauer::Rule_4(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } // Only focus on ringsystems with more than one ring std::vector<OpenBabel::OBAtom*>::iterator avi; std::vector<OpenBabel::OBMol> mols; OpenBabel::OBAtom* atom; std::vector<int> fusedRings; for (unsigned int i(0); i < allrings.size(); ++i) { for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (allrings[i]->IsMember(atom) && (atom->MemberOfRingCount() > 1)) { fusedRings.push_back(i); mols.push_back(oldMol); break; } } } if (fusedRings.empty()) { return oldMol; } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < fusedRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, fusedRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.empty()) { return oldMol; } int delta; int absdelta; std::vector<int> score; for (unsigned int i(0); i < validMols.size(); ++i) { delta = CalculateDelta(validMols[i]); absdelta = abs(delta); score.push_back(1000 * absdelta + delta); } int maximum = score[0]; for (unsigned int i(1); i < validMols.size(); ++i) { if (score[i] > maximum) { maximum = score[i]; } } unsigned int oldMolecules = validMols.size(); std::vector<OpenBabel::OBMol> remainingMols; for (unsigned int i(0); i < validMols.size(); ++i) { if (score[i] == maximum) { remainingMols.push_back(validMols[i]); } } if (remainingMols.size() == 1) { return remainingMols[0]; } return oldMol; }
bool Oprea_2::CalculateScaffold(const OpenBabel::OBMol& mol, Options* o) { OpenBabel::OBMol m(mol); // Tag all HBD std::vector<bool> hbd(m.NumAtoms() + 1); for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (atom->MatchesSMARTS("[NH,NH2,NH3,OH,nH]")) { hbd[atom->GetIdx()] = true; } else { hbd[atom->GetIdx()] = false; } } // Tag all HBA std::vector<bool> hba(m.NumAtoms() + 1); for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (!atom->IsAmideNitrogen() && // No amide nitrogen !atom->IsAromatic() && // Not aromatic (atom->GetFormalCharge() <= 0) && // No + charge atom->MatchesSMARTS("[NH0]")) // No hydrogens { hba[atom->GetIdx()] = true; } else if (atom->IsNitrogen() && // Nitrogen atom->IsAromatic() && // Aromatic atom->MatchesSMARTS("[nH0]") && // No hydrogens (atom->GetHvyValence() <= 2) && // Maximal two non-H atoms connected (atom->GetFormalCharge() <= 0)) // No + charge { hba[atom->GetIdx()] = true; } else if (atom->IsOxygen() && // Oxygen (atom->GetFormalCharge() <= 0)) // No + charge { hba[atom->GetIdx()] = true; } else { hba[atom->GetIdx()] = false; } } // Mark the C(=O) or S(=O) also as HBA for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (atom->MatchesSMARTS("C=O")) { hba[atom->GetIdx()] = true; } else if (atom->MatchesSMARTS("S=O")) { hba[atom->GetIdx()] = true; } } // Make all atoms as neutral C, N (HBD), or O (HBA) m.BeginModify(); std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (hba[atom->GetIdx()]) { atom->SetAtomicNum(8); } else if (hbd[atom->GetIdx()]) { atom->SetAtomicNum(7); } else { atom->SetAtomicNum(6); } atom->SetFormalCharge(0); } m.EndModify(); // Remove all endstanding atoms OpenBabel::OBBondIterator bi; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; bool removed(true); while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (IsEndStanding(atom, false, false)) { m.DeleteAtom(atom); removed = true; break; } } } // Set all bond orders equal to 1 m.BeginModify(); for (bond = m.BeginBond(bvi); bond; bond = m.NextBond(bvi)) { bond->SetBondOrder(1); } m.EndModify(); // Transform all neighbouring linker atoms into a single bond removed = true; OpenBabel::OBAtom* nbrAtom[2]; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (!atom->IsInRing() && (atom->GetValence() == 2)) { m.BeginModify(); nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } // Shrink all rings to their minimum size removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if ((atom->MemberOfRingSize() > 3) && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { if (nbrAtom[0]->GetAtomicNum() == atom->GetAtomicNum()) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } else if (nbrAtom[1]->GetAtomicNum() == atom->GetAtomicNum()) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } } if (!m.Empty()) { _smiles = _mol2can.WriteString(&m, true); } else { _smiles = "-"; return false; } return true; }
OpenBabel::OBMol Schuffenhauer::Rule_6(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } std::vector<OpenBabel::OBMol> mols; std::vector<int> rings; int size; for (unsigned int i(0); i < allrings.size(); ++i) { size = allrings[i]->Size(); if ((size == 3) || (size == 5) || (size == 6)) { mols.push_back(oldMol); rings.push_back(i); } } if (mols.empty()) { return oldMol; } // Only focus on ringsystems with more than one ring std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; std::vector<int> fusedRings; for (unsigned int i(0); i < rings.size(); ++i) { for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (allrings[rings[i]]->IsMember(atom) && (atom->MemberOfRingCount() > 1)) { fusedRings.push_back(rings[i]); break; } } } if (fusedRings.empty()) { return oldMol; } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < fusedRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, fusedRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.size() == 1) { return validMols[0]; } return oldMol; }
bool _hAccDelocalized(OpenBabel::OBAtom* a) { if (a->GetAtomicNum() != 7) { return false; } if (a->IsAromatic() && a->GetImplicitValence() == 3) { return true; } std::vector<OpenBabel::OBBond*>::iterator bi1; for (OpenBabel::OBBond* b1 = a->BeginBond(bi1); b1; b1 = a->NextBond(bi1)) { OpenBabel::OBAtom* aa = b1->GetNbrAtom(a); if (aa->IsAromatic() && a->GetImplicitValence() == 3) { return true; } if (aa->GetAtomicNum() == 6) { std::vector<OpenBabel::OBBond*>::iterator bi2; for (OpenBabel::OBBond* b2 = aa->BeginBond(bi2); b2; b2 = aa->NextBond(bi2)) { OpenBabel::OBAtom* aaa = b2->GetNbrAtom(aa); if (aaa == a) { continue; } if (b2->GetBO() == 2) { if (aaa->GetAtomicNum() == 8) return true; if (aaa->GetAtomicNum() == 7) return true; if (aaa->GetAtomicNum() == 16) return true; } } } else if (aa->GetAtomicNum() == 16) { std::vector<OpenBabel::OBBond*>::iterator bi2; for (OpenBabel::OBBond* b2 = aa->BeginBond(bi2); b2; b2 = aa->NextBond(bi2)) { OpenBabel::OBAtom* aaa = b2->GetNbrAtom(aa); if (aaa == a) { continue; } if ((b2->GetBO() == 2) && (aaa->GetAtomicNum() == 8)) { return true; } } } } return false; }
OpenBabel::OBMol Schuffenhauer::Rule_7(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } // Are all atoms and bonds aromatic? std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (!atom->IsAromatic()) { return oldMol; } } std::vector<OpenBabel::OBBond*>::iterator bvi; OpenBabel::OBBond* bond; for (bond = oldMol.BeginBond(bvi); bond; bond = oldMol.NextBond(bvi)) { if (!bond->IsAromatic()) { return oldMol; } } std::vector<OpenBabel::OBMol> mols; for (unsigned int i(0); i < allrings.size(); ++i) { mols.push_back(oldMol); } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < mols.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, i); if (!mols[i].Empty()) { // Has aromaticity been broken? bool broken(false); for (atom = mols[i].BeginAtom(avi); atom; atom = mols[i].NextAtom(avi)) { if (atom->IsInRing() && !atom->IsAromatic()) { broken = true; break; } } if (!broken) { validMols.push_back(mols[i]); } } } if (validMols.size() == 1) { return validMols[0]; } return oldMol; }
//-- bool DataProperty::Satisfy(OpenBabel::OBMol* pMolecule, const std::string& refTo, std::vector<Class*>& vecSatisfiedClasses, std::string& refValue) { //bool bSatisfied = false; int iPosition = -1; // [rad] if we are default, we automatically satisfy if(!IsDefault()) { if(!SatisfyCommon(vecSatisfiedClasses, iPosition)) { // [rad] this property does not apply refValue = ""; return(false); } } // [rad] go through possible data types.. if(!refTo.compare("MOLECULE_ATOM_COUNT")) { ConvertInt(pMolecule->NumAtoms(), refValue); } else if(!refTo.compare("MOLECULE_BOND_COUNT")) { ConvertInt(pMolecule->NumBonds(), refValue); } else if(!refTo.compare("MOLECULE_RING_COUNT")) { std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR(); ConvertInt(refSSSR.size(), refValue); } else if(!refTo.compare("MOLECULE_HEAVY_HYDROGEN_COUNT")) { ConvertInt(pMolecule->NumHvyAtoms(), refValue); } else if(!refTo.compare("MOLECULE_RESIDUE_COUNT")) { ConvertInt(pMolecule->NumResidues(), refValue); } else if(!refTo.compare("MOLECULE_ROTOR_COUNT")) { ConvertInt(pMolecule->NumRotors(), refValue); } else if(!refTo.compare("MOLECULE_FORMULA")) { refValue = pMolecule->GetFormula(); } else if(!refTo.compare("MOLECULE_FORMATION_HEAT")) { ConvertDouble(pMolecule->GetEnergy(), refValue); } else if(!refTo.compare("MOLECULE_STANDARD_MOLAR_MASS")) { ConvertDouble(pMolecule->GetMolWt(), refValue); } else if(!refTo.compare("MOLECULE_EXACT_MASS")) { ConvertDouble(pMolecule->GetExactMass(), refValue); } else if(!refTo.compare("MOLECULE_TOTAL_CHARGE")) { ConvertInt(pMolecule->GetTotalCharge(), refValue); } else if(!refTo.compare("MOLECULE_SPIN_MULTIPLICITY")) { ConvertInt(pMolecule->GetTotalSpinMultiplicity(), refValue); } else if(!refTo.compare("MOLECULE_IS_CHIRAL")) { ConvertBool(pMolecule->IsChiral(), refValue); } else if(!refTo.compare("MOLECULE_HAS_AROMATIC_RING")) { std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR(); bool bAromatic = false; std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin(); while(iter_rings != refSSSR.end()) { if((*iter_rings)->IsAromatic()) { bAromatic = true; break; } iter_rings++; } ConvertBool(bAromatic, refValue); } else if(!refTo.compare("MOLECULE_HAS_HOMOCYCLIC_RING")) { std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR(); std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin(); OpenBabel::OBAtom* pAtom; bool bHomoCyclic = true; while(iter_rings != refSSSR.end()) { std::vector<int>::iterator iter_path = (*iter_rings)->_path.begin(); while(iter_path != (*iter_rings)->_path.end()) { pAtom = pMolecule->GetAtom((*iter_path)); if(pAtom) { if(6 != pAtom->GetAtomicNum()) { bHomoCyclic = false; break; } } iter_path++; } if(!bHomoCyclic) break; iter_rings++; } ConvertBool(bHomoCyclic, refValue); } else if(!refTo.compare("MOLECULE_HAS_HETEROCYCLIC_RING")) { std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR(); std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin(); OpenBabel::OBAtom* pAtom; bool bHeteroCyclic = false; while(iter_rings != refSSSR.end()) { std::vector<int>::iterator iter_path = (*iter_rings)->_path.begin(); while(iter_path != (*iter_rings)->_path.end()) { pAtom = pMolecule->GetAtom((*iter_path)); if(pAtom) { if(6 != pAtom->GetAtomicNum()) { bHeteroCyclic = true; break; } } iter_path++; } if(bHeteroCyclic) break; iter_rings++; } ConvertBool(bHeteroCyclic, refValue); } else { // [rad] maybe it's a descriptor? if(SatisfyDescriptor(pMolecule, refTo, refValue)) { return(true); } // [rad] unknown datatype? refValue = ""; return(false); } return(true); }
//-- bool DataProperty::Satisfy(OpenBabel::OBRing* pRing, const std::string& refTo, std::vector<Class*>& vecSatisfiedClasses, std::string& refValue) { //bool bSatisfied = false; int iPosition = -1; // [rad] if we are default, we automatically satisfy if(!IsDefault()) { if(!SatisfyCommon(vecSatisfiedClasses, iPosition)) { // [rad] this property does not apply refValue = ""; return(false); } } // [rad] go through possible data types.. if(!refTo.compare("RING_SIZE")) { ConvertInt(pRing->Size(), refValue); } else if(!refTo.compare("RING_IS_AROMATIC")) { ConvertBool(pRing->IsAromatic(), refValue); } else if(!refTo.compare("RING_IS_HOMOCYCLIC")) { OpenBabel::OBMol* pMolecule = pRing->GetParent(); OpenBabel::OBAtom* pAtom; bool bHomoCyclic = true; std::vector<int>::iterator iter_path = pRing->_path.begin(); while(iter_path != pRing->_path.end()) { pAtom = pMolecule->GetAtom((*iter_path)); if(pAtom) { if(6 != pAtom->GetAtomicNum()) { bHomoCyclic = false; break; } } iter_path++; } ConvertBool(bHomoCyclic, refValue); } else if(!refTo.compare("RING_IS_HETEROCYCLIC")) { OpenBabel::OBMol* pMolecule = pRing->GetParent(); OpenBabel::OBAtom* pAtom; bool bHeteroCyclic = false; std::vector<int>::iterator iter_path = pRing->_path.begin(); while(iter_path != pRing->_path.end()) { pAtom = pMolecule->GetAtom((*iter_path)); if(pAtom) { if(6 != pAtom->GetAtomicNum()) { bHeteroCyclic = true; break; } } iter_path++; } ConvertBool(bHeteroCyclic, refValue); } else { // [rad] unknown datatype? refValue = ""; return(false); } return(true); }
OpenBabel::OBMol Schuffenhauer::RemoveRing(OpenBabel::OBMol& oldMol, std::vector<OpenBabel::OBRing*>& rings, unsigned int ringIdx) { OpenBabel::OBMol newMol(oldMol); // Make list of the ring bonds std::set<OpenBabel::OBBond*> ringBonds; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; for (bond = newMol.BeginBond(bvi); bond; bond = newMol.NextBond(bvi)) { if (rings[ringIdx]->IsMember(bond)) { ringBonds.insert(bond); } } // Make list of delocalizable bonds (aromatic, single and flanked by two double bonds) std::set<OpenBabel::OBBond*> delocalizableBonds; std::set<OpenBabel::OBBond*>::iterator bli; OpenBabel::OBBondIterator bi; OpenBabel::OBAtom* atom; OpenBabel::OBBond* nbrBond; unsigned int n; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; if ((bond->GetBondOrder() == 1) && bond->IsAromatic()) { n = 0; atom = bond->GetBeginAtom(); for (nbrBond = atom->BeginBond(bi); nbrBond; nbrBond = atom->NextBond(bi)) { if ((nbrBond != bond) && ringBonds.count(nbrBond) && (nbrBond->GetBondOrder() == 2)) { ++n; } } atom = bond->GetEndAtom(); for (nbrBond = atom->BeginBond(bi); nbrBond; nbrBond = atom->NextBond(bi)) { if ((nbrBond != bond) && ringBonds.count(nbrBond) && (nbrBond->GetBondOrder() == 2)) { ++n; } } } if (n == 2) { delocalizableBonds.insert(bond); } } // Make list of bonds which form the fusion with other rings std::set<OpenBabel::OBBond*> fusionBonds; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond)) { fusionBonds.insert(bond); } } } } // Make list of bonds which are the fusion between aromatic and non-aromatic std::set<OpenBabel::OBBond*> aromaticNonaromaticFusionBonds; if (rings[ringIdx]->IsAromatic()) { for (bli = fusionBonds.begin(); bli != fusionBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond) && !rings[i]->IsAromatic()) { aromaticNonaromaticFusionBonds.insert(bond); } } } } } // Make list of bonds which are the fusion between aromatic and aromatic std::set<OpenBabel::OBBond*> aromaticAromaticFusionBonds; if (rings[ringIdx]->IsAromatic()) { for (bli = fusionBonds.begin(); bli != fusionBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond) && rings[i]->IsAromatic()) { aromaticAromaticFusionBonds.insert(bond); } } } } } // Remove ring std::set<OpenBabel::OBBond*> bondsToBeDeleted; std::set<OpenBabel::OBAtom*> atomsToBeDeleted; OpenBabel::OBAtom* nbrAtom[2]; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; if (fusionBonds.count(bond)) { continue; } else { bondsToBeDeleted.insert(bond); nbrAtom[0] = bond->GetBeginAtom(); nbrAtom[1] = bond->GetEndAtom(); if (nbrAtom[0] && nbrAtom[1]) { if (nbrAtom[0]->MemberOfRingCount() == 1) { atomsToBeDeleted.insert(nbrAtom[0]); } if (nbrAtom[1]->MemberOfRingCount() == 1) { atomsToBeDeleted.insert(nbrAtom[1]); } } } } newMol.BeginModify(); for (bli = bondsToBeDeleted.begin(); bli != bondsToBeDeleted.end(); ++bli) { newMol.DeleteBond(*bli); } newMol.EndModify(); newMol.BeginModify(); std::set<OpenBabel::OBAtom*>::iterator ali; for (ali = atomsToBeDeleted.begin(); ali != atomsToBeDeleted.end(); ++ali) { newMol.DeleteAtom(*ali); } newMol.EndModify(); // Correct the bond orders of the ex-fusion bond(s) newMol.BeginModify(); for (bond = newMol.BeginBond(bvi); bond; bond = newMol.NextBond(bvi)) { if (aromaticNonaromaticFusionBonds.count(bond)) { bond->SetBondOrder(2); } else if (aromaticAromaticFusionBonds.count(bond) && delocalizableBonds.count(bond)) { bond->SetBondOrder(2); } } newMol.EndModify(); // Remove single atoms that originate from exocyclic bonds at ring (void) RemoveSidechains(&newMol); // Check if there are atoms with valences that are not allowed std::vector<OpenBabel::OBAtom*>::iterator avi; for (atom = newMol.BeginAtom(avi); atom; atom = newMol.NextAtom(avi)) { if (atom->IsCarbon() && (atom->BOSum() > 4)) { newMol.Clear(); break; } else if (atom->IsNitrogen() && (atom->BOSum() > 3)) { newMol.Clear(); break; } else if (atom->IsOxygen() && (atom->BOSum() > 2)) { newMol.Clear(); break; } } // Check if there are no discontinuous fragments if (newMol.Separate().size() > 1) { newMol.Clear(); } return newMol; }
OpenBabel::OBMol Schuffenhauer::Rule_11(OpenBabel::OBMol& oldMol) { // Return if the molecule contains an acyclic linker std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (!atom->IsInRing() && atom->GetValence() >= 2) { return oldMol; } } // Make sure we are dealing with a mixed aromatic/nonaromatic system bool notaromatic(false); bool aromatic(false); for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (atom->IsAromatic()) { aromatic = true; } else { notaromatic = true; } } if (aromatic && notaromatic) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } std::vector<OpenBabel::OBMol> mols; std::vector<unsigned int> aromaticRings; for (unsigned int i(0); i < allrings.size(); ++i) { if (allrings[i]->IsAromatic()) { mols.push_back(oldMol); aromaticRings.push_back(i); } } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < aromaticRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, aromaticRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.size() == 1) { return validMols[0]; } } return oldMol; }
void Molecule::addHydrogens(Atom *a, const QList<unsigned long> &atomIds, const QList<unsigned long> &bondIds) { if (atomIds.size() != bondIds.size()) { qDebug() << "Error, addHydrogens called with atom & bond id lists of different size!"; } // Construct an OBMol, call AddHydrogens and translate the changes OpenBabel::OBMol obmol = OBMol(); if (a) { OpenBabel::OBAtom *obatom = obmol.GetAtom(a->index()+1); // Set implicit valence for unusual elements not handled by OpenBabel // PR#2803076 switch (obatom->GetAtomicNum()) { case 3: case 11: case 19: case 37: case 55: case 85: case 87: obatom->SetImplicitValence(1); obatom->SetHyb(1); obmol.SetImplicitValencePerceived(); break; case 4: case 12: case 20: case 38: case 56: case 88: obatom->SetImplicitValence(2); obatom->SetHyb(2); obmol.SetImplicitValencePerceived(); break; case 84: // Po obatom->SetImplicitValence(2); obatom->SetHyb(3); obmol.SetImplicitValencePerceived(); break; default: // do nothing break; } obmol.AddHydrogens(obatom); } else obmol.AddHydrogens(); // All new atoms in the OBMol must be the additional hydrogens unsigned int numberAtoms = numAtoms(); int j = 0; for (unsigned int i = numberAtoms+1; i <= obmol.NumAtoms(); ++i, ++j) { if (obmol.GetAtom(i)->IsHydrogen()) { OpenBabel::OBAtom *obatom = obmol.GetAtom(i); Atom *atom; if (atomIds.isEmpty()) atom = addAtom(); else if (j < atomIds.size()) atom = addAtom(atomIds.at(j)); else { qDebug() << "Error - not enough unique ids in addHydrogens."; break; } atom->setOBAtom(obatom); // Get the neighbor atom OpenBabel::OBBondIterator iter; OpenBabel::OBAtom *next = obatom->BeginNbrAtom(iter); Bond *bond; if (bondIds.isEmpty()) bond = addBond(); else // Already confirmed by atom ids bond = addBond(bondIds.at(j)); bond->setEnd(Molecule::atom(atom->index())); bond->setBegin(Molecule::atom(next->GetIdx()-1)); } } for (unsigned int i = 1; i <= numberAtoms; ++i) { // Warning -- OB atom index off-by-one here atom(i-1)->setPartialCharge(obmol.GetAtom(i)->GetPartialCharge()); } }
void FilterAtomsInSmallestBridge::Calculate(OpenBabel::OBMol* mol) { // Are there rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { // Make workcopy of original mol OpenBabel::OBMol m = *mol; m.DeleteHydrogens(); // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } // Now remove all ring atoms rings = true; while (rings && m.NumAtoms()) { rings = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->IsInRing()) { if (m.DeleteAtom(atom)) { rings = true; break; } } } } // Separate into fragments if (m.NumAtoms()) { std::vector<std::vector<int> > bridges; m.ContigFragList(bridges); _result = bridges[0].size(); for (unsigned int i(1); i < bridges.size(); ++i) { if (bridges[i].size() < _result) _result = bridges[i].size(); } } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } } else { _result = 0; _passed = true; } }
bool Oprea_1::CalculateScaffold(const OpenBabel::OBMol& mol, Options* o) { OpenBabel::OBMol m(mol); OpenBabel::OBAtom* atom; OpenBabel::OBAtom* nbrAtom[2]; OpenBabel::OBBondIterator bi; std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; bool removed(true); while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (IsEndStanding(atom, false, false)) { m.DeleteAtom(atom); removed = true; break; } } } // Make all atoms as neutral C and all bond orders equal to 1 m.BeginModify(); for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { atom->SetAtomicNum(6); atom->SetFormalCharge(0); } for (bond = m.BeginBond(bvi); bond; bond = m.NextBond(bvi)) { bond->SetBondOrder(1); } m.EndModify(); // Transform all neighbouring linker atoms into a single bond removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (!atom->IsInRing() && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } // Shrink all rings to their minimum size removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if ((atom->MemberOfRingSize() > 3) && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } if (!m.Empty()) { _smiles = _mol2can.WriteString(&m, true); } else { _smiles = "-"; return false; } return true; }
void FilterBridgeFraction::Calculate(OpenBabel::OBMol* mol) { // Are there rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { // Make workcopy of original mol OpenBabel::OBMol m = *mol; m.DeleteHydrogens(); unsigned int natoms(m.NumAtoms()); if (!natoms) { _result = 0.0; _passed = false; return; } // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } // Now remove all ring atoms rings = true; while (rings && m.NumAtoms()) { rings = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->IsInRing()) { if (m.DeleteAtom(atom)) { rings = true; break; } } } } _result = (double) m.NumAtoms() / (double) natoms; } else { _result = 0.0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }