Beispiel #1
0
def preprocess_with_augmentation(patient_data,
                                 result,
                                 index,
                                 augment=True,
                                 metadata=None,
                                 testaug=False):
    """
    Load the resulting data, augment it if needed, and put it in result at the correct index
    :param patient_data:
    :param result:
    :param index:
    :return:
    """
    if augment:
        augmentation_parameters = sample_augmentation_parameters()
    else:
        augmentation_parameters = None

    for tag, data in patient_data.iteritems():
        metadata_tag = metadata[tag]
        desired_shape = result[tag][index].shape
        # try to fit data into the desired shape
        if tag.startswith("sliced:data:singleslice"):
            cleaning_processes = getattr(config(), 'cleaning_processes', [])
            data = clean_images([patient_data[tag]],
                                metadata=metadata_tag,
                                cleaning_processes=cleaning_processes)
            patient_4d_tensor, zoom_ratios = resize_and_augment(
                data,
                output_shape=desired_shape[-2:],
                augment=augmentation_parameters)[0]
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(
                    metadata_tag["PixelSpacing"])

            put_in_the_middle(result[tag][index], patient_4d_tensor)
        elif tag.startswith("sliced:data"):
            # put time dimension first, then axis dimension
            data = clean_images(patient_data[tag], metadata=metadata_tag)
            patient_4d_tensor, zoom_ratios = resize_and_augment(
                data,
                output_shape=desired_shape[-2:],
                augment=augmentation_parameters)
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(
                    metadata_tag[0]["PixelSpacing"])

            if "noswitch" not in tag:
                patient_4d_tensor = np.swapaxes(patient_4d_tensor, 1, 0)

            put_in_the_middle(result[tag][index], patient_4d_tensor)
        if tag.startswith("sliced:data:shape"):
            result[tag][index] = patient_data[tag]
        if tag.startswith("sliced:meta:"):
            # TODO: this probably doesn't work very well yet
            result[tag][index] = patient_data[tag]
    return
Beispiel #2
0
def preprocess_with_augmentation(patient_data, result, index, augment=True, metadata=None, testaug=False):
    """
    Load the resulting data, augment it if needed, and put it in result at the correct index
    :param patient_data:
    :param result:
    :param index:
    :return:
    """
    if augment:
        augmentation_parameters = sample_augmentation_parameters()
    else:
        augmentation_parameters = None

    for tag, data in patient_data.iteritems():
        metadata_tag = metadata[tag]
        desired_shape = result[tag][index].shape
        # try to fit data into the desired shape
        if tag.startswith("sliced:data:singleslice"):
            cleaning_processes = getattr(config(), 'cleaning_processes', [])
            data = clean_images(
                [patient_data[tag]], metadata=metadata_tag,
                cleaning_processes=cleaning_processes)
            patient_4d_tensor, zoom_ratios = resize_and_augment(data, output_shape=desired_shape[-2:], augment=augmentation_parameters)[0]
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(metadata_tag["PixelSpacing"])

            put_in_the_middle(result[tag][index], patient_4d_tensor)
        elif tag.startswith("sliced:data"):
            # put time dimension first, then axis dimension
            data = clean_images(patient_data[tag], metadata=metadata_tag)
            patient_4d_tensor, zoom_ratios = resize_and_augment(data, output_shape=desired_shape[-2:], augment=augmentation_parameters)
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(metadata_tag[0]["PixelSpacing"])

            if "noswitch" not in tag:
                patient_4d_tensor = np.swapaxes(patient_4d_tensor,1,0)

            put_in_the_middle(result[tag][index], patient_4d_tensor)
        if tag.startswith("sliced:data:shape"):
            result[tag][index] = patient_data[tag]
        if tag.startswith("sliced:meta:"):
            # TODO: this probably doesn't work very well yet
            result[tag][index] = patient_data[tag]
    return
