Logo Search packages:      
Sourcecode: ball version File versions

smartsParser.C

// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: smartsParser.C,v 1.13.8.3 2007/04/17 16:13:32 bertsch Exp $
//

#include <BALL/STRUCTURE/smartsParser.h>
#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/PTE.h>

#include <stack>

// defined in the lexer (smartsParserLexer.l)
extern void SmartsParser_initBuffer(const char* buf);
extern void SmartsParser_delBuffer();
extern int SmartsParserparse();

using namespace std;

namespace BALL
{
      // Implementation SPNode
00024       SmartsParser::SPNode::SPNode()
            :     internal_(false),
                  is_not_(false),
                  recursive_(false),
                  log_op_(SmartsParser::NOOP),
                  first_edge_((SPEdge*)0),
                  second_edge_((SPEdge*)0),
                  sp_atom_((SPAtom*)0),
                  component_no_(-1)
      {
      }

00036       SmartsParser::SPNode::SPNode(SPAtom* atom)
            :     internal_(false),
                  is_not_(false),
                  recursive_(false),
                  log_op_(SmartsParser::NOOP),
                  first_edge_((SPEdge*)0),
                  second_edge_((SPEdge*)0),
                  sp_atom_(atom),
                  component_no_(-1)
      {
      }

00048       SmartsParser::SPNode::SPNode(SPNode* first, LogicalOperator log_op, SPNode* second)
            :     internal_(true),
                  is_not_(false),
                  recursive_(false),
                  log_op_(log_op),
                  first_edge_(new SmartsParser::SPEdge()),
                  second_edge_(new SmartsParser::SPEdge()),
                  sp_atom_((SPAtom*)0),
                  component_no_(-1)
      {
            first_edge_->setFirstSPNode(this);
            first_edge_->setSecondSPNode(first);
            first_edge_->setInternal(true);
            second_edge_->setFirstSPNode(this);
            second_edge_->setSecondSPNode(second);
            second_edge_->setInternal(true);
      }

00066       SmartsParser::SPNode::~SPNode()
      {
            if (first_edge_)
                  delete (first_edge_);
            if (second_edge_)
            delete (second_edge_);
      }

00074       void SmartsParser::SPNode::setRecursive(bool recursive)
      {
            for (EdgeIterator it = begin(); it != end(); ++it)
            {
                  SmartsParser::state.current_parser->addRecursiveEdge(*it);
            }
            recursive_ = recursive;
      }

      // Implementation SPEdge
00084       SmartsParser::SPEdge::SPEdge()
            :     internal_(false),
                  is_not_(false),
                  first_((SmartsParser::SPNode*)0),
                  second_((SmartsParser::SPNode*)0),
                  bond_((SmartsParser::SPBond*)0),
                  first_edge_((SmartsParser::SPEdge*)0),
                  second_edge_((SmartsParser::SPEdge*)0),
                  log_op_(SmartsParser::NOOP)
      {
      }

00096       SmartsParser::SPEdge::~SPEdge()
      {
      }

00100       SmartsParser::SPBond::SPBond()
            :     ze_type_(SmartsParser::NONE),
                  bond_order_(SmartsParser::SPBond::ANY),
                  not_(false)
      {
      }

