示例#1
0
def test_tiff_image_entry_creation(resource, expected_error_message):
    error_message = ""
    image_entry = None

    try:
        tiff_file = load_tiff_file(path=resource)
        image_entry = create_tiff_image_entry(tiff_file=tiff_file)
    except ValidationError as e:
        error_message = e.message

    # Asserts possible file opening failures
    assert error_message == expected_error_message

    # Asserts successful creation data
    if not error_message:
        tiff_file = tiff_lib.TiffFile(str(resource.absolute()))
        tiff_tags = tiff_file.pages[0].tags

        assert image_entry.name == resource.name
        assert image_entry.width == tiff_tags["ImageWidth"].value
        assert image_entry.height == tiff_tags["ImageLength"].value
        assert image_entry.depth == 1
        assert image_entry.resolution_levels == len(tiff_file.pages)
        assert image_entry.color_space == get_color_space(
            str(tiff_tags["PhotometricInterpretation"].value))
示例#2
0
    def __init__(self):
        super().__init__()

        self.s = Q_(1, 's')
        self.us = Q_(1, 'us')

        self.mock = True
        self.temperature_setpoint = -10
        self.cooler_on_state = False
        self.acq_mode = 'Run till abort'
        self.status_state = 'Camera is idle, waiting for instructions.'
        self.image_size = self.detector_shape
        self.preamp_st = 1
        self.EM_gain_st = 1
        self.ftm_state = False
        self.horiz_shift_speed_state = 1
        self.n_preamps = 1

        self.PreAmps = np.around([self.true_preamp(n)
                                  for n in np.arange(self.n_preamps)],
                                 decimals=1)[::-1]
        self.HRRates = [self.true_horiz_shift_speed(n)
                        for n in np.arange(self.n_horiz_shift_speeds())]
        self.vertSpeeds = [np.round(self.true_vert_shift_speed(n), 1)
                           for n in np.arange(self.n_vert_shift_speeds)]
        self.vertAmps = ['+' + str(self.true_vert_amp(n))
                         for n in np.arange(self.n_vert_clock_amps)]
        self.vertAmps[0] = 'Normal'

        with tiff.TiffFile(os.path.join(os.getcwd(), 'tormenta', 'control',
                           'beads.tif')) as ff:
            self.image = ff.asarray()

        self.expTime = 0.1 * self.s
示例#3
0
def _custom_try_except(node, key):
    """
    Parameters
    ----------
    node: quilt.nodes.Node
        The current self node.
    key: str
        The target child node.
    Output
    ----------
    Attempts to open the target by try -> except blocks with default loaders. If all loaders fail, it getattrs the target from current as a safety.
    """

    # this is disgusting and im sorry
    try:
        return json.load(open(getattr(node, key)()))
    except:
        pass

    try:
        return tfle.TiffFile(getattr(node, key)())
    except:
        pass

    return getattr(node, key)()
示例#4
0
文件: tiff.py 项目: fbain79/champ
 def axes(self):
     if not self._axes:
         best_first = 0
         best_second = 0
         for file_path in self._filenames:
             tif_axes = {}
             log.debug("Loading position list from %s" % file_path)
             with tifffile.TiffFile(file_path) as tif_stack:
                 for tif in tif_stack:
                     position_text = tif.micromanager_metadata['PositionName']
                     axis_positions = name_regex.search(position_text)
                     if not axis_positions:
                         print("Unable to determine the position of this field of view: %s" % position_text)
                     else:
                         first = int(axis_positions.group(1))
                         second = int(axis_positions.group(2))
                         best_first = max(first, best_first)
                         best_second = max(second, best_second)
                         tif_axes[position_text] = (first, second)
             if best_second > best_first:
                 # the second thing is the major axis, so we need to invert them
                 tif_axes = {position_text: (second, first) for position_text, (first, second) in tif_axes.items()}
             # no need to invert, just return the values we already have
             self._axes[file_path] = tif_axes
     return self._axes
def raw_parameters(rawFilePath):
    '''Obtain raw image parameters: zSpacing, xResolution and yResolution from TIFF'''

    rawImg = tiff.TiffFile(rawFilePath)
    try:
        zSpacing = rawImg.imagej_metadata['spacing']
    except Exception as e:
        zSpacing = 1

    if rawImg.imagej_metadata['unit'] == 'micron':
        measurementsInMicrons = True

    rawImg = Image.open(rawFilePath)

    if TAGS[282] == 'XResolution':
        xResolution = 1 / rawImg.tag_v2[282]

    if TAGS[283] == 'YResolution':
        yResolution = 1 / rawImg.tag_v2[283]

    if measurementsInMicrons:
        #To nanometers
        zSpacing = zSpacing * 1000
        xResolution = xResolution * 1000
        yResolution = yResolution * 1000

    return zSpacing, xResolution, yResolution
