Example #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;
}
Example #2
0
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;
}