def run_allosteric(parsed_yaml: dict) -> (pv.EnviroBuilder, pv.EnviroBuilder): ''' Run allosteric simulation by: 1) Run global exploration to identify most important pockets 2) Run induced fit simulation to find deep pockets ''' #Let user choose working folder original_dir = os.path.abspath(os.getcwd()) working_folder = os.path.abspath("{}_Pele".format(parsed_yaml.residue)) if not parsed_yaml.folder: working_folder = is_repited( working_folder) if not parsed_yaml.adaptive_restart else is_last( working_folder) else: working_folder = os.path.abspath(parsed_yaml.folder) #Set main folder parsed_yaml.folder = os.path.join(working_folder, "1_global_exploration") # start initial simulation parsed_yaml.full = True simulation = si.run_adaptive(parsed_yaml) simulation_path = os.path.join(simulation.pele_dir, simulation.output) # get best structures and cluster them with cd(simulation_path): # NEED ALGORITHM TO CHOOSE OPTIMUM NUMBERS OF CLUSTERS!!!! cluster_best_structures("5", n_components=simulation.n_components, residue=simulation.residue, topology=simulation.topology, directory=working_folder) # adjust original input.yaml if not parsed_yaml.skip_refinement: parsed_yaml.system = os.path.join(working_folder, "refinement_input/*.pdb") parsed_yaml.folder = os.path.join(working_folder, "2_refinement_simulation") parsed_yaml.full = None parsed_yaml.poses = None parsed_yaml.induced_fit_exhaustive = True if not parsed_yaml.test: parsed_yaml.iterations = 20 parsed_yaml.pele_steps = 10 parsed_yaml.box_center = simulation.box_center parsed_yaml.box_radius = simulation.box_radius # refine selected best structures with cd(original_dir): induced_fit = si.run_adaptive(parsed_yaml) else: induced_fit = None return simulation, induced_fit
def run(self): """ Runs the simulation for all inputs. Returns ------- A list of job parameters (EnviroBuilder objects) for each simulation subset. """ self.set_package_params() self.check_cpus() self.set_working_folder() self.all_mutations = self.retrieve_inputs() self.restart_checker() self.split_into_subsets() for idx, subset in enumerate(self.mutation_subsets, self.start): self.env.input = subset self.env.cpus = self.env.cpus_per_mutation * len(subset) + 1 self.env.folder = os.path.join( self.working_folder, "{}{}".format(self.subset_folder, idx)) with helpers.cd(self.original_dir): job = simulation.run_adaptive(self.env) self.postprocessing(job) self.all_jobs.append(deepcopy(job)) self.logger(job) return self.all_jobs
def run(self, hook=False): with helpers.cd(os.path.dirname(self.adaptive_file)): if hook: ad.main(self.adaptive_file, clusteringHook=self.interactive_clustering) else: ad.main(self.adaptive_file)
def _pca_to_json(self, pdbs) -> str: # calculate pca over pdb and get json pdbs_full_path = [os.path.abspath(pdb) for pdb in pdbs] with helpers.cd(self.pele_dir): pca = pc.main(pdbs_full_path) self.pca = cs.PCA.format(pca) return self.pca
def _choose_refinement_input(self): """ Scan top 75% best binding energies, pick n best ones as long as ligand COMs are >= box radius away from each other. """ simulation_path = os.path.join( self.global_simulation.pele_dir, self.global_simulation.output ) n_best_poses = int( self.global_simulation.iterations * self.global_simulation.pele_steps * (self.global_simulation.cpus - 1) * 0.25 ) if not self.args.debug: with cd(simulation_path): files_out, _, _, _, output_energy = bs.main( str(self.args.be_column), n_structs=n_best_poses, path=".", topology=self.global_simulation.topology, logger=self.global_simulation.logger, ) snapshot = 0 files_out = [ os.path.join( self.global_simulation.pele_dir, self.global_simulation.output, f, ) for f in files_out ] input_pool = [ [ f, snapshot, self.global_simulation.residue, self.global_simulation.topology, ] for f in files_out ] all_coords = parallelize(_extract_coords, input_pool, 1) coords = [list(c[0:3]) for c in all_coords] dataframe = pd.DataFrame( list(zip(files_out, output_energy, coords)), columns=["File", "Binding energy", "1st atom coordinates"], ) self.dataframe = dataframe.sort_values( ["Binding energy"], ascending=True ) inputs = self._check_ligand_distances() directory = os.path.join(self.working_folder, "refinement_input") if not os.path.isdir(directory): os.makedirs(directory, exist_ok=True) for i in inputs: os.system("cp {} {}/.".format(i, directory))
def _launch_refinement(self): with cd(self.original_dir): # with cd(self.working_folder): if not self.args.debug: sim_params = si.run_adaptive(self.args) else: sim_params = None return sim_params
def check(self): """ Performs all checks: protonation, negative residues, capped termini and CONECT lines. Then copies the final output PDB to the current working directory with '_fixed' suffix. Returns ------- PDB file with added CONECT lines (necessary for Parametrizer) and no capped termini. """ with tempfile.TemporaryDirectory() as tmp_dir: with helpers.cd(tmp_dir): self.check_protonation() self.check_negative_residues() self.fixed_file = self.remove_capped_termini() added_conects_file = self.check_conects() if added_conects_file: self.fixed_file = added_conects_file self.fixed_file = self.save_file() return self.fixed_file
def run_ppi(parsed_yaml: dict) -> (pv.ParametersBuilder, pv.ParametersBuilder): # Let user choose working folder original_dir = os.path.abspath(os.getcwd()) working_folder = os.path.abspath("{}_Pele".format(parsed_yaml.residue)) if not parsed_yaml.folder: working_folder = is_repeated( working_folder) if not parsed_yaml.adaptive_restart else is_last( working_folder) else: working_folder = os.path.abspath(parsed_yaml.folder) # Set main folder parsed_yaml.folder = os.path.join(working_folder, "1_interface_exploration") # Check n_waters before launching the simulation #water_checker(parsed_yaml) # get arguments from input.yaml n_waters = parsed_yaml.n_waters parsed_yaml.n_waters = None protein_file = parsed_yaml.system chain = parsed_yaml.protein ligand_pdb = parsed_yaml.ligand_pdb # no waters in the first simulation parsed_yaml.water_arg = None # remove chains except for "protein" flag protein_file = prepare_structure(protein_file, ligand_pdb, chain, True) parsed_yaml.system = protein_file # start simulation 1 - induced fit parsed_yaml.induced_fit_exhaustive = True simulation1 = si.run_adaptive(parsed_yaml) simulation1_path = os.path.join(simulation1.pele_dir, simulation1.output) # cluster best structures if not parsed_yaml.debug: with cd(simulation1_path): cluster_best_structures("5", n_components=simulation1.n_components, residue=simulation1.residue, topology=simulation1.topology, directory=working_folder, logger=simulation1.logger) # adjust original input.yaml if not parsed_yaml.skip_refinement: parsed_yaml.system = os.path.join(working_folder, "refinement_input/*.pdb") parsed_yaml.folder = os.path.join(working_folder, "2_refinement_simulation") parsed_yaml.induced_fit_exhaustive = None parsed_yaml.ppi = None parsed_yaml.poses = None parsed_yaml.rescoring = True del parsed_yaml.water_arg # Set waters ony if specified by user if n_waters != 0: parsed_yaml.waters = "all_waters" parsed_yaml.n_waters = n_waters else: parsed_yaml.waters = None parsed_yaml.n_waters = n_waters parsed_yaml.adaptive_restart = False if not parsed_yaml.test: parsed_yaml.iterations = 1 parsed_yaml.steps = 100 parsed_yaml.box_center = simulation1.box_center parsed_yaml.box_radius = 100 # We should have a look at how to set no box but at the moment super big # start simulation 2 - minimisation with cd(original_dir): if not parsed_yaml.debug: simulation2 = launch_simulation(parsed_yaml) else: simulation2 = None else: simulation2 = None return simulation1, simulation2
def run(self, hook=False) -> None: # Launch montecarlo simulation with helpers.cd(os.path.dirname(self.adaptive_file)): ad.main(self.adaptive_file)
def run_ppi(parsed_yaml: dict) -> (pv.ParametersBuilder, pv.ParametersBuilder): # Let user choose working folder original_dir = os.path.abspath(os.getcwd()) working_folder = os.path.abspath("{}_Pele".format(parsed_yaml.residue)) if not parsed_yaml.folder: working_folder = get_next_peledir(working_folder) if not parsed_yaml.adaptive_restart else get_latest_peledir( working_folder) else: working_folder = os.path.abspath(parsed_yaml.folder) # Set main folder parsed_yaml.folder = os.path.join(working_folder, "1_interface_exploration") # get arguments from input.yaml n_waters = parsed_yaml.n_waters parsed_yaml.n_waters = None protein_file = parsed_yaml.system chain = parsed_yaml.protein ligand_pdb = parsed_yaml.ligand_pdb # Parametrize hetero molecules before merging PDBs, if using peleffy. Otherwise they will go through Plop in # Adaptive.simulation. if parsed_yaml.use_peleffy: templates, rotamers, to_skip = parametrize_hetero_ppi(parsed_yaml) parsed_yaml.template = parsed_yaml.template.extend(templates) if parsed_yaml.template else templates parsed_yaml.rotamers = parsed_yaml.rotamers.extend(rotamers) if parsed_yaml.rotamers else rotamers parsed_yaml.skip_ligand_prep = parsed_yaml.skip_ligand_prep.extend(to_skip) if parsed_yaml.skip_ligand_prep else to_skip # no waters in the first simulation parsed_yaml.water_arg = None parsed_yaml.use_peleffy = parsed_yaml.use_peleffy if parsed_yaml.use_peleffy is not None else False # remove chains except for "protein" flag protein_file = prepare_structure(protein_file, ligand_pdb, chain, True, peleffy=parsed_yaml.use_peleffy) parsed_yaml.system = protein_file # start simulation 1 - induced fit parsed_yaml.induced_fit_long = True simulation1 = si.run_adaptive(parsed_yaml) simulation1_path = os.path.join(simulation1.pele_dir, simulation1.output) # cluster best structures if not parsed_yaml.debug: with cd(simulation1_path): cluster_best_structures("5", n_components=simulation1.n_components, residue=simulation1.residue, topology=simulation1.topology, directory=working_folder, logger=simulation1.logger) # adjust original input.yaml if not parsed_yaml.skip_refinement: parsed_yaml.system = os.path.join(working_folder, "refinement_input/*.pdb") parsed_yaml.folder = os.path.join(working_folder, "2_refinement_simulation") parsed_yaml.induced_fit_long = None parsed_yaml.ppi = None parsed_yaml.poses = None parsed_yaml.rescoring = True del parsed_yaml.water_arg # Set waters only if specified by user if n_waters != 0: parsed_yaml.waters = "all_waters" parsed_yaml.n_waters = n_waters else: parsed_yaml.waters = None parsed_yaml.n_waters = n_waters parsed_yaml.adaptive_restart = False if not parsed_yaml.test: parsed_yaml.iterations = 1 parsed_yaml.steps = 100 parsed_yaml.box_center = simulation1.box_center parsed_yaml.box_radius = 100 # We should have a look at how to set no box but at the moment super big # start simulation 2 - minimisation with cd(original_dir): if not parsed_yaml.debug: simulation2 = launch_simulation(parsed_yaml) else: simulation2 = None else: simulation2 = None return simulation1, simulation2
def run_adaptive(args: YamlParser): """ Main function to prepare and launch the simulation. 1) Create Parameters - variables, folders, logger... 2) Prepare ligand and receptor 3) Launch simulation 4) Analyse simulation """ builder = ParametersBuilder() parameters = builder.build_adaptive_variables(args) parameters.create_files_and_folders() shutil.copy(args.yamlfile, parameters.pele_dir) missing_residues = [] if parameters.adaptive_restart and not parameters.only_analysis: with helpers.cd(parameters.pele_dir): adaptiveSampling.main(parameters.ad_ex_temp) parameters.logger.info("Simulation run successfully (:\n\n") args.adaptive_restart = False elif not parameters.only_analysis and not parameters.restart: parameters.logger.info( "System: {}; Platform Functionality: {}\n\n".format( parameters.residue, parameters.software)) pdb_checker.PDBChecker(parameters.system).check_negative_residues() # Create inputs directory if not os.path.exists(parameters.inputs_dir): os.mkdir(parameters.inputs_dir) if parameters.perturbation: syst = sp.SystemBuilder.build_system( parameters.system, args.mae_lig, args.residue, parameters.pele_dir, inputs_dir=parameters.inputs_dir) else: syst = sp.SystemBuilder(parameters.system, None, None, parameters.pele_dir, inputs_dir=parameters.inputs_dir) parameters.logger.info("Prepare complex {}".format(syst.system)) # If user overrides 'system' with 'input' if parameters.input: parameters.inputs_simulation = [] for input in parameters.input: input_path = os.path.join(parameters.inputs_dir, os.path.basename(input)) shutil.copy(input, input_path) if parameters.no_ppp: input_proc = input_path else: input_proc, missing_residues, _, _, _ = ppp.main( input_path, parameters. inputs_dir, # to ensure it goes to pele_dir/inputs, not pele_dir output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=None, ligand_pdb=parameters.ligand_ref) input_proc = os.path.basename(input_proc) input_proc = os.path.join(parameters.inputs_dir, input_proc) parameters.inputs_simulation.append(input_proc) parameters.adap_ex_input = ", ".join([ '"' + input + '"' for input in parameters.inputs_simulation ]).strip('"') # If randomization in necessary (PPI, site_finder, global exploration)... elif args.full or args.randomize or args.ppi or args.site_finder: ligand_positions, box_radius, box_center = rd.randomize_starting_position( parameters, args.box_center, args.box_radius) if parameters.no_ppp: receptor = syst.system else: receptor, missing_residues, _, _, _ = ppp.main( syst.system, parameters. inputs_dir, # to ensure it goes to pele_dir/input, not pele_dir output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=None, ligand_pdb=parameters.ligand_ref) inputs = rd.join(receptor, ligand_positions, parameters.residue, output_folder=parameters.inputs_dir) parameters.input = [ os.path.join(parameters.inputs_dir, inp) for inp in inputs ] if args.gpcr_orth or args.out_in: randomization_box_radius, randomization_box_center = rd.set_box( args.final_site if args.final_site else args.orthosteric_site, ligand_positions, parameters.system) if not args.box_center: parameters.box_center = randomization_box_center if not args.box_radius: parameters.box_radius = randomization_box_radius else: parameters.box_center = box_center parameters.box_radius = box_radius parameters.adap_ex_input = ", ".join( ['"' + input + '"' for input in parameters.input]).strip('"') hp.silentremove(ligand_positions) # Prepare System if parameters.no_ppp or parameters.input: # No need to run system through PPP, if we already preprocessed # parameters.input if parameters.input: # If we have more than one input for input in parameters.input: try: shutil.copy(input, parameters.inputs_dir) except shutil.SameFileError: # systems that go through randomization are already moved pass else: shutil.copy(parameters.system, parameters.inputs_dir) else: parameters.nonstandard.extend(hp.find_nonstd_residue(syst.system)) parameters.system, missing_residues, _, _, _ = ppp.main( syst.system, parameters.inputs_dir, output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, mid_chain_nonstd_residue=parameters.nonstandard, skip=parameters.skip_prep, back_constr=parameters.ca_constr, constrain_smiles=None, ligand_pdb=parameters.ligand_ref, ca_interval=parameters.ca_interval) parameters.constraints = alpha_constraints.retrieve_constraints( parameters.system, interval=parameters.ca_interval, back_constr=parameters.ca_constr, ter_constr=parameters.terminal_constr) # Metal constraints if not args.no_metal_constraints: metal_constraints, parameters.external_constraints = mc.main( args.external_constraints, os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"')), syst.system, permissive=parameters.permissive_metal_constr, all_metals=args.constrain_all_metals, external=parameters.external_constraints, logger=parameters.logger) parameters.external_constraints = hp.retrieve_constraints_for_pele( parameters.external_constraints, parameters.system) metal_constraints_json = hp.retrieve_constraints_for_pele( metal_constraints, os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"'))) parameters.external_constraints.extend(metal_constraints_json) else: parameters.external_constraints = hp.retrieve_constraints_for_pele( parameters.external_constraints, parameters.system) # Keep JSON ordered by having first title and then constraints if parameters.external_constraints: parameters.constraints = (parameters.constraints[0:1] + parameters.external_constraints + parameters.constraints[1:]) if parameters.remove_constraints: parameters.constraints = "" parameters.logger.info(f"Complex {parameters.system} prepared\n\n") # Ligand/metal and solvent parameters if (parameters.perturbation or parameters.sidechain_perturbation) and parameters.use_peleffy: ligand_parametrizer = parametrizer.Parametrizer.from_parameters( parameters) ligand_parametrizer.parametrize_ligands_from( pdb_file=syst.system, ppp_file=parameters.system) elif (parameters.perturbation or parameters.sidechain_perturbation ) and not parameters.use_peleffy: # Parametrize the ligand ligand_params = lg.LigandParametrization(parameters) ligand_params.generate() # Parametrize missing residues identified by PPP for res, __, _ in missing_residues: if res != args.residue and res not in parameters.skip_ligand_prep: parameters.logger.info( "Creating template for residue {}".format(res)) with hp.cd(parameters.pele_dir): mr.create_template(parameters, res) parameters.logger.info( "Template {}z created\n\n".format(res)) # Covalent residue parametrization should not run in refinement simulation if parameters.covalent_residue and os.path.basename( parameters.pele_dir) != "2_refinement": parametrizer.parametrize_covalent_residue( parameters.pele_data, parameters.pele_dir, parameters.gridres, parameters.residue_type, parameters.residue, ppp_system=parameters.system) if parameters.ligand_conformations: ligand_conformations.LigandConformations( path=parameters.ligand_conformations, system=parameters.system, resname=parameters.residue, forcefield=parameters.forcefield, pele_dir=parameters.pele_dir).generate() # Create simulation box, if performing perturbation if parameters.perturbation and parameters.box: box = bx.BoxSetter(parameters.box_center, parameters.box_radius, parameters.ligand_ref, parameters.logger) parameters.box = box.generate_json() else: parameters.box = "" # Solvent parameters solvent = sv.ImplicitSolvent( parameters.solvent, parameters.obc_tmp, parameters.template_folder, parameters.obc_file, parameters.logger, ) solvent.generate() # Build PCA if parameters.pca_traj: pca_obj = pca.PCA(parameters.pca_traj, parameters.pele_dir) parameters.pca = pca_obj.generate(parameters.logger) # Core constraints based on SMILES string if parameters.constrain_core: smiles_input_pdb = os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0]) smiles = smiles_constraints.SmilesConstraints( smiles_input_pdb, parameters.constrain_core, parameters.residue, parameters.chain, parameters.constrain_core_spring) smi_constraint = smiles.run() parameters.constraints = (parameters.constraints[0:1] + smi_constraint + parameters.constraints[1:]) # Waters input_waters = [ input.strip().strip('"') for input in parameters.adap_ex_input.split(",") ] input_waters = [ os.path.join(parameters.inputs_dir, inp) for inp in input_waters ] water_obj = wt.WaterIncluder( input_waters, parameters.n_waters, user_waters=parameters.waters, ligand_perturbation_params=parameters.parameters, water_center=args.water_center, water_radius=parameters.water_radius, allow_empty_selectors=parameters.allow_empty_selectors, water_temp=parameters.water_temp, water_trials=parameters.water_trials, water_overlap=parameters.water_overlap, water_constr=parameters.water_constr, test=parameters.test, water_freq=parameters.water_freq, ligand_residue=parameters.residue) water_obj.run() parameters.parameters = water_obj.ligand_perturbation_params parameters.water_ids_to_track = water_obj.water_ids_to_track # Check if atoms need mapping due to preprocessing args = AtomMapper(args, parameters, syst.system).run() # Metrics builder - builds JSON strings for PELE to be able to # track atom distances, RMSD, etc. metrics = mt.MetricBuilder() parameters.metrics = (metrics.distance_to_atom_json( os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"'), ), args.atom_dist, ) if args.atom_dist else "") parameters.native = (metrics.rmsd_to_json( args.native, parameters.chain) if args.native else "") parameters.local_nonbonding_energy = metrics.local_nonbonding_energy_json( parameters.covalent_residue, parameters.nonbonding_radius) # metal polarisation if parameters.polarize_metals: mp.change_metal_charges( parameters.template_folder, parameters.forcefield, parameters.polarization_factor, parameters.system, ) # Predict cluster values in a short equilibration if parameters.cluster_conditions == "auto": preequilibration = PreEquilibrator(args, parameters) parameters.cluster_conditions = preequilibration.run() # Point adaptive.conf to input dir parameters.adap_ex_input = os.path.join(parameters.inputs_dir, parameters.adap_ex_input) # Fill in simulation templates adaptive = ad.SimulationBuilder(parameters.ad_ex_temp, parameters.pele_exit_temp, parameters.topology) adaptive.generate_inputs(parameters, water_obj) # Run simulation only if we are not in debug mode if not parameters.debug: parameters.logger.info("Running Simulation") adaptive.run() parameters.logger.info("Simulation run successfully (:\n\n") elif parameters.restart and not parameters.only_analysis: # Start simulation from scratch (unlike adaptive_restart) but use files created in debug mode parameters.logger.info( f"Launching simulation from {parameters.pele_dir}") adaptive = ad.SimulationBuilder(parameters.ad_ex_temp, parameters.pele_exit_temp, parameters.topology) adaptive.run() parameters.logger.info("Simulation run successfully (:\n\n") # Run analysis if parameters.analyse and not parameters.debug: from pele_platform.analysis import Analysis # Retrieve water IDs to track from existing pele.conf, if running analysis only if parameters.only_analysis: parameters.water_ids_to_track = wt.water_ids_from_conf( parameters.pele_temp) analysis_folder = os.path.join(parameters.pele_dir, "results") analysis = Analysis.from_parameters(parameters) analysis.generate( analysis_folder, clustering_type=parameters.clustering_method.lower(), bandwidth=parameters.bandwidth, analysis_nclust=parameters.analysis_nclust, max_top_clusters=parameters.max_top_clusters, min_population=parameters.min_population, max_top_poses=parameters.max_top_poses, top_clusters_criterion=parameters.top_clusters_criterion, representatives_criterion=parameters. cluster_representatives_criterion) return parameters
def create_ligand_parameters(self) -> None: # create ligz template files with hp.cd(self.env.pele_dir): plop.parametrize_miss_residues(self.env)
def run_adaptive(args: pv.EnviroBuilder) -> pv.EnviroBuilder: """ Main function to prepare and launch simulation 1) Crate working folders and inputs 2) Prepare ligand and receptor 3) Launch simulation 4) Analyse simulation """ # Build Folders and Logging and env variable that will containt #all main attributes of the simulation env = pele.EnviroBuilder() env.software = "Adaptive" env.build_adaptive_variables(args) env.create_files_and_folders() shutil.copy(args.yamlfile, env.pele_dir) ####### if env.adaptive_restart and not env.only_analysis: with helpers.cd(env.pele_dir): adt.main(env.ad_ex_temp) env.logger.info("Simulation run succesfully (:\n\n") elif not env.only_analysis: env.logger.info("System: {}; Platform Functionality: {}\n\n".format(env.residue, env.software)) if env.perturbation: syst = sp.SystemBuilder.build_system(env.system, args.mae_lig, args.residue, env.pele_dir) else: syst = sp.SystemBuilder(env.system, None, None, env.pele_dir) env.logger.info("Prepare complex {}".format(syst.system)) ########Choose your own input#################### # User specifies more than one input if env.input: env.inputs_simulation = [] for input in env.input: input_path = os.path.join(env.pele_dir, os.path.basename(input)) shutil.copy(input, input_path) if env.no_ppp: input_proc = input else: input_proc = os.path.basename(ppp.main(input_path, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=env.constrain_smiles, ligand_pdb=env.ligand_ref)[0]) env.inputs_simulation.append(input_proc) hp.silentremove([input_path]) env.adap_ex_input = ", ".join(['"' + input + '"' for input in env.inputs_simulation]).strip('"') # Global exploration mode: Create inputs around protein elif args.full or args.randomize or args.ppi: ligand_positions, box_radius, box_center = rd.randomize_starting_position(env.ligand_ref, env.receptor, outputfolder=env.pele_dir, nposes=env.poses, test=env.test, user_center=env.center_of_interface) if not args.gpcr_orth: env.box_center = box_center env.box_radius = box_radius if env.no_ppp: receptor = syst.system else: receptor = ppp.main(syst.system, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=env.constrain_smiles, ligand_pdb=env.ligand_ref)[0] inputs = rd.join(receptor, ligand_positions, env.residue, output_folder=env.pele_dir) env.adap_ex_input = ", ".join(['"' + os.path.basename(input) + '"' for input in inputs]).strip('"') hp.silentremove(ligand_positions) #Parsing input for errors and saving them as inputs ##########Prepare System################ if env.no_ppp: missing_residues = [] gaps = {} metals = {} env.constraints = ct.retrieve_constraints(env.system, gaps, metals, back_constr=env.ca_constr) if env.input: # If we have more than one input for input in env.input: shutil.copy(input, env.pele_dir) else: shutil.copy(env.system, env.pele_dir) else: env.system, missing_residues, gaps, metals, env.constraints = ppp.main(syst.system, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, mid_chain_nonstd_residue=env.nonstandard, skip=env.skip_prep, back_constr=env.ca_constr, constrain_smiles=env.constrain_smiles, ligand_pdb=env.ligand_ref) ################METAL CONSTRAINTS################## if not args.no_metal_constraints: metal_constraints, env.external_constraints = mc.main(args.external_constraints, os.path.join(env.pele_dir, env.adap_ex_input.split(",")[0].strip().strip('"')), syst.system, permissive=env.permissive_metal_constr, all_metals=args.constrain_all_metals, external=env.external_constraints) metal_constraints_json = hp.retrieve_constraints_for_pele(metal_constraints, env.system) env.external_constraints = hp.retrieve_constraints_for_pele(env.external_constraints, env.system) metal_constraints_json = hp.retrieve_constraints_for_pele(metal_constraints, env.system) env.external_constraints.extend(metal_constraints_json) else: env.external_constraints = hp.retrieve_constraints_for_pele(env.external_constraints, env.system) # Keep Json ordered by having first title and then constraints if env.external_constraints: env.constraints = env.constraints[0:1] + env.external_constraints + env.constraints[1:] if env.remove_constraints: env.constraints = "" env.logger.info(cs.SYSTEM.format(missing_residues, gaps, metals)) env.logger.info("Complex {} prepared\n\n".format(env.system)) ####Ligand parameters and simulation box if env.perturbation: ligand_params = lg.LigandParametrization(env) ligand_params.generate() box = bx.BoxSetter(env.box_center, env.box_radius, env.ligand_ref, env.logger) env.box = box.generate_json() else: env.box="" ###########Parametrize missing residues for res, __, _ in missing_residues: if res != args.residue and res not in env.skip_ligand_prep: env.logger.info("Creating template for residue {}".format(res)) with hp.cd(env.pele_dir): mr.create_template(env, res) env.logger.info("Template {}z created\n\n".format(res)) #########Solvent parameters solvent = sv.ImplicitSolvent(env.solvent, env.obc_tmp, env.template_folder, env.obc_file, env.logger) solvent.generate() #####Build PCA####### if env.pca_traj: pca_obj = pca.PCA(env.pca_traj, env.pele_dir) env.pca = pca_obj.generate() ####### Add waters, if needed if args.n_waters: # Add n water molecules to minimisation inputs input_waters = [input.strip().strip('"') for input in env.adap_ex_input.split(",")] input_waters = [os.path.join(env.pele_dir, inp) for inp in input_waters] wt.water_checker(args) wt.add_water(input_waters, args.residue, args.n_waters, test=env.test) wt.set_water_control_file(env) elif args.waters: wt.set_water_control_file(env) ############Fill in Simulation Templates############ adaptive = ad.SimulationBuilder(env.ad_ex_temp, env.pele_exit_temp, env.topology) adaptive.generate_inputs(env) if env.analyse and not env.debug: report = pt.analyse_simulation(env.report_name, env.traj_name[:-4]+"_", os.path.join(env.pele_dir, env.output), env.residue, cpus=env.cpus, output_folder=env.pele_dir, clustering=env.perturbation, mae=env.mae, nclusts=env.analysis_nclust, overwrite=env.overwrite, topology=env.topology, be_column=env.be_column, limit_column=env.limit_column, te_column=env.te_column) print("Pdf summary report successfully writen to: {}".format(report)) return env
def run_adaptive(args): """ Main function to prepare and launch the simulation. 1) Create EnviroBuilder - variables, folders, logger... 2) Prepare ligand and receptor 3) Launch simulation 4) Analyse simulation """ builder = ParametersBuilder() parameters = builder.build_adaptive_variables(args) parameters.create_files_and_folders() shutil.copy(args.yamlfile, parameters.pele_dir) if parameters.adaptive_restart and not parameters.only_analysis: with helpers.cd(parameters.pele_dir): adaptiveSampling.main(parameters.ad_ex_temp) parameters.logger.info("Simulation run successfully (:\n\n") elif not parameters.only_analysis: parameters.logger.info( "System: {}; Platform Functionality: {}\n\n".format( parameters.residue, parameters.software)) # Create inputs directory if not os.path.exists(parameters.inputs_dir): os.mkdir(parameters.inputs_dir) if parameters.perturbation: syst = sp.SystemBuilder.build_system( parameters.system, args.mae_lig, args.residue, parameters.pele_dir, inputs_dir=parameters.inputs_dir, ) else: syst = sp.SystemBuilder( parameters.system, None, None, parameters.pele_dir, inputs_dir=parameters.inputs_dir, ) parameters.logger.info("Prepare complex {}".format(syst.system)) # If user overrides 'system' with 'input' if parameters.input: parameters.inputs_simulation = [] for input in parameters.input: input_path = os.path.join(parameters.inputs_dir, os.path.basename(input)) shutil.copy(input, input_path) if parameters.no_ppp: input_proc = input_path else: input_proc = os.path.basename( ppp.main( input_path, parameters. inputs_dir, # to ensure it goes to pele_dir/inputs, not pele_dir output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=None, ligand_pdb=parameters.ligand_ref, )[0]) input_proc = os.path.join(parameters.inputs_dir, input_proc) parameters.inputs_simulation.append(input_proc) parameters.adap_ex_input = ", ".join([ '"' + input + '"' for input in parameters.inputs_simulation ]).strip('"') # If randomization in necessary (PPI, site_finder, global exploration)... elif args.full or args.randomize or args.ppi: ligand_positions, box_radius, box_center = rd.randomize_starting_position( parameters.ligand_ref, parameters.receptor, outputfolder=parameters.inputs_dir, nposes=parameters.poses, test=parameters.test, user_center=parameters.center_of_interface, logger=parameters.logger, ) if not args.gpcr_orth: parameters.box_center = box_center parameters.box_radius = box_radius if parameters.no_ppp: receptor = syst.system else: receptor = ppp.main( syst.system, parameters. inputs_dir, # to ensure it goes to pele_dir/input, not pele_dir output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, constrain_smiles=None, ligand_pdb=parameters.ligand_ref, )[0] inputs = rd.join( receptor, ligand_positions, parameters.residue, output_folder=parameters.inputs_dir, ) inputs = [ os.path.join(parameters.inputs_dir, inp) for inp in inputs ] parameters.adap_ex_input = ", ".join( ['"' + input + '"' for input in inputs]).strip('"') hp.silentremove(ligand_positions) # Prepare System if ( parameters.no_ppp or parameters.input ): # No need to run system through PPP, if we already preprocessed parameters.input missing_residues = [] if parameters.input: # If we have more than one input for input in parameters.input: shutil.copy(input, parameters.inputs_dir) else: shutil.copy(parameters.system, parameters.inputs_dir) else: parameters.nonstandard.extend(hp.find_nonstd_residue(syst.system)) parameters.system, missing_residues, _, _, _ = ppp.main( syst.system, parameters.inputs_dir, output_pdb=[ "", ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, mid_chain_nonstd_residue=parameters.nonstandard, skip=parameters.skip_prep, back_constr=parameters.ca_constr, constrain_smiles=None, ligand_pdb=parameters.ligand_ref, ca_interval=parameters.ca_interval, ) parameters.constraints = alpha_constraints.retrieve_constraints( parameters.system, interval=parameters.ca_interval, back_constr=parameters.ca_constr, ter_constr=parameters.terminal_constr, ) # Metal constraints if not args.no_metal_constraints: metal_constraints, parameters.external_constraints = mc.main( args.external_constraints, os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"'), ), syst.system, permissive=parameters.permissive_metal_constr, all_metals=args.constrain_all_metals, external=parameters.external_constraints, logger=parameters.logger, ) parameters.external_constraints = hp.retrieve_constraints_for_pele( parameters.external_constraints, parameters.system) metal_constraints_json = hp.retrieve_constraints_for_pele( metal_constraints, os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"'), ), ) parameters.external_constraints.extend(metal_constraints_json) else: parameters.external_constraints = hp.retrieve_constraints_for_pele( parameters.external_constraints, parameters.system) # Keep JSON ordered by having first title and then constraints if parameters.external_constraints: parameters.constraints = (parameters.constraints[0:1] + parameters.external_constraints + parameters.constraints[1:]) if parameters.remove_constraints: parameters.constraints = "" parameters.logger.info("Complex {} prepared\n\n".format( parameters.system)) # Ligand parameters and simulation box if parameters.perturbation: ligand_params = lg.LigandParametrization(parameters) ligand_params.generate() box = bx.BoxSetter( parameters.box_center, parameters.box_radius, parameters.ligand_ref, parameters.logger, ) parameters.box = box.generate_json() else: parameters.box = "" # Parametrize missing residues for res, __, _ in missing_residues: if res != args.residue and res not in parameters.skip_ligand_prep: parameters.logger.info( "Creating template for residue {}".format(res)) with hp.cd(parameters.pele_dir): mr.create_template(parameters, res) parameters.logger.info("Template {}z created\n\n".format(res)) # Solvent parameters solvent = sv.ImplicitSolvent( parameters.solvent, parameters.obc_tmp, parameters.template_folder, parameters.obc_file, parameters.logger, ) solvent.generate() # Build PCA if parameters.pca_traj: pca_obj = pca.PCA(parameters.pca_traj, parameters.pele_dir) parameters.pca = pca_obj.generate(parameters.logger) # Core constraints based on SMILES string if parameters.constrain_core: smiles_input_pdb = os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0]) smiles = smiles_constraints.SmilesConstraints( smiles_input_pdb, parameters.constrain_core, parameters.residue, parameters.chain, parameters.constrain_core_spring, ) smi_constraint = smiles.run() parameters.constraints = (parameters.constraints[0:1] + smi_constraint + parameters.constraints[1:]) # Waters input_waters = [ input.strip().strip('"') for input in parameters.adap_ex_input.split(",") ] input_waters = [ os.path.join(parameters.inputs_dir, inp) for inp in input_waters ] water_obj = wt.WaterIncluder( input_waters, parameters.n_waters, user_waters=parameters.waters, ligand_perturbation_params=parameters.parameters, water_center=args.water_center, water_radius=parameters.water_radius, allow_empty_selectors=parameters.allow_empty_selectors, water_temp=parameters.water_temp, water_trials=parameters.water_trials, water_overlap=parameters.water_overlap, water_constr=parameters.water_constr, test=parameters.test, water_freq=parameters.water_freq, ligand_residue=parameters.residue, ) water_obj.run() parameters.parameters = water_obj.ligand_perturbation_params # Check if atoms need mapping due to preprocessing args = AtomMapper(args, parameters, syst.system).run() # Metrics builder - builds JSON strings for PELE to be able to track atom distances, RMSD, etc. metrics = mt.MetricBuilder() parameters.metrics = (metrics.distance_to_atom_json( os.path.join( parameters.inputs_dir, parameters.adap_ex_input.split(",")[0].strip().strip('"'), ), args.atom_dist, ) if args.atom_dist else "") parameters.native = (metrics.rsmd_to_json( args.native, parameters.chain) if args.native else "") # interaction restrictions # TODO this is not the place to initialize parameters for the interaction restrictions if args.interaction_restrictions: interaction_restrictions = ir.InteractionRestrictionsBuilder() interaction_restrictions.parse_interaction_restrictions( parameters.system, args.interaction_restrictions) parameters.met_interaction_restrictions = ( interaction_restrictions.metrics_to_json()) parameters.interaction_restrictions = ( interaction_restrictions.conditions_to_json()) else: parameters.met_interaction_restrictions = "" parameters.interaction_restrictions = "" # metal polarisation if parameters.polarize_metals: mp.change_metal_charges( parameters.template_folder, parameters.forcefield, parameters.polarization_factor, parameters.system, ) # Point adaptive.conf to input dir parameters.adap_ex_input = os.path.join(parameters.inputs_dir, parameters.adap_ex_input) # Fill in simulation templates adaptive = ad.SimulationBuilder(parameters.ad_ex_temp, parameters.pele_exit_temp, parameters.topology) adaptive.generate_inputs(parameters, water_obj) # Run simulation only if we are not in debug mode if not parameters.debug: parameters.logger.info("Running Simulation") adaptive.run() parameters.logger.info("Simulation run successfully (:\n\n") # Run analysis if parameters.analyse and not parameters.debug: from pele_platform.analysis import Analysis analysis_folder = os.path.join(parameters.pele_dir, "results") analysis = Analysis.from_parameters(parameters) analysis.generate(analysis_folder, clustering_type=parameters.clustering_method.lower(), bandwidth=parameters.bandwidth, analysis_nclust=parameters.analysis_nclust, max_top_clusters=parameters.max_top_clusters, min_population=parameters.min_population) return parameters
def run_adaptive(args): # Build Folders and Logging and env variable that will containt #all main attributes of the simulation env = pele.EnviroBuilder.build_env(args) shutil.copy(args.yamlfile, env.pele_dir) if env.adaptive_restart: with helpers.cd(env.pele_dir): adt.main(env.ad_ex_temp) env.logger.info("Simulation run succesfully (:\n\n") else: ##PREPWIZARD## if args.prepwizard: args.system = pp.run_prepwizard(args.system) env.logger.info("System: {}; Platform Functionality: {}\n\n".format(env.residue, env.software)) if env.perturbation: syst = sp.SystemBuilder.build_system(args.system, args.mae_lig, args.residue, env.pele_dir) else: syst = sp.SystemBuilder(args.system, None, None, env.pele_dir) env.logger.info("Prepare complex {}".format(syst.system)) ########Choose your own input#################### if args.input: env.inputs_simulation = [] for input in env.input: input_path = os.path.join(env.pele_dir, os.path.basename(input)) shutil.copy(input, input_path) input_proc = os.path.basename(ppp.main(input_path, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter)[0]) env.inputs_simulation.append(input_proc) hp.silentremove([input_path]) env.adap_ex_input = ", ".join(['"' + input + '"' for input in env.inputs_simulation]) elif args.full or args.randomize: ligand_positions, box_center, box_radius = rd.randomize_starting_position(env.ligand_ref, "input_ligand.pdb", env.residue, env.receptor, None, None, env, poses=env.poses) # Use choice stays as first priority env.box_center = box_center if not env.box_center else env.box_center env.box_radius = box_radius if not env.box_radius else env.box_radius receptor = ppp.main(syst.system, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter)[0] inputs = rd.join(receptor, ligand_positions, env) env.adap_ex_input = ", ".join(['"' + os.path.basename(input) + '"' for input in inputs]).strip('"') hp.silentremove(ligand_positions) #Parsing input for errors and saving them as inputs ##########Prepare System################ if env.no_ppp: env.adap_ex_input = system_fix = syst.system missing_residues = [] gaps = {} metals = {} env.constraints = ct.retrieve_constraints(system_fix, gaps, metals, back_constr=env.ca_constr) shutil.copy(env.adap_ex_input, env.pele_dir) else: system_fix, missing_residues, gaps, metals, env.constraints = ppp.main(syst.system, env.pele_dir, output_pdb=["" , ], charge_terminals=args.charge_ter, no_gaps_ter=args.gaps_ter, mid_chain_nonstd_residue=env.nonstandard, skip=env.skip_prep, back_constr=env.ca_constr) if env.remove_constraints: env.constraints = "" env.logger.info(cs.SYSTEM.format(missing_residues, gaps, metals)) env.logger.info("Complex {} prepared\n\n".format(system_fix)) ############Build metrics################## env.logger.info("Setting metrics") metrics = mt.Metrics_Builder(syst.system) if env.atom_dist: metrics.distance_to_atom(args.atom_dist) env.metrics = "\n".join(metrics.get_metrics()) if metrics.get_metrics() else None env.logger.info("Metrics set\n\n") ############Parametrize Ligand############### if env.perturbation: env.logger.info("Creating template for residue {}".format(args.residue)) with hp.cd(env.pele_dir): plop.parametrize_miss_residues(args, env, syst) env.logger.info("Template {}z created\n\n".format(args.residue.lower())) if env.external_template: for template_file in env.external_template: cmd_to_move_template = "cp {} {}".format(template_file, env.template_folder) subprocess.call(cmd_to_move_template.split()) if env.external_rotamers: for rotamer_file in env.external_rotamers: cmd_to_move_rotamer_file = "cp {} {}".format(rotamer_file, env.rotamers_folder) subprocess.call(cmd_to_move_rotamer_file.split()) ###########Parametrize missing residues################# for res, __, _ in missing_residues: if res != args.residue: env.logger.info("Creating template for residue {}".format(res)) with hp.cd(env.pele_dir): mr.create_template(args, env, res) env.logger.info("Template {}z created\n\n".format(res)) #########Parametrize solvent parameters if need it############## env.logger.info("Setting implicit solvent: {}".format(env.solvent)) if env.solvent == "OBC": shutil.copy(env.obc_tmp, env.obc_file) for template in glob.glob(os.path.join(env.template_folder, "*")): obc.main(template, env.obc_file) env.logger.info("Implicit solvent set\n\n".format(env.solvent)) #################Set Box################### env.logger.info("Generating exploration box") if not env.box_center: env.box_center = cm.center_of_mass(env.ligand_ref) env.logger.info("Box {} generated\n\n".format(env.box_center)) else: env.logger.info("Box {} generated\n\n".format(env.box_center)) env.box = cs.BOX.format(env.box_radius, env.box_center) if env.box_radius else "" else: env.box="" #####Build PCA####### if env.pca_traj: if isinstance(env.pca_traj, str): pdbs = glob.glob(env.pca_traj) elif isinstance(env.pca_traj, list): pdbs = env.pca_traj pdbs_full_path = [os.path.abspath(pdb) for pdb in pdbs] output = os.path.basename(pdbs[0])[:-4] + "_ca_pca_modes.nmd" pca_script = os.path.join(cs.DIR, "Utilities/Helpers/calculatePCA4PELE.py") command = 'python {} --pdb "{}"'.format(pca_script, " ".join(pdbs_full_path)) with helpers.cd(env.pele_dir): os.system(command) env.pca = cs.PCA.format(output) ############Fill in Simulation Templates############ env.logger.info("Running Simulation") if env.adaptive: ext.external_adaptive_file(env) if env.pele: ext.external_pele_file(env) adaptive = ad.SimulationBuilder(env.ad_ex_temp, env.pele_exit_temp, env) if not env.debug: adaptive.run() env.logger.info("Simulation run succesfully (:\n\n") return env