示例#6
0
    def __init__(self, filename, verbose=False):
        super(TifReader, self).__init__(filename, verbose)

        # Save the filename
        self.fileptr = tifffile.TiffFile(filename)
        number_pages = len(self.fileptr.pages)

        # Get shape by loading first frame
        self.isize = self.fileptr.asarray(key=0).shape

        # Check if each page has multiple frames.
        if (len(self.isize) == 3):
            self.frames_per_page = self.isize[0]
            self.image_height = self.isize[1]
            self.image_width = self.isize[2]

        else:
            self.frames_per_page = 1
            self.image_height = self.isize[0]
            self.image_width = self.isize[1]

        if self.verbose:
            print("{0:0d} frames per page, {1:0d} pages".format(
                self.frames_per_page, number_pages))

        self.number_frames = self.frames_per_page * number_pages
        self.page_number = -1
        self.page_data = None
示例#7
0
def extract_tif_meta(fname):
    '''
        Extracts .tif metadata (tags) and additional information embdedded in 'ImageDescription'
        meta = extract_tif_meta(fname)
        INPUTS:
            fname ~ string [path to .tif file]
        OUTPUTS:
            meta ~ dict [contains .tif tags (UPPERCASE keys) and additional information (lowercase keys, if present)
    '''

    with tifffile.TiffFile(fname) as tif:
        meta = {item[0] : item[1].value \
                    for item in tif.pages[0].tags.items()}

    # Expand tags embedded in ImageDescription fields
    # Note: My current solution uses a literal_eval to turn the string into a
    #   Python dictionary. I know that eval() is not good practice and I would not
    #   normally use it, but ast.literal_eval() is at least rigorously limited to
    #   parsing Python datatypes exclusively.
    try:
        tags_extra = ast.literal_eval(meta['ImageDescription'])
        meta.update(tags_extra)
        # Extra metadata appended to original tags
    except:
        pass
        # Exception handling in case 'ImageDescription' field is not formatted as dictionary
    try:
        tags_extra2 = ast.literal_eval(meta['ImageDescription1'])
        meta.update(tags_extra2)
        # Check in case 'ImageDescription1' might have some tags
    except:
        pass

    return meta
示例#8
0
def split_tiff(
    in_path: Path,
    out_dir: Path,
    tile_size: int,
    overlap: int,
    nzplanes: int,
    selected_channels: list,
):
    with tif.TiffFile(in_path) as TF:
        npages = len(TF.pages)

    for z in range(0, nzplanes):
        pages = []
        for c in selected_channels:
            page = c * nzplanes + z
            pages.append(page)
        print("pages", [p + 1 for p in pages], "/", npages)
        this_plane_tiles, this_plane_tile_names, slicer_info = split_plane(
            in_path, pages, z, tile_size, overlap
        )
        task = []
        for i, tile in enumerate(this_plane_tiles):
            out_path = path_to_str(out_dir.joinpath(this_plane_tile_names[i]))
            task.append(
                dask.delayed(tif.imwrite)(out_path, tile, photometric="minisblack")
            )

        dask.compute(*task, scheduler="threads")
    return slicer_info
示例#9
0
def path_is_otf(fpath):
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        with tf.TiffFile(fpath) as tif:
            if (not len(tif.series)) or (tif.series[0].ndim != 2):
                return False
            return array_is_otf(tif.series[0].asarray())
示例#10
0
def read_si_tiffstack(path_name: str, header_only: bool = False) -> tuple:
    """Open a scanimage tiff file

    Reads header data using PIL and tiff image data using scikit-image.

    Todo:
        Using two libraries is inefficient, finding a single solution would be the best.

    Args:
        path_name (str): Path to a tif file
        header_only (bool): flag to parse header only and return no image data
    Returns:
        tuple: Image Data (numpy.ndarray (z,y,x)), header (dict)
    """
    # convert any windows style
    if not isinstance(path_name, Path):
        file_to_open = Path(path_name)
    else:
        file_to_open = path_name
    assert file_to_open.exists(), 'File does not exist!'

    img = tifffile.TiffFile(file_to_open)
    if img.is_bigtiff:
        header = parse_si_header(img.scanimage_metadata['FrameData'])
    else:
        header = parse_si_header(img.scanimage_metadata['Description'])

    if not header_only:
        img_data = img.asarray()
    else:
        img_data = None
    return img_data, header
