Source code for daplis_rtp.functions.sen_pop

"""Module for collecting number of timestamps in each pixel.

Works with firmware versions 2212b and 2212s.

The following functions are provided.

    * sen-pop - collects the number of timestamps in each pixel for the
    data file provided and returns it as an array.

"""

import numpy as np

from daplis_rtp.functions.tdc_occupancy import slot_occupancy
from daplis_rtp.functions.unpack import unpack_bin


[docs] def sen_pop( file, board_number, fw_ver, timestamps: int = 512, pix_add_fix: bool = False, absolute_timestamps: bool = False, return_occupancy: bool = False, ): """Collect number of timestamps in each pixel. The output is used for plotting the sensor population. Works with firmware versions 2212b and 2212s. Parameters ---------- file : str Address of the data file. board_number : str LinoSPAD2 daughterboard number. fw_ver : str LinoSPAD2 firmware version, '2212b' or '2212s'. timestamps : int, optional Number of timestamps per TDC per acquisition cycle, by default 512. pix_add_fix : bool, optional Switch for correcting the pixel addressing of the sensor half, by default False. absolute_timestamps : bool, optional Indicator for data files collected with absolute timestamps, by default False. return_occupancy : bool, optional Also return how much of the TDC slot memory the file used, as an 'Occupancy'. Computed from the same unpacked matrix as the rates, so it costs no extra read of the file. By default False. Returns ------- rates : array-like Photon rate in each pixel, in Hz. occupancy : Occupancy Only when 'return_occupancy' is set: slots used per TDC per acquisition cycle. See 'daplis_rtp.functions.tdc_occupancy'. """ # 'unpack_bin' rejects any firmware version other than the two data = unpack_bin( file, board_number, fw_ver, timestamps, absolute_timestamps ) pix_coor = ( np.arange(256).reshape(4, 64).T if fw_ver == "2212s" else np.arange(256).reshape(64, 4) ) valid_per_pixel = np.zeros(256) for i in range(256): tdc, pix = np.argwhere(pix_coor == i)[0] ind = np.where(data[tdc].T[0] == pix)[0] ind1 = np.where(data[tdc].T[1][ind] > 0)[0] valid_per_pixel[i] += len(data[tdc].T[1][ind[ind1]]) if pix_add_fix is True: fix = np.zeros(len(valid_per_pixel)) fix[:128] = valid_per_pixel[128:] fix[128:] = np.flip(valid_per_pixel[:128]) valid_per_pixel = fix del fix acq_window_length = np.max(data[:].T[1]) * 1e-12 number_of_cycles = len(np.where(data[0].T[0] == -2)[0]) rates = valid_per_pixel / acq_window_length / number_of_cycles if return_occupancy: # From the matrix already in hand: one comparison per TDC, no # second pass over the file. Note that the TDC indices of the # result are the ones the board reads out, so a caller that # asked for 'pix_add_fix' must map its pixels through # 'tdc_occupancy.pixel_to_tdc_map' with the same flag. return rates, slot_occupancy(data, fw_ver, timestamps) return rates