      bool SmartsParser::SPBond::equals(const Bond* bond) const
      {
            // TODO - Z/E isomer types
            bool matches(false);
            switch (bond_order_)
            {
                  case SINGLE:      
                        if (bond->getOrder() == Bond::ORDER__SINGLE)
                        {
                              matches = true;
                        }
                        break;
                  case SINGLE_UP:
                        if (bond->getOrder() == Bond::ORDER__SINGLE)
                        {
                              matches = true;
                              Log.error() << "SmartsParser: chiral bond definitions are not implemented yet" << endl;
                        }
                        break;
                  case SINGLE_UP_OR_ANY:
                        if (bond->getOrder() == Bond::ORDER__SINGLE)
                        {
                              matches = true;
                              Log.error() << "SmartsParser: chiral bond definitions are not implemented yet" << endl;
                        }
                        break;
                  case SINGLE_DOWN:
                        if (bond->getOrder() == Bond::ORDER__SINGLE)
                        {
                              matches = true;
                              Log.error() << "SmartsParser: chiral bond definitions are not implemented yet" << endl;
                        }
                        break;
                  case SINGLE_DOWN_OR_ANY:
                        if (bond->getOrder() == Bond::ORDER__SINGLE)
                        {
                              matches = true;
                              Log.error() << "SmartsParser: chiral bond definitions are not implemented yet" << endl;
                        }
                        break;
                  case SINGLE_OR_AROMATIC:
                        if (bond->getOrder() == Bond::ORDER__SINGLE || bond->isAromatic())
                        {
                              matches = true;
                        }
                        break;
                  case DOUBLE:
                        if (bond->getOrder() == Bond::ORDER__DOUBLE)
                        {
                              matches = true;
                        }
                        break;
                  case TRIPLE:
                        if (bond->getOrder() == Bond::ORDER__TRIPLE)
                        {
                              matches = true;
                        }
                        break;
                  case AROMATIC: 
                        if (bond->isAromatic())
                        {
                              matches = true;
                        }
                        break;
                  case ANY:
                        matches = true;
                        break;
                  case NOT_NECESSARILY_CONNECTED:
                        matches = true;
                        break;
                  case IN_RING:
                        if (bond->getProperty("InRing").getBool())
                        {
                              matches = true;
                        }
                        break;
                  default:
                        Log.error() << "SmartsParser: unknown or not implemented bond order: " << bond_order_ << endl;
            }
            
            return not_ ? !matches : matches;
      }

      // Implementation of SPAtom
00191       SmartsParser::SPAtom::SPAtom()
      {
      }

00195       SmartsParser::SPAtom::SPAtom(const String& symbol)
      {
            String s(symbol);
            if (symbol.isDigit())
            {
                  s = PTE[symbol.toUnsignedInt()].getSymbol();
            }
            else
            {
                  if (islower(symbol[0]))
                  {
                        s.toUpper(0, 1);
                        setProperty(AROMATIC, true);
                  }
                  else
                  {
                        setProperty(ALIPHATIC, true);
                  }
            }
            setProperty(SYMBOL, &PTE[s]);
      }
      
00217       SmartsParser::SPAtom::~SPAtom()
            
