HighLAND
oaAnalysisP0DTreeConverter.cxx
1 #include "oaAnalysisTreeConverter.hxx"
2 #include "InputManager.hxx"
3 #include "Versioning.hxx"
4 #include "BasicUtils.hxx"
5 #include "HighlandAnalysisUtils.hxx"
6 #include "TreeConverterUtils.hxx"
7 #include "Parameters.hxx"
8 #include "P0DAnalysisUtils.hxx"
9 #include "P0DGeometryManager.hxx"
10 
11 // ---------- TEST HIGHLAND2-P0D -------------
12 
13 //*****************************************************************************
14 void oaAnalysisTreeConverter::GetBunchLocalP0DObjects(){
15 //*****************************************************************************
16 
17  // Clear the vectors used to create links between the local p0d recon objects: indices --> pointers
18  _AnaP0DVertices.clear();
19  _AnaP0DParticles.clear();
20  _AnaP0DClusters.clear();
21  _AnaP0DTracks.clear();
22  _AnaP0DShowers.clear();
23 
24  _AnaP0DVertices.resize(NP0DReconVertices);
25  _AnaP0DParticles.resize(NP0DReconParticles);
26  _AnaP0DClusters.resize(NP0DReconClusters);
27  _AnaP0DTracks.resize(NP0DReconTracks);
28  _AnaP0DShowers.resize(NP0DReconShowers);
29 
30  // Get index of the Top level TP0DAlgoRes as indicated in the parameters file
31  _topP0DAlgoRes=-1;
32  for (int iP0D=0; iP0D<NP0DAlgoResults; ++iP0D){
33  ND::TP0DReconModule::TP0DAlgoRes *p0dAlgoRes = (ND::TP0DReconModule::TP0DAlgoRes*) (*P0DAlgoResults)[iP0D];
34  // std::cout << p0dAlgoRes->AlgorithmName << " " << p0dAlgoRes->FullName << std::endl;
35  if (p0dAlgoRes->AlgorithmName == _p0dAlgoResName){
36  _topP0DAlgoRes = iP0D;
37  break;
38  }
39  }
40 
41  GetBunchLocalP0DObjectsInAlgoResult(_topP0DAlgoRes);
42 }
43 
44 //*****************************************************************************
45 void oaAnalysisTreeConverter::GetBunchLocalP0DObjectsInAlgoResult(Int_t iAlgoRes){
46 //*****************************************************************************
47 
48  if (iAlgoRes==-1) return;
49  ND::TP0DReconModule::TP0DAlgoRes *p0dAlgoRes = (ND::TP0DReconModule::TP0DAlgoRes*) (*P0DAlgoResults)[iAlgoRes];
50  if (!p0dAlgoRes) return;
51 
52  for (unsigned int i=0;i<NBUNCHES+1;i++){
53  _bunchP0DVerticesInAlgoRes [i][iAlgoRes].clear();
54  _bunchP0DClustersInAlgoRes [i][iAlgoRes].clear();
55  _bunchP0DParticlesInAlgoRes[i][iAlgoRes].clear();
56  _bunchP0DTracksInAlgoRes [i][iAlgoRes].clear();
57  _bunchP0DShowersInAlgoRes [i][iAlgoRes].clear();
58  }
59 
60  // Loop over all the P0D vertices in the selected AlgorithmResult
61  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->Vertices.size(); ++iP0D){
62  ND::TP0DReconModule::TP0DVertex *p0dVertex = (ND::TP0DReconModule::TP0DVertex*) (*P0DReconVertices)[p0dAlgoRes->Vertices[iP0D]];
63 
64  Int_t ibunch = _bunching.GetBunch(p0dVertex->Position.T(), RunID, IsMC, cosmic_mode);
65  if (ibunch==-1) ibunch = NBUNCHES;
66 
67  _bunchP0DVerticesInAlgoRes[ibunch][iAlgoRes].push_back(p0dAlgoRes->Vertices[iP0D]);
68  }
69 
70  // Loop over all the P0D clusters in the AlgoRes
71  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->Clusters.size(); ++iP0D){
72  ND::TP0DReconModule::TP0DCluster *p0dCluster = (ND::TP0DReconModule::TP0DCluster*) (*P0DReconClusters)[p0dAlgoRes->Clusters[iP0D]];
73 
74  Int_t ibunch = _bunching.GetBunch(p0dCluster->Position.T(), RunID, IsMC, cosmic_mode);
75  if (ibunch==-1) ibunch = NBUNCHES;
76 
77  _bunchP0DClustersInAlgoRes[ibunch][iAlgoRes].push_back(p0dAlgoRes->Clusters[iP0D]);
78  }
79 
80  // Loop over all the P0D particles in the AlgoRes
81  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->Particles.size(); ++iP0D){
82  ND::TP0DReconModule::TP0DParticle *p0dParticle = (ND::TP0DReconModule::TP0DParticle*) (*P0DReconParticles)[p0dAlgoRes->Particles[iP0D]];
83 
84  Int_t ibunch = _bunching.GetBunch(p0dParticle->Position.T(), RunID, IsMC, cosmic_mode);
85  if (ibunch==-1) ibunch = NBUNCHES;
86 
87  _bunchP0DParticlesInAlgoRes[ibunch][iAlgoRes].push_back(p0dAlgoRes->Particles[iP0D]);
88  }
89 
90  // Loop over all the P0D tracks in the AlgoRes
91  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->Tracks.size(); ++iP0D){
92  ND::TP0DReconModule::TP0DTrack *p0dTrack = (ND::TP0DReconModule::TP0DTrack*) (*P0DReconTracks)[p0dAlgoRes->Tracks[iP0D]];
93 
94  Int_t ibunch = _bunching.GetBunch(p0dTrack->Position.T(), RunID, IsMC, cosmic_mode);
95  if (ibunch==-1) ibunch = NBUNCHES;
96 
97  _bunchP0DTracksInAlgoRes[ibunch][iAlgoRes].push_back(p0dAlgoRes->Tracks[iP0D]);
98  }
99 
100  // Loop over all the P0D showers in the AlgoRes
101  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->Showers.size(); ++iP0D){
102  ND::TP0DReconModule::TP0DShower *p0dShower = (ND::TP0DReconModule::TP0DShower*) (*P0DReconShowers)[p0dAlgoRes->Showers[iP0D]];
103 
104  Int_t ibunch = _bunching.GetBunch(p0dShower->Position.T(), RunID, IsMC, cosmic_mode);
105  if (ibunch==-1) ibunch = NBUNCHES;
106 
107  _bunchP0DShowersInAlgoRes[ibunch][iAlgoRes].push_back(p0dAlgoRes->Showers[iP0D]);
108  }
109 
110  // Loop over all the P0D AlgoResults in the AlgoRes
111  for (UInt_t iP0D=0; iP0D<p0dAlgoRes->AlgoResults.size(); ++iP0D){
112  GetBunchLocalP0DObjectsInAlgoResult(p0dAlgoRes->AlgoResults[iP0D]);
113  }
114 }
115 
116 //*****************************************************************************
117 void oaAnalysisTreeConverter::FillP0DBunch(AnaBunchB* bunch, Int_t ibunch, Int_t iAlgoRes){
118 //*****************************************************************************
119 
120  if(!_isUsingReconDirP0DNew) return;
121 
122  // Cast to the P0D type
123  AnaP0DBunch* p0dBunch = static_cast<AnaP0DBunch*>(bunch);
124 
125  // Get The TP0DAlgoRes with the required index
126  if (iAlgoRes==-1) return;
127  ND::TP0DReconModule::TP0DAlgoRes *p0dAlgoRes = (ND::TP0DReconModule::TP0DAlgoRes*) (*P0DAlgoResults)[iAlgoRes];
128 
129  // Fill the P0D Water Status
130  p0dBunch->P0DWaterStatus = P0DWaterStatus;
131 
132  // Fill the FullName
133  p0dBunch->FullName = p0dAlgoRes->FullName;
134 
135  // Fill P0D vertices
136  FillP0DVertices(_bunchP0DVerticesInAlgoRes[ibunch][iAlgoRes], p0dBunch);
137 
138  // Fill P0D particles
139  FillP0DParticles( _bunchP0DParticlesInAlgoRes[ibunch][iAlgoRes], p0dBunch);
140  FillP0DParticlesFromTracks( _bunchP0DTracksInAlgoRes [ibunch][iAlgoRes], p0dBunch);
141  FillP0DParticlesFromShowers(_bunchP0DShowersInAlgoRes [ibunch][iAlgoRes], p0dBunch);
142 
143  // Fill P0D clusters
144  FillP0DClusters(_bunchP0DClustersInAlgoRes[ibunch][iAlgoRes], p0dBunch);
145 
146  // Fill Alternates
147  for (UInt_t iAlt=0;iAlt<p0dAlgoRes->AlgoResults.size();iAlt++){
148  AnaP0DBunch* alt = MakeP0DBunch();
149  p0dBunch->AlternateBunches.push_back(alt);
150  FillP0DBunch(alt, ibunch, p0dAlgoRes->AlgoResults[iAlt]);
151  }
152 }
153 
154 //*****************************************************************************
155 void oaAnalysisTreeConverter::FillP0DVertices(const std::vector<Int_t>& indices, AnaP0DBunch* bunch){
156 //*****************************************************************************
157 
158  // Loop over all the P0D vertices in the event
159  for (UInt_t iP0D=0; iP0D<indices.size(); ++iP0D){
160  ND::TP0DReconModule::TP0DVertex *p0dVertex = (ND::TP0DReconModule::TP0DVertex*) (*P0DReconVertices)[indices[iP0D]];
161 
162  // get the highland vertex
163  AnaP0DVertex *anaP0D = GetAnaP0DVertex(indices[iP0D]);
164 
165  // Fill the AnaP0DVertex with the TP0DVertex information
166  FillP0DVertexInfo(*p0dVertex,anaP0D, bunch);
167 
168  // If this object had a time outside the bunches, the anaP0D pointer is null
169  // so don't add it to the bunch or the flat tree.
170  if(anaP0D) bunch->Vertices.push_back(anaP0D);
171  }
172 }
173 
174 //*****************************************************************************
175 void oaAnalysisTreeConverter::FillP0DClusters(const std::vector<Int_t>& indices, AnaP0DBunch* bunch){
176 //*****************************************************************************
177 
178  // Create the array of clusters
179  bunch->nClusters = 0;
180  anaUtils::CreateArray(bunch->Clusters, (Int_t)indices.size());
181 
182  // Loop over all the P0D clusters in the AlgoRes
183  for (UInt_t iP0D=0; iP0D<indices.size(); ++iP0D){
184  ND::TP0DReconModule::TP0DCluster *p0dCluster = (ND::TP0DReconModule::TP0DCluster*) (*P0DReconClusters)[indices[iP0D]];
185 
186  // get the highland cluster
187  AnaP0DCluster *anaP0D = GetAnaP0DCluster(indices[iP0D]);
188 
189  // Fill the AnaP0DCluster with the TP0DCluster information
190  FillP0DClusterInfo(*p0dCluster,anaP0D);
191 
192  // If this object had a time outside the bunches, the anaP0D pointer is null
193  // so don't add it to the bunch or the flat tree.
194  if(anaP0D) bunch->Clusters[bunch->nClusters++] = anaP0D;
195  }
196 }
197 
198 //*****************************************************************************
199 void oaAnalysisTreeConverter::FillP0DParticles(const std::vector<Int_t>& indices, AnaP0DBunch* bunch){
200 //*****************************************************************************
201 
202  // Loop over all the P0D particles in the AlgoRes
203  for (UInt_t iP0D=0; iP0D<indices.size(); ++iP0D){
204  ND::TP0DReconModule::TP0DParticle *p0dParticle = (ND::TP0DReconModule::TP0DParticle*) (*P0DReconParticles)[indices[iP0D]];
205 
206  // get the highland particle
207  AnaP0DParticle *anaP0D = GetAnaP0DParticle(indices[iP0D]);
208 
209  // Fill the AnaP0DParticle with the TP0DParticle information
210  FillP0DParticleInfo(*p0dParticle,anaP0D);
211 
212  // If this object had a time outside the bunches, the anaP0D pointer is null
213  // so don't add it to the bunch or the flat tree.
214  if(anaP0D) bunch->Particles.push_back(anaP0D);
215  }
216 }
217 
218 //*****************************************************************************
219 void oaAnalysisTreeConverter::FillP0DParticlesFromTracks(const std::vector<Int_t>& indices, AnaP0DBunch* bunch){
220 //*****************************************************************************
221 
222  // Loop over all the P0D tracks in the AlgoRes
223  for (UInt_t iP0D=0; iP0D<indices.size(); ++iP0D){
224  ND::TP0DReconModule::TP0DTrack *p0dTrack = (ND::TP0DReconModule::TP0DTrack*) (*P0DReconTracks)[indices[iP0D]];
225 
226  // get the highland particle
227  AnaP0DParticle *anaP0D = GetAnaP0DParticleFromTrack(indices[iP0D]);
228 
229  // Fill the AnaP0DParticle with the TP0DTrack information
230  FillP0DParticleInfo(*p0dTrack,anaP0D);
231 
232  // If this object had a time outside the bunches, the anaP0D pointer is null
233  // so don't add it to the bunch or the flat tree.
234  if(anaP0D) bunch->Particles.push_back(anaP0D);
235  }
236 }
237 
238 //*****************************************************************************
239 void oaAnalysisTreeConverter::FillP0DParticlesFromShowers(const std::vector<Int_t>& indices, AnaP0DBunch* bunch){
240 //*****************************************************************************
241 
242  // Loop over all the P0D showers in the AlgoRes
243  for (UInt_t iP0D=0; iP0D<indices.size(); ++iP0D){
244  ND::TP0DReconModule::TP0DShower *p0dShower = (ND::TP0DReconModule::TP0DShower*) (*P0DReconShowers)[indices[iP0D]];
245 
246  // get the highland particle
247  AnaP0DParticle *anaP0D = GetAnaP0DParticleFromShower(indices[iP0D]);
248 
249  // Fill the AnaP0DParticle with the TP0DShower information
250  FillP0DParticleInfo(*p0dShower,anaP0D);
251 
252  // If this object had a time outside the bunches, the anaP0D pointer is null
253  // so don't add it to the bunch or the flat tree.
254  if(anaP0D) bunch->Particles.push_back(anaP0D);
255  }
256 }
257 
258 //*****************************************************************************
259 void oaAnalysisTreeConverter::FillP0DVertexInfo(ND::TP0DReconModule::TP0DVertex& p0dVertex, AnaP0DVertex* anaP0DVertex, AnaBunchB* bunch){
260 //*****************************************************************************
261 
262  // --- Add general info ----
263 
264  anaP0DVertex->AlgorithmName = p0dVertex.AlgorithmName;
265  anaP0DVertex->NHits = p0dVertex.NHits;
266  // anaP0DVertex->UniqueID = p0dVertex.UniqueID;
267  anaP0DVertex->Status = p0dVertex.Status;
268  anaP0DVertex->ValidDimensions = p0dVertex.ValidDimensions;
269  anaP0DVertex->Fiducial = p0dVertex.Fiducial;
270 
271  anaUtils::VectorToArray(p0dVertex.Position, anaP0DVertex->Position );
272  anaUtils::VectorToArray(p0dVertex.PosVariance, anaP0DVertex->PosVariance);
273 
274 
275  Float_t max_charge=0;
276  Int_t max_ID=-1;
277 
278  // --- Add particles to the vertex ----
279 
280  anaP0DVertex->nParticles = 0;
281  anaUtils::CreateArray(anaP0DVertex->Particles, p0dVertex.Particles.size());
282  for (UInt_t i=0;i<p0dVertex.Particles.size();i++){
283  ND::TP0DReconModule::TP0DParticle *p0dReconParticle = (ND::TP0DReconModule::TP0DParticle*) (*P0DReconParticles)[p0dVertex.Particles[i]];
284  AnaP0DParticle* p0dParticle = GetAnaP0DParticle(p0dVertex.Particles[i]);
285 
286  // Check whether this particle was already added to the bunch->Particles vector by Global (oaAnalysisTreeConverter::FillPIDs)
287  bool found=false;
288  for (UInt_t j=0;j<bunch->Particles.size();j++){
289  // The AnaParticleB can be either a global track (AnaTrack) or a AnaP0DParticle. In both cases it could have been added by global
290  // either as a global track with more constituents or as a p0d-only AnaP0DParticle
291  AnaTrack* globalTrack = dynamic_cast<AnaTrack*>(bunch->Particles[j]);
292  if (globalTrack){
293  // When it is a global track it should have a P0D segment with the same ID as the AnaP0DParticle
294  if (globalTrack->nP0DSegments!=0 && globalTrack->P0DSegments[0]->UniqueID==(Int_t)p0dReconParticle->UniqueID){
295  found=true;
296 
297  // Now we have the choice to add the global track to the vertex or just the local particle (below)
298  if (_addGlobalTracksToP0DVertices){
299  // Add the global track to the array of particles in the vertex
300  anaP0DVertex->Particles[anaP0DVertex->nParticles++] = globalTrack;
301 
302  // Stablish the link between the particle and the vertices it is associated to
303  AddReconVertexToReconParticle(anaP0DVertex, globalTrack);
304  }
305  }
306  }
307  // When it is not a global track, the ID of the AnaP0DParticle created by global should be the same as the AnaP0DParticle in p0dRecon module
308  else if ((UInt_t)bunch->Particles[j]->UniqueID==p0dReconParticle->UniqueID){
309  found=true;
310  if (_addGlobalTracksToP0DVertices){
311  // Add the AnaP0DParticle created by global to the array of particles in the vertex
312  anaP0DVertex->Particles[anaP0DVertex->nParticles++] = bunch->Particles[j];
313  // We cannot Stablish the link between the particle and the vertices it is associated to because
314  // AnaP0DParticle does not have a vector of ReconVertices (it does not inherit from AnaParticleE). TODO
315  }
316  }
317  if (found) break; // In either case the AnaP0DParticle was already found in global
318  }
319 
320 
321  // When the object found by global is added to the P0D vertex we don't need to add the one found in p0dRecon as well.
322  // In either case the AnaP0DParticle must be filled
323  if (!found || !_addGlobalTracksToP0DVertices){
324 
325  // Add the particle to the array of particles in the vertex
326  anaP0DVertex->Particles[anaP0DVertex->nParticles++] = p0dParticle;
327 
328  // Fill the particle info
329  FillP0DParticleInfo(*p0dReconParticle,p0dParticle);
330 
331  // Stablish the link between the particle and the vertices it is associated to. TODO
332  // AddReconVertexToReconParticle(anaP0DVertex, p0dParticle);
333  }
334 
335  // If this local P0DRecon object is not yet in the list of Particles (by Global) we should add it
336  if (!found){
337  // Add the particle to the vector in the bunch
338  bunch->Particles.push_back(p0dParticle);
339  }
340 
341  // Compute the true particle that contributes the most to this recon vertex
342  for(UInt_t j = 0; j < p0dReconParticle->Truth_TrajIDs.size(); j++ ){
343  if (p0dReconParticle->Truth_ChargeShare[j] > max_charge){
344  max_charge = p0dReconParticle->Truth_ChargeShare[j];
345  max_ID = p0dReconParticle->Truth_TrajIDs[j];
346  }
347  }
348  }
349 
350  // --- Add clusters to the vertex ----
351  anaP0DVertex->nClusters = 0;
352  anaUtils::CreateArray(anaP0DVertex->Clusters, p0dVertex.Clusters.size());
353  for (UInt_t i=0;i<p0dVertex.Clusters.size();i++){
354  ND::TP0DReconModule::TP0DCluster *p0dCluster2 = (ND::TP0DReconModule::TP0DCluster*) (*P0DReconClusters)[p0dVertex.Clusters[i]];
355  AnaP0DCluster* p0dCluster3 = GetAnaP0DCluster(p0dVertex.Clusters[i]);
356 
357  // Add the cluster to the array of clusters in the vertex
358  anaP0DVertex->Clusters[anaP0DVertex->nClusters++] = p0dCluster3;
359 
360  // Fill the cluster info
361  FillP0DClusterInfo(*p0dCluster2,p0dCluster3);
362  }
363 
364  // --- Associate the AnaTrueVertexB linked to the AnaTrueParticleB that contributes the most to this recon vertex ---
365  anaP0DVertex->TrueVertex=NULL;
366  std::vector<AnaTrueParticleB*>::iterator it;
367  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
368  AnaTrueParticleB* trueTrack = *it;
369  if (max_ID == trueTrack->ID){
370  anaP0DVertex->TrueVertex = trueTrack->TrueVertex;
371  static_cast<AnaTrueVertex*>(anaP0DVertex->TrueVertex)->ReconVertices.push_back(anaP0DVertex);
372  break; // Stop when association is found.
373  }
374  }
375 
376 }
377 
378 //*****************************************************************************
379 void oaAnalysisTreeConverter::FillP0DParticleInfo(ND::TP0DReconModule::TP0DParticle& p0dParticle, AnaP0DParticle* anaP0DParticle){
380 //*****************************************************************************
381 
382  // --- Add general info ----
383 
384  // This is a P0D-only object
385  SubDetId::SetDetectorUsed(anaP0DParticle->Detector, SubDetId::kP0D);
386 
387  anaUtils::VectorToArray(p0dParticle.Position, anaP0DParticle->PositionStart );
388  anaUtils::VectorToArray(p0dParticle.Direction, anaP0DParticle->DirectionStart);
389 
390  // anaP0DParticle->Type = AnaP0dParticle::kShower;
391  anaP0DParticle->AlgorithmName = p0dParticle.AlgorithmName;
392  anaP0DParticle->NHits = p0dParticle.NHits;
393  anaP0DParticle->UniqueID = p0dParticle.UniqueID;
394  anaP0DParticle->Status = p0dParticle.Status;
395  anaP0DParticle->SideDeposit = p0dParticle.SideDeposit;
396  anaP0DParticle->EndDeposit = p0dParticle.EndDeposit;
397  anaP0DParticle->ValidDimensions = p0dParticle.ValidDimensions;
398  anaP0DParticle->Momentum = p0dParticle.Momentum;
399  anaP0DParticle->Charge = p0dParticle.Charge;
400  anaP0DParticle->realPIDNames = p0dParticle.realPIDNames;
401  anaP0DParticle->realPIDValues = p0dParticle.realPIDValues;
402  anaP0DParticle->integerPIDNames = p0dParticle.integerPIDNames;
403  anaP0DParticle->integerPIDValues = p0dParticle.integerPIDValues;
404  anaP0DParticle->PID = p0dParticle.PID;
405  anaP0DParticle->PID_weight = p0dParticle.PID_weight;
406 
407  // --- Add Information only available for tracks ----
408  if (p0dParticle.Tracks.size()==1){
409  anaP0DParticle->Type = AnaP0DParticle::kTrack;
410 
411  ND::TP0DReconModule::TP0DTrack *p0dTrack = (ND::TP0DReconModule::TP0DTrack*) (*P0DReconTracks)[p0dParticle.Tracks[0]];
412  anaP0DParticle->Length = p0dTrack->Length;
413 
414  // Add the clusters to the particle
415  anaP0DParticle->nClusters = 0;
416  anaUtils::CreateArray(anaP0DParticle->Clusters, p0dTrack->Nodes.size());
417  for (UInt_t i=0;i<p0dTrack->Nodes.size();i++){
418  ND::TP0DReconModule::TP0DNode *p0dNode = (ND::TP0DReconModule::TP0DNode*) (*P0DReconNodes)[p0dTrack->Nodes[i]];
419 
420  // Must create an ad-hoc cluster since the P0DTrack does not contain clusters
421  AnaP0DCluster* p0dCluster = MakeP0DCluster();
422 
423  // Add the cluster to the array of clusters in the particle
424  anaP0DParticle->Clusters[anaP0DParticle->nClusters++] = p0dCluster;
425 
426  // Fill the cluster info from a P0DNode
427  FillP0DClusterInfo(*p0dNode,p0dCluster);
428  }
429  }
430  else if (p0dParticle.Tracks.size()>1){
431  std::cout << "more than 1 track in particle" << std::endl;
432  }
433 
434  // --- Add Information only available for showers ----
435  if (p0dParticle.Showers.size()==1){
436  anaP0DParticle->Type = AnaP0DParticle::kShower;
437 
438  ND::TP0DReconModule::TP0DShower *p0dShower = (ND::TP0DReconModule::TP0DShower*) (*P0DReconShowers)[p0dParticle.Showers[0]];
439  anaP0DParticle->EDeposit = p0dShower->EDeposit;
440 
441  // Add the clusters to the particle. Build them from clusters
442  anaP0DParticle->nClusters = 0;
443  anaUtils::CreateArray(anaP0DParticle->Clusters, p0dShower->Clusters.size());
444  for (UInt_t i=0;i<p0dShower->Clusters.size();i++){
445  ND::TP0DReconModule::TP0DCluster *p0dCluster2 = (ND::TP0DReconModule::TP0DCluster*) (*P0DReconClusters)[p0dShower->Clusters[i]];
446  AnaP0DCluster* p0dCluster3 = GetAnaP0DCluster(p0dShower->Clusters[i]);
447 
448  // Add the cluster to the array of clusters in the particle
449  anaP0DParticle->Clusters[anaP0DParticle->nClusters++] = p0dCluster3;
450 
451  // Fill the cluster info
452  FillP0DClusterInfo(*p0dCluster2,p0dCluster3);
453  }
454 
455  /*
456  // Add the clusters to the particle. Build them from nodes (Clark's advice)
457  anaP0DParticle->nClusters = 0;
458  anaUtils::CreateArray(anaP0DParticle->Clusters, p0dShower->Nodes.size());
459  for (UInt_t i=0;i<p0dShower->Nodes.size();i++){
460  ND::TP0DReconModule::TP0DNode *p0dNode = (ND::TP0DReconModule::TP0DNode*) (*P0DReconNodes)[p0dShower->Nodes[i]];
461 
462  // Must create an ad-hoc cluster since the P0DTrack does not contain clusters
463  AnaP0DCluster* p0dCluster = MakeP0DCluster();
464 
465  // Add the cluster to the array of clusters in the particle
466  anaP0DParticle->Clusters[anaP0DParticle->nClusters++] = p0dCluster;
467 
468  // Fill the cluster info from a P0DNode
469  FillP0DClusterInfo(*p0dNode,p0dCluster);
470  }
471  */
472 
473  }
474  else if (p0dParticle.Showers.size()>1){
475  std::cout << "more than 1 shower in particle" << std::endl;
476  }
477 
478 
479  //--- Compute the true particle that contributes the most to this recon particle ---
480  Float_t max_charge=0;
481  Int_t max_index=-1;
482  Float_t total_charge=0;
483  for (UInt_t i = 0; i<p0dParticle.Truth_PrimaryTrajIDs.size();i++){
484  if (p0dParticle.Truth_ChargeShare[i] > max_charge){
485  max_charge = p0dParticle.Truth_ChargeShare[i];
486  max_index = i;
487  }
488  total_charge += p0dParticle.Truth_ChargeShare[i];
489  // std::cout << p0dParticle.Truth_PrimaryTrajIDs[i] << " " << p0dParticle.Truth_TrajIDs[i] << " " << p0dParticle.Truth_HitCount[i] << " " << p0dParticle.Truth_ChargeShare[i] <<std::endl;
490  }
491 
492 
493  // --- Associate the AnaTrueParticleB that contributes the most to this recon particle ---
494  anaP0DParticle->TrueObject=NULL;
495  if (max_index>-1){
496  std::vector<AnaTrueParticleB*>::iterator it;
497  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
498  AnaTrueParticleB* trueTrack = *it;
499 
500  if (p0dParticle.Truth_TrajIDs[max_index] == trueTrack->ID){
501  anaP0DParticle->TrueObject = trueTrack;
502  if (p0dParticle.Truth_ChargeShare[max_index]/total_charge!=0)
503  static_cast<AnaTrueParticle*>(trueTrack)->Purity = p0dParticle.Truth_ChargeShare[max_index]/total_charge;
504 
505  break; // Stop when association is found.
506  }
507  }
508  }
509 
510  // --- Save all recon tracks associated to this true track ---
511  if (anaP0DParticle->TrueObject){
512  static_cast<AnaTrueParticle*>(anaP0DParticle->TrueObject)->ReconParticles.push_back(anaP0DParticle);
513 
514  if (anaP0DParticle->GetTrueParticle()->TrueVertex){
515  // Save all recon tracks associated to this true vertex (track without truth association might be missing here)
516  static_cast<AnaTrueVertex*>(anaP0DParticle->GetTrueParticle()->TrueVertex)->ReconParticles.push_back(anaP0DParticle);
517  }
518  }
519 
520 
521 
522  /*
523  for (UInt_t i = 0; i<p0dParticle.realPIDNames.size();i++){
524  std::cout << i << " (realPID): "
525  << p0dParticle.realPIDNames[i] << " --> ";
526  for (UInt_t j = 0; j<p0dParticle.realPIDValues[i].size();j++)
527  std::cout << p0dParticle.realPIDValues[i][j] << " ";
528  std::cout << std::endl;
529  }
530  for (UInt_t i = 0; i<p0dParticle.integerPIDNames.size();i++){
531  std::cout << i << " (IntPID): "
532  << p0dParticle.integerPIDNames[i] << " --> ";
533  for (UInt_t j = 0; j<p0dParticle.integerPIDValues[i].size();j++)
534  std::cout << p0dParticle.integerPIDValues[i][j] << " ";
535  std::cout << std::endl;
536  }
537 
538  for (UInt_t i = 0; i<p0dParticle.PID.size();i++)
539  std::cout << i << " (PID) : "
540  << p0dParticle.PID[i] << " "
541  << p0dParticle.PID_weight[i] << std::endl;
542  */
543 
544 }
545 
546 //*****************************************************************************
547 void oaAnalysisTreeConverter::FillP0DParticleInfo(ND::TP0DReconModule::TP0DTrack& p0dTrack, AnaP0DParticle* anaP0DParticle){
548 //*****************************************************************************
549 
550  // --- Add general info ----
551 
552  // This is a P0D-only object
553  SubDetId::SetDetectorUsed(anaP0DParticle->Detector, SubDetId::kP0D);
554 
555  anaUtils::VectorToArray(p0dTrack.Position, anaP0DParticle->PositionStart );
556  anaUtils::VectorToArray(p0dTrack.Direction, anaP0DParticle->DirectionStart);
557 
558  anaP0DParticle->Type = AnaP0DParticle::kTrack;
559  anaP0DParticle->AlgorithmName = p0dTrack.AlgorithmName;
560  anaP0DParticle->NHits = p0dTrack.NHits;
561  anaP0DParticle->UniqueID = p0dTrack.UniqueID;
562  anaP0DParticle->Status = p0dTrack.Status;
563  anaP0DParticle->SideDeposit = p0dTrack.SideDeposit;
564  anaP0DParticle->EndDeposit = p0dTrack.EndDeposit;
565  anaP0DParticle->ValidDimensions = p0dTrack.ValidDimensions;
566  /*
567  anaP0DParticle->Momentum = p0dTrack.Momentum;
568  anaP0DParticle->Charge = p0dTrack.Charge;
569  anaP0DParticle->realPIDNames = p0dTrack.realPIDNames;
570  anaP0DParticle->realPIDValues = p0dTrack.realPIDValues;
571  anaP0DParticle->integerPIDNames = p0dTrack.integerPIDNames;
572  anaP0DParticle->integerPIDValues = p0dTrack.integerPIDValues;
573  anaP0DParticle->PID = p0dTrack.PID;
574  anaP0DParticle->PID_weight = p0dTrack.PID_weight;
575  */
576  anaP0DParticle->Length = p0dTrack.Length;
577 
578  // Add the clusters to the particle
579  anaP0DParticle->nClusters = 0;
580  anaUtils::CreateArray(anaP0DParticle->Clusters, p0dTrack.Nodes.size());
581  for (UInt_t i=0;i<p0dTrack.Nodes.size();i++){
582  ND::TP0DReconModule::TP0DNode *p0dNode = (ND::TP0DReconModule::TP0DNode*) (*P0DReconNodes)[p0dTrack.Nodes[i]];
583 
584  // Must create an ad-hoc cluster since the P0DTrack does not contain clusters
585  AnaP0DCluster* p0dCluster = MakeP0DCluster();
586 
587  // Add the cluster to the array of clusters in the particle
588  anaP0DParticle->Clusters[anaP0DParticle->nClusters++] = p0dCluster;
589 
590  // Fill the cluster info from a P0DNode
591  FillP0DClusterInfo(*p0dNode,p0dCluster);
592  }
593 
594  //--- Compute the true particle that contributes the most to this recon particle ---
595  Float_t max_charge=0;
596  Int_t max_index=-1;
597  Float_t total_charge=0;
598  for (UInt_t i = 0; i<p0dTrack.Truth_PrimaryTrajIDs.size();i++){
599  if (p0dTrack.Truth_ChargeShare[i] > max_charge){
600  max_charge = p0dTrack.Truth_ChargeShare[i];
601  max_index = i;
602  }
603  total_charge += p0dTrack.Truth_ChargeShare[i];
604  // std::cout << p0dTrack.Truth_PrimaryTrajIDs[i] << " " << p0dTrack.Truth_TrajIDs[i] << " " << p0dTrack.Truth_HitCount[i] << " " << p0dTrack.Truth_ChargeShare[i] <<std::endl;
605  }
606 
607 
608  // --- Associate the AnaTrueParticleB that contributes the most to this recon particle ---
609  anaP0DParticle->TrueObject=NULL;
610  if (max_index>-1){
611  std::vector<AnaTrueParticleB*>::iterator it;
612  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
613  AnaTrueParticleB* trueTrack = *it;
614 
615  if (p0dTrack.Truth_TrajIDs[max_index] == trueTrack->ID){
616  anaP0DParticle->TrueObject = trueTrack;
617  if (p0dTrack.Truth_ChargeShare[max_index]/total_charge!=0)
618  static_cast<AnaTrueParticle*>(trueTrack)->Purity = p0dTrack.Truth_ChargeShare[max_index]/total_charge;
619 
620  break; // Stop when association is found.
621  }
622  }
623  }
624 
625  // --- Save all recon tracks associated to this true track ---
626  if (anaP0DParticle->TrueObject){
627  static_cast<AnaTrueParticle*>(anaP0DParticle->TrueObject)->ReconParticles.push_back(anaP0DParticle);
628 
629  if (anaP0DParticle->GetTrueParticle()->TrueVertex){
630  // Save all recon tracks associated to this true vertex (track without truth association might be missing here)
631  static_cast<AnaTrueVertex*>(anaP0DParticle->GetTrueParticle()->TrueVertex)->ReconParticles.push_back(anaP0DParticle);
632  }
633  }
634 
635 
636 }
637 
638 //*****************************************************************************
639 void oaAnalysisTreeConverter::FillP0DParticleInfo(ND::TP0DReconModule::TP0DShower& p0dShower, AnaP0DParticle* anaP0DParticle){
640 //*****************************************************************************
641 
642  // --- Add general info ----
643 
644  // This is a P0D-only object
645  SubDetId::SetDetectorUsed(anaP0DParticle->Detector, SubDetId::kP0D);
646 
647  anaUtils::VectorToArray(p0dShower.Position, anaP0DParticle->PositionStart );
648  anaUtils::VectorToArray(p0dShower.Direction, anaP0DParticle->DirectionStart);
649 
650  anaP0DParticle->Type = AnaP0DParticle::kShower;
651  anaP0DParticle->AlgorithmName = p0dShower.AlgorithmName;
652  anaP0DParticle->NHits = p0dShower.NHits;
653  anaP0DParticle->UniqueID = p0dShower.UniqueID;
654  anaP0DParticle->Status = p0dShower.Status;
655  anaP0DParticle->SideDeposit = p0dShower.SideDeposit;
656  anaP0DParticle->EndDeposit = p0dShower.EndDeposit;
657  anaP0DParticle->ValidDimensions = p0dShower.ValidDimensions;
658 
659  /*
660  anaP0DParticle->Momentum = p0dShower.Momentum;
661  anaP0DParticle->Charge = p0dShower.Charge;
662  anaP0DParticle->realPIDNames = p0dShower.realPIDNames;
663  anaP0DParticle->realPIDValues = p0dShower.realPIDValues;
664  anaP0DParticle->integerPIDNames = p0dShower.integerPIDNames;
665  anaP0DParticle->integerPIDValues = p0dShower.integerPIDValues;
666  anaP0DParticle->PID = p0dShower.PID;
667  anaP0DParticle->PID_weight = p0dShower.PID_weight;
668  */
669  anaP0DParticle->Length = p0dShower.Length;
670 
671  // Add the clusters to the particle
672  anaP0DParticle->nClusters = 0;
673  anaUtils::CreateArray(anaP0DParticle->Clusters, p0dShower.Nodes.size());
674  for (UInt_t i=0;i<p0dShower.Nodes.size();i++){
675  ND::TP0DReconModule::TP0DNode *p0dNode = (ND::TP0DReconModule::TP0DNode*) (*P0DReconNodes)[p0dShower.Nodes[i]];
676 
677  // Must create an ad-hoc cluster since the P0DShower does not contain clusters
678  AnaP0DCluster* p0dCluster = MakeP0DCluster();
679 
680  // Add the cluster to the array of clusters in the particle
681  anaP0DParticle->Clusters[anaP0DParticle->nClusters++] = p0dCluster;
682 
683  // Fill the cluster info from a P0DNode
684  FillP0DClusterInfo(*p0dNode,p0dCluster);
685  }
686 
687  //--- Compute the true particle that contributes the most to this recon particle ---
688  Float_t max_charge=0;
689  Int_t max_index=-1;
690  Float_t total_charge=0;
691  for (UInt_t i = 0; i<p0dShower.Truth_PrimaryTrajIDs.size();i++){
692  if (p0dShower.Truth_ChargeShare[i] > max_charge){
693  max_charge = p0dShower.Truth_ChargeShare[i];
694  max_index = i;
695  }
696  total_charge += p0dShower.Truth_ChargeShare[i];
697  // std::cout << p0dShower.Truth_PrimaryTrajIDs[i] << " " << p0dShower.Truth_TrajIDs[i] << " " << p0dShower.Truth_HitCount[i] << " " << p0dShower.Truth_ChargeShare[i] <<std::endl;
698  }
699 
700 
701  // --- Associate the AnaTrueParticleB that contributes the most to this recon particle ---
702  anaP0DParticle->TrueObject=NULL;
703  if (max_index>-1){
704  std::vector<AnaTrueParticleB*>::iterator it;
705  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
706  AnaTrueParticleB* trueTrack = *it;
707 
708  if (p0dShower.Truth_TrajIDs[max_index] == trueTrack->ID){
709  anaP0DParticle->TrueObject = trueTrack;
710  if (p0dShower.Truth_ChargeShare[max_index]/total_charge!=0)
711  static_cast<AnaTrueParticle*>(trueTrack)->Purity = p0dShower.Truth_ChargeShare[max_index]/total_charge;
712 
713  break; // Stop when association is found.
714  }
715  }
716  }
717 
718  // --- Save all recon tracks associated to this true track ---
719  if (anaP0DParticle->TrueObject){
720  static_cast<AnaTrueParticle*>(anaP0DParticle->TrueObject)->ReconParticles.push_back(anaP0DParticle);
721 
722  if (anaP0DParticle->GetTrueParticle()->TrueVertex){
723  // Save all recon tracks associated to this true vertex (track without truth association might be missing here)
724  static_cast<AnaTrueVertex*>(anaP0DParticle->GetTrueParticle()->TrueVertex)->ReconParticles.push_back(anaP0DParticle);
725  }
726  }
727 
728 
729 }
730 
731 
732 //*****************************************************************************
733 void oaAnalysisTreeConverter::FillP0DClusterInfo(ND::TP0DReconModule::TP0DCluster& p0dCluster, AnaP0DCluster* anaP0DCluster){
734 //*****************************************************************************
735 
736  anaP0DCluster->AlgorithmName = p0dCluster.AlgorithmName;
737  anaP0DCluster->UniqueID = p0dCluster.UniqueID;
738  anaP0DCluster->ValidDimensions = p0dCluster.ValidDimensions;
739  // anaP0DCluster->NFiducialHits = p0dCluster.NFiducialHits;
740  anaP0DCluster->EDeposit = p0dCluster.EDeposit;
741 
742  anaUtils::CopyArray(p0dCluster.Moments, anaP0DCluster->Moments, 9);
743 
744  anaUtils::VectorToArray(p0dCluster.Position, anaP0DCluster->Position );
745  anaUtils::VectorToArray(p0dCluster.PosVariance, anaP0DCluster->PosVariance);
746 
747  // Add the hits to the cluster
748  anaP0DCluster->nHits = 0;
749  anaUtils::CreateArray(anaP0DCluster->Hits, p0dCluster.Hits.size());
750  for (UInt_t i=0;i<p0dCluster.Hits.size();i++){
751  ND::TP0DReconModule::TP0DHit *p0dHit = (ND::TP0DReconModule::TP0DHit*) (*P0DReconHits)[p0dCluster.Hits[i]];
752 
753  // Must create an ad-hoc hit since the P0DTrack does not contain hits
754  AnaP0DHit* p0dHit2 = MakeP0DHit();
755 
756  // Add the hit to the array of hits in the cluster
757  anaP0DCluster->Hits[anaP0DCluster->nHits++] = p0dHit2;
758 
759  // Fill the hit info from a P0DNode
760  FillP0DHitInfo(*p0dHit,p0dHit2);
761  }
762 
763  //--- Compute the true particle that contributes the most to this recon cluster ---
764  Float_t max_charge=0;
765  Int_t max_index=-1;
766  for (UInt_t i = 0; i<p0dCluster.Truth_PrimaryTrajIDs.size();i++){
767  if (p0dCluster.Truth_ChargeShare[i] > max_charge){
768  max_charge = p0dCluster.Truth_ChargeShare[i];
769  max_index = i;
770  }
771  }
772 
773  // --- Associate the AnaTrueParticleB that contributes the most to this recon particle ---
774  anaP0DCluster->TrueParticle=NULL;
775  if (max_index>-1){
776  std::vector<AnaTrueParticleB*>::iterator it;
777  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
778  AnaTrueParticleB* trueTrack = *it;
779  if (p0dCluster.Truth_TrajIDs[max_index] == trueTrack->ID){
780  anaP0DCluster->TrueParticle = static_cast<AnaTrueParticleB*>(trueTrack);
781  break; // Stop when association is found.
782  }
783  }
784  }
785 
786 }
787 
788 //*****************************************************************************
789 void oaAnalysisTreeConverter::FillP0DClusterInfo(ND::TP0DReconModule::TP0DNode& p0dNode, AnaP0DCluster* anaP0DCluster){
790 //*****************************************************************************
791 
792  // anaP0DCluster->AlgorithmName = p0dNode.AlgorithmName;
793  // anaP0DCluster->UniqueID = p0dNode.UniqueID;
794  anaP0DCluster->ValidDimensions = p0dNode.ValidDimensions;
795  // anaP0DCluster->NFiducialHits = p0dNode.NFiducialHits;
796  anaP0DCluster->EDeposit = p0dNode.EDeposit;
797 
798  anaUtils::VectorToArray(p0dNode.Position, anaP0DCluster->Position );
799  anaUtils::VectorToArray(p0dNode.PosVariance, anaP0DCluster->PosVariance);
800 
801  // Add the hits to the cluster
802  anaP0DCluster->nHits = 0;
803  anaUtils::CreateArray(anaP0DCluster->Hits, p0dNode.Hits.size());
804  for (UInt_t i=0;i<p0dNode.Hits.size();i++){
805  ND::TP0DReconModule::TP0DHit *p0dHit = (ND::TP0DReconModule::TP0DHit*) (*P0DReconHits)[p0dNode.Hits[i]];
806 
807  // Must create an ad-hoc hit since the P0DTrack does not contain hits
808  AnaP0DHit* p0dHit2 = MakeP0DHit();
809 
810  // Add the hit to the array of hits in the cluster
811  anaP0DCluster->Hits[anaP0DCluster->nHits++] = p0dHit2;
812 
813  // Fill the hit info from a P0DNode
814  FillP0DHitInfo(*p0dHit,p0dHit2);
815  }
816 
817 
818  //--- Compute the true particle that contributes the most to this recon cluster ---
819  Float_t max_charge=0;
820  Int_t max_index=-1;
821  for (UInt_t i = 0; i<p0dNode.Truth_PrimaryTrajIDs.size();i++){
822  if (p0dNode.Truth_ChargeShare[i] > max_charge){
823  max_charge = p0dNode.Truth_ChargeShare[i];
824  max_index = i;
825  }
826  }
827 
828  // --- Associate the AnaTrueParticleB that contributes the most to this recon particle ---
829  anaP0DCluster->TrueParticle=NULL;
830  if (max_index>-1){
831  std::vector<AnaTrueParticleB*>::iterator it;
832  for (it = _spill->TrueParticles.begin(); it!=_spill->TrueParticles.end();it++){
833  AnaTrueParticleB* trueTrack = *it;
834  if (p0dNode.Truth_TrajIDs[max_index] == trueTrack->ID){
835  anaP0DCluster->TrueParticle = static_cast<AnaTrueParticleB*>(trueTrack);
836  break; // Stop when association is found.
837  }
838  }
839  }
840 
841 }
842 
843 //*****************************************************************************
844 void oaAnalysisTreeConverter::FillP0DHitInfo(ND::TP0DReconModule::TP0DHit& p0dHit, AnaP0DHit* anaP0DHit){
845 //*****************************************************************************
846 
847 /*
848  // Get the 3D position from the GeomID
849  static P0DGeometryManager geom;
850  TVector3 pos = geom.GeomIdPosition(p0dHit.GeomID);
851  for (Int_t i=0;i<3;i++)
852  anaP0DHit->Position[i] = pos[i];
853 
854  // Set the time
855  anaP0DHit->Position[3] = p0dHit.Time;
856 
857 
858  // Set the hit type
859  Int_t type = ND::GeomId::P0D::GetBarLayer(p0dHit.GeomID);
860 
861  if (type==0) anaP0DHit->Type = AnaP0DHit::kXHit;
862  else if (type==1) anaP0DHit->Type = AnaP0DHit::kYHit;
863 */
864 
865  // Set the hit charge
866  anaP0DHit->Charge = p0dHit.Charge;
867 
868  anaP0DHit->GeomID = p0dHit.GeomID;
869  // anaP0DHit->ChanID = p0dHit.ChanID;
870  anaP0DHit->Time = p0dHit.Time;
871 }
872 
873 //*****************************************************************************
874 ND::TP0DReconModule::TP0DParticle* oaAnalysisTreeConverter::GetP0DReconParticleWithUniqueID(UInt_t uniqueID){
875 //*****************************************************************************
876 
877  ND::TP0DReconModule::TP0DParticle *p0dParticle = NULL;
878  for (Int_t i=0;i<NP0DReconParticles;i++){
879  ND::TP0DReconModule::TP0DParticle *p0dReconParticle = (ND::TP0DReconModule::TP0DParticle*) (*P0DReconParticles)[i];
880  if (p0dReconParticle->UniqueID == uniqueID){
881  p0dParticle = p0dReconParticle;
882  break;
883  }
884  }
885 
886  return p0dParticle;
887 }
888 
889 
890 //*****************************************************************************
891 void oaAnalysisTreeConverter::AddReconVertexToReconParticle(AnaVertexB* vertex, AnaTrack* part){
892 //*****************************************************************************
893 
894  part->ReconVertices.push_back(vertex);
895  // choose the vertex more primary
896  if ( ! part->ReconVertex || part->ReconVertex->PrimaryIndex > vertex->PrimaryIndex) {
897  // also check it is in the same bunch, so it will be the same in the flattree
898  if ( vertex->Bunch == part->Bunch) {
899  part->ReconVertex = vertex;
900  // part->MomentumAtVertex = vConst->Momentum.Mag();
901  // anaUtils::VectorToArray((1 / part->MomentumAtVertex) * vConst->Momentum, part->DirectionAtVertex);
902  }
903  }
904 }
905 
906 //*****************************************************************************
907 void oaAnalysisTreeConverter::FillDelayedClustersInfo(AnaSpill& spill){
908 //*****************************************************************************
909 
910  for (std::vector<AnaBunchC*>::iterator it = spill.Bunches.begin(); it != spill.Bunches.end(); ++it) {
911  AnaBunch* bunch = static_cast<AnaBunch*> (*it);
912 
913  bunch->nDelayedClusters = p0dUtils::GetMichelElectrons(spill, bunch->DelayedClusters, bunch->Bunch);
914  }
915 }
916 
917 //*****************************************************************************
918 AnaP0DVertex* oaAnalysisTreeConverter::GetAnaP0DVertex(Int_t index){
919 //*****************************************************************************
920 
921  if (_AnaP0DVertices[index]) return _AnaP0DVertices[index];
922 
923  _AnaP0DVertices[index] = MakeP0DVertex();
924  return _AnaP0DVertices[index];
925 }
926 
927 //*****************************************************************************
928 AnaP0DCluster* oaAnalysisTreeConverter::GetAnaP0DCluster(Int_t index){
929 //*****************************************************************************
930 
931  if (_AnaP0DClusters[index]) return _AnaP0DClusters[index];
932 
933  _AnaP0DClusters[index] = MakeP0DCluster();
934  return _AnaP0DClusters[index];
935 }
936 
937 //*****************************************************************************
938 AnaP0DParticle* oaAnalysisTreeConverter::GetAnaP0DParticle(Int_t index){
939 //*****************************************************************************
940 
941  if (_AnaP0DParticles[index]) return _AnaP0DParticles[index];
942 
943  _AnaP0DParticles[index] = MakeP0DParticle();
944  return _AnaP0DParticles[index];
945 }
946 
947 //*****************************************************************************
948 AnaP0DParticle* oaAnalysisTreeConverter::GetAnaP0DParticleFromTrack(Int_t index){
949 //*****************************************************************************
950 
951  if (_AnaP0DTracks[index]) return _AnaP0DTracks[index];
952 
953  _AnaP0DTracks[index] = MakeP0DParticle();
954  return _AnaP0DTracks[index];
955 }
956 
957 //*****************************************************************************
958 AnaP0DParticle* oaAnalysisTreeConverter::GetAnaP0DParticleFromShower(Int_t index){
959 //*****************************************************************************
960 
961  if (_AnaP0DShowers[index]) return _AnaP0DShowers[index];
962 
963  _AnaP0DShowers[index] = MakeP0DParticle();
964  return _AnaP0DShowers[index];
965 }
bool cosmic_mode
Whether we&#39;re running in "cosmic" mode, where there is only one bunch.
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
int nP0DSegments
How many P0D tracks are associated with this track.
Float_t PositionStart[4]
The reconstructed start position of the particle.
Representation of a global track.
AnaTrueVertexB * TrueVertex
AnaP0DParticleB * P0DSegments[NMAXP0DS]
The P0D segments that contributed to this global track.
unsigned long Detector
Int_t Status
The Status of the fit of this reconstructed object.
Float_t Position[4]
The identified position of the global vertex.
std::vector< AnaBunchC * > Bunches
The reconstructed objects, split into timing bunches.
Int_t Bunch
The bunch of the track, based on the PositionStart.T()
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
Float_t Moments[9]
Moments of the Cluster.
Int_t Bunch
The bunch of the global vertex, based on the Position.T()
Int_t UniqueID
The UniqueID of this reconstructed object.
Float_t Charge
The reconstructed charge of the particle.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
std::vector< AnaVertexB * > Vertices
AnaDelayedClustersB ** DelayedClusters
The delayed cluster groups.
static void SetDetectorUsed(unsigned long &BitField, SubDetId::SubDetEnum det)
Method to set a certain subdetector or subdetector system to used used.
Definition: SubDetId.cxx:36
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo vertex.
Definition: DataClasses.hxx:50
Representation of a true Monte Carlo trajectory/particle.
Int_t NHits
The number of hits in the particle.
AnaParticleB ** Particles
std::vector< AnaTrueParticleB * > TrueParticles
The true MC particles used in this spill.
Representation of a global vertex.
AnaVertexB * ReconVertex
The pointer to the most primary AnaVertexB (global vertex) associated with this track.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
Int_t Bunch
The index of this bunch (0-7).
std::vector< AnaVertexB * > ReconVertices
Vector of pointers to AnaVertexB (global vertices) associated with this track.
Int_t PrimaryIndex
Index of the global vertex.
std::vector< AnaParticleB * > Particles
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
Int_t GetBunch(Float_t tTrack, Int_t run, bool isMC, bool cosmic_mode, Float_t sigma=15., Float_t NSigmas=4.0) const
The run number for a given time.
Representation of a true Monte Carlo trajectory/particle.
Int_t GetMichelElectrons(const AnaSpillB &spill, AnaDelayedClustersB **&delayedClusters, Int_t firstBunch=0)
Get the number of P0D michel electrons.