def Closest_Rotamers(experiment, gn = None): """Assign the Closest Rotamers to amino acids in Design Molecules""" # Make sure the experiment is an experiment if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Closest Rotamers function requires an Experiment class " text += "object as its input." raise IPRO_Error(text) # Start timing this startTime = time.time() # Loop through the Design Groups for group in experiment: if gn not in [None, group.number]: continue # Time the group groupTime = time.time() # Go through the amino acids of the Design Molecules for molecule in group: for residue in molecule: if molecule.design and residue.kind in \ aminoAcids[residue.fileFormat]: residue.permission = "ISOMER" else: residue.permission = "FIXED" # use the ROTAMERS function ROTAMERS.Closest_Rotamer(group, experiment) # Update the summary experiment["Summary"] += SHARING.summary_update(groupTime, \ "Assigning the Closest Rotamers to Design Group " + str(group.number)) if gn == None: experiment["Summary"] += SHARING.summary_update(groupTime, \ "The Closest Rotamers function")
def make_refinement_choice(experiment, IEs, BEs): """Make a decision regarding the results of a structure refinement""" # Always keep the results of mutator experiments if experiment["Type"] == "Mutator": return True # Or if this is the initial refinement f = open("./Current/iteration.txt", "r") n = int(f.readline()) f.close() if n == 0: return True # Otherwise, make sure the Experiment is using its reference energies SHARING.load_reference_Energies(experiment) # Get the type of energy calculation type = experiment["Energy Calculation"] # Go through the Design groups for group in experiment: if type == "Binding" and group.number == len(experiment): continue # Get the energy to compare if type == "Binding": energy = BEs[group.number]["Average"][0] else: energy = IEs[group.number]["Average"][0] energy -= experiment["Energies"][group.number][type] # Make the choice based on the objective if group.objective in ['improve', 'maintain']: if energy > 0: return False elif group.objective in ['reduce', 'eliminate']: if energy < 0: return False # if all Design Groups passed the test, return True return True
def Finish(experiment, mn=None): """Finish a Refinement""" # Sharing will have been started elsewhere (in finish_check) # Collect the calculated energies energies = gather_energies(experiment) # Get interaction, complex, and binding energies IEs = calculate_IEs(energies) CEs = calculate_CEs(energies) BEs = calculate_BEs(experiment, energies) # Evaluate the results choice = make_refinement_choice(experiment, IEs, BEs) # If the choice is to keep the results, make a permanent copy if choice: store_results(experiment, IEs, BEs, CEs, mn) # Summarize the results Summarize(experiment, choice, IEs, BEs, CEs, mn) # Move out of the refinement's folder os.chdir(experiment["Folder"]) # Store the refinement summary name = SHARING.summary_name(experiment["Folder"]) f = open(name, "a") f.write(experiment["Summary"]) f.close() # Delete the folder the refinement happened in if experiment["Type"] == "Mutator": if mn in [None, 0]: name = "wildtype" else: name = "mutant" + str(mn) else: name = "refinement" os.system("rm -rf " + name) # End sharing SHARING.End(experiment)
def initialize(experiment, mn): """Set up an Experiment to work in a refinement""" # Start sharing SHARING.Start(experiment) # Modify the number of iterations modify = change_iterations(experiment, mn) # Identify the proper folder for the refinement if experiment["Type"] == "Mutator": if mn in [None, 0]: folder = "./wildtype/" else: folder = "./mutant" + str(mn) + "/" else: folder = "./refinement/" # Move into the refinement folder os.chdir(folder) # Load the current structures and energies SHARING.update_Current(experiment, "./Current/") SHARING.update_Energies(experiment, "./Current/") # Stop sharing SHARING.End(experiment) # Make the extra Design Group make_extra_group(experiment) # Modify the 'Activity' of the Experiment experiment['Activity'] = "Refinement" return modify
def initial_check(experiment, mn): """Do an initial check about doing calculations for a mutant""" # Start sharing SHARING.Start(experiment) # This is the name of the folder we're looking for folder = "mutant" + str(mn) # If the results are already completed if folder in os.listdir(experiment["Folder"] + "results/"): SHARING.End(experiment) return False # Or if the refinement is ongoing elif folder in os.listdir(experiment["Folder"]): SHARING.End(experiment) return False # If the initial folder for that mutant does not yet exist, make it folder = "initial_" + folder if folder not in os.listdir(experiment["Folder"]): os.mkdir(folder) os.mkdir(folder + "/Current") # Load the wildtype structures SHARING.update_Current(experiment, experiment["Folder"] + \ "results/wildtype/") SHARING.update_Energies(experiment, experiment["Folder"] + \ "results/wildtype/") # End sharing SHARING.End(experiment) return True
def Optimal_Rotamers(experiment, gn = None): """Select an optimal combination of Rotamers for a system""" # Do the standard starting checks if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Optimal Rotamers function requires an Experiment class " text += "object as its input." raise IPRO_Error(text) refinement = refinement_check(experiment, gn) if refinement: return refinement, "success" # Start timing this startTime = time.time() # Determine the group that will have mutations done for it if gn == None: N = 1 else: N = gn # Do this for each Design Group for group in experiment: if gn not in [None, group.number]: continue # Time the group groupTime = time.time() # Make sure the amino acid sequences match across Design Groups if group.number != N: for molecule in group: for residue in molecule: if residue.design and residue.permission == "ROTAMER": residue.permittedKinds = \ [experiment[N][molecule.name][residue.name].kind] # Pick the Rotamers probability = True objective, solution = ROTAMERS.Optimal_Rotamers(group, experiment, probability) # Summarize the results message = '' if group.number == N: for molecule in group: for residue in molecule: if residue.permission == "ROTAMER": # Summarize the Residue message += "Residue " + residue.name + " in Molecule " message += molecule.name + ": " + residue.kind + "\n" if solution: message += "The objective value of the MILP was " + format(objective, \ '.3f') + "\n" experiment["Summary"] += SHARING.summary_update(groupTime, \ "Selecting Rotamers for Design Group " + str(group.number), message) return refinement, "success" else: message += "No rotamers are selected " experiment["Summary"] += SHARING.summary_update(groupTime, \ "No selecting Rotamers for Design Group " + str(group.number), message) return refinement, "failure"
def change_iterations(experiment, mn = None): """Do 2x the calculations for initial / wildtype calcs""" # If there is a mutant number that's not 0, don't do this if mn not in [None, 0]: return False # If it is None, check the number of completed iterations if mn == None: n = SHARING.iteration_counter(SHARING.get_current(), False) if n > 0: return False # multiply the number by 2 experiment["Refinement Iterations"] *= 2 return True
def change_iterations(experiment, mn=None): """Do 2x the calculations for initial / wildtype calcs""" # If there is a mutant number that's not 0, don't do this if mn not in [None, 0]: return False # If it is None, check the number of completed iterations if mn == None: n = SHARING.iteration_counter(SHARING.get_current(), False) if n > 0: return False # multiply the number by 2 experiment["Refinement Iterations"] *= 2 return True
def Calculate_Energy(experiment, gn = None): """Calculate the energies of an IPRO iteration""" # Do the standard introductory checks if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Calculate Energy function requires an Experiment class " text += "object as its input." raise IPRO_Error(text) refinement = refinement_check(experiment, gn) if refinement: return {}, refinement # Start timing startTime = time.time() # Store the energies here energies = {} # Loop through the Design Groups for group in experiment: if gn not in [None, group.number]: continue # Time the group groupTime = time.time() # initialize the dictionary energies[group.number] = {} # If there are no Target Molecules, it is impossible to calculate an # interaction energy do = False for molecule in group: if not molecule.design: do = True break # Calculate the energies if experiment["Force Field"] == "CHARMM": complex = CHARMM.Energy(group, experiment, "all") energies[group.number]["Complex"] = complex if do: design = CHARMM.Energy(group, experiment, True) target = CHARMM.Energy(group, experiment, False) energies[group.number]["Interaction"] = complex-design-target else: text = "The Calculate Energy function does not support the " text += str(experiment["Force Field"]) + " force field." raise IPRO_Error(text) # update the summary if gn == None: experiment["Summary"] += SHARING.summary_update(groupTime, \ "Energy Calculation for Design Group " + str(group.number)) experiment["Summary"] +=SHARING.format_energies(energies[group.number],\ group.number, False) experiment["Summary"] += SHARING.summary_update(startTime, \ "The Calculate Energy function") return energies, refinement
def mutate_DesignGroups(experiment, mn): """Make the initial mutants of the Design Groups""" # Move into the folder to do the initial calculations in folder = "initial_mutant" + str(mn) os.chdir(folder) # Loop through the Design Groups for group in experiment: # The calculations will be stored in this folder folder = "Group" + str(group.number) # Try to claim the calculations do = SHARING.claim_calculations(folder) # If this processor is doing those calculations if do: # Time stamp when this started experiment["Summary"] = "Started" + SHARING.time_stamp() # Move into the folder os.chdir(folder) # Copy in the C++ and force field files SHARING.copy_standard_files(experiment) # Use the Current structures for molecule in experiment[group.number]: text =format(experiment["Current"][group.number][molecule.name]) molecule.load(text) # Set the permissions for the Molecules permission_setter(experiment, group.number, mn) # Mutate the Residues refinement = IPRO_FUNCTIONS.Optimal_Rotamers(experiment, \ group.number) refinement = IPRO_FUNCTIONS.Relaxation(experiment, group.number, \ True) energies, refinement = IPRO_FUNCTIONS.Calculate_Energy(experiment, \ group.number) # Start sharing SHARING.Start(experiment) # Write a brief summary file name = SHARING.summary_name(SHARING.get_current()) f = open(name, "w") f.write(experiment["Summary"]) f.close() # Move up a folder os.chdir("../") # Store the structures in the Current dictionary IPRO_FUNCTIONS.store_structures(experiment, group.number) IPRO_FUNCTIONS.store_energies(experiment, energies, group.number) # Write the structures to the Current folder SHARING.output_Current(experiment, "./Current/", group.number) SHARING.output_Energies(experiment, "./Current/", group.number) # End sharing SHARING.End(experiment)
def Start_Iteration(experiment, gn = None): """Start an iteration of IPRO""" # Do the standard initial checks if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Start Iteration function requires an Experiment class " text += "object as its input." raise IPRO_Error(text) refinement = refinement_check(experiment, gn) if refinement: return 0, refinement # Start sharing so this processor has exclusive access to the shared files SHARING.Start(experiment) # Determine what iteration this will be iteration = SHARING.iteration_counter(SHARING.get_current(), True) + 1 # Determine what the expected maximum number of iterations is ITERATIONS = max_iterations(experiment) # Create a folder while iteration <= ITERATIONS: folder = "iteration" + str(iteration) do = SHARING.claim_calculations(folder) if do: break else: iteration += 1 # If a folder was made if iteration <= ITERATIONS: # Start a summary experiment["Summary"] = "Started" + SHARING.time_stamp() # Get the last time structures were updated N = SHARING.identify_last_update("./Current/") # If necessary, update the structures if N > experiment["Last Update"]: SHARING.update_Current(experiment, "./Current/", gn) experiment["Last Update"] = N # Say what structures are being used if experiment["Last Update"] == 0: experiment["Summary"] += "Using the initial structures\n" else: experiment["Summary"] += "Using the structures from iteration " experiment["Summary"] += str(experiment["Last Update"]) + "\n" # Move into the appropriate folder os.chdir(folder) # Copy in the C++ and force field files SHARING.copy_standard_files(experiment) # Update the Experiment's structures for group in experiment: if gn not in [None, group.number]: continue for molecule in group: text =format(experiment["Current"][group.number][molecule.name]) molecule.load(text) # End sharing SHARING.End(experiment) return iteration, refinement
def Finish(experiment, mn = None): """Finish a Refinement""" # Sharing will have been started elsewhere (in finish_check) # Collect the calculated energies energies = gather_energies(experiment) # Get interaction, complex, and binding energies IEs = calculate_IEs(energies) CEs = calculate_CEs(energies) BEs = calculate_BEs(experiment, energies) # Evaluate the results choice = make_refinement_choice(experiment, IEs, BEs) # If the choice is to keep the results, make a permanent copy if choice: store_results(experiment, IEs, BEs, CEs, mn) # Summarize the results Summarize(experiment, choice, IEs, BEs, CEs, mn) # Move out of the refinement's folder os.chdir(experiment["Folder"]) # Store the refinement summary name = SHARING.summary_name(experiment["Folder"]) f = open(name, "a") f.write(experiment["Summary"]) f.close() # Delete the folder the refinement happened in if experiment["Type"] == "Mutator": if mn in [None, 0]: name = "wildtype" else: name = "mutant" + str(mn) else: name = "refinement" os.system("rm -rf " + name) # End sharing SHARING.End(experiment)
def input_validation(experiment): """Make sure that the force field and rotamer calculations will work""" # Clear the screen os.system("clear") # Tell the user what is happening message = """ The inputs you have provided are now being validated. This should only take a moment, so please be patient.""" print screen_formatting(message[1:]) # Make the Experiment's folder os.mkdir(experiment["Folder"]) # Get the current folder, so we can move back to it when finished current = os.getcwd() # Move to the Experiment's folder os.chdir(experiment["Folder"]) # copy in the force field and solvation files SHARING.copy_standard_files(experiment, current + "/input_files/", False, \ True, True) # Check the appropriateness of the Molecules, force field, and non-bonded # energy parameters molecules = appropriateness(experiment, True) # If everything worked correctly, the folder can be prepped for the # experiment # Delete all files, as they're not needed anymore names = os.listdir("./") for name in names: i = os.remove(name) # Make an input files folder os.mkdir("input_files") # Move into that folder os.chdir("input_files") # Copy in the force field and solvation files SHARING.copy_standard_files(experiment, current + "/input_files/", False, \ True, True) # Move back to the Experiment's folder os.chdir(experiment["Folder"]) # Create a results folder os.mkdir("results") # Create a structures folder os.mkdir("structures") # Move into that folder os.chdir("structures") # Output each Molecule in the structures folder for molecule in molecules: molecule.output(None, experiment["File Format"], experiment["User"]) # Move back to the starting folder os.chdir(current)
def End_Iteration(experiment, energies, iteration, gn): """End an iteration of IPRO.""" # The standard initial checks if not isinstance(experiment, EXPERIMENT.Experiment): text = "The End Iteration function requires an Experiment class object " text += "as its input." raise IPRO_Error(text) refinement = refinement_check(experiment, gn) if refinement: return refinement # Move out of the iteration's folder os.chdir("../") # Start sharing SHARING.Start(experiment) # Load the appropriate reference energies if experiment["Activity"] == "Standard": SHARING.load_reference_Energies(experiment) else: SHARING.update_Energies(experiment, "./Best/", gn) # Determine the last completed iteration this = SHARING.iteration_counter(SHARING.get_current(), False) + 1 # Determine whether or not keep the iteration results best, keep = iteration_decision(experiment, energies, this, gn) # If results should be kept, do so if best or keep: store_structures(experiment, gn) # If these are the best results so far, store the energies if best: store_energies(experiment, energies, gn) # If appropriate, share the results with other processors SHARING.Results(experiment, this, best, keep, gn) # Say what happened in the summary experiment["Summary"] = "\nIteration " + str(this) + "\n" + \ experiment["Summary"] + "The results were " if best: experiment["Summary"] += "the BEST so far\n" elif keep: experiment["Summary"] += "KEPT by simulated annealing\n" else: experiment["Summary"] += "DISCARDED\n" # Put a time stamp on the summary experiment["Summary"] += "Ended" + SHARING.time_stamp() # Get the name of the Summary file name = SHARING.summary_name(SHARING.get_current()) f = open(name, "a") f.write(experiment["Summary"]) f.close() # Delete the iteration os.system("rm -rf iteration" + str(iteration)) # End sharing SHARING.End(experiment) return refinement
def finish_initialization(experiment): """Finish an initialization""" # Sharing is already started and the structures and energies have already # been loaded into the Experiment # Make the initial experiment summary experiment["Summary"] = "Initial Calculations\n" # Determine when they started f = open(experiment["Folder"]+"initialize/Group1/Group1_Summary.txt","r") for line in f: if line.startswith("Started"): experiment["Summary"] += line break f.close() # Include the energies of each Design Group for group in experiment: experiment["Summary"] += SHARING.format_energies(\ experiment["Energies"][group.number], group.number, False) # Create the initial folder in results SHARING.output_best(experiment, 0, None) # Figure out the name of the output file if experiment["Type"] == "Mutator": folder = experiment["Folder"] + "results/wildtype/" else: folder = experiment["Folder"] + "results/initial/" # List the energies of each Target Molecule, too if experiment["Energy Calculation"] == "Binding": for molecule in experiment[0]: if not molecule.design: name = experiment["Folder"] + "initialize/Current/Molecule" name += molecule.name + "_Energy.txt" f = open(name, "r") energy = f.readline().split()[2] f.close() experiment["Summary"] += "The energy of Target Molecule " experiment["Summary"] += molecule.name + " is " + energy experiment["Summary"] += " kcal / mol\n" # Copy the file to the output folder os.system("cp " + name + " " + folder) # Move to the Experiment's folder os.chdir(experiment["Folder"]) # Try to make the current folder try: os.mkdir("Current") except OSError: pass # Write the Structures to the Current folder SHARING.output_Current(experiment, "./Current/", None, 0) experiment["Last Update"] = 0 # Start a refinment REFINEMENT.Start(experiment, 0, None) # Create the initial summary file experiment["Summary"] += "Ended" + SHARING.time_stamp() name = SHARING.summary_name(experiment["Folder"]) f = open(name, "w") f.write(experiment["Summary"]) f.close() # Remove the initialization folder os.system("rm -rf initialize") # End the sharing that was started elsewhere SHARING.End(experiment)
def Relaxation(experiment, gn = None, all = True): """Do an energy minimization""" # Make sure we have an Experiment if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Relaxation function requires an Experiment class object as " text += "its input." raise IPRO_Error(text) # Check to see if a refinement is happening refinement = refinement_check(experiment, gn) if refinement: return refinement # Start timing startTime = time.time() # Loop through the relevant Design Groups for group in experiment: if gn not in [None, group.number]: continue # Time the group groupTime = time.time() # If appropriate, free all Residues if all: for molecule in group: for residue in molecule: residue.freedom = "FREE" # If appropriate, superimpose the reference structures of Molecules for molecule in group: # Design Molecules never need to have structures superimposed if not molecule.design: if experiment["Superimpose"][group.number][molecule.name]: superimpose(molecule, experiment[0][molecule.name]) # Do the relaxation if experiment["Force Field"] == "CHARMM": CHARMM.Relaxation(group, experiment) else: text = "The Relaxation function does not support the " text += str(experiment["Force Field"]) + " force field." raise IPRO_Error(text) # update the summary if gn == None: experiment["Summary"] += SHARING.summary_update(groupTime, \ "The Relaxation of Design Group " + str(group.number)) experiment["Summary"] += SHARING.summary_update(startTime, \ "The Relaxation function") return refinement
def Wait(experiment): """Wait for an IPRO Experiment to be entirely completed""" # Keep track using this variable finished = False while not finished: # Periodically check the last completed iteration SHARING.Start(experiment) n = SHARING.iteration_counter(SHARING.get_current(), False) SHARING.End(experiment) # If all iterations are complete, the program doesn't need to wait any # more if n == experiment["IPRO Iterations"]: finished = True # If another processor has called for a refinement, do it REFINEMENT.DO(experiment) # If the experiment isn't done yet, take a 15 second break before # continuing the while loop if not finished: time.sleep(15)
def DO(experiment, mn): """Make a particular Mutant""" # Determine if the mutant should be made do = initial_check(experiment, mn) # If it should be, do so if do: # Mutate the Design Groups mutate_DesignGroups(experiment, mn) # Check to see if everything is finished finished = check_finish(experiment) # If everything is done, start the refinement calculations for the # mutant if finished: Finish(experiment, mn) else: # Otherwise, go back to the Experiment's folder, end sharing, and # wait for the initial folder to be deleted os.chdir(experiment["Folder"]) SHARING.End(experiment) SHARING.Wait("initial_mutant" + str(mn))
def DO(experiment, mn=None): """Do a Refinement""" # Only do a refinement when there is a refinement folder to do the # refinement IN if experiment["Type"] == "Mutator": if mn in [None, 0]: name = "wildtype" else: name = "mutant" + str(mn) else: name = "refinement" # If the folder doesn't exist, don't do anything if name in os.listdir("./"): # Initialize the experiment for the refinement modify = initialize(experiment, mn) # do the first set of refinement calculations - which exist to try and # keep the processors working on separate jobs as much as possible first_group_refinement(experiment) # And the second, which exists to get everything finished ASAP second_group_refinement(experiment) # Determine if the calculations are finished yet finished = finish_check(experiment, mn) # If the refinement is not finished, move out of the refinement's folder # and wait for it to be deleted if not finished: os.chdir(experiment["Folder"]) SHARING.End(experiment) # There's no need to wait during mutator experiments, except for the # Wildtype values to finish if experiment["Type"] != "Mutator" or mn in [None, 0]: SHARING.Wait(name) # If the refinement is finished, store the information else: Finish(experiment, mn) # The refinement folder is gone, the structures and energies are stored, # so we can be done with the refinement after a few more things delete_extra_group(experiment) if modify: experiment["Refinement Iterations"] = int( experiment["Refinement Iterations"] / 2) experiment["Activity"] = "Standard"
def check_finish(experiment): """Check to see if the initial structures for a mutant have been made yet""" # Start sharing SHARING.Start(experiment) # Keep track of whether everything is finished finished = True # Check every Design Group for a summary file for group in experiment: label = "Group" + str(group.number) if label + "_Summary.txt" not in os.listdir(label): finished = False break return finished
def Summarize(experiment, choice, IEs, BEs, CEs, mn=None): """Summarize the results of a structure refinement""" # Come up with an appropriate header if experiment["Type"] == "Mutator": if mn == 0: experiment["Summary"] = "\nWildtype Refinement Results\n" else: experiment["Summary"] = "\nMutant " + str( mn) + " Refinement Results\n" else: f = open("./Current/iteration.txt", "r") n = int(f.readline()) f.close() if n == 0: experiment["Summary"] = "\nInitial Structures Refinement\n" else: experiment["Summary"] = "\nRefinement of Iteration " + str( n) + "\n" # Find out when the refinement started f = open("./Group1/Ensemble1/Ensemble1_Summary.txt", "r") for line in f: if line.startswith("Started"): experiment["Summary"] += line break f.close() # Store the information about the calculated energies for group in experiment: if experiment["Energy Calculation"] == "Binding" and group.number == \ len(experiment): continue # Summarize Complex energy experiment["Summary"] += "Design Group " + str(group.number) + "\n" experiment["Summary"] += "Average Complex Energy: " + \ format(CEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(CEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" # IE experiment["Summary"] += "Average Interaction Energy: " + \ format(IEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(IEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" # BE if experiment["Energy Calculation"] == "Binding": experiment["Summary"] += "Average Binding Energy: " + \ format(BEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(BEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" if experiment["Type"] != "Mutator" and n != 0: if choice: experiment["Summary"] += "These were the BEST results so far\n" else: experiment["Summary"] += "These results were DISCARDED\n" # Say when the calculations finished experiment["Summary"] += "Ended" + SHARING.time_stamp()
def Docking(experiment, iteration, gn = None): """Carry out a local, rigid body docking of Target Molecules""" # Do the standard initial checks if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Docking function requires an Experiment class object as its" text += " input." raise IPRO_Error(text) refinement = refinement_check(experiment, gn) if refinement: return False, refinement # Make sure Docking should be run in this iteration if iteration % experiment["Docking Frequency"] != 0: return False, refinement # Time this startTime = time.time() # Collect the groups of Molecules that will move during docking dockingGroups = DOCKING_FUNCTIONS.collect_docking_groups(experiment, gn) # If there aren't any, say that if len(dockingGroups) == 0: experiment["Summary"] += "There were no Molecules that could move " experiment["Summary"] += "during docking.\n" return False, refinement # Store the names of all files generated by this function fileNames = [] # Create all of the information and structures needed to run Docking information, movingMolecules = DOCKING_FUNCTIONS.create_moving_structures(\ experiment, dockingGroups, fileNames) DOCKING_FUNCTIONS.create_static_structures(experiment, movingMolecules, \ fileNames) DOCKING_FUNCTIONS.make_docking_information(experiment, dockingGroups, \ information, fileNames) # Run docking i = os.system("./docking.out") if i != 0: text = "There was an error running the executable docking.out file." raise IPRO_Error(text) # Load the results from docking message = DOCKING_FUNCTIONS.load_docking_results(experiment, dockingGroups,\ fileNames) DOCKING_FUNCTIONS.load_docking_structures(experiment, dockingGroups) # Delete all of the files made by docking for fileName in fileNames: try: os.remove(fileName) except OSError: pass # Update the summary experiment["Summary"] += SHARING.summary_update(startTime, \ "The Docking function", message) # Return that docking ran and that a refinement is not currently ongoing return True, refinement
def finish_check(experiment, mn): """Check that all ensembles are entirely finished""" # NOTE THAT THIS DOES NOT END SHARING SHARING.Start(experiment) # Figure out what folder we should be looking for if experiment["Type"] == "Mutator": if mn in [None, 0]: folder = "wildtype" else: folder = "mutant" + str(mn) else: folder = "refinement" # Move to the Experiment's folder os.chdir(experiment["Folder"]) # If the appropriate folder no longer exists, be done but return False so # the Finish function isn't called if folder not in os.listdir("./"): return False os.chdir(folder) finished = True # Loop through the groups for group in experiment: os.chdir("Group" + str(group.number)) # and the ensembles for en in range(1, experiment["Ensemble Number"] + 1): os.chdir("Ensemble" + str(en)) # Get the number of the last completed iteration I = SHARING.iteration_counter(SHARING.get_current(), False) # If they aren't all done yet if I < experiment["Refinement Iterations"]: finished = False os.chdir("../../") break os.chdir("../") if not finished: break os.chdir("../") return finished
def initialize_molecule(experiment, mn): """Initialize a Molecule""" # Create the folder's name folder = "Molecule" + mn do = SHARING.claim_calculations(folder) # If this processor is doing the calculations if do: # Make a summary experiment["Summary"] = "Started" + SHARING.time_stamp() # Move into the folder os.chdir(folder) SHARING.copy_standard_files(experiment) # Get a unique copy of the Molecule molecule = experiment[0][mn].duplicate() for residue in molecule: residue.freedom = "FREE" # Store the calculated energies here energies = {} # Do a relaxation and energy calculation if experiment["Force Field"] == "CHARMM": CHARMM.Relaxation(molecule, experiment) energies["Complex"] = CHARMM.Energy(molecule, experiment) else: text = "The initialize molecule function does not support the " text += str(experiment["Force Field"]) + " force field." raise IPRO_Error(text) # Format the energy text = SHARING.format_energies(energies) experiment["Summary"] += text # Create the summary file for the Molecule experiment["Summary"] += "Ended" + SHARING.time_stamp() name = SHARING.summary_name(SHARING.get_current()) f = open(name, "w") f.write(experiment["Summary"]) f.close() # Leave this folder, then start sharing os.chdir('../') SHARING.Start(experiment) # Output the Molecule's structure name = "./Current/" + molecule.generate_name() molecule.output(name, molecule.fileFormat, experiment["User"]) # Output the Complex energy f = open("./Current/Molecule" + mn + "_Energy.txt", "w") f.write(text) f.close() # End sharing SHARING.End(experiment)
def Summarize(experiment, choice, IEs, BEs, CEs, mn = None): """Summarize the results of a structure refinement""" # Come up with an appropriate header if experiment["Type"] == "Mutator": if mn == 0: experiment["Summary"] = "\nWildtype Refinement Results\n" else: experiment["Summary"] = "\nMutant " + str(mn)+" Refinement Results\n" else: f = open("./Current/iteration.txt", "r") n = int(f.readline()) f.close() if n == 0: experiment["Summary"] = "\nInitial Structures Refinement\n" else: experiment["Summary"] = "\nRefinement of Iteration " + str(n) + "\n" # Find out when the refinement started f = open("./Group1/Ensemble1/Ensemble1_Summary.txt", "r") for line in f: if line.startswith("Started"): experiment["Summary"] += line break f.close() # Store the information about the calculated energies for group in experiment: if experiment["Energy Calculation"] == "Binding" and group.number == \ len(experiment): continue # Summarize Complex energy experiment["Summary"] += "Design Group " + str(group.number) + "\n" experiment["Summary"] += "Average Complex Energy: " + \ format(CEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(CEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" # IE experiment["Summary"] += "Average Interaction Energy: " + \ format(IEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(IEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" # BE if experiment["Energy Calculation"] == "Binding": experiment["Summary"] += "Average Binding Energy: " + \ format(BEs[group.number]["Average"][0], '.3f') + " +/- " + \ format(BEs[group.number]["Average"][1], '.3f') + " kcal/mol\n" if experiment["Type"] != "Mutator" and n != 0: if choice: experiment["Summary"] += "These were the BEST results so far\n" else: experiment["Summary"] += "These results were DISCARDED\n" # Say when the calculations finished experiment["Summary"] += "Ended" + SHARING.time_stamp()
def Start(experiment, iteration, gn=None): """Create a folder to run a refinement in.""" # Only do this when appropriate if not experiment["Do Refinement"] or gn != None or experiment["Activity"] \ != "Standard": return False # Try to make the directory if experiment["Type"] == "Mutator": folder = "wildtype" else: folder = "refinement" try: os.mkdir(folder) except OSError: return False # Assuming that was successful, prep that folder folder += "/Current/" os.mkdir(folder) SHARING.output_Current(experiment, folder) SHARING.output_Energies(experiment, folder) f = open(folder + "iteration.txt", "w") f.write(str(iteration)) f.close() return True
def Start(experiment, iteration, gn = None): """Create a folder to run a refinement in.""" # Only do this when appropriate if not experiment["Do Refinement"] or gn != None or experiment["Activity"] \ != "Standard": return False # Try to make the directory if experiment["Type"] == "Mutator": folder = "wildtype" else: folder = "refinement" try: os.mkdir(folder) except OSError: return False # Assuming that was successful, prep that folder folder += "/Current/" os.mkdir(folder) SHARING.output_Current(experiment, folder) SHARING.output_Energies(experiment, folder) f = open(folder + "iteration.txt", "w") f.write(str(iteration)) f.close() return True
def load_initial_info(experiment, folder = None): """Load the initial information.""" # Generate the folder where it should be stored if folder == None: if experiment["Type"] == "Mutator": folder = experiment["Folder"] + "results/wildtype/" else: folder = experiment["Folder"] + "results/initial/" # Try to load the information try: SHARING.update_Energies(experiment, folder) SHARING.update_Current(experiment, folder) SHARING.load_Target_Energies(experiment, folder) return True except IOError: return False
def store_results(experiment, IEs, BEs, CEs, mn = None): """Store the results of the refinement and share them""" # If this isn't a mutator, get the current iteration if experiment["Type"] != "Mutator": f = open("./Current/iteration.txt", "r") mn = int(f.readline()) f.close() # Go through the Design Groups, identify the chosen ensemble, and store the # structures and relevant energies for group in experiment: if group.number == len(experiment) and BEs != {}: continue # Store the energies experiment["Energies"][group.number] = {} experiment["Energies"][group.number]["Complex"] = \ CEs[group.number]["Average"][0] experiment["Energies"][group.number]["Interaction"] = \ IEs[group.number]["Average"][0] if BEs != {}: experiment["Energies"][group.number]["Binding"] = \ BEs[group.number]["Average"][0] # Identify the best ensemble structure en = BEs[group.number]["Choice"][0] # Otherwise get the best ensemble structure from the IEs else: en = IEs[group.number]["Choice"][0] # Load the structures from that ensemble folder = "Group" + str(group.number) + "/Ensemble" + str(en) + "/Best/" SHARING.update_Current(experiment, folder, group.number) # If this isn't a mutator, share them in the Experiment's folder if experiment["Type"] != "Mutator": # Share the structures in the Experiment's Current folder SHARING.output_Current(experiment, experiment["Folder"]+"Current/",\ group.number, mn) # Share the results SHARING.output_best(experiment, mn, group.number)
def store_results(experiment, IEs, BEs, CEs, mn=None): """Store the results of the refinement and share them""" # If this isn't a mutator, get the current iteration if experiment["Type"] != "Mutator": f = open("./Current/iteration.txt", "r") mn = int(f.readline()) f.close() # Go through the Design Groups, identify the chosen ensemble, and store the # structures and relevant energies for group in experiment: if group.number == len(experiment) and BEs != {}: continue # Store the energies experiment["Energies"][group.number] = {} experiment["Energies"][group.number]["Complex"] = \ CEs[group.number]["Average"][0] experiment["Energies"][group.number]["Interaction"] = \ IEs[group.number]["Average"][0] if BEs != {}: experiment["Energies"][group.number]["Binding"] = \ BEs[group.number]["Average"][0] # Identify the best ensemble structure en = BEs[group.number]["Choice"][0] # Otherwise get the best ensemble structure from the IEs else: en = IEs[group.number]["Choice"][0] # Load the structures from that ensemble folder = "Group" + str(group.number) + "/Ensemble" + str(en) + "/Best/" SHARING.update_Current(experiment, folder, group.number) # If this isn't a mutator, share them in the Experiment's folder if experiment["Type"] != "Mutator": # Share the structures in the Experiment's Current folder SHARING.output_Current(experiment, experiment["Folder"]+"Current/",\ group.number, mn) # Share the results SHARING.output_best(experiment, mn, group.number)
def initialize_group(experiment, gn): """Initialize a Design Group""" # Create the folder's name folder = "Group" + str(gn) # Try to claim it for calculations do = SHARING.claim_calculations(folder) # If this processor is doing the calculations if do: # Make a summary experiment["Summary"] = "Started" + SHARING.time_stamp() # Move into the folder and copy in files os.chdir(folder) SHARING.copy_standard_files(experiment) # Relax everything refinement = Relaxation(experiment, gn, True) # Assign closest rotamers Closest_Rotamers(experiment, gn) # Do another relaxation refinement = Relaxation(experiment, gn, True) # Calculate the initial energies energies, refinement = Calculate_Energy(experiment, gn) # Store the structures and energies store_structures(experiment, gn) store_energies(experiment, energies, gn) # Create a summary file experiment["Summary"] += "Ended" + SHARING.time_stamp() name = SHARING.summary_name(SHARING.get_current()) f = open(name, "w") f.write(experiment["Summary"]) f.close() # Move up a folder os.chdir("../") # Start sharing SHARING.Start(experiment) # output the structures and energies to the Current folder SHARING.output_Current(experiment, "./Current/", gn) SHARING.output_Energies(experiment, "./Current/", gn) # End sharing SHARING.End(experiment) return do
def first_group_refinement(experiment): """Start all ensembles for the Design Groups""" # Start sharing (for file creation reasons) SHARING.Start(experiment) # Loop through the design groups print "Check1" for group in experiment: gn = group.number # Generate the name for the Design Group's calculations folder = "Group" + str(gn) try: os.mkdir(folder) except OSError: pass os.chdir(folder) # Start each ensemble for en in range(1, experiment["Ensemble Number"] + 1): eFolder = "Ensemble" + str(en) do = SHARING.claim_calculations(eFolder) # If this processor has started the calculations for this ensemble print en, do if do: # Make sure the experiment has the right structures and energies SHARING.update_Current(experiment, "../Current/", gn) SHARING.update_Energies(experiment, "../Current/", gn) # Move into the folder os.chdir(eFolder) # Make a copy of the best structures and energies for the group os.mkdir("Current") SHARING.output_Current(experiment, "./Current/", gn, 0) os.mkdir("Best") SHARING.output_Current(experiment, "./Best/", gn) SHARING.output_Energies(experiment, "./Best/", gn) # Move out of the e Folder os.chdir("../") SHARING.End(experiment) # Do the ensemble refinement ensemble_refinement(experiment, gn, en) SHARING.Start(experiment) # Move out of the folder os.chdir("../") SHARING.End(experiment)
def first_group_refinement(experiment): """Start all ensembles for the Design Groups""" # Start sharing (for file creation reasons) SHARING.Start(experiment) # Loop through the design groups for group in experiment: gn = group.number # Generate the name for the Design Group's calculations folder = "Group" + str(gn) try: os.mkdir(folder) except OSError: pass os.chdir(folder) # Start each ensemble for en in range(1, experiment["Ensemble Number"] + 1): eFolder = "Ensemble" + str(en) do = SHARING.claim_calculations(eFolder) # If this processor has started the calculations for this ensemble if do: # Make sure the experiment has the right structures and energies SHARING.update_Current(experiment, "../Current/", gn) SHARING.update_Energies(experiment, "../Current/", gn) # Move into the folder os.chdir(eFolder) # Make a copy of the best structures and energies for the group os.mkdir("Current") SHARING.output_Current(experiment, "./Current/", gn, 0) os.mkdir("Best") SHARING.output_Current(experiment, "./Best/", gn) SHARING.output_Energies(experiment, "./Best/", gn) # Move out of the e Folder os.chdir("../") SHARING.End(experiment) # Do the ensemble refinement ensemble_refinement(experiment, gn, en) SHARING.Start(experiment) # Move out of the folder os.chdir("../") SHARING.End(experiment)
def Finish(experiment, mn): """Finish the initial creation of a mutant""" # Sharing was started in check finish # Load the structures and energies SHARING.update_Current(experiment, "./Current/") SHARING.update_Energies(experiment, "./Current/") # Create a brief summary of the information experiment["Summary"] = '\nMutant ' + str(mn) + " Creation\n" f = open("Group1/Group1_Summary.txt", "r") for line in f: if line.startswith("Started"): experiment["Summary"] += line break f.close() # Include information about the energies for group in experiment: experiment["Summary"] += \ SHARING.format_energies(experiment["Energies"][group.number], \ group.number, False) # Put this in the overall summary os.chdir(experiment["Folder"]) name = SHARING.summary_name(SHARING.get_current()) f = open(name, "a") f.write(experiment["Summary"]) f.close() # Make a folder to do the structure refinements in folder = "mutant" + str(mn) os.mkdir(folder) folder += "/Current/" os.mkdir(folder) SHARING.output_Current(experiment, folder) SHARING.output_Energies(experiment, folder) f = open(folder + "iteration.txt", "w") f.write(str(mn)) f.close() # Delete the current folder name = "initial_mutant" + str(mn) os.system("rm -rf " + name) # End sharing SHARING.End(experiment)
def make_extra_group(experiment): """Create an extra Design Group with no Target Molecules""" # Only do this if Binding energy calculations are being done if experiment["Energy Calculation"] == "Binding": # Get all of the Design Molecules from Design Group 1 molecules = [] for molecule in experiment[1]: if molecule.design: molecules.append(molecule) # Make and store a new Design Group (which duplicates these Molecules # for run independence reasons) N = len(experiment) + 1 group = MOLECULES.DesignGroup(N, molecules, experiment["Force Field"], \ experiment["File Format"]) experiment._groupOrder.append(N) experiment._groups[N] = group n = len(experiment) # Update the Current dictionary, too experiment["Current"][n] = {} for molecule in experiment[n]: new = molecule.duplicate() experiment["Current"][n][new.name] = new # Those structures are essentially place holders at this point. However, # we do need to run an energy minimization and calculate an initial # energy for that group name = "Group" + str(n) + "_Energies.txt" SHARING.Start(experiment) # If another processor already did the calculation, we're fine if name not in os.listdir("./Current/"): # Try to make a temp directory to do the calculations in if "temp" not in os.listdir("./"): # Make the directory and move into it os.mkdir("temp") os.chdir("temp") # Stop sharing SHARING.End(experiment) # Copy in the relevant files SHARING.copy_standard_files(experiment, False) # Relax the Design Group refinement = IPRO_FUNCTIONS.Relaxation(experiment, n, True) # And calculate the energies energies, refinement = \ IPRO_FUNCTIONS.Calculate_Energy(experiment, n) # Move back up a folder os.chdir("../") # Start sharing SHARING.Start(experiment) # Store the energy text = SHARING.format_energies(energies[n]) f = open("./Current/" + name, "w") f.write(text) f.close() SHARING.output_Current(experiment, "./Current/", n) # Delete the temp folder os.system("rm -rf temp") # Otherwise, just wait else: SHARING.End(experiment) SHARING.Wait("temp", "./") SHARING.Start(experiment) # Store that complex energy f = open("./Current/" + name, "r") experiment["Energies"][n] = {"Complex": float(f.readline().split()[2])} f.close() SHARING.End(experiment)
def make_extra_group(experiment): """Create an extra Design Group with no Target Molecules""" # Only do this if Binding energy calculations are being done if experiment["Energy Calculation"] == "Binding": # Get all of the Design Molecules from Design Group 1 molecules = [] for molecule in experiment[1]: if molecule.design: molecules.append(molecule) # Make and store a new Design Group (which duplicates these Molecules # for run independence reasons) N = len(experiment) + 1 group = MOLECULES.DesignGroup(N, molecules, experiment["Force Field"], \ experiment["File Format"]) experiment._groupOrder.append(N) experiment._groups[N] = group n = len(experiment) # Update the Current dictionary, too experiment["Current"][n] = {} for molecule in experiment[n]: new = molecule.duplicate() experiment["Current"][n][new.name] = new # Those structures are essentially place holders at this point. However, # we do need to run an energy minimization and calculate an initial # energy for that group name = "Group" + str(n) + "_Energies.txt" SHARING.Start(experiment) # If another processor already did the calculation, we're fine if name not in os.listdir("./Current/"): # Try to make a temp directory to do the calculations in if "temp" not in os.listdir("./"): # Make the directory and move into it os.mkdir("temp") os.chdir("temp") # Stop sharing SHARING.End(experiment) # Copy in the relevant files SHARING.copy_standard_files(experiment, False) # Relax the Design Group refinement = IPRO_FUNCTIONS.Relaxation(experiment, n, True) # And calculate the energies energies, refinement = \ IPRO_FUNCTIONS.Calculate_Energy(experiment, n) # Move back up a folder os.chdir("../") # Start sharing SHARING.Start(experiment) # Store the energy text = SHARING.format_energies(energies[n]) f = open("./Current/" + name, "w") f.write(text) f.close() SHARING.output_Current(experiment, "./Current/", n) # Delete the temp folder os.system("rm -rf temp") # Otherwise, just wait else: SHARING.End(experiment) SHARING.Wait("temp", "./") SHARING.Start(experiment) # Store that complex energy f = open("./Current/" + name, "r") experiment["Energies"][n] = {"Complex":float(f.readline().split()[2])} f.close() SHARING.End(experiment)
def Backbone_Perturbation(experiment, gn = None): """Perturb the Backbone of a Molecule""" # Make sure the experiment is an Experiment if not isinstance(experiment, EXPERIMENT.Experiment): text = "The Backbone Perturbation function requires an Experiment class" text += " object as its input" raise IPRO_Error(text) # Find out if a refinement is happening refinement = refinement_check(experiment, gn) if refinement: return refinement # Assign the closest rotamers to all Residues #Closest_Rotamers(experiment, gn) # Start timing this startTime = time.time() # Determine which Group to make the perturbation selections for if gn == None: N = 1 else: N = gn # Choose the perturbation location spot = select_perturbation_position(experiment) # Choose the perturbation region experiment["Summary"] += "Residue " + spot[1] + " in Molecule " + spot[0] experiment["Summary"] += " selected as the Perturbation Position\n" perturbed = select_perturbation_region(experiment, experiment[N], spot) if len(perturbed) > 1: items = [] for spot in perturbed: items.append("Residue " + spot[1] + " in Molecule " + spot[0]) text = screen_formatting("Perturbing" + list_items(items) + "\n") experiment["Summary"] += text initialMolecule = experiment[N][spot[0]] #sequence = DEIMMUNIZATION.extract_sequence_molecule(initialMolecule) #fs = open("sequence.txt", "w") #fs.write(sequence) #fs.close() # Generate the random perturbation angles angles = generate_angles(experiment[N], perturbed) # Loop through the Design Groups for group in experiment: if gn not in [None, group.number]: continue # Time the group groupTime = time.time() # Assign freedoms and permissions if group.number == N: # Set based on sequence sequence_setting(experiment, group, perturbed) # Set based on distance (will only work if appropriate) distance_setting(experiment, group) # Match Dimer information Dimers(experiment, group, angles) # Otherwise, match things to the Number group else: for m in group: for r in m: # If this is a Target Molecule, freeze it if not m.design: r.freedom = "FIXED" r.permission = "FIXED" else: r.currentKind = r.kind r.freedom = experiment[N][m.name][r.name].freedom r.permission = experiment[N][m.name][r.name].permission # Mutate to Glycines ROTAMERS.Glycine(group, experiment) # Perturb the backbone if experiment["Force Field"] == "CHARMM": CHARMM.Perturbation(group, angles, experiment) else: text = "The Backbone Perturbation function does not support the " text += str(experiment["Force Field"]) + " force field." raise IPRO_Error(text) # Update the summary if gn == None: experiment["Summary"] += SHARING.summary_update(groupTime, \ "Perturbing Design Group " + str(group.number)) experiment["Summary"] += SHARING.summary_update(startTime, \ "The Backbone Perturbation function") return refinement