Beispiel #1
0
 def _parse_h_layer(self, layer):
     chunks = self._split_h_layer(layer)
     for chunk in chunks:
         try:
             head, tail = chunk.split('H')
         except Exception, e:
             raise oasa_inchi_error(
                 "error in hydrogen layer - missing H symbol")
         num_h = tail and int(tail) or 1
         vertices = []
         for p in head.split(","):
             if "-" in p:
                 try:
                     a, b = map(int, p.split("-"))
                 except Exception, e:
                     raise oasa_inchi_error(
                         "error in hydrogen layer - non-number character(s) present in atom range specification"
                     )
                 vertices.extend(range(a, b + 1))
             else:
                 try:
                     vertices.append(int(p))
                 except Exception, e:
                     raise oasa_inchi_error(
                         "error in hydrogen layer - non-number character(s) present in atom specification"
                     )
Beispiel #2
0
def generate_inchi_and_inchikey(m,
                                program=None,
                                fixed_hs=True,
                                ignore_key_error=False):
    """ignore the case when InChIKey cannot be generated for some reason
  (no mhash library and old InChI program)"""
    if not program:
        import config
        program = config.Config.inchi_binary_path
    mf = molfile.mol_to_text(m)
    if os.name == 'nt':
        options = "/AUXNONE /STDIO /Key" + (fixed_hs and " /FixedH" or "")
    else:
        options = "-AUXNONE -STDIO -Key" + (fixed_hs and " -FixedH" or "")
    #print options
    command = [os.path.abspath(program)] + options.split()
    text = _run_command(command, mf)
    inchi = ""
    key = ""
    warnings = []
    for line in text.splitlines():
        if line.startswith("Warning"):
            warnings.append(line.strip() + "\n")
        elif line.startswith("End of file detected"):
            pass
        elif line.startswith("InChIKey="):
            key = line.strip()[9:]
            break
        elif line.startswith("InChI="):
            inchi = inchi + line.strip()
        elif line.startswith("Error"):
            break
    if not inchi:
        raise oasa_inchi_error("InChI program did not create any output InChI")
    if not key:
        # probably old version of the InChI software
        try:
            import inchi_key
        except ImportError:
            if ignore_key_error:
                key = None
            else:
                raise oasa_inchi_error(
                    "InChIKey could not be generated - inchi_key module failed to load properly."
                )
        else:
            key = inchi_key.key_from_inchi(inchi)
    return inchi, key, warnings
Beispiel #3
0
 def read_inchi( self, text):
   try:
     self._read_inchi( text)
   except AssertionError:
     raise oasa_inchi_error( "Localization of bonds, charges or movable hydrogens failed")
   except:
     raise
Beispiel #4
0
 def read_inchi(self, text):
     try:
         self._read_inchi(text)
     except AssertionError:
         raise oasa_inchi_error(
             "Localization of bonds, charges or movable hydrogens failed")
     except:
         raise
Beispiel #5
0
def generate_inchi_and_inchikey( m, program=None, fixed_hs=True, ignore_key_error=False):
  """ignore the case when InChIKey cannot be generated for some reason
  (no mhash library and old InChI program)"""
  if not program:
    import config
    program = config.Config.inchi_binary_path
  mf = molfile.mol_to_text( m)
  if os.name == 'nt':
    options = "/AUXNONE /STDIO /Key" + (fixed_hs and " /FixedH" or "")
  else:
    options = "-AUXNONE -STDIO -Key" + (fixed_hs and " -FixedH" or "")
  #print options
  command = [os.path.abspath( program)] + options.split()
  text = _run_command( command, mf)
  inchi = ""
  key = ""
  warnings = []
  for line in text.splitlines():
    if line.startswith( "Warning"):
      warnings.append(line.strip() + "\n")
    elif line.startswith( "End of file detected"):
      pass
    elif line.startswith( "InChIKey="):
      key = line.strip()[9:]
      break
    elif line.startswith( "InChI="):
      inchi = inchi + line.strip()
    elif line.startswith( "Error"):
      break
  if not inchi:
    raise oasa_inchi_error( "InChI program did not create any output InChI")
  if not key:
    # probably old version of the InChI software
    try:
      import inchi_key
    except ImportError:
      if ignore_key_error:
        key = None
      else:
        raise oasa_inchi_error( "InChIKey could not be generated - inchi_key module failed to load properly.")
    else:
      key = inchi_key.key_from_inchi( inchi)
  return inchi, key, warnings
