Beispiel #1
0
def apply_frame_correction(method):
    """Do a smile correction for a single frame and return the result.

    Parameters
    ----------
        method: int
            Either 0 for lookup table method or 1 for row interpolation method.
    """
    control = toml.loads(P.example_scan_control_content)
    width = control[P.ctrl_scan_settings][P.ctrl_width]
    width_offset = control[P.ctrl_scan_settings][P.ctrl_width_offset]
    height = control[P.ctrl_scan_settings][P.ctrl_height]
    height_offset = control[P.ctrl_scan_settings][P.ctrl_height_offset]

    light_ds = F.load_frame(distortion_smile_tilt_path)
    light_ds = light_ds.isel({
        P.dim_x:
        slice(width_offset, width_offset + width),
        P.dim_y:
        slice(height_offset, height_offset + height)
    })
    sm, sl = make_shift_matrix()

    # Uncomment for debugging
    # frame_inspector.plot_frame(light_ds, sl, True, True)
    # sm.plot()
    # plt.show()

    light_frame = light_ds[P.naming_frame_data]
    corrected = sc.apply_shift_matrix(light_frame,
                                      shift_matrix=sm,
                                      method=method,
                                      target_is_cube=False)
    return corrected
Beispiel #2
0
def _show_a_frame(path, window_name=None):
    """General method to show various stuff. """

    source = F.load_frame(path)
    frame = source[P.naming_frame_data]
    dim_count = len(frame.dims)
    if dim_count == 1:
        plt.plot(frame.data)
    else:
        frame_inspector.plot_frame(source, window_name=window_name)

    plt.show()
Beispiel #3
0
def make_shift_matrix():
    """Make shift matrix and save it to disk."""

    control = toml.loads(P.example_scan_control_content)
    width = control[P.ctrl_scan_settings][P.ctrl_width]
    width_offset = control[P.ctrl_scan_settings][P.ctrl_width_offset]
    height = control[P.ctrl_scan_settings][P.ctrl_height]
    height_offset = control[P.ctrl_scan_settings][P.ctrl_height_offset]

    positions = np.array(
        control[P.ctrl_spectral_lines][P.ctrl_positions]) - width_offset
    bandpass_width = control[P.ctrl_spectral_lines][P.ctrl_window_width]

    light_ds = F.load_frame(distortion_smile_tilt_path)

    light_ds = light_ds.isel({
        P.dim_x:
        slice(width_offset, width_offset + width),
        P.dim_y:
        slice(height_offset, height_offset + height)
    })
    light_frame = light_ds[P.naming_frame_data]
    bp = sc.construct_bandpass_filter(light_frame, positions, bandpass_width)
    sl_list = sc.construct_spectral_lines(light_frame, positions, bp)
    shift_matrix = sc.construct_shift_matrix(sl_list,
                                             light_frame[P.dim_x].size,
                                             light_frame[P.dim_y].size)
    # frame_inspector.plot_frame(light_frame, sl_list, True, True, False, 'testing')

    abs_path = os.path.abspath(shift_path)
    print(f"Saving shift matrix to {abs_path}...", end=' ')
    shift_matrix.to_netcdf(abs_path)
    print("done")
    # Uncomment for debugging
    # shift_matrix.plot.imshow()
    # plt.show()
    return shift_matrix, sl_list
