Source code for httomo_backends.scripts.json_pipelines_generator
#!/usr/bin/env python3importimportlibimportinspectimportyamlfromtypingimportDict,Anyimportos"""This script provides a function `json_pipeline_generator` to generate JSON objects containing method and module names out of directive YAML files.to generate JSON for single directive yaml file : from generate_pipeline_json import process_all_yaml_filesresult = json_pipeline_generator(<address to yaml_file>)to generate a JSON for all directive yaml files in the pipelines_full directory :from generate_pipeline_json import process_all_yaml_filesresult = process_all_yaml_files()"""# Directory containing YAML files relative to this scriptPIPELINES_DIR=os.path.join(os.path.dirname(os.path.abspath(__file__)),"..","pipelines_full")ignored_methods=["calculate_stats"]
[docs]defget_yaml_path(yaml_filename:str)->str:""" Get the full path to a YAML file in the pipelines_full directory. Args: yaml_filename: Name of the YAML file (e.g., "example.yaml") Returns: Full path to the YAML file """returnos.path.join(PIPELINES_DIR,yaml_filename)
[docs]defimport_module_safely(module_name:str):""" Safely import a module handling potential import errors Args: module_name: The name of the module to import Returns: The imported module or None if import fails """try:returnimportlib.import_module(module_name)exceptImportErrorase:missing_module=str(e).split("'")[1]if"'"instr(e)elsestr(e)print(f"Warning: Could not import dependency '{missing_module}' for module '{module_name}'")print(f"You may need to install it using: pip install {missing_module}")returnNoneexceptExceptionase:print(f"Warning: Error importing module '{module_name}': {str(e)}")returnNone
[docs]definspect_method_parameters(module_name:str,method_name:str)->Dict[str,Any]:""" Inspect a method's parameters from a given module Args: module_name: The full path to the module method_name: Name of the method to inspect Returns: Dictionary of parameter names and their default values """# Import the module safelymodule=import_module_safely(module_name)ifmoduleisNone:# Return empty parameters if module import failedreturn{}try:# Get the methodmethod=getattr(module,method_name)# Get method signaturesignature=inspect.signature(method)# Create parameters dictionaryparameters={}# List of parameters to skipskip_params=["in_file","data_in","tomo","arr","prj","data","ncore","nchunk","flats","flat","dark","darks","theta","out","ang","comm_rank","out_dir","angles","gpu_id","comm","offset","shift_xy","step_xy","jpeg_quality","watermark_vals"]# Process parametersforparam_name,paraminsignature.parameters.items():ifparam_namenotinskip_params:ifparam_namein["proj1","proj2","axis"]:parameters[param_name]="auto"elifparam_name=="asynchronous":parameters[param_name]=Trueelifparam_name=="center":parameters[param_name]="${centering.side_outputs.centre_of_rotation}"elifparam_name=="glob_stats":parameters[param_name]="${statistics.side_outputs.glob_stats}"elifparam_name=="overlap":parameters[param_name]="${centering.side_outputs.overlap}"else:# Get default value if it exists, otherwise mark as REQUIREDdefault=param.defaultifparam.default!=inspect.Parameter.emptyelse"REQUIRED"parameters[param_name]=defaultreturnparametersexceptExceptionase:print(f"Warning: Error inspecting method '{method_name}' in module '{module_name}': {str(e)}")return{}
[docs]defjson_pipeline_generator(input_yaml:str)->Dict[str,Any]:""" Generate JSON pipeline from YAML directive Args: input_yaml: Path to input YAML directive file Returns: Dictionary with methods information if successful, or empty dictionary if error occurred """try:# Read input YAMLwithopen(input_yaml,'r')asfile:pipeline=yaml.safe_load(file)# Dictionary to store methods informationmethods_info={}# Process each method in pipelineforiteminpipeline:method_name=item['method']module_path=item['module_path']# Skip ignored methodsifmethod_namenotinignored_methods:print(f"Processing method: {method_name} from module: {module_path}")# Get method parametersparameters=inspect_method_parameters(module_path,method_name)# Add to methods info even if parameters are emptymethods_info[method_name]={'module_path':module_path,'parameters':parameters}returnmethods_infoexceptExceptionase:print(f"Error occurred: {str(e)}")return{}
importjsonimportos# Path to the priority configuration filePRIORITY_FILE=os.path.join(PIPELINES_DIR,"pipeline_priority.json")
[docs]defload_priority_order()->list:""" Load the pipeline priority order from the JSON configuration file in the pipelines_full directory. Returns: List of pipeline titles in priority order. """try:withopen(PRIORITY_FILE,'r')asfile:config=json.load(file)returnconfig.get("pipeline_order",[])exceptFileNotFoundError:print(f"Warning: Priority file '{PRIORITY_FILE}' not found. Using default order.")return[]exceptExceptionase:print(f"Warning: Could not load priority file '{PRIORITY_FILE}'. Using default order. Error: {str(e)}")return[]
[docs]defprocess_all_yaml_files()->Dict[str,Any]:""" Process all YAML files in the pipelines_full directory in the order of priority. Returns: Dictionary where keys are YAML file names and values are the JSON outputs from the json_pipeline_generator function. """# Load the priority orderpriority_order=load_priority_order()# Dictionary to store resultsresults={}# List all YAML files in the pipelines_full directoryyaml_files=[fforfinos.listdir(PIPELINES_DIR)iff.endswith(".yaml")orf.endswith(".yml")]# Exclude the priority file from processingyaml_files=[fforfinyaml_filesiff!="pipeline_priority.yaml"]# Sort YAML files based on priority orderifpriority_order:# Remove the "_directive.yaml" suffix for matchingyaml_files.sort(key=lambdax:priority_order.index(x.removesuffix("_directive.yaml"))ifx.removesuffix("_directive.yaml")inpriority_orderelselen(priority_order))# Process the YAML files in the sorted orderforyaml_fileinyaml_files:# Get the full path to the YAML fileyaml_path=get_yaml_path(yaml_file)# Process the YAML filejson_output=json_pipeline_generator(yaml_path)# Add to results (remove the "_directive.yaml" suffix for the key)results[yaml_file.removesuffix("_directive.yaml")]=json_outputreturnresults