BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnTrigRaw2Digit.cxx
Go to the documentation of this file.
1#include "BmnTrigRaw2Digit.h"
2// C++
3#include <climits>
4// Boost
5#include <boost/program_options.hpp>
6// ROOT
7#include <TStopwatch.h>
8// FairRoot
9#include <FairLogger.h>
10// BmnRoot
11#include "BmnTDCDigit.h"
12#include "BmnTQDCADCDigit.h"
13#include "BmnTrigDigit.h"
14#include "BmnTrigWaveDigit.h"
15
16namespace po = boost::program_options;
17using namespace std;
18using namespace TMath;
19
21{
22 for (UInt_t i = 0; i < CHANNEL_COUNT_MAX; i++) {
23 for (UInt_t j = 0; j < TDC_BIN_COUNT; j++)
24 INL[i][j] = 0u;
25 ChannelMap[i] = 0u;
27 branchArrayPtr[i] = NULL;
28 t[i] = 0.0;
29 }
30 IsT0 = kFALSE;
31}
32
33BmnTrigRaw2Digit::BmnTrigRaw2Digit(TString PlacementMapFile, TString StripMapFile, TTree* digiTree)
35 // , fWorkArray{}
36 , fTrcSerial(0)
37{
38 // fWorkHist->SetDirectory(0);
39 ReadPlacementMap(PlacementMapFile);
40 if (ReadChannelMap(StripMapFile) == kBMNERROR) {
41 printf("Error! Unable to read the trigger channel map!\n");
42 return;
43 }
44 if (digiTree == NULL)
45 return;
46 // Create corresponding branches for each trigger. //
47 // different channels of the one trigger will be stored //
48 // in one branch with different mod ID //
49 map<TString, TClonesArray*> brName2ptr;
50 for (BmnTrigChannelData& record : fMap) {
51 TString& detName = record.name;
52 TClass* cl = detName.Contains("TQDC") ? BmnTrigWaveDigit::Class() : BmnTrigDigit::Class();
53 auto it = brName2ptr.find(detName);
54 if (it == brName2ptr.end()) {
55 TClonesArray* ar = new TClonesArray(cl);
56 ar->SetName(detName.Data());
57 digiTree->Branch(detName.Data(), &ar);
58 trigArrays.push_back(ar);
59 record.branchArrayPtr = ar;
60 brName2ptr.insert(make_pair(detName, ar));
61 } else {
62 record.branchArrayPtr = it->second;
63 }
64 }
65 // Fill elements of placement map with channel->(strip, mod, branchRef) map //
66 for (BmnTrigChannelData& record : fMap) {
67 BmnTrigParameters* par = nullptr;
68 map<PlMapKey, BmnTrigParameters*>::iterator itPar = fPlacementMap.find(PlMapKey(record.serial, record.slot));
69 if (itPar == fPlacementMap.end()) {
70 printf("CrateSeral %08X slot %u not found in the placement map!\n", record.serial, record.slot);
71 par = new BmnTrigParameters();
72 par->BoardSerial = record.serial;
73 par->name = record.name;
74 par->ChannelCount = CHANNEL_COUNT_MAX; // ChanCntByName(record.name);
75 fPlacementMap.insert(pair<PlMapKey, BmnTrigParameters*>(PlMapKey(par->BoardSerial, par->slot), par));
76 } else
77 par = itPar->second;
78 par->ChannelMap[record.channel] = record.module;
79 par->branchArrayPtr[record.channel] = record.branchArrayPtr;
80 par->NegativeMap[record.channel] = record.isNegative;
81 }
82 for (auto& el : fPlacementMap) {
83 BmnTrigParameters* par = el.second;
84 ReadINLFromFile(par);
85 }
86}
87
88// BmnTrigRaw2Digit::BmnTrigRaw2Digit(TString PlacementMapFile, TString StripMapFile, FairRootManager* frm, bool
89// saveOutput) :
90
92 TString StripMapFile,
93 std::function<void(TString, TClonesArray*)> BranchRegFun)
95 // , fWorkHist(make_unique<TH1I>(Form("workhist_%p", this), "wh", SHRT_MAX - SHRT_MIN, SHRT_MIN, SHRT_MAX))
96 , fTrcSerial(0)
97{
98 // fWorkHist->SetDirectory(0);
99 ReadPlacementMap(PlacementMapFile);
100 if (ReadChannelMap(StripMapFile) == kBMNERROR) {
101 printf("Error! Unable to read the trigger channel map!\n");
102 return;
103 }
104 // Create corresponding branches for each trigger. //
105 // different channels of the one trigger will be stored //
106 // in one branch with different mod ID //
107 map<TString, TClonesArray*> brName2ptr;
108 for (BmnTrigChannelData& record : fMap) {
109 TString& detName = record.name;
110 TClass* cl = detName.Contains("TQDC") ? BmnTrigWaveDigit::Class() : BmnTrigDigit::Class();
111 auto it = brName2ptr.find(detName);
112 if (it == brName2ptr.end()) {
113 TClonesArray* ar = new TClonesArray(cl);
114 ar->SetName(detName.Data());
115 BranchRegFun(detName, ar);
116 // frm->Register(detName, "Trig", ar, saveOutput);
117 trigArrays.push_back(ar);
118 record.branchArrayPtr = ar;
119 brName2ptr.insert(make_pair(detName, ar));
120 } else
121 record.branchArrayPtr = it->second;
122 }
123 // Fill elements of placement map with channel->(strip, mod, branchRef) map //
124 for (BmnTrigChannelData& record : fMap) {
125 BmnTrigParameters* par = nullptr;
126 map<PlMapKey, BmnTrigParameters*>::iterator itPar = fPlacementMap.find(PlMapKey(record.serial, record.slot));
127 if (itPar == fPlacementMap.end()) {
128 printf("CrateSeral %08X slot %u not found in the placement map!\n", record.serial, record.slot);
129 par = new BmnTrigParameters();
130 par->BoardSerial = record.serial;
131 par->name = record.name;
132 par->ChannelCount = CHANNEL_COUNT_MAX; // ChanCntByName(record.name);
133 fPlacementMap.insert(pair<PlMapKey, BmnTrigParameters*>(PlMapKey(par->BoardSerial, par->slot), par));
134 } else
135 par = itPar->second;
136 par->ChannelMap[record.channel] = record.module;
137 par->branchArrayPtr[record.channel] = record.branchArrayPtr;
138 par->NegativeMap[record.channel] = record.isNegative;
139 }
140 for (auto& el : fPlacementMap) {
141 BmnTrigParameters* par = el.second;
142 ReadINLFromFile(par);
143 }
144}
145
147{
148 TString PlMapFileName = TString(getenv("VMCWORKDIR")) + TString("/input/") + mappingFile;
149 LOGF(info, "Reading Triggers placement mapping file %s...", PlMapFileName.Data());
150 ifstream pmFile;
151 pmFile.open(PlMapFileName.Data());
152 if (!pmFile.is_open()) {
153 cout << "Error opening map-file (" << PlMapFileName << ")!" << endl;
154 return kBMNERROR;
155 }
156 string dummy;
157 string name;
158 UInt_t crateSerial, boardSerial;
159 uint16_t slot;
160 uint16_t isT0;
161
162 pmFile >> dummy >> dummy >> dummy >> dummy >> dummy;
163 pmFile >> dummy;
164 while (pmFile >> name >> hex >> crateSerial >> dec >> slot >> hex >> boardSerial >> dec >> isT0) {
166 par->BoardSerial = boardSerial;
167 par->CrateSerial = crateSerial;
168 par->slot = slot;
169 par->name = name;
170 par->IsT0 = isT0;
171 par->ChannelCount = CHANNEL_COUNT_MAX; // ChanCntByName(name);
172 fPlacementMap.insert(pair<PlMapKey, BmnTrigParameters*>(PlMapKey(par->CrateSerial, par->slot), par));
173 }
174 pmFile.close();
175 return kBMNSUCCESS;
176}
177
179{
180 fMapFileName = TString(getenv("VMCWORKDIR")) + TString("/input/") + mappingFile;
181 LOGF(info, "Reading Triggers strip mapping file %s...", fMapFileName.Data());
182
183 vector<string> trc_trigger_bits;
184 vector<string> scalers;
185 vector<string> configuration;
186 vector<string> t0_raw;
187
188 // Setup options.
189 po::options_description desc("Options");
190 desc.add_options()("INPUTS.serial", po::value<string>(), "TRC serial")(
191 "INPUTS.channels", po::value<vector<string>>(&trc_trigger_bits)->multitoken(), "TRC trigger input signal bits")(
192 "SCALERS.channels", po::value<vector<string>>(&scalers)->multitoken(),
193 "Scaler channels")("TDC-CONFIGURATION.channels", po::value<vector<string>>(&configuration)->multitoken(),
194 "TDC configuration")("T0-RAW.virt_serial", po::value<string>(), "T0 virtual serial")(
195 "T0-RAW.channels", po::value<vector<string>>(&t0_raw)->multitoken(), "TDC configuration");
196
197 // Load config file.
198 po::variables_map vm;
199 ifstream config_file(fMapFileName.Data(), ifstream::in);
200 if (!config_file.is_open()) {
201 printf("%s - file open error!\n", mappingFile.Data());
202 return kBMNERROR;
203 }
204 po::store(po::parse_config_file(config_file, desc), vm);
205 config_file.close();
206 po::notify(vm);
207
208 stringstream hs(vm["INPUTS.serial"].as<string>());
209 hs >> std::hex >> fTrcSerial;
210 LOGF(info, "TRC serial %8X", fTrcSerial);
211
212 //========== read TRC trig bits map ==========//
213 string tr_name;
214 uint16_t bit;
215 for (auto it : trc_trigger_bits) {
216 istringstream ss(it);
217 ss >> tr_name >> bit;
218 fTrcBitMap[tr_name] = bit;
219 // printf("trig[%8s] = %u\n", tr_name.data(), fTrigBitsMap[tr_name]);
220 }
221 //========== read scalers channel map ==========//
222 UInt_t ser;
223 uint16_t ch;
224 uint16_t scalers_ar_size(0); // MSC list size
225 for (auto it : scalers) {
226 istringstream ss(it);
227 ss >> tr_name >> hex >> ser >> dec >> ch;
228 std::pair p_ser_ch = make_pair(ser, ch);
229 scalers2name_map.insert(make_pair(p_ser_ch, tr_name));
230 scalers2index_map.insert(make_pair(p_ser_ch, scalers_ar_size));
231 scalers_name2index_map.insert(make_pair(tr_name, scalers_ar_size));
232 scalers_index2name_map.push_back(tr_name);
233 // scalers_index2name_map.insert(make_pair(scalers_ar_size, tr_name));
234 name2scaler_map[tr_name] = p_ser_ch;
235 auto it_trc = fTrcBitMap.find(tr_name);
236 if (it_trc != fTrcBitMap.end())
237 trcIdx2scalerIdx.insert(make_pair(it_trc->second, scalers_ar_size));
238 scalers_ar_size++;
239 LOGF(debug, "msc[%15s] = (0x%08X : %2u)", tr_name.data(), name2scaler_map[tr_name].first,
240 name2scaler_map[tr_name].second);
241 }
242 //========== read TDC channel map ==========//
243 TString name;
244 uint16_t slot, mod;
245 uint16_t neg;
246 for (auto it : configuration) {
247 istringstream ss(it);
248 ss >> name >> mod >> hex >> ser >> dec >> slot >> ch >> neg;
249 if (ch < 0)
250 continue;
251 BmnTrigChannelData record;
252 record.branchArrayPtr = NULL;
253 record.name = name;
254 record.serial = ser;
255 record.module = mod;
256 record.slot = slot;
257 record.channel = ch;
258 record.isNegative = neg > 0 ? kTRUE : kFALSE;
259 fMap.push_back(record);
260 }
261 //========== read T0 raw signals from Sergeev's txt ==========//
262 stringstream vs(vm["T0-RAW.virt_serial"].as<string>());
263 UInt_t t0_virt_serial;
264 vs >> std::hex >> t0_virt_serial;
265 LOGF(info, "t0_virt_serial %0X", t0_virt_serial);
266 for (auto it : t0_raw) {
267 istringstream ss(it);
268 ss >> tr_name >> mod >> ch;
269 fT0Map[make_pair(tr_name, mod)] = ch;
270 LOGF(debug, "trig[%10s] mod %2u ch %3u", tr_name.data(), mod, ch);
271 }
272 return kBMNSUCCESS;
273}
274
276{
277 fstream ff;
278 TString fINLFileName =
279 TString(getenv("VMCWORKDIR")) + TString("/input/") + Serial2FileName(par->name, par->BoardSerial);
280 ff.open((fINLFileName).Data(), ios::in);
281 if (!ff.is_open()) {
282 cout << "Error opening INL-file (" << fINLFileName << ")!" << endl;
283 return kBMNERROR;
284 }
285 LOGF(info, "Open INL file %s", fINLFileName.Data());
286 TPRegexp reInlHdr("\\[.*(inl_corr).*\\]"); // INL block header
287 // regex reInlHdr("\\‍[.*(inl_corr).*\\‍]"); // INL block header
288 // regex reInlChannel("\\s*(\\d+)=(.+)"); // chID=c0, c1, ...
289 Bool_t isInlHdr = kFALSE;
290 while (!ff.eof()) {
291 string line;
292 std::getline(ff, line, '\n');
293 if (reInlHdr.MatchB(line)) {
294 // if (regex_match(line, reInlHdr)) {
295 isInlHdr = kTRUE;
296 break;
297 }
298 }
299 if (!isInlHdr) {
300 printf("Incorrect INL file format!\n");
301 return kBMNERROR;
302 }
303 uint16_t channelID = 0;
304 while (!ff.eof()) {
305 string line;
306 std::getline(ff, line, '\n');
307 // printf("Read %lu \n", line.length());
308 // if (!regex_match(line, reInlChannel))
309 // continue;
310 // line = regex_replace(line, reInlChannel, "$1 $2");
311 // printf("%s\n", line.c_str());
312 istringstream ss(line);
313 ss >> channelID;
314 // printf("Channel ID = %u\n", channelID);
315 uint16_t i_bin = 0;
316 while (ss.tellg() != -1) {
317 if (i_bin > TDC_BIN_COUNT) {
318 printf("INL File contains too many bins in channel.\n");
319 ff.close();
320 return kBMNERROR;
321 }
322 if (ss.peek() == ',' || ss.peek() == '=') {
323 ss.ignore();
324 }
325 ss >> par->INL[channelID][i_bin];
326 i_bin++;
327 }
328 }
329 ff.close();
330 return kBMNSUCCESS;
331}
332
333void BmnTrigRaw2Digit::ProcessWave(vector<int16_t>& iValue, Bool_t& isNeg)
334{
335 // Double_t rtime;
336 // Double_t ctime;
337 // TStopwatch timer;
338 // timer.Start();
339 int16_t baseLine = GetBaselineByMap(iValue);
340 // timer.Stop();
341 // rtime = timer.RealTime();
342 // ctime = timer.CpuTime();
343 // printf("Real time %f s, CPU time %f s baseline\n", rtime, ctime);
344 // timer.Start();
345 for (auto& val : iValue)
346 val -= baseLine;
347 if (isNeg)
348 for (auto& val : iValue)
349 val = -val;
350 // timer.Stop();
351 // rtime = timer.RealTime();
352 // ctime = timer.CpuTime();
353 // printf("Real time %f s, CPU time %f s sub\n", rtime, ctime);
354}
355
356// int16_t BmnTrigRaw2Digit::GetBaseline(vector<int16_t>& iValue)
357//{
358// fWorkArray = {};
359// for (auto& val : iValue)
360// fWorkArray[val - SHRT_MIN]++;
361// uint16_t maxCount = 0;
362// size_t mode = 0;
363// for (size_t i = 0; i < ADC_RANGE; ++i)
364// if (fWorkArray[i] > maxCount) {
365// maxCount = fWorkArray[i];
366// mode = i;
367// }
368// return (mode + SHRT_MIN);
369// }
370
371int16_t BmnTrigRaw2Digit::GetBaselineByMap(vector<int16_t>& iValue)
372{
373 fValsMap.clear();
374 for (auto& val : iValue)
375 fValsMap[val]++;
376 uint16_t maxCount = 0;
377 int16_t mode = 0;
378 for (auto& [val, cnt] : fValsMap)
379 if (cnt > maxCount) {
380 maxCount = cnt;
381 mode = val;
382 }
383 return mode;
384}
385
386BmnStatus BmnTrigRaw2Digit::FillEvent(TClonesArray* tdc, TClonesArray* adc, unordered_map<UInt_t, Long64_t>& tsMap)
387{
388 std::vector<Double_t> times;
389 std::vector<Double_t> diff;
390 for (Int_t iAdc = 0; iAdc < adc->GetEntriesFast(); iAdc++) {
391 times.clear();
392 diff.clear();
394 uint16_t iChannel = adcDig->GetChannel();
395 auto plIter = fPlacementMap.find(PlMapKey(adcDig->GetSerial(), adcDig->GetSlot()));
396 if (plIter == fPlacementMap.end())
397 continue;
398 BmnTrigParameters* par = plIter->second;
399 TClonesArray* trigAr = par->branchArrayPtr[iChannel];
400 if (trigAr) {
401 uint16_t iMod = par->ChannelMap[iChannel];
402 Double_t adcTimestamp = adcDig->GetAdcTimestamp() * ADC_CLOCK_TQDC16VS;
403 Double_t trgTimestamp = adcDig->GetTrigTimestamp() * ADC_CLOCK_TQDC16VS;
404 Double_t boardShift = par->IsT0 ? 0 : tsMap[adcDig->GetSerial()];
405
406 for (Int_t iTdc = 0; iTdc < tdc->GetEntriesFast(); ++iTdc) {
407 BmnTDCDigit* tdcDig = (BmnTDCDigit*)tdc->At(iTdc);
408 if (tdcDig->GetSerial() != adcDig->GetSerial() || tdcDig->GetSlot() != adcDig->GetSlot())
409 continue;
410 if (tdcDig->GetChannel() != iChannel)
411 continue;
412 Double_t time = (tdcDig->GetValue() + par->INL[iChannel][tdcDig->GetValue() % TDC_BIN_COUNT])
414 + boardShift;
415 times.push_back(time);
416 }
417 BmnTrigWaveDigit* dig = new ((*trigAr)[trigAr->GetEntriesFast()])
418 BmnTrigWaveDigit(iMod, move(adcDig->GetValue()), trgTimestamp, adcTimestamp);
419 ProcessWave(dig->GetValue(), par->NegativeMap[iChannel]);
420 dig->TdcVector() = std::move(times);
421 }
422 }
423 return kBMNSUCCESS;
424}
425
426BmnStatus BmnTrigRaw2Digit::FillEvent(TClonesArray* tdc, unordered_map<UInt_t, Long64_t>& tsMap)
427{
428 for (auto& el : fPlacementMap)
429 for (UInt_t i = 0; i < CHANNEL_COUNT_MAX; i++)
430 el.second->t[i] = -1.0;
431 for (Int_t iTdc = 0; iTdc < tdc->GetEntriesFast(); ++iTdc) {
432 BmnTDCDigit* tdcDig = (BmnTDCDigit*)tdc->At(iTdc);
433 auto plIter = fPlacementMap.find(PlMapKey(tdcDig->GetSerial(), tdcDig->GetSlot()));
434 if (plIter == fPlacementMap.end())
435 continue;
436 BmnTrigParameters* par = plIter->second;
437 Double_t boardShift = par->IsT0 ? 0 : tsMap[tdcDig->GetSerial()];
438 uint16_t rChannel = tdcDig->GetHptdcId() * kNCHANNELS + tdcDig->GetChannel();
439 Double_t time =
440 (tdcDig->GetValue() + par->INL[rChannel][tdcDig->GetValue() % TDC_BIN_COUNT]) * TDC_CLOCK / TDC_BIN_COUNT
441 + boardShift;
442 // printf("\tCrateSeral %08X slot %02u channel %02u time %+2.2f leading %d neg %d\n",
443 // tdcDig->GetSerial(), tdcDig->GetSlot(), rChannel, time,
444 // tdcDig->GetLeading(),par->NegativeMap[rChannel]);
445 if (tdcDig->GetLeading() ^ par->NegativeMap[rChannel]) {
446 par->t[rChannel] = time;
447 } else {
448 if (time < par->t[rChannel])
449 continue;
450 if (par->t[rChannel] < 0)
451 continue;
452 uint16_t iMod = par->ChannelMap[rChannel];
453 TClonesArray* trigAr = par->branchArrayPtr[rChannel];
454 if (trigAr == NULL)
455 continue;
456 Double_t tL = par->t[rChannel];
457 Double_t tT = time;
458 par->t[rChannel] = -1.0;
459 new ((*trigAr)[trigAr->GetEntriesFast()]) BmnTrigDigit(iMod, tL, tT - tL);
460 }
461 }
462 return kBMNSUCCESS;
463}
464
466{
467 for (TClonesArray* ar : trigArrays)
468 ar->Delete();
469 return kBMNSUCCESS;
470}
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_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
@ kBMNSETUP
Definition BmnEnums.h:166
std::pair< uint32_t, uint16_t > PlMapKey
Definition BmnAliases.h:4
UInt_t GetValue() const
Definition BmnTDCDigit.h:32
UInt_t GetSerial() const
Definition BmnTDCDigit.h:22
UChar_t GetHptdcId() const
Definition BmnTDCDigit.h:34
UChar_t GetSlot() const
Definition BmnTDCDigit.h:26
UChar_t GetChannel() const
Definition BmnTDCDigit.h:30
Bool_t GetLeading() const
Definition BmnTDCDigit.h:28
UChar_t GetSlot() const
UShort_t GetTrigTimestamp() const
UShort_t GetAdcTimestamp() const
int16_t GetBaselineByMap(vector< int16_t > &iValue)
BmnStatus ReadINLFromFile(BmnTrigParameters *par)
map< std::pair< uint32_t, uint16_t >, uint16_t > scalers2index_map
vector< BmnTrigChannelData > fMap
map< int16_t, uint16_t > fValsMap
Name2SerCh name2scaler_map
vector< string > scalers_index2name_map
BmnStatus ReadChannelMap(TString mappingFile)
map< PlMapKey, BmnTrigParameters * > fPlacementMap
map< uint16_t, uint16_t > trcIdx2scalerIdx
void ProcessWave(vector< int16_t > &iValue, Bool_t &isNeg)
SerCh2Name scalers2name_map
NameChMap scalers_name2index_map
TString Serial2FileName(TString boardName, UInt_t serial)
BmnStatus FillEvent(TClonesArray *tdc, unordered_map< UInt_t, Long64_t > &tsMap)
BmnStatus ReadPlacementMap(TString mappingFile)
vector< TClonesArray * > trigArrays
class for TQDC data including waveform can be initialized both from an std::vector and raw pointer to...
vector< int16_t > & GetValue()
vector< Double_t > & TdcVector()
void SetName(const char *name)
static TClass * Class()
Int_t GetEntriesFast() const
TObject * At(Int_t idx) const override
static TClass * Class()
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
virtual Int_t Branch(const char *folder, Int_t bufsize=32000, Int_t splitlevel=99)
const UShort_t kNCHANNELS
#define TDC_CLOCK
#define ADC_CLOCK_TQDC16VS
#define CHANNEL_COUNT_MAX
#define TDC_BIN_COUNT
Definition json.hpp:4446
TClonesArray * branchArrayPtr
Double_t INL[CHANNEL_COUNT_MAX][TDC_BIN_COUNT]
Bool_t NegativeMap[CHANNEL_COUNT_MAX]
TClonesArray * branchArrayPtr[CHANNEL_COUNT_MAX]
UShort_t ChannelMap[CHANNEL_COUNT_MAX]
Double_t t[CHANNEL_COUNT_MAX]