FairRoot/PandaRoot
PndEmcCluster.cxx
Go to the documentation of this file.
1 //---------------------------------------------------------------------
2 // Description:
3 // energy() returns energy sum of digis in cluster.
4 // where() returns a TVector3 at the centre of the
5 // cluster.
6 // x() returns the x element of this.
7 // y() returns the y element of this.
8 // z() returns the z element of this.
9 //
10 // Software developed for the BaBar Detector at the SLAC B-Factory.
11 // Adapted for the PANDA experiment at GSI
12 //
13 // Author List:
14 // Xiaorong Shi Lawrence Livermore National Lab
15 // Steve Playfer University of Edinburgh
16 // Stephen Gowdy University of Edinburgh
17 // Helmut Marsiske SLAC
18 
19 //---------------------------------------------------------------------
20 
21 #include "PndEmcCluster.h"
22 
23 #include "FairRunAna.h"
24 
25 #include "PndEmcDigi.h"
26 #include "PndEmcXtal.h"
27 #include "PndEmcStructure.h"
28 #include "TVector3.h"
29 #include "TClonesArray.h"
30 
31 #include <iostream>
32 #include <iomanip>
33 #include <cmath>
34 #include <algorithm>
35 #include <cfloat>
36 #include <vector>
37 #include <utility>
38 #include "assert.h"
39 
40 using std::endl;
41 using std::vector;
42 
43 
44 //----------------
45 // Constructors --
46 //----------------
47 
49  fDigiList(),
50  fMcList(),
51  fMemberDigiMap(),
52  fLocalMaxMap(),
53  fEnergyValid( false ),
54  fEnergy( 0 ),
55  fWhereValid( false ),
56  fWhere( TVector3(0,0,0) ),
57  fNbumps(0),
58  fZ20(0),
59  fZ53(0),
60  fLatMom(0),
61  fTrackEntering(),
62  fTrackExiting()
63 {
64  fDigiList.clear();
65  fMcList.clear();
66  fMemberDigiMap.clear();
67  fLocalMaxMap.clear();
68 }
69 
70 
71 //--------------
72 // Destructor --
73 //--------------
74 
76 {}
77 
80 {
81  if (fEnergyValid)
82  return fEnergy;
83  else
84  {
85  std::cout<<"Energy of cluster is not defined"<<std::endl;
86  abort();
87  }
88 }
89 
90 
93 {
94  return where().Theta();
95 }
96 
99 {
100  return where().Phi();
101 }
102 
103 TVector3
105 {
106  return this->where();
107 }
108 
109 
110 TVector3
112 {
113  if (fWhereValid)
114  return fWhere;
115  else
116  {
117  std::cout<<"Position of cluster is not defined"<<std::endl;
118  abort();
119  }
120 }
121 
122 Double_t
124 {
125  return where().x();
126 }
127 
128 Double_t
130 {
131  return where().y();
132 }
133 
134 Double_t
136 {
137  return where().z();
138 }
139 
140  Double_t
142 {
143  Double_t diff;
144  diff = phi1 - phi2;
145 
146  while( diff> TMath::Pi() ) diff -= 2*TMath::Pi();
147  while( diff< -TMath::Pi() ) diff += 2*TMath::Pi();
148 
149  return diff;
150 }
151 
152 //-------------
153 // Modifiers --
154 //-------------
155 
156  void
157 PndEmcCluster::addDigi(const TClonesArray *digiArray, Int_t iDigi)
158 {
159  fDigiList.push_back(iDigi);
160  PndEmcDigi *digi= (PndEmcDigi *) digiArray->At(iDigi);
161  Int_t detectorId =digi->GetDetectorId();
162  fMemberDigiMap.insert(std::pair<Int_t,Int_t>(detectorId, iDigi));
163 
164  fTimeStamp = (digi->GetTimeStamp() > this->GetTimeStamp()) ? digi->GetTimeStamp() : this->GetTimeStamp();
165  //std::cout<<"digi belongs to track #"<<digi->GetTrackId()<<std::endl;
166  ++fMcMap[digi->GetTrackId()];
167  invalidateCache(kFALSE);
168  SetInsertHistory(kFALSE);
169  if(FairRunAna::Instance()->IsTimeStamp()) {
170  AddLink((static_cast<PndEmcDigi*>(digiArray->At(iDigi))->GetEntryNr()));
171  } else {
172  AddLink(FairLink(-1, FairRootManager::Instance()->GetEntryNr(), "EmcDigi", iDigi));
173  }
174  SetInsertHistory(kTRUE);
175 }
176  void
177 PndEmcCluster::removeDigi(const TClonesArray *digiArray, Int_t iDigi)
178 {
179  for(size_t i=0;i<fDigiList.size();++i){
180  if(fDigiList[i] == iDigi){
181  fDigiList.erase(fDigiList.begin()+i);
182  break;
183  }
184  }
185  PndEmcDigi *digi= (PndEmcDigi *) digiArray->At(iDigi);
186  Int_t detectorId =digi->GetDetectorId();
187  fMemberDigiMap.erase(detectorId);
188  --fMcMap[digi->GetTrackId()];
189 }
190  std::vector<Int_t>::iterator
191 PndEmcCluster::removeDigi(const TClonesArray *digiArray, std::vector<Int_t>::iterator iDigi)
192 {
193  PndEmcDigi *digi= (PndEmcDigi *) digiArray->At(*iDigi);
194  //std::cout << "removing digi (ptr|detId): (" << digi << " | " << digi->GetDetectorId() << ")" << std::endl;
195 
196  std::map<Int_t, Int_t>::iterator it = fMemberDigiMap.find(digi->GetDetectorId());
197  if(it != fMemberDigiMap.end() && it->second == *iDigi) {
198  fMemberDigiMap.erase(it);
199  }
200 
201  --fMcMap[digi->GetTrackId()];
202  return fDigiList.erase(iDigi);
203 }
204 
205  void
206 PndEmcCluster::addCluster(PndEmcCluster* cluster, const TClonesArray *digiArray)
207 {
208  const vector<Int_t> tmpList = cluster->DigiList();
209  vector<Int_t>::const_iterator digi_iter;
210  for (digi_iter=tmpList.begin();digi_iter!=tmpList.end();++digi_iter)
211  {
212  addDigi(digiArray, *digi_iter);
213  }
215  AddLinks(cluster->GetLinks());
216 }
217 
218 void PndEmcCluster::addLocalMax(const TClonesArray *digiArray, Int_t iDigi)
219 {
220  PndEmcDigi *digi= (PndEmcDigi *) digiArray->At(iDigi);
221  Int_t detectorId =digi->GetDetectorId();
222  fLocalMaxMap.insert(std::pair<Int_t,Int_t>(detectorId, iDigi));
223 };
224 
226 {
227  Int_t detectorId =digi->GetDetectorId();
228  Int_t iDigi= fMemberDigiMap.find(detectorId)->second;
229  fLocalMaxMap.insert(std::pair<Int_t,Int_t>(detectorId, iDigi));
230 };
231 
232 //check if a digi belong to this cluster
233  bool
234 PndEmcCluster::isInCluster( PndEmcDigi* theDigi, const TClonesArray *digiArray)
235 {
236  vector<Int_t>::iterator digi_iter;
237  for (digi_iter=fDigiList.begin();digi_iter!=fDigiList.end();++digi_iter)
238  {
239  if(theDigi->isNeighbour((PndEmcDigi *) digiArray->At(*digi_iter))) return true;
240  }
241 
242  return false;
243 }
244 
245 // Returnd digi with the highest energy in cluster
246 const PndEmcDigi*
247 PndEmcCluster::Maxima(const TClonesArray *digiArray) const
248 {
249  Double_t max=0;
250  PndEmcDigi *biggest=0;
251 
252  std::vector<Int_t>::const_iterator digipos;
253  for (digipos=fDigiList.begin();digipos!=fDigiList.end();++digipos){
254  PndEmcDigi *digi = (PndEmcDigi *) digiArray->At(*digipos);
255  if ( max < digi->GetEnergy() ) {
256  max=digi->GetEnergy();
257  biggest=digi;
258  }
259  }
260 
261  return( biggest );
262 }
263 
264  PndEmcDigi*
265 PndEmcCluster::Maxima(const TClonesArray *digiArray)
266 {
267  Double_t max=0;
268  PndEmcDigi *biggest=0;
269 
270  std::vector<Int_t>::iterator digipos;
271  for (digipos=fDigiList.begin();digipos!=fDigiList.end();++digipos){
272  PndEmcDigi *digi = (PndEmcDigi *) digiArray->At(*digipos);
273  if ( max < digi->GetEnergy() ) {
274  max=digi->GetEnergy();
275  biggest=digi;
276  }
277  }
278 
279  return( biggest );
280 }
281 
283 {
284  // Get module in which cluster is located
285  // If fLocalMaxMap is defined, i.e. after bump splitting procedure
286  // the number of module if taken from the first local maxima.
287  // Otherwise it is taken from the first digi in cluster.
288  Short_t module;
289  Int_t detectorId;
290  if (fLocalMaxMap.size()>0)
291  {
292  std::map<Int_t,Int_t>::const_iterator iter=fLocalMaxMap.begin();
293  detectorId=iter->first;
294  }
295  else
296  {
297  std::map<Int_t,Int_t>::const_iterator iter=fMemberDigiMap.begin();
298  detectorId=iter->first;
299  }
300 
301  module=detectorId/100000000;
302 
303  return module;
304 };
305 
306 typedef std::pair<Int_t,Int_t> map_ele;
307 struct Ascend
308 {
309  bool operator()(const map_ele& a, const map_ele& b){
310  //std::cout<<"a = "<<a.second<<", b = "<<b.second<<std::endl;
311  return a.second > b.second;
312  }
313 };
314 const std::vector<Int_t>& PndEmcCluster::GetMcList() const {
315  std::vector< map_ele > sortedVec;
316  std::vector<FairLink> mcLinks;
317  FairMultiLinkedData mcFairLinks = GetLinksWithType(FairRootManager::Instance()->GetBranchId("MCTrack"));
318 
319  for (int i = 0; i < mcFairLinks.GetNLinks(); i++){
320  mcLinks.push_back(mcFairLinks.GetLink(i));
321  }
322 
323  std::sort(mcLinks.begin(), mcLinks.end(), [](const FairLink& a, const FairLink& b) -> bool {
324  return a.GetIndex() < b.GetIndex();
325  });
326 
327  fMcList.clear();
328  for (auto link : mcLinks)
329  fMcList.push_back(link.GetIndex());
330  return fMcList;
331 }
332 
333  void
335 {
336  fEnergyValid = kState;
337  fWhereValid = kState;
338 }
339 
340 Int_t
342 {
343  return fDigiList.size();
344 }
345 
347 {
348  return fNbumps;
349 }
350 
351 void
352 PndEmcCluster::SetNBumps(unsigned nbumps) {
353  fNbumps = nbumps;
354 }
355 
356 void
357 PndEmcCluster::Print(const Option_t* ) const
358 {
359  std::cout<<"*********************************"<< endl;
360  std::cout<<"total energy of cluster: "<< energy() << endl;
361  std::cout <<"TrackEntering: " << fTrackEntering << std::endl;
362  std::cout <<"TrackExiting: " << fTrackExiting << std::endl;
363 }
364 
365 
366 Double_t
367 PndEmcCluster::DistanceToCentre( const TVector3& aPoint ) const
368 {
369  return ( where() - aPoint ).Mag();
370 }
371 
372 Double_t
374 {
375  return ( where() - aDigi->where() ).Mag();
376 }
377 
378 Double_t
380 {
381  Double_t e=this->energy();
382  TVector3 clusterPosition= this->where();
383  Double_t theta_cluster=clusterPosition.Theta();
384 
385  Double_t e1=e;
386  Double_t theta1=theta_cluster;
387 
388  if ( (clusterPosition.Z() < 180.0)&&(theta_cluster<140.*TMath::Pi()/180.))
389  {
390  if (e<0.03) e1 = 0.03;
391  if (e>8.0) e1 = 8.0 ;
392  }
393 
394  if ( (clusterPosition.Z() < 180.0)&&(theta_cluster>140.*TMath::Pi()/180.))
395  {
396  if (e<0.03) e1 = 0.03;
397  if (e>2.0) e1 = 2.0 ;
398  }
399 
400  if (clusterPosition.Z() > 180.0)
401  {
402  if (e<0.01) e1 = 0.01;
403  if (e>16.0) e1 = 16.0 ;
404  }
405 
406  double b0 = 1.45312;
407  double b1 = 2.79086e-02;
408  double b2 = 3.91932e-04;
409  double b3 =-1.23117e-03;
410  double b4 = 2.72270e-01;
411  double b5 =-1.31540;
412  double b6 = 1.44447;
413  double b7 =-4.05724e-01;
414  double b8 =-2.07396;
415  double b9 = 4.80507e-02;
416 
417  double p0=0;
418  double p1=0;
419  double p2=0;
420  double p3=0;
421  double p4=0;
422  double p5=0;
423  double p6=0;
424  double p7=0;
425  double p8=0;
426  double p9=0;
427 
428  if(e1<1.0)
429  {
430  p0 = 4.13189e-02;
431  p1 = -2.03834e-02;
432  p2 = -2.58086e-03;
433  p3 = -1.77821e-03;
434  p4 = -1.73738e-02;
435  p5 = 7.40362e-02;
436  p6 = -6.41892e-02;
437  p7 = -9.85564e-02;
438  p8 = 1.50123e-01;
439  p9 = -7.87742e-04;
440  }
441  else
442  {
443  p0 = 5.05003e-02;
444  p1 = -3.47672e-02;
445  p2 = 3.72767e-02;
446  p3 = -1.26492e-02;
447  p4 = -2.16876e-02;
448  p5 = 1.02682e-01;
449  p6 = -9.85242e-02;
450  p7 = -1.39872e-01;
451  p8 = 2.02309e-01;
452  p9 = 1.11696e-03;
453  }
454 
455 
456  double t0 = 1.81631;
457  double t1 =-1.71202e-02;
458  double t2 = 3.59161e-03;
459  double t3 =-3.46712e-04;
460  double t4 =-3.73691e-01;
461  double t5 =-1.56688;
462  double t6 =-1.62618;
463  double t7 =-4.10972e-01;
464  double t8 = 2.2222;
465  double t9 = 4.60908e-03;
466 
467 
468  double factor1= p0
469  +p1*log(e1)
470  +p2*log(e1)*log(e1)
471  +p3*log(e1)*log(e1)*log(e1)
472  +p4*cos(theta1)
473  +p5*cos(theta1)*cos(theta1)
474  +p6*cos(theta1)*cos(theta1)*cos(theta1)
475  +p7*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
476  +p8*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
477  +p9*log(e1)*cos(theta1);
478 
479  double factor2= t0
480  +t1*log(e1)
481  +t2*log(e1)*log(e1)
482  +t3*log(e1)*log(e1)*log(e1)
483  +t4*cos(theta1)
484  +t5*cos(theta1)*cos(theta1)
485  +t6*cos(theta1)*cos(theta1)*cos(theta1)
486  +t7*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
487  +t8*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
488  +t9*log(e1)*cos(theta1);
489 
490 
491  double factor3= b0
492  +b1*log(e1)
493  +b2*log(e1)*log(e1)
494  +b3*log(e1)*log(e1)*log(e1)
495  +b4*cos(theta1)
496  +b5*cos(theta1)*cos(theta1)
497  +b6*cos(theta1)*cos(theta1)*cos(theta1)
498  +b7*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
499  +b8*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)*cos(theta1)
500  +b9*log(e1)*cos(theta1);
501 
502 
503  double eout1=e* exp(factor1);
504  double eout2=e* exp(factor2);
505  double eout3=e* exp(factor3);
506 
507  double eout4=(3.31694-0.0183379/sqrt(e1)+0.0327113/e1+0.00040156/(e1*e1)-0.00641305/(e1*sqrt(e1)))*e/3.0144;
508 
509 
510 
511  if ( clusterPosition.Z() > 500.0)
512  return eout4;
513  else if ( (clusterPosition.Z() < 180.0)&&(theta_cluster>140.*TMath::Pi()/180.))
514  return eout3;
515  else if ( (clusterPosition.Z() < 180.0)&&(theta_cluster<140.*TMath::Pi()/180.))
516  return eout1;
517  else
518  return eout2;
519 
520 }
521 
535 void PndEmcCluster::AddTracksEnteringExiting(const FairMultiLinkedData& tracksEntering, const FairMultiLinkedData& tracksExiting)
536 {
537  std::map<FairLink, LinkScoreBoard> scoreBoard;
538  std::set<FairLink> entering, exiting;
539 
540 // std::cout << "tracksEntering " << tracksEntering << std::endl;
541 // std::cout << "tracksExiting " << tracksExiting << std::endl;
542 // std::cout << "existingEntering " << fTrackEntering << std::endl;
543 // std::cout << "existingExiting " << fTrackExiting << std::endl;
544 
545  FillScoreBoard(tracksEntering, scoreBoard, 3);
546  FillScoreBoard(tracksExiting, scoreBoard, 2);
547  FillScoreBoard(fTrackEntering, scoreBoard, 1);
548  FillScoreBoard(fTrackExiting, scoreBoard, 0);
549 
550  for (std::map<FairLink, LinkScoreBoard>::iterator iter = scoreBoard.begin(); iter != scoreBoard.end(); iter++){
551  //std::cout << iter->first << " " << iter->second.score << std::endl;
552  switch (iter->second.score){
553  case 15: entering.insert(iter->first); exiting.insert(iter->first); break;
554  case 14: entering.insert(iter->first); break;
555  case 13: exiting.insert(iter->first); break;
556  case 12: entering.insert(iter->first); exiting.insert(iter->first); break;
557  case 11: entering.insert(iter->first); break;
558  case 10: std::cout << "-E- PndEmcCluster::AddTracksEnteringExiting Same particle entering twice!" << std::endl; break;
559  case 9: break;
560  case 8: entering.insert(iter->first); break;
561  case 7: exiting.insert(iter->first); break;
562  case 6: break;
563  case 5: std::cout << "-E- PndEmcCluster::AddTracksEnteringExiting Same particle exiting twice!" << std::endl; break;
564  case 4: exiting.insert(iter->first); break;
565  case 3: entering.insert(iter->first); exiting.insert(iter->first); break;
566  case 2: entering.insert(iter->first); break;
567  case 1: exiting.insert(iter->first); break;
568  case 0: break;
569  default: std::cout << "-E- PndEmcCluster::AddTracksEnteringExiting wrong score " << iter->second.score << std::endl; break;
570  }
571  }
572  fTrackEntering.SetLinks(entering);
573  fTrackExiting.SetLinks(exiting);
574 
575 // std::cout << "Entering after merge " << fTrackEntering << std::endl;
576 // std::cout << "Exiting after merge " << fTrackExiting << std::endl;
577 }
578 
579 
580 void PndEmcCluster::FillScoreBoard(FairMultiLinkedData tracks, std::map<FairLink, LinkScoreBoard>& scoreBoard, Int_t shift)
581 {
582  std::set<FairLink> links = tracks.GetLinks();
583  for (std::set<FairLink>::iterator linkIter = links.begin(); linkIter != links.end(); linkIter++){
584  scoreBoard[*linkIter].SetValShift(kTRUE, shift);
585  }
586 }
587 
virtual void Print(const Option_t *opt="") const
Double_t fEnergy
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
std::pair< Int_t, Int_t > map_ele
TClonesArray * digi
bool isInCluster(PndEmcDigi *theDigi, const TClonesArray *digiArray)
Int_t t2
Definition: hist-t7.C:106
TVector3 where() const
virtual Double_t GetEnergy() const
Definition: PndEmcDigi.cxx:296
represents the reconstructed hit of one emc crystal
Definition: PndEmcDigi.h:40
friend F32vec4 exp(const F32vec4 &a)
Definition: P4_F32vec4.h:109
Int_t i
Definition: run_full.C:25
TTree * b
Short_t GetModule() const
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
Int_t GetDetectorId() const
Definition: PndEmcDigi.h:97
std::map< Int_t, Int_t > fMcMap
TVector3 fWhere
virtual ~PndEmcCluster()
bool operator()(const map_ele &a, const map_ele &b)
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
virtual void SetNBumps(unsigned nbumps)
const std::vector< Int_t > & DigiList() const
Definition: PndEmcCluster.h:40
Int_t GetTrackId() const
Definition: PndEmcDigi.h:96
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:26
void AddTracksEnteringExiting(const FairMultiLinkedData &tracksEntering, const FairMultiLinkedData &tracksExiting)
Updates the links to entering and exiting tracks.
const std::vector< Int_t > & GetMcList() const
Int_t t1
Definition: hist-t7.C:106
void addCluster(PndEmcCluster *cluster, const TClonesArray *digiArray)
TVector3 position() const
Double_t z() const
FairMultiLinkedData GetTrackExiting() const
Int_t a
Definition: anaLmdDigi.C:126
FairMultiLinkedData fTrackExiting
Int_t t0
Definition: hist-t7.C:106
virtual const PndEmcDigi * Maxima(const TClonesArray *digiArray) const
Double_t
std::vector< Int_t > fMcList
FairMultiLinkedData fTrackEntering
virtual Double_t DistanceToCentre(const TVector3 &aPoint) const
Double_t x() const
virtual void removeDigi(const TClonesArray *digiArray, Int_t iDigi)
Int_t t3
Definition: hist-t7.C:106
a cluster (group of neighboring crystals) of hit emc crystals
Definition: PndEmcCluster.h:29
std::map< Int_t, Int_t > fMemberDigiMap
TPad * p2
Definition: hist-t7.C:117
Int_t NumberOfDigis() const
Int_t NBumps() const
void invalidateCache(bool)
Double_t GetEnergyCorrected() const
virtual Double_t energy() const
ClassImp(PndAnaContFact)
TPad * p1
Definition: hist-t7.C:116
const TVector3 & where() const
Definition: PndEmcDigi.h:111
std::vector< Int_t > fDigiList
Double_t theta() const
virtual void addLocalMax(const TClonesArray *digiArray, Int_t iDigi)
bool isNeighbour(const PndEmcDigi *theDigi) const
Definition: PndEmcDigi.cxx:201
Double_t Pi
Double_t phi() const
std::map< Int_t, Int_t > fLocalMaxMap
Double_t y() const
FairMultiLinkedData GetTrackEntering() const
static Double_t FindPhiDiff(Double_t, Double_t)
virtual void addDigi(const TClonesArray *digiArray, Int_t iDigi)
unsigned fNbumps
void FillScoreBoard(FairMultiLinkedData tracks, std::map< FairLink, LinkScoreBoard > &scoreBoard, Int_t shift)