eventAnalysis  7.0-49-g0ac7482
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
TReconPerformanceEvalModule.cxx
Go to the documentation of this file.
2 
3 #include <TParticlePDG.h>
4 #include <TString.h>
5 #include <HelixModel.hxx>
6 #include <ND280GeomId.hxx>
7 #include <ReconObjectUtils.hxx>
8 #include <ReconPrintout.hxx>
9 #include <TG4Trajectory.hxx>
10 #include <TG4TrajectoryPoint.hxx>
11 #include <TGeomIdManager.hxx>
12 #include <TEventReconUtils.hxx>
13 #include <TrackTruthInfo.hxx>
14 #include <TrackingUtils.hxx>
15 #include <cmath>
16 #include "TDatum.hxx"
17 #include "TGeomInfo.hxx"
18 #include "TOARuntimeParams.hxx"
19 #include "TPrincipal.h"
20 #include "TRealDatum.hxx"
21 #include "TReconNode.hxx"
22 
33 
34 #define CVSTAG \
35  "\
36  $Name: 7.0$"
37 #define CVSID \
38  "\
39  $Id: eventAnalysis TReconPerformanceEvalModule.cxx,2024/03/20:09:46:10,Alexander_J_Finch,lapw.lancs.ac.uk $"
40 
42  const char* name, const char* title) {
43  SetNameTitle(name, title);
44  fIsEnabled = kTRUE;
45  fDescription = "Global Recon Inputs and Outputs";
47  fCVSID = CVSID;
48 
49  // Tree variables
50  fGlobalReconObjects = new TClonesArray(
51  "ND::TReconPerformanceEvalModule::TGlobalReconObject", 200);
52 
53  // Whether to save info on all global nodes or just the first and last ones
54  fSaveAllGlobalNodes = true;
55 }
56 
58 
60  ND::TND280Event& event) {
61  return true;
62 }
63 
65  ND::TND280Event& event) {
66  return (fNGlobalReconObjects ? true : false);
67 }
68 
70 
72  // Number of global recon objects
73  fOutputTree->Branch("NGlobalReconObject", &fNGlobalReconObjects,
74  "NGlobalReconObject/I", fBufferSize);
75 
76  // TClonesArray of TGlobalReconObject objects
77  fOutputTree->Branch("GlobalReconObject", &fGlobalReconObjects, fBufferSize,
78  fSplitLevel);
79 
80  // Number of hits in each subdetector
81  fOutputTree->Branch("HitInfo", &fHitInfo, fBufferSize, fSplitLevel);
82 }
83 
85  if (fFilledConfigTree) {
86  ND280NamedWarn(
87  "TReconPerformanceEvalModule",
88  "Module: " << this->GetName()
89  << " has already written the config tree this run.");
90  }
91 
92  configTree->Branch("SaveAllGlobalNodes", &fSaveAllGlobalNodes,
93  "SaveAllGlobalNodes/O");
94 
96 }
97 
98 bool ND::TReconPerformanceEvalModule::FillTree(ND::TND280Event& event) {
99  // Initialise
100  fNGlobalReconObjects = 0;
101  fGlobalReconObjects->Clear();
102  fHitInfo.clear();
103 
104  ND::THandle<ND::TAlgorithmResult> globalResult = event.GetFit("oaRecon");
105 
106  if (globalResult) {
107  ND280Verbose("Got global result for event ID " << event.GetEventId());
108  for (ND::TDataVector::iterator dataIter = globalResult->begin();
109  dataIter != globalResult->end(); ++dataIter) {
110  // Looking for ObjectContainers that are labelled correctly
111  std::string class_name = (*dataIter)->ClassName();
112  TString object_name = (*dataIter)->GetName();
113 
114  if (class_name.find("ND::TReconObjectContainer") != std::string::npos &&
115  object_name.EqualTo("final")) {
116  ND::TReconObjectContainer* reconContainer =
117  dynamic_cast<ND::TReconObjectContainer*>(*dataIter);
118 
119  if (!reconContainer) {
120  ND280Warn("Dynamic cast of ReconObjectContainer didn't work");
121  }
122 
123  // Loop looking for objects in the top recon container
124  for (ND::TReconObjectContainer::iterator reconIter =
125  reconContainer->begin();
126  reconIter != reconContainer->end(); ++reconIter) {
127  // Get the global object and fill information related to it
128  ND::THandle<ND::TReconBase> globalObject = (*reconIter);
129 
130  TGlobalReconObject* globalReconObject =
131  new ((*fGlobalReconObjects)[fNGlobalReconObjects])
133 
134  FillGlobalInfo(event, globalObject, globalReconObject);
135  fNGlobalReconObjects++;
136 
137  ND::TReconObjectContainer conContainer =
138  GetConstituentsOfInterest(globalObject);
139  ND280Verbose(" Next PID - got " << conContainer.size()
140  << " constituents, "
141  << globalObject->ConvertDetector());
142 
143  // Loop over the constituents and fill information related to each
144  for (ND::TReconObjectContainer::iterator conIter =
145  conContainer.begin();
146  conIter != conContainer.end(); ++conIter) {
147  ND::THandle<ND::TReconBase> base = (*conIter);
148 
149  ND280Verbose(" " << base->ClassName() << " from "
150  << base->ConvertDetector());
151  TGlobalReconConstituent* constituent =
152  new ((*(globalReconObject
153  ->Constituents))[globalReconObject->NConstituents])
155  FillConstituentInfo(event, base, globalObject, constituent);
156 
157  // Fill counters of how many objects we have in total, and in each
158  // module
159  globalReconObject->NConstituents++;
160 
161  std::string det = base->ConvertDetector();
162  (*(globalReconObject->NModuleConstituents))[det]++;
163  }
164 
165  // For PIDs that are made of tracker + "something", see what effect
166  // adding the "something" has
167  if (ContainsTracker(globalObject) && !IsOnlyTracker(globalObject)) {
168  ND::TReconObjectContainer trackerConContainer =
169  GetDownToTracker(globalObject);
170  ND280Verbose(" Next PID - got "
171  << trackerConContainer.size()
172  << " constituents on way to tracker, "
173  << globalObject->ConvertDetector());
174 
175  for (ND::TReconObjectContainer::iterator conIter =
176  trackerConContainer.begin();
177  conIter != trackerConContainer.end(); ++conIter) {
178  ND::THandle<ND::TReconBase> base = (*conIter);
179 
180  ND280Verbose(" " << base->ClassName() << " from "
181  << base->ConvertDetector());
182  TDownToTrackerInfo* constituent =
183  new ((*(globalReconObject->DownToTrackerConstituents))
184  [globalReconObject->NDownToTrackerConstituents])
186  FillDownToTrackerInfo(base, constituent);
187  globalReconObject->NDownToTrackerConstituents++;
188  }
189  }
190 
191  // Fill information on the matching chi^2s that went in to this object
192  ND::TReconObjectContainer mConContainer =
193  ReconObjectUtils::GetConstituentsRecursive(globalObject, true);
194  ND280Verbose(" Got " << mConContainer.size()
195  << " constituents for matching chi^2");
196 
197  for (ND::TReconObjectContainer::iterator conIter =
198  mConContainer.begin();
199  conIter != mConContainer.end(); ++conIter) {
200  ND::THandle<ND::TReconBase> base = (*conIter);
201 
202  if (base->Has<ND::TRealDatum>("matching_chi2ndf")) {
203  TMatchingChi2Info* matchInfo = new (
204  (*(globalReconObject->MatchingChi2Info))
205  [globalReconObject->NMatchingChi2Info]) TMatchingChi2Info;
206  double matchVal = TrackingUtils::GetMatchingChi2(*base);
207  ND::THandle<ND::TReconObjectContainer> cons =
208  base->GetConstituents();
209 
210  if (cons && cons->size() == 2) {
211  ND::THandle<ND::TReconBase> con1 = cons->at(0);
212  ND::THandle<ND::TReconBase> con2 = cons->at(1);
213  matchInfo->Det1 = con1->ConvertDetector();
214  matchInfo->Det2 = con2->ConvertDetector();
215  matchInfo->IsShower1 = TrackingUtils::IsShower(con1);
216  matchInfo->IsShower2 = TrackingUtils::IsShower(con2);
217  matchInfo->MatchingChi2 = matchVal;
218  matchInfo->SetOK = true;
219  }
220 
221  globalReconObject->NMatchingChi2Info++;
222  }
223  }
224  }
225  }
226  }
227  }
228 
229  // Fill hit information
230  ND::THandle<ND::TDataVector> hitsData = event.Get<ND::TDataVector>("hits");
231  for (ND::TDataVector::iterator dataIter = hitsData->begin();
232  dataIter != hitsData->end(); ++dataIter) {
233  TString object_name = (*dataIter)->GetName();
234  ND::THitSelection* hits = dynamic_cast<ND::THitSelection*>(*dataIter);
235  fHitInfo[object_name.Data()] = hits->size();
236  }
237 
238  return true;
239 }
240 
241 /// Get the constituents of a global PID that we wish to investigate further.
242 /// Gets the list of unique highest-level constituents in each subdetector.
243 ND::TReconObjectContainer
245  ND::THandle<ND::TReconBase> input) {
246  ND::TReconObjectContainer allCons;
247 
248  static const int NDETS = 19;
249  ND::TReconBase::Status dets[NDETS] = {
252  ND::TReconBase::kTPC3, ND::TReconBase::kDSECal,
253  ND::TReconBase::kRightTECal, ND::TReconBase::kLeftTECal,
254  ND::TReconBase::kBottomTECal, ND::TReconBase::kTopTECal,
255  ND::TReconBase::kRightPECal, ND::TReconBase::kLeftPECal,
256  ND::TReconBase::kBottomPECal, ND::TReconBase::kTopPECal,
257  ND::TReconBase::kP0D, ND::TReconBase::kRightSMRD,
258  ND::TReconBase::kLeftSMRD, ND::TReconBase::kBottomSMRD,
259  ND::TReconBase::kTopSMRD};
260 
261  for (int ii = 0; ii < NDETS; ii++) {
262  ND::TReconObjectContainer cons =
263  ReconObjectUtils::GetAllConstituentsInDetector(input, dets[ii]);
264  for (ND::TReconObjectContainer::const_iterator it1 = cons.begin();
265  it1 != cons.end(); it1++) {
266  // Ensure the constituent is unique
267  bool unique = true;
268  for (ND::TReconObjectContainer::const_iterator it2 = allCons.begin();
269  it2 != allCons.end(); it2++) {
270  if ((*it1) == (*it2)) {
271  unique = false;
272  break;
273  }
274  }
275  if (unique) {
276  allCons.push_back(*it1);
277  }
278  }
279  }
280 
281  return allCons;
282 }
283 
284 /// Get the list of constituents that are found on the way down to getting the
285 /// tracker-only constituent
287  ND::THandle<ND::TReconBase> input) {
288  ND::TReconObjectContainer allCons;
289 
290  if (IsOnlyTracker(input)) {
291  allCons.push_back(input);
292  } else if (ContainsTracker(input)) {
293  allCons.push_back(input);
294  ND::THandle<ND::TReconObjectContainer> cons = input->GetConstituents();
295 
296  if (cons) {
297  for (ND::TReconObjectContainer::const_iterator it = cons->begin();
298  it != cons->end(); it++) {
299  ND::TReconObjectContainer moreCons = GetDownToTracker(*it);
300 
301  for (ND::TReconObjectContainer::const_iterator it2 = moreCons.begin();
302  it2 != moreCons.end(); it2++) {
303  allCons.push_back(*it2);
304  }
305  }
306  }
307  }
308 
309  return allCons;
310 }
311 
313  ND::THandle<ND::TReconBase> input) {
314  ND::TReconBase::Status notTrackerDets[14] = {
315  ND::TReconBase::kDSECal, ND::TReconBase::kRightTECal,
316  ND::TReconBase::kLeftTECal, ND::TReconBase::kBottomTECal,
317  ND::TReconBase::kTopTECal, ND::TReconBase::kRightPECal,
318  ND::TReconBase::kLeftPECal, ND::TReconBase::kBottomPECal,
319  ND::TReconBase::kTopPECal, ND::TReconBase::kP0D,
320  ND::TReconBase::kRightSMRD, ND::TReconBase::kLeftSMRD,
321  ND::TReconBase::kBottomSMRD, ND::TReconBase::kTopSMRD};
322 
323  // Ensure that the object doesn't use non-tracker modules
324  for (int ii = 0; ii < 14; ii++) {
325  if (input->UsesDetector(notTrackerDets[ii])) {
326  return false;
327  }
328  }
329 
330  // Ensure that it does use tracker modules
331  return ContainsTracker(input);
332 }
333 
335  ND::THandle<ND::TReconBase> input) {
336  return (input->UsesDetector(ND::TReconBase::kTPC) ||
337  input->UsesDetector(ND::TReconBase::kFGD));
338 }
339 
340 /// Fill information in the output tree relating to the global PID
342  ND::TND280Event& event, ND::THandle<ND::TReconBase> reconObject,
343  TGlobalReconObject* output) {
344  ND::THandle<ND::TReconState> globalState;
345 
346  try {
347  globalState = reconObject->GetState();
348  } catch (ND::EReconObject e) {
349  ND280Warn("TReconBase with no state. Skip object!");
350  return;
351  }
352 
353  output->UniqueID = reconObject->GetUniqueID();
354  output->Momentum = GetStateMomentum(globalState);
355  // output->MomentumByRange = TrackingUtils::GetMomentumByRange(*reconObject);
356  const double MomentumByRangeDefault = -10000;
358  *reconObject, "prange_muon", MomentumByRangeDefault);
360  *reconObject, "prange_muon_flipped", MomentumByRangeDefault);
362  *reconObject, "prange_electron", MomentumByRangeDefault);
364  *reconObject, "prange_electron_flipped", MomentumByRangeDefault);
366  *reconObject, "prange_proton", MomentumByRangeDefault);
368  *reconObject, "prange_proton_flipped", MomentumByRangeDefault);
369 
370  output->Position = GetStatePosition(globalState);
371  output->Direction = GetStateDirection(globalState);
372  output->Quality = reconObject->GetQuality();
373  output->NDOF = reconObject->GetNDOF();
374  output->SubdetectorString = reconObject->ConvertDetector();
375  output->StatusString = reconObject->ConvertStatus();
376 
377  ND::THandle<ND::TReconPID> pid = reconObject;
378  if (pid) {
379  output->ParticleID = pid->ConvertParticleId();
380  output->PIDWeight = pid->GetPIDWeight();
381  output->Charge = pid->GetCharge();
382  }
383 
384  ND::TReconNodeContainer nodes = reconObject->GetNodes();
385  for (ND::TReconNodeContainer::iterator it = nodes.begin(); it != nodes.end();
386  it++) {
387  // Only save information about the first and last nodes, unless the flag to
388  // save them all has
389  // been switched on.
390  if (fSaveAllGlobalNodes || output->NGlobalNodes == 0 ||
391  output->NGlobalNodes == ((int)nodes.size() - 1)) {
392  TGlobalReconNodeInfo* nodeInfo =
393  new ((*(output->GlobalNodes))[output->NGlobalNodesSaved])
395  ND::THandle<ND::TReconState> state = (*it)->GetState();
396  FillGlobalStateInfo(state, nodeInfo->NodeState);
397 
398  ND::THandle<ND::TReconBase> object = (*it)->GetObject();
399  if (!object) {
400  ND280Warn("Unable to get object of global node");
401  } else {
402  ND::THandle<ND::TReconState> nodeState;
403  try {
404  nodeState = object->GetState();
405  } catch (ND::EReconObject e) {
406  ND280Warn("TReconBase with no state. Skip node!");
407  continue;
408  }
409 
410  FillGlobalStateInfo(nodeState, nodeInfo->ObjectState);
411  }
412 
413  output->NGlobalNodesSaved++;
414  }
415  output->NGlobalNodes++;
416  }
417 
418  FillGlobalTruthInfo(event, reconObject, output->Truth);
419 
420  output->SetOK = true;
421 
422  return;
423 }
424 
425 /// Accessor for getting position from TReconState. Supported by all TxxxState
426 /// that inherit from TReconState.
428  ND::THandle<ND::TReconState> state) {
429  TLorentzVector pos(-10000, -10000, -10000, -10000);
430 
431  ND::THandle<ND::TPIDState> pid = state;
432  if (pid) {
433  pos = pid->GetPosition();
434  }
435  ND::THandle<ND::TTrackState> tr = state;
436  if (tr) {
437  pos = tr->GetPosition();
438  }
439  ND::THandle<ND::TShowerState> sh = state;
440  if (sh) {
441  pos = sh->GetPosition();
442  }
443  ND::THandle<ND::TClusterState> cl = state;
444  if (cl) {
445  pos = cl->GetPosition();
446  }
447  ND::THandle<ND::TVertexState> ve = state;
448  if (ve) {
449  pos = ve->GetPosition();
450  }
451 
452  return pos;
453 }
454 
455 /// Accessor for getting position variance from TReconState. Supported by all
456 /// TxxxState that inherit from TReconState.
458  ND::THandle<ND::TReconState> state) {
459  TLorentzVector pos(-10000, -10000, -10000, -10000);
460 
461  ND::THandle<ND::TPIDState> pid = state;
462  if (pid) {
463  pos = pid->GetPositionVariance();
464  }
465  ND::THandle<ND::TTrackState> tr = state;
466  if (tr) {
467  pos = tr->GetPositionVariance();
468  }
469  ND::THandle<ND::TShowerState> sh = state;
470  if (sh) {
471  pos = sh->GetPositionVariance();
472  }
473  ND::THandle<ND::TClusterState> cl = state;
474  if (cl) {
475  pos = cl->GetPositionVariance();
476  }
477  ND::THandle<ND::TVertexState> ve = state;
478  if (ve) {
479  pos = ve->GetPositionVariance();
480  }
481 
482  return pos;
483 }
484 
485 /// Accessor for getting position from TReconState. Only supported by TPIDState.
487  ND::THandle<ND::TReconState> state) {
488  double mom(-10000);
489 
490  ND::THandle<ND::TPIDState> pid = state;
491  if (pid) {
492  mom = pid->GetMomentum();
493  }
494 
495  return mom;
496 }
497 
498 /// Accessor for getting direction from TReconState. Only supported by
499 /// TPIDState, TTrackState and TShowerState.
501  ND::THandle<ND::TReconState> state) {
502  TVector3 dir(-10000, -10000, -10000);
503 
504  ND::THandle<ND::TPIDState> pid = state;
505  if (pid) {
506  dir = pid->GetDirection();
507  }
508  ND::THandle<ND::TTrackState> tr = state;
509  if (tr) {
510  dir = tr->GetDirection();
511  }
512  ND::THandle<ND::TShowerState> sh = state;
513  if (sh) {
514  dir = sh->GetDirection();
515  }
516 
517  return dir;
518 }
519 
520 /// Get the EDeposit of a TRecon(Track|Shower|Cluster) or a TReconPID that has a
521 /// single constituent
522 /// that is a TRecon(Track|Shower|Cluster)
524  ND::THandle<ND::TReconBase> object) {
525  double dep = -10000;
526 
527  ND::THandle<ND::TReconTrack> tr = object;
528  ND::THandle<ND::TReconShower> sh = object;
529  ND::THandle<ND::TReconCluster> cl = object;
530  ND::THandle<ND::TReconPID> pid = object;
531 
532  if (pid) {
533  ND::THandle<ND::TReconObjectContainer> cons = object->GetConstituents();
534  if (cons && cons->size() == 1) {
535  ND::THandle<ND::TReconBase> con = cons->front();
536  tr = con;
537  sh = con;
538  cl = con;
539  }
540  }
541 
542  if (tr) {
543  dep = tr->GetEDeposit();
544  }
545  if (sh) {
546  dep = sh->GetEDeposit();
547  }
548  if (cl) {
549  dep = cl->GetEDeposit();
550  }
551 
552  return dep;
553 }
554 
555 /// Get the state of the last node in an object
557  ND::THandle<ND::TReconBase> object) {
558  ND::THandle<ND::TReconState> state;
559 
560  for (ND::TReconNodeContainer::const_reverse_iterator it =
561  object->GetNodes().rbegin();
562  it != object->GetNodes().rend(); it++) {
563  state = (*it)->GetState();
564 
565  if (state) {
566  return state;
567  }
568  }
569 
570  return state;
571 }
572 
573 /// Get the state of the first node in an object
575  ND::THandle<ND::TReconBase> object) {
576  ND::THandle<ND::TReconState> state;
577 
578  for (ND::TReconNodeContainer::const_iterator it = object->GetNodes().begin();
579  it != object->GetNodes().end(); it++) {
580  state = (*it)->GetState();
581 
582  if (state) {
583  return state;
584  }
585  }
586 
587  return state;
588 }
589 
590 /// Fill information in the output tree relating to a constituent of a global
591 /// PID.
593  ND::TND280Event& event, ND::THandle<ND::TReconBase> reconObject,
594  ND::THandle<ND::TReconBase> globalObject, TGlobalReconConstituent* output) {
595  output->ReconAlgorithm = reconObject->GetAlgorithmName();
596  output->DetectorName = reconObject->ConvertDetector();
597  output->ClassName = reconObject->ClassName();
598  output->StatusString = reconObject->ConvertStatus();
599  output->Quality = reconObject->GetQuality();
600  output->NDOF = reconObject->GetNDOF();
601  output->IsShower = TrackingUtils::IsShower(reconObject);
602  output->EDeposit = GetEDeposit(reconObject);
603 
604  if (ReconObjectUtils::GetOriginalObject(reconObject))
605  output->UniqueID =
606  ReconObjectUtils::GetOriginalObject(reconObject)->GetUniqueID();
607  else
608  output->UniqueID = reconObject->GetUniqueID();
609 
610  ND::THandle<ND::TReconPID> pid = reconObject;
611  if (pid) {
612  output->ParticleID = pid->ConvertParticleId();
613  output->PIDWeight = pid->GetPIDWeight();
614  }
615 
616  if (reconObject->GetHits()) {
617  output->NumHits = reconObject->GetHits()->size();
618  } else {
619  output->NumHits = -1;
620  }
621 
622  ND::THandle<ND::TRealDatum> averageTime =
623  reconObject->Get<ND::TRealDatum>("averageHitTime");
624  if (averageTime) {
625  output->AverageHitTime = averageTime->GetValue();
626  }
627 
628  TVector3 refittedStatePos(-10000, -10000, -10000);
629 
630  ND::THandle<ND::TReconState> refittedState;
631  try {
632  refittedState = reconObject->GetState();
633  } catch (ND::EReconObject e) {
634  ND280Warn("TReconBase with no state.");
635  }
636 
637  if (!refittedState) {
638  ND280Warn(" Unable to get state of refitted object");
639  } else {
640  ND280Verbose(" Got refitted object state");
641 
642  // Overall state of constituent
643  refittedStatePos = GetStatePosition(refittedState).Vect();
644  FillStateInfo(refittedState, output->GlobalReconConsState);
645 
646  ND::THandle<ND::TReconNode> refittedFirstNode =
647  TrackingUtils::GetFirstFittedNode(*reconObject);
648  if (!refittedFirstNode) {
649  ND280Warn(" Unable to get first node of refitted object");
650  } else {
651  // State of first node of the constituent
652  ND::THandle<ND::TReconState> refittedFirstNodeState =
653  refittedFirstNode->GetState();
654  if (!refittedFirstNodeState) {
655  ND280Warn(" Unable to get first node state of refitted object");
656  } else {
657  FillStateInfo(refittedFirstNodeState,
659  }
660 
661  // Object of first node of the constituent
662  ND::THandle<ND::TReconBase> refittedFirstNodeBase =
663  refittedFirstNode->GetObject();
664  if (!refittedFirstNodeBase) {
665  ND280Warn(" Unable to get first node object of refitted object");
666  } else {
667  try {
668  FillStateInfo(refittedFirstNodeBase->GetState(),
670  } catch (ND::EReconObject e) {
671  ND280Warn("TReconBase first node with no state.");
672  }
673  }
674  }
675 
676  ND::THandle<ND::TReconNode> refittedLastNode =
677  TrackingUtils::GetLastFittedNode(*reconObject);
678  if (!refittedLastNode) {
679  ND280Warn(" Unable to get last node of refitted object");
680  } else {
681  // State of last node of the constituent
682  ND::THandle<ND::TReconState> refittedLastNodeState =
683  refittedLastNode->GetState();
684  if (!refittedLastNodeState) {
685  ND280Warn(" Unable to get last node state of refitted object");
686  } else {
687  FillStateInfo(refittedLastNodeState,
689  }
690 
691  // Object of last node of the constituent
692  ND::THandle<ND::TReconBase> refittedLastNodeBase =
693  refittedLastNode->GetObject();
694  if (!refittedLastNodeBase) {
695  ND280Warn(" Unable to get last node object of refitted object");
696  } else {
697  try {
698  FillStateInfo(refittedLastNodeBase->GetState(),
700  } catch (ND::EReconObject e) {
701  ND280Warn("TReconBase last node with no state.");
702  }
703  }
704  }
705 
706  // State of closest global node to constituent, extrapolated to the
707  // constituent's state position
708  ND::THandle<ND::TReconState> closestGlobalNodeState =
709  TrackingUtils::GetFirstState(*globalObject);
710  ND::TReconNodeContainer globalNodes = globalObject->GetNodes();
711  double closestOffset = 1e10;
712 
713  ND280Verbose(" Got " << globalNodes.size() << " global nodes");
714 
715  for (ND::TReconNodeContainer::iterator it = globalNodes.begin();
716  it != globalNodes.end(); it++) {
717  ND::THandle<ND::TReconNode> node(*it);
718  if (!node) {
719  ND280Warn(" Unable to get node from global container");
720  continue;
721  }
722 
723  ND::THandle<ND::TReconState> thisState(node->GetState());
724  if (!thisState) {
725  ND280Warn(" Unable to get state of global node");
726  continue;
727  }
728 
729  double thisOffset =
730  (refittedStatePos - GetStatePosition(thisState).Vect()).Mag();
731  if (thisOffset < closestOffset) {
732  closestGlobalNodeState = thisState;
733  closestOffset = thisOffset;
734  }
735  }
736 
737  if (!closestGlobalNodeState) {
738  ND280Warn(" Didn't find closest global node state");
739  } else {
740  ND280Verbose(" Got closest global node state");
741  // Extrapolate the closest global state towards the constituent's state.
742  // Extrapolation is done to the surface with normal (0,0,1) in the LOCAL
743  // geometry
744  // of the module we're in. So, for the Barrel ECals, that means we
745  // extrapolate to
746  // the surface with normal (1,0,0) or (0,1,0).
747  ND::THandle<ND::TReconState> projectedClosestGlobalNodeState(
748  new ND::TPIDState);
749  TVector3 snorm(0, 0, 1);
750  std::string det = reconObject->ConvertDetector();
751 
752  if (det.find("LTECal") != std::string::npos ||
753  det.find("RTECal") != std::string::npos) {
754  snorm = TVector3(1, 0, 0);
755  } else if (det.find("TTECal") != std::string::npos ||
756  det.find("BTECal") != std::string::npos) {
757  snorm = TVector3(0, 1, 0);
758  } else if (det.find("LPECal") != std::string::npos ||
759  det.find("RPECal") != std::string::npos) {
760  snorm = TVector3(1, 0, 0);
761  } else if (det.find("TPECal") != std::string::npos ||
762  det.find("BPECal") != std::string::npos) {
763  snorm = TVector3(0, 1, 0);
764  } else if (det.find("LSMRD") != std::string::npos ||
765  det.find("RSMRD") != std::string::npos) {
766  snorm = TVector3(1, 0, 0);
767  } else if (det.find("TSMRD") != std::string::npos ||
768  det.find("BSMRD") != std::string::npos) {
769  snorm = TVector3(0, 1, 0);
770  }
771 
772  if (fabs(refittedStatePos.X()) < 5000 &&
773  fabs(refittedStatePos.Y()) < 5000 &&
774  fabs(refittedStatePos.Z()) < 5000) {
775  if (ND::tman().PropagateToSurface(*closestGlobalNodeState,
776  refittedStatePos, snorm,
777  *projectedClosestGlobalNodeState)) {
778  FillStateInfo(projectedClosestGlobalNodeState,
779  output->ClosestGlobalNodeState);
780  } else {
781  ND280Warn(" Unable to propagate closest global node state");
782  }
783  } else {
784  ND280Warn(" Attempted to propagate to bad position "
785  << refittedStatePos.X() << ", " << refittedStatePos.Y()
786  << ", " << refittedStatePos.Z());
787  }
788  }
789 
790  //
791  // Information of first state of original subdetector recon object (before
792  // refitting by global recon)
793  //
794 
795  ND::THandle<ND::TReconBase> original =
796  ReconObjectUtils::GetOriginalObject(reconObject);
797 
798  if (original) {
799  try {
800  FillStateInfo(original->GetState(), output->OriginalObjectState);
801  } catch (ND::EReconObject e) {
802  ND280Warn(" Unable to get state of unfitted object");
803  }
804 
805  ND::THandle<ND::TReconState> unfittedFirstState = GetFirstState(original);
806  if (!unfittedFirstState) {
807  ND280Warn(" Unable to get first state of unfitted object");
808  } else {
809  FillStateInfo(unfittedFirstState, output->OriginalObjectFirstNodeState);
810  }
811 
812  ND::THandle<ND::TReconState> unfittedLastState = GetLastState(original);
813  if (!unfittedLastState) {
814  ND280Warn(" Unable to get last state of unfitted object");
815  } else {
816  FillStateInfo(unfittedLastState, output->OriginalObjectLastNodeState);
817  }
818  }
819 
820  // If the constituent is in a TPC, extrapolate its state towards the
821  // ECals/P0D, for matching studies
822  if (reconObject->GetDetectors() == ND::TReconBase::kTPC1 ||
823  reconObject->GetDetectors() == ND::TReconBase::kTPC2 ||
824  reconObject->GetDetectors() == ND::TReconBase::kTPC3) {
825  ExtrapolateToModuleAndFill(reconObject, output->StateAtDSECal, "DS");
826  ExtrapolateToModuleAndFill(reconObject, output->StateAtTTECal, "TT");
827  ExtrapolateToModuleAndFill(reconObject, output->StateAtBTECal, "BT");
828  ExtrapolateToModuleAndFill(reconObject, output->StateAtLTECal, "LT");
829  ExtrapolateToModuleAndFill(reconObject, output->StateAtRTECal, "RT");
830  ExtrapolateToModuleAndFill(reconObject, output->StateAtP0D, "P0D");
831  if (reconObject->GetDetectors() == ND::TReconBase::kTPC1 ||
832  reconObject->GetDetectors() == ND::TReconBase::kTPC3) {
833  ExtrapolateToModuleAndFill(reconObject, output->StateAtTPC2, "TPC2");
834  }
835  }
836 
837  output->SetOK = true;
838  }
839 
840  //
841  // Subdetector truth information
842  //
843  FillConsTruthInfo(event, reconObject, output->ConsTruth);
844 
845  return;
846 }
847 
848 /// Extract TReconPIDs from P0DRecon's TReconVertex container.
850  ND::THandle<ND::TReconObjectContainer> input,
851  ND::THandle<ND::TReconObjectContainer> output) {
852  if (!input || !output) return;
853 
854  ND280Verbose("GetObjectsFromVertices: # objects = " << input->size());
855 
856  ND::TReconObjectContainer::const_iterator pp, pp1;
857  for (pp = input->begin(); pp != input->end(); pp++) {
858  ND280Verbose("Next input object: " << *pp);
859  ND::THandle<ND::TReconVertex> vertex = *pp;
860  if (vertex) {
861  ND::THandle<ND::TReconObjectContainer> cons = vertex->GetConstituents();
862  if (cons) {
863  ND280Verbose(" ---> # cons = " << cons->size());
864  for (pp1 = cons->begin(); pp1 != cons->end(); pp1++) {
865  output->push_back(*pp1);
866  }
867  }
868  } else {
869  output->push_back(*pp);
870  }
871  }
872 }
873 
874 /// Check whether the THandles of the immediate constituents of two objects are
875 /// equal.
877  ND::THandle<ND::TReconBase> obj1, ND::THandle<ND::TReconBase> obj2) {
878  ND::THandle<ND::TReconObjectContainer> hcon1 = obj1->GetConstituents();
879  ND::THandle<ND::TReconObjectContainer> hcon2 = obj2->GetConstituents();
880 
881  if (ND::TND280Log::GetLogLevel("eventAnalysis") >= ND::TND280Log::VerboseLevel) {
882  std::cout << "obj1 constituents:" << std::endl;
883  ReconPrintout::DumpContainerWithHistory(*hcon1);
884  std::cout << "obj2 constituents:" << std::endl;
885  ReconPrintout::DumpContainerWithHistory(*hcon2);
886  }
887 
888  if (!hcon1 || !hcon2) {
889  ND280Verbose("Unable to get constituents");
890  return false;
891  }
892 
893  ND::TReconObjectContainer con1 = (*hcon1);
894  ND::TReconObjectContainer con2 = (*hcon2);
895 
896  if (con1.size() != con2.size()) {
897  ND280Verbose("Constituent ROCs are different sizes: "
898  << con1.size() << " vs " << con2.size());
899  return false;
900  }
901 
902  for (ND::TReconObjectContainer::iterator it1 = con1.begin();
903  it1 != con1.end(); it1++) {
904  bool foundMatch = false;
905 
906  for (ND::TReconObjectContainer::iterator it2 = con2.begin();
907  it2 != con2.end(); it2++) {
908  if ((*it1) == (*it2)) {
909  foundMatch = true;
910  break;
911  }
912  }
913 
914  if (!foundMatch) {
915  return false;
916  }
917  }
918 
919  return true;
920 }
921 
922 /// Fill information relating to the true trajectory associated to a constituent
923 /// of a global PID. Fills information
924 /// from the closest trajectory point to the constituent.
926  ND::TND280Event& event, ND::THandle<ND::TReconBase> reconObject,
927  TTruthInfo& output) {
928  ND::THandle<ND::TReconState> state;
929  try {
930  state = reconObject->GetState();
931  } catch (ND::EReconObject e) {
932  return;
933  }
934 
935  if (!state) {
936  return;
937  }
938 
939  TVector3 statePos = GetStatePosition(state).Vect();
940  ND::THandle<ND::TG4TrajectoryContainer> trajectories =
941  event.Get<ND::TG4TrajectoryContainer>("truth/G4Trajectories");
942 
943  if (trajectories && reconObject->GetHits()) {
944  // Use oaUtility to find true particle corresponding to this track, and get
945  // the associated trajectory points.
946  int G4TrkId = TrackTruthInfo::GetG4TrajIDHits(
947  *(reconObject->GetHits()), output.Efficiency, output.Purity);
948  ND::THandle<ND::TG4Trajectory> traj = trajectories->GetTrajectory(G4TrkId);
949  if (traj) {
950  ND280Verbose(" Got trajectory number " << G4TrkId);
951 
952  std::vector<ND::TG4TrajectoryPoint> trajPoints =
953  traj->GetTrajectoryPoints();
954 
955  if (trajPoints.size() > 0) {
956  output.Charge = traj->GetParticle()->Charge() / 3.0;
957 
958  // Find the momentum / direction of the true particle at the closest
959  // point to the position of the recon object's state.
960  TVector3 closestOffset(-10000, -10000, -10000);
961 
962  for (std::vector<ND::TG4TrajectoryPoint>::iterator trajPointIt =
963  trajPoints.begin();
964  trajPointIt != trajPoints.end(); trajPointIt++) {
965  ND::TG4TrajectoryPoint trajPoint = (*trajPointIt);
966 
967  TVector3 thisOffset = (trajPoint.GetPosition().Vect() - statePos);
968  if (fabs(thisOffset.Z()) < fabs(closestOffset.Z())) {
969  closestOffset = thisOffset;
970  output.Momentum = trajPoint.GetMomentum().Mag();
971  output.Direction = trajPoint.GetMomentum().Unit();
972  output.Position = trajPoint.GetPosition();
973  }
974  }
975 
976  if (closestOffset.Mag() > 100) {
977  ND280Verbose(" Closest MC trajectory point is offset by "
978  << closestOffset.Mag());
979  }
980 
981  output.SetOK = true;
982  }
983  } else {
984  ND280Warn(" No trajectory number " << G4TrkId);
985  }
986  } else if (event.GetContext().IsMC()) {
987  ND280Warn(" No trajectories, yet is MC!!!");
988  }
989 
990  return;
991 }
992 
993 /// Fill information relating to the true particle associated with a global PID.
994 /// Fills the initial status of the true trajectory.
996  ND::TND280Event& event, ND::THandle<ND::TReconBase> reconObject,
997  TGlobalTruthInfo& output) {
998  ND::THandle<ND::TReconState> state;
999 
1000  try {
1001  state = reconObject->GetState();
1002  } catch (ND::EReconObject) {
1003  return;
1004  }
1005 
1006  if (!state) {
1007  return;
1008  }
1009 
1010  TVector3 statePos = GetStatePosition(state).Vect();
1011  ND::THandle<ND::TG4TrajectoryContainer> trajectories =
1012  event.Get<ND::TG4TrajectoryContainer>("truth/G4Trajectories");
1013 
1014  if (trajectories && reconObject->GetHits()) {
1015  // Use oaUtility to find true particle corresponding to this track.
1016  int G4TrkId = TrackTruthInfo::GetG4TrajIDHits(
1017  *(reconObject->GetHits()), output.Efficiency, output.Purity);
1018  ND::THandle<ND::TG4Trajectory> traj = trajectories->GetTrajectory(G4TrkId);
1019  if (traj) {
1020  ND280Verbose(" Got trajectory number " << G4TrkId);
1021  output.Charge = traj->GetParticle()->Charge() / 3.0;
1022  output.Momentum = traj->GetInitialMomentum().Vect().Mag();
1023  output.Direction = traj->GetInitialMomentum().Vect().Unit();
1024  output.Position = traj->GetInitialPosition();
1025  output.SetOK = true;
1026  } else {
1027  ND280Warn(" No trajectory number " << G4TrkId);
1028  }
1029  } else if (event.GetContext().IsMC()) {
1030  ND280Warn(" No trajectories, yet is MC!!!");
1031  }
1032 
1033  return;
1034 }
1035 
1036 /// Fill information relating to the state of a global PID constituent.
1038  ND::THandle<ND::TReconState> state, TReconStateInfo& output) {
1039  if (!state) {
1040  return;
1041  }
1042 
1043  output.Position = GetStatePosition(state);
1044  output.PositionVariance = GetStatePositionVariance(state);
1045  output.Momentum = GetStateMomentum(state);
1046  output.Direction = GetStateDirection(state);
1047 
1048  output.SetOK = true;
1049 
1050  return;
1051 }
1052 
1053 /// Fill information relating to the state of a global PID constituent.
1055  ND::THandle<ND::TReconBase> base, TDownToTrackerInfo* output) {
1056  ND::THandle<ND::TReconState> state;
1057 
1058  try {
1059  state = base->GetState();
1060  } catch (ND::EReconObject e) {
1061  return;
1062  }
1063 
1064  if (!state) {
1065  return;
1066  }
1067 
1068  output->DetectorName = base->ConvertDetector();
1069  output->MatchingChi2 = TrackingUtils::GetMatchingChi2(*base);
1070  output->Position = GetStatePosition(state);
1071  output->Momentum = GetStateMomentum(state);
1072  output->Direction = GetStateDirection(state);
1073 
1074  output->SetOK = true;
1075 
1076  return;
1077 }
1078 
1079 /// Extrapolate an object to the surface of another module. Currently
1080 /// implemented surfaces are:
1081 /// "DS" - upstream face of DsECal
1082 /// "LT" - inner face of LTECal
1083 /// "RT" - inner face of RTECal
1084 /// "TT" - inner face of TTECal
1085 /// "BT" - inner face of BTECal
1086 /// "P0D" - downstream face of P0D
1087 /// Extrapolation is done using the tpcRecon HelixModel.
1088 /// The input object must be either a TReconTrack or a TReconPID with a single
1089 /// constituent
1090 /// that is itself a TReconTrack.
1092  ND::THandle<ND::TReconBase> base, THelixModelInfo& output,
1093  std::string module) {
1094  if (!base) {
1095  return;
1096  }
1097 
1098  // Initialize the tpcRecon HelixModel object.
1099  HelixModel* helix = new HelixModel();
1100  ND::THandle<ND::TReconTrack> track = base;
1101 
1102  if (!track) {
1103  ND::THandle<ND::TReconPID> pid = base;
1104  ND::THandle<ND::TReconObjectContainer> conContainer =
1105  base->GetConstituents();
1106  if (conContainer->size() != 1) {
1107  ND280Error("Constituent container has > 1 constituent!");
1108  return;
1109  }
1110 
1111  for (ND::TReconObjectContainer::iterator conIter = conContainer->begin();
1112  conIter != conContainer->end(); ++conIter) {
1113  ND::THandle<ND::TReconBase> base = (*conIter);
1114  track = base;
1115 
1116  if (!track) {
1117  ND280Error("Tried to convert non-track to helix");
1118  return;
1119  }
1120  }
1121  }
1122 
1123  ND::THandle<ND::TTrackState> state;
1124  try {
1125  state = track->GetState();
1126  } catch (ND::EReconObject e) {
1127  ND280Warn("Couldn't get track state.");
1128  return;
1129  }
1130 
1131  double x0 = state->GetPosition().X();
1132  double y0 = state->GetPosition().Y();
1133  double z0 = state->GetPosition().Z();
1134 
1135  double tx0 = state->GetDirection().X();
1136  double ty0 = state->GetDirection().Y() / state->GetDirection().Z();
1137 
1138  double rho = state->GetCurvature();
1139 
1140  helix->SetParameters(x0, y0, z0, tx0, ty0, rho);
1141 
1142  double x, y, z, theta;
1143  TVector3 minpos, maxpos, pos;
1144 
1145  // Propagate helix to correct co-ordinate. Inner face of TECal modules;
1146  // upstream face of DsECal; downstream face of P0D.
1147  if (module == "DS" || module == "P0D") {
1148  if (module == "DS") {
1149  GetModuleBox(ND::GeomId::DSECal::Detector(), minpos, maxpos);
1150  // Slight correction so we extrapolate to ~ first DSECal node
1151  z = minpos.Z() + 30.5;
1152  } else {
1153  GetModuleBox(ND::GeomId::P0D::Detector(), minpos, maxpos);
1154  // Slight correction so we extrapolate to ~ last P0D node
1155  z = maxpos.Z() - 42.0;
1156  }
1157  x = helix->XCoord(TVector3(0.0, 0.0, z), 2);
1158  y = helix->YCoord(TVector3(0.0, 0.0, z), 2);
1159  theta = helix->phiYZ(TVector3(0.0, 0.0, z), 2);
1160  } else if (module == "TT" || module == "BT") {
1161  if (module == "TT") {
1162  GetModuleBox(ND::GeomId::TECal::Module(0, 2), minpos, maxpos);
1163  // Slight correction so we extrapolate to ~ first TTECal node
1164  y = minpos.Y() + 45.5;
1165  } else {
1166  GetModuleBox(ND::GeomId::TECal::Module(0, 0), minpos, maxpos);
1167  // Slight correction so we extrapolate to ~ first BTECal node
1168  y = maxpos.Y() - 45.5;
1169  }
1170  x = helix->XCoord(TVector3(0.0, y, 0.0), 1);
1171  z = helix->ZCoord(TVector3(0.0, y, 0.0), 1);
1172  theta = helix->phiYZ(TVector3(0.0, 0.0, z), 2);
1173  } else if (module == "RT" || module == "LT") {
1174  if (module == "RT") {
1175  GetModuleBox(ND::GeomId::TECal::Module(0, 1), minpos, maxpos);
1176  // Slight correction so we extrapolate to ~ first RTECal node
1177  x = maxpos.X() - 55.5;
1178  } else {
1179  GetModuleBox(ND::GeomId::TECal::Module(1, 1), minpos, maxpos);
1180  // Slight correction so we extrapolate to ~ first LTECal node
1181  x = minpos.X() + 55.5;
1182  }
1183  y = helix->YCoord(TVector3(x, 0.0, 0.0), 0);
1184  z = helix->ZCoord(TVector3(x, 0.0, 0.0), 0);
1185  theta = helix->phiYZ(TVector3(0.0, 0.0, z), 2);
1186  } else if (module == "TPC2") {
1187  GetModuleBox(ND::GeomId::TPC::TPC2(), minpos, maxpos);
1188  if (base->GetDetectors() == ND::TReconBase::kTPC1) {
1189  z = maxpos.Z();
1190  } else {
1191  z = minpos.Z();
1192  }
1193  x = helix->XCoord(TVector3(0.0, 0.0, z), 2);
1194  y = helix->YCoord(TVector3(0.0, 0.0, z), 2);
1195  theta = helix->phiYZ(TVector3(0.0, 0.0, z), 2);
1196  } else {
1197  return;
1198  }
1199 
1200  // Fill the output object with the results of the extrapolation
1201  output.Position = TVector3(x, y, z);
1202  output.CosTheta = std::cos(theta);
1203  output.SetOK = true;
1204 
1205  return;
1206 }
1207 
1208 /// Get the minimum and maximum positions of the box defining this TGeometryId.
1209 /// Lovingly stolen from ND::TGeometrySummaryModule::FillBBox().
1211  TVector3& minpos,
1212  TVector3& maxpos) {
1213  try {
1214  TVector3 centre = id.GetPosition();
1215 
1216  ND::TOADatabase::Get().GeomId().CdId(id);
1217  TGeoShape* vol = gGeoManager->GetCurrentVolume()->GetShape();
1218  TGeoBBox* bbox = dynamic_cast<TGeoBBox*>(vol);
1219  if (bbox) {
1220  TVector3 corner(bbox->GetDX(), bbox->GetDY(), bbox->GetDZ());
1221  TVector3 globalcorner = ND::TGeomInfo::Get().LocalToMasterVect(
1222  id, corner.X(), corner.Y(), corner.Z());
1223  TVector3 min = centre - globalcorner;
1224  TVector3 max = centre + globalcorner;
1225  minpos.SetX(std::min(min.X(), max.X()));
1226  minpos.SetY(std::min(min.Y(), max.Y()));
1227  minpos.SetZ(std::min(min.Z(), max.Z()));
1228  maxpos.SetX(std::max(min.X(), max.X()));
1229  maxpos.SetY(std::max(min.Y(), max.Y()));
1230  maxpos.SetZ(std::max(min.Z(), max.Z()));
1231  }
1232  } catch (ND::EGeomIdInvalid e) {
1233  // It's possible that we could try passing an invalid geometry id.
1234  // This happens, for example, if we're looking at run 1 data (or 2010-02
1235  // MC) and we try to extrapolate to the non-existant Tracker ECal.
1236  ND280Verbose(" Invalid geometry id passed to GetModuleBox()");
1237  }
1238 
1239  return;
1240 }
1241 
1242 /// Fill information relating to the state of a global PID.
1244  ND::THandle<ND::TReconState> state, TGlobalReconStateInfo& output) {
1245  if (!state) {
1246  return;
1247  }
1248 
1249  output.Position = GetStatePosition(state);
1250  output.PositionVariance = GetStatePositionVariance(state);
1251  output.Momentum = GetStateMomentum(state);
1252  output.Direction = GetStateDirection(state);
1253 
1254  output.SetOK = true;
1255 
1256  return;
1257 }
1258 
1260  SetOK = false;
1261 
1262  Constituents = new TClonesArray(
1263  "ND::TReconPerformanceEvalModule::TGlobalReconConstituent", 200);
1264  Constituents->Clear();
1265 
1266  NConstituents = 0;
1267  NModuleConstituents = new std::map<std::string, int>();
1268 
1269  GlobalNodes = new TClonesArray(
1270  "ND::TReconPerformanceEvalModule::TGlobalReconNodeInfo", 200);
1271  GlobalNodes->Clear();
1272  NGlobalNodes = 0;
1273  NGlobalNodesSaved = 0;
1274 
1275  DownToTrackerConstituents = new TClonesArray(
1276  "ND::TReconPerformanceEvalModule::TDownToTrackerInfo", 200);
1277  DownToTrackerConstituents->Clear();
1278  NDownToTrackerConstituents = 0;
1279 
1280  SubdetectorString = "FAILED";
1281 
1282  ParticleID = "NOT_A_TRECONPID";
1283  PIDWeight = -10000;
1284 
1285  Momentum = -10000;
1286  MomentumByRange = -10000;
1287  Charge = -10000;
1288  Direction = TVector3(-10000, -10000, -10000);
1289  UniqueID = 0;
1290 
1291  MatchingChi2Info = new TClonesArray(
1292  "ND::TReconPerformanceEvalModule::TMatchingChi2Info", 200);
1293  MatchingChi2Info->Clear();
1294  NMatchingChi2Info = 0;
1295 }
1296 
1298 
1301  SetOK = false;
1302  ReconAlgorithm = "FAILED";
1303  DetectorName = "FAILED";
1304  ClassName = "FAILED";
1305  ParticleID = "NOT_A_TRECONPID";
1306  PIDWeight = -10000;
1307  AverageHitTime = -10000;
1308  UniqueID = 0;
1309 }
1310 
1313 
1315  SetOK = false;
1316  Position = TLorentzVector(-10000, -10000, -10000, -10000);
1317  Momentum = -10000;
1318  Charge = -10000;
1319  Direction = TVector3(-10000, -10000, -10000);
1320  Purity = -10000;
1321  Efficiency = -10000;
1322 }
1323 
1325 
1327  SetOK = false;
1328  Position = TLorentzVector(-10000, -10000, -10000, -10000);
1329  Momentum = -10000;
1330  Charge = -10000;
1331  Direction = TVector3(-10000, -10000, -10000);
1332  Purity = -10000;
1333  Efficiency = -10000;
1334 }
1335 
1337 
1339  SetOK = false;
1340 }
1341 
1343 }
1344 
1347  SetOK = false;
1348  Position = TLorentzVector(-10000, -10000, -10000, -10000);
1349  PositionVariance = TLorentzVector(-10000, -10000, -10000, -10000);
1350  Momentum = -10000;
1351  Direction = TVector3(-10000, -10000, -10000);
1352 }
1353 
1356 
1358  SetOK = false;
1359  Position = TLorentzVector(-10000, -10000, -10000, -10000);
1360  PositionVariance = TLorentzVector(-10000, -10000, -10000, -10000);
1361  Momentum = -10000;
1362  Direction = TVector3(-10000, -10000, -10000);
1363 }
1364 
1366 
1368  SetOK = false;
1369  DetectorName = "FAILED";
1370  MatchingChi2 = -10000;
1371  Position = TLorentzVector(-10000, -10000, -10000, -10000);
1372  Momentum = -10000;
1373  Direction = TVector3(-10000, -10000, -10000);
1374 }
1375 
1377 
1379  SetOK = false;
1380  Position = TVector3(-10000, -10000, -10000);
1381  CosTheta = -10000;
1382 }
1383 
1385 
1387  SetOK = false;
1388  Det1 = "FAILED";
1389  Det2 = "FAILED";
1390  MatchingChi2 = -10000;
1391  IsShower1 = false;
1392  IsShower2 = false;
1393 }
1394 
double Purity
&lt; Efficiency of this truth matching
TGlobalReconObject Object for containing global recon information.
std::string ClassName
&lt; Subdetector(s) used for this object
double AverageHitTime
Value of averageHitTime TDatum, if set.
TTruthInfo Information relating to a truth trajectory.
bool ContainsTracker(ND::THandle< ND::TReconBase > input)
double Efficiency
&lt; Position of the trajectory point
Int_t NGlobalNodes
The number of states the global track contains.
double Momentum
&lt; Easy access to the state&#39;s direction, if the state type supports it
TLorentzVector PositionVariance
&lt; Easy access to the state&#39;s position.
TReconStateInfo GlobalReconConsState
&lt; UniqueID identifying this constituent
double Momentum
&lt; Whether this object was filled
TLorentzVector PositionVariance
&lt; Easy access to the state&#39;s position.
TVector3 Direction
&lt; Momentum of the true trajectory
double MatchingChi2
&lt; Subdetector(s) used for this object
TClonesArray * GlobalNodes
Information about the nodes of the global track, in the same order as they are stored in the global t...
void FillConsTruthInfo(ND::TND280Event &event, ND::THandle< ND::TReconBase > reconObject, TTruthInfo &output)
Fill information relating to the true trajectory associated to a constituent of a global PID...
virtual bool FillTree(ND::TND280Event &)
Fill all the stuff that goes in the output tree.
ClassImp(ND::TBeamSummaryDataModule::TBeamSummaryData)
TReconStateInfo OriginalObjectFirstNodeState
State information of subdetector recon object.
virtual bool IsFullEventWorthSaving(ND::TND280Event &event)
Whether the module thinks it is worth saving the entire oaEvent event tree entry for this event...
TReconStateInfo GlobalReconConsFirstNodeState
State of first node of global recon constituent.
bool fSaveAllGlobalNodes
Flag for whether to save all global nodes or just the first and last nodes.
void FillConstituentInfo(ND::TND280Event &event, ND::THandle< ND::TReconBase > reconObject, ND::THandle< ND::TReconBase > globalObject, TGlobalReconConstituent *output)
Fill information in the output tree relating to a constituent of a global PID.
std::string fDescription
A longish descrition of the analysis.
TVector3 Direction
&lt; Easy access to the state&#39;s position variance.
THelixModelInfo StateAtP0D
Extrapolation of object to downstream face of P0D, using tpcRecon HelixModel.
TVector3 Direction
&lt; Momentum of the true trajectory at the trajectory point
double PIDWeight
&lt; ParticleID, if the constituent is a TReconPID
int NumHits
Number of hits for this constituent, or -1 if the THitSelection is invalid.
TReconStateInfo GlobalReconConsLastNodeState
State of last node of global recon constituent.
TClonesArray * fGlobalReconObjects
TClonesArray of TGlobalReconObject.
std::string DetectorName(ESubdetector const subdet)
ND::TReconObjectContainer GetDownToTracker(ND::THandle< ND::TReconBase > input)
Get the list of constituents that are found on the way down to getting the tracker-only constituent...
double Efficiency
&lt; Initial position of the trajectory
double Charge
&lt; Direction of the true trajectory
double GetStateMomentum(ND::THandle< ND::TReconState > state)
Accessor for getting position from TReconState. Only supported by TPIDState.
THelixModelInfo StateAtLTECal
Extrapolation of object to inner face of LTECal, using tpcRecon HelixModel.
double MatchingChi2
&lt; Whether the second object was a shower
double GetEDeposit(ND::THandle< ND::TReconBase > object)
Get the EDeposit of a TRecon(Track|Shower|Cluster) or a TReconPID that has a single constituent that ...
bool ConstituentsAreEqual(ND::THandle< ND::TReconBase > obj1, ND::THandle< ND::TReconBase > obj2)
Check whether the THandles of the immediate constituents of two objects are equal.
void GetObjectsFromVertices(ND::THandle< ND::TReconObjectContainer > input, ND::THandle< ND::TReconObjectContainer > output)
Extract TReconPIDs from P0DRecon&#39;s TReconVertex container.
TLorentzVector Position
&lt; Matching chi^2 of this object
THelixModelInfo StateAtTTECal
Extrapolation of object to inner face of TTECal, using tpcRecon HelixModel.
TLorentzVector Position
&lt; Charge of the trajectory
TGlobalReconConstituent The main object that contains constituent recon information Feel free to add ...
bool IsShower2
&lt; Second object&#39;s detector string
void FillGlobalTruthInfo(ND::TND280Event &event, ND::THandle< ND::TReconBase > reconObject, TGlobalTruthInfo &output)
Fill information relating to the true particle associated with a global PID.
void FillGlobalInfo(ND::TND280Event &event, ND::THandle< ND::TReconBase > reconObject, TGlobalReconObject *output)
Fill information in the output tree relating to the global PID.
void FillDownToTrackerInfo(ND::THandle< ND::TReconBase > base, TDownToTrackerInfo *output)
Fill information relating to the state of a global PID constituent.
TClonesArray * MatchingChi2Info
Matching chi^2s, if global recon merged two objects together.
TReconPerformanceEvalModule(const char *name="ReconPerfEval", const char *title="Recon Performance Evaluation Module")
Int_t NGlobalNodesSaved
The number of states of the global track that we saved information about.
double Momentum
&lt; Easy access to the state&#39;s direction, if the state type supports it
TGlobalReconNodeInfo Information related to a recon object&#39;s node.
int NMatchingChi2Info
Number of entries in the MatchingChi2s array.
std::string StatusString
&lt; ClassName of this recon object
virtual Bool_t ProcessFirstEvent(ND::TND280Event &event)
Is called after the first event is loaded in.
ND::TReconObjectContainer GetConstituentsOfInterest(ND::THandle< ND::TReconBase > input)
Get the constituents of a global PID that we wish to investigate further.
THelixModelInfo StateAtDSECal
Extrapolation of object to upstream face of DsECal, using tpcRecon HelixModel.
TGlobalReconStateInfo Information related to a recon object&#39;s state.
TVector3 Direction
&lt; Easy access to the state&#39;s position.
std::string fCVSID
Defined if an official tagged version.
TReconStateInfo OriginalObjectState
State information of subdetector recon object.
virtual void InitializeModule()
Initialize Module, override if necessary.
std::string SubdetectorString
String containing subdetectors used by this object.
THelixModelInfo Information from a state extrapolated using the tpcRecon HelixModel.
TGlobalTruthInfo Truth
True momentum, angle and charge at closest approach to global state position.
void ExtrapolateToModuleAndFill(ND::THandle< ND::TReconBase > base, THelixModelInfo &output, std::string module)
Extrapolate an object to the surface of another module.
TLorentzVector Position
Position/time of the global track.
double GetTRealDatumValue(ND::THandle< ND::TReconBase > trb, char const *name, double const &defaultValue)
TReconStateInfo OriginalObjectLastNodeState
State information of subdetector recon object.
TLorentzVector Position
&lt; Charge of the trajectory
void SetNameTitle(char const *name, char const *title)
void GetModuleBox(ND::TGeometryId id, TVector3 &minpos, TVector3 &maxpos)
Get the minimum and maximum positions of the box defining this TGeometryId.
bool IsShower
Whether the constituent is a TReconShower (or a TReconPID with a single constituent that is a TReconS...
ND::THandle< ND::TReconState > GetLastState(ND::THandle< ND::TReconBase > object)
Get the state of the last node in an object.
TVector3 GetStateDirection(ND::THandle< ND::TReconState > state)
Accessor for getting direction from TReconState.
TReconStateInfo GlobalReconConsFirstNodeObject
Object of first node of global recon constituent.
UInt_t UniqueID
&lt; PID weight, if the constituent is a TReconPID
TLorentzVector GetStatePositionVariance(ND::THandle< ND::TReconState > state)
Accessor for getting position variance from TReconState.
TMatchingChi2Info Information for storing global recon matching chi2 info.
double Purity
&lt; Efficiency of this truth matching
TVector3 Direction
&lt; Easy access to the state&#39;s position variance.
TLorentzVector GetStatePosition(ND::THandle< ND::TReconState > state)
Accessor for getting position from TReconState.
THelixModelInfo StateAtBTECal
Extrapolation of object to inner face of BTECal, using tpcRecon HelixModel.
TClonesArray * Constituents
TClonesArray of (lowest-level) constituent TGlobalReconConstituent.
double Charge
&lt; Direction of the true trajectory at the trajectory point
std::string Det2
&lt; Whether the first object was a shower
Int_t NDownToTrackerConstituents
Number of objects we saved in the DownToTrackerConstituents TClonesArray.
THelixModelInfo StateAtTPC2
Extrapolation of TPC1(TPC3) object to downstream(upstream) face of TPC2, using tpcRecon HelixModel...
THelixModelInfo StateAtRTECal
Extrapolation of object to inner face of RTECal, using tpcRecon HelixModel.
std::string ParticleID
&lt; String containing the status of the object (success, ran etc)
TClonesArray * DownToTrackerConstituents
TClonesArray of intermediate constituent states, working down to tracker-only constituent.
std::string StatusString
String containing the status of the object (success, ran etc)
bool IsShower1
&lt; First object&#39;s detector string
void FillGlobalStateInfo(ND::THandle< ND::TReconState > state, TGlobalReconStateInfo &output)
Fill information relating to the state of a global PID.
std::string DetectorName
&lt; Name of Subdetector recon algorithm
std::string fCVSTagName
Defined if an official tagged version.
double Momentum
&lt; Easy access to the state&#39;s direction, if the state type supports it
TTruthInfo ConsTruth
Truth information at MC trajectory point closest to refitted state position.
ND::THandle< ND::TReconState > GetFirstState(ND::THandle< ND::TReconBase > object)
Get the state of the first node in an object.
std::map< std::string, int > * NModuleConstituents
Number of constituents in each module.
TReconStateInfo GlobalReconConsLastNodeObject
Object of last node of global recon constituent.
TDownToTrackerInfo Information related to the constituents of an object that are built up from a trac...
void FillStateInfo(ND::THandle< ND::TReconState > state, TReconStateInfo &output)
Fill information relating to the state of a global PID constituent.
TGlobalTruthInfo Information relating to a truth trajectory.
virtual void InitializeBranches()
Initialize Branches. Don&#39;t do anything else in this function.
TReconStateInfo ClosestGlobalNodeState
State information of closest global recon node to subdetector state position, projected to the positi...
TReconStateInfo Information related to a recon object&#39;s state.
bool IsOnlyTracker(ND::THandle< ND::TReconBase > input)
Int_t NConstituents
Number of constituents of the global track.
virtual void FillConfigTree(TTree *)

Package Summary
Package Name: eventAnalysis
Package Version: 7.0-49-g0ac7482
Package Manager:

Generated on Mon Mar 25 2024 14:43:59 for eventAnalysis by doxygen 1.8.5