89 lines
3.0 KiB
C++
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));
|
|
}
|
|
}
|
|
} |