Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DCustomAction_TrackingEfficiency.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DCustomAction_TrackingEfficiency.cc
4 // Created: Wed Feb 25 09:38:06 EST 2015
5 // Creator: pmatt (on Linux pmattdesktop.jlab.org 2.6.32-504.8.1.el6.x86_64 x86_64)
6 //
7 
9 
10 void DCustomAction_TrackingEfficiency::Initialize(JEventLoop* locEventLoop)
11 {
12  //Optional: Create histograms and/or modify member variables.
13  //Create any histograms/trees/etc. within a ROOT lock.
14  //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
15 
16  const DReaction* locReaction = Get_Reaction();
17 
18  auto locMissingPIDs = Get_Reaction()->Get_MissingPIDs();
19  dMissingPID = (locMissingPIDs.size() == 1) ? locMissingPIDs[0] : Unknown;
20  if(locMissingPIDs.size() != 1)
21  return; //invalid reaction setup
22 
23  locEventLoop->GetSingle(dAnalysisUtilities);
24  locEventLoop->GetSingle(dParticleID);
25 
26  //CREATE TTREE, TFILE
27  dTreeInterface = DTreeInterface::Create_DTreeInterface(locReaction->Get_ReactionName(), "tree_trackeff.root");
28 
29  //TTREE BRANCHES
30  DTreeBranchRegister locBranchRegister;
31 
32  //USER INFO
33  TList* locUserInfo = locBranchRegister.Get_UserInfo();
34  TMap* locMiscInfoMap = new TMap(); //collection of pairs
35  locMiscInfoMap->SetName("MiscInfoMap");
36  locUserInfo->Add(locMiscInfoMap);
37  //set reaction name
38  locMiscInfoMap->Add(new TObjString("ReactionName"), new TObjString(locReaction->Get_ReactionName().c_str()));
39  //set pid
40  ostringstream locOStream;
41  locOStream << PDGtype(dMissingPID);
42  locMiscInfoMap->Add(new TObjString("MissingPID_PDG"), new TObjString(locOStream.str().c_str()));
43  //set run#
44  locOStream.str("");
45  locOStream << locEventLoop->GetJEvent().GetRunNumber();
46  locMiscInfoMap->Add(new TObjString("RunNumber"), new TObjString(locOStream.str().c_str()));
47 
48  //CHANNEL INFO
49  locBranchRegister.Register_Single<ULong64_t>("EventNumber"); //for debugging
50  locBranchRegister.Register_Single<Float_t>("BeamEnergy");
51  locBranchRegister.Register_Single<Float_t>("BeamRFDeltaT");
52  locBranchRegister.Register_Single<Float_t>("ComboVertexZ");
53  locBranchRegister.Register_Single<UChar_t>("NumExtraTracks");
54  locBranchRegister.Register_Single<Float_t>("MissingMassSquared"); //is measured
55  locBranchRegister.Register_Single<Float_t>("KinFitChiSq"); //is -1 if no kinfit or failed to converge
56  locBranchRegister.Register_Single<UInt_t>("KinFitNDF"); //is 0 if no kinfit or failed to converged
57  locBranchRegister.Register_Single<TVector3>("MissingP3"); //is kinfit if kinfit (& converged)
58 
59  //MISSING P3 ERROR MATRIX //is kinfit if kinfit (& converged)
60  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPxPx");
61  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPxPy");
62  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPxPz");
63  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPyPy");
64  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPyPz");
65  locBranchRegister.Register_Single<Float_t>("MissingP3_CovPzPz");
66 
67  //TRACKING INFO:
68  locBranchRegister.Register_Single<UInt_t>("NumUnusedWireBased");
69  locBranchRegister.Register_Single<UInt_t>("NumUnusedTimeBased");
70  locBranchRegister.Register_FundamentalArray<Float_t>("ReconMatchFOM_WireBased", "NumUnusedWireBased"); //FOM < 0 if nothing, no-match
71  locBranchRegister.Register_FundamentalArray<Float_t>("ReconTrackingFOM_WireBased", "NumUnusedWireBased"); //FOM < 0 if nothing, no-match
72  locBranchRegister.Register_ClonesArray<TVector3>("ReconP3_WireBased"); //wire-based
73  locBranchRegister.Register_FundamentalArray<Float_t>("ReconMatchFOM", "NumUnusedTimeBased"); //FOM < 0 if nothing, no-match (time-based)
74  locBranchRegister.Register_FundamentalArray<Float_t>("ReconTrackingFOM", "NumUnusedTimeBased"); //FOM < 0 if nothing, no-match (time-based)
75  locBranchRegister.Register_ClonesArray<TVector3>("ReconP3"); //time-based (time-based)
76  locBranchRegister.Register_FundamentalArray<Float_t>("MeasuredMissingE", "NumUnusedTimeBased"); //includes recon time-based track if found, else is -999.0
77  locBranchRegister.Register_FundamentalArray<UInt_t>("TrackCDCRings", "NumUnusedTimeBased"); //rings correspond to bits (1 -> 28)
78  locBranchRegister.Register_FundamentalArray<UInt_t>("TrackFDCPlanes", "NumUnusedTimeBased"); //planes correspond to bits (1 -> 24)
79 
80  //RECON P3 ERROR MATRIX
81  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPxPx", "NumUnusedTimeBased");
82  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPxPy", "NumUnusedTimeBased");
83  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPxPz", "NumUnusedTimeBased");
84  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPyPy", "NumUnusedTimeBased");
85  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPyPz", "NumUnusedTimeBased");
86  locBranchRegister.Register_FundamentalArray<Float_t>("ReconP3_CovPzPz", "NumUnusedTimeBased");
87 
88  //REGISTER BRANCHES
89  dTreeInterface->Create_Branches(locBranchRegister);
90 }
91 
92 bool DCustomAction_TrackingEfficiency::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
93 {
94  //Write custom code to perform an action on the INPUT DParticleCombo (DParticleCombo)
95  //NEVER: Grab DParticleCombo or DAnalysisResults objects (of any tag!) from the JEventLoop within this function
96  //NEVER: Grab objects that are created post-kinfit (e.g. DKinFitResults, etc.) from the JEventLoop if Get_UseKinFitResultsFlag() == false: CAN CAUSE INFINITE DEPENDENCY LOOP
97 
98  const DDetectorMatches* locDetectorMatches = NULL;
99  locEventLoop->GetSingle(locDetectorMatches);
100 
101  vector<const DBCALShower*> locBCALShowers;
102  locEventLoop->Get(locBCALShowers);
103 
104  vector<const DChargedTrack*> locUnusedChargedTracks;
105  dAnalysisUtilities->Get_UnusedChargedTracks(locEventLoop, locParticleCombo, locUnusedChargedTracks);
106 
107  const DEventRFBunch* locEventRFBunch = locParticleCombo->Get_EventRFBunch();
108  const DKinFitResults* locKinFitResults = locParticleCombo->Get_KinFitResults();
109 
110  /*********************************************** MISSING PARTICLE INFO ***********************************************/
111 
112  if(dMissingPID == Unknown)
113  return true; //invalid reaction setup
114  if(ParticleCharge(dMissingPID) == 0)
115  return true; //NOT SUPPORTED
116 
117  auto locMissingParticle = (locParticleCombo->Get_MissingParticles(Get_Reaction()))[0]; //is NULL if no kinfit!!
118  const DParticleComboStep* locParticleComboStep = locParticleCombo->Get_ParticleComboStep(0);
119 
120  // Get missing particle p4 & covariance
121  DLorentzVector locMeasuredMissingP4 = dAnalysisUtilities->Calc_MissingP4(Get_Reaction(), locParticleCombo, false);
122  DVector3 locMissingP3 = locMeasuredMissingP4.Vect();
123  TMatrixDSym locMissingCovarianceMatrix(3);
124  const DKinematicData* locBeamParticle = NULL;
125  if(locKinFitResults == NULL) //no kinfit (yet?), or kinfit failed
126  {
127  TMatrixFSym locFMissingCovarianceMatrix = dAnalysisUtilities->Calc_MissingP3Covariance(Get_Reaction(), locParticleCombo);
128  for(unsigned int loc_q = 0; loc_q < 3; ++loc_q)
129  {
130  for(unsigned int loc_r = 0; loc_r < 3; ++loc_r)
131  locMissingCovarianceMatrix(loc_q, loc_r) = locFMissingCovarianceMatrix(loc_q, loc_r);
132  }
133  locBeamParticle = locParticleComboStep->Get_InitialParticle_Measured();
134  }
135  else //kinfit succeeded
136  {
137  locMissingP3 = locMissingParticle->momentum();
138  const TMatrixFSym& locKinFitCovarianceMatrix = *(locMissingParticle->errorMatrix());
139  for(unsigned int loc_q = 0; loc_q < 3; ++loc_q)
140  {
141  for(unsigned int loc_r = 0; loc_r < 3; ++loc_r)
142  locMissingCovarianceMatrix(loc_q, loc_r) = locKinFitCovarianceMatrix(loc_q, loc_r);
143  }
144  locBeamParticle = locParticleComboStep->Get_InitialParticle();
145  }
146 
147  double locVertexZ = locParticleCombo->Get_EventVertex().Z();
148  double locBeamRFDeltaT = locBeamParticle->time() - locEventRFBunch->dTime;
149 
150  //get number of extra tracks that have at least 10 hits
151  size_t locNumExtraTracks = 0;
152  for(auto locChargedTrack : locUnusedChargedTracks)
153  {
154  auto locBestHypothesis = locChargedTrack->Get_BestFOM();
155  auto locNumTrackHits = locBestHypothesis->Get_TrackTimeBased()->Ndof + 5;
156  if(locNumTrackHits >= 10)
157  ++locNumExtraTracks;
158  }
159 
160  //kinfit results are unique for each DParticleCombo: no need to check for duplicates
161 
162  //FILL CHANNEL INFO
163  dTreeFillData.Fill_Single<ULong64_t>("EventNumber", locEventLoop->GetJEvent().GetEventNumber());
164  dTreeFillData.Fill_Single<Float_t>("BeamEnergy", locBeamParticle->energy());
165  dTreeFillData.Fill_Single<Float_t>("BeamRFDeltaT", locBeamRFDeltaT);
166  dTreeFillData.Fill_Single<UChar_t>("NumExtraTracks", (UChar_t)locNumExtraTracks);
167  dTreeFillData.Fill_Single<Float_t>("MissingMassSquared", locMeasuredMissingP4.M2());
168  dTreeFillData.Fill_Single<Float_t>("ComboVertexZ", locVertexZ);
169  if(locKinFitResults == NULL) //is true if no kinfit or failed to converged
170  {
171  dTreeFillData.Fill_Single<Float_t>("KinFitChiSq", -1.0);
172  dTreeFillData.Fill_Single<UInt_t>("KinFitNDF", 0);
173  }
174  else
175  {
176  dTreeFillData.Fill_Single<Float_t>("KinFitChiSq", locKinFitResults->Get_ChiSq());
177  dTreeFillData.Fill_Single<UInt_t>("KinFitNDF", locKinFitResults->Get_NDF());
178  }
179  TVector3 locTMissingP3(locMissingP3.Px(), locMissingP3.Py(), locMissingP3.Pz());
180  dTreeFillData.Fill_Single<TVector3>("MissingP3", locTMissingP3); //is kinfit if kinfit
181 
182  //MISSING P3 ERROR MATRIX //is kinfit if kinfit (& converged)
183  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPxPx", locMissingCovarianceMatrix(0, 0));
184  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPxPy", locMissingCovarianceMatrix(0, 1));
185  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPxPz", locMissingCovarianceMatrix(0, 2));
186  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPyPy", locMissingCovarianceMatrix(1, 1));
187  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPyPz", locMissingCovarianceMatrix(1, 2));
188  dTreeFillData.Fill_Single<Float_t>("MissingP3_CovPzPz", locMissingCovarianceMatrix(2, 2));
189 
190  /************************************************* WIRE-BASED TRACKS *************************************************/
191 
192  if(!locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST))
193  {
194  //Get unused tracks
195  vector<const DTrackWireBased*> locUnusedWireBasedTracks;
196  dAnalysisUtilities->Get_UnusedWireBasedTracks(locEventLoop, locParticleCombo, locUnusedWireBasedTracks);
197 
198  //loop over unused tracks
199  size_t locNumWireBasedTracks = 0;
200  for(size_t loc_i = 0; loc_i < locUnusedWireBasedTracks.size(); ++loc_i)
201  {
202  const DTrackWireBased* locWireBasedTrack = locUnusedWireBasedTracks[loc_i];
203  if(locWireBasedTrack->PID() != dMissingPID)
204  continue; //only use tracking results with correct PID
205 
206  DVector3 locWireBasedDP3 = locWireBasedTrack->momentum();
207  TVector3 locWireBasedP3(locWireBasedDP3.X(), locWireBasedDP3.Y(), locWireBasedDP3.Z());
208  dTreeFillData.Fill_Array<TVector3>("ReconP3_WireBased", locWireBasedP3, locNumWireBasedTracks);
209  dTreeFillData.Fill_Array<Float_t>("ReconTrackingFOM_WireBased", locWireBasedTrack->FOM, locNumWireBasedTracks);
210 
211  const TMatrixFSym& locCovarianceMatrix = *(locWireBasedTrack->errorMatrix());
212  TMatrixDSym locDCovarianceMatrix(3);
213  for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
214  {
215  for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
216  locDCovarianceMatrix(loc_j, loc_k) = locCovarianceMatrix(loc_j, loc_k);
217  }
218  locDCovarianceMatrix += locMissingCovarianceMatrix;
219 
220  //invert matrix
221  TDecompLU locDecompLU(locDCovarianceMatrix);
222  //check to make sure that the matrix is decomposable and has a non-zero determinant
223  if(locDecompLU.Decompose() && (fabs(locDCovarianceMatrix.Determinant()) >= 1.0E-300))
224  {
225  locDCovarianceMatrix.Invert();
226  DVector3 locDeltaP3 = locWireBasedTrack->momentum() - locMissingP3;
227  double locMatchFOM = Calc_MatchFOM(locDeltaP3, locDCovarianceMatrix);
228  dTreeFillData.Fill_Array<Float_t>("ReconMatchFOM_WireBased", locMatchFOM, locNumWireBasedTracks);
229  }
230  else //not invertable
231  dTreeFillData.Fill_Array<Float_t>("ReconMatchFOM_WireBased", -1.0, locNumWireBasedTracks);
232 
233  ++locNumWireBasedTracks;
234  }
235  dTreeFillData.Fill_Single<UInt_t>("NumUnusedWireBased", locNumWireBasedTracks);
236  }
237  else //is a REST event, no wire-based tracks
238  dTreeFillData.Fill_Single<UInt_t>("NumUnusedWireBased", 0);
239 
240  /************************************************* TIME-BASED TRACKS *************************************************/
241 
242  //Get unused tracks
243  vector<const DTrackTimeBased*> locUnusedTimeBasedTracks;
244  dAnalysisUtilities->Get_UnusedTimeBasedTracks(locEventLoop, locParticleCombo, locUnusedTimeBasedTracks);
245 
246  //loop over unused tracks
247  size_t locNumTimeBasedTracks = 0;
248  for(size_t loc_i = 0; loc_i < locUnusedTimeBasedTracks.size(); ++loc_i)
249  {
250  const DTrackTimeBased* locTimeBasedTrack = locUnusedTimeBasedTracks[loc_i];
251  if(locTimeBasedTrack->PID() != dMissingPID)
252  continue; //only use tracking results with correct PID
253 
254  DVector3 locTimeBasedDP3 = locTimeBasedTrack->momentum();
255  TVector3 locTimeBasedP3(locTimeBasedDP3.X(), locTimeBasedDP3.Y(), locTimeBasedDP3.Z());
256  dTreeFillData.Fill_Array<TVector3>("ReconP3", locTimeBasedP3, locNumTimeBasedTracks);
257  dTreeFillData.Fill_Array<Float_t>("ReconTrackingFOM", locTimeBasedTrack->FOM, locNumTimeBasedTracks);
258 
259  const TMatrixFSym& locCovarianceMatrix = *(locTimeBasedTrack->errorMatrix());
260  TMatrixDSym locDCovarianceMatrix(3);
261  for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
262  {
263  for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
264  locDCovarianceMatrix(loc_j, loc_k) = locCovarianceMatrix(loc_j, loc_k);
265  }
266  locDCovarianceMatrix += locMissingCovarianceMatrix;
267 
268  //invert matrix
269  TDecompLU locDecompLU(locDCovarianceMatrix);
270  //check to make sure that the matrix is decomposable and has a non-zero determinant
271  if(locDecompLU.Decompose() && (fabs(locDCovarianceMatrix.Determinant()) >= 1.0E-300))
272  {
273  locDCovarianceMatrix.Invert();
274  DVector3 locDeltaP3 = locTimeBasedTrack->momentum() - locMissingP3;
275  double locMatchFOM = Calc_MatchFOM(locDeltaP3, locDCovarianceMatrix);
276  dTreeFillData.Fill_Array<Float_t>("ReconMatchFOM", locMatchFOM, locNumTimeBasedTracks);
277  }
278  else //not invertible
279  dTreeFillData.Fill_Array<Float_t>("ReconMatchFOM", -1.0, locNumTimeBasedTracks);
280 
281  DLorentzVector locTotalMeasuredMissingP4 = locMeasuredMissingP4 - locTimeBasedTrack->lorentzMomentum();
282  dTreeFillData.Fill_Array<Float_t>("MeasuredMissingE", locTotalMeasuredMissingP4.E(), locNumTimeBasedTracks);
283  dTreeFillData.Fill_Array<UInt_t>("TrackCDCRings", locTimeBasedTrack->dCDCRings, locNumTimeBasedTracks);
284  dTreeFillData.Fill_Array<UInt_t>("TrackFDCPlanes", locTimeBasedTrack->dFDCPlanes, locNumTimeBasedTracks);
285 
286  //RECON P3 ERROR MATRIX
287  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPxPx", locCovarianceMatrix(0, 0), locNumTimeBasedTracks);
288  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPxPy", locCovarianceMatrix(0, 1), locNumTimeBasedTracks);
289  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPxPz", locCovarianceMatrix(0, 2), locNumTimeBasedTracks);
290  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPyPy", locCovarianceMatrix(1, 1), locNumTimeBasedTracks);
291  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPyPz", locCovarianceMatrix(1, 2), locNumTimeBasedTracks);
292  dTreeFillData.Fill_Array<Float_t>("ReconP3_CovPzPz", locCovarianceMatrix(2, 2), locNumTimeBasedTracks);
293 
294  ++locNumTimeBasedTracks;
295  }
296 
297  dTreeFillData.Fill_Single<UInt_t>("NumUnusedTimeBased", locNumTimeBasedTracks);
298 
299  //FILL TTREE
301  return true;
302 }
303 
304 double DCustomAction_TrackingEfficiency::Calc_MatchFOM(const DVector3& locDeltaP3, TMatrixDSym locInverse3x3Matrix) const
305 {
306  DMatrix locDeltas(3, 1);
307  locDeltas(0, 0) = locDeltaP3.Px();
308  locDeltas(1, 0) = locDeltaP3.Py();
309  locDeltas(2, 0) = locDeltaP3.Pz();
310 
311  double locChiSq = (locInverse3x3Matrix.SimilarityT(locDeltas))(0, 0);
312  return TMath::Prob(locChiSq, 3);
313 }
TMatrixD DMatrix
Definition: DMatrix.h:14
double Calc_MatchFOM(const DVector3 &locDeltaP3, TMatrixDSym locInverse3x3Matrix) const
TVector3 DVector3
Definition: DVector3.h:14
double energy(void) const
const DReaction * Get_Reaction(void) const
void Get_UnusedTimeBasedTracks(JEventLoop *locEventLoop, const DParticleCombo *locParticleCombo, vector< const DTrackTimeBased * > &locUnusedTimeBasedTracks) const
void Fill_Array(string locBranchName, const DType &locData, size_t locArrayIndex)
bool Create_Branches(const DTreeBranchRegister &locTreeBranchRegister)
const DKinematicData * Get_InitialParticle_Measured(void) const
TLorentzVector DLorentzVector
const DEventRFBunch * Get_EventRFBunch(void) const
static int ParticleCharge(Particle_t p)
static int PDGtype(Particle_t p)
double Get_ChiSq(void) const
unsigned int dFDCPlanes
double time(void) const
void Fill(DTreeFillData &locTreeFillData)
void Get_UnusedChargedTracks(JEventLoop *locEventLoop, const DParticleCombo *locParticleCombo, vector< const DChargedTrack * > &locUnusedChargedTracks) const
static DTreeInterface * Create_DTreeInterface(string locTreeName, string locFileName)
DLorentzVector Calc_MissingP4(const DReaction *locReaction, const DParticleCombo *locParticleCombo, bool locUseKinFitDataFlag) const
vector< const DKinematicData * > Get_MissingParticles(const DReaction *locReaction) const
string Get_ReactionName(void) const
Definition: DReaction.h:75
bool Perform_Action(JEventLoop *locEventLoop, const DParticleCombo *locParticleCombo)
void Get_UnusedWireBasedTracks(JEventLoop *locEventLoop, const DParticleCombo *locParticleCombo, vector< const DTrackWireBased * > &locUnusedWireBasedTracks) const
TList * Get_UserInfo(void) const
vector< Particle_t > Get_MissingPIDs(int locStepIndex=-1, Charge_t locCharge=d_AllCharges, bool locIncludeDuplicatesFlag=true) const
Definition: DReaction.cc:46
DLorentzVector lorentzMomentum(void) const
unsigned int dCDCRings
const DKinematicData * Get_InitialParticle(void) const
const DVector3 & momentum(void) const
const DKinFitResults * Get_KinFitResults(void) const
shared_ptr< const TMatrixFSym > errorMatrix(void) const
const DParticleComboStep * Get_ParticleComboStep(size_t locStepIndex) const
unsigned int Get_NDF(void) const
DLorentzVector Get_EventVertex(void) const
Particle_t PID(void) const
TMatrixFSym Calc_MissingP3Covariance(const DReaction *locReaction, const DParticleCombo *locParticleCombo) const
void Fill_Single(string locBranchName, const DType &locData)