Skip to content

Commit

Permalink
Add option to include backproject offset in file name.
Browse files Browse the repository at this point in the history
  • Loading branch information
We-Gold committed Aug 8, 2024
1 parent 28e16b3 commit 02b0ad0
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 9 deletions.
1 change: 1 addition & 0 deletions documentation/docs/guide/backproject.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ The offset of the minimum bounding box is stored in the output tiff's descriptio
- `Output Single File` - Whether to output one tiff stack file or a folder of files.
- `Output Min Bounding Box` - Save only the minimum volume needed to contain the backprojected slices. The offset will be stored in the `-configuration.json` file under `backprojection_offset`. This value is the (x_min, y_min, z_min).
- `Binary Backprojection` - Whether or not to binarize all the values of the backprojection. Enable this to backproject a segmentation.
- `Offset in Filename` - Whether or not to include the (x_min, y_min, z_min) offset for min bounding box in the output file name. Only applies if `Output Min Bounding Box` is true.
- `Max RAM (GB)` - 0 indicates no RAM limit. Setting a RAM limit allows Ouroboros to optimize performance and avoid overusing RAM.

### How Does Backprojection Work?
Expand Down
12 changes: 9 additions & 3 deletions python/ouroboros/common/file_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ def load_options_for_backproject_docker(
Returns
-------
tuple[BackprojectOptions, str, str, str | None] | str
tuple[BackprojectOptions, str, str, str | None, str] | str
The options for backprojecting the volume, the host path to the output file, the host path to the config file,
and the host path to the slices folder if the output is not a single file.
the host path to the slices folder if the output is not a single file, and the host output folder.
"""

# Copy the file to the docker volume
Expand Down Expand Up @@ -111,7 +111,13 @@ def load_options_for_backproject_docker(
# Modify the output file folder to be in the docker volume
options.output_file_folder = get_volume_path()

return options, host_output_file, host_output_config_file, host_output_slices
return (
options,
host_output_file,
host_output_config_file,
host_output_slices,
host_output_folder,
)


def save_output_for_backproject_docker(
Expand Down
22 changes: 20 additions & 2 deletions python/ouroboros/common/server_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ouroboros.common.logging import logger
from ouroboros.common.pipelines import backproject_pipeline, slice_pipeline
from ouroboros.common.server_types import BackProjectTask, SliceTask, Task
from ouroboros.helpers.files import combine_unknown_folder


def handle_slice_core(task: SliceTask, slice_options):
Expand Down Expand Up @@ -82,7 +83,7 @@ def handle_backproject_core(task: BackProjectTask, options):

task.status = "started"

_, error = pipeline.process(input_data)
output, error = pipeline.process(input_data)

if error:
return error
Expand All @@ -91,6 +92,8 @@ def handle_backproject_core(task: BackProjectTask, options):
logger.info("Backproject Pipeline Statistics:")
logger.info(pipeline.get_step_statistics())

return output


def handle_backproject(task: BackProjectTask):
options = load_options_for_backproject(task.options)
Expand All @@ -111,14 +114,29 @@ def handle_backproject_docker(task: BackProjectTask):
task.status = "error"
return

options, host_output_file, host_output_config_file, host_output_slices = load_result
(
options,
host_output_file,
host_output_config_file,
host_output_slices,
host_output_folder,
) = load_result

backproject_result = handle_backproject_core(task, options)

if isinstance(backproject_result, str):
task.error = backproject_result
task.status = "error"
return
else:
if options.make_single_file:
host_output_file = combine_unknown_folder(
host_output_folder, backproject_result.output_file_path
)
else:
host_output_slices = combine_unknown_folder(
host_output_folder, backproject_result.output_file_path
)

save_result = save_output_for_backproject_docker(
host_output_file, host_output_config_file, host_output_slices=host_output_slices
Expand Down
14 changes: 12 additions & 2 deletions python/ouroboros/helpers/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,21 @@ def format_slice_output_config_file(output_name: str):
return output_name + "-configuration.json"


def format_backproject_output_file(output_name: str):
def format_backproject_output_file(output_name: str, offset: tuple[int] | None = None):
if offset is not None:
offset_str = "-".join(map(str, offset))
return output_name + f"-backprojected-{offset_str}.tif"

return output_name + "-backprojected.tif"


def format_backproject_output_multiple(output_name: str):
def format_backproject_output_multiple(
output_name: str, offset: tuple[int] | None = None
):
if offset is not None:
offset_str = "-".join(map(str, offset))
return output_name + f"-backprojected-{offset_str}"

return output_name + "-backprojected"


Expand Down
1 change: 1 addition & 0 deletions python/ouroboros/helpers/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class BackprojectOptions(CommonOptions):
"zlib" # Compression type for the backprojected file
)
upsample_order: int = 2 # Order of the interpolation for upsampling
offset_in_name: bool = True # Whether to include the offset in the output file name


DEFAULT_SLICE_OPTIONS = SliceOptions(
Expand Down
18 changes: 16 additions & 2 deletions python/ouroboros/pipeline/backproject_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def _process(self, input_data: any) -> tuple[any, None] | tuple[None, any]:
if not isinstance(slice_rects, np.ndarray):
return "Input data must contain an array of slice rects."

straightened_volume_path = input_tiff_path
straightened_volume_path = config.straightened_volume_path

# Make sure the straightened volume exists
if not os.path.exists(straightened_volume_path):
Expand Down Expand Up @@ -193,15 +193,29 @@ def _process(self, input_data: any) -> tuple[any, None] | tuple[None, any]:
pipeline_input.backprojection_offset = f"{min_bounding_box.x_min},{min_bounding_box.y_min},{min_bounding_box.z_min}"

# Save the backprojected volume to a series of tif files
offset = (
None
if not config.backproject_min_bounding_box or not config.offset_in_name
else (
min_bounding_box.x_min,
min_bounding_box.y_min,
min_bounding_box.z_min,
)
)
folder_path = join_path(
config.output_file_folder,
format_backproject_output_multiple(config.output_file_name),
format_backproject_output_multiple(config.output_file_name, offset=offset),
)
if os.path.exists(folder_path):
shutil.rmtree(folder_path)

os.makedirs(folder_path, exist_ok=True)

# Set the output file name to match the folder path
pipeline_input.output_file_path = format_backproject_output_multiple(
config.output_file_name, offset=offset
) + (".tif" if config.make_single_file else "")

dtype = volume_cache.get_volume_dtype()
volume_shape = volume_cache.get_volume_shape()

Expand Down
10 changes: 10 additions & 0 deletions python/test/helpers/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,21 @@ def test_format_slice_output_config_file():
def test_format_backproject_output_file():
result = format_backproject_output_file("test")
assert isinstance(result, str)
assert result == "test-backprojected.tif"

result = format_backproject_output_file("test", offset=(1, 2, 3))
assert isinstance(result, str)
assert result == "test-backprojected-1-2-3.tif"


def test_format_backproject_output_multiple():
result = format_backproject_output_multiple("test")
assert isinstance(result, str)
assert result == "test-backprojected"

result = format_backproject_output_multiple("test", offset=(1, 2, 3))
assert isinstance(result, str)
assert result == "test-backprojected-1-2-3"


def test_format_backproject_tempvolumes():
Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/interfaces/options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export class BackprojectOptionsFile extends CompoundEntry {
new Entry('make_single_file', 'Output Single File', false, 'boolean'),
new Entry('backproject_min_bounding_box', 'Output Min Bounding Box', true, 'boolean'),
new Entry('make_backprojection_binary', 'Binary Backprojection', false, 'boolean'),
new Entry('offset_in_name', 'Offset in Filename', true, 'boolean'),
new Entry('flush_cache', 'Flush CloudVolume Cache', false, 'boolean').withHidden(),
new Entry('max_ram_gb', 'Max RAM (GB) (0 = no limit)', 0, 'number')
])
Expand Down

0 comments on commit 02b0ad0

Please sign in to comment.