Exemple #1
0
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)
Exemple #4
0
 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
Exemple #5
0
    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))
Exemple #6
0
    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
Exemple #7
0
    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
Exemple #8
0
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
Exemple #9
0
 def run(self, hook=False) -> None:
     # Launch montecarlo simulation
     with helpers.cd(os.path.dirname(self.adaptive_file)):
         ad.main(self.adaptive_file)
Exemple #10
0
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
Exemple #11
0
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
Exemple #15
0
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