      {
      }
      
00222       Size SmartsParser::SPAtom::getDefaultValence(const Atom* atom) const
      {
            Size an(0);
            an = atom->getElement().getAtomicNumber();
                  
            switch (an)
            {
                  case  1: return 1; // hydrogen
                  case  5: return 3; // boron
                  case  6: return 4; // carbon
                  case  7: return 3; // nitrogen
                  case  8: return 2; // oxygen
                  case 14: return 4; // silicon
                  case 15: return 3; // phosphorus
                  case 16: return 2; // sulfur
                  case  9:
                  case 17:
                  case 35:
                  case 53: return 1; // halogens
                  default:
                        Log.error() << "SmartsParmer: default valence not defined of element with atomic number" << an << endl;
                        break;
            };
            return 0;
      }

00248       Size SmartsParser::SPAtom::countRealValences(const Atom* atom) const
      {
            double count(0);
            for (Atom::BondConstIterator bit = atom->beginBond(); +bit; ++bit)
            {
                  // NOTE: we test the aromatic case first, since the bond might have
                  //       single or double order, but the property IS_AROMATIC and
                  //       we cannot handle this through the switch() below
                  if (bit->isAromatic())
                        count += 1.5;
                  else
                  {
                        switch(bit->getOrder())
                        {
                              case Bond::ORDER__SINGLE:           
                                    count += 1; 
                                    break;
                              case Bond::ORDER__DOUBLE:           
                                    count += 2;
                                    break;
                              case Bond::ORDER__TRIPLE:           
                                    count += 3;
                                    break;
                              default:
                                    Log.error() << "SmartsParser: errorneous bond order (" << bit->getOrder() << ")" << endl;
                        }
                  }
            }
            return Size(count);
      }

00279       Size SmartsParser::SPAtom::getNumberOfImplicitHydrogens(const Atom* atom) const
      {
            // TODO charges?
            int defaultValence = getDefaultValence(atom);
            int countedValence = countRealValences(atom);

            if (countedValence > defaultValence)
                  return 0;
            else
             return defaultValence - countedValence;
      }

00291       bool SmartsParser::SPAtom::equals(const Atom * atom) const
      {
            int tmp(0);
            bool bool_tmp(false);
            vector<int> ring_sizes;

            for (map<PropertyType, PropertyValue>::const_iterator it = properties_.begin(); it != properties_.end(); ++it)
            {
                  switch (it->first)
                  {
                        case SYMBOL:
                              if (atom->getElement() != *it->second.element_value)
                              {
                                    if (not_properties_.find(SYMBOL) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(SYMBOL) != not_properties_.end())
                                    {
                                          return false;
                                    }                                   
                              }
                              break;

                        case ISOTOPE:
                              Log.error() << "SmartsParser: isotope not implemented, ignoring" << endl;
                              break;
                              
                        case CHARGE:
                              if (atom->getFormalCharge() != it->second.int_value)
                              {
                                    if (not_properties_.find(CHARGE) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(CHARGE) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case AROMATIC:
                              if (atom->getProperty("IsAromatic").getBool())
                              {
                                    if (not_properties_.find(AROMATIC) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(AROMATIC) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case ALIPHATIC:
                              if (atom->getProperty("IsAromatic").getBool())
                              {
                                    if (not_properties_.find(ALIPHATIC) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(ALIPHATIC) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case IN_NUM_RINGS:
                              tmp = 0;
                              for (vector<std::set<const Atom*> >::const_iterator it1 = SmartsParser::sssr_->begin(); it1 != SmartsParser::sssr_->end(); ++it1)
                              {
                                    if (it1->find(atom) != it1->end())
                                    {
                                          ++tmp;
                                    }
                              }
                              bool_tmp = not_properties_.find(IN_NUM_RINGS) != not_properties_.end();
                              if (it->second.int_value == 999)
                              {
                                    if ((tmp == 0 && !bool_tmp) ||
                                                (tmp != 0 && bool_tmp))
                                    {
                                          return false;                                         
                                    }
                              }
                              else
                              {
                                    if ((tmp == it->second.int_value && bool_tmp) ||
                                                (tmp != it->second.int_value && !bool_tmp))
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case IN_RING_SIZE:
                              if (!atom->getProperty("InRing").getBool())
                              {
                                    return false;
                              }
                              ring_sizes.clear();
                              for (vector<std::set<const Atom*> >::const_iterator it1 = SmartsParser::sssr_->begin(); it1 != SmartsParser::sssr_->end(); ++it1)
                              {
                                    if (it1->find(atom) != it1->end())
                                    {
                                          ring_sizes.push_back(it1->size());
                                    }
                              }
                              if (find(ring_sizes.begin(), ring_sizes.end(), it->second.int_value) != ring_sizes.end())
                              {
                                    if (not_properties_.find(IN_RING_SIZE) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(IN_RING_SIZE) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              
                              break;
                              
                        case CONNECTED:
                              if ((int)(atom->countBonds() + getNumberOfImplicitHydrogens(atom)) != it->second.int_value)
                              {
                                    if (not_properties_.find(CONNECTED) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(CONNECTED) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case EXPLICIT_HYDROGENS:
                              tmp = 0;
                              for (Atom::BondConstIterator bit = atom->beginBond(); +bit; ++bit)
                              {
                                    if (bit->getPartner(*atom)->getElement() == PTE[Element::H])
                                    {
                                          ++tmp;
                                    }
                              }
                              
                              if (tmp == it->second.int_value)
                              {
                                    if (not_properties_.find(EXPLICIT_HYDROGENS) != not_properties_.end())
                                    {
                                          return false;
                                    }                                         
                              }
                              else
                              {
                                    if (not_properties_.find(EXPLICIT_HYDROGENS) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case VALENCE:
                              if ((int)countRealValences(atom) != it->second.int_value)
                              {
                                    if (not_properties_.find(VALENCE) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(VALENCE) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case IMPLICIT_HYDROGENS:
                              if ((int)getNumberOfImplicitHydrogens(atom) == it->second.int_value)
                              {
                                    if (not_properties_.find(IMPLICIT_HYDROGENS) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(IMPLICIT_HYDROGENS) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case DEGREE:
                              if ((int)(atom->countBonds()) != it->second.int_value)
                              {
                                    if (not_properties_.find(DEGREE) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(DEGREE) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case RING_CONNECTED:
                              tmp = 0;
                              for (Atom::BondConstIterator it1 = atom->beginBond(); +it1; ++it1)
                              {
                                    if (it1->getProperty("InRing").getBool())
                                    {
                                          ++tmp;
                                    }
                              }
                              if (tmp == it->second.int_value)
                              {
                                    if (not_properties_.find(RING_CONNECTED) != not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              else
                              {
                                    if (not_properties_.find(RING_CONNECTED) == not_properties_.end())
                                    {
                                          return false;
                                    }
                              }
                              break;
                              
                        case CHIRALITY:
                              Log.error() << "SmartsParser: chirality option not implemented yet" << endl;
                              return false;
                              break;
                              
                        default:
                              Log.error() << "SmartsParser: know nothing about '" << it->first << "'" << endl;
                              break;
                  }

            }
                  
            return true;
      }

00565       void SmartsParser::SPAtom::setProperty(PropertyType type, int value)
      {
            PropertyValue p;
            p.int_value = value;
            properties_[type] = p;
      }

00572       void SmartsParser::SPAtom::setProperty(PropertyType type, bool value)
      {
            PropertyValue p;
            p.bool_value = value;
            properties_[type] = p;
      }

00579       void SmartsParser::SPAtom::setProperty(PropertyType type, const Element* value)
      {
            PropertyValue p;
            p.element_value = value;
            properties_[type] = p;
      }

00586       void SmartsParser::SPAtom::setProperty(PropertyType type, ChiralClass value)
      {
            PropertyValue p;
            p.chiral_class_value = value;
            properties_[type] = p;
      }

00593       void SmartsParser::SPAtom::setProperty(Property p)
      {
            properties_[p.getType()] = p.getValue();
      }

00598       void SmartsParser::SPAtom::addPropertiesFromSPAtom(SPAtom* atom)
      {
            for (map<PropertyType, PropertyValue>::const_iterator it = atom->properties_.begin(); it != atom->properties_.end(); ++it)
            {
                  properties_[it->first] = it->second;
            }
      }

00606       void SmartsParser::SPAtom::setNotProperty(PropertyType type)
      {
            not_properties_.insert(type);
      }

00611       bool SmartsParser::SPAtom::hasProperty(PropertyType type) const
      {
            return properties_.find(type) != properties_.end();
      }

00616       SmartsParser::SPAtom::PropertyValue SmartsParser::SPAtom::getProperty(PropertyType type)
      {
            return properties_[type];
      }

00621       Size SmartsParser::SPAtom::countProperties() const
      {
            return properties_.size();
      }

00626       SmartsParser::SPAtom::Property::Property(PropertyType type, int value)
      {
            type_ = type;
            value_.int_value = value;
      }

00632       SmartsParser::SPAtom::Property::Property(PropertyType type, bool value)
      {
            type_ = type;
            value_.bool_value = value;
      }

00638       SmartsParser::SPAtom::Property::Property(PropertyType type, const Element* value)
      {
            type_ = type;
            value_.element_value = value;
      }

00644       SmartsParser::SPAtom::Property::Property(PropertyType type, ChiralClass value)
      {
            type_ = type;
            value_.chiral_class_value = value;
      }

00650       SmartsParser::SPAtom::Property::~Property()
      {
      }

00654       void SmartsParser::SPAtom::Property::operator = (const Property& property)
      {
            type_ = property.type_;
            value_ = property.value_;
      }

      
      
      // Implementation SmartsParser
00663       SmartsParser::SmartsParser()
            :     needs_SSSR_(false),
                  recursive_(false),
                  component_grouping_(false),
                  root_((SPNode*)0)
      {
      }

00671       SmartsParser::SmartsParser(const SmartsParser& parser)
            :     needs_SSSR_(parser.needs_SSSR_),
                  recursive_(parser.recursive_),
                  component_grouping_(parser.component_grouping_),
                  root_(parser.root_)
      {
            // TODO new states!
      }

00680       SmartsParser::~SmartsParser()
      {
            clear();
      }

00685       void SmartsParser::clear()
      {
            // delete all SPNodes
            for (set<SPNode*>::iterator it = nodes_.begin(); it != nodes_.end(); ++it)
            {
                  if (!(*it)->isInternal())
                  {
                        SPAtom* a = (*it)->getSPAtom();
                        if (a != 0)
                        {
                              delete a;
                        }
                  }
                  delete *it;
            }
            nodes_.clear();

            // delete all SPEdges
            for (set<SPEdge*>::iterator it = edges_.begin(); it != edges_.end(); ++it)
            {
                  if (!(*it)->isInternal())
                  {
                        SPBond* b = (*it)->getSPBond();
                        if (b != 0)
                        {
                              delete b;
                        }
                  }
                  delete *it;
            }
            edges_.clear();

            ring_connections_.clear();
            root_ = 0;
            if (sssr_ != 0)
            {
                  sssr_->clear();
                  sssr_ = 0;
            }
            needs_SSSR_ = false;
            recursive_ = false;
            component_grouping_ = false;
            component_no_ = 0;
            rec_edges_.clear();
      }

00731       void SmartsParser::parse(const String& s)
            throw(Exception::ParseError)
      {
            // clear out stuff from previous run
            clear();

            // make the internals of this parser available for all
            state.current_parser = this;
            state.buffer = s.c_str();
            state.char_count = 0;
            
            try
            {
                  SmartsParser_initBuffer(state.buffer);
                  SmartsParserparse();
                  SmartsParser_delBuffer();     
            }
            catch (Exception::ParseError& e)
            {
                  // Clean up the parser buffer.
                  SmartsParser_delBuffer();

                  // Clean up allocated memory (atoms).
                  clear();

                  // Propagate the parse error upwards.
                  throw e;
            }
      }
      
00761       void SmartsParser::addRingConnection(SPNode* spnode, Size index)
      {
            ring_connections_[index].push_back(spnode);
      }

00766       map<Size, vector<SmartsParser::SPNode*> > SmartsParser::getRingConnections() const
      {
            return ring_connections_;
      }

      void SmartsParser::setSSSR(const vector<vector<Atom*> >& new_sssr)
      {
            static vector<set<const Atom*> > sssr;
            sssr.clear();
            for (vector<vector<Atom*> >::const_iterator it1 = new_sssr.begin(); it1 != new_sssr.end(); ++it1)
            {
                  set<const Atom*> ring;
                  for (vector<Atom*>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2)
                  {
                        ring.insert(*it2);
                  }
                  sssr.push_back(ring);
            }
            sssr_ = &sssr;
      }


00788       SmartsParser::SPBond::SPBond(SPBondOrder order)
            :     ze_type_(SmartsParser::NONE),
                  bond_order_(order),
                  not_(false)
      {
      }

00795       SmartsParser::SPBond::~SPBond()
            
      {
      }

      struct SmartsParser::State SmartsParser::state;
      vector<set<const Atom*> >* SmartsParser::sssr_ = 0;
      
00803       void SmartsParser::dumpTree()
      {
            cerr << "The current tree is: " << endl;
            bool consider_as_noninternal(false);
            if (root_->isInternal())
            {
                  cerr << "root is internal: " << endl;
                  dumpTreeRecursive_(root_->getFirstEdge(), 1);
                  if (root_->getLogicalOperator() == AND_LOW) cerr << "AND_LOW" << endl;
                  if (root_->getLogicalOperator() == AND) cerr << "AND" << endl;
                  if (root_->getLogicalOperator() == OR) cerr << "OR" << endl;
                  dumpTreeRecursive_(root_->getSecondEdge(), 1);
                  if (root_->countEdges() != 0)
                  {
                        consider_as_noninternal = true;
                  }
            }
            
            if (!root_->isInternal() || consider_as_noninternal)
            {
                  if (!consider_as_noninternal)
                  {
                        cerr << "root (#properties=" << root_->getSPAtom()->countProperties();
                        if (root_->getSPAtom()->hasProperty(SPAtom::SYMBOL))
                        {
                              cerr << ", Symbol=" << root_->getSPAtom()->getProperty(SPAtom::SYMBOL).element_value->getSymbol();
                        }           
                        cerr << ")" << endl;
                  }
                  Size count(1);
                  for (SPNode::EdgeIterator eit = root_->begin(); eit != root_->end(); ++eit, ++count)
                  {
                        cerr << count << "."<< endl;
                        dumpTreeRecursive_(*eit, 1);
                  }
            }
            cerr << endl;
      }

00842       void SmartsParser::dumpTreeRecursive_(SPNode* node, Size depth)
      {
            bool consider_as_noninternal(false);
            if (node->isInternal())
            {
                  cerr << String('\t', depth) << "node (internal): " << node << "[recursive=" << node->isRecursive() << "]" << endl;
                  dumpTreeRecursive_(node->getFirstEdge(), depth + 1);
                  if (node->getLogicalOperator() == AND_LOW) cerr << String('\t', depth) << "AND_LOW" << endl;
                  if (node->getLogicalOperator() == AND) cerr << String('\t', depth) << "AND" << endl;
                  if (node->getLogicalOperator() == OR) cerr << String('\t', depth) << "OR" << endl;
                  dumpTreeRecursive_(node->getSecondEdge(), depth + 1);
                  if (node->countEdges() != 0)
                  {
                        consider_as_noninternal = true;
                  }
            }
            
            if (!node->isInternal() || consider_as_noninternal)
            {
                  if (!consider_as_noninternal)
                  {
                        cerr << String('\t', depth) << "node (#properties=" << node->getSPAtom()->countProperties();
                        if (node->getSPAtom()->hasProperty(SPAtom::SYMBOL))
                        {
                              cerr << ", Symbol=" << node->getSPAtom()->getProperty(SPAtom::SYMBOL).element_value->getSymbol();
                        }
                        cerr << ") " << node << "[recursive=" << node->isRecursive() << "]" << endl;
                  }
                  Size count(1);
                  for (SPNode::EdgeIterator eit = node->begin(); eit != node->end(); ++eit, ++count)
                  {
                        cerr << String('\t', depth) << count << "." << endl;
                        dumpTreeRecursive_(*eit, depth + 1);
                  }
            }
      }

00879       void SmartsParser::dumpTreeRecursive_(SPEdge* edge, Size depth)
      {
            if (edge->isInternal() && edge->getSecondSPEdge() != 0)
            {
                  cerr << String('\t', depth) << "edge (internal): " << edge << endl;
                  dumpTreeRecursive_(edge->getFirstSPEdge(), depth + 1);
                  if (edge->getLogicalOperator() == AND_LOW) cerr << String('\t', depth) << "AND_LOW" << endl;
                  if (edge->getLogicalOperator() == AND) cerr << String('\t', depth) << "AND" << endl;
                  if (edge->getLogicalOperator() == OR) cerr << String('\t', depth) << "OR" << endl;
                  dumpTreeRecursive_(edge->getSecondSPEdge(), depth + 1);
                  if (edge->getSecondSPNode() != 0)
                  {
                        dumpTreeRecursive_(edge->getSecondSPNode(), depth + 1);
                  }
            }
            else
            {
                  cerr << String('\t', depth) << "edge ";
                  if (edge->getSPBond() != 0)
                  {
                        cerr << "(bond order: " << edge->getSPBond()->getBondOrder() << ", not=" << edge->getSPBond()->isNot() << ") " << edge << endl;
                  }
                  else
                  {
                        cerr << endl;
                  }

                  if (edge->getSecondSPNode() != 0)
                  {
                        dumpTreeRecursive_(edge->getSecondSPNode(), depth + 1);
                  }
            }
      }

00913       void SmartsParser::setNextComponentNumberToSubTree(SPNode* spnode)
      {
            component_no_++;
            stack<SPNode*> nodes;
            nodes.push(spnode);
            while (nodes.size() != 0)
            {
                  SPNode* node = nodes.top();
                  node->setComponentNumber(component_no_);
                  nodes.pop();
                  if (node->getFirstEdge() != 0 && node->getFirstEdge()->getSecondSPNode() != 0)
                  {
                        nodes.push(node->getFirstEdge()->getSecondSPNode());
                  }
                  if (node->getSecondEdge() != 0 && node->getSecondEdge()->getSecondSPNode() != 0)
                  {
                        nodes.push(node->getSecondEdge()->getSecondSPNode());
                  }
                  for (SPNode::EdgeIterator it = node->begin(); it != node->end(); ++it)
                  {
                        nodes.push((*it)->getSecondSPNode());
                  }
            }
      }
      
} // namespace BALL


Generated by  Doxygen 1.6.0   Back to index