nabu.estimation.focus module

class nabu.estimation.focus.CameraFocus(vert_fft_width=False, horz_fft_width=False, verbose=False, logger=None, data_type=<class 'numpy.float32'>, extra_options=None)[source]

Bases: CenterOfRotation

Alignment basic functions.

Parameters:
  • vert_fft_width (boolean, optional) –

    If True, restrict the vertical size to a power of 2:

    >>> new_v_dim = 2 ** math.floor(math.log2(v_dim))
    

  • horz_fft_width (boolean, optional) –

    If True, restrict the horizontal size to a power of 2:

    >>> new_h_dim = 2 ** math.floor(math.log2(h_dim))
    

  • verbose (boolean, optional) – When True it will produce verbose output, including plots.

  • data_type (numpy.float32) – Computation data type.

find_distance(img_stack: ndarray, img_pos: array, metric='std', roi_yxhw=None, median_filt_shape=None, padding_mode=None, peak_fit_radius=1, high_pass=None, low_pass=None)[source]

Find the focal distance of the camera system.

This routine computes the motor position that corresponds to having the scintillator on the focal plain of the camera system.

Parameters:
  • img_stack (numpy.ndarray) – A stack of images at different distances.

  • img_pos (numpy.ndarray) – Position of the images along the translation axis

  • metric (string, optional) – The property, whose maximize occurs at the focal position. Defaults to ‘std’ (standard deviation). All options are: ‘std’ | ‘grad’ | ‘psd’

  • roi_yxhw ((2, ) or (4, ) numpy.ndarray, tuple, or array, optional) – 4 elements vector containing: vertical and horizontal coordinates of first pixel, plus height and width of the Region of Interest (RoI). Or a 2 elements vector containing: plus height and width of the centered Region of Interest (RoI). Default is None -> deactivated.

  • median_filt_shape ((2, ) numpy.ndarray, tuple, or array, optional) – Shape of the median filter window. Default is None -> deactivated.

  • padding_mode (str in numpy.pad's mode list, optional) –

    Padding mode, which determines the type of convolution. If None or ‘wrap’ are passed, this resorts to the traditional circular convolution. If ‘edge’ or ‘constant’ are passed, it results in a linear convolution. Default is the circular convolution. All options are:

    None | ‘constant’ | ‘edge’ | ‘linear_ramp’ | ‘maximum’ | ‘mean’ | ‘median’ | ‘minimum’ | ‘reflect’ | ‘symmetric’ |’wrap’

  • peak_fit_radius (int, optional) – Radius size around the max correlation pixel, for sub-pixel fitting. Minimum and default value is 1.

  • low_pass (float or sequence of two floats) – Low-pass filter properties, as described in nabu.misc.fourier_filters.

  • high_pass (float or sequence of two floats) – High-pass filter properties, as described in nabu.misc.fourier_filters.

Returns:

  • focus_pos (float) – Estimated position of the focal plane of the camera system.

  • focus_ind (float) – Image index of the estimated position of the focal plane of the camera system (starting from 1!).

Examples

Given the focal stack associated to multiple positions of the camera focus motor called img_stack, and the associated positions img_pos, the following code computes the highest focus position:

>>> focus_calc = alignment.CameraFocus()
... focus_pos, focus_ind = focus_calc.find_distance(img_stack, img_pos)

where focus_pos is the corresponding motor position, and focus_ind is the associated image position (starting from 1).

find_scintillator_tilt(img_stack: ndarray, img_pos: array, regions_number=4, metric='std', roi_yxhw=None, median_filt_shape=None, padding_mode=None, peak_fit_radius=1, high_pass=None, low_pass=None)[source]

Finds the scintillator tilt and focal distance of the camera system.

This routine computes the mounting tilt of the scintillator and the motor position that corresponds to having the scintillator on the focal plain of the camera system.

The input is supposed to be a stack of square images, whose sizes are multiples of the regions_number parameter. If images with a different size are passed, this function will crop the images. This also generates a warning. To suppress the warning, it is suggested to specify a ROI that satisfies those criteria (see examples).

The computed tilts tilt_vh are in unit-length per pixel-size. To obtain the tilts it is necessary to divide by the pixel-size:

>>> tilt_vh_deg = np.rad2deg(np.arctan(tilt_vh / pixel_size))

The correction to be applied is:

>>> tilt_corr_vh_deg = - np.rad2deg(np.arctan(tilt_vh / pixel_size))

The legacy octave macros computed the approximation of these values in radians:

>>> tilt_corr_vh_rad = - tilt_vh / pixel_size

Note that pixel_size should be in the same unit scale as img_pos.

Parameters:
  • img_stack (numpy.ndarray) – A stack of images at different distances.

  • img_pos (numpy.ndarray) – Position of the images along the translation axis

  • regions_number (int, optional) – The number of regions to subdivide the image into, along each direction. Defaults to 4.

  • metric (string, optional) – The property, whose maximize occurs at the focal position. Defaults to ‘std’ (standard deviation). All options are: ‘std’ | ‘grad’ | ‘psd’

  • roi_yxhw ((2, ) or (4, ) numpy.ndarray, tuple, or array, optional) – 4 elements vector containing: vertical and horizontal coordinates of first pixel, plus height and width of the Region of Interest (RoI). Or a 2 elements vector containing: plus height and width of the centered Region of Interest (RoI). Default is None -> auto-suggest correct size.

  • median_filt_shape ((2, ) numpy.ndarray, tuple, or array, optional) – Shape of the median filter window. Default is None -> deactivated.

  • padding_mode (str in numpy.pad's mode list, optional) –

    Padding mode, which determines the type of convolution. If None or ‘wrap’ are passed, this resorts to the traditional circular convolution. If ‘edge’ or ‘constant’ are passed, it results in a linear convolution. Default is the circular convolution. All options are:

    None | ‘constant’ | ‘edge’ | ‘linear_ramp’ | ‘maximum’ | ‘mean’ | ‘median’ | ‘minimum’ | ‘reflect’ | ‘symmetric’ |’wrap’

  • peak_fit_radius (int, optional) – Radius size around the max correlation pixel, for sub-pixel fitting. Minimum and default value is 1.

  • low_pass (float or sequence of two floats) – Low-pass filter properties, as described in nabu.misc.fourier_filters.

  • high_pass (float or sequence of two floats) – High-pass filter properties, as described in nabu.misc.fourier_filters.

Returns:

  • focus_pos (float) – Estimated position of the focal plane of the camera system.

  • focus_ind (float) – Image index of the estimated position of the focal plane of the camera system (starting from 1!).

  • tilts_vh (tuple(float, float)) – Estimated scintillator tilts in the vertical and horizontal direction respectively per unit-length per pixel-size.

Examples

Given the focal stack associated to multiple positions of the camera focus motor called img_stack, and the associated positions img_pos, the following code computes the highest focus position:

>>> focus_calc = alignment.CameraFocus()
... focus_pos, focus_ind, tilts_vh = focus_calc.find_scintillator_tilt(img_stack, img_pos)
... tilt_corr_vh_deg = - np.rad2deg(np.arctan(tilt_vh / pixel_size))

or to keep compatibility with the old octave macros:

>>> tilt_corr_vh_rad = - tilt_vh / pixel_size

For non square images, or images with sizes that are not multiples of the regions_number parameter, and no ROI is being passed, this function will try to crop the image stack to the correct size. If you want to remove the warning message, it is suggested to set a ROI like the following:

>>> regions_number = 4
... img_roi = (np.array(img_stack.shape[1:]) // regions_number) * regions_number
... img_roi = np.fmin(img_roi, img_roi.min())
... focus_calc = alignment.CameraFocus()
... focus_pos, focus_ind, tilts_vh = focus_calc.find_scintillator_tilt(
...     img_stack, img_pos, roi_yxhw=img_roi, regions_number=regions_number)