HighLAND
P0DAnalysisUtils.cxx
1 #include "P0DAnalysisUtils.hxx"
2 #include "EventBoxId.hxx"
3 #include <TMath.h>
4 #include <math.h>
5 
6 //********************************************************************
8 //********************************************************************
9 
10  // TODO. Is the dynamic_cast OK here ?
11  AnaP0DParticle* p0dParticle = NULL;
12  AnaTrack* track = dynamic_cast<AnaTrack*>(part);
13  if (track){
14  if (track->nP0DSegments>0)
15  p0dParticle = static_cast<AnaP0DParticle*>(track->P0DSegments[0]);
16  }
17  else
18  p0dParticle = static_cast<AnaP0DParticle*>(part);
19 
20  return p0dParticle;
21 }
22 
23 //**************************************************
24 Int_t p0dUtils::GetAllP0DParticles(const AnaEventB& event, AnaP0DParticle* selParts[]) {
25 //**************************************************
26 
27  int count = 0;
28  for (int it = 0; it < event.nParticles; it++) {
29  AnaParticleB* part = event.Particles[it];
30  AnaP0DParticle* p0dParticle = GetP0DParticle(part);
31  if (!p0dParticle) continue;
32  selParts[count] = p0dParticle;
33  count++;
34  }
35  return count;
36 }
37 
38 //**************************************************
39 Int_t p0dUtils::GetAllP0DVertices(const AnaEventB& event, AnaP0DVertex* selverts[]) {
40 //**************************************************
41 
42  // TODO. Use dynamic_cast temporarily. To be substituted by a type enum probably
43 
44  int count = 0;
45  for (int iv = 0; iv < event.nVertices; iv++) {
46  AnaP0DVertex* p0dVertex = dynamic_cast<AnaP0DVertex*>(event.Vertices[iv]);
47  if (!p0dVertex) continue;
48  selverts[count] = p0dVertex;
49  count++;
50  }
51  return count;
52 }
53 
54 //********************************************************************
55 Int_t p0dUtils::GetMichelElectrons(const AnaSpillB& spill, AnaDelayedClustersB**& delayedClusters, Int_t firstBunch){
56 //********************************************************************
57  //cout<<"in GetMichel"<<endl;
58 
59  std::vector<AnaBunchC*> bunches = spill.Bunches;
60  if (spill.OutOfBunch) bunches.push_back(spill.OutOfBunch);
61 
62  Int_t nmichels=0;
63 
64  p0dUtils::CreateArray(delayedClusters,100);
65 
66  std::vector<int> clustersUsed;
67  for (std::vector<AnaBunchC*>::iterator it = bunches.begin(); it != bunches.end(); ++it) {
68 
69  AnaP0DBunch* p0dBunch = dynamic_cast<AnaP0DBunch*> (*it);
70  if (!p0dBunch) return nmichels;
71 
72  // Skip bunches before firstBunch (except OutOfBunch, with bunch nbr -1)
73  if (p0dBunch->Bunch < firstBunch && p0dBunch->Bunch!=-1) continue;
74 
75 
76  for (Int_t c = 0 ; c<p0dBunch->nClusters; c++){
77  //cout<<"in cluster loop"<<endl;
78  AnaP0DCluster* cluster = p0dBunch->Clusters[c];
79  if (cluster->AlgorithmName.compare("TP0DTagMuonDecay") == 0 && find(clustersUsed.begin(),clustersUsed.end(),cluster->UniqueID) == clustersUsed.end() ){
80 
81  //cout<<"in if"<<endl;
82 
83  delayedClusters[nmichels] = new AnaDelayedClustersB();
84  Float_t maxTime=0;
85  Float_t minTime=1e10;
86  for (Int_t h = 0 ; h<cluster->nHits; h++){
87  AnaP0DHit* hit = cluster->Hits[h];
88  /*
89  if (hit->Position[3]>maxTime) maxTime=hit->Position[3];
90  if (hit->Position[3]<minTime) minTime=hit->Position[3];
91  */
92  if (hit->Time>maxTime) maxTime=hit->Time;
93  if (hit->Time<minTime) minTime=hit->Time;
94  delayedClusters[nmichels]->NHits++;
95  delayedClusters[nmichels]->RawChargeSum += hit->Charge;
96  }
97  delayedClusters[nmichels]->MinTime = maxTime;
98  delayedClusters[nmichels]->MaxTime = minTime;
99 
100  nmichels++;
101  clustersUsed.push_back(cluster->UniqueID);
102  }
103  }
104  }
105 
106  p0dUtils::ResizeArray(delayedClusters,nmichels);
107 
108  return nmichels;
109 }
110 
111 //********************************************************************
112 Int_t p0dUtils::GetNMichelElectrons(const AnaSpillB& spill, Int_t firstBunch){
113 //********************************************************************
114 
115  AnaDelayedClustersB** clusters;
116  return GetMichelElectrons(spill,clusters,firstBunch);
117 }
118 
119 
120 //********************************************************************
121 Int_t p0dUtils::GetMichelElectrons(AnaP0DVertex* anaP0DVertex, AnaDelayedClustersB**& delayedClusters){
122 //********************************************************************
123 
124  Int_t nmichels=0;
125 
126  p0dUtils::CreateArray(delayedClusters,100);
127 
128  if (anaP0DVertex->nClusters == 0) return nmichels;
129 
130  std::vector<int> clustersUsed;
131  for (Int_t c = 0 ; c < anaP0DVertex->nClusters; c++){
132 
133  AnaP0DCluster* cluster = anaP0DVertex->Clusters[c];
134  if (cluster->AlgorithmName.compare("TP0DTagMuonDecay") == 0 && find(clustersUsed.begin(),clustersUsed.end(),cluster->UniqueID) == clustersUsed.end() ){
135 
136  delayedClusters[nmichels] = new AnaDelayedClustersB();
137  Float_t maxTime=0;
138  Float_t minTime=1e10;
139  for (Int_t h = 0 ; h<cluster->nHits; h++){
140  AnaP0DHit* hit = cluster->Hits[h];
141  /*
142  if (hit->Position[3]>maxTime) maxTime=hit->Position[3];
143  if (hit->Position[3]<minTime) minTime=hit->Position[3];
144  */
145  if (hit->Time>maxTime) maxTime=hit->Time;
146  if (hit->Time<minTime) minTime=hit->Time;
147  delayedClusters[nmichels]->NHits++;
148  delayedClusters[nmichels]->RawChargeSum += hit->Charge;
149  }
150  delayedClusters[nmichels]->MinTime = maxTime;
151  delayedClusters[nmichels]->MaxTime = minTime;
152 
153  nmichels++;
154  clustersUsed.push_back(cluster->UniqueID);
155  }
156  }
157 
158 
159  p0dUtils::ResizeArray(delayedClusters,nmichels);
160 
161  return nmichels;
162 }
163 
164 
165 //********************************************************************
166 void p0dUtils::CreateArray(AnaDelayedClustersB** &tgtArr, int nObj){
167 //********************************************************************
168 
169  tgtArr = new AnaDelayedClustersB*[nObj];
170  for(int i = 0; i < nObj; ++i){
171  tgtArr[i] = NULL;
172  }
173 }
174 
175 //********************************************************************
176 void p0dUtils::ResizeArray(AnaDelayedClustersB** &tgtArr, int nObj){
177 //********************************************************************
178 
179  tgtArr = (AnaDelayedClustersB**) realloc (tgtArr, nObj*sizeof(AnaDelayedClustersB*));
180 }
181 
182 
183 //********************************************************************
184 void p0dUtils::CreateArray(AnaP0DVertex** &tgtArr, int nObj){
185 //********************************************************************
186 
187  tgtArr = new AnaP0DVertex*[nObj];
188  for(int i = 0; i < nObj; ++i){
189  tgtArr[i] = NULL;
190  }
191 }
192 
193 //********************************************************************
194 void p0dUtils::CopyArray(AnaP0DVertex** tgtArr, AnaP0DVertex** srcArr, int nObj){
195 //********************************************************************
196 
197  for(int i = 0; i < nObj; ++i){
198  tgtArr[i] = srcArr[i];
199  }
200 }
201 
202 //********************************************************************
203 void boxP0DUtils::FillVerticesFinal(AnaEventB& event){
204 //********************************************************************
205 
206  EventBoxP0D2* EventBox = static_cast<EventBoxP0D2*>(event.EventBoxes[EventBoxId::kEventBoxP0D]);
207 
208  // Don't fill it when already filled by other selection
209  if (EventBox->VerticesInGroup[EventBoxP0D2::kVerticesInP0DFinal]) return;
210 
211  AnaP0DVertex* vertices[NMAXVERTICES];
212  Int_t nP0D = p0dUtils::GetAllP0DVertices(event,vertices);
213  // if(NMAXTRUEPARTICLES<(UInt_t)nTPC) nTPC=NMAXTRUEPARTICLES;
214  p0dUtils::CreateArray(EventBox->VerticesInGroup[EventBoxP0D2::kVerticesInP0DFinal],nP0D);
215  p0dUtils::CopyArray(EventBox->VerticesInGroup[EventBoxP0D2::kVerticesInP0DFinal],vertices,nP0D);
216  EventBox->nVerticesInGroup[EventBoxP0D2::kVerticesInP0DFinal]= nP0D;
217 }
218 
219 
220 //********************************************************************
221 void boxP0DUtils::FillP0DParticles(AnaEventB& event){
222 //********************************************************************
223 
224  EventBoxP0D2* EventBox = static_cast<EventBoxP0D2*>(event.EventBoxes[EventBoxId::kEventBoxP0D]);
225 
226  // Don't fill it when already filled by other selection
227  if (EventBox->RecObjectsInGroup[EventBoxP0D2::kAllP0DParticles]) return;
228 
229  // Get all P0D particles
230  AnaP0DParticle* p0dParticles[NMAXPARTICLES];
231  Int_t nP0D = p0dUtils::GetAllP0DParticles(event,p0dParticles);
232  Int_t nShowers=0;
233  Int_t nTracks=0;
234 
235  // Create the variable size arrays
236  anaUtils::CreateArray(EventBox->RecObjectsInGroup[EventBoxP0D2::kAllP0DParticles],nP0D);
237  anaUtils::CreateArray(EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DTracks], nP0D);
238  anaUtils::CreateArray(EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DShowers], nP0D);
239 
240  // Fill the arrays
241  for(int i = 0; i < nP0D; ++i){
242  EventBox->RecObjectsInGroup[EventBoxP0D2::kAllP0DParticles][i] = p0dParticles[i];
243 
244  // Check whether it is a shower
245  if (p0dParticles[i]->AlgorithmName.find("Shower")!=std::string::npos)
246  EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DShowers][nShowers++] = p0dParticles[i];
247  else
248  EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DTracks][nTracks++] = p0dParticles[i];
249  }
250 
251  // Resize the arrays
252  anaUtils::ResizeArray(EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DTracks], nTracks);
253  anaUtils::ResizeArray(EventBox->RecObjectsInGroup[EventBoxP0D2::kP0DShowers], nShowers);
254 
255  // set the size
256  EventBox->nRecObjectsInGroup[EventBoxP0D2::kAllP0DParticles] = nP0D;
257  EventBox->nRecObjectsInGroup[EventBoxP0D2::kP0DShowers] = nShowers;
258  EventBox->nRecObjectsInGroup[EventBoxP0D2::kP0DTracks] = nTracks;
259 
260 }
261 
262 
263 
AnaP0DParticle * GetP0DParticle(AnaParticleB *part)
Get the P0D particle from a AnaParticleB: either a segment in a global track or the cast of the P0D-o...
int nP0DSegments
How many P0D tracks are associated with this track.
Int_t GetNMichelElectrons(const AnaSpillB &spill, Int_t firstBunch=0)
Get the number of P0D michel electrons.
Representation of a global track.
AnaP0DParticleB * P0DSegments[NMAXP0DS]
The P0D segments that contributed to this global track.
Int_t nVerticesInGroup[NMAXVERTEXGROUPS]
Different groups of tracks used for selection and systematics.
std::vector< AnaBunchC * > Bunches
The reconstructed objects, split into timing bunches.
void ResizeArray(AnaDelayedClustersB **&tgtArr, int nObj)
Resize the array.
AnaBunchB * OutOfBunch
Reconstructed objects that didn&#39;t fit into one of the timing bunches.
Int_t nRecObjectsInGroup[NMAXRECOBJECTGROUPS]
----—— RecObjects and TrueRecObjects used in the selection and systematics ------------—— ...
void CreateArray(AnaDelayedClustersB **&tgtArr, int nObj)
Create variable sized arrays of pointers.
Int_t Bunch
The index of this bunch (0-7).
Representation of a reconstructed particle (track or shower).
Int_t GetMichelElectrons(const AnaSpillB &spill, AnaDelayedClustersB **&delayedClusters, Int_t firstBunch=0)
Get the number of P0D michel electrons.