CbmRoot
Loading...
Searching...
No Matches
CbmMuchClustering.cxx
Go to the documentation of this file.
1/* Copyright (C) 2012-2021 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Grigory Kozlov, Andrey Lebedev [committer] */
4
5/*
6 * CbmMuchClustering.cxx
7 *
8 * Created on: Mar 5, 2012
9 * Author: kozlov
10 */
11
12#include "CbmMuchClustering.h"
13
14#include "CbmClusteringA1.h"
16#include "CbmClusteringSL.h"
17#include "CbmClusteringWard.h"
18#include "CbmDigiManager.h"
19#include "CbmMCTrack.h"
20#include "CbmMuchAddress.h"
21#include "CbmMuchCluster.h"
22#include "CbmMuchDigi.h"
23#include "CbmMuchDigiMatch.h"
24#include "CbmMuchGeoScheme.h"
25#include "CbmMuchModule.h"
26#include "CbmMuchModuleGem.h"
28#include "CbmMuchPad.h"
29#include "CbmMuchPadRadial.h"
30#include "CbmMuchPixelHit.h"
31#include "CbmMuchPoint.h"
32#include "CbmMuchStation.h"
33#include "FairRootManager.h"
34#include "TCanvas.h"
35#include "TClonesArray.h"
36#include "TH1F.h"
37#include "TMath.h"
38#include "TStopwatch.h"
39#include "draw/CbmDrawHist.h"
40
41#include <TFile.h>
42
43#include <cassert>
44#include <iomanip>
45#include <iostream>
46#include <map>
47#include <vector>
48
49using std::cout;
50using std::endl;
51using std::vector;
52
53CbmMuchClustering::CbmMuchClustering(const char* digiFileName)
54 : FairTask()
55 , fModulesGeometryArray()
56 , fDigiFile(digiFileName)
57 , fScheme(CbmMuchGeoScheme::Instance())
58 , fCluster()
59 , fHit()
60 , fNofClusters()
61{
63 fNofModules = 0;
64 fNofEvents = 0;
65}
66
68{
69 if (fHit) {
70 fHit->Delete();
71 delete fHit;
72 }
73 if (fCluster) {
74 fCluster->Delete();
75 delete fCluster;
76 }
77}
78
80{
81 std::cout << "CbmMuchClustering::Init" << std::endl;
82
83 // Initialize GeoScheme
85 TFile* oldFile = gFile;
86 TDirectory* oldDir = gDirectory;
87
88 TFile* file = new TFile(fDigiFile);
89 LOG_IF(fatal, !file) << "Could not open file " << fDigiFile;
90 TObjArray* stations = file->Get<TObjArray>("stations");
91 LOG_IF(fatal, !stations) << "TObjArray stations could not be read from file " << fDigiFile;
92 file->Close();
93 file->Delete();
94
96 gFile = oldFile;
97 gDirectory = oldDir;
98
99 fScheme->Init(stations, 0);
100 // Initialize arrays of objects
102 // Create special geometry for every module
104
105 return kSUCCESS;
106}
107
108void CbmMuchClustering::Exec(Option_t* /*opt*/)
109{
110 //static Int_t eventNo = 0;
111 TStopwatch timer;
112 timer.Start();
113 //std::cout << "CbmMuchClustering::Exec: event No=" << fNofEvents << std::endl;
114 fNofEvents++;
116 cout << "-I- " << GetName() << "::Exec: No digis found, event skipped. " << endl;
117 fNofEvents--;
118 return;
119 }
120 fNofClusters = 0;
121 // Clear output array
122 if (fHit) fHit->Clear();
123 if (fCluster) fCluster->Delete();
124 // Initialize digi charges for special geometry in one event
126 // Find clusters and hits
128 // Clear digi charges array
130 timer.Stop();
131 std::cout << "CbmMuchClustering: time " << timer.RealTime() << "; clusters: " << fNofClusters << "\n";
132}
133
134void CbmMuchClustering::Finish() { std::cout << "CbmMuchClustering::Finish" << std::endl; }
135
137{
138 FairRootManager* ioman = FairRootManager::Instance();
139 assert(ioman != NULL);
141 fDigiMan->Init();
142 fCluster = new TClonesArray("CbmMuchCluster", 1000);
143 ioman->Register("MuchCluster", "Cluster in MUCH", fCluster, IsOutputBranchPersistent("MuchCluster"));
144 fHit = new TClonesArray("CbmMuchPixelHit", 1000);
145 ioman->Register("MuchPixelHit", "Hit in MUCH", fHit, IsOutputBranchPersistent("MuchPixelHit"));
146}
147
149{
150 fNofModules = 0;
151 fModulesGeometryArray.clear();
152 Int_t iModule = 0;
153 Int_t nModules = 0;
154 // Create special geometry for all modules
155 for (Int_t iSt = 0; iSt < fScheme->GetNStations(); iSt++) {
157 Int_t nLayers = station->GetNLayers();
158 for (Int_t iL = 0; iL < nLayers; iL++) {
159 CbmMuchLayer* layer = (CbmMuchLayer*) station->GetLayer(iL);
160 CbmMuchLayerSide* lside = (CbmMuchLayerSide*) layer->GetSideF();
161 nModules = lside->GetNModules();
162 fNofModules += nModules;
163 for (Int_t iMod = 0; iMod < nModules; iMod++) {
164 // Add special module geometry in array
165 fModulesGeometryArray.push_back(new CbmClusteringGeometry(iSt, iL, 0, iMod, fScheme));
166 // Add module index in map
167 fModulesByDetId[fModulesGeometryArray[iModule]->GetDetId()] = iModule;
168 iModule++;
169 }
170 lside = (CbmMuchLayerSide*) layer->GetSideB();
171 nModules = lside->GetNModules();
172 fNofModules += nModules;
173 for (Int_t iMod = 0; iMod < nModules; iMod++) {
174 // Add special module geometry in array
175 fModulesGeometryArray.push_back(new CbmClusteringGeometry(iSt, iL, 1, iMod, fScheme));
176 // Add module index in map
177 fModulesByDetId[fModulesGeometryArray[iModule]->GetDetId()] = iModule;
178 iModule++;
179 }
180 std::cout << "Layer " << iL << " geometry created successful.\n";
181 }
182 std::cout << "Station " << iSt << " geometry created successful.\n";
183 }
184}
185
187{
188 for (Int_t iDigi = 0; iDigi < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); iDigi++) {
189 const CbmMuchDigi* muchDigi = fDigiMan->Get<CbmMuchDigi>(iDigi);
190 Long64_t chId = muchDigi->GetAddress();
192 Int_t iPad = fModulesGeometryArray[fModulesByDetId[detID]]->GetPadByChannelId(chId);
193 fModulesGeometryArray[fModulesByDetId[detID]]->SetPadCharge(iPad, muchDigi->GetAdc());
194 fModulesGeometryArray[fModulesByDetId[detID]]->SetDigiNum(iPad, iDigi);
195 fModulesGeometryArray[fModulesByDetId[detID]]->SetAPadsPlusOne();
196 }
197}
198
200{
201 for (Int_t iDigi = 0; iDigi < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); iDigi++) {
202 const CbmMuchDigi* muchDigi = fDigiMan->Get<CbmMuchDigi>(iDigi);
203 Long64_t chId = muchDigi->GetChannelId();
205 Int_t iPad = fModulesGeometryArray[fModulesByDetId[detID]]->GetPadByChannelId(chId);
206 fModulesGeometryArray[fModulesByDetId[detID]]->SetPadCharge(iPad, 0);
207 fModulesGeometryArray[fModulesByDetId[detID]]->SetDigiNum(iPad, 0);
208 fModulesGeometryArray[fModulesByDetId[detID]]->SetAPadsNom(0);
209 }
210}
211
213{
214 for (Int_t iMod = 0; iMod < fNofModules; iMod++) {
216 // Switching clustering algorithm by function SetAlgorithmVersion
217 switch (fAlgorithmVersion) {
218 case 1: { // 1 - Developed algorithm, using all neighbors
219 ClusteringA1(fModulesGeometryArray[iMod], module, 1);
220 break;
221 }
222 case 2: { // 2 - Developed algorithm, do not using diagonal neighbors
223 ClusteringA1(fModulesGeometryArray[iMod], module, 2);
224 break;
225 }
226 case 3: { // 3 - Simple Single Linkage method, using all neighbors
227 ClusteringSL(fModulesGeometryArray[iMod], module, 1);
228 break;
229 }
230 case 4: { // 4 - Simple Single Linkage method, do not using diagonal neighbors;
231 ClusteringSL(fModulesGeometryArray[iMod], module, 2);
232 break;
233 }
234 case 5: { // 5 - Ward's method (!) not tested
235 //ClusteringWard(fModulesGeometryArray[iMod], module);
236 std::cout << "CbmMuchClustering: Error! Algorithm not tested\n";
237 break;
238 }
239 default: std::cout << "CbmMuchClustering: Error! Wrong version of the algorithm.\n"; break;
240 }
241 }
242}
243
245{
246 // Create developed algorithm class for module m1
247 CbmClusteringA1* clustersA1 = new CbmClusteringA1(m1);
248 // Start algorithm
249 clustersA1->MainClusteringA1(m1, Ver);
250 // Increase number of clusters
251 fNofClusters += clustersA1->GetNofClusters();
252 // Write Clusters and Hits in output arrays
253 vector<Int_t> digiIndices;
254 for (Int_t iCl = 0; iCl < clustersA1->GetNofClusters(); iCl++) {
255 digiIndices.clear();
256 Double_t sumq = 0, sumx = 0, sumy = 0, sumt = 0, sumdx2 = 0, sumdy2 = 0, sumdxy2 = 0, sumdt2 = 0;
257 Double_t q = 0, x = 0, y = 0, t = 0, z = 0, dx = 0, dy = 0, dxy = 0, dt = 0;
258 Double_t tmin = -1;
259 x = clustersA1->GetX0(iCl);
260 y = clustersA1->GetY0(iCl);
261 z = m2->GetPosition()[2];
262 CbmMuchPad* pad = NULL;
263 Int_t address = 0;
264 Int_t planeId = 0;
265 for (Int_t iPad = 0; iPad < clustersA1->GetNofPads(iCl); iPad++) {
266 Int_t iDigi = clustersA1->GetPadInCluster(iCl, iPad);
267 const CbmMuchDigi* muchDigi = fDigiMan->Get<CbmMuchDigi>(iDigi);
268 if (iPad == 0) {
270 planeId = fScheme->GetLayerSideNr(address);
271 }
272 digiIndices.push_back(iDigi);
273 Long64_t channelId = muchDigi->GetChannelId();
274 pad = m2->GetPad(channelId);
275 t = muchDigi->GetTime();
276 if (tmin < 0) tmin = t;
277 if (tmin < t) tmin = t;
278 q = muchDigi->GetAdc();
279 dx = pad->GetDx();
280 dy = pad->GetDy();
281 dxy = pad->GetDxy();
282 dt = muchDigi->GetDTime();
283 sumq += q;
284 sumt += q * t;
285 sumdx2 += q * q * dx * dx;
286 sumdy2 += q * q * dy * dy;
287 sumdxy2 += q * q * dxy * dxy;
288 sumdt2 += q * q * dt * dt;
289 }
290 t = tmin;
291 dx = sqrt(sumdx2 / 12) / sumq;
292 dy = sqrt(sumdy2 / 12) / sumq;
293 dxy = sqrt(sumdxy2 / 12) / sumq;
294 dt = sqrt(sumdt2) / sumq;
295 Int_t nCluster = fCluster->GetEntriesFast();
296 CbmMuchCluster* cluster = new ((*fCluster)[nCluster]) CbmMuchCluster();
297 cluster->AddDigis(digiIndices);
298 Int_t nHit = fHit->GetEntriesFast();
299 new ((*fHit)[nHit]) CbmMuchPixelHit(address, x, y, z, dx, dy, 0, dxy, nCluster, planeId, t, dt);
300 }
301 delete clustersA1;
302}
303
305{
306 // Create SL algorithm class for module m1
307 CbmClusteringSL* clustersSL = new CbmClusteringSL(m1);
308 // Start algorithm
309 clustersSL->MainClusteringSL(m1, Ver);
310 // Increase number of clusters
311 fNofClusters += clustersSL->GetNofClusters();
312 // Write Clusters and Hits in output arrays
313 vector<Int_t> digiIndices;
314 for (Int_t iCl = 0; iCl < clustersSL->GetNofClusters(); iCl++) {
315 digiIndices.clear();
316 Double_t sumq = 0, sumx = 0, sumy = 0, sumt = 0, sumdx2 = 0, sumdy2 = 0, sumdxy2 = 0, sumdt2 = 0;
317 Double_t q = 0, x = 0, y = 0, t = 0, z = 0, dx = 0, dy = 0, dxy = 0, dt = 0;
318 Double_t tmin = -1;
319 x = clustersSL->GetX0(iCl);
320 y = clustersSL->GetY0(iCl);
321 z = m2->GetPosition()[2];
322 CbmMuchPad* pad = NULL;
323 Int_t address = 0;
324 Int_t planeId = 0;
325 for (Int_t iPad = 0; iPad < clustersSL->GetNofPads(iCl); iPad++) {
326 Int_t iDigi = clustersSL->GetPadInCluster(iCl, iPad);
327 const CbmMuchDigi* muchDigi = fDigiMan->Get<CbmMuchDigi>(iDigi);
328 if (iPad == 0) {
330 planeId = fScheme->GetLayerSideNr(address);
331 }
332 digiIndices.push_back(iDigi);
333 Long64_t channelId = muchDigi->GetChannelId();
334 pad = m2->GetPad(channelId);
335 t = muchDigi->GetTime();
336 if (tmin < 0) tmin = t;
337 if (tmin < t) tmin = t;
338 q = muchDigi->GetAdc();
339 dx = pad->GetDx();
340 dy = pad->GetDy();
341 dxy = pad->GetDxy();
342 dt = muchDigi->GetDTime();
343 sumq += q;
344 sumt += q * t;
345 sumdx2 += q * q * dx * dx;
346 sumdy2 += q * q * dy * dy;
347 sumdxy2 += q * q * dxy * dxy;
348 sumdt2 += q * q * dt * dt;
349 }
350 t = tmin;
351 dx = sqrt(sumdx2 / 12) / sumq;
352 dy = sqrt(sumdy2 / 12) / sumq;
353 dxy = sqrt(sumdxy2 / 12) / sumq;
354 dt = sqrt(sumdt2) / sumq;
355 Int_t nCluster = fCluster->GetEntriesFast();
356 CbmMuchCluster* cluster = new ((*fCluster)[nCluster]) CbmMuchCluster();
357 cluster->AddDigis(digiIndices);
358 Int_t nHit = fHit->GetEntriesFast();
359 new ((*fHit)[nHit]) CbmMuchPixelHit(address, x, y, z, dx, dy, 0, dxy, nCluster, planeId, t, dt);
360 }
361 delete clustersSL;
362}
363
365{
366 CbmClusteringWard* clustersWard = new CbmClusteringWard(m1, 1000);
367 clustersWard->WardMainFunction(m1, 100000);
368 fNofClusters += clustersWard->GetNofClusters();
369 for (Int_t iCl = 0; iCl < clustersWard->GetNofClusters(); iCl++) {
370 // std::cout<<">Start "<<iCl<<"\n";
371 vector<Int_t> digiIndices;
372 //---
373 //std::cout<<"=>Cluster "<<iCl<<"\n";
374 Int_t detId = m2->GetDetectorId();
375 Double_t sumq = 0, sumx = 0, sumy = 0, sumt = 0, sumdx2 = 0, sumdy2 = 0, sumdxy2 = 0, sumdt2 = 0;
376 Double_t q = 0, x = 0, y = 0, t = 0, z = 0, dx = 0, dy = 0, dxy = 0, dt = 0;
377 // std::cout<<">Values created\n";
378 x = clustersWard->GetX0(iCl);
379 y = clustersWard->GetY0(iCl);
380 z = m2->GetPosition()[2];
381 // std::cout<<">Center - ok; x: "<<x<<"; y: "<<y<<"; z: "<<z<<"\n";
382 CbmMuchPad* pad = NULL;
383 // std::cout<<">Start calculations... \n";
384 for (Int_t iPad = 0; iPad < clustersWard->GetNofPads(iCl); iPad++) {
385 Int_t iDigi = clustersWard->GetPadInCluster(iCl, iPad);
386 // std::cout<<">>iDigi: "<<iDigi;
387 const CbmMuchDigi* muchDigi = fDigiMan->Get<CbmMuchDigi>(iDigi);
388 // std::cout<<" - ok";
389 digiIndices.push_back(iDigi);
390 // std::cout<<" - ok\n";
391 Long64_t channelId = muchDigi->GetChannelId();
392 // std::cout<<">>channelId: "<<channelId<<"\n";
393 pad = m2->GetPad(channelId);
394 // std::cout<<">>Pad - ok\n";
395 t = muchDigi->GetTime();
396 q = muchDigi->GetADCCharge();
397 // std::cout<<">>t, q - ok\n";
398 dx = 1; //pad->GetDx();
399 // std::cout<<">>dx - ok\n";
400 dy = 1; //pad->GetDy();
401 // std::cout<<">>dy - ok\n";
402 dxy = pad->GetDxy();
403 // std::cout<<">>dxy - ok\n";
404 dt = muchDigi->GetDTime();
405 // std::cout<<">>dt - ok\n";
406 sumq += q;
407 sumt += q * t;
408 sumdx2 += q * q * dx * dx;
409 sumdy2 += q * q * dy * dy;
410 sumdxy2 += q * q * dxy * dxy;
411 sumdt2 += q * q * dt * dt;
412 // std::cout<<">>sum - ok\n";
413 }
414 // std::cout<<" ...finished\n";
415 t = sumt / sumq;
416 dx = sqrt(sumdx2 / 12) / sumq;
417 dy = sqrt(sumdy2 / 12) / sumq;
418 dxy = sqrt(sumdxy2 / 12) / sumq;
419 dt = sqrt(sumdt2) / sumq;
420 // std::cout<<"-----Data calculated for Cl "<<iCl<<"\n";
421 Int_t nCluster = fCluster->GetEntriesFast();
422 // std::cout<<"-------Add cluster "<<nCluster<<"; nDigis: "<<digiIndices.size();
423 CbmMuchCluster* cluster = new ((*fCluster)[nCluster]) CbmMuchCluster();
424 cluster->AddDigis(digiIndices);
425 // std::cout<<" - ok\n";
426 //---
427 Int_t planeId = fScheme->GetLayerSideNr(detId);
428 Int_t nHit = fHit->GetEntriesFast();
429 std::cout << "\nCluster: " << nHit << "; detId: " << detId << "; NofPads: " << clustersWard->GetNofPads(iCl)
430 << "\n";
431 std::cout << "x: " << x << "; y: " << y << "; z: " << z << "\n";
432 std::cout << "dx: " << dx << "; dy: " << dy << "; dxy: " << dxy << "\n";
433 std::cout << "planeId: " << planeId << "; t: " << t << "; dt: " << dt << "\n";
434 std::cout << "-------\n";
435 // std::cout<<"-------Add Hit "<<nHit;
436 new ((*fHit)[nHit]) CbmMuchPixelHit(detId, x, y, z, dx, dy, 0, dxy, nCluster, planeId, t, dt);
437 // std::cout<<" - ok\n";
438 }
439 delete clustersWard;
440}
@ kMuch
Muon detection system.
Helper functions for drawing 1D and 2D histograms and graphs.
@ kMuchModule
Module.
Data container for MUCH clusters.
ClassImp(CbmMuchClustering)
Class for pixel hits in MUCH detector.
friend fvec sqrt(const fvec &a)
void AddDigis(const std::vector< int32_t > &indices)
Add array of digi to cluster.
Definition CbmCluster.h:57
Int_t GetPadInCluster(Int_t iCluster, Int_t iPad)
Int_t GetNofClusters() const
void MainClusteringA1(CbmClusteringGeometry *moduleGeo, Int_t algVersion)
Int_t GetNofPads() const
Float_t GetX0(Int_t iCluster)
Float_t GetY0(Int_t iCluster)
Int_t GetNofPads() const
Float_t GetY0(Int_t iCluster)
void MainClusteringSL(CbmClusteringGeometry *moduleGeo, Int_t algVersion)
Int_t GetPadInCluster(Int_t iCluster, Int_t iPad)
Float_t GetX0(Int_t iCluster)
Int_t GetNofClusters() const
void WardMainFunction(CbmClusteringGeometry *moduleGeo, Float_t maxDistance)
Float_t GetX0(Int_t iCluster)
Int_t GetNofClusters() const
Int_t GetPadInCluster(Int_t iCluster, Int_t iPad)
Float_t GetY0(Int_t iCluster)
Int_t GetNofPads() const
static Int_t GetNofDigis(ECbmModuleId systemId)
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
static int32_t GetElementAddress(int32_t address, int32_t level)
Data container for MUCH clusters.
std::map< Int_t, Int_t > fModulesByDetId
void ClusteringA1(CbmClusteringGeometry *m1, CbmMuchModuleGem *m2, Int_t Ver)
CbmMuchGeoScheme * fScheme
TClonesArray * fCluster
Interface to digi data.
virtual void Exec(Option_t *opt)
CbmDigiManager * fDigiMan
CbmMuchClustering(const char *digiFileName)
void ClusteringSL(CbmClusteringGeometry *m1, CbmMuchModuleGem *m2, Int_t Ver)
virtual InitStatus Init()
void ClusteringWard(CbmClusteringGeometry *m1, CbmMuchModuleGem *m2)
TClonesArray * fHit
std::vector< CbmClusteringGeometry * > fModulesGeometryArray
int32_t GetDTime() const
uint16_t GetAdc() const
Definition CbmMuchDigi.h:90
int32_t GetAddress() const
Definition CbmMuchDigi.h:93
int32_t GetADCCharge() const
double GetTime() const
Definition CbmMuchDigi.h:94
int32_t GetChannelId() const
Int_t GetLayerSideNr(Int_t detId) const
CbmMuchStation * GetStation(Int_t iStation) const
void Init(TObjArray *stations, Int_t flag)
Int_t GetNStations() const
CbmMuchModule * GetModuleByDetId(Int_t detId) const
Int_t GetNModules() const
CbmMuchLayerSide * GetSideF()
CbmMuchLayerSide * GetSideB()
CbmMuchPad * GetPad(Int_t address)
Int_t GetDetectorId() const
TVector3 GetPosition() const
Double_t GetDy() const
Definition CbmMuchPad.h:35
Double_t GetDxy() const
Definition CbmMuchPad.h:36
Double_t GetDx() const
Definition CbmMuchPad.h:34
CbmMuchLayer * GetLayer(Int_t iLayer) const
Int_t GetNLayers() const