vote up 2 vote down
star

The CDK used to have a library to validate chemical graphs against common problems, including unknown atom types. Additionally, the file reader for the MDL SD format has a STRICT mode, which makes it fail if the file is not conform the format. However, the CDK currently does not have a library of command line utilities that make functionality available.

What Open Source tools are available to inspect the file and the content of a MDL SD file, and report errors?

flag
What level of error/warnings do you want? For example, should it report that the date field in line 2 (I think), is not in the right format? Should it report high valences? Lack of hydrogens (since SD files are supposed to have all hydrogens)? – Andrew Dalke Jan 21 at 2:45

3 Answers

vote up 2 vote down

Hello,

I would suggest to use a simple program based on Indigo toolkit:

#include "molecule/molecule.h"
#include "molecule/sdf_loader.h"
#include "molecule/molfile_loader.h"
#include "base_cpp/scanner.h"

int main (int argc, char *argv[])
{
   bool calc_hydro = true;
   bool allow_query = false;
   const char *idfield = 0;

   if (argc <= 1)
   {
      fprintf(stderr,
              "Usage: sdfcheck file.sdf [-id idfield] [-no-hydro-check] [-allow-query]\n");
      return -1;
   }

   const char *filename = argv[1];

   for (int i = 2; i < argc; i++)
   {
      if (strcmp(argv[i], "-id") == 0)
      {
         if (++i == argc)
         {
            fprintf(stderr, "expecting an identifier after '-id'\n");
            return -1;
         }
         idfield = argv[i];
      }
      else if (strcmp(argv[i], "-no-hydro-check") == 0)
         calc_hydro = false;
      else if (strcmp(argv[i], "-allow-query") == 0)
         allow_query = true;
      else
      {
         fprintf(stderr, "unknown parameter: %s\n", argv[i]);
         return -1;
      }
   }

   try
   {
      FileScanner scanner(filename);
      SdfLoader loader(scanner);
      int cnt = 0;

      if (idfield != 0)
         loader.initProperties(idfield);

      while (!loader.isEOF())
      {
         loader.readNext();

         const char *id = 0;

         if (idfield != 0 && loader.properties.at2(idfield) != 0)
            id = loader.properties.at(idfield).ptr();

         cnt++;

         if (idfield == 0)
            printf("reading molecule #%d... ", cnt);
         else if (id == 0)
            printf("reading molecule #%d, no %s ... ", cnt, idfield);
         else
            printf("reading molecule #%d, %s=%s ... ", cnt, idfield, id);

         fflush(stdout);

         Molecule mol;
         try
         {
            BufferScanner molscan(loader.data);
            MolfileLoader molload(molscan);

            molload.loadMolecule(mol, allow_query);
            if (calc_hydro)
               mol.calcImplicitHydrogens();
            printf("\n");
         }
         catch (Exception &e)
         {
            printf("error: %s\n", e.message());
            continue;
         }
      }
   }
   catch (Exception &e)
   {
      printf("error: %s\n", e.message());
   }

   return 0;
}

The steps to compile the program on Linux are:

  1. Download any Indigo source package containing 'graph' and 'molecule' projects (actually, every our package has them, so you can download any of them, for example Bingo)
  2. Unpack bingo-src-XXXX.zip
  3. Go to bingo-src-XXXX folder
  4. Paste the above code into sdfcheck.cpp file
  5. cd graph; make CONF=Release32; cd ..
  6. cd molecule; make CONF=Release32; cd ..
  7. gcc sdfcheck.cpp -o sdfcheck -O3 -m32 -I. -Icommon molecule/dist/Release32/GNU-Linux-x86/libmolecule.a graph/dist/Release32/GNU-Linux-x86/libgraph.a -lpthread -lstdc++

(In order to get a 64-bit executable, replace 32 with 64 in steps 5, 6, and 7.)

Then you can run the program like this:

./sdfcheck ~/sdf/database.sdf | grep error

or

./sdfcheck ~/sdf/database.sdf -id molregno -no-hydro-check | grep error

or

./sdfcheck ~/sdf/database.sdf -id molregno -no-hydro-check -allow-queries | grep error

With best regards,

Dmitry

link|flag
1 
If I read the code correctly, Indigo doesn't report the line number where the error occurred and it only reports the first error it found, with no warnings. It also makes some assumptions about the validity of the input format, which are never checked. For example, it assumes the tag will always be structured as />\s*<[^>]/ (translation from molecule/src/sdf_loader.cpp), but that's only a subset of the valid SD file headers. For example, it wouldn't handle "> 25 <MELTING.POINT>" from a Corina output file in CDK's test/data/mdl/test5.sdf . – Andrew Dalke Jan 21 at 2:42
Yes you are right: the line number is not reported, and at this moment there is no option in API to get it. You are also right about the incomplete SD header support; thank you very much for noticing, we will fix it in the future. The attached program focuses more on Molfile format mistakes and molecule drawing mistakes, than on SD format itself. Nevertheless, all such errors are written to the output, not only the first one. With best regards – Dmitry Pavlov Jan 21 at 12:46
vote up 0 vote down

OpenBabel has some checking code, as part of the parsing. It isn't designed for giving reports and just sends the messages to the log.

For what it's worth, my experience has been that most people don't care much for format validation. Who would use this?

link|flag
1 
I would... first thing I do when people report that the CDK has a bug is to validate what they input. At least in 20% of the time (very conservative estimate) it is bad input. – Egon Willighagen Dec 22 at 21:42
But that's solved by reporting the first error, including line number and column number, and hopefully also with a reason. What you asked for was something which reports multiple errors, and doing that requires writing a parser which knows how to fail gracefully, and continue. – Andrew Dalke Jan 6 at 14:29
vote up 0 vote down
check

Being curious in nature, and thus hacker, I worked out a solution for the CDK, with the option for line numbers of positions. The patch is not entirely finished yet, but I blogged about it with some examples:

http://chem-bla-ics.blogspot.com/2010/01/validating-mdl-sd-files-and-symyx.html

link|flag

Your Answer

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.