Exemple #1
0
  static int DetermineFRJ(OBMol &mol)
  {
    if (!mol.HasClosureBondsPerceived())
      return (int)FindRingAtomsAndBonds2(mol);

    int frj = 0;
    OBBond *bond;
    vector<OBBond*>::iterator j;
    for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
      if (bond->IsClosure()) // bond->HasFlag(OB_CLOSURE_BOND)?
        frj++;
    return frj;
  }
Exemple #2
0
  void OBMol::FindLSSR()
  {
    if (HasLSSRPerceived())
      return;
    SetLSSRPerceived();
    obErrorLog.ThrowError(__FUNCTION__,
                          "Ran OpenBabel::FindLSSR", obAuditMsg);

    // Delete any old data before we start finding new rings
    // The following procedure is slow
    // So if client code is multi-threaded, we don't want to make them wait
    if (HasData("LSSR")) {
      DeleteData("LSSR");
    }

    OBRing *ring;
    vector<OBRing*>::iterator j;

    //get frerejaque taking int account multiple possible spanning graphs
    int frj = DetermineFRJ(*this);
    if (frj)
      {
        vector<OBRing*> vr;
        FindRingAtomsAndBonds();

        OBBond *bond;
        vector<OBBond*> cbonds;
        vector<OBBond*>::iterator k;

        //restrict search for rings around closure bonds
        for (bond = BeginBond(k);bond;bond = NextBond(k))
          if (bond->IsClosure())
            cbonds.push_back(bond);

        if (!cbonds.empty())
          {
            OBRingSearch rs;
            //search for all rings about closures
            vector<OBBond*>::iterator i;

            for (i = cbonds.begin();i != cbonds.end();++i)
              rs.AddRingFromClosure(*this,(OBBond*)*i);

            rs.SortRings();
            rs.RemoveRedundant(-1); // -1 means LSSR

            //store the LSSR set

            for (j = rs.BeginRings();j != rs.EndRings();++j)
              {
                ring = new OBRing ((*j)->_path,NumAtoms()+1);
                ring->SetParent(this);
                vr.push_back(ring);
              }
            //rs.WriteRings();
          }

        OBRingData *rd = new OBRingData();
        rd->SetOrigin(perceived); // to separate from user or file input
        rd->SetAttribute("LSSR");
        rd->SetData(vr);
        SetData(rd);
      }
  }
