Beispiel #1
0
void testTetrahedralStereo1()
{
  cout << "testTetrahedralStereo1()" << endl;
  // read a smiles string
  OBMol mol;
  OBConversion conv;
  OB_REQUIRE( conv.SetInFormat("smi") );
  cout << "smiles: C[C@H](O)N" << endl;
  OB_REQUIRE( conv.ReadString(&mol, "C[C@H](O)N") );

  // get the stereo data
  OB_REQUIRE( mol.HasData(OBGenericDataType::StereoData) );
  std::vector<OBGenericData *> stereoData = mol.GetAllData(OBGenericDataType::StereoData);
  OB_REQUIRE( stereoData.size() == 1 );

  // convert to tetrahedral data
  OB_REQUIRE( ((OBStereoBase*)stereoData[0])->GetType() == OBStereo::Tetrahedral );
  OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(stereoData[0]);
  OB_REQUIRE( ts );

  // print the configuration
  cout << *ts << endl;

  // construct a valid configuration here
  //
  // C[C@H](O)N
  // 0 1 2  3 4  <- ids
  //
  OBTetrahedralStereo::Config cfg(1, 0, OBStereo::MakeRefs(4, 3, 2), OBStereo::Clockwise);

  // compare stereochemistry
  OB_REQUIRE( ts->GetConfig() == cfg );

  cout << endl;
}
Beispiel #2
0
void testIsomorphism1()
{
  OBMol mol;
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.ReadString(&mol, "CC1CCC(C)CC1");

  OBQuery *query = CompileMoleculeQuery(&mol);
  OBIsomorphismMapper *mapper = OBIsomorphismMapper::GetInstance(query);
  OBIsomorphismMapper::Mappings maps;
  mapper->MapAll(&mol, maps);

  OB_ASSERT( maps.size() == 4 );

  delete query;
  delete mapper;

  query = CompileSmilesQuery("C1(C)CCC(C)CC1");
  mapper = OBIsomorphismMapper::GetInstance(query);

  OBIsomorphismMapper::Mapping map;
  mapper->MapFirst(&mol, map);
  OB_ASSERT( map.size() == 8 );

  mapper->MapUnique(&mol, maps);
  OB_ASSERT( maps.size() == 1 );

  mapper->MapAll(&mol, maps);
  OB_ASSERT( maps.size() == 4 );

  delete query;
  delete mapper;
}
Beispiel #3
0
void CheckValidDipeptide(OBConversion &conv,
                         const string &test,
                         unsigned int testCount)
{
  OBMol mol;
  OBResidue *res;
  ostringstream os;

  mol.Clear();
  conv.ReadString(&mol, test);
  chainsparser.PerceiveChains(mol);
  if (mol.NumResidues() != 2) {
    os << "not ok " << testCount << " # expected 2 residues, but found "
         << mol.NumResidues() << '\n';
    os << "# ";
    FOR_RESIDUES_OF_MOL(res, mol)
      os << res->GetName() << " ";
    os << endl;
    BOOST_CHECK_MESSAGE( 0, os.str().c_str() );
  } else {
    res = mol.GetResidue(0);
    BOOST_CHECK_MESSAGE( res, "Get first AA from dipeptide" );
    res = mol.GetResidue(1);
    BOOST_CHECK_MESSAGE( res, "Get second AA from dipeptide" );
  }
}
// Delete hydrogens should not remove charged or isotopic hydrogens or [H][H] or [Cu][H][Cu]
// or hydrogens with assigned atom classes
void test_Issue178_DeleteHydrogens()
{
  OBConversion conv;
  conv.SetInFormat("smi");
  OBMol mol;
  // Test DeleteHydrogens() and DeleteNonPolarHydrogens()
  static const char *smi[] = { "C[H]", "[H][H]", "C[1H]", "C[H]C", "C[H+]" };
  int numHs[] = { 0, 2, 1, 1, 1 };
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 2; ++j) {
      conv.ReadString(&mol, smi[i]);
      if (j == 0)
        mol.DeleteHydrogens();
      else
        mol.DeleteNonPolarHydrogens();
      int myNumHs = 0;
      FOR_ATOMS_OF_MOL(atom, mol)
        if (atom->IsHydrogen())
          myNumHs++;
      OB_COMPARE(myNumHs, numHs[i]);
    }
  }
  // Test DeletePolarHydrogens()
  static const char *smiB[] = { "N[H]", "[H][H]", "N[1H]", "N[H]C", "N[H+]" };
  int numHsB[] = { 0, 2, 1, 1, 1 };
  for (int i = 0; i < 5; ++i) {
    conv.ReadString(&mol, smiB[i]);
    mol.DeletePolarHydrogens();
    int myNumHs = 0;
    FOR_ATOMS_OF_MOL(atom, mol)
      if (atom->IsHydrogen())
        myNumHs++;
    OB_COMPARE(myNumHs, numHsB[i]);
  }
  // Test atom class
  // Currently, the SMILES parser does not retain atom classes for hydrogens on reading so...
  conv.ReadString(&mol, "C[H]");
  OBAtomClassData *ac = new OBAtomClassData;
  ac->Add(2, 99); // Assign the hydrogen (atom 2) a class of 99
  mol.SetData(ac);
  mol.DeleteHydrogens();
  int myNumHs = 0;
  FOR_ATOMS_OF_MOL(atom, mol)
    if (atom->IsHydrogen())
      myNumHs++;
  OB_COMPARE(myNumHs, 1);
}
// Reading an InChI and then adding hydrogens messed up the structure
void test_Issue134_InChI_addH()
{
  OBConversion conv;
  conv.SetInFormat("inchi");
  OBMol mol;
  conv.ReadString(&mol, "InChI=1S/C2H7NO/c1-2(3)4/h2,4H,3H2,1H3/t2-/m0/s1");
  OB_ASSERT(!mol.HasData(OBGenericDataType::VirtualBondData));
  mol.AddHydrogens();
  conv.SetOutFormat("smi");
  std::string res = conv.WriteString(&mol, true);
  OB_COMPARE(res, "C[C@@H](N)O");
}
Beispiel #6
0
void testAutomorphismPreMapping()
{
  cout <<  "testAutomorphismPreMapping" << endl;
  OBMol mol;
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.ReadString(&mol, "c1(C)c(C)c(C)c(C)c(C)c1");

  Automorphisms aut;
  FindAutomorphisms((OBMol*)&mol, aut);
  cout << aut.size() << endl;
  OB_ASSERT( aut.size() == 2 );
}
// A segfault was occuring when a Universal SMILES was output after an InChIfied SMILES.
// This was due to short-circuit caching of InChIs on reading. The fix was to limit
// the situations when the cached value was used, but also to delete the cached value
// in this particular instance.
void test_Issue135_UniversalSmiles()
{
  // Test writing U smiles after I smiles
  OBConversion conv;
  conv.SetInFormat("smi");
  OBMol mol;
  conv.ReadString(&mol, "C(=O)([O-])C(=O)O");
  conv.SetOutFormat("smi");
  conv.SetOptions("I", OBConversion::OUTOPTIONS);
  std::string res = conv.WriteString(&mol, true);
  OB_COMPARE(res, "C(=O)(C(=O)O)[O-]");
  conv.SetOptions("U", OBConversion::OUTOPTIONS);
  res = conv.WriteString(&mol, true);
  OB_COMPARE(res, "C(=O)(C(=O)[O-])O");
}
int main(int argc, char **argv)
{
  // Define location of file formats for testing
#ifdef FORMATDIR
    char env[BUFF_SIZE];
    snprintf(env, BUFF_SIZE, "BABEL_LIBDIR=%s", FORMATDIR);
    putenv(env);
#endif  

  std::ifstream ifs(GetFilename("canonstable.can").c_str());
  OB_REQUIRE( ifs );


  OBMol mol;
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.SetOutFormat("can");

  std::string line;
  while (std::getline(ifs, line)) {
    OB_REQUIRE( conv.ReadString(&mol, line.c_str()) );

    std::vector<OBAtom*> atoms;
    FOR_ATOMS_OF_MOL(atom, mol)
      atoms.push_back(&*atom);

    for (int i = 0; i < 5; ++i) {
      // shuffle the atoms
      std::random_shuffle(atoms.begin(), atoms.end());
      mol.RenumberAtoms(atoms);

      // get can smiles
      mol.SetTitle("");
      std::string cansmi = conv.WriteString(&mol, true);
      // comapare with ref
      if (cansmi != line) {
        cout << "ref = " << line << endl;
        cout << "can = " << cansmi << endl;
        OB_ASSERT( cansmi == line );
      }
    }
  }
 
  return 0;
}
Beispiel #9
0
void testIsomorphism4()
{
  cout << "testIsomorphism4" << endl;
  OBMol mol;
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.ReadString(&mol, "C12C(C2)C1");

  OBQuery *query = CompileSmilesQuery("C1CC1");
  OBIsomorphismMapper *mapper = OBIsomorphismMapper::GetInstance(query);
  OBIsomorphismMapper::Mappings maps;
  mapper->MapUnique(&mol, maps);

  cout << maps.size() << endl;

  OB_ASSERT( maps.size() == 2 );

  delete query;
  delete mapper;
}
int main()
{
  // Create an OBConversion object.
  OBConversion conv;
  // Set the input format.
  if (!conv.SetInFormat("smi")) {
    // Handle error.
    return 1;
  }

  // Create the OBMol object.
  OBMol mol;

  // Read the smiles string.
  if (conv.ReadString(&mol, "CCCC")) {
    // Handle error.
    return 1;
  }

  // ...Use OBMol object...
}
Beispiel #11
0
void CheckInvalidResidue(OBConversion &conv,
                         const string &test,
                         unsigned int testCount)
{
  OBMol mol;
  
  mol.Clear();
  conv.ReadString(&mol, test);
  chainsparser.PerceiveChains(mol);
  if (mol.NumResidues() != 0) {
    OBResidue *res = mol.GetResidue(0);
    if (res->GetName() == "LIG") { // ligand, not residue
      cout << "ok " << testCount << " # found ligand, not residue "
           << test << '\n';
    } else {
      cout << "not ok " << testCount << " # expected 0 residues, found "
           << mol.NumResidues() << '\n';
      cout << "# " << res->GetName() << endl;
    }
  } else
    cout << "ok " << testCount << " # correctly rejected " << test << '\n';
}
Beispiel #12
0
bool OBReader::readSmiString(QString smiString)
{
    using namespace OpenBabel;

    OBConversion conv;

    if (!conv.SetInFormat("smi"))
    {
        qDebug() << "Error in conv.SetInFormat().";
        return false;
    }

    OBMol obMol;

    if (!conv.ReadString(&obMol, smiString.toStdString()))
    {
        qDebug() << "Error occured while reading the smi string.";
        return false;
    }

    if (!obMol.Has3D())
    {
        if (!buildGeometry(&obMol))
        {
            qDebug() << "Error in buildGeometry()";
            return false;
        }
    }

    if (!toMolecule(&obMol))
    {
        qDebug() << "Could not convert OBMol to Molecule.";
        return false;
    }


    return true;
}
Beispiel #13
0
void CheckInvalidResidue(OBConversion &conv,
                         const string &test,
                         unsigned int testCount)
{
  OBMol mol;
  ostringstream os;
  
  mol.Clear();
  conv.ReadString(&mol, test);
  chainsparser.PerceiveChains(mol);
  if (mol.NumResidues() != 0) {
    OBResidue *res = mol.GetResidue(0);
    if (res->GetName() == "LIG") { // ligand, not residue
      BOOST_CHECK( 1 );
    } else {
      os << "not ok " << testCount << " # expected 0 residues, found "
           << mol.NumResidues() << '\n';
      os << "# " << res->GetName() << endl;
      BOOST_CHECK_MESSAGE( 0, os.str().c_str() );
    }
  } else
    BOOST_CHECK( 1 );
}
Beispiel #14
0
void CheckValidDipeptide(OBConversion &conv,
                         const string &test,
                         unsigned int testCount)
{
  OBMol mol;

  mol.Clear();
  conv.ReadString(&mol, test);
  chainsparser.PerceiveChains(mol);
  if (mol.NumResidues() != 2) {
    cout << "not ok " << testCount << " # expected 2 residues, but found "
         << mol.NumResidues() << '\n';
    cout << "# ";
    FOR_RESIDUES_OF_MOL(res, mol)
      cout << res->GetName() << " ";
    cout << endl;
  } else {
    OBResidue *res;
    res = mol.GetResidue(0);
    cout << "ok " << testCount << " # " << res->GetName();
    res = mol.GetResidue(1);
    cout << " " << res->GetName() << '\n';
  }
}
Beispiel #15
0
bool OpNewS::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv)
{
  OBMol* pmol = dynamic_cast<OBMol*>(pOb);
  if(!pmol)
    return false;

  // The SMARTS and any other parameters are extracted on the first molecule
  // and stored in the member variables. The parameter is cleared so that
  // the original -s option in transform.cpp is inactive

  //string txt(pmap->find(GetID())->second); // ID can be "s" or "v"

  vector<OBQuery*>::iterator qiter;
  if(OptionText && *OptionText)//(!pConv || pConv->IsFirstInput())
  {
    //Set up on first call
    queries.clear();
    query=NULL;
    nPatternAtoms=0;
    inv=false;

    tokenize(vec, OptionText);
    inv = GetID()[0]=='v';
    if(vec[0][0]=='~')
    {
      inv = true;
      vec[0].erase(0,1);
    }

    //Do not filter out any molecules if there is a parameter "showall";
    //allows -s option to be used for highlighting substructures (--highlight also does this)
    vector<string>::iterator it = std::remove(vec.begin(), vec.end(),"showall");
    showAll = it != vec.end();
    if(showAll)
      vec.erase(it);

    //Store the number of matches required, if as a number in the second parameter, else 0.
    nmatches = 0;
    comparechar = '\0';
    if(vec.size()>1)
    {
      comparechar = vec[1][0];
      if(comparechar=='>' || comparechar=='<')
        vec[1].erase(0,1);
      else
        comparechar = '\0';
      nmatches = atoi(vec[1].c_str());
      if(nmatches) //remove this parameter to still allow coloring
        vec.erase(vec.begin()+1);
    }

    //Interpret as a filename if possible
    MakeQueriesFromMolInFile(queries, vec[0], &nPatternAtoms, strstr(OptionText,"noH"));
    vec.erase(remove(vec.begin(),vec.end(),"noH"),vec.end());//to prevent "noH2" being seen as a color
    
     
    if(queries.empty())
    {
      //SMARTS supplied
    
      // Explicit H in SMARTS requires explicit H in the molecule.
      // Calling AddHydrogens() on a copy of the molecule  is done in parsmart.cpp
      // only when SMARTS contains [H]. Doing more has complications with atom typing,
      // so AddHydrogens here on the molecule (not a copy) when #1 detected.
      addHydrogens = (vec[0].find("#1]")!=string::npos);

      // If extra target mols have been supplied, make a composite SMARTS
      // to test for any of the targets.
      if(ExtraMols.size()>0)
      {
        for(unsigned i=0;i<ExtraMols.size();++i)
        {
          OBConversion extraConv;
          extraConv.AddOption("h");
          if(!extraConv.SetOutFormat("smi"))
            return false;
          // Add option which avoids implicit H being added to the SMARTS.
          // The parameter must be present but can be anything.
          extraConv.AddOption("h",OBConversion::OUTOPTIONS, "X");
          xsmarts += ",$(" + extraConv.WriteString(ExtraMols[i], true) + ")";
        }
      }

      string ysmarts = xsmarts.empty() ? vec[0] : "[$(" + vec[0] + ")" + xsmarts +"]";
      xsmarts.clear();
      if(!sp.Init(ysmarts))
      {
        string msg = ysmarts + " cannot be interpreted as either valid SMARTS "
          "or the name of a file with an extension known to OpenBabel "
          "that contains one or more pattern molecules.";
        obErrorLog.ThrowError(__FUNCTION__, msg, obError, onceOnly);
        delete pmol;
        pmol = NULL;
        pConv->SetOneObjectOnly(); //stop conversion
        return false;
      }
    }
    else
    {
      // Target is in a file. Add extra targets if any supplied
      for(unsigned i=0;i<ExtraMols.size();++i)
        queries.push_back(CompileMoleculeQuery(static_cast<OBMol*>(ExtraMols[i])));
      ExtraMols.clear();
    }

    if(vec.size()>1 && vec[1]=="exact")
    {
      if(queries.empty())
      {
        //Convert SMARTS to SMILES to count number of atoms
        OBConversion conv;
        OBMol patmol;
        if(!conv.SetInFormat("smi") || !conv.ReadString(&patmol, vec[0]))
        {
          obErrorLog.ThrowError(__FUNCTION__, "Cannot read the parameter of -s option, "
          "which has to be valid SMILES when the exact option is used.", obError, onceOnly);
          delete pmol;
          if(pConv)
            pConv->SetOneObjectOnly(); //stop conversion
          return false;
        }
        nPatternAtoms = patmol.NumHvyAtoms();
      }
    }
    else
      nPatternAtoms = 0;

    //disable old versions
    if(pConv)
      pConv->AddOption(GetID(), OBConversion::GENOPTIONS, "");
  }

  bool match = false;
  //These are a vector of each mapping, each containing atom indxs.
  vector<vector<int> > vecatomvec;
  vector<vector<int> >* pMappedAtoms = NULL;

  if(nPatternAtoms)
    if(pmol->NumHvyAtoms() != nPatternAtoms)
      return false;

  unsigned int imol=0; //index of mol in pattern file
  if(!queries.empty()) //filename supplied
  {
    //match is set true if any of the structures match - OR behaviour
    for(qiter=queries.begin();qiter!=queries.end();++qiter, ++imol)
    {
      OBIsomorphismMapper* mapper = OBIsomorphismMapper::GetInstance(*qiter);
      OBIsomorphismMapper::Mappings mappings;
      mapper->MapUnique(pmol, mappings);
      if( (match = !mappings.empty()) ) // extra parens to indicate truth value
      {
        OBIsomorphismMapper::Mappings::iterator ita;
        OBIsomorphismMapper::Mapping::iterator itb;
        for(ita=mappings.begin(); ita!=mappings.end();++ita)//each mapping
        {
          vector<int> atomvec;
          for(itb=ita->begin(); itb!=ita->end();++itb)//each atom index
            atomvec.push_back(itb->second+1);
          vecatomvec.push_back(atomvec);
          atomvec.clear();
        }
        pMappedAtoms = &vecatomvec;
        break;
      }
    }
  }
  else //SMARTS supplied
  {

    if(addHydrogens)
      pmol->AddHydrogens(false,false);

    if( (match = sp.Match(*pmol)) ) // extra parens to indicate truth value
    {
      pMappedAtoms = &sp.GetMapList();
      if(nmatches!=0)
      {
        int n = sp.GetUMapList().size();
        if(comparechar=='>')      match = (n > nmatches);
        else if(comparechar=='<') match = (n < nmatches);
        else                      match = (n == nmatches);
      }
    }
  }

  if((!showAll && (!match && !inv)) || (match && inv))
  {
    //delete a non-matching mol
    delete pmol;
    pmol = NULL;
    return false;
  }

  if(match)
    //Copy the idxes of the first match to a member variable so that it can be retrieved from outside
    firstmatch.assign(pMappedAtoms->begin()->begin(), pMappedAtoms->begin()->end());
  else
    firstmatch.clear();

  if(match && !inv && vec.size()>=2 && !vec[1].empty() && !nPatternAtoms)
  {
    vector<vector<int> >::iterator iter;

    if (vec[1]=="extract" || (vec.size()>3 && vec[2]=="extract"))
    {
      //Delete all unmatched atoms. Use only the first match
      ExtractSubstruct(pmol, *pMappedAtoms->begin());
      return true;
    }

    // color the substructure if there is a second parameter which is not "exact" or "extract" or "noH"
    // with multiple color parameters use the one corresponding to the query molecule, or the last
    if(imol>vec.size()-2)
      imol = vec.size()-2;
    for(iter=pMappedAtoms->begin();iter!=pMappedAtoms->end();++iter)//each match
       AddDataToSubstruct(pmol, *iter, "color", vec[imol+1]);
    return true;
  }

  if(pConv && pConv->IsLast())
  {
    for(qiter=queries.begin();qiter!=queries.end();++qiter)
      delete *qiter;
    queries.clear();
  }
  return true;
}
Beispiel #16
0
  bool FastSearchFormat::ObtainTarget(OBConversion* pConv, vector<OBMol>& patternMols, const string& indexname)
  {
    //Obtains an OBMol from:
    // the filename in the -s option or
    // the SMARTS string in the -s option or
    // by converting the file in the -S or -aS options (deprecated).
    // If there is no -s -S or -aS option, information on the index file is displayed.

    OBMol patternMol;
    patternMol.SetIsPatternStructure();

    const char* p = pConv->IsOption("s",OBConversion::GENOPTIONS);

    bool OldSOption=false;
    //If no -s option, make OBMol from file in -S option or -aS option (both deprecated)
    if(!p)
    {
      p = pConv->IsOption("S",OBConversion::GENOPTIONS);
      if(!p)
        p = pConv->IsOption("S",OBConversion::INOPTIONS);//for GUI mainly
      OldSOption = true;
    }
    if(p)
    {
      vector<string> vec;
      tokenize(vec, p);

      //ignore leading ~ (not relevant to fastsearch)
      if(vec[0][0]=='~')
        vec[0].erase(0,1);

      if(vec.size()>1 && vec[1]=="exact")
        pConv->AddOption("e", OBConversion::INOPTIONS);

      OBConversion patternConv;
      OBFormat* pFormat;
      //Interpret as a filename if possible
      string& txt =vec [0];
      if( txt.empty() ||
          txt.find('.')==string::npos ||
          !(pFormat = patternConv.FormatFromExt(txt.c_str())) ||
          !patternConv.SetInFormat(pFormat) ||
          !patternConv.ReadFile(&patternMol, txt) ||
          patternMol.NumAtoms()==0)
        //if false, have a valid patternMol from a file
      {
        //is SMARTS/SMILES
        //Replace e.g. [#6] in SMARTS by C so that it can be converted as SMILES
        //for the fingerprint phase, but allow more generality in the SMARTS phase.
        for(;;)
        {
          string::size_type pos1, pos2;
          pos1 = txt.find("[#");
          if(pos1==string::npos)
            break;
          pos2 = txt.find(']');
          int atno;
          if(pos2!=string::npos &&  (atno = atoi(txt.substr(pos1+2, pos2-pos1-2).c_str())) && atno>0)
            txt.replace(pos1, pos2-pos1+1, etab.GetSymbol(atno));
          else
          {
            obErrorLog.ThrowError(__FUNCTION__,"Ill-formed [#n] atom in SMARTS", obError);
            return false;
          }
        }

        bool hasTildeBond;
        if( (hasTildeBond = (txt.find('~')!=string::npos)) ) // extra parens to indicate truth value
        {
          //Find ~ bonds and make versions of query molecule with a single and aromatic bonds
          //To avoid having to parse the SMILES here, replace ~ by $ (quadruple bond)
          //and then replace this in patternMol. Check first that there are no $ already
          //Sadly, isocynanides may have $ bonds.
          if(txt.find('$')!=string::npos)
          {
            obErrorLog.ThrowError(__FUNCTION__,
              "Cannot use ~ bonds in patterns with $ (quadruple) bonds.)", obError);
            return false;
          }
          replace(txt.begin(),txt.end(), '~' , '$');
        }

        //read as standard SMILES
        patternConv.SetInFormat("smi");
        if(!patternConv.ReadString(&patternMol, vec[0]))
        {
          obErrorLog.ThrowError(__FUNCTION__,"Cannot read the SMILES string",obError);
          return false;
        }
        if(hasTildeBond)
        {
          AddPattern(patternMols, patternMol, 0); //recursively add all combinations of tilde bond values
          return true;
        }
      }
      else
      {
        // target(s) are in a file
        patternMols.push_back(patternMol);
        while(patternConv.Read(&patternMol))
          patternMols.push_back(patternMol);
        return true;
      }
    }

    if(OldSOption) //only when using deprecated -S and -aS options
    {
      //make -s option for later SMARTS test
      OBConversion conv;
      if(conv.SetOutFormat("smi"))
      {
        string optiontext = conv.WriteString(&patternMol, true);
        pConv->AddOption("s", OBConversion::GENOPTIONS, optiontext.c_str());
      }
    }

    if(!p)
    {
      //neither -s or -S options provided. Output info rather than doing search
      const FptIndexHeader& header = fs.GetIndexHeader();
      string id(header.fpid);
      if(id.empty())
        id = "default";
      clog << indexname << " is an index of\n " << header.datafilename
           << ".\n It contains " << header.nEntries
           << " molecules. The fingerprint type is " << id << " with "
           << OBFingerprint::Getbitsperint() * header.words << " bits.\n"
           << "Typical usage for a substructure search:\n"
           << "obabel indexfile.fs -osmi -sSMILES\n"
           << "(-s option in GUI is 'Convert only if match SMARTS or mols in file')" << endl;
      return false;
    }

    patternMols.push_back(patternMol);
    return true;
  }
