BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnGemRaw2Digit.cxx
Go to the documentation of this file.
1#include "BmnGemRaw2Digit.h"
2
3#include "TH1F.h"
4// Boost
5#include <boost/program_options.hpp>
6// BmnRoot
7#include <BmnADCDigit.h>
8#include <BmnGemStripDigit.h>
9#include <BmnRawDataDecoder.h>
10#include <UniDetectorParameter.h>
11
12namespace po = boost::program_options;
13
14BmnGemRaw2Digit::BmnGemRaw2Digit(Int_t period, Int_t run, TString mapFileName, BmnSetup bmnSetup)
15 : BmnAdcProcessor(period, run, "GEM", ADC_N_CHANNELS, ADC32_N_SAMPLES, bmnSetup)
17 , fMapFileName(mapFileName)
18{
21
22 Byte_t nMods = 4;
23 fBigHot.resize(nMods);
24 fBig.resize(nMods);
25
26 if ((fPeriod >= 8) && (fSetup != kSRCSETUP)) {
27 ReadLocalMap("X0_Bottom_Left.txt", fBigHot[2], 2, 2);
28 ReadLocalMap("X0_Bottom_Right.txt", fBigHot[3], 2, 3);
29 ReadLocalMap("X_Bottom_Left.txt", fBig[2], 0, 2);
30 ReadLocalMap("X_Bottom_Right.txt", fBig[3], 0, 3);
31 ReadLocalMap("Y0_Bottom_Left.txt", fBigHot[2], 3, 2);
32 ReadLocalMap("Y0_Bottom_Right.txt", fBigHot[3], 3, 3); // 506
33 ReadLocalMap("Y_Bottom_Left.txt", fBig[2], 1, 2);
34 ReadLocalMap("Y_Bottom_Right.txt", fBig[3], 1, 3);
35
36 ReadLocalMap("X0_Top_Left.txt", fBigHot[0], 2, 0);
37 ReadLocalMap("X0_Top_Right.txt", fBigHot[1], 2, 1);
38 ReadLocalMap("X_Top_Left.txt", fBig[0], 0, 0);
39 ReadLocalMap("X_Top_Right.txt", fBig[1], 0, 1);
40 ReadLocalMap("Y0_Top_Left.txt", fBigHot[0], 3, 0);
41 ReadLocalMap("Y0_Top_Right.txt", fBigHot[1], 3, 1); // 506
42 ReadLocalMap("Y_Top_Left.txt", fBig[0], 1, 0);
43 ReadLocalMap("Y_Top_Right.txt", fBig[1], 1, 1);
44 } else {
45 ReadMap("GEM_X0_middle", fMid, 2, 0);
46 ReadMap("GEM_Y0_middle", fMid, 3, 0);
47 ReadMap("GEM_X1_middle", fMid, 0, 0);
48 ReadMap("GEM_Y1_middle", fMid, 1, 0);
49
50 ReadMap("GEM_X0_Big_Left", fBigHot[1], 2, 1);
51 ReadMap("GEM_Y0_Big_Left", fBigHot[1], 3, 1);
52 ReadMap("GEM_X1_Big_Left", fBig[1], 0, 1);
53 ReadMap("GEM_Y1_Big_Left", fBig[1], 1, 1);
54 ReadMap("GEM_X0_Big_Right", fBigHot[0], 2, 0);
55 ReadMap("GEM_Y0_Big_Right", fBigHot[0], 3, 0);
56 ReadMap("GEM_X1_Big_Right", fBig[0], 0, 0);
57 ReadMap("GEM_Y1_Big_Right", fBig[0], 1, 0);
58 }
59 ReadLocalMap("GEM_X_small.txt", fSmall, 0, 0);
60 ReadLocalMap("GEM_Y_small.txt", fSmall, 1, 0);
63}
64
65void BmnGemRaw2Digit::InitStripRanges(unique_ptr<BmnGemStripStationSet>& ss)
66{
67 for (int32_t iSt = 0; iSt < ss->GetNStations(); ++iSt) {
68 auto* st = ss->GetStation(iSt);
69 for (int32_t iMod = 0; iMod < st->GetNModules(); ++iMod) {
70 auto* mod = st->GetModule(iMod);
71 MapLayer2MaxStrip layer2MaxStrip;
72 for (int32_t iLay = 0; iLay < mod->GetNStripLayers(); ++iLay) {
73 auto& lay = mod->GetStripLayer(iLay);
74 layer2MaxStrip[iLay] = lay.GetNStrips() - 1;
75 }
76 fSM2MapMaxStrip[{iSt, iMod}] = move(layer2MaxStrip);
77 }
78 }
79}
80
82{
83 string dummy;
84 Int_t id = 0;
85 UInt_t ser = 0;
86 UInt_t ch_lo = 0;
87 UInt_t ch_hi = 0;
88 UInt_t iStation = 0;
89 UInt_t iMod = 0;
90 UInt_t zone = 0;
91 UInt_t side = 0;
92 UInt_t type = 0;
93
94 vector<string> channel_map;
95 vector<string> spec_thr;
96 Double_t final_thr = 0;
97 Double_t thr_dif = 0;
98 Int_t n_iters = 0;
99 Double_t cmod_cut = 0;
100
101 // Setup options.
102 po::options_description desc("Options");
103 desc.add_options()("CHANNEL_MAP.channels", po::value<vector<string>>(&channel_map)->multitoken(),
104 "ADC channel -> strip map")("SIGNAL_CONFIGURATION.spec_thr",
105 po::value<vector<string>>(&spec_thr)->multitoken(),
106 "ADC channel -> strip map")(
107 "SIGNAL_CONFIGURATION.Threshold", po::value<Double_t>(&final_thr)->default_value(25), "ADC final threshold")(
108 "SIGNAL_CONFIGURATION.ThresholdDif", po::value<Double_t>(&thr_dif)->default_value(10), "ADC final threshold")(
109 "SIGNAL_CONFIGURATION.NIterations", po::value<Int_t>(&n_iters)->default_value(5), "ADC final threshold")(
110 "SIGNAL_CONFIGURATION.CModCut", po::value<Double_t>(&cmod_cut)->default_value(0), "ADC final threshold");
111
112 // Load config file.
113 po::variables_map vm;
114 TString name = TString(getenv("VMCWORKDIR")) + TString("/input/") + fMapFileName;
115 LOG(info) << "Loading GEM Map: Period " << fPeriod << ", Run " << fRun << " " << name;
116 ifstream config_file(name.Data(), ifstream::in);
117 if (!config_file.is_open()) {
118 LOG(error) << "Error opening map-file (" << name << ")!";
119 return kBMNERROR;
120 }
121 po::store(po::parse_config_file(config_file, desc), vm);
122 config_file.close();
123 po::notify(vm);
124
125 // set thresholds
126 SetThreshold(final_thr, thr_dif, n_iters, cmod_cut);
127
128 // set specific thresholds
129 Int_t ch = 0;
130 Double_t thr = 0;
131 for (auto& str : spec_thr) {
132 istringstream ss(str);
133 ss >> std::hex >> ser >> std::dec >> ch >> thr;
134 fSpecThreshMap.insert(make_pair(make_pair(ser, ch), thr));
135 LOGF(debug, "Serial 0x%08X Channel %2d Threshold %3.3f", ser, ch, thr);
136 }
137
138 // set channel map
139 for (auto& str : channel_map) {
140 istringstream ss(str);
141 ss >> std::hex >> ser >> std::dec >> ch_lo >> ch_hi >> id >> side >> type >> iStation >> iMod >> zone;
142 GemMapLine* record = new GemMapLine();
143 record->Ch_hi = ch_hi / GetNSamples();
144 record->Serial = ser;
145 record->Ch_lo = ch_lo / GetNSamples();
146 record->Station = iStation;
147 record->Zone = zone;
148 record->GEM_id = id;
149 record->Side = side;
150 record->Type = type;
151 record->Module = iMod;
152 // adjust channel shifts
153 if (record->Module > 1)
154 record->Side += 2;
155 if (record->GEM_id < 5) {
156 if (record->GEM_id < 0) { // small GEM
157 record->Channel_shift = -512;
158 record->Map_arr_ptr = &fSmall;
159 } else {
160 record->Map_arr_ptr = &fMid;
161 if ((record->Ch_hi - record->Ch_lo) < 128 / GetNSamples())
162 record->Channel_shift = 2048 - record->Ch_lo * GetNSamples();
163 }
164 } else {
165 if (record->Zone == 0) { // hot zone
166 record->Channel_shift = (record->Ch_lo == 0) ? 0 : -1024;
167 if (fPeriod < 8)
168 record->Channel_shift += 1024;
169 // For 6-7 run
170 // Int_t chShift = (gemM->Ch_lo == 0) ? 1024 : 0;
171 record->Map_arr_ptr = &fBigHot[record->Side];
172 } else { // big zone
173 record->Map_arr_ptr = &fBig[record->Side];
174 if ((record->Ch_hi - record->Ch_lo) < 128 / GetNSamples())
175 record->Channel_shift = 2048 - record->Ch_lo * GetNSamples();
176 }
177 }
178 GrabNewSerial(ser);
179 auto it = fOuterMap.find(ser);
180 if (it == fOuterMap.end()) { // create inner channel map for the serial
181 InChanMap inner;
182 inner.insert(make_pair(record->Ch_lo - 1, nullptr));
183 inner.insert(make_pair(record->Ch_hi, record));
184 fOuterMap.insert(make_pair(ser, move(inner)));
185 } else { // add range to the existing inner channel map
186 InChanMap& inner = it->second;
187 auto innerItHi = inner.find(record->Ch_hi);
188 auto innerItLo = inner.find(record->Ch_lo - 1);
189 if (innerItHi == inner.end())
190 inner.insert(make_pair(record->Ch_hi, record));
191 else if (innerItHi->second == nullptr) {
192 inner.erase(innerItHi);
193 inner.insert(make_pair(record->Ch_hi, record));
194 } else {
195 fprintf(stderr, "Wrong %s map! Overlapping intervals for %08X!\n", fDetName.Data(), ser);
196 return kBMNERROR;
197 }
198 if (innerItLo == inner.end())
199 inner.insert(make_pair(record->Ch_lo - 1, nullptr));
200 }
201 }
202 return kBMNSUCCESS;
203}
204
206{
207 TString name = TString(getenv("VMCWORKDIR")) + TString("/input/") + FileName;
208 // printf("%s\n", name.Data());
209 ifstream inFile(name.Data());
210 if (!inFile.is_open()) {
211 LOG(error) << "Error opening map-file (" << name << ")!";
212 return kBMNERROR;
213 }
214
215 Int_t iStrip = 0;
216 Int_t chan = 0;
217 while (inFile >> chan) {
218 m[chan] = BmnGemMap(iStrip++, lay, mod);
219 // printf("\t\t strip %4d lay %4d mod %4d chan %4d\n", iStrip, lay, mod, chan);
220 }
221
222 return kBMNSUCCESS;
223}
224
226{
227 // Int_t size = 0;
229 vector<UniValue*> iiArr;
230 if (par != NULL)
231 par->GetValue(iiArr);
232 delete par;
233 // printf("%20s mod %d lay %d\n", parName.Data(), mod, lay);
234 for (size_t i = 0; i < iiArr.size(); ++i) {
235 IIValue* pValue = (IIValue*)iiArr[i];
236 m[pValue->value2] = BmnGemMap(pValue->value1 - 1, lay, mod); // Strip begins from 0
237 // printf("\t\t strip %4d lay %4d mod %4d chan %4d %s\n", pValue->value1, lay, mod, pValue->value2,
238 // (pValue->value1 == 0) ? "WFT!!!" : "");
239 }
240
241 if (!iiArr.empty())
242 for (size_t i = 0; i < iiArr.size(); i++)
243 delete iiArr[i];
244 return kBMNSUCCESS;
245}
246
248{
249 for (auto& it : fOuterMap)
250 for (auto& inner : it.second)
251 delete inner.second;
253}
254
256{
257 (this->*PrecalcEventModsImp)(adc);
258#ifdef BUILD_DEBUG
260#else
262#endif
263 ProcessAdc(nullptr, kTRUE);
264 return kBMNSUCCESS;
265}
266
268{
269 const Int_t kNStripsInBunch = BmnRawDataDecoder::samplesGem;
270 // cout << "GEM: " << kNStripsInBunch << endl;
271 // const Int_t kNBunches = kNStrips / kNStripsInBunch;
272 const double kNThresh = BmnRawDataDecoder::threshGem;
273
274 for (size_t iCr = 0; iCr < GetNSerials(); ++iCr) {
275 auto it = fOuterMap.find(GetSerials()[iCr]);
276 if (it == fOuterMap.end())
277 continue;
278 for (uint16_t iCh = 0; iCh < GetNChannels(); ++iCh) {
279 InChanMap& inner = it->second;
280 auto innerIt = inner.lower_bound(iCh);
281 if (innerIt == inner.end())
282 continue;
283 GemMapLine* rec = innerIt->second;
284 if (!rec)
285 continue;
286 Int_t iStation = rec->Station;
287 Int_t iMod = rec->Module;
288 MapLayer2MaxStrip& layer2MaxStrip = fSM2MapMaxStrip[{iStation, iMod}];
289 for (Int_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl)
290 if (GetNoisyChipChannels()[iCr][iCh][iSmpl] == kTRUE) {
291 Int_t strip = -1;
292 Int_t iLayer = -1;
293 MapStrip(rec, iCh, iSmpl, iLayer, strip);
294 // check range violation
295 if (strip < 0)
296 continue;
297 if (strip > layer2MaxStrip[iLayer]) {
298 LOGF(debug2,
299 "fNoisyChannels strip outside range!\n\t"
300 " Station: %d, Module: %2d, Layer: %2d iStrip: %d set true",
301 iStation, iMod, iLayer, strip);
302 LOGF(debug2, "lay : [%3d, %3d]", 0, layer2MaxStrip[iLayer]);
303 continue;
304 }
305 fNoisyChannels[iStation][iMod][iLayer][strip] = kTRUE;
306 }
307 // }
308 }
309 }
310 LOGF(debug, "Chip noise channels to strip finished");
311 for (Int_t iSt = 0; iSt < fGemStationSet->GetNStations(); ++iSt) {
312 if ((iSt == 7) && (fPeriod == 9)) // crutch to avoid marking strips on the beam noisy
313 continue;
314 auto* st = fGemStationSet->GetStation(iSt);
315 for (Int_t iMod = 0; iMod < st->GetNModules(); ++iMod) {
316 auto* mod = st->GetModule(iMod);
317 for (Int_t iLay = 0; iLay < mod->GetNStripLayers(); ++iLay) {
318 TH1F* prof = fSigProf[iSt][iMod][iLay];
319 auto& lay = mod->GetStripLayer(iLay);
320 Int_t kNBunches = lay.GetNStrips() / kNStripsInBunch;
321 for (Int_t iBunch = 0; iBunch < kNBunches; ++iBunch) {
322 Double_t mean = 0.0;
323 for (Int_t iStrip = 0; iStrip < kNStripsInBunch; ++iStrip) {
324 Int_t strip = iStrip + iBunch * kNStripsInBunch;
325 if (fNoisyChannels[iSt][iMod][iLay][strip] == kTRUE)
326 continue;
327 Double_t curr = prof->GetBinContent(strip + 1);
328 // Double_t prev = prof->GetBinContent(strip);
329 mean += curr;
330 }
331 mean /= kNStripsInBunch;
332 for (Int_t iStrip = 0; iStrip < kNStripsInBunch; ++iStrip) {
333 Int_t strip = iStrip + iBunch * kNStripsInBunch;
334 if (fNoisyChannels[iSt][iMod][iLay][strip] == kTRUE)
335 continue;
336 Double_t curr = prof->GetBinContent(strip + 1);
337 // Double_t prev = prof->GetBinContent(strip);
338 // if (kNThresh * meanDiff < curr - prev)
339 if (kNThresh * mean < Abs(curr - mean))
340 fNoisyChannels[iSt][iMod][iLay][strip] = kTRUE;
341 }
342 }
343 }
344 }
345 }
346 LOGF(debug, "Marking noisy strips finished");
347 for (size_t iCr = 0; iCr < GetNSerials(); ++iCr) {
348 auto it = fOuterMap.find(GetSerials()[iCr]);
349 if (it == fOuterMap.end())
350 continue;
351 for (uint16_t iCh = 0; iCh < GetNChannels(); ++iCh) {
352 InChanMap& inner = it->second;
353 auto innerIt = inner.lower_bound(iCh);
354 if (innerIt == inner.end())
355 continue;
356 GemMapLine* rec = innerIt->second;
357 if (!rec)
358 continue;
359 Int_t iStation = rec->Station;
360 Int_t iMod = rec->Module;
361 MapLayer2MaxStrip& layer2MaxStrip = fSM2MapMaxStrip[{iStation, iMod}];
362 for (Int_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl) {
363 Int_t strip = -1;
364 Int_t iLayer = -1;
365 MapStrip(rec, iCh, iSmpl, iLayer, strip);
366 // check range violation
367 if (strip < 0)
368 continue;
369 if (strip > layer2MaxStrip[iLayer]) {
370 LOGF(debug2,
371 "fNoisyChannels strip outside range!\n\t"
372 " Station: %d, Module: %2d, Layer: %2d iStrip: %d set true back",
373 iStation, iMod, iLayer, strip);
374 LOGF(debug2, "lay : [%3d, %3d]", 0, layer2MaxStrip[iLayer]);
375 continue;
376 }
377 if (fNoisyChannels[iStation][iMod][iLayer][strip] == kTRUE)
378 GetNoisyChipChannels()[iCr][iCh][iSmpl] = kTRUE;
379 }
380 }
381 }
382 LOGF(debug, "noisy strips to chips finished");
383 return kBMNSUCCESS;
384}
385
387{
388 for (size_t iCr = 0; iCr < GetNSerials(); ++iCr) {
389 auto it = fOuterMap.find(GetSerials()[iCr]);
390 if (it == fOuterMap.end())
391 continue;
392 // LOGF(info, "cr[%2lu] = 0x08X found", iCr, GetSerials()[iCr]);
393 for (uint16_t iCh = 0; iCh < fNChannels; ++iCh) {
394 auto innerIt = it->second.lower_bound(iCh);
395 if (innerIt == it->second.end())
396 continue;
397 GemMapLine* rec = innerIt->second;
398 if (!rec)
399 continue;
400 Int_t iStation = rec->Station;
401 Int_t iMod = rec->Module;
402 MapLayer2MaxStrip& layer2MaxStrip = fSM2MapMaxStrip[{iStation, iMod}];
403 for (Int_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl) {
404 if (GetNoisyChipChannels()[iCr][iCh][iSmpl] == kTRUE)
405 continue;
406 Int_t strip = -1;
407 Int_t iLayer = -1;
408 MapStrip(rec, iCh, iSmpl, iLayer, strip);
409 // cout << "DECODER INFO: " << station << " " << mod << " " << layer << " " << strip << endl;
410 if ((strip < 0) || (strip > layer2MaxStrip[iLayer])) {
411 LOGF(debug2,
412 "fNoisyChannels strip outside range!\n\t"
413 " Station: %d, Module: %2d, Layer: %2d iStrip: %d digi add",
414 iStation, iMod, iLayer, strip);
415 LOGF(debug2, "info : [%3d, %3d]", 0, layer2MaxStrip[iLayer]);
416 continue;
417 }
418
419 Double_t sig = fAdc[iCr][iCh][iSmpl] - fPedVal[iCr][iCh][iSmpl] + fCMode[iCr][iCh] - fSMode[iCr][iCh];
420 // Double_t Asig = TMath::Abs(sig);
421 Double_t SpecThr(0);
422 auto itThr = fSpecThreshMap.find(make_pair(GetSerials()[iCr], iCh));
423 if (itThr != fSpecThreshMap.end())
424 SpecThr = itThr->second;
425
426 Double_t thr = Max(FinalThr, 3.5 * GetPedestalsRMS()[iCr][iCh][iSmpl]);
427 thr = Max(thr, SpecThr);
428 if ((!GetApplyThreshold()) || (sig > thr)) {
429 if (doFill /* && (Abs(fCMode[iCr][iCh] - fSMode[iCr][iCh]) < cmodcut)*/) {
430 fSigProf[iStation][iMod][iLayer]->Fill(strip);
431 } else {
432 BmnGemStripDigit* resDig = new ((*gem)[gem->GetEntriesFast()])
433 BmnGemStripDigit(iStation, iMod, iLayer, strip, sig, GetPedestalsRMS()[iCr][iCh][iSmpl]);
434 // if ((Abs(fCMode[iCr][iCh] - fSMode[iCr][iCh]) >
435 // cmodcut))
436 // resDig->SetIsGoodDigit(kFALSE);
437 // else
438 resDig->SetIsGoodDigit(kTRUE);
439 }
440 }
441 }
442 }
443 }
444}
445
447{
448 (this->*PrecalcEventModsImp)(adc);
449#ifdef BUILD_DEBUG
451#else
453#endif
454 ProcessAdc(gem, kFALSE);
455 return kBMNSUCCESS;
456}
457
458inline void BmnGemRaw2Digit::MapStrip(GemMapLine* gemM, UInt_t ch, Int_t iSmpl, Int_t& lay, Int_t& strip)
459{
460 size_t realChannel = ch * GetNSamples() + iSmpl + gemM->Channel_shift;
461 lay = (*gemM->Map_arr_ptr)[realChannel].lay;
462 strip = (*gemM->Map_arr_ptr)[realChannel].strip;
463 return;
464}
int i
Definition P4_F32vec4.h:22
__m128 m
Definition P4_F32vec4.h:27
bool Bool_t
int Int_t
unsigned char Byte_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
BmnStatus
Define status code.
Definition BmnEnums.h:93
@ kBMNERROR
Error.
Definition BmnEnums.h:95
@ kBMNSUCCESS
Success.
Definition BmnEnums.h:94
@ kSRCSETUP
Definition BmnEnums.h:167
void DeleteStripNoiseArrays(SST &ss)
void InitStripNoiseArrays(SST &ss)
uint32_t GetPeriod()
map< PlMapKey, Double_t > fSpecThreshMap
Double_t *** GetPedestalsRMS()
BmnAdcProcessor(uint32_t period, uint32_t run, TString det, uint16_t nCh, const uint16_t nSmpl, BmnSetup setup=kBMNSETUP)
void SetThreshold(Double_t final_thr, Double_t thr_dif=-1, Double_t n_iters=-1, Double_t cmod_cut=-1)
Float_t *** fPedVal
Bool_t **** fNoisyChannels
const uint16_t fNChannels
void GrabNewSerial(UInt_t serial)
const uint16_t GetNChannels()
const uint16_t GetNSamples()
Bool_t *** GetNoisyChipChannels()
void(BmnAdcProcessor::* PrecalcEventModsImp)(TClonesArray *adc)
vector< uint32_t > & GetSerials()
std::array< BmnGemMap, N_CH_BUF > StripMapArray
StripMapArray fMid
map< uint8_t, int32_t > MapLayer2MaxStrip
map< int32_t, GemMapLine * > InChanMap
void ProcessAdc(TClonesArray *silicon, Bool_t doFill)
Uses raw ADC data to either fill profile histograms or produce output digits.
BmnStatus FillEvent(TClonesArray *adc, TClonesArray *gem)
BmnGemRaw2Digit(Int_t period, Int_t run, TString mapFileName, BmnSetup bmnSetup=kBMNSETUP)
BmnStatus ReadGlobalMap(TString FileName)
void MapStrip(GemMapLine *gemM, UInt_t ch, Int_t iSmpl, Int_t &lay, Int_t &strip)
vector< StripMapArray > fBig
vector< StripMapArray > fBigHot
BmnStatus FillNoisyChannels()
BmnStatus ReadMap(TString parName, StripMapArray &m, Int_t lay, Int_t mod)
unordered_map< uint32_t, InChanMap > fOuterMap
BmnStatus ReadLocalMap(TString parName, StripMapArray &m, Int_t lay, Int_t mod)
BmnStatus FillProfiles(TClonesArray *adc)
StripMapArray fSmall
map< KeySM, MapLayer2MaxStrip > fSM2MapMaxStrip
unique_ptr< BmnGemStripStationSet > fGemStationSet
void InitStripRanges(unique_ptr< BmnGemStripStationSet > &ss)
static double threshGem
void SetIsGoodDigit(Bool_t tmp)
virtual Double_t GetBinContent(Int_t bin) const
Int_t GetEntriesFast() const
const char * Data() const
int GetValue(vector< UniValue * > &parameter_value)
get value of detector parameter presented by an array
static UniDetectorParameter * GetDetectorParameter(int value_id)
get detector parameter from the database
#define ADC_N_CHANNELS
#define ADC32_N_SAMPLES
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)