diff --git a/EAPM/EAPM.py b/EAPM/EAPM.py index a7ad8f3..d6f6c1c 100644 --- a/EAPM/EAPM.py +++ b/EAPM/EAPM.py @@ -95,13 +95,21 @@ def createPlugin(): eapmPlugin.addBlock(epPredBlock) - from Blocks.testBlock import testBlock # type: ignore + # from Blocks.testBlock import testBlock # type: ignore - eapmPlugin.addBlock(testBlock) + # eapmPlugin.addBlock(testBlock) - from Blocks.AnalyseGlideGPX import AnalyseGPXBlock # type: ignore + from Blocks.AnalyseGlide import AnalyseGBlock # type: ignore - eapmPlugin.addBlock(AnalyseGPXBlock) + eapmPlugin.addBlock(AnalyseGBlock) + + # from Blocks.Rbcavity import rbCavityBlock # type: ignore + + # eapmPlugin.addBlock(rbCavityBlock) + + # from Blocks.Rbdock import rbDockBlock # type: ignore + + # eapmPlugin.addBlock(rbDockBlock) # Add the configs from Configs.mafftConfig import mafftExecutableConfig # type: ignore diff --git a/EAPM/Include/Blocks/Ahatool.py b/EAPM/Include/Blocks/Ahatool.py index 1e6e64b..e1865e3 100644 --- a/EAPM/Include/Blocks/Ahatool.py +++ b/EAPM/Include/Blocks/Ahatool.py @@ -1,7 +1,3 @@ -import datetime -import os -import subprocess - from HorusAPI import PluginBlock, PluginVariable, VariableList, VariableTypes # TODO Add to the documentation @@ -85,6 +81,10 @@ def initialAction(block: PluginBlock): + import datetime + import os + import subprocess + container_name = block.inputs.get("container_name", "bsceapm/ahatool:2.2") input_fasta = block.inputs.get("input_fasta", None) fasta = os.path.basename(input_fasta) diff --git a/EAPM/Include/Blocks/AlignPdbEAPM.py b/EAPM/Include/Blocks/AlignPdbEAPM.py index 5593445..d3ef54a 100644 --- a/EAPM/Include/Blocks/AlignPdbEAPM.py +++ b/EAPM/Include/Blocks/AlignPdbEAPM.py @@ -124,26 +124,30 @@ def initialAlign(block: PluginBlock): alignmentMode = block.variables.get("alignment_mode", "aligned") referenceResidues = block.variables.get("reference_residues", []) + import prepare_proteins + + print("Loading PDB files...") + + models = prepare_proteins.proteinModels(inputFolder) + # Parse the chain indexes if chainIndexes is not None: chainIndexes = [x["chain_index"] for x in chainIndexes] else: chainIndexes = [0] + trajectory_chain_indexes = None # Parse the trajectory chain indexes if trajectoryChainIndexes is not None: trajectoryChainIndexes = [x["trajectory_chain_index"] for x in trajectoryChainIndexes] + trajectory_chain_indexes = {} + for i, model in enumerate(models.models_names): + trajectory_chain_indexes[model] = trajectoryChainIndexes[i] # Parse the reference residues if referenceResidues is not None: referenceResidues = [x["reference_residues"] for x in referenceResidues] - import prepare_proteins - - print("Loading PDB files...") - - models = prepare_proteins.proteinModels(inputFolder) - print("Aligning models...") import subprocess @@ -163,7 +167,7 @@ def hookSubprocessMafft(command, **kwargs): pdbReference, outputFolder, chain_indexes=chainIndexes, - trajectory_chain_indexes=trajectoryChainIndexes, + trajectory_chain_indexes=trajectory_chain_indexes, aligment_mode=alignmentMode, reference_residues=referenceResidues, verbose=True, diff --git a/EAPM/Include/Blocks/AlphaFoldEAPM.py b/EAPM/Include/Blocks/AlphaFoldEAPM.py index 815c9d8..9c80b10 100644 --- a/EAPM/Include/Blocks/AlphaFoldEAPM.py +++ b/EAPM/Include/Blocks/AlphaFoldEAPM.py @@ -2,8 +2,6 @@ Module containing the AlphaFold block for the EAPM plugin """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -72,6 +70,8 @@ def initialAlphafold(block: SlurmBlock): print("Alphafold requires an accelerated partition. Changing to acc_bscls.") block.variables["partition"] = "acc_bscls" + import os + # If folder already exists, raise exception if removeExisting and os.path.exists(folderName): os.system("rm -rf " + folderName) @@ -107,6 +107,8 @@ def finalAlhafoldAction(block: SlurmBlock): resultsFolder = block.extraData["folder_name"] + import os + output_models_folder = os.path.join(downloaded_path, resultsFolder, "output_models") block.setOutput(outputModelsVariable.id, output_models_folder) diff --git a/EAPM/Include/Blocks/AnalyseGlideGPX.py b/EAPM/Include/Blocks/AnalyseGlide.py similarity index 55% rename from EAPM/Include/Blocks/AnalyseGlideGPX.py rename to EAPM/Include/Blocks/AnalyseGlide.py index 425a48a..cd3c048 100644 --- a/EAPM/Include/Blocks/AnalyseGlideGPX.py +++ b/EAPM/Include/Blocks/AnalyseGlide.py @@ -1,11 +1,3 @@ -import json -import os -import shutil - -import bsc_calculations -import pandas as pd -import prepare_proteins - from HorusAPI import PluginBlock, PluginVariable, VariableGroup, VariableTypes # TODO Configure the inputs correctly @@ -28,10 +20,16 @@ defaultValue=None, ) residueProtein = PluginVariable( - name="Atom Protein", id="resi_id1", description="atom1", type=VariableTypes.ATOM + name="Atom Protein", + id="resi_id1", + description="Atom of the protein to calculate the distance to", + type=VariableTypes.ATOM, ) residueLigand = PluginVariable( - name="Atom Ligand", id="resi_id2", description="atom2", type=VariableTypes.ATOM + name="Atom Ligand", + id="resi_id2", + description="Atom of the ligand to calculate the distance to", + type=VariableTypes.ATOM, ) resNameProt = PluginVariable( name="Protein residue name", @@ -40,10 +38,10 @@ type=VariableTypes.STRING, defaultValue="CYS", ) -resNameLig = PluginVariable( - name="Ligand residue name", - id="res_name_lig", - description="The ligand residue name", +atomNameProt = PluginVariable( + name="Protein atomname", + id="atom_name_prot", + description="The protein atom name", type=VariableTypes.STRING, defaultValue="SG", ) @@ -54,12 +52,26 @@ type=VariableTypes.STRING, defaultValue="GSH", ) +atomNameLig = PluginVariable( + name="Ligand atom name", + id="atom_name_ligand", + description="The atom name of the ligand", + type=VariableTypes.STRING, + defaultValue="S1", +) stringGroup = VariableGroup( id="string_input", name="Input String", description="The input are in string", - variables=[conservedResidues, glideOutputVariable, resNameProt, resNameLig, ligandName], + variables=[ + conservedResidues, + glideOutputVariable, + resNameProt, + atomNameProt, + ligandName, + atomNameLig, + ], ) atomGroup = VariableGroup( id="atom_input", @@ -70,12 +82,18 @@ # Output variables outputModelsVariable = PluginVariable( - id="models", - name="Alphafold models", - description="The output models", + id="best_poses", + name="Best poses", + description="The best poses from the analysis", type=VariableTypes.FOLDER, ) - +analyseGlideOutputVariable = PluginVariable( + id="glide_results_output", + name="Glide results output", + description="Output results of the Glide analysis", + type=VariableTypes.CUSTOM, + allowedValues=["glide_output"], +) # ==========================# # Variable @@ -87,10 +105,26 @@ type=VariableTypes.STRING, defaultValue="SG_S", ) +removePreviousVar = PluginVariable( + name="Remove previous models", + id="remove_previous", + description="Remove previous", + type=VariableTypes.BOOLEAN, + defaultValue=False, +) +separatorVar = PluginVariable( + name="Separator", + id="separator", + description="The separator", + type=VariableTypes.STRING, + defaultValue="@", +) def finalAction(block: PluginBlock): + import prepare_proteins + bsc_result = block.inputs.get(glideOutputVariable.id, None) folder_to_analyse = bsc_result["dock_folder"] model_folder = bsc_result["model_folder"] @@ -98,43 +132,58 @@ def finalAction(block: PluginBlock): conserved_indexes = block.inputs.get(conservedResidues.id, None) metrics = block.variables.get("metrics", "SG_S") + remove_previous = block.variables.get("remove_previous", False) + separator = block.variables.get("separator", "@") if block.selectedInputGroup == stringGroup.id: res_name_prot = block.inputs.get(resNameProt.id, "CYS") - res_name_lig = block.inputs.get(resNameLig.id, "SG") + atom_name_prot = block.inputs.get(atomNameProt.id, "SG") ligand_name = block.inputs.get(ligandName.id, "GSH") + atom_name_lig = block.inputs.get(atomNameLig.id, "S1") else: residue_protein = block.inputs.get(residueProtein.id, None) + res_name_prot = residue_protein["auth_comp_id"] + atom_name_prot = residue_protein["auth_atom_id"] residue_ligand = block.inputs.get(residueLigand.id, None) + ligand_name = residue_ligand["auth_comp_id"] + atom_name_lig = residue_ligand["auth_atom_id"] + metrics = f"{atom_name_prot}_{atom_name_lig}" models = prepare_proteins.proteinModels(model_folder) + if conserved_indexes is None: + raise ValueError("Conserved residues must be provided") + if not isinstance(conserved_indexes, dict): + try: + conserved_indexes = int(conserved_indexes) + except ValueError: + raise ValueError("Conserved indexes must be an integer or a dictionary of integers") + conserved_indexes_f = {} + for model in models: + conserved_indexes_f[model] = [conserved_indexes] + conserved_indexes = conserved_indexes_f + center_atom = {} # Create dictionary to store the atom 3-element tuple for each model for model in models: # Iterate the models inside the library # Iterate the residues for each Bio.PDB.Structure object for r in models.structures[model].get_residues(): # Check that the residue matches the defined index - aa = conserved_indexes[model] # for cons_ind in conserved_indexes[model]: if r.id[1] in conserved_indexes[model]: # Assert that the residue has the correct residue identity if r.resname == res_name_prot: # Store the corresponsing tuple. - center_atom[model] = (r.get_parent().id, r.id[1], res_name_lig) + center_atom[model] = (r.get_parent().id, r.id[1], atom_name_prot) break - print(f"center_atom: {center_atom}") - atom_pairs = {} # Define the dictionary containing the atom pairs for each model for model in models: atom_pairs[model] = {} for ligand in [ligand_name]: atom_pairs[model][ligand] = [] - atom_pairs[model][ligand].append((center_atom[model], "S1")) + atom_pairs[model][ligand].append((center_atom[model], atom_name_lig)) - print(f"Atom pairs: {atom_pairs}") - - models.analyseDocking(folder_to_analyse, atom_pairs=atom_pairs) + models.analyseDocking(folder_to_analyse, atom_pairs=atom_pairs, separator=separator) metric_distances = {} # Define the global dictionary metric_distances[metrics] = {} # Define the metric nested dictionary @@ -144,24 +193,38 @@ def finalAction(block: PluginBlock): # Define the ligand nested dictionary with all the docking distances list metric_distances[metrics][model][ligand] = models.getDockingDistances(model, ligand) - print(f"metric_distances: {metric_distances}") - models.combineDockingDistancesIntoMetrics(metric_distances) - print(f"models.docking_data: {models.docking_data}") - best_poses = models.getBestDockingPosesIteratively(metric_distances) - models.extractDockingPoses(best_poses, folder_to_analyse, "best_docking_poses", separator="@") + models.extractDockingPoses( + best_poses, + folder_to_analyse, + "best_docking_poses", + separator=separator, + remove_previous=remove_previous, + ) block.setOutput(outputModelsVariable.id, "best_docking_poses") + glideOutput = { + "poses_folder": "best_docking_poses", + "models_folder": model_folder, # "prepared_proteins", + "atom_pairs": atom_pairs, + } + import pickle + + with open("glide_output.pkl", "wb") as f: + pickle.dump(glideOutput, f) + + block.setOutput(analyseGlideOutputVariable.id, glideOutput) + -AnalyseGPXBlock = PluginBlock( - name="Analyse Glide GPX", - description="To analyse Glide GPX results", +AnalyseGBlock = PluginBlock( + name="Analyse Glide", + description="To analyse Glide results", action=finalAction, - variables=[metricsVar], - inputGroups=[stringGroup, atomGroup], - outputs=[outputModelsVariable], + variables=[metricsVar, removePreviousVar, separatorVar], + inputGroups=[atomGroup, stringGroup], + outputs=[outputModelsVariable, analyseGlideOutputVariable], ) diff --git a/EAPM/Include/Blocks/AnalyseGlideDocking.py b/EAPM/Include/Blocks/AnalyseGlideDocking.py index 504bc56..9d1056b 100644 --- a/EAPM/Include/Blocks/AnalyseGlideDocking.py +++ b/EAPM/Include/Blocks/AnalyseGlideDocking.py @@ -1,6 +1,3 @@ -import datetime -import os - from HorusAPI import ( Extensions, PluginBlock, @@ -133,6 +130,10 @@ def analyseDockingAction(block: PluginBlock): + + import datetime + import os + if block.selectedInputGroup == "folder_variable_group": folder_to_analyse = block.inputs.get("docking_folder", "docking") model_folder = block.inputs.get("model_folder", "models") @@ -391,6 +392,7 @@ def analyseDocking( """ import json + import os import pandas as pd import prepare_proteins @@ -529,6 +531,7 @@ def extractDockingPoses( Remove all content in the output folder """ + import os import shutil # Check the separator is not in model or ligand names diff --git a/EAPM/Include/Blocks/AsiteDesign.py b/EAPM/Include/Blocks/AsiteDesign.py index 1bb9b39..3998ec2 100644 --- a/EAPM/Include/Blocks/AsiteDesign.py +++ b/EAPM/Include/Blocks/AsiteDesign.py @@ -2,10 +2,7 @@ Module containing the Asitedesign block for the EAPM plugin """ -import os -import subprocess - -from HorusAPI import PluginVariable, SlurmBlock, VariableList, VariableTypes +from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# # Variable inputs @@ -72,6 +69,9 @@ def initialAsite(block: SlurmBlock): + import os + import subprocess + # Get the input variables input_yaml = block.inputs.get("input_yaml", None) input_params = block.inputs.get("input_params", None) @@ -110,6 +110,9 @@ def initialAsite(block: SlurmBlock): def finalAsiteAction(block: SlurmBlock): + + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/ConservedResiduesMSA.py b/EAPM/Include/Blocks/ConservedResiduesMSA.py index bee7ae6..de12d8b 100644 --- a/EAPM/Include/Blocks/ConservedResiduesMSA.py +++ b/EAPM/Include/Blocks/ConservedResiduesMSA.py @@ -25,7 +25,7 @@ def getConservedMSAPositions(block: PluginBlock): - proteinFolder = block.inputs.get("protein_folder", "proteins") + proteinFolder = block.inputs.get(proteinFolderVariable.id, "proteins") # Check that there is at least one pdb file in the folder import os @@ -73,7 +73,7 @@ def hookSubprocessMafft(command, **kwargs): Extensions().loadHTML(html, title="Conserved residues") # Get the residue index to get - residueIndexes = block.variables.get("residue_index", []) + residueIndexes = block.variables.get(residueIndexToGetVariable.id, []) if residueIndexes is None or len(residueIndexes) == 0: # Get all the indexes @@ -90,7 +90,7 @@ def hookSubprocessMafft(command, **kwargs): if len(conservedResidues[model]) == 0: raise Exception( "There are no conserved residues for the selected indexes: " - + " ".join(residueIndexes) + + " ".join(str(residueIndexes)) ) break diff --git a/EAPM/Include/Blocks/EpPred.py b/EAPM/Include/Blocks/EpPred.py index 1d385a2..705d77b 100644 --- a/EAPM/Include/Blocks/EpPred.py +++ b/EAPM/Include/Blocks/EpPred.py @@ -1,8 +1,4 @@ -import datetime -import os -import subprocess - -from HorusAPI import PluginVariable, SlurmBlock, VariableList, VariableTypes +from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # TODO Making the block to work in marenostrum, if not, will work in local. # TODO Add to documentation @@ -199,6 +195,8 @@ def runEppred(block: SlurmBlock): + import os + inputfasta = block.inputs.get("input_fasta", None) if inputfasta is None: diff --git a/EAPM/Include/Blocks/HmmAlign.py b/EAPM/Include/Blocks/HmmAlign.py index d494eb1..b993faa 100644 --- a/EAPM/Include/Blocks/HmmAlign.py +++ b/EAPM/Include/Blocks/HmmAlign.py @@ -2,8 +2,6 @@ Module containing the HmmAlign block for the EAPM plugin as a nord3 implementation """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -52,6 +50,8 @@ def runHmmAlign(block: SlurmBlock): + import os + inputfasta = block.inputs.get("input_fasta", None) inputhmm = block.inputs.get("input_hmm", None) @@ -88,7 +88,12 @@ def runHmmAlign(block: SlurmBlock): os.system(f"cp {inputfasta} {folderName}") os.system(f"cp {inputhmm} {folderName}") - jobs = [f"hmmalign {folderName}/{inputhmm} {folderName}/{inputfasta}"] + if block.remote.isLocal: + hmmerExecutable = block.config.get("hmmer_path", "hmmer") + "/hmmalign" + else: + hmmerExecutable = "hmmalign" + + jobs = [f"{hmmerExecutable} {folderName}/{inputhmm} {folderName}/{inputfasta}"] from utils import launchCalculationAction @@ -103,6 +108,8 @@ def runHmmAlign(block: SlurmBlock): def finalAction(block: SlurmBlock): + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/HmmBuild.py b/EAPM/Include/Blocks/HmmBuild.py index 6d5a3cc..9f54e7c 100644 --- a/EAPM/Include/Blocks/HmmBuild.py +++ b/EAPM/Include/Blocks/HmmBuild.py @@ -2,8 +2,6 @@ Module containing the HmmBuild block for the EAPM plugin as a nord3 implementation """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -45,6 +43,8 @@ def runHmmBuild(block: SlurmBlock): + import os + input = block.inputs.get("input_msa", None) if "nord3" not in block.remote.host: @@ -76,7 +76,12 @@ def runHmmBuild(block: SlurmBlock): output = block.outputs.get("output", "output.hmm") - jobs = [f"hmmbuild {folderName}/{output} {folderName}/{input}"] + if block.remote.isLocal: + hmmerExecutable = block.config.get("hmmer_path", "hmmer") + "/hmmbuild" + else: + hmmerExecutable = "hmmbuild" + + jobs = [f"{hmmerExecutable} {folderName}/{output} {folderName}/{input}"] from utils import launchCalculationAction @@ -91,6 +96,8 @@ def runHmmBuild(block: SlurmBlock): def finalAction(block: SlurmBlock): + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/HmmScan.py b/EAPM/Include/Blocks/HmmScan.py index 7dc939a..208228f 100644 --- a/EAPM/Include/Blocks/HmmScan.py +++ b/EAPM/Include/Blocks/HmmScan.py @@ -2,8 +2,6 @@ Module containing the HmmScan block for the EAPM plugin as a nord3 implementation """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -50,6 +48,7 @@ def runHmmScan(block: SlurmBlock): + import os input = block.inputs.get("input_fasta", None) @@ -83,7 +82,12 @@ def runHmmScan(block: SlurmBlock): hmmDB = block.variables.get("hmm_db", None) output = block.outputs.get("output", "output.hmm") - jobs = [f"hmmscan {hmmDB} {folderName}/{input} -o {folderName}/{output}"] + if block.remote.isLocal: + hmmerExecutable = block.config.get("hmmer_path", "hmmer") + "/hmmscan" + else: + hmmerExecutable = "hmmscan" + + jobs = [f"{hmmerExecutable} {hmmDB} {folderName}/{input} -o {folderName}/{output}"] from utils import launchCalculationAction @@ -98,6 +102,8 @@ def runHmmScan(block: SlurmBlock): def finalAction(block: SlurmBlock): + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/HmmSearch.py b/EAPM/Include/Blocks/HmmSearch.py index 10d6fb2..4c46c30 100644 --- a/EAPM/Include/Blocks/HmmSearch.py +++ b/EAPM/Include/Blocks/HmmSearch.py @@ -2,8 +2,6 @@ Module containing the HmmSearch block for the EAPM plugin as a nord3 implementation """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -58,6 +56,8 @@ def runHmmSearch(block: SlurmBlock): + import os + input = block.inputs.get("input_hmm", None) if "nord3" not in block.remote.host: @@ -94,8 +94,13 @@ def runHmmSearch(block: SlurmBlock): "sequence_db", "/gpfs/projects/shared/public/AlphaFold/uniref90/uniref90.fa" ) + if block.remote.isLocal: + hmmerExecutable = block.config.get("hmmer_path", "hmmer") + "/hmmsearch" + else: + hmmerExecutable = "hmmsearch" + jobs = [ - f"hmmsearch --cpu {cpus} -E {evalue} {folderName}/{input} {sequenceDB} -o {folderName}/{output}" + f"{hmmerExecutable} --cpu {cpus} -E {evalue} {folderName}/{input} {sequenceDB} -o {folderName}/{output}" ] from utils import launchCalculationAction @@ -111,6 +116,8 @@ def runHmmSearch(block: SlurmBlock): def finalAction(block: SlurmBlock): + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/HmmSearchLocal.py b/EAPM/Include/Blocks/HmmSearchLocal.py index bd6da5e..b8eeffa 100644 --- a/EAPM/Include/Blocks/HmmSearchLocal.py +++ b/EAPM/Include/Blocks/HmmSearchLocal.py @@ -2,10 +2,7 @@ Module containing the HmmSearch block for the EAPM plugin as a local implementation """ -import os -import pyhmmer -from HorusAPI import PluginBlock, PluginVariable, VariableTypes, Extensions - +from HorusAPI import Extensions, PluginBlock, PluginVariable, VariableTypes # ==========================# # Variable inputs @@ -38,47 +35,51 @@ allowedValues=["domtbl"], ) + def runHmmSearch(block: PluginBlock): - + import os + + import pyhmmer + input = block.inputs.get("input_hmm", None) - + if input is None: raise Exception("No input hmm provided") - + if not os.path.exists(input): raise Exception(f"The input hmm file does not exist: {input}") - + try: with pyhmmer.plan7.HMMFile(input) as hmm_file: hmm = hmm_file.read() except Exception as e: raise Exception(f"Error reading the input hmm file: {e}") - + alphabet = pyhmmer.plan7.Alphabet.amino() background = pyhmmer.plan7.Background(alphabet) pipeline = pyhmmer.plan7.Pipeline(alphabet, background=background) - + sequenceDB = block.inputs.get("sequence_db", None) - + if sequenceDB is None: raise Exception("No sequence database provided") - + if not os.path.exists(sequenceDB): raise Exception(f"The sequence database file does not exist: {sequenceDB}") - + try: with pyhmmer.easel.SequenceFile(sequenceDB, digital=True, alphabet=alphabet) as seq_file: hits = pipeline.search_hmm(hmm, seq_file) except Exception as e: raise Exception(f"Error searching the sequence database: {e}") - + output = block.outputs.get("output", "output.domtbl") - + with open(output, "wb") as f: hits.write(f, format="domains") - + block.setOutput("outputVariable", output) - + hmmsearchLocalBlock = PluginBlock( name="HmmSearch Local", diff --git a/EAPM/Include/Blocks/JackHmmer.py b/EAPM/Include/Blocks/JackHmmer.py index f14d47d..b2f01f9 100644 --- a/EAPM/Include/Blocks/JackHmmer.py +++ b/EAPM/Include/Blocks/JackHmmer.py @@ -2,8 +2,6 @@ Module containing the JackHmmer block for the EAPM plugin as a nord3 implementation """ -import os - from HorusAPI import PluginVariable, SlurmBlock, VariableTypes # ==========================# @@ -44,17 +42,25 @@ id="sequence_db", name="Sequence DB", description="The sequence database to search", - type=VariableTypes.STRING, - defaultValue="/gpfs/projects/shared/public/AlphaFold/uniref90/uniref90.fa", + type=VariableTypes.FILE, + defaultValue="/apps/ACC/ALPHAFOLD/SRC/database/Alphafold/uniref90/uniref90.fasta", +) +folderNameVar = PluginVariable( + id="folder_name", + name="Folder name", + description="The folder name", + type=VariableTypes.FOLDER, + defaultValue="jackHmmer", ) def runJackHmmer(block: SlurmBlock): + import os inputfasta = block.inputs.get("input_fasta", None) - if "nord3" not in block.remote.host: - raise Exception("This block only works on Nord3.") + # if "nord3" not in block.remote.host or "glogin" not in block.remote.host: + # raise Exception("This block only works on Nord3 or mn.") if inputfasta is None: raise Exception("No input fasta provided") @@ -71,7 +77,7 @@ def runJackHmmer(block: SlurmBlock): if not removeExisting and os.path.exists(folderName): raise Exception( - "The folder {} already exists. Please, choose another name or remove it.".format( + "The folder {} already exists. Please, choose another name or remove it with the RemoveExistingFolder option.".format( folderName ) ) @@ -80,15 +86,19 @@ def runJackHmmer(block: SlurmBlock): os.makedirs(folderName, exist_ok=True) os.system(f"cp {inputfasta} {folderName}") + inputfasta = os.path.join(folderName, os.path.basename(inputfasta)) + output = block.outputs.get("output", "output.hmm") sequenceDB = block.variables.get( - "sequence_db", "/gpfs/projects/shared/public/AlphaFold/uniref90/uniref90.fa" + "sequence_db", "/apps/ACC/ALPHAFOLD/SRC/database/Alphafold/uniref90/uniref90.fasta" ) cpus = block.variables.get("cpus", 1) - jobs = [ - f"jackhmmer -o {folderName}/{output} --cpu {cpus} {folderName}/{inputfasta} {sequenceDB}" - ] + if block.remote.isLocal: + hmmerExecutable = block.config.get("hmmer_path", "hmmer") + "/jackhmmer" + else: + hmmerExecutable = "jackhmmer" + jobs = [f"{hmmerExecutable} -o {folderName}/{output} --cpu {cpus} {inputfasta} {sequenceDB}"] from utils import launchCalculationAction @@ -103,6 +113,8 @@ def runJackHmmer(block: SlurmBlock): def finalAction(block: SlurmBlock): + import os + from utils import downloadResultsAction downloaded_path = downloadResultsAction(block) @@ -122,6 +134,6 @@ def finalAction(block: SlurmBlock): finalAction=finalAction, description="Iteratively search a protein sequence against a protein database", inputs=[fastaInput], - variables=BSC_JOB_VARIABLES + [sequenceDBVar, removeExistingResults], + variables=BSC_JOB_VARIABLES + [sequenceDBVar, removeExistingResults, folderNameVar], outputs=[outputVariable], ) diff --git a/EAPM/Include/Blocks/MSA2HMM.py b/EAPM/Include/Blocks/MSA2HMM.py index dcdcf60..d1c0d7d 100644 --- a/EAPM/Include/Blocks/MSA2HMM.py +++ b/EAPM/Include/Blocks/MSA2HMM.py @@ -2,11 +2,7 @@ Module containing the MSA2HMM block for the EAPM plugin """ -import pyhmmer -import os - -from HorusAPI import PluginBlock, PluginVariable, VariableTypes, VariableGroup - +from HorusAPI import PluginBlock, PluginVariable, VariableGroup, VariableTypes # ==========================# # Variable inputs @@ -44,36 +40,39 @@ # ==========================# - def convertMSA2HMM(block: PluginBlock): """ Convert MSA to HMM """ + import os + + import pyhmmer # Loading plugin variables inputMSA = block.inputs.get("input_file_msa") if inputMSA is None: raise Exception("No input MSA provided") - + if not os.path.exists(inputMSA): raise Exception(f"The input MSA file does not exist: {inputMSA}") - + alphabet = pyhmmer.easel.Alphabet.amino() - + with pyhmmer.easel.MSAFile(inputMSA, digital=True, alphabet=alphabet) as msa_file: msa = msa_file.read() msa.name = b"input_msa" - + builder = pyhmmer.plan7.Builder(alphabet) background = pyhmmer.plan7.Background(alphabet) hmm, _, _ = builder.build_msa(msa, background) - + output = "output.hmm" with open(output, "wb") as output_file: hmm.write(output_file) - + block.setOutput("output_hmm", output) - + + convertMSAToHMMBlock = PluginBlock( name="MSA to HMM", description="Convert MSA files to HMM", diff --git a/EAPM/Include/Blocks/Mafft.py b/EAPM/Include/Blocks/Mafft.py index 473c19e..b1e764d 100644 --- a/EAPM/Include/Blocks/Mafft.py +++ b/EAPM/Include/Blocks/Mafft.py @@ -2,10 +2,7 @@ Module containing the Mafft block for the EAPM plugin """ -import Bio.AlignIO -import Bio.SeqIO - -from HorusAPI import Extensions, PluginBlock, PluginVariable, VariableTypes +from HorusAPI import PluginBlock, PluginVariable, VariableTypes # ==========================# # Variable inputs diff --git a/EAPM/Include/Blocks/PDBToMAE.py b/EAPM/Include/Blocks/PDBToMAE.py index e033459..4f0f6bb 100644 --- a/EAPM/Include/Blocks/PDBToMAE.py +++ b/EAPM/Include/Blocks/PDBToMAE.py @@ -1,6 +1,3 @@ -import os -import shutil - from HorusAPI import PluginBlock, PluginVariable, VariableGroup, VariableTypes # Input variables @@ -45,6 +42,9 @@ def convertPDBToMAE(block: PluginBlock): + import os + import shutil + # Test if we have valid glide installation command = "echo $SCHRODINGER" output = block.remote.remoteCommand(command) @@ -58,7 +58,23 @@ def convertPDBToMAE(block: PluginBlock): import prepare_proteins - pdb_folder = block.inputs.get("pdb_folder", None) + if block.selectedInputGroup == singlePDBVariable.id: + pdb_file = block.inputs.get("single_pdb", None) + + if pdb_file is None: + raise Exception("No PDB file selected") + + if not os.path.isfile(pdb_file): + raise Exception(f"Invalid PDB file: {pdb_file}") + + if os.path.exists("tmp_ligand"): + shutil.rmtree("tmp_ligand") + os.mkdir("tmp_ligand") + shutil.copy(pdb_file, "tmp_ligand") + + pdb_folder = os.path.join(os.getcwd(), "tmp_ligand") + else: + pdb_folder = block.inputs.get("pdb_folder", None) if pdb_folder is None: raise Exception("No PDB folder selected") @@ -163,12 +179,6 @@ def mockSystem(command): name="PDB to MAE", description="Convert PDB files to MAE for Glide", inputGroups=[ - VariableGroup( - id=structureVariable.id, - name=structureVariable.name, - description=structureVariable.description, - variables=[structureVariable], - ), VariableGroup( id=singlePDBVariable.id, name=singlePDBVariable.name, @@ -181,6 +191,12 @@ def mockSystem(command): description=pdbFolderVariable.description, variables=[pdbFolderVariable], ), + VariableGroup( + id=structureVariable.id, + name=structureVariable.name, + description=structureVariable.description, + variables=[structureVariable], + ), ], variables=[changeLigandNameVariable], outputs=[outputVariable], diff --git a/EAPM/Include/Blocks/PeleEAPM.py b/EAPM/Include/Blocks/PeleEAPM.py index ddb9136..636fec9 100644 --- a/EAPM/Include/Blocks/PeleEAPM.py +++ b/EAPM/Include/Blocks/PeleEAPM.py @@ -1,4 +1,4 @@ -import random + from HorusAPI import (PluginVariable, SlurmBlock, VariableGroup, VariableList, VariableTypes) @@ -9,7 +9,7 @@ name="PELE yaml", description="YAML file containing the PELE configuration", type=VariableTypes.FILE, - defaultValue="cst_input.yaml", + defaultValue="input.yaml", allowedValues=["yaml"], ) @@ -25,7 +25,7 @@ id="poses_folder", name="Best docking poses", description="Best docking poses to analyse", - type=VariableTypes.FOLDER + type=VariableTypes.FOLDER, ) glideOutputVariable = PluginVariable( @@ -41,7 +41,7 @@ id="folder_input_group", name="Folder input group", description="Input the model and ligand folders after a Dcoking Grid setup has been run", - variables=[modelFolderVariable, posesFolderVariable, yamlPELEFileVariable] + variables=[modelFolderVariable, posesFolderVariable, yamlPELEFileVariable], ) glideOutputGroup = VariableGroup( @@ -168,7 +168,7 @@ name="PELE separator", description="Separator for the PELE models and ligands", type=VariableTypes.STRING, - defaultValue="-", + defaultValue="@", category="PELE", ) @@ -326,7 +326,7 @@ description="Enable log file", type=VariableTypes.BOOLEAN, defaultValue=False, - category="PELE" + category="PELE", ) rescoringVariable = PluginVariable( @@ -335,7 +335,7 @@ description="Enable rescoring", type=VariableTypes.BOOLEAN, defaultValue=False, - category="PELE" + category="PELE", ) epsilonVariable = PluginVariable( @@ -344,7 +344,7 @@ description="TODO Epsilon description", type=VariableTypes.FLOAT, defaultValue=0.5, - category="PELE" + category="PELE", ) ligandEquilibrationCstVariable = PluginVariable( @@ -353,7 +353,7 @@ description="TODO Ligand equilibration cst description", type=VariableTypes.BOOLEAN, defaultValue=True, - category="PELE" + category="PELE", ) covalentSetupVariable = PluginVariable( @@ -362,7 +362,7 @@ description="Enable covalent setup", type=VariableTypes.BOOLEAN, defaultValue=False, - category="PELE" + category="PELE", ) nonbondedNewFlagVariable = PluginVariable( @@ -371,7 +371,7 @@ description="Enable nonbonded new flag", type=VariableTypes.BOOLEAN, defaultValue=False, - category="PELE" + category="PELE", ) onlyModelsVariable = PluginVariable( @@ -414,12 +414,12 @@ category="PELE", ) -membraneResiduesVariable= PluginVariable( +membraneResiduesVariable = PluginVariable( id="membrane_residues", name="Membrane residues", description="TODO membrane residues description", type=VariableTypes.LIST, - category="PELE" + category="PELE", ) biasToPointVariable = PluginVariable( @@ -427,7 +427,7 @@ name="Bias to point", description="TODO bias_to_point description", type=VariableTypes.LIST, - category="PELE" + category="PELE", ) comBias1Variable = PluginVariable( @@ -435,7 +435,7 @@ name="com bias1", description="TODO com_bias1 description", type=VariableTypes.LIST, - category="PELE" + category="PELE", ) comBias2Variable = PluginVariable( @@ -443,7 +443,7 @@ name="com bias2", description="TODO com_bias2 description", type=VariableTypes.LIST, - category="PELE" + category="PELE", ) ligandTemplateVariable = PluginVariable( @@ -478,35 +478,35 @@ id="model", name="Model", description="TODO model variable description", - type=VariableTypes.STRING + type=VariableTypes.STRING, ) ligandVariable = PluginVariable( id="ligand", name="Ligand", description="TODO ligand variable description", - type=VariableTypes.STRING + type=VariableTypes.STRING, ) chainVariable = PluginVariable( id="chain", name="Chain", description="TODO chain variable description", - type=VariableTypes.STRING + type=VariableTypes.STRING, ) residueVariable = PluginVariable( id="residue", name="Residue number", description="TODO residue number variable description", - type=VariableTypes.INTEGER + type=VariableTypes.INTEGER, ) atomNameVariable = PluginVariable( id="atom_name", name="Atom name", description="TODO atom name variable description", - type=VariableTypes.STRING + type=VariableTypes.STRING, ) # box_centers VariableList @@ -515,13 +515,7 @@ name="Box centers", description="TODO Box center variable description", category="PELE", - prototypes=[ - modelVariable, - ligandVariable, - chainVariable, - residueVariable, - atomNameVariable - ], + prototypes=[modelVariable, ligandVariable, chainVariable, residueVariable, atomNameVariable], ) # Outputs @@ -533,9 +527,13 @@ ) - def peleAction(block: SlurmBlock): if block.selectedInputGroup == "glide_output_group": + glide_outputr = block.inputs.get("glide_output") + # load the pickle file + + # with open(glide_outputr, "rb") as f: + # glide_output = pickle.load(f) glide_output = block.inputs.get("glide_output") poses_folder = glide_output.get("poses_folder") models_folder = glide_output.get("models_folder") @@ -549,7 +547,7 @@ def peleAction(block: SlurmBlock): atom_pairs = {} # Get all the variables from the block - boxCentersValue = block.variables.get("box_centers", []) + boxCentersValue = block.variables.get("box_centers", None) boxRadiusValue = block.variables.get("box_radius", 10) constraintsValue = block.variables.get("constraints", []) ligandIndexValue = block.variables.get("ligand_index", 1) @@ -558,7 +556,7 @@ def peleAction(block: SlurmBlock): peleIterationsValue = block.variables.get("pele_iterations", 5) equilibrationStepsValue = block.variables.get("equilibration_steps", 100) ligandEnergyGroupsValue = block.variables.get("ligand_energy_groups", []) - peleSeparatorValue = block.variables.get("pele_separator", "-") + peleSeparatorValue = block.variables.get("pele_separator", "@") usePeleffyValue = block.variables.get("use_peleffy", True) useSrunValue = block.variables.get("use_srun", True) energyByResidueValue = block.variables.get("energy_by_residue", False) @@ -579,7 +577,7 @@ def peleAction(block: SlurmBlock): onlyModelsValue = block.variables.get("only_models", []) onlyLigandsValue = block.variables.get("only_ligands", []) onlyCombinationsValue = block.variables.get("only_combinations", []) - nonbondedEnergyValue = block.variables.get('nonbonded_energy', {}) + nonbondedEnergyValue = block.variables.get("nonbonded_energy", {}) ligandTemplateValue = block.variables.get("ligand_template", "") seedValue = block.variables.get("seed", -1) logFileValue = block.variables.get("log_file", False) @@ -595,19 +593,31 @@ def peleAction(block: SlurmBlock): comBias2Value = block.variables.get("com_bias2", {}) # Parse spawningValue - validSpawnings = ['independent', 'inverselyProportional', 'epsilon', 'variableEpsilon', - 'independentMetric', 'UCB', 'FAST', 'ProbabilityMSM', 'MetastabilityMSM', - 'IndependentMSM'] - + validSpawnings = [ + "independent", + "inverselyProportional", + "epsilon", + "variableEpsilon", + "independentMetric", + "UCB", + "FAST", + "ProbabilityMSM", + "MetastabilityMSM", + "IndependentMSM", + ] + if spawningValue != None and spawningValue not in validSpawnings: - message = 'Spawning method %s not found.' % spawningValue - message = 'Allowed options are: ' + str(validSpawnings) - raise ValueError(message) + message = "Spawning method %s not found." % spawningValue + message = "Allowed options are: " + str(validSpawnings) + raise ValueError(message) # Parse energyByResidueValue - energy_by_residue_types = ['all', 'lennard_jones', 'sgb', 'electrostatic'] + energy_by_residue_types = ["all", "lennard_jones", "sgb", "electrostatic"] if energyByResidueTypeValue not in energy_by_residue_types: - raise ValueError('%s not found. Try: %s' % (energyByResidueTypeValue, energy_by_residue_types)) + raise ValueError( + "%s not found. Try: %s" % (energyByResidueTypeValue, energy_by_residue_types) + ) + import random # Parse seedValue if seedValue == -1: @@ -616,44 +626,49 @@ def peleAction(block: SlurmBlock): # Parse ligandEnergyGroups if not isinstance(ligandEnergyGroupsValue, type(None)): if not isinstance(ligandEnergyGroupsValue, dict): - raise ValueError('Ligand energy groups, must be given as a dictionary') - - # Parse box_centers + raise ValueError("Ligand energy groups, must be given as a dictionary") - box_centers = {} - for model in boxCentersValue: - box_centers[(model['model'], model['ligand'])] = (model['chain'], model['residue'], model['atom_name']) + # Parse box_centers + if not isinstance(boxCentersValue, type(None)) or boxCentersValue is not None: + box_centers = {} + for model in boxCentersValue: + box_centers[(model["model"], model["ligand"])] = ( + model["chain"], + model["residue"], + model["atom_name"], + ) + else: + box_centers = None # Parse skip_models if not isinstance(skipModelsValue, type(None)): if not isinstance(skipModelsValue, list): - raise ValueError('skip_models must be a list.') + raise ValueError("skip_models must be a list.") - # Parse skip_ligands if not isinstance(skipLigandsValue, type(None)): if not isinstance(skipLigandsValue, list): - raise ValueError('skip_ligands must be a list.') + raise ValueError("skip_ligands must be a list.") # Parse nonbonded_energy if not isinstance(nonbondedEnergyValue, type(None)): if not isinstance(nonbondedEnergyValue, dict): - raise ValueError('nonbonded_energy, must be given as a dictionary') + raise ValueError("nonbonded_energy, must be given as a dictionary") # Parse only_ligands if not isinstance(onlyLigandsValue, type(None)): if not isinstance(onlyLigandsValue, list): - raise ValueError('only_ligands must be a list.') - + raise ValueError("only_ligands must be a list.") + # Parse only_models if not isinstance(onlyModelsValue, type(None)): if not isinstance(onlyModelsValue, list): - raise ValueError('only_models must be a list.') + raise ValueError("only_models must be a list.") # Parse only_combinations if not isinstance(onlyCombinationsValue, type(None)): if not isinstance(onlyCombinationsValue, list): - raise ValueError('only_combinations must be a list.') + raise ValueError("only_combinations must be a list.") import prepare_proteins @@ -663,7 +678,7 @@ def peleAction(block: SlurmBlock): selections = block.variables.get("selections_list", []) if atom_pairs == {}: groups = [] - for model in models: + for model in models: atom_pairs[model] = {} for selection in selections: current_group = selection["group"] @@ -686,7 +701,7 @@ def peleAction(block: SlurmBlock): atom_pairs[model][ligandName] = [] atom_pairs[model][ligandName].append((protein_tuple, ligand_atom)) - cst_yaml = block.inputs.get("yaml_pele_file") + input_yaml = block.inputs.get("yaml_pele_file") cpus = block.variables.get("cpus", 48) peleFolderName = block.variables.get("pele_folder_name", "pele") @@ -694,7 +709,7 @@ def peleAction(block: SlurmBlock): jobs = models.setUpPELECalculation( peleFolderName, poses_folder, - cst_yaml, + input_yaml, box_radius=boxRadiusValue, iterations=peleIterationsValue, cpus=cpus, @@ -738,7 +753,7 @@ def peleAction(block: SlurmBlock): bias_to_point=biasToPointValue, com_bias1=comBias1Value, com_bias2=comBias2Value, - ligand_energy_groups=ligandEnergyGroupsValue + ligand_energy_groups=ligandEnergyGroupsValue, ) from utils import launchCalculationAction @@ -754,7 +769,7 @@ def peleAction(block: SlurmBlock): ) -def peleFinalAction(block: SlurmBlock):# +def peleFinalAction(block: SlurmBlock): # print("Pele finished") from utils import downloadResultsAction @@ -766,7 +781,6 @@ def peleFinalAction(block: SlurmBlock):# block.setOutput("pele_output_folder", peleFolderName) - from utils import BSC_JOB_VARIABLES blockVariables = BSC_JOB_VARIABLES + [ @@ -813,18 +827,20 @@ def peleFinalAction(block: SlurmBlock):# membraneResiduesVariable, biasToPointVariable, comBias1Variable, - comBias2Variable - + comBias2Variable, ] + def wrappedFunction(block: SlurmBlock): try: peleAction(block) except Exception as e: import traceback + print("Exception:", e) traceback.print_exc() + peleBlock = SlurmBlock( name="PELE", description="Run PELE", diff --git a/EAPM/Include/Blocks/PrepWizardEAPM.py b/EAPM/Include/Blocks/PrepWizardEAPM.py index 08e903a..70774a2 100644 --- a/EAPM/Include/Blocks/PrepWizardEAPM.py +++ b/EAPM/Include/Blocks/PrepWizardEAPM.py @@ -2,9 +2,7 @@ Module containing the PrepWizard block for the EAPM plugin """ -import os - -from HorusAPI import PluginVariable, SlurmBlock, VariableTypes +from HorusAPI import PluginVariable, SlurmBlock, VariableGroup, VariableTypes # ==========================# # Variable inputs @@ -16,6 +14,26 @@ type=VariableTypes.FOLDER, defaultValue=None, ) +inputFilePW = PluginVariable( + name="Input File", + id="input_file", + description="File of the pdb to prepare.", + type=VariableTypes.FILE, + allowedValues=["pdb"], +) +folderVariableGroup = VariableGroup( + id="folder_variable_group", + name="Folder variable group", + description="Input folder with the models.", + variables=[inputFolderPW], +) +fileVariableGroup = VariableGroup( + id="file_output_variable_group", + name="PDB file group", + description="Input PDB file.", + variables=[inputFilePW], +) + # ==========================# # Variable outputs @@ -26,6 +44,13 @@ description="Folder containing the prepared proteins.", type=VariableTypes.FOLDER, ) +outputPDB = PluginVariable( + name="Output PDB", + id="out_pdb", + description="Last PDB of the Prepwizard.", + type=VariableTypes.FILE, + allowedValues=["pdb"], +) ############################## # Block's advanced variables # @@ -39,6 +64,7 @@ ) +# Variables phPW = PluginVariable( name="PH", id="ph", @@ -112,28 +138,36 @@ def prepWizardAction(block: SlurmBlock): Args: block (SlurmBlock): The block to run the action on. """ - # Loading plugin variables - inputFolder = block.inputs.get("input_folder", None) - if inputFolder is None: - raise Exception("No input folder provided.") + + import os + + if block.selectedInputGroup == fileVariableGroup.id: + input_file = block.inputs.get(inputFilePW.id, None) + input_folder = "models" + os.makedirs(input_folder, exist_ok=True) + os.system(f"cp {input_file} {input_folder}") + elif block.selectedInputGroup == folderVariableGroup.id: + input_folder = block.inputs.get(inputFolderPW.id, None) + else: + raise Exception("No input selected") # Get prepWizard variables - folderName = block.variables.get("folder_name", "prepared_proteins") - ph = int(block.variables.get("ph", 7)) - epikPH = block.variables.get("epik_ph", False) - sampleWater = block.variables.get("sample_water", False) - removeHydrogens = block.variables.get("remove_hydrogens", False) - delWaterHbondCutOff = block.variables.get("del_water_hbond_cut_off", False) - fillLoops = block.variables.get("fill_loops", False) - protonationStates = block.variables.get("protonation_states", None) - noepik = block.variables.get("no_epik", False) - noProtAssign = block.variables.get("no_prot_assign", False) + folderName = block.variables.get(folderNameVariable.id, "prepared_proteins") + ph = int(block.variables.get(phPW.id, 7)) + epikPH = block.variables.get(epikPHPW.id, False) + sampleWater = block.variables.get(sampleWaterPW.id, False) + removeHydrogens = block.variables.get(removeHydrogensPW.id, False) + delWaterHbondCutOff = block.variables.get(delWaterHbondCutOffPW.id, False) + fillLoops = block.variables.get(fillLoopsPW.id, False) + protonationStates = block.variables.get(protonationStatesPW.id, None) + noepik = block.variables.get(noepikPW.id, False) + noProtAssign = block.variables.get(noProtAssignPW.id, False) import prepare_proteins print("Loading pdbs files...") - models = prepare_proteins.proteinModels(inputFolder) + models = prepare_proteins.proteinModels(input_folder) print("Setting up PrepWizard Optimitzations...") @@ -173,11 +207,13 @@ def prepWizardAction(block: SlurmBlock): def downloadPrepWizardResults(block: SlurmBlock): + import os + from utils import downloadResultsAction downloadResultsAction(block) - folderName = block.variables.get("folder_name", "prepared_proteins") + folderName = block.variables.get(folderNameVariable.id, "prepared_proteins") # Create the output folder containing the prepared proteins if not os.path.exists(folderName): @@ -193,7 +229,8 @@ def downloadPrepWizardResults(block: SlurmBlock): pdbPath = os.path.join(folderName + "_wizard", "output_models", model, file) shutil.copyfile(pdbPath, finalPath) - block.setOutput("prepared_proteins", folderName) + block.setOutput(outputPDB.id, finalPath) + block.setOutput(outputPW.id, folderName) from utils import BSC_JOB_VARIABLES @@ -218,6 +255,6 @@ def downloadPrepWizardResults(block: SlurmBlock): initialAction=prepWizardAction, finalAction=downloadPrepWizardResults, variables=block_variables, - inputs=[inputFolderPW], - outputs=[outputPW], + inputGroups=[folderVariableGroup, fileVariableGroup], + outputs=[outputPDB, outputPW], ) diff --git a/EAPM/Include/Blocks/Rbcavity.py b/EAPM/Include/Blocks/Rbcavity.py new file mode 100644 index 0000000..04b89ac --- /dev/null +++ b/EAPM/Include/Blocks/Rbcavity.py @@ -0,0 +1,93 @@ +""" +Module containing the rbcavity block for the EAPM plugin +""" + +from HorusAPI import PluginBlock, PluginVariable, VariableTypes + +# ==========================# +# Variable inputs +# ==========================# +inputPRMFile = PluginVariable( + name="Parameter file", + id="input_prm_file", + description="The input '.prm' file.", + type=VariableTypes.FILE, + defaultValue="parameter_file.prm", + allowedValues=["prm"], +) + +# ==========================# +# Variable outputs +# ==========================# +outputLog = PluginVariable( + name="Output log", + id="output_log", + description="The output log file.", + type=VariableTypes.FILE, + defaultValue="parameter_file.log", +) + + +############################## +# Other variables # +############################## +was = PluginVariable( + name="Was", + id="was", + description="Write docking cavities (plus distance grid) to .as file.", + type=VariableTypes.BOOLEAN, + defaultValue=True, +) +dumpInsight = PluginVariable( + name="Dump Insight", + id="dump_insight", + description="Dump InsightII/PyMOL grids for each cavity for visualisation.", + type=VariableTypes.BOOLEAN, + defaultValue=False, +) + + +# Align action block +def initialRbcavity(block: PluginBlock): + + if block.remote.name != "Local": + raise Exception("This block is only available for local execution.") + + # Loading plugin variables + input_PRMfile = block.inputs.get(inputPRMFile.id, None) + output_log = block.outputs.get(outputLog.id, "parameter_file.log") + + # rbcavity -was -d -r parameter_file.prm > parameter_file.log + command = "rbcavity " + if block.variables.get("was", True): + command += "-was " + if block.variables.get("dump_insight", False): + command += "-d " + command += f"-r {input_PRMfile} > {output_log}" + + print("Setting output of block to the results directory...") + + # subprocess the command + import subprocess + + completed_process = subprocess.run(command, shell=True, capture_output=True, text=True) + + # Get the output and error + output = completed_process.stdout + error = completed_process.stderr + + # Set the output + block.setOutput(outputLog.id, output_log) + + +rbCavityBlock = PluginBlock( + name="Rbcavity", + description="Calculate docking cavities. (For local)", + action=initialRbcavity, + variables=[ + was, + dumpInsight, + ], + inputs=[inputPRMFile], + outputs=[outputLog], +) diff --git a/EAPM/Include/Blocks/Rbdock.py b/EAPM/Include/Blocks/Rbdock.py new file mode 100644 index 0000000..38d0124 --- /dev/null +++ b/EAPM/Include/Blocks/Rbdock.py @@ -0,0 +1,128 @@ +""" +Module containing the rbdock block for the EAPM plugin +""" + +from HorusAPI import PluginBlock, PluginVariable, VariableTypes + +# ==========================# +# Variable inputs +# ==========================# +inputPRMFile = PluginVariable( + name="Parameter file", + id="input_prm_file", + description="The input '.prm' file.", + type=VariableTypes.FILE, + defaultValue="parameter_file.prm", + allowedValues=["prm"], +) +inputLigand = PluginVariable( + name="Ligand SD file", + id="input_ligand", + description="The input ligand SD file.", + type=VariableTypes.FILE, + allowedValues=["sd"], +) + +# ==========================# +# Variable outputs +# ==========================# +outputFile = PluginVariable( + name="Output File", + id="output_file", + description="The output file with the ligand docked.", + type=VariableTypes.FILE, + defaultValue="parameter_file", +) + + +############################## +# Other variables # +############################## +protoPrmFile = PluginVariable( + name="proto Prm File", + id="proto_prm_file", + description="The docking protocol parameter file.", + type=VariableTypes.FILE, + defaultValue="dock.prm", +) +nRuns = PluginVariable( + name="nRuns", + id="n_runs", + description="Number of runs/ligand (default=1).", + type=VariableTypes.INTEGER, + defaultValue=None, +) +allH = PluginVariable( + name="allH", + id="all_h", + description="Keep all hydrogens, read all hydrogens present (default=polar hydrogens only).", + type=VariableTypes.BOOLEAN, + defaultValue=False, +) + + +# Align action block +def initialRbdock(block: PluginBlock): + + import os + + if block.remote.name != "Local": + raise Exception("This block is only available for local execution.") + + # Loading plugin variables + input_PRMfile = block.inputs.get(inputPRMFile.id, None) + if input_PRMfile is None: + raise Exception("No parameter file provided.") + if not os.path.exists(input_PRMfile): + raise Exception("Parameter file does not exist.") + input_ligand = block.inputs.get(inputLigand.id, None) + out = "output_dock" + if input_ligand is None: + raise Exception("No ligand file provided.") + if not os.path.exists(input_ligand): + raise Exception("Ligand file does not exist.") + else: + out = os.path.basename(input_ligand).split(".")[0] + "_out" + output_file = block.outputs.get(outputFile.id, out) + + # rbcavity -was -d -r parameter_file.prm > parameter_file.log + command = f"rbdock -i {input_ligand} -o {output_file} -r {input_PRMfile} " + if block.variables.get("proto_prm_file", None) is not None: + command += f"-p {block.variables.get('proto_prm_file')} " + if block.variables.get("n_runs", None) is not None: + command += f"-n {block.variables.get('n_runs')} " + if block.variables.get("all_h", False): + command += "-allH " + + print("Setting output of block to the results directory...") + + # Subprocess the command + import subprocess + + completed_process = subprocess.run(command, shell=True, capture_output=True, text=True) + + # Get the output and error + output = completed_process.stdout + # Save the output and error + with open(f"{output_file}.out", "w") as f: + f.write(output) + error = completed_process.stderr + with open(f"{output_file}.err", "w") as f: + f.write(error) + + # Set the output + block.setOutput(outputFile.id, output_file) + + +rbDockBlock = PluginBlock( + name="Rbdock", + description="Calculate the docking. (For local)", + action=initialRbdock, + variables=[ + protoPrmFile, + nRuns, + allH, + ], + inputs=[inputPRMFile, inputLigand], + outputs=[outputFile], +) diff --git a/EAPM/Include/Blocks/SetupDockingGrid.py b/EAPM/Include/Blocks/SetupDockingGrid.py index 4a41dfd..73b3898 100644 --- a/EAPM/Include/Blocks/SetupDockingGrid.py +++ b/EAPM/Include/Blocks/SetupDockingGrid.py @@ -1,6 +1,4 @@ -import os - -from HorusAPI import InputBlock, PluginVariable, SlurmBlock, VariableGroup, VariableTypes +from HorusAPI import PluginVariable, SlurmBlock, VariableGroup, VariableTypes # Input variables modelFolderVariable = PluginVariable( @@ -45,6 +43,8 @@ # Action def glideDocking(block: SlurmBlock): + import os + import prepare_proteins models_folder = block.inputs.get("model_folder") diff --git a/EAPM/Include/Blocks/SetupGlide.py b/EAPM/Include/Blocks/SetupGlide.py index 1107585..908875e 100644 --- a/EAPM/Include/Blocks/SetupGlide.py +++ b/EAPM/Include/Blocks/SetupGlide.py @@ -1,6 +1,3 @@ -import os -import shutil - from HorusAPI import PluginVariable, SlurmBlock, VariableGroup, VariableTypes # Input variables @@ -54,6 +51,9 @@ def setupGlideDocking(block: SlurmBlock): + import os + import shutil + import prepare_proteins if block.selectedInputGroup == "folder_input_group": @@ -138,6 +138,8 @@ def setupGlideDocking(block: SlurmBlock): def downloadGlideDocking(block: SlurmBlock): + import os + from utils import downloadResultsAction downloadResultsAction(block) diff --git a/EAPM/Include/Blocks/TrimAlphafoldModels.py b/EAPM/Include/Blocks/TrimAlphafoldModels.py index 2d96444..a24eae0 100644 --- a/EAPM/Include/Blocks/TrimAlphafoldModels.py +++ b/EAPM/Include/Blocks/TrimAlphafoldModels.py @@ -1,6 +1,3 @@ -import os -import shutil - from HorusAPI import PluginBlock, PluginVariable, VariableTypes resultsFolderAF = PluginVariable( @@ -37,6 +34,8 @@ def trimAlphaFoldModels(block: PluginBlock): + import os + import shutil # Get the models folder models_folder = block.inputs.get("results_folder", None) diff --git a/EAPM/Include/Blocks/testBlock.py b/EAPM/Include/Blocks/testBlock.py index 36b14cb..ded4d28 100644 --- a/EAPM/Include/Blocks/testBlock.py +++ b/EAPM/Include/Blocks/testBlock.py @@ -1,6 +1,3 @@ -import os -import shutil - from HorusAPI import PluginBlock, PluginVariable, VariableTypes # ==========================# @@ -43,6 +40,8 @@ def finalAlhafoldAction(block: PluginBlock): + import os + import shutil resultsFolder = "alphafold" downloaded_path = "/home/perry/data/acanella/testHorus/all_test/alphafold" diff --git a/EAPM/Include/Configs/hmmerConfig.py b/EAPM/Include/Configs/hmmerConfig.py index b3c5322..451b6e2 100644 --- a/EAPM/Include/Configs/hmmerConfig.py +++ b/EAPM/Include/Configs/hmmerConfig.py @@ -18,7 +18,7 @@ def checkHmmerInstallation(block: PluginConfig): hmmerPath = block.variables.get(hmmerPathVariable.id) # Check if the path is valid - if not os.path.isfile(hmmerPath): + if not os.path.isdir(hmmerPath): raise Exception("The HMMER executable path is not valid") diff --git a/EAPM/Include/utils.py b/EAPM/Include/utils.py index 9201443..87dc0ac 100644 --- a/EAPM/Include/utils.py +++ b/EAPM/Include/utils.py @@ -4,8 +4,7 @@ import subprocess import typing -from HorusAPI import (PluginBlock, PluginVariable, SlurmBlock, VariableList, - VariableTypes) +from HorusAPI import PluginBlock, PluginVariable, SlurmBlock, VariableList, VariableTypes localIPs = {"cactus": "84.88.51.217", "blossom": "84.88.51.250", "bubbles": "84.88.51.219"} @@ -36,7 +35,7 @@ def setup_bsc_calculations_based_on_horus_remote( if program == "pele": if cluster not in [ "glogin1.bsc.es", - "glogin4.bsc.es", + "glogin2.bsc.es", "glogin3.bsc.es", "glogin4.bsc.es", "nord3.bsc.es", @@ -121,7 +120,7 @@ def setup_bsc_calculations_based_on_horus_remote( program=program, script_name=scriptName, cpus=cpus, - #module_purge=modulePurge, + # module_purge=modulePurge, ) # powerpuff elif cluster == "powerpuff": diff --git a/EAPM/config/eapm.json b/EAPM/config/eapm.json index e4550b8..f9593d4 100644 --- a/EAPM/config/eapm.json +++ b/EAPM/config/eapm.json @@ -1,4 +1,4 @@ { "mafft_path": "/home/perry/miniconda3/envs/horus/bin/mafft", - "hmmer_path": "/gpfs/projects/bsc72/conda_envs/hmm/bin/hmmsearch" + "hmmer_path": "/home/perry/miniconda3/envs/horus/bin" } \ No newline at end of file diff --git a/EAPM/preinst.sh b/EAPM/preinst.sh index b19f3b8..f33cc76 100644 --- a/EAPM/preinst.sh +++ b/EAPM/preinst.sh @@ -1,3 +1,3 @@ -pip install "pycaret[analysis, models]" --target deps +# pip install "pycaret[analysis, models]" --target deps -pip install "werkzeug<=2.3.0" +# pip install "werkzeug<=2.3.0"