def func_05(mode="print",idx=None): """Insert xyz geometries into input""" if preferences.comp_software == "orca": if mode == "print": print(f"{idx} - Insert .xyz geometries into the corresponding .inp files") elif mode == "run": xyz_insert(file_weeder([".xyz"])) elif preferences.comp_software == "gaussian": if mode == "print": print(f"{idx} - Insert .xyz geometries into the corresponding {preferences.gauss_ext} files") elif mode == "run": xyz_insert(file_weeder([".xyz"]))
def func_06(mode="print",idx=None): """Analyze relative free energies""" if preferences.comp_software == "orca": if mode == "print": print(f"{idx} - Extract free energies from .log files*") elif mode == "run": e_analysis(file_weeder([".log"])) elif preferences.comp_software == "gaussian": if mode == "print": print(f"{idx} - Extract free energies from .log files") elif mode == "run": e_analysis(file_weeder([".log"]))
def deduplicate(): print("Analyzing energies...") energies = [[ b.name, float(b.scf_done[-1][1]), b.normal_termin, b.last_xyz_obj() ] for i in file_weeder([".log"]) for b in [LogFile(read_item(i))]] unique = energies if not unique: print("No log files to be analyzed") return black_list, folder_mov = [], [] print("Starting analysis...") for file in sorted(unique, key=lambda x: (x[2], -x[1]), reverse=True): if file[0] in black_list: continue black_list.append(file[0]) sim_en = [ i for i in unique if i[0] not in black_list and i[1] + 1 > file[1] > i[1] - 1 ] if sim_en: duplicates = [] for obj in sim_en: if obj[3].superimpose(file[3], ret="max_d", conv=6): print("{} is a duplicate of {}".format( obj[3].name(), file[3].name())) duplicates.append(obj[3].name()) black_list.append(obj[3].name()) if duplicates: folder_mov.append([file[3].name(), duplicates]) for folder in folder_mov: subfolder = os.path.join( os.getcwd(), "duplicates_of_{}".format(folder[0].replace(".log", ""))) try: os.mkdir(subfolder) except FileExistsError: pass print("Moving duplicates of {} to the following directory:\n{}".format( folder[0], subfolder)) for file in folder[1]: for alt_file in file_weeder([file.replace(".log", ".")]): try: shutil.move(os.path.join(os.getcwd(), alt_file), os.path.join(subfolder, alt_file)) print("Moved: {}".format(alt_file)) except PermissionError: print("Error while moving log files:") print( "Maybe {} already exists in the following directory:\n{}" .format(alt_file, subfolder)) except FileNotFoundError: print("File {} not found in the following directory:\n{}". format(alt_file, subfolder)) print("Done!")
def func_03(self,mode="print",idx=None): """Validade inputs and possibly create pbs files""" if preferences.comp_software == "orca": if mode == "print": if self.pbs: print(f'{idx} - Create .pbs files and a submission script from .inp files') else: print(f'{idx} - Validate .inp files') elif mode == "run": validate_input(file_weeder([".inp"])) elif preferences.comp_software == "gaussian": if mode == "print": if self.pbs: print(f"{idx} - Create .pbs files and a submission script from {preferences.gauss_ext} files") else: print(f"{idx} - Validate {preferences.gauss_ext} files") elif mode == "run": validate_input(file_weeder([preferences.gauss_ext]))
def xyz_ent(): weeded_list = file_weeder([".xyz"]) weeded_list = weeded_list if preferences.folder_op else sel_files(weeded_list) if not weeded_list: return for i in weeded_list: xyz = XyzFile(read_item(i)).enantiomer() xyz.save_file()
def log_to_xyz_scan(): weeded_list = sel_files(file_weeder([".log"])) for item in weeded_list: log = LogFile(read_item(item)) if log.calc_type.lower() == "red": xyzs = log.scan_geoms(); ext_name = "_scan_traject.xyz" elif log.calc_type.lower() == "irc": xyzs = log.irc(); ext_name = "_irc_traject.xyz" elif log.calc_type.lower() in ["opt","ts"]: xyzs = log.opt(); ext_name = "_opt_traject.xyz" else: print("The file is not a scan, opt or irc log file"); continue if len(xyzs) < 2: print("The file contains less than 2 steps") is_terse_irc = all([len(xyzs) < 2, log.calc_type == "IRC", log.raw_route.lower().startswith("#t") or log.raw_route.lower().startswith("# t ")]) if is_terse_irc: print("WARNING! Error above may have been caused by the following:") print("IRC calculations with the #T keyword may not archive intermediate geometries") print("#N or #P keywords are recommended instead") continue max_e = max(float(i.title()) for i in xyzs) min_e = min(float(i.title()) for i in xyzs) c=[0,"percentage","kcal"] print("{:5}{:^90}{:>8}".format("Entry"," >---> Relative Energy >---> "," kcal")) for entry in [float(i.title()) for i in xyzs]: c[0]=c[0]+1 c[1]= "|"*int(90*((float(entry)-min_e)/(max_e-min_e)) if max_e != min_e else 0) c[2]= (float(entry)-min_e)*627.5 print("{:<5}{:<90}".format(c[0],c[1]),"{:>6.5f}".format(c[2]) if ext_name == "_opt_traject.xyz" else "{:>6.2f}".format(c[2])) file_name = item.replace(".log",ext_name) with open(file_name,mode="w",newline="\n") as file: file.write("\n".join([a for i in xyzs for a in i.return_print()]))
def __init__(self,use_logs=False): self.use_logs = use_logs self.original_ext = ".log" if use_logs else ".xyz" self.template_ext = ".GAUSSIAN" if preferences.comp_software == "gaussian" else ".ORCA" self.extension = preferences.gauss_ext if preferences.comp_software == "gaussian" else ".inp" self.weeded_list = file_weeder([self.original_ext]) self.p_files_dir = os.path.join(os.path.dirname(__file__),"builtin_templates") self.user_files_dir = os.path.join(os.path.dirname(__file__), "par_templates") self.submit_parameters()
def input_to_xyz(): extension = preferences.gauss_ext if preferences.comp_software == "gaussian" else ".inp" weeded_list = file_weeder([extension]) weeded_list = weeded_list if preferences.folder_op else sel_files(weeded_list) if not weeded_list: return for i in weeded_list: if preferences.comp_software == "orca": xyz = InpFile(read_item(i)).xyz_obj() xyz.save_file() elif preferences.comp_software == "gaussian": xyz = GjfFile(read_item(i)).xyz_obj() xyz.save_file()
def submit_parameters(self): l_files = file_weeder([self.template_ext]) if len(l_files) == 1: print("Reading parameters from {} in current folder".format(l_files[0])) parameters = read_item(l_files[0]) self.find_idx(parameters) elif len(l_files) > 1: l_files.insert(0, None) option = True print("Chose a parameter file:") for idx, i in enumerate(l_files): if i is None: print(" 0 - Cancel") else: print("{:>3} - {}".format(idx, i)) while option == True: option = {str(idx): i for idx, i in enumerate(l_files)}.get(input(), True) if option is None: return else: parameters = read_item(option); self.find_idx(parameters) else: print("Could not find {} file on current file".format(self.template_ext)) option = True while option == True: print("Chose an option:") print("0 - To cancel") print("1 - Use builtins") print("2 - User defined") option = {str(i): str(i) for i in range(3)}.get(input(), True) if option == "0": return else: folder = self.p_files_dir if option == "1" else self.user_files_dir p_files = file_weeder([self.template_ext], cf=folder) p_files.insert(0, None) print(f"Reading {self.template_ext} files from:\n{folder}\nChoose a parameter file:") option_2 = True for idx, i in enumerate(p_files): if i == None: print(" 0 - Cancel") else: print("{:>3} - {}".format(idx, i)) while option_2 == True: option_2 = {str(idx): i for idx, i in enumerate(p_files)}.get(input(), True) if option_2 == None: return else: shutil.copy(os.path.join(folder, option_2), os.path.join(os.getcwd(), "PARAMETERS{}".format(self.template_ext))) self.try_again()
def superimpose_alg(): while True: print("Chosse an option:") print("0 - To cancel") print("1 - For batch mode") print("2 - For single structure(In screen printing)") mode = input() if mode in [str(n) for n in range(3)]: break if mode == "0": return elif mode == "1": if os.path.exists(os.path.join(os.getcwd(), "rotated")): print("Rotated directory already exists in current directory!") print("Please remove it and try again.") return os.mkdir(os.path.join(os.getcwd(), "rotated")) xyz_1 = read_item(None, "Which item do you wish to compare to?", [".xyz"]) if xyz_1: xyz_1 = XyzFile(xyz_1) else:return while True: num_atoms = input("compare first N atoms (0 for all):\n") if num_atoms in [str(a) for a in range(xyz_1.n_atoms())]: num_atoms = int(num_atoms) break else: print("Invalid input for {}".format(xyz_1.name())) for file in file_weeder(["xyz"]): if not file == xyz_1.name(): xyz_2 = XyzFile(read_item(file)) xyz_3 = xyz_2.superimpose(xyz_1, num_atoms, True) xyz_3.save_file(os.path.join(os.getcwd(), "rotated")) xyz_1.std_cord(num_atoms).save_file(os.path.join(os.getcwd(), "rotated")) elif mode == "2": xyz_1 = read_item(None, "Which item do you wish to compare to?", [".xyz"]) if xyz_1: xyz_1 = XyzFile(xyz_1) else: return xyz_2 = read_item(None, "Which item do you wish to rotate?", [".xyz"]) if xyz_2: xyz_2 = XyzFile(xyz_2) else:return while True: num_atoms = input("compare first N atoms (0 for all):\n") if num_atoms in [str(a) for a in range(min([xyz_1.n_atoms(),xyz_2.n_atoms()]))]: num_atoms = int(num_atoms) break else: print("Invalid input for either or both {} and {}".format(xyz_1.name(),xyz_2.name())) xyz_2.superimpose(xyz_1, num_atoms, True).print_file() xyz_1.std_cord(num_atoms).print_file()
def rel_scf(list=False): energies = [] for i in file_weeder([".log"]): log = LogFile(read_item(i)) energies.append([log.name, log.scf_done[-1][1], log.normal_termin]) if len(energies) == 0: print("No .log files in current folder") return energies = [[i[0], float(i[1]), i[2]] for i in energies] energies.sort(key=lambda x: x[1]) min_e = energies[0][1] energies = [[i[0], (i[1] - min_e) * 627.509, i[2]] for i in energies] if list == False: print("\n".join(["{:>30}{:>15f}{:>5}".format(*l) for l in energies])) elif list == True: return energies
def log_to_xyz(): weeded_list = file_weeder([".log"]) weeded_list = weeded_list if preferences.folder_op else sel_files(weeded_list) if not weeded_list: return while True: print("Which geometry do you want?") print("0 - Cancel") print("1 - Last") print("2 - Lowest energy") print("3 - First") geom = input() if geom == "0": return if geom in ["1","2","3"]: break else: print("Invalid option!") for i in weeded_list: try: if geom == "1": LogFile(read_item(i)).last_xyz_obj().save_file() elif geom == "2": LogFile(read_item(i)).low_e_xyz_obj().save_file() elif geom == "3": LogFile(read_item(i)).first_xyz_obj().save_file() except Exception as e: print("Error on file: {}".format(i)) print(e)
def deploy(): scripts_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"scripts") while True: options = file_weeder([".py"], scripts_dir) options = [a for a in options if a != "__init__.py"] options.insert(0, "To cancel") print("Which script do you want to paste in the current folder?") for idx, i in enumerate(options): print("{:>3} - {}".format(idx, i)) option = input() if option in [str(a) for a in range(len(options))]: break if option == "0": return else: with open(os.path.join(scripts_dir,options[int(option)])) as file: script = file.readlines() script = [a.replace("sub_s_name",preferences.sub_s_name) for a in script] script = [a.replace(".gjf", preferences.gauss_ext) for a in script] with open((os.path.join(os.getcwd(), options[int(option)])), "w", newline="\n") as file_b: for line in script: file_b.write(str(line))
def log_freq_xyz(): weeded_list = sel_files(file_weeder([".log"])) for i in weeded_list: log = LogFile(read_item(i)) if not log.last_freq: print("No frequencies found in file:{}!".format(i)) continue option = None while True: print("Analizing file: {}".format(i)) print("Chose a frequency to split (0-To cancel/m-For more)") for idx,item in enumerate(log.last_freq.frequencies(),start=1): print("{:>5}:{:>15}".format(idx,item)) if option == "m": continue if idx > 2: break option=input() if option == "m": continue elif option in [str(a+1) for a in range(len(log.last_freq.frequencies()))]: break elif option == "0": break else: print("Invalid option, try again!") if option == "0": continue print("Give a multiplier (recomended multiplier = 1) ") while True: try: mult=float(input().replace(",",".")) break except ValueError: print("Not a valid number") left = log.last_xyz_obj().displace(-mult,log.last_freq.displ_for_freq_idx(int(option)-1)) left.list[0] = i.replace(".log","_l.xyz") left.save_file() right = log.last_xyz_obj().displace(mult,log.last_freq.displ_for_freq_idx(int(option)-1)) right.list[0] = i.replace(".log","_r.xyz") right.save_file() print("\nJob Done!\n") print("Finished !")
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