CbmRoot
Loading...
Searching...
No Matches
CbmMuchFindHitsGem.cxx
Go to the documentation of this file.
1/* Copyright (C) 2008-2021 St. Petersburg Polytechnic University, St. Petersburg
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Vikas Singhal, Ajit Kumar, Ekata Nandy, Evgeny Kryshen [committer] , Ajay Kumar, Florian Uhlig */
4
5/*
6 * CbmMuchFindHitsGem.cxx
7 *
8 * Modified on 08/08/2019 : Hit reconstruction in Event (in time slice) and Time slice mode
9 * Default is time slice (kCbmTimeSlice) and it will run in event mode (kCbmEvent) if find event branch in the tree
10 * @authors Vikas Singhal and Ajit Kumar
11 *
12 //@author : Ekata Nandy (ekata@vecc.gov.in) since 21-06-19- Drift time correction for GEM and RPC have been done separately.
13 */
14#include "CbmMuchFindHitsGem.h"
15
16#include "CbmDigiManager.h"
17#include "CbmMuchCluster.h"
18#include "CbmMuchGeoScheme.h"
19#include "CbmMuchModule.h"
20#include "CbmMuchModuleGem.h"
21#include "CbmMuchPad.h"
22#include "CbmMuchPixelHit.h"
23#include "FairRootManager.h"
24#include "TClonesArray.h"
25#include "TFile.h"
26#include "TMath.h"
27#include "TStopwatch.h"
28//#include "CbmTimeSlice.h"
29#include "CbmMuchAddress.h"
30#include "CbmMuchBeamTimeDigi.h"
31#include "CbmMuchDigi.h"
32
33#include <algorithm>
34#include <iomanip>
35#include <iostream>
36
37using std::cout;
38using std::endl;
39using std::fixed;
40using std::left;
41using std::multimap;
42using std::right;
43using std::setw;
44using std::vector;
45
46// -------------------------------------------------------------------------
47CbmMuchFindHitsGem::CbmMuchFindHitsGem(const char* digiFileName, Int_t flag)
48 : FairTask("MuchFindHitsGem", 1)
49 , fDigiFile(digiFileName)
50 , fFlag(flag)
51 , fAlgorithm(3)
53 , fThresholdRatio(0.1)
54 , fEvent(0)
56 ,
57 //fDigis(NULL),
58 fEvents(NULL)
60 , fLocalMax()
61 , fClusterPads()
62 , fNeighbours()
63 , fClusters(new TClonesArray("CbmMuchCluster", 1000))
64 , fHits(new TClonesArray("CbmMuchPixelHit", 1000))
65 , fGeoScheme(CbmMuchGeoScheme::Instance())
66 , fDigiIndices()
67 , fFiredPads()
68 ,
69 // fDaq(),
70 // fTimeSlice(NULL),
71 // fDigiData(),
72 fuClusters(0)
73{
74}
75
76// ----- Private method Init -------------------------------------------
78{
79 FairRootManager* ioman = FairRootManager::Instance();
80 //if (fDaq) fTimeSlice = (CbmTimeSlice*) ioman->GetObject("TimeSlice.");
81 //else fDigis = (TClonesArray*) ioman->GetObject("MuchDigi");
82
83 // --- Digi Manager for reading digis which were stored in vector
85 if (bBeamTimeDigi) fDigiManager->UseMuchBeamTimeDigi();
86 fDigiManager->Init();
87
88 // fDigis will not be used now. Just for checking. Need to remove
89 /*fDigis = (TClonesArray*) ioman->GetObject("MuchDigi");
90 if (! fDigis)
91 fDigis = (TClonesArray*) ioman->GetObject("MuchBeamTimeDigi");
92 if (! fDigis)
93 fDigis = (TClonesArray*) ioman->GetObject("CbmMuchBeamTimeDigi");
94 if (! fDigis)
95 fDigis = (TClonesArray*) ioman->GetObject("CbmMuchDigi");
96 if (! fDigis)
97 LOG(info) << "MuchFindHitsGem: No MuchDigi or MuchBeamTimeDigi or CbmMuchDigi or CbmMuchBeamTimeDigi exist";
98 */
99
100 // Implementation of Event by event execution after TimeSlice Mode and Event Building should have one Event branch.
101
102 fEvents = dynamic_cast<TClonesArray*>(FairRootManager::Instance()->GetObject("Event"));
103 if (!fEvents) fEvents = dynamic_cast<TClonesArray*>(FairRootManager::Instance()->GetObject("CbmEvent"));
104
105 if (!fEvents) {
106 LOG(info) << GetName() << ": No event branch present.";
107 // return kfatal;
108 }
109 else {
110 fEventMode = kTRUE;
111 //fMode=kCbmEvent;
112 LOG(info) << GetName() << "TimeSlice: Event-by-event mode after Event Building selected. ";
113 }
114
115 ioman->Register("MuchCluster", "Cluster in MUCH", fClusters, IsOutputBranchPersistent("MuchCluster"));
116 ioman->Register("MuchPixelHit", "Hit in MUCH", fHits, IsOutputBranchPersistent("MuchPixelHit"));
117
118 // Initialize GeoScheme
120 TFile* oldFile = gFile;
121 TDirectory* oldDir = gDirectory;
122
123 TFile* file = new TFile(fDigiFile);
124 LOG_IF(fatal, !file) << "Could not open file " << fDigiFile;
125 TObjArray* stations = file->Get<TObjArray>("stations");
126 LOG_IF(fatal, !stations) << "TObjArray stations not found in file " << fDigiFile;
127
128 //For X, Y position correction according to different geometry file and its tag.
129
130 if (fDigiFile.Contains("mcbm")) {
131 if (fDigiFile.Contains("v19a")) {
132 fGemTX = 18.5;
133 fGemTY = 80.5;
134 }
135 else if (fDigiFile.Contains("v20a")) {
136 fGemTX = 18.5;
137 fGemTY = 80.0;
138 }
139 else if (fDigiFile.Contains("v22j")) { // for high intensity runs during June 2022 mMuCh in acceptance
140 fGemTX = 8.0;
141 fGemTY = 81.5;
142 fRpcTX = 66.25; //RPC introduced during 2022 data taking
143 fRpcTY = -70.5;
144 }
145 else if (fDigiFile.Contains("v22k")) { // during benchmark runs. mMuCh is out of acceptance
146 fGemTX = -44.5;
147 fGemTY = 81.5;
148 fRpcTX = 48.0;
149 fRpcTY = -70.0;
150 }
151 else if (fDigiFile.Contains("v24a")) {
152 fGemTX = 33.0;
153 fGemTY = 0.0;
154 }
155 else if (fDigiFile.Contains("v25a")) {
156 fGemTX = 36.5;
157 fGemTY = 0.0;
158 }
159 }
160
161 file->Close();
162 file->Delete();
164 gFile = oldFile;
165 gDirectory = oldDir;
166
167 fGeoScheme->Init(stations, fFlag);
168 return kSUCCESS;
169}
170// -------------------------------------------------------------------------
171
172// ----- Task execution ------------------------------------------------
174{
175 TStopwatch timer;
176 timer.Start();
177 // fDigiData.clear();
178 // Removing SetDaq functionality as Cluster and Hit Finder algorithm is same for both the Time Based and Event Based mode.
179 //if (fDaq) ;
180 //fDigiData = fTimeSlice->GetMuchData();
181 // else {
182 //LOG(debug)<<"Start Reading digi from a module ";
183
184 /*for (Int_t iDigi = 0; iDigi < fDigiManager->GetNofDigis(ECbmModuleId::kMuch); iDigi++) {
185 //Reading digi from CbmDigiManager which stors digis in vector
186 const auto * digi;
187 if(!bBeamTimeDigi) digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(iDigi);
188 else digi = (CbmMuchBeamTimeDigi*) fDigiManager->Get<CbmMuchBeamTimeDigi>(iDigi);
189 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigis->At(iDigi);
190 CbmMuchModule* module = fGeoScheme->GetModuleByDetId(digi->GetAddress()); //AZ
191 //std::cout << module->GetDetectorType() << std::endl; //AZ
192 if (module->GetDetectorType() == 2) continue; //AZ - skip 2-D straws
193 fDigiData.push_back(*digi);
194 }*/
195 //}
196
197 // Clear output array
198 if (fHits) fHits->Clear();
199 if (fClusters) fClusters->Delete(); //Clear(); // Delete because of memory escape
200
201 fuClusters = 0;
202 // --- Time-slice mode: process entire array
203
204 if (!fEventMode) {
205 //if ( fMode == kCbmTimeslice ){
206 ProcessData(nullptr);
207 LOG(info) << setw(20) << left << GetName() << ": processing time is " << timer.RealTime()
208 << " Time Slice Number is " << fNofTimeslices << " digis "
209 << fDigiManager->GetNofDigis(ECbmModuleId::kMuch)
210 //<< "s digis " << fDigis->GetEntriesFast()
211 << " clusters " << fClusters->GetEntriesFast() << " total hits " << fHits->GetEntriesFast();
212 }
213 // --- Event mode: loop over events
214 else {
215 assert(fEvents);
216 Int_t nEvents = fEvents->GetEntriesFast();
217 for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
218 CbmEvent* event = dynamic_cast<CbmEvent*>(fEvents->At(iEvent));
219 assert(event);
220 Int_t nDigis =
221 (event ? event->GetNofData(ECbmDataType::kMuchDigi) : fDigiManager->GetNofDigis(ECbmModuleId::kMuch));
222 //: fDigis->GetEntriesFast() );
223 //if (event) LOG(debug)<<" Timeslice "<< fNofTimeslices <<" event : " << event->GetNumber() <<" nDigi : " << nDigis;
224 ProcessData(event);
225 LOG(debug) << setw(20) << left
226 << GetName()
227 //<< ": Processing Time for an event is " << timer.RealTime()
228 << ": Time slice " << fNofTimeslices << " with " << nEvents << (nEvents == 1 ? " event" : " events")
229 << " and processing event nubmer " << iEvent << " digis "
230 << nDigis
231 //<< "s digis " << fDigis->GetEntriesFast()
232 << " and created cluster " << event->GetNofData(ECbmDataType::kMuchCluster) << " and created hit "
233 << event->GetNofData(ECbmDataType::kMuchPixelHit);
234 } //# events
235 LOG(info) << setw(20) << left << GetName() << ": Processing Time is " << timer.RealTime() << ": Time slice "
236 << fNofTimeslices << " with " << nEvents << (nEvents == 1 ? " event" : " events") << "s digis "
237 << fDigiManager->GetNofDigis(ECbmModuleId::kMuch)
238 //<< "s digis " << fDigis->GetEntriesFast()
239 << " and event wise total "
240 << " clusters " << fClusters->GetEntriesFast() << " total hits " << fHits->GetEntriesFast();
241
242 } //? event mode
244 /* double *pos = IgnoredAddresses.data();
245 for (int i=0;i<IgnoredAddresses.size();i++)
246 LOG(info) << "Ignored Address " << *pos++ ; */
247 LOG(info) << "Total ignored address " << IgnoredAddresses.size();
248 IgnoredAddresses.clear();
249}
250// -------------------------------------------------------------------------
251
252// ----- Public method Exec --------------------------------------------
254{
255 TStopwatch EventTimer;
256 EventTimer.Start();
257
258 fEvent++;
259 //LOG(debug3)<<" Start creating cluster ";
260 // Find clusters
261 FindClusters(event);
262 Int_t NuOfClusterInEvent = (event ? event->GetNofData(ECbmDataType::kMuchCluster) : fClusters->GetEntriesFast());
263
264 for (Int_t clusterIndex = 0; clusterIndex < NuOfClusterInEvent; ++clusterIndex) {
265 UInt_t iCluster = (event ? event->GetIndex(ECbmDataType::kMuchCluster, clusterIndex) : clusterIndex);
266 CbmMuchCluster* cluster = (CbmMuchCluster*) fClusters->At(iCluster);
267 switch (fAlgorithm) {
268 // Hit
269 case 0:
270 // One hit per pad
271 case 1: {
272 // One hit per cluster
273 CreateHits(cluster, iCluster, event);
274 break;
275 }
276 case 2: {
277 // Simple cluster deconvolution
278 ExecClusteringSimple(cluster, iCluster, event);
279 break;
280 }
281 case 3: {
282 ExecClusteringPeaks(cluster, iCluster, event);
283 break;
284 }
285 default: {
286 LOG(fatal) << GetName() << "::Exec: The algorithm index does not exist.";
287 break;
288 }
289 }
290 }
291 fDigiIndices.clear();
292 fFiredPads.clear();
293}
294// -------------------------------------------------------------------------
295
296
297// ----- Private method FindClusters ------------------------------------
299{
300
301 Int_t nDigis = (event ? event->GetNofData(ECbmDataType::kMuchDigi) : fDigiManager->GetNofDigis(ECbmModuleId::kMuch));
302 //: fDigis->GetEntriesFast() );
303 if (event)
304 LOG(debug2) << " Timeslice " << fNofTimeslices << " event : " << event->GetNumber() << " nDigi : " << nDigis;
305 if (nDigis < 0) return;
306 if (fAlgorithm == 0) {
307 for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
308 UInt_t digiIndex = (event ? event->GetIndex(ECbmDataType::kMuchDigi, iDigi) : iDigi);
309 fDigiIndices.clear();
310 fDigiIndices.push_back(digiIndex);
311 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(digiIndex);
312 const CbmMuchDigi* digi;
313 if (!bBeamTimeDigi)
314 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(digiIndex));
315 else
316 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(digiIndex));
317 //const CbmMuchDigi* digi = static_cast<const CbmMuchDigi*>(fDigis->At(digiIndex));
318 CbmMuchCluster* cluster = new ((*fClusters)[fuClusters++]) CbmMuchCluster();
322 cluster->SetAddress(address);
323 cluster->AddDigis(fDigiIndices);
324 // --- In event-by-event mode after event building: register clusters to event using ECbmDataType::kMuchCluster
325 //Uncomment below code
326 if (event) {
327 event->AddData(ECbmDataType::kMuchCluster, fuClusters - 1);
328 } //? Event object
329 }
330 return;
331 }
332
333 vector<CbmMuchModuleGem*> modules = fGeoScheme->GetGemModules();
334
335 // Clear array of digis in the modules
336 for (UInt_t m = 0; m < modules.size(); m++)
337 modules[m]->ClearDigis();
338
339 // Fill array of digis in the modules. Digis are automatically sorted in time
340
341 for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
342 UInt_t digiIndex = (event ? event->GetIndex(ECbmDataType::kMuchDigi, iDigi) : iDigi);
343 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(digiIndex);
344 //const auto * digi;
345 const CbmMuchDigi* digi;
346 if (!bBeamTimeDigi)
347 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(digiIndex));
348 else
349 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(digiIndex));
350 //const CbmMuchDigi* digi =static_cast<const CbmMuchDigi*>(fDigis->At(digiIndex));
351 Double_t time = digi->GetTime();
352 // Double_t chanid = digi->GetChannelId();
353 UInt_t address = digi->GetAddress();
354 // UInt_t adc = digi->GetAdc();
355 // 22/02/23 for mCBM Data checking for GEM and RPC sector and channel limits in a module.
356 //
357 if (fFlag) {
359 || (CbmMuchAddress::GetStationIndex(digi->GetAddress()) == 1)) {
362 IgnoredAddresses.push_back(digi->GetAddress());
363 continue;
364 }
367 IgnoredAddresses.push_back(digi->GetAddress());
368 continue;
369 }
370 }
372 || (CbmMuchAddress::GetStationIndex(digi->GetAddress()) == 3)) {
375 IgnoredAddresses.push_back(digi->GetAddress());
376 continue;
377 }
380 IgnoredAddresses.push_back(digi->GetAddress());
381 continue;
382 }
383 }
384 if (fGeoScheme->GetModuleByDetId(address) == NULL) {
385 IgnoredAddresses.push_back(digi->GetAddress());
386 continue;
387 }
388 }
389 fGeoScheme->GetModuleByDetId(address)->AddDigi(time, digiIndex);
390 }
391
392 // Find clusters module-by-module
393 for (UInt_t m = 0; m < modules.size(); m++) {
394 CbmMuchModuleGem* module = modules[m];
395 assert(module);
396 multimap<Double_t, Int_t> digis = modules[m]->GetDigis();
397 multimap<Double_t, Int_t>::iterator it, itmin, itmax;
398
399 // Split module digis into time slices according to fClusterSeparationTime
401 Double_t tlast = -10000;
402 // slices.push_back(digis.begin());
403 for (it = digis.begin(); it != digis.end(); ++it) {
404 Double_t t = it->first;
405 if (t > tlast + fClusterSeparationTime) slices.push_back(it);
406 tlast = t;
407 }
408 slices.push_back(it);
409 for (UInt_t s = 1; s < slices.size(); s++) {
410 fFiredPads.clear();
411 for (it = slices[s - 1]; it != slices[s]; it++) {
412 Int_t iDigi = it->second;
413 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(iDigi);
414 const CbmMuchDigi* digi;
415 //const auto * digi;
416 if (!bBeamTimeDigi)
417 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(iDigi));
418 else
419 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(iDigi));
420 //const CbmMuchDigi* digi = static_cast<const CbmMuchDigi*>(fDigis->At(iDigi));
421
422 if (module->GetPad(digi->GetAddress()) == nullptr) {
423 IgnoredAddresses.push_back(digi->GetAddress());
424 continue;
425 }
426
427 CbmMuchPad* pad = module->GetPad(digi->GetAddress());
428
429 pad->SetDigiIndex(iDigi);
430 fFiredPads.push_back(pad);
431 }
432 // Loop over fired pads in a time slice of 100 ns
433 for (UInt_t p = 0; p < fFiredPads.size(); p++) {
434 fDigiIndices.clear();
436 if (fDigiIndices.size() == 0) continue;
437 //const CbmMuchDigi* digi = static_cast<const CbmMuchDigi*>(fDigis->At(fDigiIndices.front()));
438 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(fDigiIndices.front());
439 //const auto * digi;
440 const CbmMuchDigi* digi;
441 if (!bBeamTimeDigi)
442 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(fDigiIndices.front()));
443 else
444 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(fDigiIndices.front()));
445
446 CbmMuchCluster* cluster = new ((*fClusters)[fuClusters++]) CbmMuchCluster();
450
451 cluster->SetAddress(address);
452 cluster->AddDigis(fDigiIndices);
453 // --- In event-by-event mode after event building: register clusters to event using ECbmDataType::kMuchCluster
454 if (event) {
455 event->AddData(ECbmDataType::kMuchCluster, fuClusters - 1);
456 } //? Event object
457 }
458 }
459 }
460}
461// -------------------------------------------------------------------------
462
463
464// ----- Private method CreateCluster -----------------------------------
466{
467 Int_t digiIndex = pad->GetDigiIndex();
468 if (digiIndex < 0) return;
469 fDigiIndices.push_back(digiIndex);
470 pad->SetDigiIndex(-1);
471 vector<CbmMuchPad*> neighbours = pad->GetNeighbours();
472 for (UInt_t i = 0; i < neighbours.size(); i++)
473 CreateCluster(neighbours[i]);
474}
475// -------------------------------------------------------------------------
476
477
478// ----- Private method ExecClusteringSimple ----------------------------
480{
481 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(cluster->GetDigi(0));
482 //const auto * digi;
483 const CbmMuchDigi* digi;
484 if (!bBeamTimeDigi)
485 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(cluster->GetDigi(0)));
486 else
487 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(cluster->GetDigi(0)));
488 //CbmMuchDigi* digi = static_cast<CbmMuchDigi*>(fDigis->At(cluster->GetDigi(0)));
489 CbmMuchModule* m = fGeoScheme->GetModuleByDetId(digi->GetAddress());
490 CbmMuchModuleGem* module = (CbmMuchModuleGem*) m;
491 assert(module);
492 // Int_t iStation = CbmMuchAddress::GetStationIndex(digi->GetAddress());
493
494 Int_t maxCharge = 0;
495 for (Int_t iDigi = 0; iDigi < cluster->GetNofDigis(); iDigi++) {
496 Int_t digiIndex = cluster->GetDigi(iDigi);
497 //digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(digiIndex);
498 if (!bBeamTimeDigi)
499 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(digiIndex));
500 else
501 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(digiIndex));
502 //digi = static_cast<CbmMuchDigi*> (fDigis->At(digiIndex));
503 Int_t charge = digi->GetAdc();
504 if (charge > maxCharge) maxCharge = charge;
505 }
506
507 UInt_t threshold = UInt_t(fThresholdRatio * maxCharge);
508
509 // Fire pads which are higher than threshold in a cluster
510 fFiredPads.clear();
511 for (Int_t iDigi = 0; iDigi < cluster->GetNofDigis(); iDigi++) {
512 Int_t digiIndex = cluster->GetDigi(iDigi);
513 //digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(digiIndex);
514 if (!bBeamTimeDigi)
515 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(digiIndex));
516 else
517 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(digiIndex));
518 //digi = static_cast<CbmMuchDigi*> (fDigis->At(digiIndex));
519 if (digi->GetAdc() <= threshold) continue;
520 if (module->GetPad(digi->GetAddress()) == nullptr) {
521 IgnoredAddresses.push_back(digi->GetAddress());
522 continue;
523 }
524
525 CbmMuchPad* pad = module->GetPad(digi->GetAddress());
526 pad->SetDigiIndex(digiIndex);
527 fFiredPads.push_back(pad);
528 }
529 for (UInt_t p = 0; p < fFiredPads.size(); p++) {
530 fDigiIndices.clear();
532 if (fDigiIndices.size() == 0) continue;
535 CreateHits(&cl, iCluster, event);
536 }
537}
538// -------------------------------------------------------------------------
539
540
541// -------------------------------------------------------------------------
543{
544 Int_t nDigis = cluster->GetNofDigis();
545 if (nDigis <= 2) {
546 CreateHits(cluster, iCluster, event);
547 return;
548 }
549 fClusterCharges.clear();
550 fClusterPads.clear();
551 fLocalMax.clear();
552 // for (Int_t i=0;i<fNeighbours.size();i++) fNeighbours[i].clear();
553 fNeighbours.clear();
554
555 // Fill cluster map
556 for (Int_t i = 0; i < nDigis; i++) {
557 Int_t iDigi = cluster->GetDigi(i);
558 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(iDigi);
559 //const auto * digi;
560 const CbmMuchDigi* digi;
561 if (!bBeamTimeDigi)
562 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(iDigi));
563 else
564 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(iDigi));
565 //const CbmMuchDigi* digi = static_cast<const CbmMuchDigi*>(fDigis->At(iDigi));
566 UInt_t address = digi->GetAddress();
567 CbmMuchModuleGem* module = (CbmMuchModuleGem*) fGeoScheme->GetModuleByDetId(address);
568 assert(module);
569 if (module->GetPad(digi->GetAddress()) == nullptr) {
570 IgnoredAddresses.push_back(digi->GetAddress());
571 continue;
572 }
573 CbmMuchPad* pad = module->GetPad(address);
574 Int_t adc = digi->GetAdc();
575 fClusterPads.push_back(pad);
576 fClusterCharges.push_back(adc);
577 fLocalMax.push_back(1);
578 }
579
580 // Fill neighbours
581 for (Int_t i = 0; i < nDigis; i++) {
582 CbmMuchPad* pad = fClusterPads[i];
583 vector<CbmMuchPad*> neighbours = pad->GetNeighbours();
584 vector<Int_t> selected_neighbours;
585 for (UInt_t ip = 0; ip < neighbours.size(); ip++) {
586 CbmMuchPad* p = neighbours[ip];
587 vector<CbmMuchPad*>::iterator it = find(fClusterPads.begin(), fClusterPads.end(), p);
588 if (it == fClusterPads.end()) continue;
589 selected_neighbours.push_back(it - fClusterPads.begin());
590 }
591 fNeighbours.push_back(selected_neighbours);
592 }
593
594 // Flag local maxima
595 for (Int_t i = 0; i < nDigis; i++) {
596 Int_t c = fClusterCharges[i];
597 for (UInt_t n = 0; n < fNeighbours[i].size(); n++) {
598 Int_t in = fNeighbours[i][n];
599 Int_t cn = fClusterCharges[in];
600 if (cn < c) fLocalMax[in] = 0;
601 }
602 }
603
604 // Fire pads corresponding to local maxima
605 fFiredPads.clear();
606 for (Int_t i = 0; i < nDigis; i++) {
607 if (fLocalMax[i] == 0) continue;
608 CbmMuchPad* pad = fClusterPads[i];
609 pad->SetDigiIndex(cluster->GetDigi(i));
610 fFiredPads.push_back(pad);
611 }
612
613 // Create clusters
614 for (UInt_t p = 0; p < fFiredPads.size(); p++) {
615 fDigiIndices.clear();
617 if (fDigiIndices.size() == 0) continue;
620 CreateHits(&cl, iCluster, event);
621 }
622}
623// -------------------------------------------------------------------------
624
625
626// ----- Private method CreateHits --------------------------------------
628{
629 Int_t nDigis = cluster->GetNofDigis();
630 Double_t sumq = 0, sumx = 0, sumy = 0, sumdx2 = 0, sumdy2 = 0, sumdxy2 = 0,
631 sumdt2 = 0; // , sumt =0 // not used FU 22.03.23
632 Double_t q = 0, x = 0, y = 0, t = 0, z = 0, dx = 0, dy = 0, dxy = 0, dt = 0;
633 Double_t nX = 0, nY = 0, nZ = 0;
634 Int_t address = 0;
635 Int_t planeId = 0;
636 CbmMuchModuleGem* module = NULL;
637
638 Double_t tmin = -1;
639
640 for (Int_t i = 0; i < nDigis; i++) {
641 Int_t iDigi = cluster->GetDigi(i);
642 //const CbmMuchDigi* digi = (CbmMuchDigi*) fDigiManager->Get<CbmMuchDigi>(iDigi);
643 //const auto * digi;
644 const CbmMuchDigi* digi;
645 if (!bBeamTimeDigi)
646 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchDigi>(iDigi));
647 else
648 digi = static_cast<const CbmMuchDigi*>(fDigiManager->Get<CbmMuchBeamTimeDigi>(iDigi));
649 //const CbmMuchDigi* digi = static_cast<const CbmMuchDigi*>(fDigis->At(iDigi));
650 if (i == 0) {
652 planeId = fGeoScheme->GetLayerSideNr(address);
653 // Below address should be 32 bit CbmMuchAddress therefore changing it. Need to check for simulation. 22/02/23
654 module = (CbmMuchModuleGem*) fGeoScheme->GetModuleByDetId(digi->GetAddress());
655 assert(module);
656 z = module->GetPosition()[2];
657 }
658 // One cluster must be from single module. No need of below line.
659 // CbmMuchModule* moduleDet = fGeoScheme->GetModuleByDetId(digi->GetAddress()); /// added
660
661 if (module->GetPad(digi->GetAddress()) == nullptr) {
662 IgnoredAddresses.push_back(digi->GetAddress());
663 continue;
664 }
665
666 CbmMuchPad* pad = module->GetPad(digi->GetAddress());
667 x = pad->GetX();
668 y = pad->GetY();
669
671 Double_t gemDriftTimeCorrc = 15.0; // Drift time mean for GEM is 15 ns. Drift vel =100um/ns and drift width 3mm.
672 Double_t rpcDriftTimeCorrc = 8.33; // Drift time mean for RPC is 8.33 ns. Drift vel =120um/ns and drift width 2mm.
673 Double_t gemHitTimeError = 4.0; // Hit time error for GEM = 4.0 as residual dist width is 4, to make pull width 1.
674 Double_t rpcHitTimeError =
675 2.3; // Hit time error for RPC = 2.3 ns, as residual dist width is 2.3. This is made to make pull dist width ~1
676 Double_t timeShift = 0.5; // this is added because residual time dist is shifted by -0.5 from 0.
677
678 if (module->GetDetectorType() == 3)
679 {
680 if (fFlag == 0)
681 t = digi->GetTime() - gemDriftTimeCorrc + timeShift;
682 else
683 t = digi->GetTime(); // Not correcting Drift Time for mCBM data
684 dt = gemHitTimeError;
685 }
686 if (module->GetDetectorType() == 4)
687 {
688 t = digi->GetTime() - rpcDriftTimeCorrc + timeShift;
689 dt = rpcHitTimeError;
690 }
691
692 if (tmin < 0) tmin = t;
693 if (tmin < t) tmin = t;
694 q = digi->GetAdc();
695 dx = pad->GetDx();
696 dy = pad->GetDy();
697 dxy = pad->GetDxy();
698 //dt = 4.; // digi->GetDTime(); //TODO introduce time uncertainty determination
699 sumq += q;
700 sumx += q * x;
701 sumy += q * y;
702 //sumt += q * t; // not used FU 22.03.23
703 sumdx2 += q * q * dx * dx;
704 sumdy2 += q * q * dy * dy;
705 sumdxy2 += q * q * dxy * dxy;
706 sumdt2 += q * q * dt * dt;
707 //std::cout<<" i "<<i<<" q "<<q<<" sumq "<<sumq<<std::endl;
708 }
709
710 x = sumx / sumq;
711 y = sumy / sumq;
712 // t = sumt/sumq;
713 t = tmin;
714 dx = sqrt(sumdx2 / 12) / sumq;
715 dy = sqrt(sumdy2 / 12) / sumq;
716 dxy = sqrt(sumdxy2 / 12) / sumq;
717 dt = sqrt(sumdt2) / sumq;
718 Int_t iHit = fHits->GetEntriesFast();
719
720 //------------------------------Added by A. Agarwal 29.09.2022 for mCbm ---------------------------
721 // Double_t tX = 8.5, tY = 81.0;
722 Double_t tX = 8.5, tY = 81.0; // commented for testing
723 //Double_t tX =18.5 , tY = 80.0 ;
724 if (module->GetDetectorType() == 3) // GEM
725 {
726 tX = fGemTX;
727 tY = fGemTY;
728 if (fDigiFile.Contains("v25a")) {
730 // During May 2025, GEM-2 at mCBM will be Real Size Station-2 Module
731 tX = fGemTX + 12.5; //Nilay
732 }
733 }
734 }
735 else if (module->GetDetectorType() == 4) // RPC
736 {
737 tX = fRpcTX;
738 tY = fRpcTY;
739 //tX = -66.5;
740 //tY = 72.0;
741 }
742 else {
743 LOG(error) << "Unknown detector type";
744 }
745
746 nX = x + tX; // for miniCBM setup set these according to the geometry
747 // tag and in line number 125 during initialization.
748 nY = y + tY; //
749 nZ = z;
750
751 if (fFlag == 1) {
752 new ((*fHits)[iHit]) CbmMuchPixelHit(address, nX, nY, nZ, dx, dy, 0, dxy, iCluster, planeId, t, dt); //mCbm
753 }
754 else {
755 new ((*fHits)[iHit]) CbmMuchPixelHit(address, x, y, z, dx, dy, 0, dxy, iCluster, planeId, t, dt); //Cbm
756 }
757 //Adding CbmMuchPixelHit entries in the CbmEvent
758 if (event) {
759 event->AddData(ECbmDataType::kMuchPixelHit, iHit);
760 } //? Event object
761}
762// ---------------------------------------------------------------------------------
763
ClassImp(CbmConverterManager)
@ kMuch
Muon detection system.
Definition CbmDefs.h:50
@ kMuchModule
Module.
Data container for MUCH clusters.
Class for pixel hits in MUCH detector.
friend fvec sqrt(const fvec &a)
int Int_t
void SetAddress(int32_t address)
Definition CbmCluster.h:94
int32_t GetDigi(int32_t index) const
Get digi at position index.
Definition CbmCluster.h:76
void AddDigis(const std::vector< int32_t > &indices)
Add array of digi to cluster.
Definition CbmCluster.h:57
int32_t GetNofDigis() const
Number of digis in cluster.
Definition CbmCluster.h:69
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
static int32_t GetModuleIndex(int32_t address)
static int32_t GetSectorIndex(int32_t address)
static int32_t GetChannelIndex(int32_t address)
static int32_t GetLayerIndex(int32_t address)
static int32_t GetLayerSideIndex(int32_t address)
static int32_t GetElementAddress(int32_t address, int32_t level)
static uint32_t GetAddress(int32_t station=0, int32_t layer=0, int32_t side=0, int32_t module=0, int32_t sector=0, int32_t channel=0)
static int32_t GetStationIndex(int32_t address)
Data container for MUCH clusters.
uint16_t GetAdc() const
Definition CbmMuchDigi.h:90
int32_t GetAddress() const
Definition CbmMuchDigi.h:93
double GetTime() const
Definition CbmMuchDigi.h:94
CbmDigiManager * fDigiManager
std::vector< Int_t > fClusterCharges
virtual void Exec(Option_t *opt)
void CreateHits(CbmMuchCluster *cluster, Int_t iCluster, CbmEvent *event)
void ExecClusteringPeaks(CbmMuchCluster *cluster, Int_t iCluster, CbmEvent *event)
std::vector< Bool_t > fLocalMax
void ProcessData(CbmEvent *)
std::vector< Double_t > IgnoredAddresses
std::vector< CbmMuchPad * > fClusterPads
std::vector< CbmMuchPad * > fFiredPads
void CreateCluster(CbmMuchPad *pad)
TClonesArray * fClusters
CbmMuchGeoScheme * fGeoScheme
CbmMuchFindHitsGem(const char *digiFileName, Int_t flag)
void FindClusters(CbmEvent *)
std::vector< Int_t > fDigiIndices
virtual InitStatus Init()
std::vector< std::vector< Int_t > > fNeighbours
TClonesArray * fEvents
Interface to digi branch.
void ExecClusteringSimple(CbmMuchCluster *cluster, Int_t iCluster, CbmEvent *event)
CbmMuchPad * GetPad(Int_t address)
Int_t GetDetectorId() const
Int_t GetDetectorType() const
void SetDigiIndex(Int_t iDigi)
Definition CbmMuchPad.h:45
Double_t GetX() const
Definition CbmMuchPad.h:32
std::vector< CbmMuchPad * > GetNeighbours() const
Definition CbmMuchPad.h:42
Double_t GetDy() const
Definition CbmMuchPad.h:35
Double_t GetDxy() const
Definition CbmMuchPad.h:36
Double_t GetDx() const
Definition CbmMuchPad.h:34
Int_t GetDigiIndex() const
Definition CbmMuchPad.h:38
Double_t GetY() const
Definition CbmMuchPad.h:33