Example #1
0
  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();
  }
    //--
    // [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;
    }
Example #3
0
unsigned int
Schuffenhauer::CalculateAcyclicBonds(OpenBabel::OBMol& mol)
{
   	unsigned int nbonds(0);
   	OpenBabel::OBAtom* nbratom[2];
   	OpenBabel::OBBond* bond;
   	std::vector<OpenBabel::OBBond*>::iterator bvi;
   	for (bond = mol.BeginBond(bvi); bond; bond = mol.NextBond(bvi))
   	{
      	nbratom[0] = bond->GetBeginAtom();
      	nbratom[1] = bond->GetEndAtom();
		if (nbratom[0] && nbratom[1])
		{
      		if (!bond->IsInRing() && 
				(nbratom[0]->GetValence() > 1) && 
				(nbratom[1]->GetValence() > 1))
      		{
         		++nbonds;
      		}
		}
   	}
   	return nbonds;
}
Example #4
0
bool
Schuffenhauer::HasLinkerToHeteroAtom(OpenBabel::OBMol& mol, OpenBabel::OBRing* ring)
{
   	std::vector<OpenBabel::OBBond*>::iterator bvi;
   	OpenBabel::OBBond* bond;
   	OpenBabel::OBAtom* nbrAtom[2];
   	for (bond = mol.BeginBond(bvi); bond; bond = mol.NextBond(bvi))
   	{
      	nbrAtom[0] = bond->GetBeginAtom();
      	nbrAtom[1] = bond->GetEndAtom();
      	if
		(
			// Neighbours are real
			nbrAtom[0] &&
			nbrAtom[1] &&
			
			// Bond should be acyclic
			!bond->IsInRing() &&
			
			// Both atoms have to be ring atoms
			nbrAtom[0]->IsInRing() && 
			nbrAtom[1]->IsInRing() && 
			
			// At least one of the atoms should be hetero
			(nbrAtom[0]->IsHeteroatom() || nbrAtom[1]->IsHeteroatom()) &&
			
			// One of the atoms, but not both, should be part of this ring	
			((ring->IsMember(nbrAtom[0]) && !ring->IsMember(nbrAtom[1])) ||
			(ring->IsMember(nbrAtom[1]) && !ring->IsMember(nbrAtom[0])))
		)
		{
         	return true;
     	}
   	}
   	return false;
}
Example #5
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;
}