Beispiel #3
0
def preprocess_normscale(
        patient_data,
        result,
        index,
        augment=True,
        metadata=None,
        normscale_resize_and_augment_function=normscale_resize_and_augment,
        testaug=False):
    """Normalizes scale and augments the data.

    Args:
        patient_data: the data to be preprocessed.
        result: dict to store the result in.
        index: index indicating in which slot the result dict the data
            should go.
        augment: flag indicating wheter augmentation is needed.
        metadata: metadata belonging to the patient data.
    """
    if augment:
        if testaug:
            augmentation_params = sample_test_augmentation_parameters()
        else:
            augmentation_params = sample_augmentation_parameters()
    else:
        augmentation_params = None

    zoom_factor = None

    # Iterate over different sorts of data
    for tag, data in patient_data.iteritems():
        if tag in metadata:
            metadata_tag = metadata[tag]
        desired_shape = result[tag][index].shape

        cleaning_processes = getattr(config(), 'cleaning_processes', [])
        cleaning_processes_post = getattr(config(), 'cleaning_processes_post',
                                          [])

        if tag.startswith("sliced:data:singleslice"):
            # Cleaning data before extracting a patch
            data = clean_images([patient_data[tag]],
                                metadata=metadata_tag,
                                cleaning_processes=cleaning_processes)

            # Augment and extract patch
            # Decide which roi to use.
            shift_center = (None, None)
            if getattr(config(), 'use_hough_roi', False):
                shift_center = metadata_tag["hough_roi"]

            patient_3d_tensor = normscale_resize_and_augment_function(
                data,
                output_shape=desired_shape[-2:],
                augment=augmentation_params,
                pixel_spacing=metadata_tag["PixelSpacing"],
                shift_center=shift_center[::-1])[0]

            if augmentation_params is not None:
                zoom_factor = augmentation_params[
                    "zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0

            # Clean data further
            patient_3d_tensor = clean_images(
                patient_3d_tensor,
                metadata=metadata_tag,
                cleaning_processes=cleaning_processes_post)

            if "area_per_pixel:sax" in result:
                raise NotImplementedError()

            if augmentation_params and not augmentation_params.get(
                    "change_brightness", 0) == 0:
                patient_3d_tensor = augment_brightness(
                    patient_3d_tensor,
                    augmentation_params["change_brightness"])

            put_in_the_middle(result[tag][index], patient_3d_tensor, True)

        elif tag.startswith("sliced:data:randomslices"):
            # Clean each slice separately
            data = [
                clean_images([slicedata],
                             metadata=metadata,
                             cleaning_processes=cleaning_processes)[0]
                for slicedata, metadata in zip(data, metadata_tag)
            ]

            # Augment and extract patches
            shift_centers = [(None, None)] * len(data)
            if getattr(config(), 'use_hough_roi', False):
                shift_centers = [m["hough_roi"] for m in metadata_tag]

            patient_3d_tensors = [
                normscale_resize_and_augment_function(
                    [slicedata],
                    output_shape=desired_shape[-2:],
                    augment=augmentation_params,
                    pixel_spacing=metadata["PixelSpacing"],
                    shift_center=shift_center[::-1])[0]
                for slicedata, metadata, shift_center in zip(
                    data, metadata_tag, shift_centers)
            ]
            if augmentation_params is not None:
                zoom_factor = augmentation_params[
                    "zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0

            # Clean data further
            patient_3d_tensors = [
                clean_images([patient_3d_tensor],
                             metadata=metadata,
                             cleaning_processes=cleaning_processes_post)[0]
                for patient_3d_tensor, metadata in zip(patient_3d_tensors,
                                                       metadata_tag)
            ]

            patient_4d_tensor = _make_4d_tensor(patient_3d_tensors)

            if augmentation_params and not augmentation_params.get(
                    "change_brightness", 0) == 0:
                patient_4d_tensor = augment_brightness(
                    patient_4d_tensor,
                    augmentation_params["change_brightness"])

            if "area_per_pixel:sax" in result:
                raise NotImplementedError()

            put_in_the_middle(result[tag][index], patient_4d_tensor, True)

        elif tag.startswith("sliced:data:sax:locations"):
            pass  # will be filled in by the next one
        elif tag.startswith("sliced:data:sax:is_not_padded"):
            pass  # will be filled in by the next one
        elif tag.startswith("sliced:data:sax"):
            # step 1: sort (data, metadata_tag) with slice_location_finder
            slice_locations, sorted_indices, sorted_distances = slice_location_finder(
                {i: metadata
                 for i, metadata in enumerate(metadata_tag)})

            data = [data[idx] for idx in sorted_indices]
            metadata_tag = [metadata_tag[idx] for idx in sorted_indices]

            slice_locations = np.array([
                slice_locations[idx]["relative_position"]
                for idx in sorted_indices
            ])
            slice_locations = slice_locations - (slice_locations[-1] +
                                                 slice_locations[0]) / 2.0

            data = [
                clean_images([slicedata],
                             metadata=metadata,
                             cleaning_processes=cleaning_processes)[0]
                for slicedata, metadata in zip(data, metadata_tag)
            ]

            # Augment and extract patches
            shift_centers = [(None, None)] * len(data)
            if getattr(config(), 'use_hough_roi', False):
                shift_centers = [m["hough_roi"] for m in metadata_tag]

            patient_3d_tensors = [
                normscale_resize_and_augment_function(
                    [slicedata],
                    output_shape=desired_shape[-2:],
                    augment=augmentation_params,
                    pixel_spacing=metadata["PixelSpacing"],
                    shift_center=shift_center[::-1])[0]
                for slicedata, metadata, shift_center in zip(
                    data, metadata_tag, shift_centers)
            ]

            if augmentation_params is not None:
                zoom_factor = augmentation_params[
                    "zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0

            # Clean data further
            patient_3d_tensors = [
                clean_images([patient_3d_tensor],
                             metadata=metadata,
                             cleaning_processes=cleaning_processes_post)[0]
                for patient_3d_tensor, metadata in zip(patient_3d_tensors,
                                                       metadata_tag)
            ]

            patient_4d_tensor = _make_4d_tensor(patient_3d_tensors)

            if augmentation_params and not augmentation_params.get(
                    "change_brightness", 0) == 0:
                patient_4d_tensor = augment_brightness(
                    patient_4d_tensor,
                    augmentation_params["change_brightness"])

            # Augment sax order
            if augmentation_params and augmentation_params.get("flip_sax",
                                                               0) > 0.5:
                patient_4d_tensor = patient_4d_tensor[::-1]
                slice_locations = slice_locations[::-1]

            # Put data (images and metadata) in right location
            put_in_the_middle(result[tag][index], patient_4d_tensor, True)

            if "sliced:data:sax:locations" in result:
                eps_location = 1e-7
                is_padded = np.array(
                    [False] * len(result["sliced:data:sax:locations"][index]))
                put_in_the_middle(result["sliced:data:sax:locations"][index],
                                  slice_locations + eps_location, True,
                                  is_padded)

            if "sliced:data:sax:distances" in result:
                eps_location = 1e-7
                sorted_distances.append(0.0)  # is easier for correct padding
                is_padded = np.array(
                    [False] * len(result["sliced:data:sax:distances"][index]))
                put_in_the_middle(result["sliced:data:sax:distances"][index],
                                  np.array(sorted_distances) + eps_location,
                                  True, is_padded)

            if "sliced:data:sax:is_not_padded" in result:
                result["sliced:data:sax:is_not_padded"][
                    index] = np.logical_not(is_padded)

        elif tag.startswith("sliced:data:chanzoom:2ch"):
            # step 1: sort (data, metadata_tag) with slice_location_finder
            slice_locations, sorted_indices, sorted_distances = slice_location_finder(
                {i: metadata
                 for i, metadata in enumerate(metadata_tag[2])})

            top_slice_metadata = metadata_tag[2][sorted_indices[0]]
            bottom_slice_metadata = metadata_tag[2][sorted_indices[-1]]

            ch2_metadata = metadata_tag[1]
            ch4_metadata = metadata_tag[0]

            trf_2ch, trf_4ch = get_chan_transformations(
                ch2_metadata=ch2_metadata,
                ch4_metadata=ch4_metadata,
                top_point_metadata=top_slice_metadata,
                bottom_point_metadata=bottom_slice_metadata,
                output_width=desired_shape[-1])

            ch4_3d_patient_tensor, ch2_3d_patient_tensor = [], []
            ch4_data = data[0]
            ch2_data = data[1]
            if ch4_data is None and ch2_data is not None:
                ch4_data = ch2_data
                ch4_metadata = ch2_metadata
            if ch2_data is None and ch4_data is not None:
                ch2_data = ch4_data
                ch2_metadata = ch4_metadata

            for ch, ch_result, transform, metadata in [
                (ch4_data, ch4_3d_patient_tensor, trf_4ch, ch4_metadata),
                (ch2_data, ch2_3d_patient_tensor, trf_2ch, ch2_metadata)
            ]:
                tform_shift_center, tform_shift_uncenter = build_center_uncenter_transforms(
                    desired_shape[-2:])
                zoom_factor = np.sqrt(
                    np.abs(np.linalg.det(transform.params[:2, :2])) *
                    np.prod(metadata["PixelSpacing"]))
                normalise_zoom_transform = build_augmentation_transform(
                    zoom_x=zoom_factor, zoom_y=zoom_factor)
                if augmentation_params:
                    augment_tform = build_augmentation_transform(
                        **augmentation_params)
                    total_tform = tform_shift_uncenter + augment_tform + normalise_zoom_transform + tform_shift_center + transform
                else:
                    total_tform = tform_shift_uncenter + normalise_zoom_transform + tform_shift_center + transform

                ch_result[:] = [
                    fast_warp(c, total_tform, output_shape=desired_shape[-2:])
                    for c in ch
                ]
                # print "zoom factor:", zoom_factor

            if augmentation_params is not None:
                zoom_factor = augmentation_params[
                    "zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0
            # Clean data further
            ch4_3d_patient_tensor = clean_images(
                np.array([ch4_3d_patient_tensor]),
                metadata=ch4_metadata,
                cleaning_processes=cleaning_processes_post)[0]
            ch2_3d_patient_tensor = clean_images(
                np.array([ch2_3d_patient_tensor]),
                metadata=ch2_metadata,
                cleaning_processes=cleaning_processes_post)[0]

            # Put data (images and metadata) in right location
            put_in_the_middle(result["sliced:data:chanzoom:2ch"][index],
                              ch2_3d_patient_tensor, True)
            put_in_the_middle(result["sliced:data:chanzoom:4ch"][index],
                              ch4_3d_patient_tensor, True)

        elif tag.startswith("sliced:data:shape"):
            raise NotImplementedError()

        elif tag.startswith("sliced:data"):
            # put time dimension first, then axis dimension
            data = clean_images(patient_data[tag], metadata=metadata_tag)
            patient_4d_tensor, zoom_ratios = resize_and_augment(
                data,
                output_shape=desired_shape[-2:],
                augment=augmentation_parameters)
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(
                    metadata_tag[0]["PixelSpacing"])

            if "noswitch" not in tag:
                patient_4d_tensor = np.swapaxes(patient_4d_tensor, 1, 0)

            put_in_the_middle(result[tag][index], patient_4d_tensor)

        elif tag.startswith("sliced:meta:all"):
            # TODO: this probably doesn't work very well yet
            result[tag][index] = patient_data[tag]

        elif tag.startswith("sliced:meta:PatientSex"):
            result[tag][index][0] = -1. if patient_data[tag] == 'M' else 1.

        elif tag.startswith("sliced:meta:PatientAge"):
            number, letter = patient_data[tag][:3], patient_data[tag][-1]
            letter_rescale_factors = {
                'D': 365.25,
                'W': 52.1429,
                'M': 12.,
                'Y': 1.
            }
            result[tag][index][0] = float(
                patient_data[tag][:3]) / letter_rescale_factors[letter]

    if augmentation_params and zoom_factor:
        label_correction_function = lambda x: x * zoom_factor
        classification_correction_function = lambda x: utils.zoom_array(
            x, 1. / zoom_factor)
        return label_correction_function, classification_correction_function
    else:
        return lambda x: x, lambda x: x
Beispiel #4
0
def preprocess_normscale(patient_data, result, index, augment=True,
                         metadata=None,
                         normscale_resize_and_augment_function=normscale_resize_and_augment,
                         testaug=False):
    """Normalizes scale and augments the data.

    Args:
        patient_data: the data to be preprocessed.
        result: dict to store the result in.
        index: index indicating in which slot the result dict the data
            should go.
        augment: flag indicating wheter augmentation is needed.
        metadata: metadata belonging to the patient data.
    """
    if augment:
        if testaug:
            augmentation_params = sample_test_augmentation_parameters()
        else:
            augmentation_params = sample_augmentation_parameters()
    else:
        augmentation_params = None

    zoom_factor = None

    # Iterate over different sorts of data
    for tag, data in patient_data.iteritems():
        if tag in metadata:
            metadata_tag = metadata[tag]
        desired_shape = result[tag][index].shape

        cleaning_processes = getattr(config(), 'cleaning_processes', [])
        cleaning_processes_post = getattr(config(), 'cleaning_processes_post', [])

        if tag.startswith("sliced:data:singleslice"):
            # Cleaning data before extracting a patch
            data = clean_images(
                [patient_data[tag]], metadata=metadata_tag,
                cleaning_processes=cleaning_processes)

            # Augment and extract patch
            # Decide which roi to use.
            shift_center = (None, None)
            if getattr(config(), 'use_hough_roi', False):
                shift_center = metadata_tag["hough_roi"]

            patient_3d_tensor = normscale_resize_and_augment_function(
                data, output_shape=desired_shape[-2:],
                augment=augmentation_params,
                pixel_spacing=metadata_tag["PixelSpacing"],
                shift_center=shift_center[::-1])[0]

            if augmentation_params is not None:
                zoom_factor = augmentation_params["zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0
                
            # Clean data further
            patient_3d_tensor = clean_images(
                patient_3d_tensor, metadata=metadata_tag,
                cleaning_processes=cleaning_processes_post)

            if "area_per_pixel:sax" in result:
                raise NotImplementedError()

            if augmentation_params and not augmentation_params.get("change_brightness", 0) == 0:
                patient_3d_tensor = augment_brightness(patient_3d_tensor, augmentation_params["change_brightness"])

            put_in_the_middle(result[tag][index], patient_3d_tensor, True)


        elif tag.startswith("sliced:data:randomslices"):
            # Clean each slice separately
            data = [
                clean_images([slicedata], metadata=metadata, cleaning_processes=cleaning_processes)[0]
                for slicedata, metadata in zip(data, metadata_tag)]

            # Augment and extract patches
            shift_centers = [(None, None)] * len(data)
            if getattr(config(), 'use_hough_roi', False):
                shift_centers = [m["hough_roi"] for m in metadata_tag]

            patient_3d_tensors = [
                normscale_resize_and_augment_function(
                    [slicedata], output_shape=desired_shape[-2:],
                    augment=augmentation_params,
                    pixel_spacing=metadata["PixelSpacing"],
                    shift_center=shift_center[::-1])[0]
                for slicedata, metadata, shift_center in zip(data, metadata_tag, shift_centers)]
            if augmentation_params is not None:
                zoom_factor = augmentation_params["zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0

            # Clean data further
            patient_3d_tensors = [
                clean_images([patient_3d_tensor], metadata=metadata, cleaning_processes=cleaning_processes_post)[0]
                for patient_3d_tensor, metadata in zip(patient_3d_tensors, metadata_tag)]

            patient_4d_tensor = _make_4d_tensor(patient_3d_tensors)

            if augmentation_params and not augmentation_params.get("change_brightness", 0) == 0:
                patient_4d_tensor = augment_brightness(patient_4d_tensor, augmentation_params["change_brightness"])

            if "area_per_pixel:sax" in result:
                raise NotImplementedError()

            put_in_the_middle(result[tag][index], patient_4d_tensor, True)

        elif tag.startswith("sliced:data:sax:locations"):
            pass  # will be filled in by the next one
        elif tag.startswith("sliced:data:sax:is_not_padded"):
            pass  # will be filled in by the next one
        elif tag.startswith("sliced:data:sax"):
            # step 1: sort (data, metadata_tag) with slice_location_finder
            slice_locations, sorted_indices, sorted_distances = slice_location_finder({i: metadata for i,metadata in enumerate(metadata_tag)})

            data = [data[idx] for idx in sorted_indices]
            metadata_tag = [metadata_tag[idx] for idx in sorted_indices]

            slice_locations = np.array([slice_locations[idx]["relative_position"] for idx in sorted_indices])
            slice_locations = slice_locations - (slice_locations[-1] + slice_locations[0])/2.0

            data = [
                clean_images([slicedata], metadata=metadata, cleaning_processes=cleaning_processes)[0]
                for slicedata, metadata in zip(data, metadata_tag)]

            # Augment and extract patches
            shift_centers = [(None, None)] * len(data)
            if getattr(config(), 'use_hough_roi', False):
                shift_centers = [m["hough_roi"] for m in metadata_tag]

            patient_3d_tensors = [
                normscale_resize_and_augment_function(
                    [slicedata], output_shape=desired_shape[-2:],
                    augment=augmentation_params,
                    pixel_spacing=metadata["PixelSpacing"],
                    shift_center=shift_center[::-1])[0]
                for slicedata, metadata, shift_center in zip(data, metadata_tag, shift_centers)]

            if augmentation_params is not None:
                zoom_factor = augmentation_params["zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0

            # Clean data further
            patient_3d_tensors = [
                clean_images([patient_3d_tensor], metadata=metadata, cleaning_processes=cleaning_processes_post)[0]
                for patient_3d_tensor, metadata in zip(patient_3d_tensors, metadata_tag)]

            patient_4d_tensor = _make_4d_tensor(patient_3d_tensors)

            if augmentation_params and not augmentation_params.get("change_brightness", 0) == 0:
                patient_4d_tensor = augment_brightness(patient_4d_tensor, augmentation_params["change_brightness"])

            # Augment sax order
            if augmentation_params and augmentation_params.get("flip_sax", 0) > 0.5:
                patient_4d_tensor = patient_4d_tensor[::-1]
                slice_locations = slice_locations[::-1]

            # Put data (images and metadata) in right location
            put_in_the_middle(result[tag][index], patient_4d_tensor, True)

            if "sliced:data:sax:locations" in result:
                eps_location = 1e-7
                is_padded = np.array([False]*len(result["sliced:data:sax:locations"][index]))
                put_in_the_middle(result["sliced:data:sax:locations"][index], slice_locations + eps_location, True, is_padded)

            if "sliced:data:sax:distances" in result:
                eps_location = 1e-7
                sorted_distances.append(0.0)  # is easier for correct padding
                is_padded = np.array([False]*len(result["sliced:data:sax:distances"][index]))
                put_in_the_middle(result["sliced:data:sax:distances"][index], np.array(sorted_distances) + eps_location, True, is_padded)

            if "sliced:data:sax:is_not_padded" in result:
                result["sliced:data:sax:is_not_padded"][index] = np.logical_not(is_padded)



        elif tag.startswith("sliced:data:chanzoom:2ch"):
            # step 1: sort (data, metadata_tag) with slice_location_finder
            slice_locations, sorted_indices, sorted_distances = slice_location_finder({i: metadata for i,metadata in enumerate(metadata_tag[2])})

            top_slice_metadata = metadata_tag[2][sorted_indices[0]]
            bottom_slice_metadata = metadata_tag[2][sorted_indices[-1]]

            ch2_metadata = metadata_tag[1]
            ch4_metadata = metadata_tag[0]

            trf_2ch, trf_4ch = get_chan_transformations(
                ch2_metadata=ch2_metadata,
                ch4_metadata=ch4_metadata,
                top_point_metadata = top_slice_metadata,
                bottom_point_metadata = bottom_slice_metadata,
                output_width=desired_shape[-1]
                )

            ch4_3d_patient_tensor, ch2_3d_patient_tensor = [], []
            ch4_data = data[0]
            ch2_data = data[1]
            if ch4_data is None and ch2_data is not None:
                ch4_data = ch2_data
                ch4_metadata = ch2_metadata
            if ch2_data is None and ch4_data is not None:
                ch2_data = ch4_data
                ch2_metadata = ch4_metadata

            for ch, ch_result, transform, metadata in [(ch4_data, ch4_3d_patient_tensor, trf_4ch, ch4_metadata),
                                                        (ch2_data, ch2_3d_patient_tensor, trf_2ch, ch2_metadata)]:
                tform_shift_center, tform_shift_uncenter = build_center_uncenter_transforms(desired_shape[-2:])
                zoom_factor = np.sqrt(np.abs(np.linalg.det(transform.params[:2,:2])) * np.prod(metadata["PixelSpacing"]))
                normalise_zoom_transform = build_augmentation_transform(zoom_x=zoom_factor, zoom_y=zoom_factor)
                if augmentation_params:
                    augment_tform = build_augmentation_transform(**augmentation_params)
                    total_tform = tform_shift_uncenter + augment_tform + normalise_zoom_transform + tform_shift_center + transform
                else:
                    total_tform = tform_shift_uncenter + normalise_zoom_transform + tform_shift_center + transform

                ch_result[:] = [fast_warp(c, total_tform, output_shape=desired_shape[-2:]) for c in ch]
                # print "zoom factor:", zoom_factor

            if augmentation_params is not None:
                zoom_factor = augmentation_params["zoom_x"] * augmentation_params["zoom_y"]
            else:
                zoom_factor = 1.0
            # Clean data further
            ch4_3d_patient_tensor = clean_images(np.array([ch4_3d_patient_tensor]), metadata=ch4_metadata, cleaning_processes=cleaning_processes_post)[0]
            ch2_3d_patient_tensor = clean_images(np.array([ch2_3d_patient_tensor]), metadata=ch2_metadata, cleaning_processes=cleaning_processes_post)[0]

            # Put data (images and metadata) in right location
            put_in_the_middle(result["sliced:data:chanzoom:2ch"][index], ch2_3d_patient_tensor, True)
            put_in_the_middle(result["sliced:data:chanzoom:4ch"][index], ch4_3d_patient_tensor, True)

        elif tag.startswith("sliced:data:shape"):
            raise NotImplementedError()

        elif tag.startswith("sliced:data"):
            # put time dimension first, then axis dimension
            data = clean_images(patient_data[tag], metadata=metadata_tag)
            patient_4d_tensor, zoom_ratios = resize_and_augment(data, output_shape=desired_shape[-2:], augment=augmentation_parameters)
            if "area_per_pixel:sax" in result:
                result["area_per_pixel:sax"][index] = zoom_ratios[0] * np.prod(metadata_tag[0]["PixelSpacing"])

            if "noswitch" not in tag:
                patient_4d_tensor = np.swapaxes(patient_4d_tensor,1,0)

            put_in_the_middle(result[tag][index], patient_4d_tensor)

        elif tag.startswith("sliced:meta:all"):
            # TODO: this probably doesn't work very well yet
            result[tag][index] = patient_data[tag]

        elif tag.startswith("sliced:meta:PatientSex"):
            result[tag][index][0] = -1. if patient_data[tag]=='M' else 1.

        elif tag.startswith("sliced:meta:PatientAge"):
            number, letter = patient_data[tag][:3], patient_data[tag][-1]
            letter_rescale_factors = {'D': 365.25, 'W': 52.1429, 'M': 12., 'Y': 1.}
            result[tag][index][0] = float(patient_data[tag][:3]) / letter_rescale_factors[letter]

    if augmentation_params and zoom_factor:
        label_correction_function = lambda x: x * zoom_factor
        classification_correction_function = lambda x: utils.zoom_array(x, 1./zoom_factor)
        return label_correction_function, classification_correction_function
    else:
        return lambda x: x, lambda x: x