Esempio n. 1
0
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;
}
Esempio n. 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;
}