Beispiel #4
0
def make_undistorted_and_dark_frame():
    """Creates an example of undistorted frame and dark frame to examples directory.

    Created frame is "full sensor size" where the area illuminated by the slit
    is centered vertically. Use global variables 'row_noise_fac' and 'random_noise_fac'
    to control the level of added random noise.

    Frame data follows closely to the form that camazing uses in the frames it provides.
    Attributes are omitted though.
    """

    print(f"Generating frame example to '{undistorted_frame_path}'...", end='')
    source = F.load_frame(example_spectrogram_path)
    height = slit_height
    width = source[P.naming_frame_data][P.dim_x].size
    source_data = source[P.naming_frame_data].data
    max_pixel_val = source_data.max()
    expanded_data = np.repeat(source_data, height)
    expanded_data = np.reshape(expanded_data, (width, height))
    expanded_data = expanded_data.transpose()

    full_sensor = np.zeros((sensor_height, width))
    fh2 = int(sensor_height / 2)
    sh2 = int(slit_height / 2)
    full_sensor[fh2 - sh2:fh2 + sh2, :] = expanded_data

    # Multiply each row with a random number
    rand_row = np.random.normal(1, row_noise_fac, size=(sensor_height, ))
    full_sensor = full_sensor * rand_row[:, None]

    # Add random noise
    rando = np.random.uniform(0,
                              random_noise_fac * max_pixel_val,
                              size=(sensor_height, width))
    full_sensor = full_sensor + rando

    coords = {
        P.dim_x:
        (P.dim_x,
         np.arange(0, source[P.naming_frame_data][P.dim_x].size) + 0.5),
        P.dim_y: (P.dim_y, np.arange(0, sensor_height) + 0.5),
        "timestamp":
        dt.datetime.today().timestamp(),
    }
    dims = (P.dim_y, P.dim_x)
    frame = xr.DataArray(
        full_sensor,
        name=P.naming_frame_data,
        dims=dims,
        coords=coords,
    )

    # frame_inspector.plot_frame(frame)
    F.save_frame(frame, undistorted_frame_path)
    print("done")

    print(f"Generating dark frame example to '{dark_frame_path}'...", end='')
    dark = frame.copy(deep=True)
    dark.data = rando
    dark_frame = xr.DataArray(
        dark,
        name=P.naming_frame_data,
        dims=dims,
        coords=coords,
    )
    F.save_frame(dark_frame, dark_frame_path)
    print("done")
Beispiel #5
0
def make_stripe_cube():
    """Generates a raw cube.

    The cube is as if black and white target illuminated with fluorescence
    light was scanned. The result is saved to example_scan directory along
    with generated dark and white frames (copied from frame_examples directory),
    which will later be needed to calculate reflectance images. Also shift
    matrix is copied from frame_examples.
    """

    print(f"Generating stripe example raw cube.")

    control = toml.loads(P.example_scan_control_content)
    width = control[P.ctrl_scan_settings][P.ctrl_width]
    width_offset = control[P.ctrl_scan_settings][P.ctrl_width_offset]
    height = control[P.ctrl_scan_settings][P.ctrl_height]
    height_offset = control[P.ctrl_scan_settings][P.ctrl_height_offset]

    if not os.path.exists(distortion_smile_tilt_path + '.nc'):
        make_distorted_frame(['smile', 'tilt'])

    white_area = F.load_frame(distortion_smile_tilt_path)
    dark_area = white_area.copy(deep=True)

    F.save_frame(
        white_area[P.naming_frame_data],
        P.path_rel_scan + P.example_scan_name + '/' + P.ref_white_name)
    F.save_frame(dark_area[P.naming_frame_data],
                 P.path_rel_scan + P.example_scan_name + '/' + P.ref_dark_name)
    shift = F.load_shit_matrix(shift_path)
    F.save_shift_matrix(
        shift, P.path_rel_scan + P.example_scan_name + '/' + P.shift_name)

    x_slice = slice(width_offset, width_offset + width)
    y_slice = slice(height_offset, height_offset + height)
    white_area = white_area.isel({P.dim_x: x_slice, P.dim_y: y_slice})
    dark_area = dark_area.isel({P.dim_x: x_slice, P.dim_y: y_slice})
    white_area[P.naming_frame_data].values = np.nan_to_num(
        white_area[P.naming_frame_data].values)
    white_area[P.dim_x] = np.arange(0, white_area[P.dim_x].size) + 0.5
    white_area[P.dim_y] = np.arange(0, white_area[P.dim_y].size) + 0.5
    dark_area[P.dim_x] = np.arange(0, white_area[P.dim_x].size) + 0.5
    dark_area[P.dim_y] = np.arange(0, white_area[P.dim_y].size) + 0.5
    area_shape = white_area[P.naming_frame_data].values.shape
    max_pixel_val = white_area[P.naming_frame_data].max().item()
    dark_area[P.naming_frame_data].values = np.random.uniform(
        0, random_noise_fac * max_pixel_val, size=area_shape)

    frame_list = []
    stripe_counter = 0
    use_white = True
    for i in range(cube_depth):
        if stripe_counter > stripe_width - 1:
            use_white = not use_white
            stripe_counter = 0
        rando = np.random.uniform(0,
                                  random_noise_fac * max_pixel_val,
                                  size=area_shape)
        if use_white:
            f = white_area.copy(deep=True)
            f[P.
              naming_frame_data].values = f[P.naming_frame_data].values + rando
        else:
            f = dark_area.copy(deep=True)
            f[P.naming_frame_data].values = rando

        f.coords[P.dim_scan] = i
        frame_list.append(f[P.naming_frame_data])
        stripe_counter += 1

    frames = xr.concat(frame_list, dim=P.dim_scan)
    cube = xr.Dataset(data_vars={
        P.naming_cube_data: frames,
    }, )
    F.save_cube(
        cube,
        P.path_rel_scan + '/' + P.example_scan_name + '/' + P.cube_raw_name)
    print(f"Generated stripe example raw cube.")