示例#11
0
def small_Test_residual():
    animal, day = 'IT2', '181115'
    root = "/Volumes/DATA_01/NL/layerproject/"
    root = "/Volumes/DATA_01/NL/layerproject/"
    # TODO: VISUALLY INSPECT A and C.
    ORDER = 'F'
    T = 200
    rawf_name = "baseline_00001.tif"
    hf = h5py.File(
        root +
        "processed/{}/full_{}_{}__data.hdf5".format(animal, animal, day), 'r')
    rawf = os.path.join(root, "raw/{}/{}/{}".format(animal, day, rawf_name))
    rf = tifffile.TiffFile(rawf)

    Y = np.concatenate([p.asarray()[:, :, np.newaxis] for p in rf.pages[:T]],
                       axis=2)  #shape=(256, 256, T)
    B = np.array(hf['base_im']).reshape((-1, 4))  #shape=(65536, 4)
    Yr = Y.reshape((-1, T), order=ORDER)

    data = hf['Nsparse']['data']
    indices = hf['Nsparse']['indices']
    indptr = hf['Nsparse']['indptr']
    Asparse = csc_matrix((data, indices, indptr))  #(N, P)
    #Asparse = csc_matrix(np.array(data), np.array(indices), np.array(indptr))

    A_all = np.sum(Asparse.toarray(), axis=0)

    C = hf['C']
    C_samp = C[:, :T]

    CP = Asparse.T @ C_samp

    R = Yr - CP
示例#12
0
def makeJpg(filename, resize, outputFolder):
    try:
        kelvin = -273.15
        name = ntpath.basename(filename)
        dt = ""
        print("BEFORE")
        with tiff.TiffFile(filename) as tif:

            imgDataAsNumpy = tif.asarray()
            # Obtains the DateTime from the tiff file and stores it in dt
            print(type(tif))
            for page in tif:
                print("AFTER")
                dt = page.tags['datetime'].value
                dt = dt.decode("utf-8")
                #print('Date ', dt)

        # Gets the maximum and minimum values from the image array which is wrong.
        h, w = imgDataAsNumpy.shape

        # Hard code the minimum and maximum values for the color palette
        temp_min = 213.15  # -60 Celsius
        temp_max = np.max(imgDataAsNumpy)

        print('Temperatures ', temp_min + kelvin, temp_max + kelvin)

        imc = Image.new("P", (w, h))
        pco = imc.load()

        # Computes the minimum index for the palette (equivalent to -32 Celsius)
        minTempIdx = int(temptoindex(Celsius2Kelvin(-30.0), temp_max,
                                     temp_min))
        p = creapaleta(minTempIdx)
        imc.putpalette(p)

        # Compute the 'color' index temperature value for the image
        temp = (
            (temp_max - imgDataAsNumpy) * 256) / (temp_max - temp_min + .0001)

        for j in range(h - 1):
            for i in range(w - 1):
                pco[i, j] = int(temp[j, i])

        hazbarra(imc, minTempIdx)
        haztitulo(imc, "GOES16 C13 UTC: " + dt, minTempIdx)

        #    print(os.path.dirname(os.path.realpath(__file__)))
        marco = Image.open(
            os.path.dirname(os.path.realpath(__file__)) + "/marco.png")
        out = imc.convert("RGB")
        out.paste(marco, (0, 0), marco.convert("L"))

        if (resize < 1.0):
            out = out.resize((int(w * resize), int(h * resize)))

        out.save(outputFolder + '/' + name + '.jpg')
    except Exception as e:
        print("ERROR: Received at makeJpg")
        print(e)
        raise
示例#13
0
def read_tiff_voxel_size(file_path):
    """
    Implemented based on information found in https://pypi.org/project/tifffile
    """
    def _xy_voxel_size(tags, key):
        assert key in ['XResolution', 'YResolution']
        if key in tags:
            num_pixels, units = tags[key].value
            return units / num_pixels
        # return default
        return 1.

    with tifffile.TiffFile(file_path) as tiff:
        image_metadata = tiff.imagej_metadata
        if image_metadata is not None:
            z = image_metadata.get('spacing', 1.)
        else:
            # default voxel size
            z = 1.

        tags = tiff.pages[0].tags
        # parse X, Y resolution
        y = _xy_voxel_size(tags, 'YResolution')
        x = _xy_voxel_size(tags, 'XResolution')
        # return voxel size
        return [z, y, x]
