def parseLines(self, lines): """Parse list of lines in RAWXYZ format. Return Structure object or raise StructureFormatError. """ linefields = [l.split() for l in lines] # prepare output structure stru = Structure() # find first valid record start = 0 for field in linefields: if len(field) == 0 or field[0] == "#": start += 1 else: break # find the last valid record stop = len(lines) while stop > start and len(linefields[stop - 1]) == 0: stop -= 1 # get out for empty structure if start >= stop: return stru # here we have at least one valid record line # figure out xyz layout from the first line for plain and raw formats floatfields = [isfloat(f) for f in linefields[start]] nfields = len(linefields[start]) if nfields not in (3, 4): emsg = ("%d: invalid RAWXYZ format, expected 3 or 4 columns" % (start + 1)) raise StructureFormatError(emsg) if floatfields[:3] == [True, True, True]: el_idx, x_idx = (None, 0) elif floatfields[:4] == [False, True, True, True]: el_idx, x_idx = (0, 1) else: emsg = "%d: invalid RAWXYZ format" % (start + 1) raise StructureFormatError(emsg) # now try to read all record lines try: p_nl = start for fields in linefields[start:]: p_nl += 1 if fields == []: continue elif len(fields) != nfields: emsg = ('%d: all lines must have ' + 'the same number of columns') % p_nl raise StructureFormatError, emsg symbol = el_idx is not None and fields[el_idx] or "" xyz = [float(f) for f in fields[x_idx:x_idx + 3]] if len(xyz) == 2: xyz.append(0.0) stru.addNewAtom(symbol, xyz=xyz) except ValueError: emsg = "%d: invalid number" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() raise StructureFormatError, emsg, exc_traceback return stru
def parseLines(self, lines): """Parse list of lines in RAWXYZ format. Return Structure object or raise StructureFormatError. """ linefields = [l.split() for l in lines] # prepare output structure stru = Structure() # find first valid record start = 0 for field in linefields: if len(field) == 0 or field[0] == "#": start += 1 else: break # find the last valid record stop = len(lines) while stop > start and len(linefields[stop-1]) == 0: stop -= 1 # get out for empty structure if start >= stop: return stru # here we have at least one valid record line # figure out xyz layout from the first line for plain and raw formats floatfields = [ isfloat(f) for f in linefields[start] ] nfields = len(linefields[start]) if nfields not in (3, 4): emsg = ("%d: invalid RAWXYZ format, expected 3 or 4 columns" % (start + 1)) raise StructureFormatError(emsg) if floatfields[:3] == [True, True, True]: el_idx, x_idx = (None, 0) elif floatfields[:4] == [False, True, True, True]: el_idx, x_idx = (0, 1) else: emsg = "%d: invalid RAWXYZ format" % (start + 1) raise StructureFormatError(emsg) # now try to read all record lines try: p_nl = start for fields in linefields[start:] : p_nl += 1 if fields == []: continue elif len(fields) != nfields: emsg = ('%d: all lines must have ' + 'the same number of columns') % p_nl raise StructureFormatError, emsg symbol = el_idx is not None and fields[el_idx] or "" xyz = [ float(f) for f in fields[x_idx:x_idx+3] ] if len(xyz) == 2: xyz.append(0.0) stru.addNewAtom(symbol, xyz=xyz) except ValueError: emsg = "%d: invalid number" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() raise StructureFormatError, emsg, exc_traceback return stru
def parseLines(self, lines): """Parse list of lines in PDB format. Return Structure object or raise StructureFormatError. """ xcfg_Number_of_particles = None xcfg_A = None xcfg_H0 = numpy.zeros((3, 3), dtype=float) xcfg_H0_set = numpy.zeros((3, 3), dtype=bool) xcfg_NO_VELOCITY = False xcfg_entry_count = None xcfg_auxiliary = [] p_nl = 0 p_auxiliary_re = re.compile(r"^auxiliary\[(\d+)\] =") p_auxiliary = {} try: stru = Structure() # ignore trailing blank lines stop = len(lines) while stop > 0 and lines[stop - 1].strip() == "": stop -= 1 ilines = iter(lines[:stop]) # read XCFG header for line in ilines: p_nl += 1 stripped_line = line.strip() # blank lines and lines starting with # are ignored if stripped_line == "" or line[0] == '#': continue elif xcfg_Number_of_particles is None: if line.find("Number of particles =") != 0: emsg = ("%d: first line must " + "contain 'Number of particles ='") % p_nl raise StructureFormatError(emsg) xcfg_Number_of_particles = int(line[21:].split(None, 1)[0]) p_natoms = xcfg_Number_of_particles elif line.find("A =") == 0: xcfg_A = float(line[3:].split(None, 1)[0]) elif line.find("H0(") == 0: i, j = (int(line[3]) - 1, int(line[5]) - 1) xcfg_H0[i, j] = float(line[10:].split(None, 1)[0]) xcfg_H0_set[i, j] = True elif line.find(".NO_VELOCITY.") == 0: xcfg_NO_VELOCITY = True elif line.find("entry_count =") == 0: xcfg_entry_count = int(line[13:].split(None, 1)[0]) elif p_auxiliary_re.match(line): m = p_auxiliary_re.match(line) idx = int(m.group(1)) p_auxiliary[idx] = line[m.end():].split(None, 1)[0] else: break # check header for consistency if numpy.any(xcfg_H0_set == False): emsg = "H0 tensor is not properly defined" raise StructureFormatError(emsg) p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys()) + 1 for i in range(p_auxnum): if not i in p_auxiliary: p_auxiliary[i] = "aux%d" % i sorted_aux_keys = p_auxiliary.keys() sorted_aux_keys.sort() if p_auxnum != 0: stru.xcfg = { 'auxiliaries': [p_auxiliary[k] for k in sorted_aux_keys] } if 6 - 3 * xcfg_NO_VELOCITY + len(p_auxiliary) != xcfg_entry_count: emsg = ("%d: auxiliary fields " + "not consistent with entry_count") % p_nl raise StructureFormatError(emsg) # define proper lattice stru.lattice.setLatBase(xcfg_H0) # build p_assign_atom function to assign entries to proper fields p_exprs = [ "a.xyz[0]=fields[0]", "a.xyz[1]=fields[1]", "a.xyz[2]=fields[2]" ] if not xcfg_NO_VELOCITY: p_exprs += [ "a.v=numpy.zeros(3, dtype=float)", "a.v[0]=fields[3]", "a.v[1]=fields[4]", "a.v[2]=fields[5]" ] for idx in sorted_aux_keys: prop = p_auxiliary[idx] col = idx + 6 - 3 * xcfg_NO_VELOCITY if prop == "Uiso": p_exprs.append("a.U[0,0]=a.U[1,1]=a.U[2,2]=" + "fields[%d]" % col) elif re.match(r"^U\d\d$", prop) \ and 1<=int(prop[1])<=3 and 1<=int(prop[2])<=3 : i, j = int(prop[1]) - 1, int(prop[2]) - 1 if i == j: p_exprs.append("a.U[%i,%i]=fields[%d]" % (i, j, col)) else: p_exprs.append("a.U[%i,%i]=a.U[%i,%i]=fields[%d]" % \ (i, j, j, i, col) ) else: p_exprs.append( "a.__dict__[%r]=fields[%d]" % \ (prop, col) ) p_assign_expr = "pass; " + "; ".join(p_exprs[3:]) exec "def p_assign_atom(a, fields) : %s" % p_assign_expr # here we are inside data p_element = None p_nl -= 1 for line in lines[p_nl:stop]: p_nl += 1 words = line.split() # ignore atom mass if len(words) == 1 and isfloat(words[0]): continue # parse element allowing empty symbol elif len(words) <= 1: w = line.strip() p_element = w[:1].upper() + w[1:].lower() elif len(words) == xcfg_entry_count and p_element is not None: fields = [float(w) for w in words] stru.addNewAtom(p_element, fields[:3]) a = stru.getLastAtom() a.xyz *= xcfg_A p_assign_atom(a, fields) else: emsg = "%d: invalid record" % p_nl raise StructureFormatError(emsg) if len(stru) != p_natoms: emsg = "expected %d atoms, read %d" % (p_natoms, len(stru)) raise StructureFormatError(emsg) except (ValueError, IndexError): emsg = "%d: file is not in XCFG format" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() raise StructureFormatError, emsg, exc_traceback return stru
def parseLines(self, lines): """Parse list of lines in PDB format. Return Structure object or raise StructureFormatError. """ xcfg_Number_of_particles = None xcfg_A = None xcfg_H0 = numpy.zeros((3,3), dtype=float) xcfg_H0_set = numpy.zeros((3,3), dtype=bool) xcfg_NO_VELOCITY = False xcfg_entry_count = None xcfg_auxiliary = [] p_nl = 0 p_auxiliary_re = re.compile(r"^auxiliary\[(\d+)\] =") p_auxiliary = {} try: stru = Structure() # ignore trailing blank lines stop = len(lines) while stop>0 and lines[stop-1].strip() == "": stop -= 1 ilines = iter(lines[:stop]) # read XCFG header for line in ilines: p_nl += 1 stripped_line = line.strip() # blank lines and lines starting with # are ignored if stripped_line == "" or line[0] == '#': continue elif xcfg_Number_of_particles is None: if line.find("Number of particles =") != 0: emsg = ("%d: first line must " + "contain 'Number of particles ='") % p_nl raise StructureFormatError(emsg) xcfg_Number_of_particles = int(line[21:].split(None, 1)[0]) p_natoms = xcfg_Number_of_particles elif line.find("A =") == 0: xcfg_A = float(line[3:].split(None, 1)[0]) elif line.find("H0(") == 0: i, j = ( int(line[3])-1 , int(line[5])-1 ) xcfg_H0[i,j] = float(line[10:].split(None, 1)[0]) xcfg_H0_set[i,j] = True elif line.find(".NO_VELOCITY.") == 0: xcfg_NO_VELOCITY = True elif line.find("entry_count =") == 0: xcfg_entry_count = int(line[13:].split(None, 1)[0]) elif p_auxiliary_re.match(line): m = p_auxiliary_re.match(line) idx = int(m.group(1)) p_auxiliary[idx] = line[m.end():].split(None, 1)[0] else: break # check header for consistency if numpy.any(xcfg_H0_set == False): emsg = "H0 tensor is not properly defined" raise StructureFormatError(emsg) p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys())+1 for i in range(p_auxnum): if not i in p_auxiliary: p_auxiliary[i] = "aux%d" % i sorted_aux_keys = p_auxiliary.keys() sorted_aux_keys.sort() if p_auxnum != 0: stru.xcfg = { 'auxiliaries' : [ p_auxiliary[k] for k in sorted_aux_keys ] } if 6-3*xcfg_NO_VELOCITY+len(p_auxiliary) != xcfg_entry_count: emsg = ("%d: auxiliary fields " + "not consistent with entry_count") % p_nl raise StructureFormatError(emsg) # define proper lattice stru.lattice.setLatBase(xcfg_H0) # build p_assign_atom function to assign entries to proper fields p_exprs = [ "a.xyz[0]=fields[0]", "a.xyz[1]=fields[1]", "a.xyz[2]=fields[2]" ] if not xcfg_NO_VELOCITY: p_exprs += [ "a.v=numpy.zeros(3, dtype=float)", "a.v[0]=fields[3]", "a.v[1]=fields[4]", "a.v[2]=fields[5]" ] for idx in sorted_aux_keys: prop = p_auxiliary[idx] col = idx + 6 - 3*xcfg_NO_VELOCITY if prop == "Uiso": p_exprs.append("a.U[0,0]=a.U[1,1]=a.U[2,2]=" + "fields[%d]" % col) elif re.match(r"^U\d\d$", prop) \ and 1<=int(prop[1])<=3 and 1<=int(prop[2])<=3 : i, j = int(prop[1])-1, int(prop[2])-1 if i==j: p_exprs.append("a.U[%i,%i]=fields[%d]" % (i, j, col) ) else: p_exprs.append("a.U[%i,%i]=a.U[%i,%i]=fields[%d]" % \ (i, j, j, i, col) ) else: p_exprs.append( "a.__dict__[%r]=fields[%d]" % \ (prop, col) ) p_assign_expr = "pass; " + "; ".join(p_exprs[3:]) exec "def p_assign_atom(a, fields) : %s" % p_assign_expr # here we are inside data p_element = None p_nl -= 1 for line in lines[p_nl:stop]: p_nl += 1 words = line.split() # ignore atom mass if len(words) == 1 and isfloat(words[0]): continue # parse element allowing empty symbol elif len(words) <= 1: w = line.strip() p_element = w[:1].upper() + w[1:].lower() elif len(words) == xcfg_entry_count and p_element is not None: fields = [ float(w) for w in words ] stru.addNewAtom(p_element, fields[:3]) a = stru.getLastAtom() a.xyz *= xcfg_A p_assign_atom(a, fields) else: emsg = "%d: invalid record" % p_nl raise StructureFormatError(emsg) if len(stru) != p_natoms: emsg = "expected %d atoms, read %d" % (p_natoms, len(stru)) raise StructureFormatError(emsg) except (ValueError, IndexError): emsg = "%d: file is not in XCFG format" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() raise StructureFormatError, emsg, exc_traceback return stru