Source code for aiida_amber.data.tleap_input

"""Sub class of `Data` to handle inputs used and outputs that will be produced
from commands in the tleap input file."""
import re
import os
import sys
from aiida.orm import SinglefileData, FolderData, List
from aiida_amber.utils import node_utils


[docs] class TleapInputData(SinglefileData): """Class to find the inputs used and outputs produced from the commands in the tleap input file"""
[docs] def set_file(self, file, filename=None, **kwargs): """Add a file to the node, parse it and set the attributes found. :param file: absolute path to the file or a filelike object :param filename: specify filename to use (defaults to name of provided file). """ super().set_file(file, filename, **kwargs) # Parse the tleap file parsed_info = parse_tleap_input_file(self.get_content().splitlines()) # Add all other attributes found in the parsed dictionary for key, value in parsed_info.items(): self.base.attributes.set(key, value)
@property def inpfile_list(self): """Return the list input files used in the tleap script """ return self.base.attributes.get('input_files') @property def outfile_list(self): """Return the list output files to be produced from the tleap script """ return self.base.attributes.get('output_files') @property def calculation_inputs_outputs(self): """Return the inputs for the tleap calculation job """ input_files = self.inpfile_list subdirs, files = node_utils.check_filepath(input_files) calc_inputs = add_calculation_inputs(subdirs, files) output_files = self.outfile_list calc_outputs = add_calculation_outputs(output_files) return calc_inputs, calc_outputs
[docs] def parse_tleap_input_file(lines): """Parse tleap script and find any instances of file loads (inputs) or saves (outputs) """ input_files = [] output_files = [] # iterate through tleap lines and find input and output files for line in lines: head, sep, tail = line.partition("#") # if "load" string in line then find input file if re.search("load", head, re.IGNORECASE): split_line = head.split() if len(split_line) > 2: if "load" in split_line[-2]: input_files.append(split_line[-1]) if "load" in split_line[0]: input_files.append(split_line[1]) # if "save" string in line then find output file if re.search("save", head, re.IGNORECASE): if re.search("saveAmberParm", head, re.IGNORECASE): output_files.extend(head.split()[-2:]) else: output_files.append(head.split()[2]) if re.search("logFile", head, re.IGNORECASE): output_files.append(head.split()[-1]) parsed_info = {} parsed_info["input_files"] = input_files parsed_info["output_files"] = output_files return parsed_info
[docs] def add_calculation_inputs(subdirs, files): """If they exist, add input files for tleap and dirs into the calcjob inputs directory """ calc_inputs = {} input_list = [] # If we have tleap input files then tag them. if files: calc_inputs["tleap_inpfiles"] = {} # Iterate files to assemble a dict of names and paths. for file in files: formatted_filename = node_utils.format_link_label(file) if os.path.isfile(file): input_list.append(file) calc_inputs["tleap_inpfiles"][formatted_filename] = \ SinglefileData(file=os.path.join(os.getcwd(), file)) elif "PYTEST_CURRENT_TEST" in os.environ: test_path = os.path.join(os.getcwd(), 'tests/input_files/tleap', file) if os.path.isfile(test_path): calc_inputs["tleap_inpfiles"][formatted_filename] = \ SinglefileData(file=test_path) else: sys.exit(f"Error: Input file {file} referenced in tleap file does not exist") else: sys.exit(f"Error: Input file {file} referenced in tleap file does not exist") # If we have included files in subdirs then process these. if subdirs: calc_inputs["tleap_dirs"] = {} # for each entry establish dir path and build file tree. for subdir in subdirs: if os.path.isfile(subdir): # add file to input list input_list.append(subdir.split("/")[-1]) frst_dir = subdir.split("/")[0] # Create a folder that is empty. if frst_dir not in calc_inputs["tleap_dirs"].keys(): calc_inputs["tleap_dirs"][frst_dir] = FolderData() # Now fill it with files referenced in the tleap inputfile. # need to make sure to include any nested dirs in the path calc_inputs["tleap_dirs"][frst_dir].put_object_from_file( os.path.join(os.getcwd(), subdir), path="/".join(subdir.split("/")[1:]) # remove the first dir ) # For tests elif "PYTEST_CURRENT_TEST" in os.environ: if os.path.isfile(os.path.join(os.getcwd(), "tests", subdir)): # Create a folder that is empty. if "tests" not in calc_inputs["tleap_dirs"].keys(): calc_inputs["tleap_dirs"]["tests"] = FolderData() # Now fill it with files referenced in the tleap inputfile. calc_inputs["tleap_dirs"]["tests"].put_object_from_file( os.path.join(os.getcwd(), "tests", subdir), path=subdir) else: sys.exit(f"Error: subdir {subdir} referenced in tleap file does not exist") # NOTE: this list is not used at the moment, might use for searchprevious calc_inputs["input_list"] = List(input_list) return calc_inputs
[docs] def add_calculation_outputs(files): """Add outputs from tleap script """ calc_outputs = {} # If we have tleap output files then tag them. if files: output_list = [] # Iterate files to assemble a dict of names and paths. for file in files: if "/" in file: file = file.split("/")[-1] output_list.append(file) calc_outputs["tleap_outfiles"] = List(output_list) return calc_outputs