Beispiel #6
0
def make_distorted_frame(distortions, amount=None):
    """Creates an example of a frame suffering from spectral smile or tilt or both to examples directory.

    Adds metadata to the frame, which can be accessed through the dataset ds by 'ds.attributes'.
    Meta contains tilt and curvature of the spectral lines.
    """

    print("Generating distorted frame")
    if not os.path.exists(undistorted_frame_path):
        make_undistorted_and_dark_frame()

    u_frame_ds = F.load_frame(undistorted_frame_path)
    u_frame = u_frame_ds[P.naming_frame_data]
    width = u_frame[P.dim_x].size
    height = u_frame[P.dim_y].size
    save_path = P.path_example_frames + 'distorted'
    meta = {}

    if 'smile' in distortions:
        if amount is None:
            curvature = default_curvature
        else:
            curvature = amount
        meta[key_curvature_generated] = curvature
        distortion_matrix = generate_distortion_matrix(width,
                                                       height,
                                                       curvature,
                                                       method='smile')
        u_frame = interpolative_distortion(u_frame, distortion_matrix)
        save_path = save_path + '_smile'
    if 'tilt' in distortions:
        if amount is None:
            tilt = default_tilt
        else:
            tilt = amount
        meta[key_tilt_generated] = tilt
        distortion_matrix = generate_distortion_matrix(width,
                                                       height,
                                                       tilt,
                                                       method='tilt')
        save_path = save_path + '_tilt'
        u_frame = interpolative_distortion(u_frame, distortion_matrix)

    ################
    # Find spectral lines and add the mean values to metadata to verify correctness of
    # the calculated values.
    control = toml.loads(P.example_scan_control_content)
    width = control[P.ctrl_scan_settings][P.ctrl_width]
    width_offset = control[P.ctrl_scan_settings][P.ctrl_width_offset]
    height = control[P.ctrl_scan_settings][P.ctrl_height]
    height_offset = control[P.ctrl_scan_settings][P.ctrl_height_offset]
    positions = np.array(
        control[P.ctrl_spectral_lines][P.ctrl_positions]) - width_offset
    peak_width = control[P.ctrl_spectral_lines][P.ctrl_peak_width]
    bandpass_width = control[P.ctrl_spectral_lines][P.ctrl_window_width]

    crop_frame = u_frame.isel({
        P.dim_x:
        slice(width_offset, width_offset + width),
        P.dim_y:
        slice(height_offset, height_offset + height)
    })
    bp = sc.construct_bandpass_filter(crop_frame, positions, bandpass_width)
    sl_list = sc.construct_spectral_lines(crop_frame,
                                          positions,
                                          bp,
                                          peak_width=peak_width)

    meta[P.meta_key_sl_count] = len(sl_list)
    meta[P.meta_key_location] = [sl.location for sl in sl_list]
    meta[P.meta_key_tilt] = [sl.tilt for sl in sl_list]
    meta[P.meta_key_curvature] = [sl.curvature for sl in sl_list]

    meta[key_curvature_measured_mean] = np.mean(
        np.array([sl.curvature for sl in sl_list]))
    meta[key_tilt_measured_mean] = np.mean(
        np.array([sl.tilt_angle_degree_abs for sl in sl_list]))

    print(meta)

    ################

    u_frame = u_frame.isel({
        P.dim_x:
        slice(width_offset, width_offset + width),
        P.dim_y:
        slice(height_offset, height_offset + height)
    })

    F.save_frame(u_frame, save_path, meta)
    print(f"Generated distorted frame to '{save_path}'")
