HighLAND
p0dExampleAnalysis.cxx
1 #include "p0dExampleAnalysis.hxx"
2 #include "FiducialVolumeDefinition.hxx"
3 #include "p0dExampleSelection.hxx"
4 #include "Parameters.hxx"
5 #include "CategoriesUtils.hxx"
6 #include "BasicUtils.hxx"
7 #include "P0DAnalysisUtils.hxx"
8 #include "P0DGeometryManager.hxx"
9 
10 #include <iostream>
11 #include <iterator>
12 
13 //***************************************************************************************
14 p0dExampleAnalysis::p0dExampleAnalysis(AnalysisAlgorithm* ana) : baseP0DAnalysis(ana) {
15 //***************************************************************************************
16 
17  // Add the package version (to be stored in the "config" tree). Nothing in this case because we are inside baseP0DAnalysis package
18  // ND::versioning().AddPackage("p0dExampleAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("P0DEXAMPLENALYSISROOT")));
19 }
20 
21 //***********************************************************
23 //***********************************************************
24 
25  // Initialize the baseP0DAnalysis
26  if(!baseP0DAnalysis::Initialize()) return false;
27 
28  // Minimum accum level to save event into the output Micro-trees
29  SetMinAccumCutLevelToSave(ND::params().GetParameterI("baseP0DAnalysis.Example.MinAccumLevelToSave"));
30 
31  // for whether or not P0D Recon directory variables are read
32  _isUsingReconDirP0D = ND::params().GetParameterI("highlandIO.FlatTree.UseReconDirP0D");
33 
34  // for whether or not P0D Recon directory variables are read
35  _isUsingReconDirP0DNew = ND::params().GetParameterI("highlandIO.P0DDataClasses.UseReconDirP0DNew");
36 
37  // parameter to control output
38  _debug = ND::params().GetParameterI("baseP0DAnalysis.Example.DebugAnalysis");
39 
40  // Add the standard categories
42 
43  return true;
44 }
45 
46 //***********************************************************
47 void p0dExampleAnalysis::DefineSelections(){
48 //***********************************************************
49 
50  //Add a simple Selection
51  sel().AddSelection("p0dExampleSelection", "Simple selection in the P0D" , new p0dExampleSelection(false));
52 }
53 
54 //**********************************************************
55 void p0dExampleAnalysis::DefineCorrections(){
56 //**********************************************************
57 
58  baseP0DAnalysis::DefineCorrections();
59 }
60 
61 //***********************************************************
62 void p0dExampleAnalysis::DefineSystematics(){
63 //***********************************************************
64 
65  baseP0DAnalysis::DefineSystematics();
66 }
67 
68 //***********************************************************
69 void p0dExampleAnalysis::DefineConfigurations(){
70 //***********************************************************
71 
72  baseP0DAnalysis::DefineConfigurations();
73 }
74 
75 //***********************************************************
76 void p0dExampleAnalysis::DefineMicroTrees(bool addBase){
77 //***********************************************************
78 
79  if (addBase) baseP0DAnalysis::DefineMicroTrees(addBase);
80 
81  AddVarVI(output(), P0DOnlyTracksInGlobalID, "ID for P0D only tracks in global", nP0DOnlyTracksInGlobal);
82  AddVarVI(output(), P0DTracksInGlobalID, "ID of P0D segment in global tracks containing P0D", nP0DTracksInGlobal);
83 
84  AddVarI(output(), nShowers, "number of showers");
85  AddVarF(output(), Shower1EDeposit, "EDeposit of first shower");
86  AddVarF(output(), Shower2EDeposit, "EDeposit of second shower");
87  AddVar3VF(output(), Shower1Direction, "Direction of first shower");
88  AddVar3VF(output(), Shower2Direction, "Direction of second shower");
89 
90  AddVar4VF(output(), truevertex_pos, "position of the selected true vertex");
91 
92  AddVarVI(output(), nClustersInVertex, "number of P0DRecon clusters associated to each vertex", nVertices);
93  AddVarVI(output(), nHitsInVertex, "number of P0DRecon hits associated to each vertex", nVertices);
94  AddVarMI(output(), ClusterInVertexTruePDG, "PDG of TrueParticle associated to cluster in vertex", nVertices,-200,100);
95  output().Add3DMatrixVar(ClusterInVertexPosition, "ClusterInVertexPosition", "F", "Position of clusters in vertex", nVertices,
96  "nVertices", -200, 100, 4);
97 
98  output().Add3DMatrixVar(HitInVertexPosition, "HitInVertexPosition", "F", "Position of hits in vertex", nVertices,
99  "nVertices", -200, 100, 4);
100 
101 
102 
103  AddVarVI(output(), nTracksInParticle, "number of P0DRecon tracks associated to each particle", nParticles);
104  AddVarVI(output(), nShowersInParticle, "number of P0DRecon showers associated to each particle", nParticles);
105  AddVarVI(output(), nNodesInParticle, "number of P0DRecon nodes associated to each particle", nParticles);
106  AddVarVI(output(), nHitsInParticle, "number of P0DRecon hits associated to each particle", nParticles);
107  AddVar4MF(output(),ParticlePosition, "number of P0DRecon tracks associated to each particle", nParticles);
108 
109  AddVarVI(output(), nClustersInParticleInVertex, "number of P0DRecon clusters associated to each particle", nParticlesInVertex);
110  AddVarVI(output(), nTracksInParticleInVertex, "number of P0DRecon tracks associated to each particle", nParticlesInVertex);
111  AddVarVI(output(), nShowersInParticleInVertex, "number of P0DRecon showers associated to each particle", nParticlesInVertex);
112  AddVarVI(output(), nNodesInParticleInVertex, "number of P0DRecon nodes associated to each particle", nParticlesInVertex);
113  AddVarVI(output(), nHitsInParticleInVertex, "number of P0DRecon hits associated to each particle", nParticlesInVertex);
114  AddVar4MF(output(),ParticleInVertexPosition, "Position of particle", nParticlesInVertex);
115  AddVarVF(output(), ParticleInVertexMomentum, "Momentum of particle (only for showers)", nParticlesInVertex);
116  AddVarVF(output(), ParticleInVertexEDeposit, "Energy deposited (only for showers)", nParticlesInVertex);
117  AddVarVF(output(), ParticleInVertexLength, "Length of particle (only for tracks)", nParticlesInVertex);
118  AddVarVI(output(), ParticleInVertexID, "Unique ID of particle", nParticlesInVertex);
119  AddVarVF(output(), ParticleInVertexTrueMomentum, "TrueMomentum of particle ", nParticlesInVertex);
120  AddVarVI(output(), ParticleInVertexTruePDG, "TruePDG of particle", nParticlesInVertex);
121  AddVarVI(output(), ParticleInVertexLink, "Has this P0D particle a link in global ?", nParticlesInVertex);
122  AddVarVI(output(), ParticleInVertexGlobal, "Is this particle a global track with a P0D segment ?", nParticlesInVertex);
123 
124  AddVarMI(output(), ClusterInParticleInVertexTruePDG, "PDG of TrueParticle associated to cluster in a particle in a vertex", nParticlesInVertex, -200,100);
125 
126  output().Add3DMatrixVar(ClusterInParticleInVertexPosition, "ClusterInParticleInVertexPosition", "F", "Position of clusters in particle in vertex", nParticlesInVertex,
127  "nParticlesInVertex", -100, 100, 4);
128 
129 
130  output().Add3DMatrixVar(HitInParticleInVertexPosition, "HitInParticleInVertexPosition", "F", "Position of hits in particle in vertex", nParticlesInVertex,
131  "nParticlesInVertex", -100, 200, 4);
132 
133  AddVarMF(output(),HitInParticleInVertexCharge, "Charge of hits in particle in vertex", nParticlesInVertex,-100, 200);
134  AddVarMI(output(),HitInParticleInVertexType, "Type (X=0, Y=1) of hits in particle in vertex", nParticlesInVertex,-100, 200);
135 
136 
137 
138  output().AddMatrixVar(ClusterPosition, "ClusterPosition", "F", "Position of clusters", nClusters,
139  "nClusters", -200, 4);
140 
141 
142  AddVarMaxSizeVI(output(), ClusterTruePDG, "PDG of TrueParticle associated to a cluster in a particle", nClusters,200);
143  AddVarMaxSizeVI(output(), nHitsInCluster, "number of P0DRecon hits associated to each cluster", nClusters,200); // extend the size of the vector to 200, default is 100
144 
145  AddVarVF(output(), vertexFiducial, "Positive values imply within Fiducial Volume", nVertices);
146  AddVarVI(output(), vertexCycle, " Vertex Cycle", nVertices);
147  AddVarVI(output(), vertexValidDim, "Vertex Valid Dimensions", nVertices);
148  AddVar4MF(output(), vertexPosition, "Vertex position", nVertices);
149 
150  AddVarI(output(), nMichel, "number of p0dreconclusters with AlgorithmName==TP0DTagMuonDecay in out-of-time bunch");
151 }
152 
153 //***********************************************************
154 void p0dExampleAnalysis::DefineTruthTree(){
155 //***********************************************************
156 
157  baseP0DAnalysis::DefineTruthTree();
158 }
159 
160 //***********************************************************
161 void p0dExampleAnalysis::FillMicroTrees(bool addBase){
162 //***********************************************************
163 
164  if (addBase) baseP0DAnalysis::FillMicroTrees(addBase);
165 
166  //-----------------Add variables to the anlysis tree -------------
167 
168  // Count the number of P0D tracks
169  AnaTrackB* p0dTracks[NMAXPARTICLES];
170  int nP0D = anaUtils::GetAllTracksUsingDet(GetBunch(), SubDetId::kP0D, p0dTracks);
171 
172  for (Int_t i=0;i<nP0D;i++){
173  if (static_cast<AnaTrack*>(p0dTracks[i])->nP0DSegments>0)
174  output().FillVectorVar(P0DTracksInGlobalID, static_cast<AnaTrack*>(p0dTracks[i])->P0DSegments[0]->UniqueID);
175  else
176  output().FillVectorVar(P0DTracksInGlobalID, 0);
177  output().IncrementCounter(nP0DTracksInGlobal);
178  }
179 
180  AnaTrackB* p0dOnlyTracks[NMAXPARTICLES];
181  int nP0DOnly = anaUtils::GetAllTracksUsingOnlyDet(GetBunch(), SubDetId::kP0D, p0dOnlyTracks);
182 
183  if (_debug) std::cout << " nP0Dtracks using _event : " << nP0D << std::endl;
184 
185  for (Int_t i=0;i<nP0DOnly;i++){
186  if (static_cast<AnaTrack*>(p0dOnlyTracks[i])->nP0DSegments>2)
187  output().FillVectorVar(P0DOnlyTracksInGlobalID, static_cast<AnaTrack*>(p0dOnlyTracks[i])->P0DSegments[0]->UniqueID);
188  else
189  output().FillVectorVar(P0DOnlyTracksInGlobalID, 0);
190  output().IncrementCounter(nP0DOnlyTracksInGlobal);
191  }
192 
193  // Use the old AnaLocalReconBunch stuff or the new strategy with fully integrated native objects
194  if (_isUsingReconDirP0DNew)
195  FillMicroTreesNative();
196  else if (_isUsingReconDirP0D)
197  FillMicroTreesLocal();
198 
199 }
200 
201 //***********************************************************
202 void p0dExampleAnalysis::FillMicroTreesLocal(){
203 //***********************************************************
204 
205  // Count the number of P0D tracks
206  AnaTrackB* p0dTracks[NMAXPARTICLES];
207  int nP0D = anaUtils::GetAllTracksUsingDet(GetBunch(), SubDetId::kP0D, p0dTracks);
208 
209  // Cast this event to the local variety
210  AnaLocalReconEvent* localEvent = NULL;
211  localEvent = static_cast<AnaLocalReconEvent*>(_event);
212 
213  // Pointer will be NULL if dynamic_cast fails
214  if(!localEvent){
215  std::cerr<<"Invalid local event, did you enable UseReconDirP0D = 1 in highlandIO.parameters.dat?\n";
216  return;
217  }
218 
219  if (_debug) std::cout << "For the iBunch value:" << GetEvent().Bunch << "the # of P0D Recon vertices" << localEvent->P0DReconVertices.size() << std::endl;
220 
221  for(std::vector<AnaP0DReconVertex*>::iterator it =localEvent->P0DReconVertices.begin(); it!= localEvent->P0DReconVertices.end(); ++it ){
222  if (_debug) std::cout << "P0DReconVertices:AlgorithmName : " << (*it)->AlgorithmName << " Cycle: " << (*it)->Cycle << " Bunch: " << (*it)->Bunch << std::endl;
223 
224  output().FillVectorVar(nClustersInVertex, (Int_t)(*it)->ClustersP.size());
225  output().FillVectorVar(nHitsInVertex, (Int_t)(*it)->Hits.size());
226 
227  output().FillVectorVar(vertexCycle, (Int_t)(*it)->Cycle);
228  output().FillVectorVar(vertexFiducial, (*it)->Fiducial);
229  output().FillVectorVar(vertexValidDim, (Int_t)(*it)->ValidDimensions);
230  output().FillMatrixVarFromArray(vertexPosition, (*it)->Position, 4 );
231 
232  output().IncrementCounter(nVertices);
233 
234  for(std::vector<AnaP0DReconParticle*>::iterator it2 =(*it)->ParticlesP.begin(); it2!= (*it)->ParticlesP.end(); ++it2 ){
235  if (_debug) std::cout << "P0DReconParticles:AlgorithmName : " << (*it2)->AlgorithmName << " Cycle: " << (*it2)->Cycle << " Bunch: " << (*it2)->Bunch << std::endl;
236 
237  if (!(*it2)) continue;
238  output().FillVectorVar(nClustersInParticleInVertex, (Int_t)(*it2)->Clusters.size());
239  output().FillVectorVar(nTracksInParticleInVertex, (Int_t)(*it2)->Tracks.size());
240  output().FillVectorVar(nShowersInParticleInVertex, (Int_t)(*it2)->Showers.size());
241  output().FillVectorVar(nNodesInParticleInVertex, (Int_t)(*it2)->Nodes.size());
242  output().FillVectorVar(nHitsInParticleInVertex, (Int_t)(*it2)->Hits.size());
243 
244  output().FillMatrixVarFromArray(ParticleInVertexPosition, (*it2)->Position, 4 );
245  output().FillVectorVar(ParticleInVertexMomentum, (*it2)->Momentum);
246  output().FillVectorVar(ParticleInVertexEDeposit, (*it2)->EDeposit);
247  output().FillVectorVar(ParticleInVertexLength, (*it2)->Length);
248  output().FillVectorVar(ParticleInVertexID, (Int_t)(*it2)->UniqueID);
249  if ((*it2)->TrueParticle){
250  output().FillVectorVar(ParticleInVertexTrueMomentum, (*it2)->TrueParticle->Momentum);
251  output().FillVectorVar(ParticleInVertexTruePDG, (*it2)->TrueParticle->PDG);
252  }
253 
254  bool found=false;
255  for (Int_t i=0;i<nP0D;i++){
256  AnaP0DParticle* part = p0dUtils::GetP0DParticle(p0dTracks[i]);
257  if (part->UniqueID == (Int_t)(*it2)->UniqueID){
258  found=true;
259  break;
260  }
261  }
262 
263  output().FillVectorVar(ParticleInVertexLink, (Int_t)found);
264 
265  output().IncrementCounter(nParticlesInVertex);
266  }
267  }
268 
269  for(std::vector<AnaP0DReconParticle*>::iterator it =localEvent->P0DReconParticles.begin(); it!= localEvent->P0DReconParticles.end(); ++it ){
270  if (_debug) std::cout << "P0DReconParticles:AlgorithmName : " << (*it)->AlgorithmName << " Cycle: " << (*it)->Cycle << " Bunch: " << (*it)->Bunch << std::endl;
271 
272  output().FillVectorVar(nTracksInParticle, (Int_t)(*it)->Tracks.size());
273  output().FillVectorVar(nShowersInParticle, (Int_t)(*it)->Showers.size());
274  output().FillVectorVar(nNodesInParticle, (Int_t)(*it)->Nodes.size());
275  output().FillVectorVar(nHitsInParticle, (Int_t)(*it)->Hits.size());
276  output().IncrementCounter(nParticles);
277  }
278 
279  for(std::vector<AnaP0DReconCluster*>::iterator it =localEvent->P0DReconClusters.begin(); it!= localEvent->P0DReconClusters.end(); ++it ){
280  if (_debug) std::cout << "P0DReconClusters:AlgorithmName : " << (*it)->AlgorithmName << " Cycle: " << (*it)->Cycle << "Bunch: " << (*it)->Bunch << std::endl;
281 
282  output().FillVectorVar(nHitsInCluster, (Int_t)(*it)->Hits.size());
283  output().IncrementCounter(nClusters);
284  }
285 
286  // Count the number of P0D michel candidates
287  int nmichels = 0;
288 
289  // Check clusters in bunches equal to or after bunch of HMNtrack
290  for (std::vector<AnaBunchC*>::iterator it = GetSpill().Bunches.begin();
291  it != GetSpill().Bunches.end(); ++it) {
292  AnaLocalReconBunch* p0dRecoBunch = dynamic_cast<AnaLocalReconBunch*> (*it);
293 
294  // Skip bunches before HMNtrack
295  // if (p0dRecoBunch->Bunch < ((AnaTrack*) box().HMNtrack)->Bunch) continue;
296 
297  for (std::vector<AnaP0DReconCluster*>::iterator it = p0dRecoBunch->P0DReconClusters.begin();
298  it != p0dRecoBunch->P0DReconClusters.end(); ++it) {
299  if (_debug) std::cout << "P0DReconCluster (*it)->AlgorithmName: " << (*it)->AlgorithmName << std::endl;
300  if (_debug) std::cout << "P0DReconCluster (*it)->Position: " << (*it)->Position << std::endl;
301  if ((*it)->AlgorithmName.compare("TP0DTagMuonDecay") == 0) nmichels += 1;
302  }
303  }
304 
305  // !!!!!!!!!!!!!!!!!! The box was not filled by the Selection. HMN will be empty
306  // Check clusters in out of bunch with time > HMNtrack->time
307  /* TODO HMNTrack not available now in the box
308  AnaLocalReconBunch* p0dRecoOutOfBunch = dynamic_cast<AnaLocalReconBunch*> (GetSpill().OutOfBunch);
309  if (p0dRecoOutOfBunch) {
310  for (std::vector<AnaP0DReconCluster*>::iterator it = p0dRecoOutOfBunch->P0DReconClusters.begin();
311  it != p0dRecoOutOfBunch->P0DReconClusters.end(); ++it) {
312  if (box().HMNtrack && (*it)->Position[3] > box().HMNtrack->PositionStart[3] &&
313  (*it)->AlgorithmName.compare("TP0DTagMuonDecay") == 0) nmichels += 1;
314  }
315  }
316  */
317  output().FillVar(nMichel, nmichels);
318 }
319 
320 //***********************************************************
321 void p0dExampleAnalysis::FillMicroTreesNative(){
322 //***********************************************************
323 
324  /*
325  This method only uses the AnaEventB. All information is fully integrated using psyche philosophy:
326  - No derived buch type
327  - No use of spill to get the michel electrons
328  */
329 
330  static P0DGeometryManager geom;
331 
332  // Cast this event to the local variety
333  AnaP0DEvent* p0dEvent = static_cast<AnaP0DEvent*>(_event);
334 
335  if (_debug){
336  std::cout << "-------------------------- AlternateEvents structure for event " << p0dEvent->EventInfo.Event
337  << " and bunch " << p0dEvent->Bunch << " --------------------------" << std::endl;
338  std::cout << " - " << p0dEvent->FullName << std::endl;
339  for (UInt_t i=0;i<p0dEvent->AlternateEvents.size();i++){
340  std::cout << " - " << p0dEvent->AlternateEvents[i]->FullName << std::endl;
341  for (UInt_t j=0;j<p0dEvent->AlternateEvents[i]->AlternateEvents.size();j++){
342  std::cout << " - " << p0dEvent->AlternateEvents[i]->AlternateEvents[j]->FullName << std::endl;
343  for (UInt_t k=0;k<p0dEvent->AlternateEvents[i]->AlternateEvents[j]->AlternateEvents.size();k++){
344  std::cout << " - " << p0dEvent->AlternateEvents[i]->AlternateEvents[j]->AlternateEvents[k]->FullName << std::endl;
345  for (UInt_t l=0;l<p0dEvent->AlternateEvents[i]->AlternateEvents[j]->AlternateEvents[k]->AlternateEvents.size();l++){
346  std::cout << " - " << p0dEvent->AlternateEvents[i]->AlternateEvents[j]->AlternateEvents[k]->AlternateEvents[l]->FullName << std::endl;
347  }
348  }
349  }
350  }
351  std::cout << "-------------------------------------------------------------------------------------------------------------" << std::endl;
352  }
353 
354  // This is just to verify that all tracks including in vertices are also in the array of tracks in the event
355  Int_t nPartsInVertices=0;
356 
357  // Get all objects containing P0D segment (global tracks and p0d only tracks)
358  AnaTrackB* p0dTracks[NMAXPARTICLES];
359  int nP0D = anaUtils::GetAllTracksUsingDet(GetEvent(), SubDetId::kP0D, p0dTracks);
360 
361  if (_debug) std::cout << "For the iBunch value:" << GetEvent().Bunch << "the # of P0D Recon vertices is " << GetEvent().nVertices << std::endl;
362 
363  // ------- Loop over vertices in the event and select the ones of type AnaP0DVertex ------------------
364 
365  // Get all vertices of type AnaP0DVertex
366  AnaP0DVertex* p0dVertices[NMAXVERTICES];
367  Int_t nVerts = p0dUtils::GetAllP0DVertices(GetEvent(),p0dVertices);
368 
369  for(Int_t iv=0;iv<nVerts; iv++ ){
370  AnaP0DVertex* p0dVertex = p0dVertices[iv];
371 
372  if (_debug) std::cout << "P0DReconVertices:AlgorithmName : " << p0dVertex->AlgorithmName << " Bunch: " << p0dVertex->Bunch << std::endl;
373 
374  // ---- Fill Vertex variables -----------
375  output().FillVectorVar(nClustersInVertex, (Int_t)p0dVertex->nClusters);
376  output().FillVectorVar(vertexFiducial, p0dVertex->Fiducial);
377  output().FillVectorVar(vertexValidDim, (Int_t)p0dVertex->ValidDimensions);
378  output().FillMatrixVarFromArray(vertexPosition, p0dVertex->Position, 4 );
379 
380  // ------ Loop over clusters in the vertex ----------
381  Int_t nhits = 0;
382  for(Int_t ic=0;ic<p0dVertex->nClusters; ic++ ){
383  AnaP0DCluster* p0dCluster = static_cast<AnaP0DCluster*>(p0dVertex->Clusters[ic]);
384 
385  // ---- Fill cluster variables -----------
386  output().Fill3DMatrixVarFromArray(ClusterInVertexPosition, p0dCluster->Position, -1, ic, 4);
387  if (p0dCluster->TrueParticle)
388  output().FillMatrixVar(ClusterInVertexTruePDG, p0dCluster->TrueParticle->PDG, -1, ic);
389 
390  // ---- Fill the Hit position ----------
391  for(Int_t ih=0;ih<p0dCluster->nHits; ih++ ){
392  if (nhits>=200) break;
393  AnaP0DHit* p0dHit = static_cast<AnaP0DHit*>(p0dCluster->Hits[ih]);
394  // Get the 3D position from the GeomID
395  TVector3 pos = geom.GeomIdPosition(p0dHit->GeomID);
396  Float_t posArray[4]={pos[0],pos[1],pos[2],p0dHit->Time};
397  // output().Fill3DMatrixVarFromArray(HitInVertexPosition, p0dHit->Position, -1, nhits, 4);
398  output().Fill3DMatrixVarFromArray(HitInVertexPosition, posArray, -1, nhits, 4);
399  nhits++;
400  }
401  }
402  output().FillVectorVar(nHitsInVertex, nhits);
403 
404 
405  // ------ Loop over particles in the vertex ----------
406  for(Int_t ip=0;ip<p0dVertex->nParticles; ip++ ){
407  // Get the P0DParticle from the track in the vertex. That means either the P0Donly track or the segment inside a global track
408  AnaP0DParticle* p0dParticle = p0dUtils::GetP0DParticle(p0dVertex->Particles[ip]);
409  if (!p0dParticle) continue;
410 
411  if (_debug) std::cout << "P0DReconParticles:AlgorithmName : " << p0dParticle->AlgorithmName << std::endl;
412 
413  // ---- Fill Particle variables -----------
414  output().FillVectorVar(nClustersInParticleInVertex, (Int_t)p0dParticle->nClusters);
415 
416  output().FillMatrixVarFromArray(ParticleInVertexPosition, p0dParticle->PositionStart, 4 );
417  output().FillVectorVar(ParticleInVertexMomentum, p0dParticle->Momentum);
418  output().FillVectorVar(ParticleInVertexEDeposit, p0dParticle->EDeposit);
419  output().FillVectorVar(ParticleInVertexLength, p0dParticle->Length);
420  output().FillVectorVar(ParticleInVertexID, (Int_t)p0dParticle->UniqueID);
421 
422  if (p0dParticle->TrueObject){
423  output().FillVectorVar(ParticleInVertexTrueMomentum, p0dParticle->GetTrueParticle()->Momentum);
424  output().FillVectorVar(ParticleInVertexTruePDG, p0dParticle->GetTrueParticle()->PDG);
425  }
426 
427  // ------ Loop over clusters in the particle ----------
428  nhits=0;
429  for(Int_t ic=0;ic<p0dParticle->nClusters; ic++ ){
430  AnaP0DCluster* p0dCluster = static_cast<AnaP0DCluster*>(p0dParticle->Clusters[ic]);
431 
432  // ---- Fill cluster variables -----------
433  output().Fill3DMatrixVarFromArray(ClusterInParticleInVertexPosition, p0dCluster->Position, -1, ic, 4);
434  if (p0dCluster->TrueParticle)
435  output().FillMatrixVar(ClusterInParticleInVertexTruePDG, p0dCluster->TrueParticle->PDG, -1, ic);
436 
437 
438  // ---- Fill the Hit variables ----------
439  for(Int_t ih=0;ih<p0dCluster->nHits; ih++ ){
440  if (nhits>=200) break;
441  AnaP0DHit* p0dHit = static_cast<AnaP0DHit*>(p0dCluster->Hits[ih]);
442  // Get the 3D position from the GeomID
443  TVector3 pos = geom.GeomIdPosition(p0dHit->GeomID);
444  Float_t posArray[4]={pos[0],pos[1],pos[2],p0dHit->Time};
445 
446  // Get the hit type
447  Int_t type = ND::GeomId::P0D::GetBarLayer(p0dHit->GeomID);
448 
449  output().Fill3DMatrixVarFromArray(HitInParticleInVertexPosition, posArray, -1, nhits, 4);
450  output().FillMatrixVar( HitInParticleInVertexCharge, p0dHit->Charge, -1, nhits);
451  output().FillMatrixVar( HitInParticleInVertexType, type, -1, nhits);
452 
453  nhits++;
454  }
455  }
456 
457  output().FillVectorVar(nHitsInParticleInVertex, nhits);
458 
459  // ------ Is there any segment in a global track with the same ID ----------
460  bool found=false;
461  for (Int_t i=0;i<nP0D;i++){
462  AnaP0DParticle* part = p0dUtils::GetP0DParticle(p0dTracks[i]);
463  if (part->UniqueID == (Int_t)p0dParticle->UniqueID){
464  found=true;
465  break;
466  }
467  }
468 
469  // output().FillVectorVar(ParticleInVertexGlobal, (Int_t)(static_cast<AnaTrack*>(p0dParticle)->nP0DSegments!=0)); TODO
470  output().FillVectorVar(ParticleInVertexLink, (Int_t)found);
471 
472  nPartsInVertices++;
473  output().IncrementCounter(nParticlesInVertex);
474  }
475 
476  output().IncrementCounter(nVertices);
477  }
478 
479  // ------ Loop over particles in the event ----------
480 
481  // This is just to verify that all tracks including in vertices are also in the array of tracks in the event
482  AnaP0DParticle* p0dParticles[NMAXPARTICLES];
483  Int_t nParts = p0dUtils::GetAllP0DParticles(GetEvent(), p0dParticles);
484  if (_debug && nParts != nPartsInVertices) std::cout << "warning: #Particles in vertices and #Particles in event differ !!!!" << std::endl;
485 
486  for(Int_t ip=0;ip<nParts; ip++ ){
487  AnaP0DParticle* p0dParticle = p0dParticles[ip];
488 
489  if (_debug) std::cout << "P0DReconParticles:AlgorithmName : " << p0dParticle->AlgorithmName << std::endl;
490 
491  output().FillMatrixVarFromArray(ParticlePosition, p0dParticle->PositionStart, 4 );
492  output().IncrementCounter(nParticles);
493  }
494 
495 
496 
497  // ---- Count the number of P0D michel candidates. This is precomputed inside oaAnalysisTreeConverter using the method p0dUtils::GetMichelElectrons
498  Int_t nmichels = static_cast<AnaEvent*>(_event)->nDelayedClusters;
499  output().FillVar(nMichel, nmichels);
500 
501  // ------ Loop over clusters in the event ----------
502  for(Int_t i = 0; i< p0dEvent->nClusters;i++ ){
503  // if (_debug) std::cout << "P0DReconClusters:AlgorithmName : " << (*it)->AlgorithmName << " Cycle: " << (*it)->Cycle << "Bunch: " << (*it)->Bunch << std::endl;
504  AnaP0DCluster* cluster = p0dEvent->Clusters[i];
505 
506  output().FillVectorVar(nHitsInCluster, cluster->nHits);
507  output().FillMatrixVarFromArray(ClusterPosition, cluster->Position,4);
508 
509  if (cluster->TrueParticle)
510  output().FillVectorVar(ClusterTruePDG, cluster->TrueParticle->PDG);
511 
512  output().IncrementCounter(nClusters);
513  }
514 
515  // ---- Fill variables needing the box (computed in the selection) -----------
516 
517  // downcast the box to the appropriate type
518  const ToyBoxP0D* p0dBox = static_cast<const ToyBoxP0D*>(&boxB());
519 
520  output().FillVar(nShowers, p0dBox->nShowers);
521 
522  if (p0dBox->Shower1){
523  output().FillVar(Shower1EDeposit, p0dBox->Shower1->EDeposit);
524  output().FillVectorVarFromArray(Shower1Direction, p0dBox->Shower1->DirectionStart,3);
525  }
526  if (p0dBox->Shower2){
527  output().FillVar(Shower2EDeposit, p0dBox->Shower2->EDeposit);
528  output().FillVectorVarFromArray(Shower2Direction, p0dBox->Shower2->DirectionStart,3);
529  }
530 
531  if (p0dBox->TrueVertex){
532  output().FillVectorVarFromArray(truevertex_pos, p0dBox->TrueVertex->Position,4);
533  }
534 
535 }
536 
537 //***********************************************************
538 void p0dExampleAnalysis::FillToyVarsInMicroTrees(bool addBase){
539 //***********************************************************
540 
541  if (addBase) baseP0DAnalysis::FillToyVarsInMicroTreesBase(addBase);
542 }
543 
544 //*********************************************************************
545 bool p0dExampleAnalysis::CheckFillTruthTree(const AnaTrueVertex& vtx){
546 //*********************************************************************
547 
548  /* To avoid unecessary events in the "truth" tree in this method we define the condition to include or not a given
549  true vertex in the tree.
550  */
551  // In this case we only save neutral currents (|ReacCode|>=30) interactions in the P0D FV
552  bool NC=(abs(vtx.ReacCode)>=30);
553  return (anaUtils::InFiducialVolume(SubDetId::kP0D, vtx.Position, FVDef::FVdefminP0D,FVDef::FVdefmaxP0D) && NC);
554 }
555 
556 //*********************************************************************
557 void p0dExampleAnalysis::FillTruthTree(const AnaTrueVertex& vtx){
558 //*********************************************************************
559 
560  baseP0DAnalysis::FillTruthTreeBase(vtx);
561 }
562 
563 //********************************************************************
564 void p0dExampleAnalysis::FillCategories(){
565 //********************************************************************
566 
567  // For the muon candidate
568  anaUtils::FillCategories(box().TrueVertex,"", SubDetId::kP0D, GetEvent().GetIsSandMC());
569 }
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...
Float_t PositionStart[4]
The reconstructed start position of the particle.
int GetAllTracksUsingOnlyDet(const AnaBunchB &bunch, SubDetId::SubDetEnum det, AnaTrackB *selTracks[])
bool Initialize()
[AnalysisAlgorithm_mandatory]
void SetMinAccumCutLevelToSave(Int_t level)
Set the minimum accumulated cut level to save an event into the micro-tree.
int GetParameterI(std::string)
Get parameter. Value is returned as integer.
Definition: Parameters.cxx:217
AnaP0DBunch & GetBunch()
Get a casted AnaBunchBB to AnaBunch from the InputManager.
Float_t Position[4]
The identified position of the global vertex.
void FillVectorVar(Int_t index, Float_t var, Int_t indx=-1)
Fill a vector variable.
std::vector< AnaBunchC * > Bunches
The reconstructed objects, split into timing bunches.
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
virtual bool Initialize()
[AnalysisAlgorithm_mandatory]
void Fill3DMatrixVarFromArray(Int_t index, const Double_t var[], Int_t indx1, Int_t indx2, UInt_t size)
Fill a 3D matrix variable from array.
int GetBarLayer(TGeometryId id)
Float_t Momentum
The initial momentum of the true particle.
AnaTrueVertexB * TrueVertex
For storing the true vertex, for analyses with no reconstructed primary vertex.
Definition: ToyBoxND280.hxx:22
Int_t Bunch
The bunch of the global vertex, based on the Position.T()
void FillMatrixVarFromArray(Int_t index, const Double_t var[], Int_t indx1, UInt_t size)
Fill a matrix variable from array.
AnaEventInfoB EventInfo
Run, sunrun, event, time stamp, etc.
Int_t UniqueID
The UniqueID of this reconstructed object.
AnaP0DEvent & GetEvent()
Get a casted AnaEventC to AnaEvent.
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo vertex.
Definition: DataClasses.hxx:50
AnaEventC * _event
The current event.
Float_t Position[4]
The position the true interaction happened at.
Int_t PDG
The PDG code of this particle.
void FillCategories(AnaEventB *event, AnaTrack *track, const std::string &prefix, const SubDetId::SubDetEnum det=SubDetId::kFGD1, bool IsAntinu=false, bool useCATSAND=true)
Fill the track categories for color drawing.
Representation of a global track.
Int_t Bunch
The index of this bunch (0-7).
TVector3 GeomIdPosition(int geomId)
AnaParticleB ** Particles
void FillVar(Int_t index, Float_t var)
Fill a single variable.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
void AddSelection(const std::string &name, const std::string &title, SelectionBase *sel, Int_t presel=-1)
Add a user selection to the selection manager.
AnaSpill & GetSpill()
Get a casted AnaSpillC to AnaSpill from the InputManager.
Int_t Event
The ND280 event number.
void AddStandardCategories(const std::string &prefix="")
Add the standard categories only, given a prefix for their name.
void AddMatrixVar(Int_t index, const std::string &name, const std::string &type, const std::string &doc, Int_t counter_index, const std::string &counter_name, int size1=-MAXVECTORSIZE, int size2=-1)
Add a matrix variable to all trees.
int GetAllTracksUsingDet(const AnaBunchB &bunch, SubDetId::SubDetEnum det, AnaTrackB *selTracks[])
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool InFiducialVolume(SubDetId::SubDetEnum det, const Float_t *pos, const Float_t *FVdefmin, const Float_t *FVdefmax)
void FillMatrixVar(Int_t index, Float_t var, Int_t indx1, Int_t indx2)
Fill a matrix variable.
void FillVectorVarFromArray(Int_t index, const Double_t var[], UInt_t size)
Fill a vector variable from array.
void Add3DMatrixVar(Int_t index, const std::string &name, const std::string &type, const std::string &doc, Int_t counter_index, const std::string &counter_name, int size1=-MAXVECTORSIZE, int size2=-1, int size3=-1)
Add a 3D matrix variable to all trees.