示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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());
    }
}
示例#4
0
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;
}