Skip to content

Commit e86c1c5

Browse files
committed
Add file attachment support
1 parent 5c679df commit e86c1c5

3 files changed

Lines changed: 54 additions & 13 deletions

File tree

biomero/constants.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
IMAGE_EXPORT_SCRIPT = "_SLURM_Image_Transfer.py"
1818
IMAGE_IMPORT_SCRIPT = "SLURM_Get_Results.py"
1919
CONVERSION_SCRIPT = "SLURM_Remote_Conversion.py"
20+
FILE_TRANSFER_SCRIPT = "_SLURM_File_Transfer.py"
2021
RUN_WF_SCRIPT = "SLURM_Run_Workflow.py"
2122
RUN_WF_BATCHED_SCRIPT = "SLURM_Run_Workflow_Batched.py"
2223

@@ -150,9 +151,17 @@ class transfer:
150151
OME_ZARR_VERSION_1_0 = '1.0'
151152
FOLDER = "Folder_Name"
152153
FOLDER_DEFAULT = 'SLURM_IMAGES_'
153-
154154

155-
class workflow_status:
155+
156+
class file_transfer:
157+
# ------------------------------------------------------------
158+
# _SLURM_File_Transfer script constants
159+
# ------------------------------------------------------------
160+
FILE_ANNOTATION_ID = "Annotation_ID"
161+
PARAM_NAME = "Param_Name"
162+
FOLDER = "Folder_Name"
163+
164+
156165
INITIALIZING = "INITIALIZING"
157166
TRANSFERRING = "TRANSFERRING"
158167
CONVERTING = "CONVERTING"

biomero/schema_parsers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def adapt_to_biomero_schema(
110110
"default-value": raw_default, # Alias
111111
"optional": input_param.get("optional", False),
112112
"set-by-server": input_param.get("set-by-server", False),
113+
"file-attachment": False, # BIAFLOWS has no optional file-attachment inputs
113114
"value-choices": input_param.get("value-choices"),
114115
}
115116

@@ -281,6 +282,11 @@ def _map_bilayers(self, param, is_output=False):
281282
raw_type in ("image", "file", "array", "measurement", "executable") and not is_output
282283
) or param.get("output_dir_set", False),
283284
"output-dir-set": param.get("output_dir_set", False) or False,
285+
# file-attachment: user supplies an OMERO annotation ID; biomero transfers the file to HPC
286+
"file-attachment": (
287+
raw_type in ("file", "array", "measurement", "executable")
288+
and not is_output
289+
),
284290
"mode": param.get("mode"),
285291
}
286292

biomero/slurm_client.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,20 @@ def workflow_params_to_subs(self, params) -> Dict[str, str]:
15261526

15271527
_FOLDER_INPUT_TYPES = ('image', 'file', 'array', 'measurement', 'executable')
15281528

1529+
# Folder-type inputs that the user can supply as OMERO file-annotation IDs
1530+
# (i.e. not images — those are handled by Image_Transfer).
1531+
_FILE_ATTACHMENT_TYPES = ('file', 'array', 'measurement', 'executable')
1532+
1533+
def get_file_attachment_params(self, workflow: str) -> Dict[str, Dict[str, Any]]:
1534+
"""Return only the file-attachment params for a workflow.
1535+
1536+
Thin filter over :meth:`get_workflow_parameters`.
1537+
"""
1538+
return {
1539+
k: v for k, v in self.get_workflow_parameters(workflow).items()
1540+
if v.get('file_attachment')
1541+
}
1542+
15291543
def _is_bilayers_workflow(self, descriptor: Dict) -> bool:
15301544
"""Return True if descriptor originated from a bilayers config."""
15311545
return descriptor.get('schema-version', '').startswith('bilayers')
@@ -1659,17 +1673,23 @@ def update_slurm_scripts(self,
16591673
logger.info("Generating Slurm job scripts")
16601674
for wf, job_path in self.slurm_model_jobs.items():
16611675
# generate job script
1662-
params = self.get_workflow_parameters(wf)
1676+
# All params in one call; file-attachment ones get type→'string'
1677+
# so the job script uses $VAR placeholders, not typed defaults.
1678+
all_params = self.get_workflow_parameters(wf)
1679+
merged_params = {
1680+
k: ({**v, 'type': 'string'} if v['file_attachment'] else v)
1681+
for k, v in all_params.items()
1682+
}
16631683
descriptor = self.generic_descriptor_from_github(wf)
16641684
if self._is_bilayers_workflow(descriptor):
16651685
template = "job_template_bilayers.sh"
16661686
folder_subs = self.workflow_bilayers_folder_params_to_subs(
16671687
descriptor)
1668-
subs = {**self.workflow_params_to_subs(params),
1688+
subs = {**self.workflow_params_to_subs(merged_params),
16691689
**folder_subs}
16701690
else:
16711691
template = "job_template.sh"
1672-
subs = self.workflow_params_to_subs(params)
1692+
subs = self.workflow_params_to_subs(merged_params)
16731693
job_script = self.generate_slurm_job_for_workflow(
16741694
wf, subs, template)
16751695
# ensure all dirs exist remotely
@@ -2168,15 +2188,21 @@ def get_workflow_parameters(self,
21682188
# filter cytomine parameters
21692189
id_name = param.get('id')
21702190
if not id_name.startswith('cytomine'):
2171-
# skip folder params managed by biomero (bilayers image/file inputs)
2172-
if param.get('set-by-server'):
2191+
# skip folder params managed by biomero (bilayers image inputs, output dirs)
2192+
# but keep file-attachment params — they need CLI flags AND OMERO UI input
2193+
if param.get('set-by-server') and not param.get('file-attachment'):
21732194
continue
2174-
workflow_param = {'name': id_name,
2175-
'default': param.get('default-value'),
2176-
'type': param['type'],
2177-
'optional': param['optional'],
2178-
'cmd_flag': param.get('command-line-flag').replace("@id", id_name),
2179-
'description': param['description']}
2195+
raw_flag = param.get('command-line-flag') or f'--{id_name}'
2196+
workflow_param = {
2197+
'name': id_name,
2198+
'default': param.get('default-value'),
2199+
'type': param['type'],
2200+
'optional': param['optional'],
2201+
'cmd_flag': raw_flag.replace("@id", id_name),
2202+
'description': param['description'],
2203+
'file_attachment': bool(param.get('file-attachment')),
2204+
'format': param.get('format') or [],
2205+
}
21802206
params_dict[id_name] = workflow_param
21812207
return params_dict
21822208

0 commit comments

Comments
 (0)