Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global vars doc #25

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ test -d "venv" || python3 -m venv venv
source venv/bin/activate

# install dependencies / requirements:
MOCKS_REL="0.1.1"
MOCKS_REL="0.2.0"
URL_PFX="https://github.com/imcf/imcf-fiji-mocks/releases/download/v$MOCKS_REL"
pip install --upgrade \
$URL_PFX/imcf_fiji_mocks-0.1.1-py2.py3-none-any.whl \
$URL_PFX/imcf_fiji_mocks-${MOCKS_REL}-py2.py3-none-any.whl \
$URL_PFX/micrometa-15.2.2-py2.py3-none-any.whl \
$URL_PFX/sjlogging-0.5.2-py2.py3-none-any.whl \
olefile \
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ readme = "README.md"
version = "1.5.0.a0"

[tool.poetry.dependencies]
imcf-fiji-mocks = "^0.1.1"
imcf-fiji-mocks = "^0.2.0"
micrometa = "^15.2.2"
python = ">=2.7"
sjlogging = ">=0.5.2"
Expand Down
227 changes: 178 additions & 49 deletions src/imcflibs/imagej/bdv.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@
# The attribute count is not really our choice:
# pylint: disable-msg=too-many-instance-attributes

import sys
import os
import shutil
import sys

from ij import IJ

from .. import pathtools
from ..log import LOG as log

SINGLE = "[Single %s (Select from List)]"
"""@private template string"""
"""Option to use to select only one value for the current dimension"""
MULTIPLE = "[Multiple %ss (Select from List)]"
"""Option to use to select specified multiple values for the current dimension"""
RANGE = "[Range of %ss (Specify by Name)]"
"""Option to use to select a range of values for the current dimension"""


class ProcessingOptions(object):
Expand Down Expand Up @@ -87,8 +91,8 @@ def __init__(self):
self._treat_angles = "[treat individually]"
self._treat_channels = "group"
self._treat_illuminations = "group"
self._treat_tiles = "group"
self._treat_timepoints = "group"
self._treat_tiles = "compare"
self._treat_timepoints = "[treat individually]"

### reference-X methods

Expand Down Expand Up @@ -177,56 +181,111 @@ def reference_timepoint(self, value):

### process-X methods

def process_angle(self, value): # def angle_select(self, value):
def process_angle(self, value, range_end=None): # def angle_select(self, value):
"""Select a single angle to use for processing.

Parameters
----------
value : int or int-like
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int, optional
Contains the end of the range, by default None

"""
self._angle_processing_option = SINGLE % "angle"
self._angle_select = "processing_angle=[angle %s]" % value

def process_channel(self, value): # def channel_select(self, value):
"""Select a single channel to use for processing.
selection = check_processing_input(value, range_end)
processing_option, dimension_select = get_processing_settings(
"angle", selection, value, range_end
)

self._angle_processing_option = processing_option
self._angle_select = dimension_select

def process_channel(
self, value, range_end=None
): # def channel_select(self, value):
"""Select the channel(s) to use for processing.

Parameters
----------
value : int or int-like
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int, optional
Contains the end of the range, by default None

"""
self._channel_processing_option = SINGLE % "channel"
# channel = int(value) - 1
self._channel_select = "processing_channel=[channel %s]" % int(value)

def process_illumination(self, value): # def illumination_select(self, value):
selection = check_processing_input(value, range_end)
processing_option, dimension_select = get_processing_settings(
"channel", selection, value, range_end
)

self._channel_processing_option = processing_option
self._channel_select = dimension_select

def process_illumination(
self, value, range_end=None
): # def illumination_select(self, value):
"""Select a single illumination to use for processing.

Parameters
----------
value : int or int-like
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int, optional
Contains the end of the range, by default None