示例#14
0
 def loader(opened_file):
     with tifffile.TiffFile(opened_file) as tif:
         fh = tif.filehandle
         for page in tif.pages:
             fh.seek(page.dataoffsets[0])
             fh.read(page.databytecounts[0])
             return
示例#15
0
def dataSize(filename, **args):
    """Returns size of data in tif file
    
    Arguments:
        filename (str): file name as regular expression
        x,y,z (tuple): data range specifications
    
    Returns:
        tuple: data size
    """
    t = tiff.TiffFile(filename)
    d3 = len(t.pages)
    d2 = t.pages[0].shape
    #d2 = (d2[0], d2[1]);
    if len(d2) == 3:
        d2 = (d2[2], d2[1], d2[0])
    else:
        d2 = (d2[1], d2[0])

    if d3 > 1:
        dims = d2 + (d3, )
    else:
        dims = d2

    return io.dataSizeFromDataRange(dims, **args)
示例#16
0
    def _get_filenames(self, xml_path, sync_path):
        super(PrairieHaussIO, self)._get_filenames(xml_path, sync_path)
        if not os.path.exists(self.filetrunk + "{0:04d}.tif".format(1)):
            if not os.path.exists(self.dirname):
                os.makedirs(self.dirname)
            sys.stdout.write("Converting to individual tiffs... ")
            sys.stdout.flush()
            self.mptifs = [tifffile.TiffFile(self.dirname + ".tif")]
            for mptif in self.mptifs:
                for nf, frame in enumerate(mptif.pages):
                    tifffile.imsave(
                        self.filetrunk + "{0:04d}.tif".format(nf + 1),
                        frame.asarray())
            sys.stdout.write("done\n")
        if xml_path is None:
            self.xml_name = self.dirname + ".xml"
        else:
            self.xml_name = xml_path
        # This needs to be done *after* the individual tiffs have been written
        self.filenames = sorted(glob.glob(self.filetrunk + "*.tif"))

        if "?" in self.filetrunk:
            self.ffmpeg_fn = "'" + self.filetrunk + self.format_index(
                "?") + ".tif'"
        else:
            self.ffmpeg_fn = self.filetrunk + self.format_index("%") + ".tif"
示例#17
0
def list_of_frames(img_name):
    """Return the list of frames for an image file.

    Details are as described in the imgimport_intelligent docstring.

    """
    img = tifffile.TiffFile(img_name)
    #img = Image.open(img_name)
    imglist = []

    try:
        for i in range(np.size(img)):
            imdata = img[i].asarray()
            # fix 3-channel TIFF images
            if np.rank(imdata) == 3:
                imdata = imdata[:, :,
                                0] + 256 * imdata[:, :,
                                                  1] + 65536 * imdata[:, :, 2]
            imglist.append(imdata)
    except EOFError:
        pass

    if not imglist:
        raise ImportError, 'No frames detected in file %s' % img_name
    else:
        return imglist
示例#18
0
 def setUp(self):
     Rois2MasksTestMixin.setUp(self)
     os.makedirs(self.tempdir)
     self.filename = os.path.join(self.tempdir, "tmp.tif")
     tifffile.imsave(self.filename, self.data)
     self.data = tifffile.TiffFile(self.filename)
     self.datahandler = extraction.DataHandlerTifffileLazy()
示例#19
0
 def addLSM(self, ch):
     #this should be a LSM file containing ch spectral channels
     # ch=9
     valerr = False
     LSMfile = tkinter.filedialog.askopenfilename(
         title='Select a .LSM file', filetypes=[("LSM files", "*.LSM")])
     if os.path.splitext(LSMfile)[1] == '.lsm':
         ti = tiff.TiffFile(LSMfile)  # read in first file in directory
         self.SpecfileName.append(LSMfile)
         self.order.append(ti.series[0].axes.lower())
         # self.meta.append(ti.lsm_metadata())
         try:
             self.spectralRange.append(
                 np.asarray(ti.lsm_metadata['ChannelColors']
                            ['ColorNames']).astype(float)[:ch])
         except ValueError:
             valerr = True
             ct = 0
             for i in ti.lsm_metadata['ChannelColors']['ColorNames']:
                 try:
                     float(i)
                     ct += 1
                 except:
                     break
             # self.spectralRange.append(np.asarray(ti.lsm_metadata['ChannelColors']['ColorNames'])[:ct].astype(float))
             self.spectralRange.append(
                 np.asarray(ti.lsm_metadata['ChannelColors']['ColorNames'])
                 [:ch].astype(float))
             c = ti.series[0].axes.lower().find('c')
             self.spectralIm.append(
                 np.delete(ti.asarray()[:, :, :ch + 1, :, :], -1, axis=c))
         if valerr == False:
             self.spectralIm.append(ti.asarray()[:, :, :ch, :, :])