Beispiel #6
0
 def _parse_h_layer( self, layer):
   chunks = self._split_h_layer( layer)
   for chunk in chunks:
     try:
       head, tail = chunk.split( 'H')
     except Exception, e:
       raise oasa_inchi_error( "error in hydrogen layer - missing H symbol")
     num_h = tail and int( tail) or 1
     vertices = []
     for p in head.split( ","):
       if "-" in p:
         try:
           a, b = map( int, p.split("-"))
         except Exception, e:
           raise oasa_inchi_error( "error in hydrogen layer - non-number character(s) present in atom range specification")
         vertices.extend( range( a, b+1))
       else:
         try:
           vertices.append( int( p))
         except Exception, e:
           raise oasa_inchi_error( "error in hydrogen layer - non-number character(s) present in atom specification")
Beispiel #7
0
 def get_lowest_numbered_neighbor( atom, verbotten_atom):
   neighs = [(n.properties_.get('inchi_number',1000000), n)
             for n in atom.neighbors
             if n is not verbotten_atom and "inchi_number" in n.properties_]
   if neighs:
     neighs.sort( reverse=True)
     return neighs[0][1]
   else:
     # we take the only one that is there (if any)
     neighs = [n for n in atom.neighbors if n is not verbotten_atom]
     if neighs:
       return neighs[0]
     else:
       raise oasa_inchi_error( "No neigbors on atom with stereo information!")
Beispiel #8
0
 def get_lowest_numbered_neighbor(atom, verbotten_atom):
     neighs = [
         (n.properties_.get('inchi_number', 1000000), n)
         for n in atom.neighbors
         if n is not verbotten_atom and "inchi_number" in n.properties_
     ]
     if neighs:
         neighs.sort(reverse=True)
         return neighs[0][1]
     else:
         # we take the only one that is there (if any)
         neighs = [n for n in atom.neighbors if n is not verbotten_atom]
         if neighs:
             return neighs[0]
         else:
             raise oasa_inchi_error(
                 "No neigbors on atom with stereo information!")
Beispiel #9
0
  def _read_inchi( self, text):
    if not text:
      raise oasa_inchi_error( "No inchi was given")
    self.structure = molecule()
    self.layers = self.split_layers( text)
    # version support (very crude)
    self.version = self._check_version( self.layers[0])
    if not self.version:
      raise oasa_unsupported_inchi_version_error( self.layers[0])
    elif str( self.version[0]) != '1' or str( self.version[1]) != '0':
      raise oasa_unsupported_inchi_version_error( self.layers[0])
    
    self.hs_in_hydrogen_layer = self.get_number_of_hydrogens_in_hydrogen_layer()
    self.read_sum_layer()
    self.read_connectivity_layer()
    self._charge_mover = self._move_charge_somewhere_else()
    repeat = True
    run = 0
    # we have to repeat this step in order to find the right positioning of movable hydrogens
    while repeat and not self._no_possibility_to_improve:
      # cleanup
      for h in self._added_hs:
        self.structure.remove_vertex( h)
      for b in self.structure.edges:
        b.order = 1
      for v in self.structure.vertices:
        v.symbol = v.symbol
        v.charge = 0
      self.cleanup()

      # the code itself
      run += 1
      assert run < 50
      self._deal_with_notorious_groups()
      self.process_forced_charges()
      self.read_hydrogen_layer( run=run)
      self.read_charge_layer()
      self.read_p_layer()
      self.deal_with_da_bonds()
      #self._deal_with_valencies()
      self.compensate_for_forced_charges()
      self.structure.add_missing_bond_orders()
      #self.read_double_bond_stereo_layer()

      # here we check out if the molecule seems ok
      fvs = [v for v in self.structure.vertices if v.free_valency]
      if not fvs and not filter( None, [not v.order for v in self.structure.edges]):
        repeat = False
      else:
        if len( fvs) == 1:
          a = fvs[0]
          a.symbol = a.symbol # this resets the valency
          a.raise_valency_to_senseful_value()
          if not a.free_valency:
            repeat = False

      if repeat and self._no_possibility_to_improve and self.charge:
        try:
          self._charge_mover.next()
        except StopIteration:
          pass
        else:
          self._no_possibility_to_improve = False
          run = 0

    if repeat and self._no_possibility_to_improve:
