diff --git a/docs/source/howto/run_httomo.rst b/docs/source/howto/run_httomo.rst index 4f09712f4..f47305860 100644 --- a/docs/source/howto/run_httomo.rst +++ b/docs/source/howto/run_httomo.rst @@ -235,7 +235,7 @@ directory created by HTTomo would be Options/flags ############# -The :code:`run` command has 17 options/flags: +The :code:`run` command has 18 options/flags: - :code:`--output-folder-name` - :code:`--save-all` @@ -254,6 +254,7 @@ The :code:`run` command has 17 options/flags: - :code:`--recon-filename-stem` - :code:`--pipeline-format` - :code:`--mpi-abort-hook` +- :code:`--continuous-scan-subset` :code:`--output-folder-name` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -542,6 +543,28 @@ before the MPI abort mechanism begins to terminate the python processes. Thus, t terminal when MPI abort is invoked may only contain partial information about the exception that triggered the MPI abort. +:code:`--continuous-scan-subset` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is an alternative to the :code:`continuous_scan_subset` loader parameter, see +:ref:`continuous_scan_subset_selection` for more details. + +This flag takes two values, the first one being the start index and the second one being the +stop index. For example, an equivalent of the following config: + +.. literalinclude:: ../../../tests/samples/pipeline_template_examples/testing/loader_with_offset_param.yaml + :language: yaml + :emphasize-lines: 7-9 + +can be achieved with the flag via :code:`--continuous-scan-subset 90 180` + +.. note:: This flag overrides the :code:`continuous_scan_subset` parameter in the YAML + config. Meaning, if the :code:`continuous_scan_subset` parameter is present in the loader's + config in the YAML pipeline but the :code:`--continuous-scan-subset` flag is used, then the + values given in the YAML config are ignored and the values given to the flag take + precedence. If this occurs, it will be logged to the :code:`debug.log` file that HTTomo + produces. + Developer options +++++++++++++++++ diff --git a/docs/source/reference/loaders.rst b/docs/source/reference/loaders.rst index a8d4d51fa..acdf0d8ec 100644 --- a/docs/source/reference/loaders.rst +++ b/docs/source/reference/loaders.rst @@ -260,6 +260,8 @@ passed along to the first method. The loader has the :code:`preview` parameter for configuring the cropping/previewing. Please see :ref:`previewing` for more details on previewing. +.. _continuous_scan_subset_selection: + Continuous Scan Subset Selection ================================ diff --git a/httomo/cli.py b/httomo/cli.py index 086dcc6f8..c35099ddc 100644 --- a/httomo/cli.py +++ b/httomo/cli.py @@ -206,6 +206,13 @@ def check(pipeline: Union[Path, str], in_data_file: Optional[Path] = None): is_flag=True, help="Enable hook that invokes MPI abort if an unhandled exception is encountered", ) +@click.option( + "--continuous-scan-subset", + nargs=2, + type=click.INT, + default=None, + help="Start and stop indices for selecting subset of projections along angular dimension", +) def run( in_data_file: Path, pipeline: Union[Path, str], @@ -227,6 +234,7 @@ def run( frames_per_chunk: int, recon_filename_stem: Optional[str], mpi_abort_hook: bool, + continuous_scan_subset: Optional[tuple[int, int]], ): """Run a pipeline on input data.""" if mpi_abort_hook: @@ -242,6 +250,7 @@ def run( syslog_port, output_folder_name, recon_filename_stem, + continuous_scan_subset, ) does_contain_sweep = is_sweep_pipeline(pipeline) @@ -329,6 +338,7 @@ def set_global_constants( syslog_port: int, output_folder_name: Optional[Path], recon_filename_stem: Optional[str], + continuous_scan_subset: Optional[tuple[int, int]], ) -> None: if compress_intermediate and frames_per_chunk == 0: # 0 means write contiguously but compression must have chunk @@ -340,6 +350,7 @@ def set_global_constants( httomo.globals.SYSLOG_SERVER = syslog_host httomo.globals.SYSLOG_PORT = syslog_port httomo.globals.RECON_FILENAME_STEM = recon_filename_stem + httomo.globals.CONTINUOUS_SCAN_SUBSET = continuous_scan_subset if output_folder_name is None: httomo.globals.run_out_dir = out_dir.joinpath( diff --git a/httomo/globals.py b/httomo/globals.py index 1110dc63f..47fce4f23 100644 --- a/httomo/globals.py +++ b/httomo/globals.py @@ -16,3 +16,4 @@ SYSLOG_SERVER = "localhost" SYSLOG_PORT = 514 RECON_FILENAME_STEM: Optional[str] = None +CONTINUOUS_SCAN_SUBSET: Optional[tuple[int, int]] = None diff --git a/httomo/ui_layer.py b/httomo/ui_layer.py index c8be4db2b..e2ace8808 100644 --- a/httomo/ui_layer.py +++ b/httomo/ui_layer.py @@ -1,3 +1,4 @@ +import logging import yaml from enum import Enum, auto from typing import Any, Dict, List, Optional, TypeAlias, Union @@ -13,6 +14,7 @@ from httomo.runner.method_wrapper import MethodWrapper from httomo.runner.pipeline import Pipeline +import httomo.globals from httomo.method_wrappers import make_method_wrapper from httomo.loaders import make_loader from httomo.runner.loader import LoaderInterface @@ -20,10 +22,12 @@ from httomo.sweep_runner.param_sweep_json_loader import ParamSweepJsonLoader from httomo.sweep_runner.param_sweep_yaml_loader import get_param_sweep_yaml_loader from httomo.transform_loader_params import ( + ContinuousScanSubsetParam, select_continuous_scan_subset, parse_config, parse_preview, ) +from httomo.utils import log_once from httomo_backends.methods_database.query import MethodDatabaseRepository MethodConfig: TypeAlias = Dict[str, Any] @@ -144,7 +148,28 @@ def _setup_loader(self) -> LoaderInterface: with h5py.File(data_config.in_file, "r") as f: data_shape = f[data_config.data_path].shape preview = parse_preview(parameters.get("preview", None), data_shape) - continuous_scan_subset_config = parameters.get("continuous_scan_subset", None) + continuous_scan_subset_param = parameters.get("continuous_scan_subset", None) + if ( + continuous_scan_subset_param is not None + and httomo.globals.CONTINUOUS_SCAN_SUBSET is not None + ): + warn_str = ( + "continuous_scan_subset parameter exists in loader config with " + f"start={continuous_scan_subset_param["start"]} and " + f"stop={continuous_scan_subset_param["stop"]}, but is overidden by " + "values given to --continuous-scan-subset flag " + f"start={httomo.globals.CONTINUOUS_SCAN_SUBSET[0]} and " + f"stop={httomo.globals.CONTINUOUS_SCAN_SUBSET[1]}" + ) + log_once(warn_str, level=logging.DEBUG) + continuous_scan_subset_config = ( + ContinuousScanSubsetParam( + start=httomo.globals.CONTINUOUS_SCAN_SUBSET[0], + stop=httomo.globals.CONTINUOUS_SCAN_SUBSET[1], + ) + if httomo.globals.CONTINUOUS_SCAN_SUBSET is not None + else continuous_scan_subset_param + ) if continuous_scan_subset_config is not None: preview = select_continuous_scan_subset( preview, continuous_scan_subset_config