def ir_spectra(self, threshold=20): pairs = [] for a, b in zip(self.frequencies(), self.ir_intensities()): if is_str_float(a) and is_str_float(b): pairs.append([float(a), float(b)]) for a, b in zip(sorted(pairs, key=lambda x: x[1], reverse=True), range(threshold)): print("{:>10.1f}{:>10.1f}".format(float(a[0]), float(a[1]))) print("---------")
def __init__(self, file_content): self.list = file_content if len(self.list) < 2: raise Exception(".xyz Object is empty?") elif not (str(self.list[1]).strip().isdigit() and len(str(self.list[1]).split()) == 1): print( "{} is not a proper .xyz file\nAttempting to read it anyway!". format(self.list[0])) try_xyz = [] for line in self.list: line = line.split() if len(line) != 4: continue if not all(is_str_float(line[i]) for i in range(1, 4)): continue if line[0] in elements[0:]: try_xyz.append(" ".join(line)) continue try: line[0] = elements[int(line[0])] try_xyz.append(" ".join(line)) except: raise Exception("Could not understand file {}".format( self.list[0])) try_xyz.insert(0, len(try_xyz)) try_xyz.insert(1, " ") try_xyz.insert(0, self.list[0]) self.list = try_xyz self.list_l = [str(a).split() for a in self.list]
def __init__(self, line, idx): assert type(line) is list assert len(line) == 4 assert line[0] in elements assert all(is_str_float(a) for a in line[1:]) self.idx = idx self.element = line[0] self.cord = [float(a) for a in line[1:]]
def low_e_xyz_obj(self): if self.calc_type == "SP": return None else: xyzs = { "TS": self.opt, "Red": self.scan_geoms, "IRC": self.irc, "Opt": self.opt }[self.calc_type]() if len(xyzs) == 0: return None else: return sorted(xyzs, key=lambda x: float(x.title()) if is_str_float(x.title()) else 1)[0]
def read_strucure(self): charge_mult = None title = None coordinates = [] for i, a in enumerate(self.list[self.hash_line:]): if i > 5 and not coordinates: break a = a.split(",") if len(a) == 2 and not coordinates: charge_mult = a continue if len(a) == 4: if a[0] in elements and all( is_str_float(a[n]) for n in [1, 2, 3]): coordinates.append(" ".join(a)) elif coordinates: break elif coordinates: break return charge_mult, XyzFile( [self.list[0], str(len(coordinates)), title, *coordinates])
def first_cord_block(self): if not all([self.start_xyz_idxs, self.end_xyz_idxs]): if self.input_geom_idx: coordinates = [] for i, a in enumerate(self.list[self.input_geom_idx:]): if i > 5 and not coordinates: break a = a.split() if len(a) == 4: if a[0] in elements and all( is_str_float(a[n]) for n in [1, 2, 3]): coordinates.append(a) elif coordinates: break elif coordinates: break return coordinates else: return None else: return self.xyz_cord_block(self.start_xyz_idxs[0], self.end_xyz_idxs[0])
def csv_e_analysis(): options = ["Free energy","+A", "+B", "+C", "+D", "-E", "-F", "Structure", "Rel_E", \ "FOLD", "Filename", "XYZ", "INP", "LOG", "TYP", "iFreq", "Needs refinement?", "Done?",\ "last_SCF", "Hentalphy", "Log Route","Inp Route", "Error msg"] def idx(name): return options.index(name) def evaluate_list(folder, files=set()): for file in os.listdir(folder): if os.path.isdir(os.path.join(folder, file)): evaluate_list(os.path.join(folder, file), files) elif any([ file.endswith(".log"), file.endswith(".xyz"), file.endswith(preferences.gauss_ext) ]): files.add(os.path.join(folder, os.path.splitext(file)[0])) return files def evaluate_file(a, options, i, last): try: row = ["None" for _ in options] #FILE PROPERTIES row[idx("Filename")] = os.path.basename(a) #FOLDER PROPERTIES fold_name = os.path.dirname(a) row[idx("FOLD")] = 'HYPERLINK("{}";"{}")'.format( fold_name, os.path.relpath(fold_name, os.getcwd())) #INPUT PROPERTIES inp_name = a + preferences.gauss_ext is_inp = os.path.isfile(os.path.relpath(inp_name, os.getcwd())) inp = GjfFile(read_item(os.path.relpath( inp_name, os.getcwd()))) if is_inp else False row[idx("INP")] = 'HYPERLINK("{}";"Link")'.format( inp_name) if is_inp else "-" row[idx("Inp Route")] = inp.route_text() if inp else "No data" #XYZ PROPERTIES xyz_name = a + ".xyz" is_xyz = os.path.isfile(os.path.relpath(xyz_name, os.getcwd())) row[idx("XYZ")] = 'HYPERLINK("{}";"Link")'.format( xyz_name) if is_xyz else "-" #LOG PROPERTIES log_name = a + ".log" is_log = os.path.isfile(os.path.relpath(log_name, os.getcwd())) log = LogFile(read_item(os.path.relpath( log_name, os.getcwd()))) if is_log else False freq = log and log.last_freq row[idx("Free energy")] = str( log.thermal[7]) if freq else "No data" row[idx("+A")] = "-" row[idx("+B")] = "-" row[idx("+C")] = "-" row[idx("+D")] = "-" row[idx("-E")] = "-" row[idx("-F")] = "-" row[idx("Structure")] = "-" row[idx( "Rel_E" )] = "(SUM($A#:$E#)-SUM($F#:$G#)-SUM($A#:$E#)+SUM($F#:$G#))*627.509474" row[idx("iFreq")] = log.last_freq.n_ifreq() if freq else "-" row[idx("TYP")] = log.calc_type if log else "-" row[idx("LOG")] = 'HYPERLINK("{}";"Link")'.format( log_name) if log else "-" row[idx("Done?")] = "Yes" if log and log.normal_termin else "No" row[idx("last_SCF")] = str( log.scf_done[-1][-1]) if log and log.normal_termin else "-" row[idx("Hentalphy")] = str(log.thermal[6]) if freq else "-" row[idx("Error msg")] = log.error_msg if log else "-" row[idx("Needs refinement?")] = log.needs_ref() if log else "-" row[idx("Log Route")] = log.raw_route if log else "-" except Exception as e: print() print("\nError on file:\n{}\n".format(a)) print(e, "\n") finally: if i + 1 < last: print("\rEvaluating... {}/{}".format(i + 1, last), end=" ") else: print( "\rEvaluation done ({}/{}), saving '.xls' file...".format( i + 1, last)) return row files = evaluate_list(os.getcwd()) csv_list = [ evaluate_file(file, options, i, len(files)) for i, file in enumerate(files) ] if not csv_list: return print("No .log files in {} directory".format(os.getcwd())) csv_list.sort(key=lambda x: x[idx("FOLD")]) try: import xlwt from xlwt import Workbook except ImportError: print("xlwt module is needed") return wb = Workbook() sheet1 = wb.add_sheet('Data') style0 = xlwt.easyxf("", "#.0000000") for i_b, b in enumerate(options): sheet1.write(0, i_b, b) for i_a, a in enumerate(csv_list, start=1): a[idx("Rel_E")] = a[idx("Rel_E")].replace("#", str(i_a + 1)) for i_b, b in enumerate(a): if i_b in [ idx(term) for term in ("Free energy", "last_SCF", "Hentalphy") ]: sheet1.write(i_a, i_b, float(b) if is_str_float(b) else b, style0) elif i_b in [ idx(term) for term in ("FOLD", "XYZ", "INP", "LOG", "Rel_E") ]: try: sheet1.write(i_a, i_b, xlwt.Formula(b)) except Exception: sheet1.write(i_a, i_b, b) else: sheet1.write(i_a, i_b, b) try: wb.save("linked_analysis.xls") except PermissionError: print( "Error while saving file!\nIs the file '{}' already open?".format( "linked_analysis.xls"))
def save_gjf(self,parameters,index): heavy_e, gjf_overwrite, folder_op = [preferences.heavy_atom,preferences.gjf_overwrite,preferences.folder_op] ecps, basis = None, None if not folder_op: self.weeded_list = sel_files(self.weeded_list) if not self.weeded_list: return if any([b in parameters for b in ["INSERT_GBS_BASIS","INSERT_GBS_ECP"]]): print("This parameter file requires an aditional gbs file.") print("Where should it be taken from?") print("0 - Current folder") print("1 - Builtins") print("2 - User defined") while True: option = input() if option in ["0","1","2"]: break if option == "0": files_dir = os.getcwd() elif option == "1": files_dir = self.p_files_dir elif option == "2": files_dir = self.user_files_dir gbs_files = file_weeder([".gbs"], cf=files_dir) print("Chosse one basis/ecp set\n0 - Cancel") for i, file in enumerate(gbs_files): print("{} - {}".format(i+1, file)) while True: option = input() if option in [str(a) for a in range(len(gbs_files)+1)]: break print("Invalid option") if option == "0": return with open(os.path.join(files_dir,gbs_files[int(option)-1])) as file: gbs_file = file.read().splitlines() basis, ecps = self.read_gbs(gbs_file) assert type(basis) == dict, "Basis was not read" assert type(ecps) == dict, "Ecps were not read" for i in self.weeded_list: try: gjf_out, rm_lines, = [], [] if os.path.isfile(os.path.join(os.getcwd(),(i.replace(self.original_ext,preferences.gauss_ext)))) and not gjf_overwrite: print(i.replace(self.original_ext,preferences.gauss_ext) + " already exist on current directory!") continue xyz = LogFile(read_item(i)).last_xyz_obj() if self.use_logs else XyzFile(read_item(i)) for idx_a,line in enumerate(parameters[0:index]): if self.use_logs and idx_a+1 == len(parameters[0:index]): line = " ".join(LogFile(read_item(i)).charge_mult) gjf_out.append(line.replace("FILENAME",i.replace(self.original_ext,""))+"\n") for line in xyz.form_cord_block(): gjf_out.append(line+"\n") possible = [str(b + 1) for b in range(xyz.n_atoms())] for line in parameters[index+1:]: # SCAN like: "B S APROX" or "B S DIST" is_mod_red = any("modredundant" in i.lower() for i in parameters[0:index]) s_line = line.split() while len(s_line) == 3: if s_line[0] != "B" or s_line[1] != "S": break if s_line[2] not in ["APROX","DIST"]: break if not is_mod_red: print("Missing 'modredundant' keyword?") break if xyz.n_atoms() <2: raise Exception(f"At least two atoms are neded in struture {xyz.name()} to perform a scan") atom=["a","b"] if s_line[-1] == "APROX": print(f"Detected bond scan (APROX) for xyz file {i}.") while not all(atom[a] in possible if atom[0] != atom[1] else False for a in [0,1]): atom = [input("Enter atom A: "),input("Enter atom B: ")] line = f"B {atom[0]} {atom[1]} S APROX" elif s_line[-1] == "DIST": print(f"Detected bond scan (DIST) for xyz file {i}.") while not all(atom[a] in possible if atom[0] != atom[1] else False for a in [0,1]): atom = [input("Enter atom A: "),input("Enter atom B: ")] line = f"B {atom[0]} {atom[1]} S DIST" s_line = line.split() break # SCAN like: "B 1 2 S APROX" or "B 1 2 S DIST" while len(s_line) == 5: if s_line[0] != "B" or s_line[3] != "S": break if not s_line[1].isdigit(): break if not s_line[2].isdigit(): break if s_line[4] not in ["APROX", "DIST"]: break if not is_mod_red: print("Missing 'modredundant' keyword?") break if xyz.n_atoms() < 2: raise Exception(f"At least two atoms are neded in struture {xyz.name()} to perform a scan") atoms_idx = [int(s_line[1])-1, int(s_line[2])-1] if any(True for a in atoms_idx if not a in range(xyz.n_atoms())): raise Exception(f"Scan atom numbers are larger than the number of atoms for: {xyz.name()}") atoms_cord = [i for idx,i in enumerate(xyz.cord_block()) if idx in atoms_idx] dist = math.sqrt(sum((float(i)-float(atoms_cord[1][idx]))**2 for idx,i in enumerate(atoms_cord[0]) if idx > 0)) ideal_dist=sum(b[1] for idx,b in enumerate(element_radii) if b[0] in [i[0] for i in atoms_cord])/100 if s_line[-1] == "APROX": line = line.replace("APROX",f"{1+int((dist-ideal_dist)/0.075)} -0.075") elif s_line[-1] == "DIST": line = line.replace("DIST",f"{1+int(ideal_dist/0.075)} 0.075") s_line = line.split() break # SCAN like: "D S" while len(s_line) == 2: if not is_mod_red: break if s_line[0] != "D" or s_line[1] != "S": break print(f"Detected dihedral scan for xyz file {i}.") if xyz.n_atoms() < 4: raise Exception(f"At least two four atoms are neded in struture {xyz.name()} to perform a dihedral scan") while True: atom = [input(f"Enter atom {a}: ") for a in ["A","B","C","D"]] atom = [a.strip() for a in atom] if not all([len(a.split()) == 1 and a.isdigit() for a in atom]): print("No non-numeric characters or spaces are allowed for atom numbers") continue if not len(set(atom)) == 4: print("No atom should be repeated!") continue if not all([a in possible for a in atom]): print("Atoms with incorrect number were found!") continue break while True: n_steps = input("Please give the number of steps to be taken: ").strip() if n_steps.isdigit(): break else: print("The number of steps must be an integer") while True: print("Please give the step size to be taken in degrees") size = input("The number must include a dot character as a decimal place (eg. '10.0'): ").strip() if is_str_float(size) and size.count(".") == 1: break else: print("Please make sure the number complies with formating rules!") line = f"D {' '.join(atom)} S {n_steps} {size}" s_line = line.split() break # READOPTIMIZE + NOTATOMS if line.replace(" ", "").lower() == "notatoms=": print("Please enter the atoms you want to freeze on structure {} separated by comma".format(xyz.name())) line = line + input(line) # READOPTIMIZE + ATOMS elif line.replace(" ", "").lower() == "noatomsatoms=": print("Please enter the atoms you want to optimize on structure {} separated by comma".format(xyz.name())) line = line + input(line) # BASIS like: "LIGHT_ELEMENT_BASIS 0" or "HEAVY_ELEMENT_BASIS 0" and ECP like "HEAVY_ELEMENT_ECP 0" elif len(s_line) == 2: if any(True for a in ["/gen","gen ","genecp"] if a in " ".join(parameters[0:index-3]).lower()): if s_line == ["LIGHT_ELEMENT_BASIS","0"]: elm = [a for a in xyz.elements() if elements.index(a) < heavy_e+1] if elm: line = line.replace("LIGHT_ELEMENT_BASIS"," ".join(elm)) else: for a in range(3): rm_lines.append(len(gjf_out)+a) elif s_line == ["HEAVY_ELEMENT_BASIS","0"]: elm = [a for a in xyz.elements() if elements.index(a) > heavy_e] if elm: line = line.replace("HEAVY_ELEMENT_BASIS"," ".join(elm)) else: for a in range(3): rm_lines.append(len(gjf_out)+a) if "pseudo=read" in " ".join(parameters[0:index - 3]).lower().replace(" ",""): if s_line == ["HEAVY_ELEMENT_ECP","0"]: elm = [a for a in xyz.elements() if elements.index(a) > heavy_e] if elm: line = line.replace("HEAVY_ELEMENT_ECP"," ".join(elm)) else: pattern = re.compile(r'pseudo.{0,3}=.{0,3}read',re.IGNORECASE) eval_lines = gjf_out[0:index-3] for idx_a,a in enumerate(eval_lines): gjf_out[idx_a] = pattern.sub("",a) rm_lines.append(len(gjf_out)) rm_lines.append(len(gjf_out)+1) # BASIS like: "INSERT_GBS_BASIS" elif "INSERT_GBS_BASIS" in line: for element in sorted(xyz.elements(),key=lambda x: elements.index(x)): for line_a in basis[element]: gjf_out.append(line_a+"\n") continue # ECP like: "INSERT_GBS_ECP" elif "INSERT_GBS_ECP" in line: if "pseudo=read" in " ".join(parameters[0:index - 3]).lower().replace(" ", ""): need_ecp = [a for a in xyz.elements() if elements.index(a) > preferences.heavy_atom] for element in sorted(need_ecp,key=lambda x: elements.index(x)): for line_a in ecps[element]: gjf_out.append(line_a+"\n") if not need_ecp: pattern = re.compile(r'pseudo.{0,3}=.{0,3}read', re.IGNORECASE) eval_lines = gjf_out[0:index - 3] for idx_a, a in enumerate(eval_lines): gjf_out[idx_a] = pattern.sub("", a) continue gjf_out.append(line.replace("FILENAME",i.replace(self.original_ext,""))+"\n") gjf_out.append("\n") with open(os.path.join(os.getcwd(),(i.replace(self.original_ext,preferences.gauss_ext))),"w") as gjf_file: for line in [i for idx,i in enumerate(gjf_out) if idx not in rm_lines]: gjf_file.write(line) print(i.replace(self.original_ext,preferences.gauss_ext)," created!") except TypeError as e: print("Error on file {}".format(i)) print(e) return