def readColumns(filename, columns=[1, 2]): # Read file and clear out comments with open(filename, 'r') as file: cleanStr = file.read() comments = pp.ZeroOrMore(pp.pythonStyleComment).setParseAction( pp.replaceWith('')) try: cleanStr = comments.transformString(cleanStr) except pp.ParseException as pe: print(('Parsing Error using pyparsing: invalid input:', pe)) sys.exit() # Define grammar for ncols of data based on number of entries in first row floating = pp.Word(pp.nums + ".+-E").setParseAction(lambda t: float(t[0])) EOL = pp.LineEnd().suppress() row1entry = floating.copy().setWhitespaceChars(" \t") row1 = pp.Group(pp.ZeroOrMore(EOL) + pp.OneOrMore(row1entry) + EOL) row = pp.Forward() def defineTotalCols(toks): ncols = len(toks[0]) row << pp.Group(floating * ncols) return None row1.addParseAction(defineTotalCols) text = row1 + pp.ZeroOrMore(row) try: data = text.parseString(cleanStr).asList() except pp.ParseException as pe: print(('Parsing Error using pyparsing: invalid input:', pe)) sys.exit() cols = list(map(list, list(zip(*data)))) return [cols[i - 1] for i in columns]
def readDym(dymFilename): integer = pp.Word(pp.nums).setParseAction(lambda t: int(t[0])) floating = pp.Word(pp.nums + ".+-E").setParseAction(lambda t: float(t[0])) vector = pp.Group(floating * 3) matrix = pp.Group(vector * 3) dymtype = integer ncluster = integer.copy() # Uses unique ParseAction for Forward atNums = pp.Forward() # Placeholders for grabbing ncluster entries atMasses = pp.Forward() atCoords = pp.Forward() def countedParseAction(toks): n = toks[0] atNums << pp.Group(integer * n) atMasses << pp.Group(floating * n) atCoords << pp.Group(vector * n) return None ncluster.addParseAction(countedParseAction) dm = pp.Group(pp.OneOrMore(pp.Group(integer * 2 + matrix))) specifics = pp.SkipTo(pp.stringEnd) text = dymtype + ncluster + atNums + atMasses + atCoords + dm + specifics with open(dymFilename, 'r') as f: try: data = text.parseString(f.read()).asList() except pp.ParseException as pe: print(('Parsing Error using pyparsing: invalid input:', pe)) sys.exit() # Construct dym object dym = {'dymType': data[0]} dym['nAt'] = data[1] dym['atNums'] = data[2] dym['atMasses'] = data[3] dym['atCoords'] = data[4] dym['dm'] = [[None for j in range(dym['nAt'])] for i in range(dym['nAt'])] for i, j in ((i, j) for i in range(dym['nAt']) for j in range(dym['nAt'])): index = i * dym['nAt'] + j if data[5][index][0] == i + 1 and data[5][index][1] == j + 1: dym['dm'][i][j] = data[5][index][2] # Parse dymtype-specific items if dym['dymType'] == 2: nUnique = integer nCell = integer centralZAtom = pp.Group(integer + integer + vector) zAtomList = pp.Group(integer + pp.countedArray(centralZAtom)) typeSpecific = nUnique + nCell + pp.Group(pp.OneOrMore(zAtomList)) # Parse try: data = typeSpecific.parseString(data[6]).asList() except pp.ParseException as pe: print(('Parsing Error using pyparsing: invalid input:', pe)) sys.exit() # Store type-specific information if dym['dymType'] == 2: dym['nTypeAt'] = data[0] dym['nCellAt'] = data[1] dym['centerAt'] = {} for zAtomList in data[2]: z = zAtomList[0] dym['centerAt'][z] = [] for centralZAtom in zAtomList[1]: atomInfo = {} atomInfo['clustIndex'] = centralZAtom[0] atomInfo['cellIndex'] = centralZAtom[1] atomInfo['coord'] = centralZAtom[2] dym['centerAt'][z].append(atomInfo) return dym