def reader(file, stripHydrogens=1): lines = collector(file) while 1: try: fields = {} name = lines.next().strip() userLine = lines.next().strip() comment = lines.next().strip() molinfo = lines.next() numAtoms, numBonds = int(molinfo[0:3]), int(molinfo[3:6]) atoms = [] # this is the full list of atoms _atoms = [] # this is the (potentially stripped list # of atoms. I.e. no hydrogens.) i = 0 for index in range(numAtoms): line = lines.next() x,y,z,symbol,mass,charge,stereo,hcount,hcount_fixed = parse_atom(line) if symbol == "H" and stripHydrogens: atoms.append(None) else: atom = Atom() atoms.append(atom) _atoms.append(atom) atom.set_symbol(symbol)# = symbol atom.explicit_hcount = hcount atom.charge = charge atom._line = line atom.x = x atom.y = y atom.z = z if hcount_fixed: print "hcount fixed" atom.fixed_hcount = 1 # oops, we shouldn't use this atom.has_explicit_hcount = True if mass: atom.weight = atom.mass + mass atom.index = i i = i + 1 bonds = [] for index in range(numBonds): line = lines.next() a1, a2, bondtype, stereo, remainder = parse_bond(line) symbol, bondorder, bondtype, fixed = BOND_SYMBOL[bondtype] atom1, atom2 = atoms[a1], atoms[a2] if atom1 is not None and atom2 is not None: h1, h2 = atom1.handle, atom2.handle bond = Bond(symbol, bondorder, bondtype, fixed) bonds.append(bond) bond._line = remainder bond.index = index bond.atoms = [atom1, atom2] try: bond.stereo = BOND_LOOKUP_STEREO[bondtype-1][stereo] except KeyError: raise MolReaderError("An SD record cannot have a bondtype of %s and a stereo value of %s"%(bondtype, stereo)) except IndexError: print "*"*44 print line print "bondtype, stereo", bondtype, stero raise atom1.bonds.append(bond) atom2.bonds.append(bond) atom1.oatoms.append(atom2) atom2.oatoms.append(atom1) if atom1.symbol == "H": atom2.explicit_hcount += 1 if atom2.symbol == "H": atom1.explicit_hcount += 1 else: if atom1 is None and atom2 is not None: atom2.explicit_hcount += 1 elif atom2 is None and atom1 is not None: atom1.explicit_hcount += 1 ############################################################## # read the mprops if necessary line = lines.next().strip() while 1: if line and line[0:6] == "M END": line = lines.next().strip() break elif line == "M CHG": groups = line[6:].split()[1:] index = 0 while index < len(groups): atomIndex = int(groups[index]) - 1 atom = self.atoms[atomIndex] charge = int(groups[index+1]) self.atoms[atomIndex].charge = charge index += 2 line = lines.next().strip() elif line and line[0] == ">": break elif line[0:4] == "$$$$": break line = lines.next().strip() # What about end of mol? ############################################################# # read the fields if necessary while line != "$$$$": if line and line[0] == ">": res = FIELDPATTERN.match(line) if res: field, potentialID = res.groups() else: res = ALTFIELDPATTERN.match(line) if res: field = res.groups()[0] potentialID = None else: field, potentialID = None, None if name is None: name = potentialID if field: data = [] line = lines.next().strip() while line and line != "$$$$": data.append(line) line = lines.next().strip() fields[field] = os.linesep.join(data) line = lines.next().strip() mol = Molecule(_atoms, bonds) mol.name = name mol.fields = fields mol.name = name yield mol, lines.dump(), None except StopIteration: break except Exception: line = lines.current.strip() while line[0:4] != "$$$$": line = lines.next().strip() stdout, stderr = sys.stdout, sys.stderr sys.stdout = sys.stderr = io = StringIO() traceback.print_exc() sys.stdout = stdout sys.stderr = stderr yield None, lines.dump(), io.getvalue()