def __init__(self, link="./simulation/", box=None): # Initialize self._link = link if link[-1] == "/" else link+"/" self._config = self._link+"/"+"config.yml" # Create simulation folder if not existent utils.mkdirp(self._link) # Create simulation config file if not existent if not os.path.isfile(self._config): # Get package directory package_dir = os.path.split(__file__)[0]+"/" # Job file file_in = package_dir+"templates/config.yml" file_out = self._config shutil.copy(file_in, file_out) # Load simulation config file with open(self._config, "r") as stream: self._sim_dict = yaml.load(stream, Loader=yaml.FullLoader) # Create box objects boxes = {} for i in self._sim_dict["box"]: temp = Box() temp.set_sim_dict(self._sim_dict["box"][i]) boxes[i] = temp self._sim_dict["box"] = boxes # Add boxes to simulation dictionary if box is not None: boxes = box if isinstance(box, list) else [box] self._sim_dict["box"] = {i:boxes[i] for i in range(len(boxes))} self._update_config()
def __init__(self, link, param): # Initialize self._link = link + "_mdp/" self._param = param # Create folder utils.mkdirp(self._link)
def __init__(self, link, topol): # Initialize self._link = link+"_top/" self._topol = topol # Create folder utils.mkdirp(self._link)
def extract_mol(self, step): """This function extracts molecules of a type from a trajectory for further analysis using MolDyn. Parameters ---------- step : string Step to analyze (**nvt**, **npt**, **run**) """ # Set folder names folder_step = "../" + step + "/" # Set file names file_trr = step + ".trr" file_tpr = step + ".tpr" # Open file utils.mkdirp(self._box_path + "ana") with open(self._box_path + "ana/ana.sh", "w") as file_out: # Check if backup folder is given file_out.write("# Set Todos\n") file_out.write("echo \"Load gromacs ...\"; exit;\n") file_out.write("echo \"Set MOLECULEINDEX ...\"; exit;\n") file_out.write("\n") # Extract molecule file_out.write("# Extract molecules from trajectory\n") file_out.write("declare -A mols\n\n") file_out.write("mols[]=" "\n\n") file_out.write("for key in \"${!mols[@]}\"; do\n") out_string = "gmx_mpi trjconv " out_string += "-f " + folder_step + file_trr + " " out_string += "-s " + folder_step + file_tpr + " " out_string += "-o traj${mols[$key]}.xtc " out_string += "-pbc mol " out_string += "<<EOF\n" out_string += "$key\n" out_string += "EOF\n\n" file_out.write(out_string) file_out.write("echo \"System " + self._box_link + " - Finished Extraction ...\"\n\n") file_out.write("\ndone")
def generate(self): """Generate simulation folder. """ # Run through boxes for box_id in self._sim_dict["box"]: box = self._sim_dict["box"][box_id] box_link = self._link+box.get_name()+"/" if len(self._sim_dict["box"])>1 else self._link # Create folder if multiple boxes exist utils.mkdirp(box_link) # Create parameter files params = self._sim_dict["param"] if box.get_param() is None else box.get_param() param = Parameter(box_link, params) param.generate_files() # Create topology files topol = Topology(box_link, box.get_topol()) topol.generate_files() # Create structure files and shells construct = Construct(self._link, box_link, box.get_mols(), box.get_struct()) construct.generate_files() # Create simulation shells job = self._sim_dict["job"] if box.get_job() is None else box.get_job() actuate = Actuate(self._link, box_link, self._sim_dict["cluster"], job, box.get_label(), box.get_struct()) actuate.generate_files() # Create analysis shell file for automated filling for mol in box.get_mols(): if box.get_mols()[mol][0]=="fill": analyze = Analyze(self._link, box_link) analyze.extract_mol("nvt") # Copy automated filling if box.get_mols()[mol][2] is not None: utils.copy(os.path.split(__file__)[0]+"/templates/auto_dens.py", box_link+"ana/ana.py") utils.replace(box_link+"ana/ana.py", "MOLSHORT", mol) utils.replace(box_link+"ana/ana.py", "MOLLINK", "../_gro/"+box.get_struct()[mol].split("/")[-1]) utils.replace(box_link+"ana/ana.py", "TARGETDENS", str(box.get_mols()[mol][2])) utils.replace(box_link+"ana/ana.py", "SUBMITCOMMAND", self._sim_dict["cluster"]["queuing"]["submit"]+" min.job") # End message print("Finished simulation folder - "+box.get_label()+" ...")
def generate_files(self): """Generate structure files and shells. """ # Create construction shell file self._structure() # Create structure folder utils.mkdirp(self._box_path + "_gro") # Copy structure files for mol in self._struct: file_link = self._struct[mol] if mol == "BOX": utils.copy(file_link, self._box_path + "_gro/" + "box.gro") elif mol == "GENERATE": utils.copy(file_link, self._box_path + "_gro/" + "generate.sh") elif mol == "PLUMED": utils.copy(file_link, self._box_path + "_gro/" + "plumed.dat") else: utils.copy(file_link, self._box_path + "_gro/" + file_link.split("/")[-1]) # Pore simulation that needs to be filled if "fill" in [self._mols[mol][0] for mol in self._mols]: # Create filling backup folder utils.mkdirp(self._box_path + "_fill") # Create shell files self._fill() # Create fill backup for automatic filling if not all(x is None for x in [self._mols[mol][2] for mol in self._mols]): utils.copy(self._box_path + "_fill/fill.sh", self._box_path + "_fill/fillBackup.sh") # Copy empty script utils.copy( os.path.split(__file__)[0] + "/templates/empty_grid.py", self._box_path + "_fill/" + "empty_grid.py") utils.copy( os.path.split(__file__)[0] + "/templates/sort.py", self._box_path + "_fill/" + "sort.py")
def _equilibration(self): """Create equilibration simulation shells for * **min** for energy minimization * **nvt** for temperature equilibration * **npt** for pressure equilibration """ # Set simulation folder descriptors sim_min = "min" sim_nvt = "nvt" sim_npt = "npt" sim_all = {sim_min: sim_min, sim_nvt: sim_nvt, sim_npt: sim_npt} # Set folder names folder_gro = "../_gro/" folder_top = "../_top/" folder_mdp = "../_mdp/" # Set file names file_box = "box.gro" file_top = "topol.top" file_ndx = "index.ndx" # Get simulation properties np = {step: str(self._job[step]["np"]) for step in self._job} ntomp = { step: str(self._job[step]["ntomp"]) if "ntomp" in self._job[step] else "0" for step in self._job } nodes = {step: str(self._job[step]["nodes"]) for step in self._job} gpu = { step: self._job[step]["gpu"] if "gpu" in self._job[step] else False for step in self._job } wall = {step: self._job[step]["wall"] for step in self._job} # Set step dependent files conf = { "min": folder_gro + file_box, "nvt": "../" + sim_min + "/" + sim_min + ".gro", "npt": "../" + sim_nvt + "/" + sim_nvt + ".gro" } check = { "min": "", "nvt": "", "npt": "-t ../" + sim_nvt + "/" + sim_nvt + ".cpt " } forward = {"min": sim_nvt, "nvt": sim_npt, "npt": ""} if "npt" not in self._job: forward["nvt"] = "" # Create job shells for step in self._job: if not step == "run": link_shell = self._link + step + "/" + step + ".job" utils.mkdirp(self._link + step) utils.copy(self._job[step]["file"], link_shell) # Simulation options utils.replace(link_shell, "SIMULATIONNODES", nodes[step]) utils.replace(link_shell, "SIMULATIONPROCS", np[step]) utils.replace(link_shell, "SIMULATIONGPU", ":gpus=1:exclusive_process" if gpu[step] else "") utils.replace(link_shell, "SIMULATIONTIME", wall[step]) utils.replace(link_shell, "SIMULATIONLABEL", self._label + "_" + step) utils.replace(link_shell, "COMMANDCHANGEDIR", "cd " + self._clr_link + step) # Grompp gro_string = "" gro_string += "gmx_mpi grompp " gro_string += "-f " + folder_mdp + sim_all[step] + ".mdp " gro_string += "-c " + conf[step] + " " gro_string += check[step] gro_string += "-p " + folder_top + file_top + " " gro_string += "-n " + folder_gro + file_ndx + " " if self._is_pore else "" gro_string += "-po " + sim_all[step] + " " gro_string += "-o " + sim_all[step] gro_string += " -maxwarn 1" if self._is_pore else "" gro_string += "\n" # Mdrun gro_string += self._cluster["queuing"]["mpi"] + " " gro_string += str( int(np[step]) * int(nodes[step]) ) + " " if self._cluster["queuing"]["add_np"] else "" gro_string += "gmx_mpi mdrun " gro_string += "-s " + sim_all[step] + ".tpr " gro_string += "-ntomp " + ntomp[step] + " " if not ntomp[ step] == "0" else "" gro_string += "-plumed ../_gro/plumed.dat " if self._is_plm else "" gro_string += "-deffnm " + sim_all[step] + " " gro_string += "-dlb no -c -e -g -o -cpo" # Insert into file utils.replace(link_shell, "COMMANDGROMACS", gro_string) # Add forward queuing with open(link_shell, "a") as file_out: if not forward[step] == "": file_out.write("\n") file_out.write("sleep 20\n") file_out.write("rm *#\n") file_out.write("cd ../" + forward[step] + "/\n") file_out.write(self._cluster["queuing"]["submit"] + " " + forward[step] + ".job" + "\n") # Add to master shell with open(self._sim_link + "equilibrate.sh", "a") as file_out: file_out.write("cd " + self._box_link + sim_min + "/\n") file_out.write(self._cluster["queuing"]["submit"] + " " + sim_min + ".job\n") back = "" if self._box_link == "./" else "../" file_out.write("cd " + back + "../\n") file_out.write("\n")
def _simulation(self): """Create simulation job files. For the first run - for creating the tpr file - run0.job is used. For further simulations, job script run.job is created. Note that the latter automatically extends the current simulation. The breakpoint can be set using the *sim_num* variable in the shell file. """ # Set simulation folder descriptor sim_nvt = "nvt" sim_npt = "npt" sim_run = "run" # Set folder names folder_gro = "../_gro/" folder_top = "../_top/" folder_mdp = "../_mdp/" # Set file names file_top = "topol.top" file_ndx = "index.ndx" # Get last step last = "../" + sim_npt + "/" + sim_npt if "npt" in self._job else "../" + sim_nvt + "/" + sim_nvt # Get simulation properties np = str(self._job["run"]["np"]) nodes = str(self._job["run"]["nodes"]) ntomp = str( self._job["run"]["ntomp"]) if "ntomp" in self._job["run"] else "0" gpu = self._job["run"]["gpu"] if "gpu" in self._job["run"] else False wall = self._job["run"]["wall"] # Create job shells for i in range(2): # Initialize is_first = i == 0 shell_num = "0" if is_first else "" sim_num = i + 1 # Create shell link_shell = self._link + sim_run + "/" + sim_run + shell_num + ".job" utils.mkdirp(self._link + sim_run) utils.copy(self._job["run"]["file"], link_shell) # Change variables utils.replace(link_shell, "SIMULATIONNODES", nodes) utils.replace(link_shell, "SIMULATIONPROCS", np) utils.replace(link_shell, "SIMULATIONGPU", ":gpus=1:exclusive_process" if gpu else "") utils.replace(link_shell, "SIMULATIONTIME", wall) utils.replace(link_shell, "SIMULATIONLABEL", self._label + "_" + str(sim_num)) utils.replace(link_shell, "COMMANDCHANGEDIR", "cd " + self._clr_link + sim_run) # Grompp gro_string = "" if is_first: gro_string += "gmx_mpi grompp " gro_string += "-f " + folder_mdp + sim_run + ".mdp " gro_string += "-c " + last + ".gro " gro_string += "-t " + last + ".cpt " gro_string += "-p " + folder_top + file_top + " " gro_string += "-n " + folder_gro + file_ndx + " " if self._is_pore else "" gro_string += "-po " + sim_run + " " gro_string += "-o " + sim_run + " " gro_string += " -maxwarn 1" if self._is_pore else "" gro_string += "\n" # Mdrun gro_string += self._cluster["queuing"]["mpi"] + " " gro_string += str( int(np) * int(nodes)) + " " if self._cluster["queuing"]["add_np"] else "" gro_string += "gmx_mpi mdrun " gro_string += "-s " + sim_run + ".tpr " gro_string += "-ntomp " + ntomp + " " if not ntomp == "0" else "" gro_string += "-plumed ../_gro/plumed.dat " if self._is_plm else "" gro_string += "-cpi " + sim_run + ".cpt " if not is_first else "" gro_string += "-deffnm " + sim_run + " " gro_string += "-maxh " + str( self._job["run"] ["maxh"]) + " " if "maxh" in self._job["run"] else "" gro_string += "-dlb no -c -e -g -o -cpo" gro_string += " -append" if not is_first else "" # Insert into file utils.replace(link_shell, "COMMANDGROMACS", gro_string) # Add forward queuing with open(link_shell, "a") as file_out: file_out.write("\n") file_out.write("sim_num=" + str(sim_num) + "\n") if not is_first: file_out.write("\n") file_out.write("cp " + sim_run + ".job temp.job\n") file_out.write( "sed -i \"s/sim_num=$sim_num/sim_num=$((sim_num+1))/\" temp.job\n" ) file_out.write("sed -i \"s/" + self._label + "_$sim_num/" + self._label + "_$((sim_num+1))/\" temp.job\n") file_out.write("mv temp.job " + sim_run + ".job\n") file_out.write("\n") file_out.write("sleep 20\n") out_string = "if " out_string += "[ -f " + sim_run + ".cpt ] && " out_string += "[ $sim_num -lt " + str( self._job["run"]["runs"]) + " ]; " out_string += "then " + self._cluster["queuing"][ "submit"] + " " + sim_run + ".job;" out_string += "fi\n" file_out.write(out_string) # Add to master shell with open(self._sim_link + "simulate.sh", "a") as file_out: file_out.write("cd " + self._box_link + sim_run + "/\n") file_out.write(self._cluster["queuing"]["submit"] + " " + sim_run + "0.job\n") back = "" if self._box_link == "./" else "../" file_out.write("cd " + back + "../\n") file_out.write("\n")
def generate(self): """Generate simulation folder. """ # Set parameter dictionary params = self._sim_dict["param"] params["nvt"]["param"]["NUMBEROFSTEPS"] = 1000 if "npt" in params: params["npt"]["param"]["NUMBEROFSTEPS"] = 1000 if "run" in params: del params["run"] # Remove run from job dictionary if "run" in self._sim_dict["job"]: del self._sim_dict["job"]["run"] # Set box specifications self._box.set_name("X") self._box.set_label("X") self._box.set_param(params) # Create parameter files box_link = self._link + self._box.get_name() + "/" # Create folder if multiple boxes exist utils.mkdirp(box_link) # Create parameter files param = Parameter(box_link, self._box.get_param()) param.generate_files() # Create topology files topol = Topology(box_link, self._box.get_topol()) topol.generate_files() # Create structure files and shells construct = Construct(self._link, box_link, self._box.get_mols(), self._box.get_struct()) construct.generate_files() # Create simulation shells actuate = Actuate(self._link, box_link, self._sim_dict["cluster"], self._sim_dict["job"], self._box.get_label(), self._box.get_struct()) actuate.generate_files() # Process iterator input if self._iterator == "nodes": iterator = self._nodes elif self._iterator == "np": iterator = self._np # Create copy shell after minimization with open(self._link + "benchmark.sh", "a") as file_out: # Create subfolders for different simulations job = self._sim_dict["job"] for it in iterator: # Set nodes and np n = it if iterator == self._np else self._np[0] node = it if iterator == self._nodes else self._nodes[0] # Set job dictionary job["min"]["np"] = n job["min"]["nodes"] = node job["min"]["wall"] = "00:30:00" job["nvt"]["np"] = n job["nvt"]["nodes"] = node job["nvt"]["wall"] = "00:30:00" if "npt" in params: job["npt"]["np"] = n job["npt"]["nodes"] = node job["npt"]["wall"] = "00:30:00" # Set subfolder self._sim_dict["job"] = job self._box.set_name(str(it).zfill(2)) self._box.set_label("b_" + str(it).zfill(2)) box_link = self._link + self._box.get_name() + "/" # Create parameter files param = Parameter(box_link, self._box.get_param()) param.generate_files() # Create simulation shells actuate = Actuate(self._link, box_link, self._sim_dict["cluster"], self._sim_dict["job"], self._box.get_label(), self._box.get_struct()) actuate.generate_files() # Write copy to shell file_out.write("cp -r X/_gro " + self._box.get_name() + "/_gro\n") file_out.write("cp -r X/_top " + self._box.get_name() + "/_top\n") file_out.write("cp X/min/* " + self._box.get_name() + "/min/\n\n") # Set equilibration master shell to nvt utils.replace(self._link + "equilibrate.sh", "min", "nvt")