Beispiel #7
0
    def __init__(self, session_name:str):
        """Initializes new scanning session with given name.

        Creates a default directory (/scans/<session_name>) if it does not yet exist. If it
        exists, the existing files are loaded.

        Parameters
        ----------
        session_name : str
            Name of the session either existing or a new one.
        """

        self.session_name = session_name
        self.session_root = P.path_rel_scan + '/' + session_name + '/'
        self.camera_setting_path = self.session_root + P.fn_camera_settings
        self.scan_settings_path = os.path.abspath(self.session_root + P.fn_control)
        self.dark_path  = os.path.abspath(self.session_root + P.ref_dark_name + '.nc')
        self.white_path = os.path.abspath(self.session_root + P.ref_white_name + '.nc')
        self.light_path = os.path.abspath(self.session_root + P.ref_light_name + '.nc')
        self.shift_path = os.path.abspath(self.session_root + P.shift_name + '.nc')
        self.cube_raw_path = os.path.abspath(self.session_root + P.cube_raw_name + '.nc')
        self.cube_rfl_path = os.path.abspath(self.session_root + P.cube_reflectance_name + '.nc')
        self.cube_desmiled_lut_path = os.path.abspath(self.session_root + P.cube_desmiled_lut + '.nc')
        self.cube_desmiled_intr_path = os.path.abspath(self.session_root + P.cube_desmiled_intr + '.nc')

        # CameraInterface object
        self._cami = None
        # Contents of the control file as a dictionary
        self.control = None
        # Dark reference frame
        self.dark = None
        # White reference frame
        self.white = None
        # Light reference frame
        self.light = None

        if self.session_exists():
            print(f"Found existing session '{session_name}'.")

            logging.info(f"Searching for existing dark frame from '{self.dark_path}'")
            if os.path.exists(self.dark_path):
                print(f"Found existing dark frame. Loading into memory", end='...')
                self.dark = F.load_frame(self.dark_path)
                print("done")

            logging.info(f"Searching for existing white frame from '{self.white_path}'")
            if os.path.exists(self.white_path):
                print(f"Found existing white frame. Loading into memory", end='...')
                self.white = F.load_frame(self.white_path)
                print("done")

            logging.info(f"Searching for existing light frame from '{self.light_path}'")
            if os.path.exists(self.light_path):
                print(f"Found existing light frame. Loading into memory", end='...')
                self.light = F.load_frame(self.light_path)
                print("done")

        else:
            print(f"Creating new session '{session_name}'")
            F.create_directory(self.session_root)

        if not os.path.exists(self.scan_settings_path):
            self.generate_default_scan_control()
        else:
            self.load_control_file()
        print(f"Session initialized and ready to work.")