BmnRoot
Loading...
Searching...
No Matches
BmnFHCalRaw2Digit.cxx
Go to the documentation of this file.
1#include "BmnFHCalRaw2Digit.h"
2
3#include "TMath.h"
4#include "TSystem.h"
5
6#include <bitset>
7
9{
10 LOG(info) << Form("BmnFHCalRaw2Digit");
11}
12
14 : WfmProcessor()
15{
16 fPeriodId = 0;
17 fRunId = 0;
18}
19
20BmnFHCalRaw2Digit::BmnFHCalRaw2Digit(int period, int run, TString mappingFile, TString CalibrationFile)
21 : WfmProcessor()
22{
23 LOG(info) << Form("BmnFHCalRaw2Digit : Config file: %s", mappingFile.Data());
24 LOG(info) << Form("BmnFHCalRaw2Digit : Calibration file: %s", CalibrationFile.Data());
25 fPeriodId = period;
26 fRunId = run;
27 fmappingFileName = mappingFile;
28 ParseConfig(fmappingFileName);
29 fcalibrationFileName = CalibrationFile;
30 ParseCalibration(fcalibrationFileName);
31}
32
33void BmnFHCalRaw2Digit::ParseConfig(TString mappingFile)
34{
35
36 namespace po = boost::program_options;
37
38 TString dir = getenv("VMCWORKDIR");
39 TString path = dir + "/input/";
40
41 float version;
42 std::string comment;
43 std::vector<std::string> configuration;
44
45 // Setup options.
46 po::options_description desc("Options");
47 desc.add_options()("VERSION.id", po::value<float>(&version),
48 "version identificator")("COMMENT.str", po::value<std::string>(&comment), "comment")(
49 "CONFIGURATION.config", po::value<std::vector<std::string>>(&configuration)->multitoken(), "configuration");
50
51 // Load config file.
52 po::variables_map vm;
53 std::ifstream config_file((path + mappingFile).Data(), std::ifstream::in);
54 if (!config_file.is_open()) {
55 LOG(error) << Form("BmnFHCalRaw2Digit : Loading Config from file: %s - file open error!", mappingFile.Data());
56 return;
57 }
58 LOG(debug) << Form("BmnFHCalRaw2Digit : Loading Config from file: %s", mappingFile.Data());
59 po::store(po::parse_config_file(config_file, desc), vm);
60 config_file.close();
61 po::notify(vm);
62
63 std::string board_serial;
64 size_t board_channel;
65 int module_type;
66 int module_id;
67 int section_id;
68
69 fuoChannelMap.clear();
70 for (auto it : configuration) {
71 istringstream ss(it);
72 ss >> board_serial >> board_channel >> module_type >> module_id >> section_id;
73
74 auto key = std::make_pair(std::stoul(board_serial, nullptr, 16), board_channel);
75 uint32_t address = (module_type == 0) ? 0 : BmnFHCalAddress::GetAddress(module_type, module_id, section_id);
76 fuoChannelMap[key] = address;
77 }
78 // std::LOG(debug) << "COMMENT.str: " << comment;
79}
80
81void BmnFHCalRaw2Digit::ParseCalibration(TString calibrationFile)
82{
83
84 namespace po = boost::program_options;
85
86 TString dir = getenv("VMCWORKDIR");
87 TString path = dir + "/parameters/fhcal/";
88
89 float version;
90 std::string comment;
91 std::vector<std::string> harmonics;
92 std::vector<std::string> calibrations;
93
94 // Setup options.
95 po::options_description desc("Options");
96 desc.add_options()("VERSION.id", po::value<float>(&version),
97 "version identificator")("COMMENT.str", po::value<std::string>(&comment), "comment")(
98 "CHECKER.isWriteWfm", po::value<bool>(&fdigiPars.isWriteWfm),
99 "writing waveforms")("PARAMETERS.gateBegin", po::value<int>(&fdigiPars.gateBegin), "digi parameters")(
100 "PARAMETERS.gateEnd", po::value<int>(&fdigiPars.gateEnd),
101 "digi parameters")("PARAMETERS.threshold", po::value<float>(&fdigiPars.threshold), "digi parameters")(
102 "PARAMETERS.signalType", po::value<int>(&fdigiPars.signalType),
103 "digi parameters")("PARAMETERS.doInvert", po::value<bool>(&fdigiPars.doInvert), "digi parameters")(
104 "FITPARAMETERS.isfit", po::value<bool>(&fdigiPars.isfit), "digi parameters")(
105 "FITPARAMETERS.harmonic", po::value<std::vector<std::string>>(&harmonics)->multitoken(), "fit harmonics")(
106 "CALIBRATION.calib", po::value<std::vector<std::string>>(&calibrations)->multitoken(), "calibrations");
107
108 // Load config file.
109 po::variables_map vm;
110 std::ifstream calib_file((path + calibrationFile).Data(), std::ifstream::in);
111 if (!calib_file.is_open()) {
112 LOG(error) << Form("BmnFHCalRaw2Digit : Loading Calibration from file: %s - file open error!",
113 calibrationFile.Data());
114 return;
115 }
116 LOG(debug) << Form("BmnFHCalRaw2Digit : Loading Calibration from file: %s", calibrationFile.Data());
117 po::store(po::parse_config_file(calib_file, desc), vm);
118 calib_file.close();
119 po::notify(vm);
120
121 for (auto str : harmonics) {
122 if (str.find(',') != std::string::npos) {
123 // Split the string into real and imaginary parts
124 std::string real_part_str, imaginary_part_str;
125 std::istringstream iss(str);
126 std::getline(iss, real_part_str, ',');
127 std::getline(iss, imaginary_part_str);
128
129 // Convert the real and imaginary parts to floats
130 float real_part = std::stof(real_part_str);
131 float imaginary_part = std::stof(imaginary_part_str);
132
133 // Set the value to the complex number
134 fdigiPars.harmonics.push_back(std::complex<float>(real_part, imaginary_part));
135 } else
136 fdigiPars.harmonics.push_back(std::stof(str));
137 }
138
139 uint32_t mod_id;
140 uint32_t sec_id;
141 float calibration;
142 float calibError;
143 fuoCalibMap.clear();
144 for (auto it : calibrations) {
145 istringstream ss(it);
146 ss >> mod_id >> sec_id >> calibration >> calibError;
147 for (auto addrMap : GetChannelMap()) {
148 uint32_t address = addrMap.second;
149 if (mod_id == BmnFHCalAddress::GetModuleId(address) && sec_id == BmnFHCalAddress::GetSectionId(address)) {
150 fuoCalibMap[address] = std::make_pair(calibration, calibError);
151 }
152 }
153 }
154
155 if (fdigiPars.isfit) {
156 int model_order = fdigiPars.harmonics.size() + 1;
158 auto maxElement = std::max_element(
159 fdigiPars.harmonics.begin(), fdigiPars.harmonics.end(),
160 [](const std::complex<float>& a, const std::complex<float>& b) { return std::abs(a) < std::abs(b); });
161 if (maxElement != fdigiPars.harmonics.end()) {
162 // set signal length as 5 * harmonic length
163 int maxElementLength = floor(5. / (-log(real(*maxElement))));
164 if (maxElementLength < fSignalLength)
165 fSignalLength = maxElementLength;
166 }
167
168 fAZik = new std::complex<float>*[model_order];
169 for (int i = 0; i < model_order; i++) {
170 fAZik[i] = new std::complex<float>[model_order];
171 for (int j = 0; j < model_order; j++)
172 fAZik[i][j] = {0., 0.};
173 }
179 }
180}
181
182std::optional<uint32_t> BmnFHCalRaw2Digit::GetAddressFromBoard(std::pair<size_t, size_t> key)
183{
184 try {
185 return fuoChannelMap.at(key);
186 } catch (const std::out_of_range& e) {
187 LOG(debug) << "BmnFHCalRaw2Digit:: GetAddressFromBoard. Board serial " << std::hex << key.first << std::dec
188 << " channel " << key.second << " is not connected. Skipping it";
189 return std::nullopt;
190 }
191}
192
193std::optional<std::pair<float, float>> BmnFHCalRaw2Digit::GetCalibPairFromAddress(uint32_t address)
194{
195 try {
196 return fuoCalibMap.at(address);
197 } catch (const std::out_of_range& e) {
198 LOG(debug) << "BmnFHCalRaw2Digit:: GetCalibPairFromAddress " << std::bitset<32>(address)
199 << " is marked badly in calibration file.";
200 return std::nullopt;
201 }
202}
203
204void BmnFHCalRaw2Digit::fillEvent(TClonesArray* data, TClonesArray* FHCaldigit)
205{
206 LOG(debug) << "BmnFHCalRaw2Digit::fillEvent";
207
208 for (int i = 0; i < data->GetEntriesFast(); i++) {
209 BmnADCDigit* digit = (BmnADCDigit*)data->At(i);
210 auto key = std::make_pair(digit->GetSerial(), digit->GetChannel());
211 auto catch_address = GetAddressFromBoard(key);
212 if (!catch_address.has_value())
213 continue; // Not connected lines
214 auto address = catch_address.value();
215 if (address == 0)
216 continue; // Not connected lines
217
218 auto catch_calib = GetCalibPairFromAddress(address);
219 if (!catch_calib.has_value())
220 continue; // not involved in the analysis
221 auto calib_pair = catch_calib.value();
222
223 std::vector<float> wfm((short*)digit->GetUShortValue(), (short*)digit->GetUShortValue() + digit->GetNSamples());
224 BmnFHCalDigi ThisDigi;
225 ThisDigi.reset();
226 ThisDigi.SetAddress(address);
227 ProcessWfm(wfm, &ThisDigi);
228
229 // Apply calibration
230 LOG(debug4) << "BmnFHCalRaw2Digit::ProcessWfm Calibration";
231 if (fdigiPars.signalType == 0)
232 ThisDigi.SetSignal((float)ThisDigi.fAmpl * calib_pair.first);
233 if (fdigiPars.signalType == 1)
234 ThisDigi.SetSignal((float)ThisDigi.fIntegral * calib_pair.first);
235 if (ThisDigi.GetSignal() < fdigiPars.threshold)
236 continue;
237
238 TClonesArray& ar_FHCal = *FHCaldigit;
239 new (ar_FHCal[FHCaldigit->GetEntriesFast()]) BmnFHCalDigi(ThisDigi);
240 }
241}
242
int i
Definition P4_F32vec4.h:22
friend F32vec4 log(const F32vec4 &a)
Definition P4_F32vec4.h:123
UInt_t GetNSamples() const
Definition BmnADCDigit.h:35
UShort_t GetChannel() const
Definition BmnADCDigit.h:33
UInt_t GetSerial() const
Definition BmnADCDigit.h:31
UShort_t * GetUShortValue() const
Definition BmnADCDigit.h:37
void SetAddress(uint32_t address)
double GetSignal() const
void SetSignal(double signal)
int fIntegral
ZeroLevel from waveform [adc counts].
static uint32_t GetModuleId(uint32_t address)
Return Module id from address.
static uint32_t GetSectionId(uint32_t address)
Return Section id from address.
static uint32_t GetAddress(uint32_t ModuleType, uint32_t ModuleId, uint32_t SectionId, uint32_t ScintillatorId=0)
Return address from system ID, Module type, Module ID, Section ID, Scintillator ID (optional).
Data class for Bmn FHCal digital signal processing.
void reset() override final
std::optional< uint32_t > GetAddressFromBoard(std::pair< size_t, size_t > key)
void ParseConfig(TString mappingFile)
void ParseCalibration(TString calibrationFile)
std::optional< std::pair< float, float > > GetCalibPairFromAddress(uint32_t address)
void fillEvent(TClonesArray *data, TClonesArray *FHCaldigit)
void SetExternalHarmonics(std::vector< std::complex< float > > harmonics)
void Initialize(int model_order, int exponent_number, int gate_beg, int gate_end)
void MakeInvHarmoMatrix(int signal_length, std::complex< float > **output)
std::complex< float > ** fAZik
struct WfmProcessor::digiPars fdigiPars
void ProcessWfm(std::vector< float > &wfm, BmnDigiContainerTemplate *digi)
-clang-format
std::vector< std::complex< float > > harmonics