示例#20
0
 def _imload(self, filename):
     ext = osp.splitext(filename)[-1]
     if 'tif' in ext:
         image = tifffile.TiffFile(filename).asarray()
     else:
         image = np.array(Image.open(filename))
     return image
示例#21
0
def read_tiffstack(path):
    """ converts a tiff stack (image x y dimensions, individual tiff pages t)
    into a 3d np array, dimensions are (x,y,t)"""

    data = tifffile.TiffFile(path).asarray()
    data = data.swapaxes(0,2) # moves t to last dim. tifffile reads pages as first dim
    return data
示例#22
0
 def __call__(self, point_number):
     import tifffile
     ret = []
     for fn in self._fnames_for_point(point_number):
         with tifffile.TiffFile(fn) as tif:
             ret.append(tif.asarray())
     return np.array(ret).squeeze()
示例#23
0
文件: tiff.py 项目: fbain79/champ
    def __iter__(self):
        first_filename = self._filenames[0]
        with tifffile.TiffFile(first_filename) as tif:
#FLETCHER EDIT
            summary = tif.shape
            height, width = summary[1], summary[2]
            if height % 512 != 0 or width % 512 != 0:
                raise ValueError("CHAMP currently only supports images with sides that are multiples of 512 pixels.")
            # if the images are larger than 512x512, we need to subdivide them
            subrows, subcolumns = range(height / 512), range(width / 512)

            for file_path in self._filenames:
                major_axis_position, minor_axis_position = self.axes[file_path]
                # let the user ignore images in certain columns. This is useful when an experiment is started and
                # only afterwards do we discover that data on the edges isn't useful.
                if self._min_column is not None and major_axis_position < self._min_column:
                    continue
                if self._max_column is not None and major_axis_position > self._max_column:
                    continue
                for subrow in subrows:
                    minor_axis_label = (minor_axis_position * len(subrows)) + subrow
                    for subcolumn in subcolumns:
                        major_axis_label = (major_axis_position * len(subcolumns)) + subcolumn
                        dataset_name = '(Major, minor) = ({}, {})'.format(major_axis_label, minor_axis_label)
#FLETCHER EDIT
            return dataset_name
示例#24
0
def GetThumb(args):
    filepath = args[0]
    try:
        md5val = md5file(filepath)
        cachefolder = GetCachefolder()
        thumbpath = '%s/%s.jpg' % (cachefolder, md5val)

        # create thumb
        if not os.path.exists(thumbpath):
            img = tiff.imread(filepath, key=0)
            # img = cv2.resize(img, (512, 512))
            img = transform.resize(img,(512,512))
            p2 = np.percentile(img, 0.5)
            p98 = np.percentile(img, 99.5)
            img = exposure.rescale_intensity(img, in_range=(p2, p98))
            print('MIN',np.min(img),'MAX',np.max(img))
            img = (255*img).astype('uint8')
            img = cv2.applyColorMap(img, cv2.COLORMAP_VIRIDIS)
            cv2.imwrite(thumbpath, img)

        dim = tiff.TiffFile(filepath).series[0].shape
        res = 't\n%s\n%s\n%s' % (filepath, thumbpath, dim)
        return res
    except:
        log('Error in GetThumb, %s, %s' % (filepath,traceback.format_exc()))
        res = 't\n%s\n%s\n%s' % (filepath, '0','N/A')
        return res