"""
self._illumination_processing_option = SINGLE % "illumination"
self._illumination_select = "processing_illumination=[illumination %s]" % value

def process_tile(self, value): # def tile_select(self, value):
selection = check_processing_input(value, range_end)
processing_option, dimension_select = get_processing_settings(
"illumination", selection, value, range_end
)

self._illumination_processing_option = processing_option
self._illumination_select = dimension_select

def process_tile(self, value, range_end=None): # def tile_select(self, value):
"""Select a single tile to use for processing.

Parameters
----------
value : int or int-like
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int, optional
Contains the end of the range, by default None

"""
self._tile_processing_option = SINGLE % "tile"
self._tile_select = "processing_tile=[tile %s]" % value

def process_timepoint(self, value): # def timepoint_select(self, value):
selection = check_processing_input(value, range_end)
processing_option, dimension_select = get_processing_settings(
"tile", selection, value, range_end
)

self._tile_processing_option = processing_option
self._tile_select = dimension_select

def process_timepoint(
self, value, range_end=None
): # def timepoint_select(self, value):
"""Select a single timepoint to use for processing.

Parameters
----------
value : int or int-like
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int, optional
Contains the end of the range, by default None

"""
self._timepoint_processing_option = SINGLE % "timepoint"
self._timepoint_select = "processing_timepoint=[timepoint %s]" % value

selection = check_processing_input(value, range_end)
processing_option, dimension_select = get_processing_settings(
"timepoint", selection, value, range_end
)

self._timepoint_processing_option = processing_option
self._timepoint_select = dimension_select

### treat-X methods

Expand Down Expand Up @@ -278,7 +337,7 @@ def treat_illuminations(self, value):
def treat_tiles(self, value):
"""Set the value for the `how_to_treat_tiles` option.

The default setting is `group`.
The default setting is `compare`.

Parameters
----------
Expand All @@ -291,7 +350,7 @@ def treat_tiles(self, value):
def treat_timepoints(self, value):
"""Set the value for the `how_to_treat_timepoints` option.

The default setting is `group`.
The default setting is `[treat individually]`.

Parameters
----------
Expand Down Expand Up @@ -394,8 +453,13 @@ def fmt_use_acitt(self):


SINGLE_FILE = "[NO (one %s)]"
"""Option to use if the current dimension is singular (like only one angle)."""
MULTI_SINGLE_FILE = "[YES (all %ss in one file)]"
"""Option to use if the current dimension is plural (like multiple angles)
contained in a single file."""
MULTI_MULTI_FILE = "[YES (one file per %s)]"
"""Option to use if the current dimension is plural (like multiple angles)
contained in multiple files."""


class DefinitionOptions(object):
Expand All @@ -421,7 +485,7 @@ class DefinitionOptions(object):
def __init__(self):
self._angle_definition = SINGLE_FILE % "angle"
self._channel_definition = MULTI_SINGLE_FILE % "channel"
self._illumination_definition = SINGLE_FILE % "illumination"
self._illumination_definition = SINGLE_FILE % "illumination direction"
self._tile_definition = MULTI_MULTI_FILE % "tile"
self._timepoint_definition = SINGLE_FILE % "time-point"

Expand Down Expand Up @@ -535,6 +599,86 @@ def fmt_acitt_options(self):
return parameter_string + " "


def check_processing_input(value, range_end):
"""Sanitize and clarifies the acitt input selection
Parameters
----------
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int or None
Contains the end of the range if need be
Returns
-------
str
Returns the type of selection: single, multiple or range
"""
if type(value) is not list:
value = [value]
# Check if all the elements of the value list are of the same type
if not all(isinstance(x, type(value[0])) for x in value):
raise TypeError("Invalid input type. All the values should be of the same type")
if type(range_end) is int:
if type(value[0]) is not int:
raise TypeError("Invalid input type. Expected an int for the range start")
elif len(value) != 1:
raise ValueError(
"Invalid input type. Expected a single number for the range start"
)
else:
return "range"
elif len(value) == 1:
return "single"
else:
return "multiple"


def get_processing_settings(dimension, selection, value, range_end):
"""Get the processing option and dimension selection string that corresponds
to the selected processing mode

