|
30 | 30 |
|
31 | 31 | import os |
32 | 32 | import logging |
| 33 | +import glob |
| 34 | +import math |
33 | 35 |
|
34 | | -from pycbc.workflow.core import FileList, make_analysis_dir |
| 36 | +from pycbc.workflow.core import FileList, make_analysis_dir, File |
35 | 37 | from pycbc.workflow.jobsetup import (PycbcSplitBankExecutable, |
36 | 38 | PycbcSplitBankXmlExecutable, PycbcSplitInspinjExecutable, |
37 | 39 | PycbcHDFSplitInjExecutable) |
38 | 40 |
|
| 41 | +from urllib.parse import urljoin |
| 42 | +from urllib.request import pathname2url |
| 43 | + |
39 | 44 | logger = logging.getLogger('pycbc.workflow.splittable') |
40 | 45 |
|
41 | 46 | def select_splitfilejob_instance(curr_exe): |
@@ -109,18 +114,59 @@ def setup_splittable_workflow(workflow, input_tables, out_dir=None, tags=None): |
109 | 114 | logger.info("Adding split output file jobs to workflow.") |
110 | 115 | split_table_outs = setup_splittable_dax_generated(workflow, |
111 | 116 | input_tables, out_dir, tags) |
| 117 | + elif splitMethod == "MANUAL_DIRECTORY": |
| 118 | + logger.info("Registering pre-existing split files from directory.") |
| 119 | + split_table_outs = setup_splittable_manual_directory(workflow, tags) |
112 | 120 | elif splitMethod == "NOOP": |
113 | 121 | # Probably better not to call the module at all, but this option will |
114 | 122 | # return the input file list. |
115 | 123 | split_table_outs = input_tables |
116 | 124 | else: |
117 | 125 | errMsg = "Splittable method not recognized. Must be one of " |
118 | | - errMsg += "IN_WORKFLOW or NOOP." |
| 126 | + errMsg += "IN_WORKFLOW, MANUAL_DIRECTORY or NOOP." |
119 | 127 | raise ValueError(errMsg) |
120 | 128 |
|
121 | 129 | logger.info("Leaving split output files module.") |
122 | 130 | return split_table_outs |
123 | 131 |
|
| 132 | +def setup_splittable_manual_directory(workflow, tags=None): |
| 133 | + """ |
| 134 | + New function to glob a directory and register existing files as |
| 135 | + workflow products. |
| 136 | + """ |
| 137 | + if tags is None: |
| 138 | + tags = [] |
| 139 | + cp = workflow.cp |
| 140 | + |
| 141 | + # Get directory from config |
| 142 | + bank_dir = cp.get_opt_tags("workflow-splittable", "tmpltbank-directory", tags) |
| 143 | + |
| 144 | + # Glob all HDF files |
| 145 | + bank_paths = sorted(glob.glob(os.path.join(bank_dir, '*.hdf'))) |
| 146 | + if not bank_paths: |
| 147 | + raise ValueError(f"No .hdf files found in {bank_dir}") |
| 148 | + |
| 149 | + n_dp = math.ceil(math.log10(max(len(bank_paths), 2))) |
| 150 | + tmplt_banks = FileList([]) |
| 151 | + |
| 152 | + for i, path in enumerate(bank_paths): |
| 153 | + bank_tag = ('bank%0{}d'.format(n_dp)) % i |
| 154 | + abs_path = os.path.abspath(path) |
| 155 | + pfn_local = urljoin('file:', pathname2url(abs_path)) |
| 156 | + |
| 157 | + # Create a File object that Pegasus recognizes as an existing input |
| 158 | + curr_file = File( |
| 159 | + workflow.ifos, |
| 160 | + 'TMPLTBANK', |
| 161 | + workflow.analysis_time, |
| 162 | + file_url=pfn_local, |
| 163 | + tags=tags + [bank_tag] |
| 164 | + ) |
| 165 | + curr_file.add_pfn(pfn_local, site='local') |
| 166 | + tmplt_banks.append(curr_file) |
| 167 | + |
| 168 | + return tmplt_banks |
| 169 | + |
124 | 170 | def setup_splittable_dax_generated(workflow, input_tables, out_dir, tags): |
125 | 171 | ''' |
126 | 172 | Function for setting up the splitting jobs as part of the workflow. |
@@ -178,4 +224,3 @@ def setup_splittable_dax_generated(workflow, input_tables, out_dir, tags): |
178 | 224 | workflow.add_node(node) |
179 | 225 | out_file_groups += node.output_files |
180 | 226 | return out_file_groups |
181 | | - |
|
0 commit comments