BmnRoot
Loading...
Searching...
No Matches
BmnSiliconRaw2Digit.cxx
Go to the documentation of this file.
2
3// Boost
4#include <boost/program_options.hpp>
5// BmnRoot
6#include "BmnRawDataDecoder.h"
7
8namespace po = boost::program_options;
9
10BmnSiliconRaw2Digit::BmnSiliconRaw2Digit(Int_t period, Int_t run, TString MapFileName, BmnSetup bmnSetup)
12 , fMapFileName(MapFileName)
13{
14 fSetup = bmnSetup;
15 LOG(info) << "Loading SILICON Map from FILE: Period " << period << ", Run " << run << "...";
16 ReadMapFile();
17 GrabSerialsFromMap(fOuterMap);
18 InitArrays();
19
20 fSilStationSet = BmnSiliconStationSet::Create(period, fSetup);
21
22 Int_t kNStations = fSilStationSet->GetNStations();
23 fSigProf = new TH1F***[kNStations];
24 fNoisyChannels = new Bool_t***[kNStations];
25 for (Int_t iSt = 0; iSt < kNStations; ++iSt) {
26 auto* st = fSilStationSet->GetStation(iSt);
27 Int_t kNModules = st->GetNModules();
28 fSigProf[iSt] = new TH1F**[kNModules];
29 fNoisyChannels[iSt] = new Bool_t**[kNModules];
30 for (Int_t iMod = 0; iMod < kNModules; ++iMod) {
31 auto* mod = st->GetModule(iMod);
32 Int_t kNLayers = 2; // mod->GetNStripLayers();
33 fSigProf[iSt][iMod] = new TH1F*[kNLayers];
34 fNoisyChannels[iSt][iMod] = new Bool_t*[kNLayers];
35 for (Int_t iLay = 0; iLay < kNLayers; ++iLay) {
36 BmnSiliconLayer& lay = mod->GetStripLayer(iLay);
37 if (iSt != 0) {
38 BmnSiliconLayer& lay1 = mod->GetStripLayer(iLay * 2);
39 BmnSiliconLayer& lay2 = mod->GetStripLayer(iLay * 2 + 1);
40 if (lay1.GetLastStripNumber() > lay2.GetLastStripNumber())
41 lay = lay1;
42 else
43 lay = lay2;
44 // LOGF(info, "Station: %d, Module: %2d, PseudoLayer: %2d, Strips: %3d", iSt,
45 // iMod, iLay, lay.GetLastStripNumber() + 1); LOGF(info, "\tLay 1 FirstStripNumber:
46 // %3d, LastStripNumber: %3d", lay1.GetFirstStripNumber(),
47 // lay1.GetLastStripNumber()); LOGF(info, "\tLay 2 FirstStripNumber: %3d,
48 // LastStripNumber: %3d", lay2.GetFirstStripNumber(), lay2.GetLastStripNumber());
49 }
50 LOGF(debug, "Station: %d, Module: %2d, PseudoLayer: %2d, Strips: %3d", iSt, iMod, iLay,
51 lay.GetLastStripNumber() + 1);
52 // printf("FirstStripNumber: %3d, LastStripNumber: %3d\n", lay.GetFirstStripNumber(),
53 // lay.GetLastStripNumber());
54 Int_t kNStrips = lay.GetLastStripNumber() + 1;
55 TString histName;
56 histName.Form("%s_%d_%d_%d", fDetName.Data(), iSt, iMod, iLay);
57 fSigProf[iSt][iMod][iLay] = new TH1F(histName, histName, kNStrips, 0, kNStrips);
58 fSigProf[iSt][iMod][iLay]->SetDirectory(0);
59 fNoisyChannels[iSt][iMod][iLay] = new Bool_t[kNStrips + 30]();
60 // for (Int_t iStrip = 0; iStrip < kNStrips; ++iStrip){
61 // LOGF(info, "fNoisyChannels Station: %d, Module: %2d, PseudoLayer: %2d iStrip: %d
62 // is %d",
63 // iSt,iMod,iLay, iStrip, fNoisyChannels[iSt][iMod][iLay][iStrip]);
64 // fNoisyChannels[iSt][iMod][iLay][iStrip] = kFALSE;
65 // }
66 }
67 }
68 }
69}
70
72{
73 Int_t kNStations = fSilStationSet->GetNStations();
74 for (Int_t iSt = 0; iSt < kNStations; ++iSt) {
75 auto* st = fSilStationSet->GetStation(iSt);
76 Int_t kNModules = st->GetNModules();
77 for (Int_t iMod = 0; iMod < kNModules; ++iMod) {
78 // auto *mod = st->GetModule(iMod);
79 Int_t kNLayers = 2; // mod->GetNStripLayers();
80 for (Int_t iLay = 0; iLay < kNLayers; ++iLay) {
81 delete fSigProf[iSt][iMod][iLay];
82 delete[] fNoisyChannels[iSt][iMod][iLay];
83 }
84 delete[] fSigProf[iSt][iMod];
85 delete[] fNoisyChannels[iSt][iMod];
86 }
87 delete[] fSigProf[iSt];
88 delete[] fNoisyChannels[iSt];
89 }
90 delete[] fNoisyChannels;
91 delete[] fSigProf;
92 if (canStrip)
93 delete canStrip;
94 for (auto& it : fOuterMap)
95 for (auto& inner : it.second)
96 delete inner.second;
97}
98
99BmnStatus BmnSiliconRaw2Digit::ReadMapFile()
100{
101 UInt_t ser = 0;
102 Int_t ch_lo = 0;
103 Int_t ch_hi = 0;
104 Int_t mod_adc = 0;
105 Int_t mod = 0;
106 Int_t lay = 0;
107 Int_t station = 0;
108
109 vector<string> channel_map;
110 vector<string> spec_thr;
111 Double_t final_thr = 0;
112 Double_t thr_dif = 0;
113 Int_t n_iters = 0;
114 Double_t cmod_cut = 0;
115
116 // Setup options.
117 po::options_description desc("Options");
118 desc.add_options()("CHANNEL_MAP.channels", po::value<vector<string>>(&channel_map)->multitoken(),
119 "ADC channel -> strip map")("SIGNAL_CONFIGURATION.spec_thr",
120 po::value<vector<string>>(&spec_thr)->multitoken(),
121 "ADC channel -> strip map")(
122 "SIGNAL_CONFIGURATION.Threshold", po::value<Double_t>(&final_thr)->default_value(150), "ADC final threshold")(
123 "SIGNAL_CONFIGURATION.ThresholdDif", po::value<Double_t>(&thr_dif)->default_value(100), "ADC threshold step")(
124 "SIGNAL_CONFIGURATION.NIterations", po::value<Int_t>(&n_iters)->default_value(6), "ADC filter iterations")(
125 "SIGNAL_CONFIGURATION.CModCut", po::value<Double_t>(&cmod_cut)->default_value(100), "ADC CModCut");
126
127 // Load config file.
128 po::variables_map vm;
129 TString name = TString(getenv("VMCWORKDIR")) + TString("/input/") + fMapFileName;
130 ifstream config_file(name.Data(), ifstream::in);
131 if (!config_file.is_open()) {
132 LOG(error) << "Error opening map-file (" << name << ")!";
133 return kBMNERROR;
134 }
135 po::store(po::parse_config_file(config_file, desc), vm);
136 config_file.close();
137 po::notify(vm);
138
139 // set thresholds
140 SetThreshold(final_thr, thr_dif, n_iters, cmod_cut);
141
142 // set specific thresholds
143 Int_t ch = 0;
144 Double_t thr = 0;
145 for (auto& str : spec_thr) {
146 istringstream ss(str);
147 ss >> std::hex >> ser >> std::dec >> ch >> thr;
148 fSpecThreshMap.insert(make_pair(make_pair(ser, ch), thr));
149 LOGF(debug, "Serial 0x%08X Channel %2d Threshold %3.3f", ser, ch, thr);
150 }
151
152 // set channel map
153 for (auto& str : channel_map) {
154 istringstream ss(str);
155 ss >> std::hex >> ser >> std::dec >> ch_lo >> ch_hi >> mod_adc >> mod >> lay >> station;
156 BmnSiliconMapping* record = new BmnSiliconMapping();
157 record->layer = lay;
158 record->serial = ser;
159 record->module = mod;
160 if (ch_lo < ch_hi) {
161 record->channel_low = ch_lo;
162 record->channel_high = ch_hi;
163 } else {
164 record->channel_low = ch_hi;
165 record->channel_high = ch_lo;
166 record->inverted = true;
167 }
168 record->station = station;
169 fMap.push_back(record);
170 auto it = fOuterMap.find(ser);
171 if (it == fOuterMap.end()) { // create inner channel map for the serial
172 InChanMapSil inner;
173 inner.insert(make_pair(record->channel_low - 1, nullptr));
174 inner.insert(make_pair(record->channel_high, record));
175 fOuterMap.insert(make_pair(ser, move(inner)));
176 } else { // add range to the existing inner channel map
177 InChanMapSil& inner = it->second;
178 auto innerItHi = inner.find(record->channel_high);
179 auto innerItLo = inner.find(record->channel_low - 1);
180 if (innerItHi == inner.end()) {
181 inner.insert(make_pair(record->channel_high, record));
182 } else {
183 if (innerItHi->second == nullptr) {
184 inner.erase(innerItHi);
185 inner.insert(make_pair(record->channel_high, record));
186 } else {
187 fprintf(stderr, "Wrong %s map! Overlapping intervals for %08X!\n", fDetName.Data(), ser);
188 return kBMNERROR;
189 }
190 }
191 if (innerItLo == inner.end()) {
192 inner.insert(make_pair(record->channel_low - 1, nullptr));
193 }
194 }
195 }
196 return kBMNSUCCESS;
197}
198
199BmnStatus BmnSiliconRaw2Digit::FillEvent(TClonesArray* adc, TClonesArray* digits)
200{
201 (this->*PrecalcEventModsImp)(adc);
202#ifdef BUILD_DEBUG
204#else
206#endif
207 ProcessAdc(digits, kFALSE);
208 return kBMNSUCCESS;
209}
210
212{
213 (this->*PrecalcEventModsImp)(adc);
214#ifdef BUILD_DEBUG
216#else
218#endif
219 ProcessAdc(nullptr, kTRUE);
220
221 return kBMNSUCCESS;
222}
223
225{
226 const Int_t kNStripsInBunch = BmnRawDataDecoder::samplesSil; // GetNSamples();
227 // const Int_t kNBunches = kNStrips / kNStripsInBunch;
228 Double_t kNThresh = BmnRawDataDecoder::threshSil;
229 Double_t correction = BmnRawDataDecoder::correctionSil;
230 LOGF(info, "Searching Noisy Channels in Silicon Strip Detectors");
231 LOGF(info, "Window size: %3d, Threshold: %.2f, Correction: %3d", kNStripsInBunch, kNThresh,
232 (int)round(correction));
233 // repeat noisy channels in the physical terms (station/module/layer)
234 for (Int_t iCr = 0; iCr < GetNSerials(); ++iCr) {
235 auto it = fOuterMap.find(GetSerials()[iCr]);
236 if (it == fOuterMap.end())
237 continue;
238 for (Int_t iCh = 0; iCh < GetNChannels(); ++iCh) {
239 InChanMapSil& inner = it->second;
240 auto innerIt = inner.lower_bound(iCh);
241 if (innerIt == inner.end())
242 continue;
243 BmnSiliconMapping* rec = innerIt->second;
244 if (!rec)
245 continue;
246 for (Short_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl) {
247 if (GetNoisyChipChannels()[iCr][iCh][iSmpl] == kTRUE) {
248 Int_t iStrip = MapStrip(rec, iCh, iSmpl);
249 //
250 // auto * st = fSilStationSet->GetStation(rec->station);
251 // auto *mod = st->GetModule(rec->module);
252 // BmnSiliconLayer& lay = mod->GetStripLayer(rec->layer);
253 // if(rec->station != 0) {
254 // BmnSiliconLayer& lay1 = mod->GetStripLayer(rec->layer * 2);
255 // BmnSiliconLayer& lay2 = mod->GetStripLayer(rec->layer * 2 + 1);
256 // if(lay1.GetLastStripNumber() > lay2.GetLastStripNumber()) lay = lay1;
257 // else lay = lay2;
258 // }
259 //
260 // if (iStrip >= lay.GetLastStripNumber() || iStrip < 0)
261 // LOGF(info, "fNoisyChannels Station: %d, Module: %2d, PseudoLayer: %2d iStrip:
262 // %d set true",
263 // rec->station, rec->module, rec->layer, iStrip);
264 fNoisyChannels[rec->station][rec->module][rec->layer][iStrip] = kTRUE;
265 }
266 }
267 }
268 }
269 int newNoisyCnt = 0;
270 // LOGF(info, "mark noisy");
271 // mark noisy
272 for (Int_t iSt = 0; iSt < fSilStationSet->GetNStations(); ++iSt) {
273 auto* st = fSilStationSet->GetStation(iSt);
274 for (Int_t iMod = 0; iMod < st->GetNModules(); ++iMod) {
275 auto* mod = st->GetModule(iMod);
276 for (Int_t iLay = 0; iLay < 2 /*mod->GetNStripLayers()*/; ++iLay) {
277 // LOGF(info, "fNoisyChannels Station: %d, Module: %2d, PseudoLayer: %2d iStrip: %d
278 // set true",
279 // rec->station, rec->module, rec->layer, iStrip);
280 TH1F* prof = fSigProf[iSt][iMod][iLay];
282 // Int_t realILayer = (mod->GetNStripLayers() == 4) ? 2 * iLay : iLay;
283 BmnSiliconLayer& lay = mod->GetStripLayer(iLay);
284 if (iSt != 0) {
285 BmnSiliconLayer& lay1 = mod->GetStripLayer(iLay * 2);
286 BmnSiliconLayer& lay2 = mod->GetStripLayer(iLay * 2 + 1);
287 if (lay1.GetLastStripNumber() > lay2.GetLastStripNumber())
288 lay = lay1;
289 else
290 lay = lay2;
291 }
292 Double_t sum;
293 Int_t properStrips;
294 bool newNoisyChannels = true;
295 while (newNoisyChannels) {
296 sum = 0.0;
297 properStrips = 0;
298 newNoisyChannels = false;
299 // calculating initial window
300 vector<int> noisyChannels;
301 for (Int_t iStrip = 0; iStrip < kNStripsInBunch; ++iStrip) {
302 Int_t strip = iStrip; // + iBunch * kNStripsInBunch;
303 if (fNoisyChannels[iSt][iMod][iLay][strip] == kTRUE)
304 continue;
305 Double_t curr = prof->GetBinContent(strip + 1);
306 sum += curr;
307 if (curr > 0) // current channel might be broken
308 properStrips++;
309 }
310 // LOGF(info, "checking noisy channels");
311 // marking noisy channels
312 for (Int_t strip = 0; strip < lay.GetLastStripNumber() + 1; strip++) {
313 // checking if this channel is noisy
314 // LOGF(info, "check noise on iSt %d iMod %d iLay %d strip
315 // %d",
316 // iSt, iMod, iLay, strip);
317 if (fNoisyChannels[iSt][iMod][iLay][strip] == kFALSE) {
318 Double_t curr = prof->GetBinContent(strip + 1);
319 if (curr > 0 && properStrips > 0) {
320 if (properStrips == 1
321 || (kNThresh * (sum - curr) / (properStrips - 1) < curr - correction))
322 {
323 LOGF(debug2, "profile noise on iSt %d iMod %d iLay %d strip %d", iSt, iMod, iLay,
324 strip);
325 newNoisyCnt++;
326 newNoisyChannels = true;
327 noisyChannels.push_back(strip);
328 }
329 }
330 }
331 // moving the current frame for calculating mean
332 if (strip >= (kNStripsInBunch - 1) / 2
333 && lay.GetLastStripNumber() + 1 - strip > (kNStripsInBunch / 2) + 1)
334 {
335 if ((fNoisyChannels[iSt][iMod][iLay][strip - (kNStripsInBunch - 1) / 2] == kFALSE)) {
336 sum -= prof->GetBinContent(strip - (kNStripsInBunch - 1) / 2
337 + 1); // first element in window
338 if (prof->GetBinContent(strip - (kNStripsInBunch - 1) / 2 + 1) > 0)
339 properStrips--;
340 }
341 // LOGF(info, "check noise on iSt %d iMod %d iLay %d
342 // strip %d left bound",
343 // iSt, iMod, iLay, strip);
344 if ((fNoisyChannels[iSt][iMod][iLay][strip + (kNStripsInBunch / 2) + 1] == kFALSE)) {
345 sum += prof->GetBinContent(strip + (kNStripsInBunch / 2) + 1
346 + 1); // element right after the window
347 if (prof->GetBinContent(strip + (kNStripsInBunch / 2) + 1 + 1) > 0)
348 properStrips++;
349 }
350 }
351 }
352 // LOGF(info, "marking noisy channels");
353 // marking noisy channels
354 for (auto strip : noisyChannels) {
355 fNoisyChannels[iSt][iMod][iLay][strip] = kTRUE;
356 for (auto& it : fMap)
357 if (it->station == iSt && it->module == iMod && it->layer == iLay) {
358 UInt_t iCr = 0;
359 for (iCr = 0; iCr < GetSerials().size(); iCr++) {
360 if (GetSerials()[iCr] == it->serial)
361 break;
362 }
363 UInt_t iCh = it->inverted ? (it->channel_high - strip / GetNSamples())
364 : (it->channel_low + strip / GetNSamples());
365 UInt_t iSmpl = (strip) % GetNSamples();
366 GetNoisyChipChannels()[iCr][iCh][iSmpl] = kTRUE;
367 }
368 }
369 }
370 }
371 }
372 }
373 // LOGF(info, "Marked %d new channels as noisy on Silicon Strip Detectors", newNoisyCnt);
374 // repeat noisy channels back into the electronics terms
375 for (Int_t iCr = 0; iCr < GetNSerials(); ++iCr) {
376 auto it = fOuterMap.find(GetSerials()[iCr]);
377 if (it == fOuterMap.end())
378 continue;
379 for (Int_t iCh = 0; iCh < GetNChannels(); ++iCh) {
380 InChanMapSil& inner = it->second;
381 auto innerIt = inner.lower_bound(iCh);
382 if (innerIt == inner.end())
383 continue;
384 BmnSiliconMapping* rec = innerIt->second;
385 if (!rec)
386 continue;
387 for (Short_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl) {
388 Int_t iStrip = MapStrip(rec, iCh, iSmpl);
389 if (fNoisyChannels[rec->station][rec->module][rec->layer][iStrip] == kTRUE)
390 GetNoisyChipChannels()[iCr][iCh][iSmpl] = kTRUE;
391 }
392 }
393 }
394 // LOGF(info, "Finished marking on Silicon Strip Detectors");
395 return kBMNSUCCESS;
396}
397
398void BmnSiliconRaw2Digit::ProcessAdc(TClonesArray* digs, Bool_t doFill)
399{
400 for (Int_t iCr = 0; iCr < GetNSerials(); ++iCr) {
401 auto it = fOuterMap.find(GetSerials()[iCr]);
402 if (it == fOuterMap.end())
403 continue;
404 for (Int_t iCh = 0; iCh < GetNChannels(); ++iCh) {
405 auto innerIt = it->second.lower_bound(iCh);
406 if (innerIt == it->second.end())
407 continue;
408 BmnSiliconMapping* rec = innerIt->second;
409 if (!rec)
410 continue;
411 // spec threshold
412 Double_t SpecThr(0);
413 auto itThr = fSpecThreshMap.find(make_pair(GetSerials()[iCr], iCh));
414 if (itThr != fSpecThreshMap.end())
415 SpecThr = itThr->second;
416 // strip map
417 Short_t station = rec->station;
418 Short_t module = rec->module;
419 Short_t layer = rec->layer;
420 // printf("st %d mod %d l %d\n", station, module ,layer);
421 Double_t cs = fCMode[iCr][iCh] - fSMode[iCr][iCh];
422 for (Short_t iSmpl = 0; iSmpl < GetNSamples(); ++iSmpl) {
423 if ((GetNoisyChipChannels()[iCr][iCh][iSmpl] == kTRUE) /* || (fPedVal[iCr][iCh][iSmpl] == 0.0)*/)
424 continue;
425 Int_t strip = MapStrip(rec, iCh, iSmpl);
426 if (strip < 0)
427 continue;
428 Double_t sig = fAdc[iCr][iCh][iSmpl] - fPedVal[iCr][iCh][iSmpl] + cs;
429 // LOGF(debug2,"%s st %2d mod %2d l %2d strip %4d ser %08X ch %2d iSmpl %3d pedestal
430 // %4.2f CMode %4.2f SMode %4.2f GetPedestalsRMS() %4.2f sig %4.2f\n",
431 // fDetName.Data(), station, module, layer, strip, GetSerials()[iCr], iCh, iSmpl,
432 // fPedVal[iCr][iCh][iSmpl], fCMode[iCr][iCh], fSMode[iCr][iCh],
433 // GetPedestalsRMS()[iCr][iCh][iSmpl], sig);
434 if (layer == 1)
435 sig = -sig;
436 // Double_t Asig = TMath::Abs(sig);
437 // Double_t thr = Max(SpecThr, Max(FinalThr, 3.5 * GetPedestalsRMS()[iCr][iCh][iSmpl]));
438 // // default
439 Double_t thr = Max(SpecThr, FinalThr);
440 if ((!GetApplyThreshold()) || (sig > thr)) {
441 if (doFill) {
442 if (Abs(fCMode[iCr][iCh] - fSMode[iCr][iCh]) < cmodcut)
443 fSigProf[station][module][layer]->Fill(strip);
444 }
445 if (digs) {
446 // if ((fVerbose > 0) && (GetSerials()[iCr] == 0x0AADF52A) && (!doFill))
447 // LOGF(debug2, "%s st %2d mod %2d l %2d strip %4d ser %08X ch %2d iSmpl"
448 // " %3d pedestal %4.2f CMode %4.2f SMode %4.2f GetPedestalsRMS() %4.2f" "sig %4.2f\n",
449 // fDetName.Data(), station, module, layer, strip, GetSerials()[iCr], iCh, iSmpl,
450 // fPedVal[iCr][iCh][iSmpl], fCMode[iCr][iCh],
451 // fSMode[iCr][iCh], GetPedestalsRMS()[iCr][iCh][iSmpl], sig);
452 BmnSiliconDigit* resDig = new ((*digs)[digs->GetEntriesFast()])
453 BmnSiliconDigit(station, module, layer, strip, sig, GetPedestalsRMS()[iCr][iCh][iSmpl]);
454 if ((Abs(fCMode[iCr][iCh] - fSMode[iCr][iCh]) > cmodcut))
455 resDig->SetIsGoodDigit(kFALSE);
456 else
457 resDig->SetIsGoodDigit(kTRUE);
458 }
459 }
460 }
461 }
462 }
463}
const float thr
int MapStrip(size_t &iChar, size_t &iCh)
BmnStatus
Definition BmnEnums.h:24
@ kBMNERROR
Definition BmnEnums.h:26
@ kBMNSUCCESS
Definition BmnEnums.h:25
BmnSetup
Definition BmnEnums.h:89
map< PlMapKey, Double_t > fSpecThreshMap
Double_t *** GetPedestalsRMS()
vector< UInt_t > & GetSerials()
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
void GrabSerialsFromMap(unordered_map< UInt_t, cl > m)
Bool_t *** GetNoisyChipChannels()
void(BmnAdcProcessor::* PrecalcEventModsImp)(TClonesArray *adc)
static double correctionSil
static double threshSil
Int_t GetLastStripNumber()
BmnStatus FillProfiles(TClonesArray *adc)
BmnStatus FillEvent(TClonesArray *adc, TClonesArray *sts)
BmnSiliconRaw2Digit(Int_t period, Int_t run, TString MapFileName, BmnSetup bmnSetup=kBMNSETUP)
static unique_ptr< BmnSiliconStationSet > Create(Int_t period, Int_t stp=0)
void SetIsGoodDigit(Bool_t tmp)
#define ADC128_N_SAMPLES
#define ADC_N_CHANNELS
map< Int_t, BmnSiliconMapping * > InChanMapSil
map< Int_t, BmnSiliconMapping * > InChanMapSil
-clang-format
Short_t Short_t channel_low