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