##       if len( filter( None, [v.free_valency for v in self.structure.vertices])) == 1:
##         print
##         print [(v.symbol, v.valency, v.free_valency)  for v in self.structure.vertices if v.free_valency], filter( None, [not v.order for v in self.structure.edges]), text
##       if sum( [v.charge for v in self.structure.vertices]) != self.charge:
##         print "Charge problem", sum( [v.charge for v in self.structure.vertices]), self.charge
      #pass
      raise oasa_inchi_error( "Localization of bonds, charges or movable hydrogens failed")
Beispiel #10
0
    def _read_inchi(self, text):
        if not text:
            raise oasa_inchi_error("No inchi was given")
        self.structure = molecule()
        self.layers = self.split_layers(text)
        # version support (very crude)
        self.version = self._check_version(self.layers[0])
        if not self.version:
            raise oasa_unsupported_inchi_version_error(self.layers[0])
        elif str(self.version[0]) != '1' or str(self.version[1]) != '0':
            raise oasa_unsupported_inchi_version_error(self.layers[0])

        self.hs_in_hydrogen_layer = self.get_number_of_hydrogens_in_hydrogen_layer(
        )
        self.read_sum_layer()
        self.read_connectivity_layer()
        self._charge_mover = self._move_charge_somewhere_else()
        repeat = True
        run = 0
        # we have to repeat this step in order to find the right positioning of movable hydrogens
        while repeat and not self._no_possibility_to_improve:
            # cleanup
            for h in self._added_hs:
                self.structure.remove_vertex(h)
            for b in self.structure.edges:
                b.order = 1
            for v in self.structure.vertices:
                v.symbol = v.symbol
                v.charge = 0
            self.cleanup()

            # the code itself
            run += 1
            assert run < 50
            self._deal_with_notorious_groups()
            self.process_forced_charges()
            self.read_hydrogen_layer(run=run)
            self.read_charge_layer()
            self.read_p_layer()
            self.deal_with_da_bonds()
            #self._deal_with_valencies()
            self.compensate_for_forced_charges()
            self.structure.add_missing_bond_orders()
            #self.read_double_bond_stereo_layer()

            # here we check out if the molecule seems ok
            fvs = [v for v in self.structure.vertices if v.free_valency]
            if not fvs and not filter(
                    None, [not v.order for v in self.structure.edges]):
                repeat = False
            else:
                if len(fvs) == 1:
                    a = fvs[0]
                    a.symbol = a.symbol  # this resets the valency
                    a.raise_valency_to_senseful_value()
                    if not a.free_valency:
                        repeat = False

            if repeat and self._no_possibility_to_improve and self.charge:
                try:
                    self._charge_mover.next()
                except StopIteration:
                    pass
                else:
                    self._no_possibility_to_improve = False
                    run = 0

        if repeat and self._no_possibility_to_improve:
            ##       if len( filter( None, [v.free_valency for v in self.structure.vertices])) == 1:
            ##         print
            ##         print [(v.symbol, v.valency, v.free_valency)  for v in self.structure.vertices if v.free_valency], filter( None, [not v.order for v in self.structure.edges]), text
            ##       if sum( [v.charge for v in self.structure.vertices]) != self.charge:
            ##         print "Charge problem", sum( [v.charge for v in self.structure.vertices]), self.charge
            #pass
            raise oasa_inchi_error(
                "Localization of bonds, charges or movable hydrogens failed")