示例#25
0
def load_full_img(path, verbose=True):
    """
    Reads using Tifffile one stack from the Tiff on a 3D Numpy array (TZCYX).
    :param verbose:
    :param channel:
    :param frame:
    :param meta:
    :param path:
    """
    import tifffile
    import sys
    import numpy as np

    if verbose:
        print('Loading the full image...'),
        sys.stdout.flush()

    with tifffile.TiffFile(path, fastij=True) as tif:
        img = tif.asarray()

    size = (sys.getsizeof(img)) / float(1024**3)
    if verbose:
        print(' [Done]')
        print(np.shape(img))
        print('Total of {:.2f} GB'.format(size))
        sys.stdout.flush()

    return img
示例#26
0
def openLSM(fname, callback=None):
    """ open LSM780 file using tifffile """
    info = dict()
    info["type"] = "binned"

    lsm = tifffile.TiffFile(fname)

    # two channels 0, 1?
    info["data_binned"] = lsm.asarray()[0]
    info["system_clock"] = 1

    page = lsm.pages[0]
    # pixel time in us
    info["bin_time"] = page.cz_lsm_scan_information["tracks"][0]["pixel_time"]

    # line time in s -> us
    info["line_time"] = (page.cz_lsm_time_stamps[1] -
                         page.cz_lsm_time_stamps[0]) * 1e6

    # total time in s -> us
    info["total_time"] = (page.cz_lsm_time_stamps[-1] -
                          page.cz_lsm_time_stamps[0]) * 1e6

    info["bins_per_line"] = info["data_binned"].shape[1]
    info["size"] = info["data_binned"].shape[0] * info["data_binned"].shape[1]
    info["bin_shift"] = None

    return info
        def _open(self, **kwargs):
            if not _tifffile:
                load_lib()
            self._tf = _tifffile.TiffFile(self.request.get_file(), **kwargs)

            # metadata is the same for all images
            self._meta = {}
示例#28
0
    def load(self, warn=True):
        if _tf is None:
            raise NotImplementedError

        data = []
        if self.load_metadata:
            metadata = dict()
        else:
            metadata = None

        t = _tf.TiffFile(self.name)
        for i, p in enumerate(t.pages):
            d = p.asarray()
            if p.photometric == p.photometric.RGB:
                # convert to an rgb dataset
                d = _core.asarray(d, dtype=_core.int16).view(_RGB)

                if not self.ascolour:
                    d = d.get_grey()

            data.append(("image-%02d" % (i+1,), d))
            if self.load_metadata:
                for k,v in p.tags.items():
                    metadata[k] = v.value

        if len(data) < 1:
            pass
        return DataHolder(data, metadata, warn)
示例#29
0
def test_tags_rbg_tiled(tmpdir_factory):
    testfile = "test_data/tiled_rgb_sample.tif"
    basename = os.path.basename(testfile)
    with Tiff(testfile) as handle:
        tags = handle.read_tags()

    with tifffile.TiffFile(testfile) as handle:
        page1 = handle.pages[0]
        tifffile_tags = {}
        for tag in page1.tags.values():
            name, value = tag.name, tag.value
            tifffile_tags[name] = value
        image = page1.asarray()

    compare_tags(tags, tifffile_tags)

    filename = str(tmpdir_factory.mktemp("write_tags").join(basename))
    with Tiff(filename, "w") as handle:
        handle.set_tags(**tags)
        handle.write(image,
                     method="tile",
                     tile_length=tags["tile_length"],
                     tile_width=tags["tile_width"])

    with Tiff(filename) as handle:
        written_tags = handle.read_tags()
        written_image = handle[:]

    assert np.all(written_image == image)
    check_written_tags(written_tags, tags)
示例#30
0
    def step_load_mask(self, operation: MaskMapper,
                       children: List[CalculationTree]):
        """
        Load mask using mask mapper (mask can be defined with suffix, substitution, or file with mapping saved,
        then iterate over ``children`` nodes.

        :param MaskMapper operation: operation to perform
        :param List[CalculationTree] children: list of nodes to iterate over with applied mask
        """
        mask_path = operation.get_mask_path(self.calculation.file_path)
        if mask_path == "":
            raise ValueError("Empty path to mask.")
        with tifffile.TiffFile(mask_path) as mask_file:
            mask = mask_file.asarray()
            mask = TiffImageReader.update_array_shape(
                mask, mask_file.series[0].axes)[..., 0]
        mask = (mask > 0).astype(np.uint8)
        try:
            mask = self.image.fit_array_to_image(mask)[0]
            # TODO fix this time bug fix
        except ValueError:
            raise ValueError("Mask do not fit to given image")
        old_mask = self.mask
        self.mask = mask
        self.iterate_over(children)
        self.mask = old_mask