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" )
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
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
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
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
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")
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!")
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!")
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")
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")