Beispiel #17
0
bool OpNewS::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv)
{
  OBMol* pmol = dynamic_cast<OBMol*>(pOb);
  if(!pmol)
    return false;

  // The SMARTS and any other parameters are extracted on the first molecule
  // and stored in the static variables vec, inv. The parameter is cleared so that:
  // (a) the original -s option in transform.cpp is inactive, and
  // (b) the parsing does not have to be done again for multi-molecule files

  string txt(pmap->find(GetID())->second); // ID can be "s" or "v"
  static vector<string> vec;
  static bool inv;
  static int nPatternAtoms; //non-zero for exact matches
  static OBQuery* query;
  static vector<OBQuery*> queries;
  vector<OBQuery*>::iterator qiter;
  if(!txt.empty())
  {
    //Set up on first call
    tokenize(vec, txt);
    inv = GetID()[0]=='v';
    if(vec[0][0]=='~')
    {
      inv = true;
      vec[0].erase(0,1);
    }

    //Interpret as a filename if possible
    MakeQueriesFromMolInFile(queries, vec[0], &nPatternAtoms);

    if(vec.size()>1 && vec[1]=="exact")
    {
      if(queries.empty())
      {
        //Convert SMARTS to SMILES to count number of atoms
        OBConversion conv;
        OBMol patmol;
        if(!conv.SetInFormat("smi") || !conv.ReadString(&patmol, vec[0]))
        {
          obErrorLog.ThrowError(__FUNCTION__, "Cannot read the parameter of -s option, "
          "which has to be valid SMILES when the exact option is used.", obError, onceOnly);
          delete pmol;
          pConv->SetOneObjectOnly(); //stop conversion
          return false;
        }
        nPatternAtoms = patmol.NumHvyAtoms();
      }
    }
    else
      nPatternAtoms = 0;
    
    //disable old versions
    pConv->AddOption(GetID(), OBConversion::GENOPTIONS, "");
  }

  bool match;
  //These are a vector of each mapping, each containing atom indxs.
  vector<vector<int> > vecatomvec;
  vector<vector<int> >* pMappedAtoms = NULL;
  OBSmartsPattern sp;

  if(nPatternAtoms)
    if(pmol->NumHvyAtoms() != nPatternAtoms)
      return false;

  int imol=0; //index of mol in pattern file
  if(!queries.empty()) //filename supplied
  {
    //match is set true if any of the structures match - OR behaviour
    for(qiter=queries.begin();qiter!=queries.end();++qiter, ++imol) 
    {
      OBIsomorphismMapper* mapper = OBIsomorphismMapper::GetInstance(*qiter);
      OBIsomorphismMapper::Mappings mappings;
      mapper->MapUnique(pmol, mappings);
      if( (match = !mappings.empty()) ) // extra parens to indicate truth value
      {
        OBIsomorphismMapper::Mappings::iterator ita;
        OBIsomorphismMapper::Mapping::iterator itb;
        for(ita=mappings.begin(); ita!=mappings.end();++ita)//each mapping
        {
          vector<int> atomvec;
          for(itb=ita->begin(); itb!=ita->end();++itb)//each atom index
            atomvec.push_back(itb->second+1);
          vecatomvec.push_back(atomvec);
          atomvec.clear();
        }
        pMappedAtoms = &vecatomvec;
        break;
      }
    }
  }
  else //SMARTS supplied
  {
    if(!sp.Init(vec[0]))
    {
      string msg = vec[0] + " cannot be interpreted as either valid SMARTS "
        "or the name of a file with an extension known to OpenBabel "
        "that contains one or more pattern molecules.";
      obErrorLog.ThrowError(__FUNCTION__, msg, obError, onceOnly);
      delete pmol;
      pmol = NULL;
      pConv->SetOneObjectOnly(); //stop conversion
      return false;
    }

    if( (match = sp.Match(*pmol)) ) // extra parens to indicate truth value
      pMappedAtoms = &sp.GetMapList();
  }

  if((!match && !inv) || (match && inv))
  {
    //delete a non-matching mol
    delete pmol;
    pmol = NULL;
    return false;
  }

  if(!inv && vec.size()>=2 && !vec[1].empty() && !nPatternAtoms)
  {
    vector<vector<int> >::iterator iter;

    if(vec[1]=="extract")
    {
      //Delete all unmatched atoms. Use only the first match
      ExtractSubstruct(pmol, *pMappedAtoms->begin());
      return true;
    }

    // color the substructure if there is a second parameter which is not "exact" or "extract"
    // with multiple color parameters use the one corresponding to the query molecule, or the last
    if(imol>vec.size()-2)
      imol = vec.size()-2;
    for(iter=pMappedAtoms->begin();iter!=pMappedAtoms->end();++iter)//each match
       AddDataToSubstruct(pmol, *iter, "color", vec[imol+1]);
    return true;
  }

  if(pConv && pConv->IsLast())
  {
    for(qiter=queries.begin();qiter!=queries.end();++qiter)
      delete *qiter;
    queries.clear();
  }
  return true;
}
Beispiel #18
0
void residue_test()
{
  cout << "# Unit tests for OBResidue \n";

  // OBResidue isolation tests
  OBResidue emptyResidue, testRes1;

  // chains parser tests

  // PR#1515198
  static const string loopTest1("C1(C(NC(C(N1C(C(NC(C=Cc1ccccc1)=O)C)=O)Cc1ccccc1)=O)Cc1ccccc1)=O");
  OBConversion conv;
  OBMol mol;
  OBFormat *inFormat = conv.FindFormat("SMI");
  
  conv.SetInFormat(inFormat);
  conv.ReadString(&mol, loopTest1);
  chainsparser.PerceiveChains(mol);

  // parse common residues
  unsigned int testCount = 3;
  static const string ala("NC(C)C(O)(=O)");
  CheckValidResidue(conv, ala, ++testCount);
  static const string arg("NC(CCCNC(N)=N)C(O)(=O)");
  CheckValidResidue(conv, arg, ++testCount);
  static const string asn("NC(CC(N)=O)C(O)(=O)");
  CheckValidResidue(conv, asn, ++testCount);
  static const string asp("NC(CC(O)=O)C(O)(=O)");
  CheckValidResidue(conv, asp, ++testCount);
  static const string cys("NC(CS)C(O)(=O)");
  CheckValidResidue(conv, cys, ++testCount);
  static const string glu("NC(CCC(O)=O)C(O)(=O)");
  CheckValidResidue(conv, glu, ++testCount);
  static const string gln("NC(CCC(N)=O)C(O)(=O)");
  CheckValidResidue(conv, gln, ++testCount);
  static const string gly("NC([H])C(O)(=O)");
  CheckValidResidue(conv, gly, ++testCount);
  static const string his("NC(CC1=CNC=N1)C(O)(=O)");
  CheckValidResidue(conv, his, ++testCount);
  static const string ile("NC(C(CC)C)C(O)(=O)");
  CheckValidResidue(conv, ile, ++testCount);
  static const string leu("NC(CC(C)C)C(O)(=O)");
  CheckValidResidue(conv, leu, ++testCount);
  static const string lys("NC(CCCCN)C(O)(=O)");
  CheckValidResidue(conv, lys, ++testCount);
  static const string met("NC(CCSC)C(O)(=O)");
  CheckValidResidue(conv, met, ++testCount);
  static const string phe("NC(CC1=CC=CC=C1)C(O)(=O)");
  CheckValidResidue(conv, phe, ++testCount);
  static const string pro("OC(C1CCCN1)(=O)");
  CheckValidResidue(conv, pro, ++testCount);
  static const string ser("NC(CO)C(O)(=O)");
  CheckValidResidue(conv, ser, ++testCount);
  static const string thr("NC(C(C)O)C(O)(=O)");
  CheckValidResidue(conv, thr, ++testCount);
  static const string trp("NC(CC1=CNC2=C1C=CC=C2)C(O)(=O)");
  CheckValidResidue(conv, trp, ++testCount);
  static const string tyr("NC(CC1=CC=C(O)C=C1)C(O)(=O)");
  CheckValidResidue(conv, tyr, ++testCount);
  static const string val("NC(C(C)C)C(O)(=O)");
  CheckValidResidue(conv, val, ++testCount);

  // nucleics
  static const string a("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c(ncnc12)N");
  CheckValidResidue(conv, a, ++testCount);
  static const string g("OC[C@H]1O[C@H](C[C@@H]1O)n1c(nc(cc1)N)=O");
  CheckValidResidue(conv, g, ++testCount);
  static const string c("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c([nH]c(nc12)N)=O");
  CheckValidResidue(conv, c, ++testCount);
  static const string t("OC[C@H]1O[C@H](C[C@@H]1O)n1c([nH]c(c(c1)C)=O)=O");
  CheckValidResidue(conv, t, ++testCount);
  static const string u("OC[C@H]1O[C@H]([C@@H]([C@@H]1O)O)n1c([nH]c(cc1)=O)=O");
  CheckValidResidue(conv, u, ++testCount);

  // invalid residues
  static const string benzene("c1ccccc1");
  CheckInvalidResidue(conv, benzene, ++testCount);
  static const string pyrrole("c1cccn[H]1");
  CheckInvalidResidue(conv, pyrrole, ++testCount);
  static const string amine("CC(=O)CCN");
  CheckInvalidResidue(conv, amine, ++testCount);

  // check some dipeptides
  static const string ala_val("NC(C)C(=O)NC(C(C)C)C(=O)O");
  CheckValidDipeptide(conv, ala_val, ++testCount);
  static const string cys_leu("NC(CS)C(=O)NC(CC(C)C)C(=O)O");
  CheckValidDipeptide(conv, cys_leu, ++testCount);
 
}
int main(int argc,char *argv[])
{
  // turn off slow sync with C-style output (we don't use it anyway).
  std::ios::sync_with_stdio(false);

  if (argc != 1)
    {
      cout << "Usage: conversion" << endl;
      cout << " Unit tests for OBConversion " << endl;
      return(-1);
    }

  cout << "# Unit tests for OBConversion \n";

  // the number of tests for "prove"
  cout << "1..9\n";

  cout << "ok 1\n"; // for loading tests

  OBMol obMol;
  OBConversion obConversion;
  obConversion.SetInAndOutFormats("smi", "mdl");
  cout << "ok 2\n";

  obConversion.ReadString(&obMol, "C1=CC=CS1");
  cout << "ok 3\n";

  if (obMol.NumAtoms() == 5) {
    cout << "ok 4\n";
  } else {
    cout << "not ok 4\n";
  }

  obMol.AddHydrogens();
  if (obMol.NumAtoms() == 9) {
    cout << "ok 5\n";
  } else {
    cout << "not ok 5\n";
  }

  if ( (obConversion.WriteString(&obMol)).length() > 0)
    cout << "ok 6\n";
  else
    cout << "not ok 6\n";

  // PR#1474265
  obConversion.WriteFile(&obMol, "test.mdl");
  ifstream ifs("test.mdl");
  if (ifs.good())
    cout << "ok 7\n";
  else
    cout << "not ok 7\n";

  // PR#143577
  obConversion.SetInFormat("mdl");
  obConversion.ReadFile(&obMol, "test.mdl");
  if ( remove("test.mdl") != -1)
    cout << "ok 8\n";
  else
    cout << "not ok 8\n";
  
  // gzip input
  // gzip output

  // multi-molecule reading
  // PR#1465586
  // aromatics.smi
  // attype.00.smi

  //ReadFile()
  //Read()
  //WriteString()
  // GetOutputIndex()
  // IsLast

  //ReadString()
  //IsFirstInput
  //Read()

  // splitting
  
  // splitting using gzip-input
  // PR#1357705
  
  // size 0 input
  // PR#1250900
  
  // RegisterFormat
  // FindFormat
  // FormatFromExt
  // FormatFromMIME
  // GetNextFormat
  // GetDefaultFormat

  // BatchFileName
  // IncrementedFileName

  // option handling
  // AddOption
  // IsOption
  // RemoveOption
  // IsOption

  // SetOptions
  // IsOption

  // RegisterOptionParam
  // GetOptionParams

  // GetInStream
  // GetOutStream
  // SetInStream
  // SetOutStream

  // nasty tests
  obConversion.ReadString(&obMol, "");
  obConversion.Read(&obMol);
  cout << "ok 9\n";

  return(0);
}
Beispiel #20
0
void genericSmilesCanonicalTest(const std::string &smiles)
{
  cout << "Testing generic smiles <-> canonical smiles" << endl;
  // read a smiles string
  OBMol mol;
  OBConversion conv;
  OB_REQUIRE( conv.SetInFormat("smi") );
  OB_REQUIRE( conv.SetOutFormat("can") );
  cout << "smiles: " << smiles << endl;
  // read a smiles string
  OB_REQUIRE( conv.ReadString(&mol, smiles) );

  // store the stereo data for the smiles string using unique symmetry ids
  std::vector<OBTetrahedralStereo::Config> tetrahedral1;
  std::vector<OBCisTransStereo::Config> cistrans1;
  std::vector<OBSquarePlanarStereo::Config> squareplanar1;

  // get the stereo data
  OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) );
  std::vector<OBGenericData *> stereoData = mol.GetAllData(OBGenericDataType::StereoData);

  std::vector<unsigned int> canlbls;
  std::vector<unsigned int> symclasses;
  OBGraphSym gs1(&mol);
  gs1.GetSymmetry(symclasses);
  CanonicalLabels(&mol, symclasses, canlbls);
  cout << "mol.NumAtoms = " << mol.NumAtoms() << endl;
  for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) {
    if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) {
      // convert to tetrahedral data
      OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data);
      OB_REQUIRE( ts );
      OB_ASSERT( ts->IsValid() );
      if (!ts->IsValid())
        continue;

      OBTetrahedralStereo::Config config = ts->GetConfig();
      // convert atom ids to symmetry ids
     if (mol.GetAtomById(config.center))
        config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 );
      if (mol.GetAtomById(config.from))
        config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      tetrahedral1.push_back(config);
    } else
    if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) {
      // convert to tetrahedral data
      OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data);
      OB_REQUIRE( ct );
      OB_ASSERT( ct->IsValid() );

      OBCisTransStereo::Config config = ct->GetConfig();
      // convert atom ids to symmetry ids
      config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 );
      config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[3]))
        config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      cistrans1.push_back(config);
    } else
    if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) {
      // convert to tetrahedral data
      OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data);
      OB_REQUIRE( sp );
      OB_ASSERT( sp->IsValid() );
      if (!sp->IsValid())
        continue;

      OBSquarePlanarStereo::Config config = sp->GetConfig();
      // convert atom ids to symmetry ids
     if (mol.GetAtomById(config.center))
        config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[3]))
        config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      squareplanar1.push_back(config);
    }


  }

  // write to can smiles
  std::string canSmiles = conv.WriteString(&mol);
  cout << "canSmiles: " << canSmiles;
  // read can smiles in again
  OB_REQUIRE( conv.ReadString(&mol, canSmiles) );

  // store the stereo data for the smiles string using unique symmetry ids
  std::vector<OBTetrahedralStereo::Config> tetrahedral2;
  std::vector<OBCisTransStereo::Config> cistrans2;
  std::vector<OBSquarePlanarStereo::Config> squareplanar2;

  // get the stereo data
  OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) );
  stereoData = mol.GetAllData(OBGenericDataType::StereoData);

  OBGraphSym gs2(&mol);
  gs2.GetSymmetry(symclasses);
  CanonicalLabels(&mol, symclasses, canlbls);
  cout << "mol.NumAtoms = " << mol.NumAtoms() << endl;
  for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) {
    if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) {
      // convert to tetrahedral data
      OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data);
      OB_REQUIRE( ts );
      OB_ASSERT( ts->IsValid() );

      OBTetrahedralStereo::Config config = ts->GetConfig();
      // convert atom ids to symmetry ids
      if (mol.GetAtomById(config.center))
        config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 );
      if (mol.GetAtomById(config.from))
        config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      tetrahedral2.push_back(config);
    }
    if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) {
      // convert to tetrahedral data
      OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data);
      OB_REQUIRE( ct );
      OB_ASSERT( ct->IsValid() );

      OBCisTransStereo::Config config = ct->GetConfig();
      // convert atom ids to symmetry ids
      config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 );
      config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[3]))
        config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      cistrans2.push_back(config);
    } else
    if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) {
      // convert to tetrahedral data
      OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data);
      OB_REQUIRE( sp );
      OB_ASSERT( sp->IsValid() );

      OBSquarePlanarStereo::Config config = sp->GetConfig();
      // convert atom ids to symmetry ids
      if (mol.GetAtomById(config.center))
        config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[0]))
        config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[1]))
        config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[2]))
        config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 );
      if (mol.GetAtomById(config.refs[3]))
        config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 );
      cout << "Config with symmetry ids: " << config << endl;
      squareplanar2.push_back(config);
    }

  }

  // compare the tetrahedral structs
  OB_ASSERT( tetrahedral1.size() == tetrahedral2.size() );
  for (unsigned int i = 0; i < tetrahedral1.size(); ++i) {
    for (unsigned int j = 0; j < tetrahedral2.size(); ++j) {
      if (tetrahedral1[i].center == tetrahedral2[j].center)
        OB_ASSERT( tetrahedral1[i] == tetrahedral2[j] );
        if ( tetrahedral1[i] != tetrahedral2[j] ) {
          cout << "1 = " << tetrahedral1[i] << endl;
          cout << "2 = " << tetrahedral2[j] << endl;
        }
    }
  }
  // compare the cistrans structs
  OB_ASSERT( cistrans1.size() == cistrans2.size() );
  for (unsigned int i = 0; i < cistrans1.size(); ++i) {
    for (unsigned int j = 0; j < cistrans2.size(); ++j) {
      if ((cistrans1[i].begin == cistrans2[j].begin) && (cistrans1[i].end == cistrans2[j].end))
        OB_ASSERT( cistrans1[i] == cistrans2[j] );
      if ((cistrans1[i].begin == cistrans2[j].end) && (cistrans1[i].end == cistrans2[j].begin))
        OB_ASSERT( cistrans1[i] == cistrans2[j] );
    }
  }
  // compare the square-planar structs
  OB_ASSERT( squareplanar1.size() == squareplanar2.size() );
  for (unsigned int i = 0; i < squareplanar1.size(); ++i) {
    for (unsigned int j = 0; j < squareplanar2.size(); ++j) {
      if (squareplanar1[i].center == squareplanar2[j].center)
        OB_ASSERT( squareplanar1[i] == squareplanar2[j] );
        if ( squareplanar1[i] != squareplanar2[j] ) {
          cout << "1 = " << squareplanar1[i] << endl;
          cout << "2 = " << squareplanar2[j] << endl;
        }
    }
  }

  cout << "." << endl << endl;
}
Beispiel #21
0
int main(int argc,char *argv[])
{
  // turn off slow sync with C-style output (we don't use it anyway).
  std::ios::sync_with_stdio(false);

  if (argc != 1)
    {
      cout << "Usage: residue" << endl;
      cout << " Unit tests for OBResidue " << endl;
      return(-1);
    }

  cout << "# Unit tests for OBResidue \n";

  cout << "ok 1\n"; // for loading tests

  // OBResidue isolation tests
  OBResidue emptyResidue, testRes1;
  cout << "ok 2\n"; // ctor works

  // chains parser tests

  // PR#1515198
  static const string loopTest1("C1(C(NC(C(N1C(C(NC(C=Cc1ccccc1)=O)C)=O)Cc1ccccc1)=O)Cc1ccccc1)=O");
  OBConversion conv;
  OBMol mol;
  OBFormat *inFormat = conv.FindFormat("SMI");
  
  conv.SetInFormat(inFormat);
  conv.ReadString(&mol, loopTest1);
  chainsparser.PerceiveChains(mol);

  // OK if it doesn't crash
  cout << "ok 3\n";

  // parse common residues
  unsigned int testCount = 3;
  static const string ala("NC(C)C(O)(=O)");
  CheckValidResidue(conv, ala, ++testCount);
  static const string arg("NC(CCCNC(N)=N)C(O)(=O)");
  CheckValidResidue(conv, arg, ++testCount);
  static const string asn("NC(CC(N)=O)C(O)(=O)");
  CheckValidResidue(conv, asn, ++testCount);
  static const string asp("NC(CC(O)=O)C(O)(=O)");
  CheckValidResidue(conv, asp, ++testCount);
  static const string cys("NC(CS)C(O)(=O)");
  CheckValidResidue(conv, cys, ++testCount);
  static const string glu("NC(CCC(O)=O)C(O)(=O)");
  CheckValidResidue(conv, glu, ++testCount);
  static const string gln("NC(CCC(N)=O)C(O)(=O)");
  CheckValidResidue(conv, gln, ++testCount);
  static const string gly("NC([H])C(O)(=O)");
  CheckValidResidue(conv, gly, ++testCount);
  static const string his("NC(CC1=CNC=N1)C(O)(=O)");
  CheckValidResidue(conv, his, ++testCount);
  static const string ile("NC(C(CC)C)C(O)(=O)");
  CheckValidResidue(conv, ile, ++testCount);
  static const string leu("NC(CC(C)C)C(O)(=O)");
  CheckValidResidue(conv, leu, ++testCount);
  static const string lys("NC(CCCCN)C(O)(=O)");
  CheckValidResidue(conv, lys, ++testCount);
  static const string met("NC(CCSC)C(O)(=O)");
  CheckValidResidue(conv, met, ++testCount);
  static const string phe("NC(CC1=CC=CC=C1)C(O)(=O)");
  CheckValidResidue(conv, phe, ++testCount);
  static const string pro("OC(C1CCCN1)(=O)");
  CheckValidResidue(conv, pro, ++testCount);
  static const string ser("NC(CO)C(O)(=O)");
  CheckValidResidue(conv, ser, ++testCount);
  static const string thr("NC(C(C)O)C(O)(=O)");
  CheckValidResidue(conv, thr, ++testCount);
  static const string trp("NC(CC1=CNC2=C1C=CC=C2)C(O)(=O)");
  CheckValidResidue(conv, trp, ++testCount);
  static const string tyr("NC(CC1=CC=C(O)C=C1)C(O)(=O)");
  CheckValidResidue(conv, tyr, ++testCount);
  static const string val("NC(C(C)C)C(O)(=O)");
  CheckValidResidue(conv, val, ++testCount);

  // nucleics
  static const string a("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c(ncnc12)N");
  CheckValidResidue(conv, a, ++testCount);
  static const string g("OC[C@H]1O[C@H](C[C@@H]1O)n1c(nc(cc1)N)=O");
  CheckValidResidue(conv, g, ++testCount);
  static const string c("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c([nH]c(nc12)N)=O");
  CheckValidResidue(conv, c, ++testCount);
  static const string t("OC[C@H]1O[C@H](C[C@@H]1O)n1c([nH]c(c(c1)C)=O)=O");
  CheckValidResidue(conv, t, ++testCount);
  static const string u("OC[C@H]1O[C@H]([C@@H]([C@@H]1O)O)n1c([nH]c(cc1)=O)=O");
  CheckValidResidue(conv, u, ++testCount);

  // invalid residues
  static const string benzene("c1ccccc1");
  CheckInvalidResidue(conv, benzene, ++testCount);
  static const string pyrrole("c1cccn[H]1");
  CheckInvalidResidue(conv, pyrrole, ++testCount);
  static const string amine("CC(=O)CCN");
  CheckInvalidResidue(conv, amine, ++testCount);

  // check some dipeptides
  static const string ala_val("NC(C)C(=O)NC(C(C)C)C(=O)O");
  CheckValidDipeptide(conv, ala_val, ++testCount);
  static const string cys_leu("NC(CS)C(=O)NC(CC(C)C)C(=O)O");
  CheckValidDipeptide(conv, cys_leu, ++testCount);
 
  // the number of tests for "prove"
  cout << "1.." << testCount << "\n";

  return(0);
}
Beispiel #22
0
void phmodel_test()
{
  OBMol mol;
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.SetOutFormat("smi");

  unsigned int test = 0;

  // amine acid COOH pKa = 4.0 (carboxylic acid entry in phmodel.txt)
  // amino acid NH3+ pKa = 10.0 (amine entry in phmodel.txt)

  // 
  // Aspartic acid (sidechain COOH pKa = 3.8)
  //
  conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH COOH
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Aspartic acid pH 1.0" );

  conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 3.9); // NH3+ COOH COO-
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 16, "Aspartic acid pH 3.9" );

  conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- COO-
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 15, "Aspartic acid pH 7.4" );

  conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- COO-
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 14, "Aspartic acid pH 13.0" );

  // 
  // Glutamic acid (sidechain COOH pKa = 4.3)
  //
  conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH COOH
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 20, "Glutamic acid pH 1.0" );

  conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 4.15); // NH3+ COOH COO-
  //conv.Write(&mol, &cout);
 
  // known bug
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 19, "Glutamic acid pH 4.15" );

  conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- COO-
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 18, "Glutamic acid pH 7.4" );

  conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- COO-
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Glutamic acid pH 13.0" );

  // 
  // Histidine (sidechain nH+ pKa = 6.08)
  //
  conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH nH+
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 22, "Histidine pH 1.0" );
  
  conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 5.0); // NH3+ COO- nH+
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 21, "Histidine pH 5.0" );

  conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- n:
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 20, "Histidine pH 7.4" );

  conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- n:
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 19, "Histidine pH 13.0" );

  // 
  // Lysine (sidechain NH3+ pKa = 8.28)
  //
  conv.ReadString(&mol, "NC(CCCCN)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH NH3+
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 26, "Lysine pH 1.0" );

  conv.ReadString(&mol, "NC(CCCCN)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Lysine pH 7.4" );

  conv.ReadString(&mol, "NC(CCCCN)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 9.0); // NH3+ COO- NH2
  //conv.Write(&mol, &cout);
  
  // known bug
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 24, "Lysine pH 9.0" );

  conv.ReadString(&mol, "NC(CCCCN)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 23, "Lysine pH 13.0" );

  // 
  // Tyrosine (sidechain OH pKa = 10.1)
  //
  conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH NH3+
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Tyrosine pH 1.0" );

  conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 24, "Tyrosine pH 7.4" );

  conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 10.05); // NH3+ COO- NH2
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 23, "Tyrosine pH 10.05" );

  conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 22, "Tyrosine pH 13.0" );

  // 
  // Arginine (sidechain =NH2+ pKa = 12.0)
  //
  conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH =NH2+
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 28, "Arginine pH 1.0" );

  conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 27, "Arginine pH 7.4" );

  conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 11.0); // NH3+ COO- NH2
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 26, "Arginine pH 11.0" );

  conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Arginine pH 13.0" );

  // 
  // Gly-Gly (terminal NH3+, COOH and the amide bond)
  //
  conv.ReadString(&mol, "NCC(=O)NCC(=O)O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 1.0); // NH3+ COOH =NH2+
  //conv.Write(&mol, &cout);
  
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 18, "Gly-Gly pH 1.0" );

  conv.ReadString(&mol, "NCC(=O)NCC(=O)O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+
  //conv.Write(&mol, &cout);
 
  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Gly-Gly pH 7.4" );

  conv.ReadString(&mol, "NCC(=O)NCC(=O)O");
  mol.SetAutomaticFormalCharge(true);
  mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2
  //conv.Write(&mol, &cout);

  BOOST_CHECK_MESSAGE( mol.NumAtoms() == 16, "Gly-Gly pH 13.0" );

}
Beispiel #23
0
void readSmiles(const std::string &smiles, OBMol &mol)
{
  OBConversion conv;
  conv.SetInFormat("smi");
  conv.ReadString(&mol, smiles);
}