Exemple #3
0
  /**
   * \brief Select the root atoms for traversing atoms in rings.
   *
   * Picking only the begin atom of a closure bond can cause
   * difficulties when the selected atom is an inner atom
   * with three neighbour ring atoms. Why ? Because this atom
   * can get trapped by the other atoms when determining aromaticity,
   * because a simple visited flag is used in the
   * OBAromaticTyper::TraverseCycle() method.
   *
   * Ported from JOELib, copyright Joerg Wegner, 2003 under the GPL version 2
   * Improved by Fabian (fab5) in 2009 -- PR#2889708
   *
   * @param mol the molecule
   * @param avoidInnerRingAtoms inner closure ring atoms with more than 2 neighbours will be avoided
   *
   */
  void OBAromaticTyper::SelectRootAtoms(OBMol &mol, bool avoidInnerRingAtoms)
  {
    OBBond *bond;
    OBAtom *atom, *nbr, *nbr2;
    OBRing *ring;
    //    vector<OBAtom*>::iterator i;
    vector<OBBond*>::iterator j, l, nbr2Iter;
    vector<OBRing*> sssRings = mol.GetSSSR();
    vector<OBRing*>::iterator k;
    
    int rootAtom;
    int ringNbrs;
    int heavyNbrs;
    int newRoot = -1;
    vector<int> tmpRootAtoms;
    vector<int> tmp;

    vector<OBBond*> cbonds;
    vector< vector<OBRing*> > ringAtoms; // store ring pointers on an atom basis
    
    //generate list of closure bonds 
    for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
      {
        if( bond->IsClosure() )
          {
            cbonds.push_back(bond);
            if(avoidInnerRingAtoms)
              {
                tmpRootAtoms.push_back(bond->GetBeginAtomIdx());
              }
          }
      }
    
    if(avoidInnerRingAtoms)
      {
        //for every atom fill vector with ring pointer it's associated with
        ringAtoms.resize(mol.NumAtoms()+1);
        for (k = sssRings.begin();k != sssRings.end();++k)
          {
            tmp = (*k)->_path;
            for (unsigned int j (0),j_end(tmp.size()); j < j_end; ++j)
              {
                ringAtoms[tmp[j]].push_back(*k);
              }
          }
      }
    
    
    //loop over closure bonds
    for(OBBondIterator bd(cbonds.begin()),bd_end(cbonds.end());bd!=bd_end;++bd)
      {
        bond = *bd;

        // BASIC APPROACH
        // pick beginning atom at closure bond
        // this is really ready, isn't it ! ;-)
        rootAtom = bond->GetBeginAtomIdx();
        _root[rootAtom] = true;
	
        // EXTENDED APPROACH
        if (avoidInnerRingAtoms)
          {
            // count the number of neighbor ring atoms
            atom = mol.GetAtom(rootAtom);
            ringNbrs = heavyNbrs = 0;
	    
            for (nbr = atom->BeginNbrAtom(l);nbr;nbr = atom->NextNbrAtom(l))
              {
                // we can get this from atom->GetHvyValence()
                // but we need to find neighbors in rings too
                // so let's save some time
                if (!nbr->IsHydrogen())
                  {
                    heavyNbrs++;
                    if (nbr->IsInRing())
                      ringNbrs++;
                  }
		
                // if this atom has more than 2 neighbor ring atoms
                // we could get trapped later when traversing cycles
                // which can cause aromaticity false detection
                newRoot = -1;
		
                if (ringNbrs > 2)
                  {
                    // try to find another root atom
                    // only loop over rings which contain rootAtom
                    for(k = ringAtoms[rootAtom].begin() ; k != ringAtoms[rootAtom].end(); ++k)
                      {
                        ring = (*k);
                        tmp = ring->_path;
			
                        bool checkThisRing = false;
                        int rootAtomNumber=0;
                        int idx=0;
                        // avoiding two root atoms in one ring !
                        for (unsigned int j = 0; j < tmpRootAtoms.size(); ++j)
                          {
                            idx= tmpRootAtoms[j];
                            if(ring->IsInRing(idx))
                              {
                                rootAtomNumber++;
                                if(rootAtomNumber>=2)
                                  break;
                              }
                          }
                        if(rootAtomNumber<2)
                          {
                            for (unsigned int j = 0; j < tmp.size(); ++j)
                              {
                                // find critical ring
                                if (tmp[j] == rootAtom)
                                  {
                                    checkThisRing = true;
                                  }
                                else
                                  {
                                    // second root atom in this ring ?
                                    if (_root[tmp[j]] == true)
                                      {
                                        // when there is a second root
                                        // atom this ring can not be
                                        // used for getting an other
                                        // root atom
                                        checkThisRing = false;
					
                                        break;
                                      }
                                  }
                              }
                          }
			
                        // check ring for getting another
                        // root atom to avoid aromaticity typer problems
                        if (checkThisRing)
                          {
                            // check if we can find another root atom
                            for (unsigned int m = 0; m < tmp.size(); ++m)
                              {
                                ringNbrs = heavyNbrs = 0;
                                for (nbr2 = (mol.GetAtom(tmp[m]))->BeginNbrAtom(nbr2Iter);
                                     nbr2;nbr2 = (mol.GetAtom(tmp[m]))->NextNbrAtom(nbr2Iter))
                                  {
                                    if (!nbr2->IsHydrogen())
                                      {
                                        heavyNbrs++;
					
                                        if (nbr2->IsInRing())
                                          ringNbrs++;
                                      }
                                  }
				
                                // if the number of neighboured heavy atoms is also
                                // the number of neighboured ring atoms, the aromaticity
                                // typer could be stuck in a local traversing trap
                                if (ringNbrs <= 2 && ring->IsInRing((mol.GetAtom(tmp[m])->GetIdx())))
                                  {
                                    newRoot = tmp[m];
                                  }
                              }
                          }
                      }
		    
                    if ((newRoot != -1) && (rootAtom != newRoot))
                      {
                        // unset root atom
                        _root[rootAtom] = false;
			
                        // pick new root atom
                        _root[newRoot] = true;
                      }
                  } // if (ringNbrs > 2)
		
              } // end for
          } // if (avoid)
      } // end for(closure bonds)
  }