Files
Jungfraujoch/jungfrau/JFPedestalCalc.cpp

89 lines
3.0 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include "JFPedestalCalc.h"
#include "../common/JFJochException.h"
JFPedestalCalc::JFPedestalCalc(const DiffractionExperiment & experiment, int64_t in_lines, int64_t in_line0) {
if ((in_lines <= 0) || (in_line0 < 0) || (in_lines + in_line0 > RAW_MODULE_LINES))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in lines number");
lines = in_lines;
line0 = in_line0;
currPedestal.resize(RAW_MODULE_COLS*lines, 0);
wrongCount.resize(RAW_MODULE_COLS*lines, 0);
switch (experiment.GetDetectorMode()) {
case DetectorMode::PedestalG1:
gain_level = 1;
break;
case DetectorMode::PedestalG2:
gain_level = 2;
break;
default:
gain_level = 0;
break;
}
}
template <unsigned int GAIN_BIT> void JFPedestalCalc::AnalyzeImage(const uint16_t *raw_image) {
if (image_number < window_size) {
for (int i = 0; i < lines * RAW_MODULE_COLS; i++) {
uint16_t adc = raw_image[i + line0 * RAW_MODULE_COLS] & 0x3FFF;
uint16_t gain = raw_image[i + line0 * RAW_MODULE_COLS] & 0xC000;
if (gain != GAIN_BIT)
wrongCount[i] ++;
currPedestal[i] += adc;
}
} else {
for (int i = 0; i < lines * RAW_MODULE_COLS; i++) {
uint16_t adc = raw_image[i + line0 * RAW_MODULE_COLS] & 0x3FFF;
uint16_t gain = raw_image[i + line0 * RAW_MODULE_COLS] & 0xC000;
if (gain != GAIN_BIT)
wrongCount[i]++;
else {
// Don't include wrong gains into moving average
currPedestal[i] += adc - currPedestal[i] / window_size;
}
}
}
}
void JFPedestalCalc::AnalyzeImage(const uint16_t *raw_image) {
switch (gain_level) {
case 0:
AnalyzeImage<0>(raw_image);
break;
case 1:
AnalyzeImage<0x4000>(raw_image);
break;
case 2:
AnalyzeImage<0xc000>(raw_image);
break;
default:
break;
}
image_number++;
}
void JFPedestalCalc::Export(JFModulePedestal &calibration, size_t allowed_wrong_gains) {
auto calib_mask = calibration.GetPedestalMask();
auto calib_pedestal = calibration.GetPedestal();
for (int i = 0; i < lines * RAW_MODULE_COLS; i++) {
float tmp = currPedestal[i] / window_size;
// Minimally, full window size needs to be recorded to give viable pedestal
if ((image_number < window_size) || (wrongCount[i] > allowed_wrong_gains)) {
calib_mask[i + line0 * RAW_MODULE_COLS] |= 1U << (gain_level + 1);
calib_pedestal[i + line0 * RAW_MODULE_COLS] = 16384;
} else {
calib_mask[i + line0 * RAW_MODULE_COLS] &= ~(1U << (gain_level + 1));
calib_pedestal[i + line0 * RAW_MODULE_COLS] = static_cast<uint16_t>(std::lround(tmp));
}
}
}