Parameters
----------
dimension : str
"angle", "channel", "illumination", "tile" or "timepoint"
selection : str
"single", "multiple", or "range"
value : str, int, list of int or list of str
Contains the list of input dimensions, the first input dimension of a range or a single channel
range_end : int or None
Contains the end of the range if need be

Returns
-------
list of str
processing options string, dimension selection string
"""

if selection == "single":
processing_option = SINGLE % dimension
dimension_select = "processing_" + dimension + "=[" + dimension + " %s]" % value

if selection == "multiple":
processing_option = MULTIPLE % dimension
dimension_list = ""
for dimension_name in value:
dimension_list += dimension + "_%s " % dimension_name
dimension_select = dimension_list.rstrip()

if selection == "range":
processing_option = RANGE % dimension
dimension_select = (
"process_following_"
+ dimension
+ "s=%s-%s"
% (
value,
range_end,
)
)

return processing_option, dimension_select


def backup_xml_files(source_directory, subfolder_name):
"""Create a backup of BDV-XML files inside a subfolder of `xml-backup`.

Expand Down Expand Up @@ -613,30 +757,15 @@ def define_dataset_auto(
if not dataset_save_path:
dataset_save_path = pathtools.join2(result_folder, project_filename)
if subsampling_factors:
subsampling_factors = "subsampling_factors=" + subsampling_factors + " "
else:
subsampling_factors = (
"manual_mipmap_setup "
"subsampling_factors=[{ "
"{1,1,1}, "
"{2,2,1}, "
"{4,4,1}, "
"{8,8,2}, "
"{16,16,4} "
"}] "
"manual_mipmap_setup subsampling_factors=" + subsampling_factors + " "
)
else:
subsampling_factors = ""
if hdf5_chunk_sizes:
hdf5_chunk_sizes = "hdf5_chunk_sizes=" + hdf5_chunk_sizes + " "
else:
hdf5_chunk_sizes = (
"hdf5_chunk_sizes=[{ "
"{32,32,4}, "
"{32,16,8}, "
"{16,16,16}, "
"{32,16,8}, "
"{32,32,4} "
"}] "
)
hdf5_chunk_sizes = ""

if bf_series_type == "Angles":
angle_rotation = "apply_angle_rotation "
Expand All @@ -661,7 +790,7 @@ def define_dataset_auto(
+ resave
+ "] "
+ "dataset_save_path=["
+ result_folder
+ dataset_save_path
+ "] "
+ "check_stack_sizes "
+ angle_rotation
Expand Down
3 changes: 1 addition & 2 deletions src/imcflibs/imagej/bioformats.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

from ij import IJ

from ._loci import ImporterOptions
from ._loci import BF, ImageReader, Memoizer
from ._loci import BF, ImageReader, ImporterOptions, DynamicMetadataOptions, Memoizer, ZeissCZIReader

from ..pathtools import gen_name_from_orig
from ..log import LOG as log
Expand Down
6 changes: 4 additions & 2 deletions src/imcflibs/imagej/labelimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ def relate_label_images(label_image_ref, label_image_to_relate):

❗ NOTE: Won't work with touching labels ❗

FIXME: explain with an example what the function is doing!
Given two label images, this function will create a new label image
with the same labels as the reference image, but with the objects
of the second image.

Parameters
----------
Expand All @@ -90,7 +92,7 @@ def relate_label_images(label_image_ref, label_image_to_relate):
Prefs.blackBackground = True
IJ.run(imp_dup, "Convert to Mask", "")
IJ.run(imp_dup, "Divide...", "value=255")
return ImageCalculator.run(label_image_ref, imp_dup, "Multimage_processorly create")
return ImageCalculator.run(label_image_ref, imp_dup, "Multiply create")


def filter_objects(label_image, table, string, min_val, max_val):
Expand Down
Loading
Loading