Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DKinFitUtils.cc
Go to the documentation of this file.
1 #include "DKinFitUtils.h"
2 
3 /*************************************************************** RESOURCE MANAGEMENT ***************************************************************/
4 
6 {
7  dKinFitter = nullptr; //Is set by DKinFitter constructor
8  dLinkVerticesFlag = true;
9  dDebugLevel = 0;
11 
12  dResourcePool_TMatrixFSym = std::make_shared<DResourcePool<TMatrixFSym>>();
13  dResourcePool_TMatrixFSym->Set_ControlParams(20, 20, 100);
14 
15  dResourcePool_KinFitParticle = std::make_shared<DResourcePool<DKinFitParticle>>();
16  dResourcePool_KinFitParticle->Set_ControlParams(50, 20, 500, 5000, 0);
17 
18  dResourcePool_KinFitChainStep = std::make_shared<DResourcePool<DKinFitChainStep>>();
19  dResourcePool_KinFitChainStep->Set_ControlParams(5, 5, 50, 100, 0);
20 
21  dResourcePool_KinFitChain = std::make_shared<DResourcePool<DKinFitChain>>();
22  dResourcePool_KinFitChain->Set_ControlParams(5, 5, 50, 100, 0);
23 
24  dResourcePool_MassConstraint = std::make_shared<DResourcePool<DKinFitConstraint_Mass>>();
25  dResourcePool_MassConstraint->Set_ControlParams(20, 20, 100, 300, 0);
26 
27  dResourcePool_P4Constraint = std::make_shared<DResourcePool<DKinFitConstraint_P4>>();
28  dResourcePool_P4Constraint->Set_ControlParams(20, 20, 100, 300, 0);
29 
30  dResourcePool_VertexConstraint = std::make_shared<DResourcePool<DKinFitConstraint_Vertex>>();
31  dResourcePool_VertexConstraint->Set_ControlParams(20, 20, 100, 300, 0);
32 
33  dResourcePool_SpacetimeConstraint = std::make_shared<DResourcePool<DKinFitConstraint_Spacetime>>();
34  dResourcePool_SpacetimeConstraint->Set_ControlParams(20, 20, 100, 300, 0);
35 }
36 
38 {
40  dMassConstraintMap.clear();
41  dP4ConstraintMap.clear();
42  dVertexConstraintMap.clear();
44  Reset_NewFit();
45 }
46 
47 shared_ptr<TMatrixFSym> DKinFitUtils::Get_SymMatrixResource(unsigned int locNumMatrixRows)
48 {
49  auto locSymMatrix = dResourcePool_TMatrixFSym->Get_SharedResource();
50  locSymMatrix->ResizeTo(locNumMatrixRows, locNumMatrixRows);
51  return locSymMatrix;
52 }
53 
54 /***************************************************************** CREATE PARTICLES ****************************************************************/
55 
56 shared_ptr<DKinFitParticle> DKinFitUtils::Make_BeamParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, const shared_ptr<const TMatrixFSym>& locCovarianceMatrix)
57 {
58  if((locCovarianceMatrix->GetNrows() != 7) || (locCovarianceMatrix->GetNcols() != 7))
59  return NULL; //is not 7x7
60 
61  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
62  locKinFitParticle->Set_PID(locPID);
63  locKinFitParticle->Set_Charge(locCharge);
64  locKinFitParticle->Set_Mass(locMass);
65  locKinFitParticle->Set_SpacetimeVertex(locSpacetimeVertex);
66  locKinFitParticle->Set_CommonSpacetimeVertex(locSpacetimeVertex);
67 
68  locKinFitParticle->Set_Momentum(locMomentum);
69  locKinFitParticle->Set_CovarianceMatrix(locCovarianceMatrix);
70 
71  locKinFitParticle->Set_KinFitParticleType(d_BeamParticle);
72 
73  if(dDebugLevel > 5)
74  {
75  cout << "DKinFitUtils: Beam particle created. Printing:" << endl;
76  locKinFitParticle->Print_ParticleParams();
77  }
78 
79  return locKinFitParticle;
80 }
81 
82 shared_ptr<DKinFitParticle> DKinFitUtils::Make_TargetParticle(int locPID, int locCharge, double locMass)
83 {
84  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
85  locKinFitParticle->Set_PID(locPID);
86  locKinFitParticle->Set_Charge(locCharge);
87  locKinFitParticle->Set_Mass(locMass);
88  locKinFitParticle->Set_KinFitParticleType(d_TargetParticle);
89  locKinFitParticle->Set_VertexP4AtProductionVertex(true);
90 
91  if(dDebugLevel > 5)
92  {
93  cout << "DKinFitUtils: Target particle created. Printing:" << endl;
94  locKinFitParticle->Print_ParticleParams();
95  }
96 
97  return locKinFitParticle;
98 }
99 
100 shared_ptr<DKinFitParticle> DKinFitUtils::Make_DetectedParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, double locPathLength, const shared_ptr<const TMatrixFSym>& locCovarianceMatrix)
101 {
102  if((locCovarianceMatrix->GetNrows() != 7) || (locCovarianceMatrix->GetNcols() != 7))
103  return NULL; //is not 7x7
104 
105  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
106  locKinFitParticle->Set_PID(locPID);
107  locKinFitParticle->Set_Charge(locCharge);
108  locKinFitParticle->Set_Mass(locMass);
109  locKinFitParticle->Set_SpacetimeVertex(locSpacetimeVertex);
110  locKinFitParticle->Set_CommonSpacetimeVertex(locSpacetimeVertex);
111  locKinFitParticle->Set_Momentum(locMomentum);
112  locKinFitParticle->Set_CovarianceMatrix(locCovarianceMatrix);
113  locKinFitParticle->Set_PathLength(locPathLength);
114  locKinFitParticle->Set_KinFitParticleType(d_DetectedParticle);
115 
116  if(dDebugLevel > 5)
117  {
118  cout << "DKinFitUtils: Detected particle created. Printing:" << endl;
119  locKinFitParticle->Print_ParticleParams();
120  }
121 
122  return locKinFitParticle;
123 }
124 
125 shared_ptr<DKinFitParticle> DKinFitUtils::Make_DetectedShower(int locPID, double locMass, TLorentzVector locSpacetimeVertex, double locShowerEnergy, const shared_ptr<const TMatrixFSym>& locCovarianceMatrix)
126 {
127  if((locCovarianceMatrix->GetNrows() != 5) || (locCovarianceMatrix->GetNcols() != 5))
128  return NULL; //is not 5x5
129 
130  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
131  locKinFitParticle->Set_PID(locPID);
132  locKinFitParticle->Set_Charge(0);
133  locKinFitParticle->Set_Mass(locMass);
134  locKinFitParticle->Set_IsNeutralShowerFlag(true);
135  locKinFitParticle->Set_SpacetimeVertex(locSpacetimeVertex);
136  locKinFitParticle->Set_CommonSpacetimeVertex(locSpacetimeVertex); //will be updated with vertex guess
137  locKinFitParticle->Set_ShowerEnergy(locShowerEnergy);
138  locKinFitParticle->Set_CovarianceMatrix(locCovarianceMatrix);
139 
140  locKinFitParticle->Set_KinFitParticleType(d_DetectedParticle);
141 
142  if(dDebugLevel > 5)
143  {
144  cout << "DKinFitUtils: Detected shower created. Printing:" << endl;
145  locKinFitParticle->Print_ParticleParams();
146  }
147 
148  return locKinFitParticle;
149 }
150 
151 shared_ptr<DKinFitParticle> DKinFitUtils::Make_MissingParticle(int locPID, int locCharge, double locMass)
152 {
153  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
154  locKinFitParticle->Set_PID(locPID);
155  locKinFitParticle->Set_Charge(locCharge);
156  locKinFitParticle->Set_Mass(locMass);
157  locKinFitParticle->Set_KinFitParticleType(d_MissingParticle);
158  locKinFitParticle->Set_VertexP4AtProductionVertex(true);
159 
160  if(dDebugLevel > 5)
161  {
162  cout << "DKinFitUtils: Missing particle created. Printing:" << endl;
163  locKinFitParticle->Print_ParticleParams();
164  }
165 
166  return locKinFitParticle;
167 }
168 
169 shared_ptr<DKinFitParticle> DKinFitUtils::Make_DecayingParticle(int locPID, int locCharge, double locMass, const set<shared_ptr<DKinFitParticle>>& locFromInitialState, const set<shared_ptr<DKinFitParticle>>& locFromFinalState)
170 {
171  auto locKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
172  locKinFitParticle->Set_PID(locPID);
173  locKinFitParticle->Set_Charge(locCharge);
174  locKinFitParticle->Set_Mass(locMass);
175  locKinFitParticle->Set_KinFitParticleType(d_DecayingParticle);
176  locKinFitParticle->Set_FromInitialState(locFromInitialState);
177  locKinFitParticle->Set_FromFinalState(locFromFinalState);
178 
179  if(dDebugLevel > 5)
180  {
181  cout << "DKinFitUtils: Decaying particle created. Printing:" << endl;
182  locKinFitParticle->Print_ParticleParams();
183  }
184 
185  return locKinFitParticle;
186 }
187 
188 /**************************************************************** CREATE CONSTRAINTS ***************************************************************/
189 
190 shared_ptr<DKinFitConstraint_Mass> DKinFitUtils::Make_MassConstraint(const shared_ptr<DKinFitParticle>& locDecayingParticle)
191 {
192  if(locDecayingParticle->dKinFitParticleType != d_DecayingParticle)
193  {
194  cout << "ERROR: Wrong particle type in DKinFitUtils::Make_MassConstraint(). Returning NULL." << endl;
195  return nullptr;
196  }
197 
198  //if constraint already exists for this particle, return it
199  auto locIterator = dMassConstraintMap.find(locDecayingParticle);
200  if(locIterator != dMassConstraintMap.end())
201  return locIterator->second;
202 
203  auto locConstraint = dResourcePool_MassConstraint->Get_SharedResource();
204  locConstraint->Set_DecayingParticle(locDecayingParticle);
205 
206  dMassConstraintMap[locDecayingParticle] = locConstraint;
207  return locConstraint;
208 }
209 
210 shared_ptr<DKinFitConstraint_P4> DKinFitUtils::Make_P4Constraint(const set<shared_ptr<DKinFitParticle>>& locInitialParticles, const set<shared_ptr<DKinFitParticle>>& locFinalParticles)
211 {
212  //if constraint already exists for this input, return it
213  auto locInputPair = std::make_pair(locInitialParticles, locFinalParticles);
214  auto locIterator = dP4ConstraintMap.find(locInputPair);
215  if(locIterator != dP4ConstraintMap.end())
216  return locIterator->second;
217 
218  auto locConstraint = dResourcePool_P4Constraint->Get_SharedResource();
219  locConstraint->Set_InitialParticles(locInitialParticles);
220  locConstraint->Set_FinalParticles(locFinalParticles);
221 
222  dP4ConstraintMap[locInputPair] = locConstraint;
223  return locConstraint;
224 }
225 
226 shared_ptr<DKinFitConstraint_Vertex> DKinFitUtils::Make_VertexConstraint(const set<shared_ptr<DKinFitParticle>>& locFullConstrainParticles, const set<shared_ptr<DKinFitParticle>>& locNoConstrainParticles, TVector3 locVertexGuess)
227 {
228  //if constraint already exists for this input, return it
229  auto locInputPair = std::make_pair(locFullConstrainParticles, locNoConstrainParticles);
230  auto locIterator = dVertexConstraintMap.find(locInputPair);
231  if(locIterator != dVertexConstraintMap.end())
232  return locIterator->second;
233 
234  auto locConstraint = dResourcePool_VertexConstraint->Get_SharedResource();
235  locConstraint->Set_FullConstrainParticles(locFullConstrainParticles);
236  locConstraint->Set_NoConstrainParticles(locNoConstrainParticles);
237  locConstraint->Set_InitVertexGuess(locVertexGuess);
238 
239  dVertexConstraintMap[locInputPair] = locConstraint;
240  return locConstraint;
241 }
242 
243 shared_ptr<DKinFitConstraint_Spacetime> DKinFitUtils::Make_SpacetimeConstraint(const set<shared_ptr<DKinFitParticle>>& locFullConstrainParticles, const set<shared_ptr<DKinFitParticle>>& locOnlyConstrainTimeParticles, const set<shared_ptr<DKinFitParticle>>& locNoConstrainParticles, TLorentzVector locSpacetimeGuess)
244 {
245  cout << "ERROR: SPACETIME CONSTRAINTS ARE NOT SUPPORTED YET. RETURNING NULL FROM DKinFitUtils::Make_SpacetimeConstraint()." << endl;
246  return NULL;
247 
248  //if constraint already exists for this input, return it
249  DSpacetimeParticles locSpacetimeParticles(locFullConstrainParticles, locOnlyConstrainTimeParticles, locNoConstrainParticles);
250  auto locIterator = dSpacetimeConstraintMap.find(locSpacetimeParticles);
251  if(locIterator != dSpacetimeConstraintMap.end())
252  return locIterator->second;
253 
254  auto locConstraint = dResourcePool_SpacetimeConstraint->Get_SharedResource();
255  locConstraint->Set_FullConstrainParticles(locFullConstrainParticles);
256  locConstraint->Set_OnlyConstrainTimeParticles(locOnlyConstrainTimeParticles);
257  locConstraint->Set_NoConstrainParticles(locNoConstrainParticles);
258  locConstraint->Set_InitVertexGuess(locSpacetimeGuess.Vect());
259  locConstraint->Set_InitTimeGuess(locSpacetimeGuess.T());
260 
261  dSpacetimeConstraintMap[locSpacetimeParticles] = locConstraint;
262  return locConstraint;
263 }
264 
265 /********************************************************** CLONE PARTICLES AND CONSTRAINTS ********************************************************/
266 
267 shared_ptr<TMatrixFSym> DKinFitUtils::Clone_SymMatrix(const TMatrixFSym* locMatrix)
268 {
269  if(locMatrix == NULL)
270  return NULL;
271  int locMatrixSize = locMatrix->GetNcols();
272  auto locNewMatrix = Get_SymMatrixResource(locMatrixSize);
273  *locNewMatrix = *locMatrix;
274  return locNewMatrix;
275 }
276 
277 shared_ptr<DKinFitParticle> DKinFitUtils::Clone_KinFitParticle(const shared_ptr<DKinFitParticle>& locKinFitParticle)
278 {
279  auto locClonedKinFitParticle = dResourcePool_KinFitParticle->Get_SharedResource();
280  *locClonedKinFitParticle = *locKinFitParticle;
281  dParticleMap_OutputToInput[locClonedKinFitParticle] = locKinFitParticle;
282 
283  if(dDebugLevel > 20)
284  cout << "Cloned Particle: PID, input, output = " << locKinFitParticle->Get_PID() << ", " << locKinFitParticle << ", " << locClonedKinFitParticle << endl;
285 
286  //clone covariance matrix
287  auto locCovarianceMatrix = locClonedKinFitParticle->Get_CovarianceMatrix();
288  if((locCovarianceMatrix != NULL) && dUpdateCovarianceMatricesFlag)
289  locClonedKinFitParticle->Set_CovarianceMatrix(Clone_SymMatrix(locCovarianceMatrix.get()));
290 
291  return locClonedKinFitParticle;
292 }
293 
294 shared_ptr<DKinFitConstraint_P4> DKinFitUtils::Clone_KinFitConstraint_P4(const DKinFitConstraint_P4* locConstraint)
295 {
296  //to be called PRIOR to a fit
297  auto locClonedConstraint = dResourcePool_P4Constraint->Get_SharedResource();
298  *locClonedConstraint = *locConstraint;
299  return locClonedConstraint;
300 }
301 
302 shared_ptr<DKinFitConstraint_Mass> DKinFitUtils::Clone_KinFitConstraint_Mass(const DKinFitConstraint_Mass* locConstraint)
303 {
304  //to be called PRIOR to a fit
305  auto locClonedConstraint = dResourcePool_MassConstraint->Get_SharedResource();
306  *locClonedConstraint = *locConstraint;
307  return locClonedConstraint;
308 }
309 
310 shared_ptr<DKinFitConstraint_Vertex> DKinFitUtils::Clone_KinFitConstraint_Vertex(const DKinFitConstraint_Vertex* locConstraint)
311 {
312  //to be called PRIOR to a fit
313  auto locClonedConstraint = dResourcePool_VertexConstraint->Get_SharedResource();
314  *locClonedConstraint = *locConstraint;
315  return locClonedConstraint;
316 }
317 
318 shared_ptr<DKinFitConstraint_Spacetime> DKinFitUtils::Clone_KinFitConstraint_Spacetime(const DKinFitConstraint_Spacetime* locConstraint)
319 {
320  //to be called PRIOR to a fit
321  auto locClonedConstraint = dResourcePool_SpacetimeConstraint->Get_SharedResource();
322  *locClonedConstraint = *locConstraint;
323  return locClonedConstraint;
324 }
325 
326 set<shared_ptr<DKinFitParticle>> DKinFitUtils::Build_CloneParticleSet(const set<shared_ptr<DKinFitParticle>>& locInputParticles, const map<shared_ptr<DKinFitParticle>, shared_ptr<DKinFitParticle>>& locCloneIOMap) const
327 {
328  set<shared_ptr<DKinFitParticle>> locCloneParticles;
329  for(auto& locParticle : locInputParticles)
330  locCloneParticles.insert(locCloneIOMap.find(locParticle)->second);
331  return locCloneParticles;
332 }
333 
334 set<shared_ptr<DKinFitConstraint>> DKinFitUtils::Clone_ParticlesAndConstraints(const set<shared_ptr<DKinFitConstraint>>& locInputConstraints)
335 {
336  set<shared_ptr<DKinFitConstraint>> locClonedConstraints;
337 
338  //Get all of the particles from the constraints (some particles may be listed in multiple constraints!)
339  //This is why you can't clone the constraint particles one constraint at a time
340  set<shared_ptr<DKinFitParticle>> locAllParticles;
341  for(auto& locConstraint : locInputConstraints)
342  {
343  auto locConstraintKinFitParticles = locConstraint->Get_AllParticles();
344  locAllParticles.insert(locConstraintKinFitParticles.begin(), locConstraintKinFitParticles.end());
345 
346  //now, for those particles that may not directly be used in a constraint, but ARE used to define a decaying particle
347  for(auto& locParticle : locConstraintKinFitParticles)
348  {
349  auto locFromAllParticles = locParticle->Get_FromAllParticles();
350  locAllParticles.insert(locFromAllParticles.begin(), locFromAllParticles.end());
351  }
352  }
353 
354  //Clone all of the particles //keep track of clone IO for this fit
355  //can't do as an overall class member, because one input may have several cloned outputs (multiple fits).
356  //but for this fit, can track locally (here)
357  map<shared_ptr<DKinFitParticle>, shared_ptr<DKinFitParticle>> locCloneIOMap; //for this fit
358  for(auto& locParticle : locAllParticles)
359  locCloneIOMap[locParticle] = Clone_KinFitParticle(locParticle);
360 
361  //Now, for all of the decaying cloned particles, go through and set new pointers for the from-initial and from-final state particles
362  for(auto& locClonePair : locCloneIOMap)
363  {
364  auto locOutputParticle = locClonePair.second;
365  if(locOutputParticle->Get_KinFitParticleType() != d_DecayingParticle)
366  continue; //none
367 
368  //initial state
369  set<shared_ptr<DKinFitParticle>> locNewFromInitialState;
370  auto locFromInitialState = locOutputParticle->Get_FromInitialState();
371  for(auto& locParticle : locFromInitialState)
372  locNewFromInitialState.insert(locCloneIOMap[locParticle]);
373  locOutputParticle->Set_FromInitialState(locNewFromInitialState);
374 
375  //final state
376  set<shared_ptr<DKinFitParticle>> locNewFromFinalState;
377  auto locFromFinalState = locOutputParticle->Get_FromFinalState();
378  for(auto& locParticle : locFromFinalState)
379  locNewFromFinalState.insert(locCloneIOMap[locParticle]);
380  locOutputParticle->Set_FromFinalState(locNewFromFinalState);
381  }
382 
383  //Clone the constraints, and then set the particles to the cloned particles
384  for(auto& locConstraint : locInputConstraints)
385  {
386  auto locP4Constraint = std::dynamic_pointer_cast<DKinFitConstraint_P4>(locConstraint);
387  if(locP4Constraint != NULL)
388  {
389  auto locClonedConstraint = Clone_KinFitConstraint_P4(locP4Constraint.get());
390  locClonedConstraint->Set_InitialParticles(Build_CloneParticleSet(locClonedConstraint->Get_InitialParticles(), locCloneIOMap));
391  locClonedConstraint->Set_FinalParticles(Build_CloneParticleSet(locClonedConstraint->Get_FinalParticles(), locCloneIOMap));
392  locClonedConstraints.insert(std::dynamic_pointer_cast<DKinFitConstraint>(locClonedConstraint));
393  continue;
394  }
395 
396  auto locMassConstraint = std::dynamic_pointer_cast<DKinFitConstraint_Mass>(locConstraint);
397  if(locMassConstraint != NULL)
398  {
399  auto locClonedConstraint = Clone_KinFitConstraint_Mass(locMassConstraint.get());
400  locClonedConstraint->Set_DecayingParticle(locCloneIOMap.find(locClonedConstraint->Get_DecayingParticle())->second);
401  locClonedConstraints.insert(std::dynamic_pointer_cast<DKinFitConstraint>(locClonedConstraint));
402  continue;
403  }
404 
405  auto locVertexConstraint = std::dynamic_pointer_cast<DKinFitConstraint_Vertex>(locConstraint);
406  auto locSpacetimeConstraint = std::dynamic_pointer_cast<DKinFitConstraint_Spacetime>(locConstraint);
407  if((locVertexConstraint != NULL) && (locSpacetimeConstraint == NULL))
408  {
409  auto locClonedConstraint = Clone_KinFitConstraint_Vertex(locVertexConstraint.get());
410  locClonedConstraint->Set_FullConstrainParticles(Build_CloneParticleSet(locClonedConstraint->Get_FullConstrainParticles(), locCloneIOMap));
411  locClonedConstraint->Set_NoConstrainParticles(Build_CloneParticleSet(locClonedConstraint->Get_NoConstrainParticles(), locCloneIOMap));
412  locClonedConstraints.insert(std::dynamic_pointer_cast<DKinFitConstraint>(locClonedConstraint));
413  continue;
414  }
415 
416  if(locSpacetimeConstraint != NULL)
417  {
418  auto locClonedConstraint = Clone_KinFitConstraint_Spacetime(locSpacetimeConstraint.get());
419  locClonedConstraint->Set_FullConstrainParticles(Build_CloneParticleSet(locClonedConstraint->Get_FullConstrainParticles(), locCloneIOMap));
420  locClonedConstraint->Set_NoConstrainParticles(Build_CloneParticleSet(locClonedConstraint->Get_NoConstrainParticles(), locCloneIOMap));
421  locClonedConstraint->Set_OnlyConstrainTimeParticles(Build_CloneParticleSet(locClonedConstraint->Get_OnlyConstrainTimeParticles(), locCloneIOMap));
422  locClonedConstraints.insert(std::dynamic_pointer_cast<DKinFitConstraint>(locClonedConstraint));
423  continue;
424  }
425  }
426 
427  return locClonedConstraints;
428 }
429 
430 void DKinFitUtils::Recycle_LastFitMemory(set<shared_ptr<DKinFitConstraint>>& locKinFitConstraints)
431 {
432  //Get all of the particles from the constraints (some particles may be listed in multiple constraints!)
433  //This is why you can't clone the constraint particles one constraint at a time
434  set<shared_ptr<DKinFitParticle>> locAllParticles;
435  auto locConstraintIterator = locKinFitConstraints.begin();
436  for(; locConstraintIterator != locKinFitConstraints.end(); ++locConstraintIterator)
437  {
438  auto locConstraintKinFitParticles = (*locConstraintIterator)->Get_AllParticles();
439  locAllParticles.insert(locConstraintKinFitParticles.begin(), locConstraintKinFitParticles.end());
440 
441  //now, for those particles that may not directly be used in a constraint, but ARE used to define a decaying particle
442  auto locParticleIterator = locConstraintKinFitParticles.begin();
443  for(; locParticleIterator != locConstraintKinFitParticles.end(); ++locParticleIterator)
444  {
445  auto locFromAllParticles = (*locParticleIterator)->Get_FromAllParticles();
446  locAllParticles.insert(locFromAllParticles.begin(), locFromAllParticles.end());
447  }
448  }
449 
450  //Remove them from the output-to-input clone map
451  for(auto& locParticle : locAllParticles)
452  dParticleMap_OutputToInput.erase(locParticle);
453 
454  locKinFitConstraints.clear();
455 }
456 
457 /*************************************************************** VALIDATE CONSTRAINTS **************************************************************/
458 
459 bool DKinFitUtils::Validate_Constraints(const set<shared_ptr<DKinFitConstraint>>& locKinFitConstraints) const
460 {
461  //Do independent of the kinematic fitter!
462  //Empty for now. User can override in derived class
463  return true;
464 }
465 
466 /*************************************************************** CALCULATION ROUTINES **************************************************************/
467 
469 {
470  auto locFromInitState = locKinFitParticle->Get_FromInitialState();
471  if(locFromInitState.empty())
472  return true;
473  if(locFromInitState.size() >= 2)
474  return false;
475  return ((*locFromInitState.begin())->Get_KinFitParticleType() == d_TargetParticle);
476 }
477 
478 TLorentzVector DKinFitUtils::Calc_DecayingP4_ByPosition(const DKinFitParticle* locKinFitParticle, bool locAtPositionFlag, bool locDontPropagateAtAllFlag) const
479 {
480  //if input flag is true: return the value of the p4 at spot defined by locKinFitParticle->Get_Position() //else at the common vertex
481  //useful for setting the momentum: locKinFitParticle->Set_Momentum()
482  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
483  return TLorentzVector();
484 
485  bool locP3DerivedAtProductionVertexFlag = !Get_IsDecayingParticleDefinedByProducts(locKinFitParticle); //else decay vertex
486  bool locP3DerivedAtPositionFlag = (locP3DerivedAtProductionVertexFlag == locKinFitParticle->Get_VertexP4AtProductionVertex());
487  bool locDontPropagateDecayingP3Flag = (locP3DerivedAtPositionFlag == locAtPositionFlag);
488  return Calc_DecayingP4(locKinFitParticle, locDontPropagateDecayingP3Flag, 1.0, locDontPropagateAtAllFlag);
489 }
490 
491 TLorentzVector DKinFitUtils::Calc_DecayingP4_ByP3Derived(const DKinFitParticle* locKinFitParticle, bool locAtP3DerivedFlag, bool locDontPropagateAtAllFlag) const
492 {
493  //if input flag is true: return the value of the p4 at the vertex where the p3-deriving particles are at
494  //useful for doing mass constraints
495  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
496  return TLorentzVector();
497 
498  bool locDontPropagateDecayingP3Flag = locAtP3DerivedFlag;
499  return Calc_DecayingP4(locKinFitParticle, locDontPropagateDecayingP3Flag, 1.0, locDontPropagateAtAllFlag);
500 }
501 
502 TLorentzVector DKinFitUtils::Calc_DecayingP4_ByVertex(const DKinFitParticle* locKinFitParticle, bool locAtProductionVertexFlag, bool locDontPropagateAtAllFlag) const
503 {
504  //if input flag is true: return the value of the p4 at the production vertex
505  //else return it at the decay vertex
506  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
507  return TLorentzVector();
508 
509  bool locP3DerivedAtProductionVertexFlag = !Get_IsDecayingParticleDefinedByProducts(locKinFitParticle);
510  bool locDontPropagateDecayingP3Flag = (locP3DerivedAtProductionVertexFlag == locAtProductionVertexFlag);
511  return Calc_DecayingP4(locKinFitParticle, locDontPropagateDecayingP3Flag, 1.0, locDontPropagateAtAllFlag);
512 }
513 
514 //Don't call this directly! Well you can, but it's a little confusing. Better to call the wrapper functions.
515 TLorentzVector DKinFitUtils::Calc_DecayingP4(const DKinFitParticle* locKinFitParticle, bool locDontPropagateDecayingP3Flag, double locStateSignMultiplier, bool locDontPropagateAtAllFlag) const
516 {
517  //locDontPropagateDecayingP3Flag: if true: don't propagate first decaying particle p3 from defined vertex to the other vertex
518  //E, px, py, pz
519  int locCharge = locKinFitParticle->Get_Charge();
520  DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
521 
522  TLorentzVector locP4 = locKinFitParticle->Get_P4();
523  TVector3 locPosition = locKinFitParticle->Get_Position();
524  TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
525  TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
526 
527  //This section is calculated assuming that the p4 is NEEDED at the COMMON vertex
528  //if not, need a factor of -1 on delta-x, and on the derivatives wrst the vertices
529  //e.g. for detected particles, needed p4 is at the common vertex, but it is defined at some other point on its trajectory
530  //HOWEVER, for decaying particles, this MAY NOT be true: it MAY be defined at the position where it is needed
531  //Decaying particles technically have two common vertices: where it is produced and where it decays
532  //So here, the DEFINED vertex is where its position is defined by the other tracks,
533  //and its COMMON vertex is the vertex where it is used to constrain another vertex
534  //e.g. g, p -> K+, K+, Xi- Xi- -> pi-, Lambda Lambda -> p, pi-
535  //Assuming standard constraint setup: p4 constraint is initial step, mass constraints by invariant mass, Xi- vertex defined by K's
536  //For Xi-, the p3 is defined at its decay vertex (by decay products)
537  //And the Xi- DEFINED vertex is at its production vertex (from kaons)
538  //But the p3 is NEEDED at the production vertex, which is where it's DEFINED
539  //Thus we need a factor of -1
540  bool locNeedP4AtProductionVertex = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle); //true if defined by decay products; else by missing mass
541  double locVertexSignMultiplier = (locNeedP4AtProductionVertex == locKinFitParticle->Get_VertexP4AtProductionVertex()) ? -1.0 : 1.0;
542  TVector3 locDeltaX = locVertexSignMultiplier*(locCommonVertex - locPosition); //vector points in the OPPOSITE direction of the momentum
543 
544  TVector3 locH = locBField.Unit();
545  double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
546 
547  bool locCommonVertexFitFlag = locKinFitParticle->Get_FitCommonVertexFlag();
548  bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
549 
550  TLorentzVector locP4Sum;
551  if(locKinFitParticleType != d_DecayingParticle)
552  locP4Sum += locStateSignMultiplier*locP4; //all but enclosed decaying particle: will instead get p4 from decay products (may still need to propagate it below)
553 
554  if(dDebugLevel > 30)
555  cout << "PID, sign, pxyzE = " << locKinFitParticle->Get_PID() << ", " << locStateSignMultiplier << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locP4.E() << endl;
556 
557  if(!locDontPropagateAtAllFlag && (locKinFitParticleType != d_MissingParticle) && (locKinFitParticleType != d_TargetParticle) && locCommonVertexFitFlag && locChargedBFieldFlag && ((locKinFitParticleType != d_DecayingParticle) || !locDontPropagateDecayingP3Flag))
558  {
559  //fitting vertex of charged track in magnetic field: momentum changes as function of vertex
560  //decaying particles: p4 not directly used, deriving particles are: so must propagate if charged
561  //if initial particle is a "detected" particle (actually a decaying particle treated as detected): still propagate vertex (assume p3/v3 defined at production vertex)
562 
563  TVector3 locDeltaXCrossH = locDeltaX.Cross(locH);
564  if(dDebugLevel > 30)
565  cout << "propagate pxyz by: " << -1.0*locStateSignMultiplier*locA*locDeltaXCrossH.X() << ", " << -1.0*locStateSignMultiplier*locA*locDeltaXCrossH.Y() << ", " << -1.0*locStateSignMultiplier*locA*locDeltaXCrossH.Z() << endl;
566 
567  locP4Sum.SetVect(locP4Sum.Vect() - locStateSignMultiplier*locA*locDeltaXCrossH);
568  }
569 
570  if(locKinFitParticleType == d_DecayingParticle)
571  {
572  //enclosed decaying particle
573  if(dDebugLevel > 30)
574  cout << "DKinFitter: Calc_DecayingP4() Decaying Particle; PID = " << locKinFitParticle->Get_PID() << endl;
575 
576  //replace the decaying particle with the particles it's momentum is derived from
577  //initial state
578  auto locFromInitialState = locKinFitParticle->Get_FromInitialState();
579  for(auto& locParticle : locFromInitialState)
580  {
581  if(dDebugLevel > 30)
582  cout << "decaying, partially replace with init-state PID = " << locParticle->Get_PID() << endl;
583  auto locNextStateSignMultiplier = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle) ? -1.0*locStateSignMultiplier : locStateSignMultiplier;
584  locP4Sum += Calc_DecayingP4(locParticle.get(), false, locNextStateSignMultiplier, locDontPropagateAtAllFlag);
585  }
586 
587  //final state
588  auto locFromFinalState = locKinFitParticle->Get_FromFinalState();
589  for(auto& locParticle : locFromFinalState)
590  {
591  if(dDebugLevel > 30)
592  cout << "decaying, partially replace with final-state PID = " << locParticle->Get_PID() << endl;
593  //If defined by invariant mass: add p4s of final state particles
594  //If defined by missing mass: add p4s of init state, subtract final state
595  auto locNextStateSignMultiplier = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle) ? locStateSignMultiplier : -1.0*locStateSignMultiplier;
596  locP4Sum += Calc_DecayingP4(locParticle.get(), false, locNextStateSignMultiplier, locDontPropagateAtAllFlag);
597  }
598  }
599 
600  return locP4Sum;
601 }
602 
603 bool DKinFitUtils::Propagate_TrackInfoToCommonVertex(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, TVector3& locMomentum, TLorentzVector& locSpacetimeVertex, pair<double, double>& locPathLengthPair, pair<double, double>& locRestFrameLifetimePair, TMatrixFSym* locCovarianceMatrix) const
604 {
605  // propagates the track info to the fit common vertex
606  //returns false if nothing changed (info not propagated: e.g. missing particle), else returns true
607  //assumes: that between the two points on the track (input measured point & kinfit common point): the b-field is constant and there is no eloss or multiple scattering
608  // this function acts in the following way on each particle, IN THIS ORDER OF EXECUTION:
609  // if a common vertex was not fit, then the current results are returned
610  // for the remaining types (including decaying particles):
611  // the vertex is set to the common vertex
612  // if the time was fit, then the time is set to the common time, else it is propagated to the common vertex
613  // the path length is propagated
614  // momentum:
615  // if this is a neutral shower: momentum is redefined by the new vertex //already done by Update_ParticleParams()
616  // if this is a neutral particle (either detected, beam, or decaying) or a charged particle without a b-field: the momentum is unchanged
617  // if this is a charged particle in a b-field (either beam, detected, or decaying): the momentum is propagated to the common vertex
618  //propagating the covariance matrix:
619  //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
620  //add common time to matrix: 11x11 or 9x9 (neutral shower): if kinfit just add in (no correlations to meas, corr to common v3), else transform
621  //for non-decaying: transform to 7x7: common v3 & common t are just copied to the measured spots
622 
623  DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
624 
625  if(!locKinFitParticle->Get_FitCommonVertexFlag())
626  return false; // no distance over which to propagate
627 
628  if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
629  return false; // particle properties already defined at the fit vertex
630 
631  auto locFitCovMatrix = locKinFitParticle->Get_CovarianceMatrix();
633  {
634  if(locFitCovMatrix != NULL)
635  locCovarianceMatrix->SetSub(0, *locFitCovMatrix);
636  else
637  locCovarianceMatrix->Zero();
638  }
639 
640  bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
641  int locCharge = locKinFitParticle->Get_Charge();
642  TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
643 
644  TLorentzVector locP4 = locKinFitParticle->Get_P4();
645  TVector3 locPosition = locKinFitParticle->Get_Position();
646  TVector3 locDeltaX = locCommonVertex - locPosition;
647  TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
648  TVector3 locH = locBField.Unit();
649  double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
650 
651  // covariance matrix
652  int locCovMatrixEParamIndex = locKinFitParticle->Get_CovMatrixEParamIndex();
653  int locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
654  int locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
655  int locCovMatrixTParamIndex = locKinFitParticle->Get_CovMatrixTParamIndex();
656 
657  int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
658  int locCommonTParamIndex = locKinFitParticle->Get_CommonTParamIndex();
659 
660  //FIRST, DO EVERYTHING BUT THE COVARIANCE MATRIX
661 
662  //common v3
663  locSpacetimeVertex.SetVect(locCommonVertex);
664 
665  //common time
666  double locCommonTime = 0.0;
667  if(locKinFitParticle->Get_FitCommonTimeFlag()) //spacetime was fit
668  locCommonTime = locKinFitParticle->Get_CommonTime();
669  else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
670  {
671  double locDeltaXDotH = locDeltaX.Dot(locH);
672  double locPDotH = locP4.Vect().Dot(locH);
673  locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotH*locP4.E()/(29.9792458*locPDotH);
674  }
675  else if(!locNeutralShowerFlag) //non-accelerating, non-shower
676  {
677  double locDeltaXDotP = locDeltaX.Dot(locP4.Vect());
678  locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotP*locP4.E()/(29.9792458*locP4.Vect().Mag2());
679  }
680  else //neutral shower
681  locCommonTime = locKinFitParticle->Get_Time() - locDeltaX.Mag()*locP4.E()/(29.9792458*locP4.P());
682  locSpacetimeVertex.SetT(locCommonTime);
683 
684  //p3
685  if((locCharge != 0) && Get_IsBFieldNearBeamline()) //charged & in b-field
686  locMomentum = locP4.Vect() - locDeltaX.Cross(locA*locH);
687  else //constant: either neutral or no b-field
688  locMomentum = locP4.Vect();
689 
690  //if not updating the covariance matrix, skip to the path length and return
692  return Calc_PathLength(locKinFitParticle, locVXi, nullptr, locPathLengthPair, locRestFrameLifetimePair);
693 
694  //UPDATE THE COVARIANCE MATRIX
695  int locCommonVxParamIndex_TempMatrix = 7, locCommonTParamIndex_TempMatrix = 10; //changed if needed
696 
697  //add common spacetime to cov matrix, unless already included (is included for decaying
698  if(locKinFitParticleType != d_DecayingParticle)
699  {
700  //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
701  locCommonVxParamIndex_TempMatrix = locCovarianceMatrix->GetNcols();
702  locCovarianceMatrix->ResizeTo(locCommonVxParamIndex_TempMatrix + 3, locCommonVxParamIndex_TempMatrix + 3);
703  for(size_t loc_i = 0; loc_i < 3; ++loc_i)
704  {
705  for(size_t loc_j = 0; loc_j < 3; ++loc_j)
706  (*locCovarianceMatrix)(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
707  }
708  // done: no correlations between common vertex and measured params!!!
709 
710  //add common time to matrix: 11x11 or 9x9 (neutral shower): if kinfit just add in (no correlations to meas, corr to common v3), else transform
711  //note that if the common time is not kinfit, then the true uncertainty is overestimated:
712  //cannot be obtained without a kinematic fit (3 equations (xyz), one unknown (time))
713  locCommonTParamIndex_TempMatrix = locCovarianceMatrix->GetNcols();
714  if(locKinFitParticle->Get_FitCommonTimeFlag()) //spacetime was fit
715  {
716  locCovarianceMatrix->ResizeTo(locCovarianceMatrix->GetNcols() + 1, locCovarianceMatrix->GetNcols() + 1);
717  (*locCovarianceMatrix)(locCommonTParamIndex_TempMatrix, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonTParamIndex, locCommonTParamIndex);
718  for(size_t loc_i = 0; loc_i < 3; ++loc_i) //correlations to common v3
719  {
720  (*locCovarianceMatrix)(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + loc_i) = (*locVXi)(locCommonTParamIndex, locCommonVxParamIndex + loc_i);
721  (*locCovarianceMatrix)(locCommonVxParamIndex_TempMatrix + loc_i, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonTParamIndex);
722  }
723  }
724  else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
725  {
726  double locDeltaXDotH = locDeltaX.Dot(locH);
727  double locPDotH = locP4.Vect().Dot(locH);
728 
729  TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix->GetNcols() + 1, locCovarianceMatrix->GetNcols());
730  for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix->GetNcols(); ++loc_i)
731  locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
732 
733  TVector3 locDCommonTimeDP3 = (locDeltaXDotH/(29.9792458*locPDotH)) * ((1.0/locP4.E())*locP4.Vect() - (locP4.E()/locPDotH)*locH);
734  TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locPDotH))*locH;
735  TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
736 
737  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
738  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
739  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
740 
741  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
742  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
743  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
744 
745  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
746  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
747  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
748 
749  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
750 
751  locCovarianceMatrix->Similarity(locTransformationMatrix_CommonTime);
752  }
753  else if(!locNeutralShowerFlag) //non-accelerating, non-shower
754  {
755  double locDeltaXDotP = locDeltaX.Dot(locP4.Vect());
756 
757  TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix->GetNcols() + 1, locCovarianceMatrix->GetNcols());
758  for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix->GetNcols(); ++loc_i)
759  locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
760 
761  TVector3 locDCommonTimeDP3 = (1.0/(29.9792458*locP4.Vect().Mag2())) * (locP4.E()*locDeltaX + locDeltaXDotP*(1.0/locP4.E() - 2.0*locP4.E()/locP4.Vect().Mag2())*locP4.Vect());
762  TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locP4.Vect().Mag2()))*locP4.Vect();
763  TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
764 
765  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
766  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
767  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
768 
769  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
770  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
771  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
772 
773  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
774  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
775  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
776 
777  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
778 
779  locCovarianceMatrix->Similarity(locTransformationMatrix_CommonTime);
780  }
781  else //neutral shower
782  {
783  TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix->GetNcols() + 1, locCovarianceMatrix->GetNcols());
784  for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix->GetNcols(); ++loc_i)
785  locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
786 
787  double locDCommonTimeDEnergy = locDeltaX.Mag()*locP4.M2()/(29.9792458*locP4.P()*locP4.Vect().Mag2());
788  TVector3 locDCommonTimeDPosition = (locP4.E()/(29.9792458*locP4.P()*locDeltaX.Mag()))*locDeltaX;
789  TVector3 locDCommonTimeDCommonVertex = -1.0*locDCommonTimeDPosition;
790 
791  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixEParamIndex) = locDCommonTimeDEnergy;
792 
793  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
794  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
795  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
796 
797  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
798  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
799  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
800 
801  locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
802 
803  locCovarianceMatrix->Similarity(locTransformationMatrix_CommonTime);
804  }
805  }
806 
807  //transform to 7x7 (non-decaying) or switch common/position (decaying):
808  //common v3 & common t are just copied to the measured spots; p is propagated if in bfield, else is copied
809  auto locMatrixSize = (locKinFitParticleType == d_DecayingParticle) ? 11 : 7;
810  TMatrixD locTransformationMatrix_Propagation(locMatrixSize, locCovarianceMatrix->GetNcols());
811 
812  //p3
813  if((locCharge != 0) && Get_IsBFieldNearBeamline()) //charged & in b-field
814  {
815  locTransformationMatrix_Propagation(0, locCovMatrixPxParamIndex) = 1.0;
816  locTransformationMatrix_Propagation(1, locCovMatrixPxParamIndex + 1) = 1.0;
817  locTransformationMatrix_Propagation(2, locCovMatrixPxParamIndex + 2) = 1.0;
818 
819  locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 1) = -1.0*locA*locH.Z();
820  locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 2) = locA*locH.Y();
821 
822  locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex) = locA*locH.Z();
823  locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex + 2) = -1.0*locA*locH.X();
824 
825  locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex) = -1.0*locA*locH.Y();
826  locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex + 1) = locA*locH.X();
827 
828  locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 1) = locA*locH.Z();
829  locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 2) = -1.0*locA*locH.Y();
830 
831  locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix) = -1.0*locA*locH.Z();
832  locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix + 2) = locA*locH.X();
833 
834  locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix) = locA*locH.Y();
835  locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix + 1) = -1.0*locA*locH.X();
836  }
837  else //constant: either neutral or no b-field
838  {
839  for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
840  locTransformationMatrix_Propagation(loc_i, locCovMatrixPxParamIndex + loc_i) = 1.0;
841  }
842 
843  //v3
844  for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
845  locTransformationMatrix_Propagation(3 + loc_i, locCommonVxParamIndex_TempMatrix + loc_i) = 1.0;
846 
847  //t
848  locTransformationMatrix_Propagation(6, locCommonTParamIndex_TempMatrix) = 1.0;
849 
850  if(locKinFitParticleType == d_DecayingParticle)
851  {
852  //common v3
853  for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
854  locTransformationMatrix_Propagation(7 + loc_i, locCovMatrixVxParamIndex + loc_i) = 1.0;
855 
856  //common t
857  locTransformationMatrix_Propagation(10, locCovMatrixTParamIndex) = 1.0;
858  }
859 
860  //transform!!
861  locCovarianceMatrix->Similarity(locTransformationMatrix_Propagation); //FINALLY!!!
862 
863  //now calculate the path length
864  if(locKinFitParticleType == d_DecayingParticle)
865  return true; //don't recompute path length, because we've done it already
866  return Calc_PathLength(locKinFitParticle, locVXi, locCovarianceMatrix, locPathLengthPair, locRestFrameLifetimePair);
867 }
868 
869 bool DKinFitUtils::Calc_PathLength(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, const TMatrixFSym* locCovarianceMatrix, pair<double, double>& locPathLengthPair, pair<double, double>& locRestFrameLifetimePair) const
870 {
871  //locPathLengthPair: value, uncertainty
872  DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
873 
874  if(!locKinFitParticle->Get_FitCommonVertexFlag())
875  return false; // no distance over which to propagate
876 
877  if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
878  return false; // particle properties already defined at the fit vertex
879 
880  auto locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
881  auto locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
882  auto locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
883  auto locCommonTParamIndex = locKinFitParticle->Get_CommonTParamIndex();
884  auto locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
885 
886  int locCharge = locKinFitParticle->Get_Charge();
887  TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
888  TVector3 locMomentum = locKinFitParticle->Get_Momentum();
889  TVector3 locPosition = locKinFitParticle->Get_Position();
890  TVector3 locDeltaX = locCommonVertex - locPosition;
891  TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
892  TVector3 locH = locBField.Unit();
893 
894  //First, compute the path length
895  double locPMag = locMomentum.Mag();
896  if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
897  {
898  double locDeltaXDotH = locDeltaX.Dot(locH);
899  double locPDotH = locMomentum.Dot(locH);
900  locPathLengthPair.first = locDeltaXDotH*locPMag/locPDotH; //cos(theta_helix) = p.dot(h)/|p| = x.dot(h)/l (l = path length)
901  }
902  else // non-accelerating
903  locPathLengthPair.first = locDeltaX.Mag();
904 
905  //Then, compute the lifetime if decaying & in 2 vertex constraints
906  auto locMass = locKinFitParticle->Get_Mass();
907  if((locKinFitParticleType == d_DecayingParticle) && (locVxParamIndex >= 0) && (locCommonVxParamIndex >= 0))
908  {
909  //below, t, x, and tau are really delta-t, delta-x, and delta-tau
910  //tau = gamma*(t - beta*x/c) //plug in: t = x/(beta*c), gamma = 1/sqrt(1 - beta^2)
911  //tau = (x/(beta*c) - beta*x/c)/sqrt(1 - beta^2) //plug in beta = p*c/E
912  //tau = (x*E/(p*c^2) - p*x/E)/sqrt(1 - p^2*c^2/E^2) //multiply num & denom by E*P, factor x/c^2 out of num
913  //tau = (x/c^2)*(E^2 - p^2*c^2)/(p*sqrt(E^2 - p^2*c^2)) //plug in m^2*c^4 = E^2 - p^2*c^2
914  //tau = (x/c^2)*m^2*c^4/(p*m*c^2) //cancel c's & m's
915  //tau = x*m/p
916  //however, in data, p & m are in units with c = 1, so need an extra 1/c: tau = x*m/(c*p)
917  locRestFrameLifetimePair.first = locPathLengthPair.first*locMass/(29.9792458*locPMag); //tau
918  }
919  else
920  {
921  locRestFrameLifetimePair.first = 0.0;
922  locRestFrameLifetimePair.second = 0.0;
923  }
924 
925  //if not updating the errors, set the error to zero
926  if(locCovarianceMatrix == nullptr)
927  {
928  locPathLengthPair.second = 0.0;
929  locRestFrameLifetimePair.second = 0.0;
930  return true;
931  }
932 
933  //now compute the uncertainty
934  //if decaying just reuse matrix, else add common v3 to matrix: 11x11 or 9x9 (neutral shower)
935  TMatrixFSym locTempMatrix(locCovarianceMatrix->GetNcols());
936  locTempMatrix = *locCovarianceMatrix;
937  int locCommonVxParamIndex_TempMatrix = (locKinFitParticleType != d_DecayingParticle) ? locTempMatrix.GetNcols() : 7;
938  if(locKinFitParticleType != d_DecayingParticle)
939  {
940  locTempMatrix.ResizeTo(locCommonVxParamIndex_TempMatrix + 4, locCommonVxParamIndex_TempMatrix + 4);
941  size_t locSizeToCopy = (locCommonTParamIndex >= 0) ? 4 : 3;
942  for(size_t loc_i = 0; loc_i < locSizeToCopy; ++loc_i)
943  {
944  for(size_t loc_j = 0; loc_j < locSizeToCopy; ++loc_j)
945  locTempMatrix(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
946  }
947  }
948 
949  //find path length & flight time uncertainties
950  TMatrixD locTransformationMatrix(2, locTempMatrix.GetNcols());
951  if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
952  {
953  double locDeltaXDotH = locDeltaX.Dot(locH);
954  double locPDotH = locMomentum.Dot(locH);
955  double locPMag = locMomentum.Mag();
956 
957  TVector3 locDPathDP3 = (locDeltaXDotH/locPDotH)*((1.0/locPMag)*locMomentum - (locPMag/locPDotH)*locH);
958  TVector3 locDPathDCommon = (locPMag/locPDotH)*locH;
959  TVector3 locDPathDPosition = -1.0*locDPathDCommon;
960  double locMOverC = locMass/29.9792458;
961  TVector3 locDLifetimeDP3 = -1.0*locMOverC*(locDeltaXDotH/(locPDotH*locPDotH))*locH;
962  TVector3 locDLifetimeDCommon = (locMOverC/locPDotH)*locH;
963  TVector3 locDLifetimeDPosition = -1.0*locDLifetimeDCommon;
964 
965  //Path length
966  locTransformationMatrix(0, locCovMatrixPxParamIndex) = locDPathDP3.X();
967  locTransformationMatrix(0, locCovMatrixPxParamIndex + 1) = locDPathDP3.Y();
968  locTransformationMatrix(0, locCovMatrixPxParamIndex + 2) = locDPathDP3.Z();
969 
970  locTransformationMatrix(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
971  locTransformationMatrix(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
972  locTransformationMatrix(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
973 
974  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
975  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
976  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
977 
978  //Lifetime
979  locTransformationMatrix(1, locCovMatrixPxParamIndex) = locDLifetimeDP3.X();
980  locTransformationMatrix(1, locCovMatrixPxParamIndex + 1) = locDLifetimeDP3.Y();
981  locTransformationMatrix(1, locCovMatrixPxParamIndex + 2) = locDLifetimeDP3.Z();
982 
983  locTransformationMatrix(1, locCovMatrixVxParamIndex) = locDLifetimeDPosition.X();
984  locTransformationMatrix(1, locCovMatrixVxParamIndex + 1) = locDLifetimeDPosition.Y();
985  locTransformationMatrix(1, locCovMatrixVxParamIndex + 2) = locDLifetimeDPosition.Z();
986 
987  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix) = locDLifetimeDCommon.X();
988  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix + 1) = locDLifetimeDCommon.Y();
989  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix + 2) = locDLifetimeDCommon.Z();
990  }
991  else // non-accelerating
992  {
993  TVector3 locDPathDCommon = locDeltaX.Unit();
994  TVector3 locDPathDPosition = -1.0*locDPathDCommon;
995  double locMOverC = locMass/29.9792458;
996  TVector3 locDLifetimeDP3 = -1.0*locMOverC*(locPathLengthPair.first/(locPMag*locPMag*locPMag))*locMomentum;
997  TVector3 locDLifetimeDCommon = (locMOverC/(locPMag*locPathLengthPair.first))*locDeltaX;
998  TVector3 locDLifetimeDPosition = -1.0*locDLifetimeDCommon;
999 
1000  //Path length
1001  locTransformationMatrix(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
1002  locTransformationMatrix(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
1003  locTransformationMatrix(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
1004 
1005  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
1006  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
1007  locTransformationMatrix(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
1008 
1009  //Lifetime
1010  locTransformationMatrix(1, locCovMatrixPxParamIndex) = locDLifetimeDP3.X();
1011  locTransformationMatrix(1, locCovMatrixPxParamIndex + 1) = locDLifetimeDP3.Y();
1012  locTransformationMatrix(1, locCovMatrixPxParamIndex + 2) = locDLifetimeDP3.Z();
1013 
1014  locTransformationMatrix(1, locCovMatrixVxParamIndex) = locDLifetimeDPosition.X();
1015  locTransformationMatrix(1, locCovMatrixVxParamIndex + 1) = locDLifetimeDPosition.Y();
1016  locTransformationMatrix(1, locCovMatrixVxParamIndex + 2) = locDLifetimeDPosition.Z();
1017 
1018  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix) = locDLifetimeDCommon.X();
1019  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix + 1) = locDLifetimeDCommon.Y();
1020  locTransformationMatrix(1, locCommonVxParamIndex_TempMatrix + 2) = locDLifetimeDCommon.Z();
1021  }
1022 
1023  if(dDebugLevel >= 20)
1024  {
1025  cout << "Calc_PathLength: Combined matrix: " << endl;
1026  Print_Matrix(locTempMatrix);
1027  cout << "Calc_PathLength: Transform matrix: " << endl;
1028  Print_Matrix(locTransformationMatrix);
1029  }
1030 
1031  locTempMatrix.Similarity(locTransformationMatrix);
1032  if(dDebugLevel >= 20)
1033  {
1034  cout << "path/life matrix: " << endl;
1035  Print_Matrix(locTempMatrix);
1036  }
1037 
1038  locPathLengthPair.second = sqrt(locTempMatrix(0, 0));
1039  locRestFrameLifetimePair.second = sqrt(locTempMatrix(1, 1));
1040  if(dDebugLevel >= 20)
1041  {
1042  cout << "calced path, sigma = " << locPathLengthPair.first << ", " << locPathLengthPair.second << endl;
1043  cout << "calced lifetime, sigma = " << locRestFrameLifetimePair.first << ", " << locRestFrameLifetimePair.second << endl;
1044  }
1045 
1046  return true;
1047 }
1048 
1049 void DKinFitUtils::Calc_DecayingParticleJacobian(const DKinFitParticle* locKinFitParticle, bool locDontPropagateDecayingP3Flag, double locStateSignMultiplier, int locNumEta, const map<const DKinFitParticle*, int>& locAdditionalPxParamIndices, TMatrixD& locJacobian) const
1050 {
1051  //locJacobian: matrix used to convert dV to the decaying particle covariance matrix: indices are px, py, pz, x, y, z, t
1052  //dimensions are: 7/11, (dNumXi + locNumEta); (11 if common vertex is fit, 7 otherwise)
1053  //uses defining-particles to calculate decaying particle information
1054  //technically, this only calculates & sets the d_p3_Lambda/d_all terms. Setting 1's for the d_vertex/d_vertex's must be done outside of this function. Everything else is zero.
1055 
1056  DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1057 
1058  int locCharge = locKinFitParticle->Get_Charge();
1059  TLorentzVector locP4 = locKinFitParticle->Get_P4();
1060  TVector3 locPosition = locKinFitParticle->Get_Position();
1061  TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
1062  TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
1063  if(dDebugLevel > 50)
1064  cout << "jacobian: decay product: PID = " << locKinFitParticle->Get_PID() << endl;
1065 
1066  //This section is calculated assuming that the p4 is NEEDED at the COMMON vertex
1067  //if not, need a factor of -1 on delta-x, and on the derivatives wrst the vertices
1068  //e.g. for detected particles, needed p4 is at the common vertex, but it is defined at some other point on its trajectory
1069  //HOWEVER, for decaying particles, this MAY NOT be true: it MAY be defined at the position where it is needed
1070  //Decaying particles technically have two common vertices: where it is produced and where it decays
1071  //So here, the DEFINED vertex is where its position is defined by the other tracks,
1072  //and its COMMON vertex is the vertex where it is used to constrain another vertex
1073  //e.g. g, p -> K+, K+, Xi- Xi- -> pi-, Lambda Lambda -> p, pi-
1074  //Assuming standard constraint setup: p4 constraint is initial step, mass constraints by invariant mass, Xi- vertex defined by K's
1075  //For Xi-, the p3 is defined at its decay vertex (by decay products)
1076  //And the Xi- DEFINED vertex is at its production vertex (from kaons)
1077  //But the p3 is NEEDED at the production vertex, which is where it's DEFINED
1078  //Thus we need a factor of -1
1079  bool locNeedP4AtProductionVertex = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle); //true if defined by decay products; else by missing mass
1080  double locVertexSignMultiplier = (locNeedP4AtProductionVertex == locKinFitParticle->Get_VertexP4AtProductionVertex()) ? -1.0 : 1.0;
1081  TVector3 locDeltaX = locVertexSignMultiplier*(locCommonVertex - locPosition); //vector points in the OPPOSITE direction of the momentum
1082 
1083  TVector3 locH = locBField.Unit();
1084  double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
1085 
1086  bool locCommonVertexFitFlag = locKinFitParticle->Get_FitCommonVertexFlag();
1087  bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
1088  bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
1089 
1090  int locEParamIndex = locKinFitParticle->Get_EParamIndex();
1091  int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
1092  if(((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle)) && (locPxParamIndex >= 0))
1093  locPxParamIndex += locNumEta;
1094  int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
1095  if(((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle)) && (locVxParamIndex >= 0))
1096  locVxParamIndex += locNumEta;
1097  if(locPxParamIndex < 0)
1098  {
1099  //for particles not included in the fit matrices
1100  auto locPxParamIterator = locAdditionalPxParamIndices.find(locKinFitParticle);
1101  if(locPxParamIterator != locAdditionalPxParamIndices.end())
1102  locPxParamIndex = locPxParamIterator->second;
1103  }
1104  int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex() + locNumEta;
1105 
1106  if(locKinFitParticleType == d_TargetParticle)
1107  return;
1108  else if(locChargedBFieldFlag && locCommonVertexFitFlag && (locKinFitParticleType != d_DecayingParticle))
1109  {
1110  if(dDebugLevel > 50)
1111  cout << "jacobian: partials part 1" << endl;
1112 
1113  locJacobian(0, locPxParamIndex) = 1.0;
1114  locJacobian(1, locPxParamIndex + 1) = 1.0;
1115  locJacobian(2, locPxParamIndex + 2) = 1.0;
1116 
1117  locJacobian(0, locVxParamIndex + 1) = locA*locH.Z();
1118  locJacobian(0, locVxParamIndex + 2) = -1.0*locA*locH.Y();
1119 
1120  locJacobian(1, locVxParamIndex) = -1.0*locA*locH.Z();
1121  locJacobian(1, locVxParamIndex + 2) = locA*locH.X();
1122 
1123  locJacobian(2, locVxParamIndex) = locA*locH.Y();
1124  locJacobian(2, locVxParamIndex + 1) = -1.0*locA*locH.X();
1125 
1126  locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
1127  locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
1128 
1129  locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
1130  locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
1131 
1132  locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
1133  locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
1134  }
1135  else if(locNeutralShowerFlag)
1136  {
1137  if(dDebugLevel > 50)
1138  cout << "jacobian: partials part 2" << endl;
1139 
1140  double locEOverPSq = locP4.E()/locP4.Vect().Mag2();
1141  locJacobian(0, locEParamIndex) = locEOverPSq*locP4.Px();
1142  locJacobian(1, locEParamIndex) = locEOverPSq*locP4.Py();
1143  locJacobian(2, locEParamIndex) = locEOverPSq*locP4.Pz();
1144 
1145  TVector3 locDeltaXOverMagDeltaXSq = locDeltaX*(1.0/locDeltaX.Mag2());
1146 
1147  locJacobian(0, locVxParamIndex) = locP4.Px()*(locDeltaXOverMagDeltaXSq.X() - 1.0/locDeltaX.X());
1148  locJacobian(1, locVxParamIndex + 1) = locP4.Py()*(locDeltaXOverMagDeltaXSq.Y() - 1.0/locDeltaX.Y());
1149  locJacobian(2, locVxParamIndex + 2) = locP4.Pz()*(locDeltaXOverMagDeltaXSq.Z() - 1.0/locDeltaX.Z());
1150 
1151  locJacobian(0, locVxParamIndex + 1) = locP4.Px()*locDeltaXOverMagDeltaXSq.Y();
1152  locJacobian(0, locVxParamIndex + 2) = locP4.Px()*locDeltaXOverMagDeltaXSq.Z();
1153 
1154  locJacobian(1, locVxParamIndex) = locP4.Py()*locDeltaXOverMagDeltaXSq.X();
1155  locJacobian(1, locVxParamIndex + 2) = locP4.Py()*locDeltaXOverMagDeltaXSq.Z();
1156 
1157  locJacobian(2, locVxParamIndex) = locP4.Pz()*locDeltaXOverMagDeltaXSq.X();
1158  locJacobian(2, locVxParamIndex + 1) = locP4.Pz()*locDeltaXOverMagDeltaXSq.Y();
1159 
1160  locJacobian(0, locCommonVxParamIndex) -= locJacobian(0, locVxParamIndex);
1161  locJacobian(1, locCommonVxParamIndex + 1) -= locJacobian(1, locVxParamIndex + 1);
1162  locJacobian(2, locCommonVxParamIndex + 2) -= locJacobian(2, locVxParamIndex + 2);
1163 
1164  locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
1165  locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
1166 
1167  locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
1168  locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
1169 
1170  locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
1171  locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
1172  }
1173  else if((locKinFitParticleType == d_MissingParticle) || ((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex >= 0)))
1174  {
1175  if(dDebugLevel > 50)
1176  cout << "jacobian: partials part 3" << endl;
1177 
1178  //missing or open-ended-decaying particle: p3 is unknown (not derivable)
1179  locJacobian(0, locPxParamIndex) = 1.0;
1180  locJacobian(1, locPxParamIndex + 1) = 1.0;
1181  locJacobian(2, locPxParamIndex + 2) = 1.0;
1182  }
1183  else if(locKinFitParticleType == d_DecayingParticle)
1184  {
1185  if(dDebugLevel > 50)
1186  cout << "jacobian: partials part 4" << endl;
1187 
1188  //charged, enclosed decaying particle in a b-field
1189  if(locChargedBFieldFlag && locKinFitParticle->Get_FitCommonVertexFlag() && !locDontPropagateDecayingP3Flag)
1190  {
1191  if(dDebugLevel > 50)
1192  cout << "jacobian: partials part 4a" << endl;
1193 
1194  //vertex factors
1195  locJacobian(0, locVxParamIndex + 1) += locA*locH.Z();
1196  locJacobian(0, locVxParamIndex + 2) += -1.0*locA*locH.Y();
1197 
1198  locJacobian(1, locVxParamIndex) += -1.0*locA*locH.Z();
1199  locJacobian(1, locVxParamIndex + 2) += locA*locH.X();
1200 
1201  locJacobian(2, locVxParamIndex) += locA*locH.Y();
1202  locJacobian(2, locVxParamIndex + 1) += -1.0*locA*locH.X();
1203 
1204  locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
1205  locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
1206 
1207  locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
1208  locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
1209 
1210  locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
1211  locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
1212  }
1213 
1214  //replace the decaying particle with the particles it's momentum is derived from
1215  //initial state
1216  auto locFromInitialState = locKinFitParticle->Get_FromInitialState();
1217  for(auto& locParticle : locFromInitialState)
1218  {
1219  if(dDebugLevel > 30)
1220  cout << "decaying, partially replace with init-state PID = " << locParticle->Get_PID() << endl;
1221  auto locNextStateSignMultiplier = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle) ? -1.0*locStateSignMultiplier : locStateSignMultiplier;
1222  Calc_DecayingParticleJacobian(locParticle.get(), false, locNextStateSignMultiplier, locNumEta, locAdditionalPxParamIndices, locJacobian); //decaying particle multiplier * 1.0
1223  }
1224 
1225  //final state
1226  auto locFromFinalState = locKinFitParticle->Get_FromFinalState();
1227  for(auto& locParticle : locFromFinalState)
1228  {
1229  if(dDebugLevel > 30)
1230  cout << "decaying, partially replace with final-state PID = " << locParticle->Get_PID() << endl;
1231  //If defined by invariant mass: add p4s of final state particles
1232  //If defined by missing mass: add p4s of init state, subtract final state
1233  auto locNextStateSignMultiplier = Get_IsDecayingParticleDefinedByProducts(locKinFitParticle) ? locStateSignMultiplier : -1.0*locStateSignMultiplier;
1234  Calc_DecayingParticleJacobian(locParticle.get(), false, locNextStateSignMultiplier, locNumEta, locAdditionalPxParamIndices, locJacobian);
1235  }
1236  }
1237  else
1238  {
1239  if(dDebugLevel > 50)
1240  cout << "jacobian: partials part 5" << endl;
1241 
1242  // either no common vertex constraint, charged and detected but b-field = 0, or neutral particle with pre-ordained vertex (e.g. beam particle)
1243  locJacobian(0, locPxParamIndex) = 1.0;
1244  locJacobian(1, locPxParamIndex + 1) = 1.0;
1245  locJacobian(2, locPxParamIndex + 2) = 1.0;
1246  }
1247 }
1248 
1249 shared_ptr<const DKinFitChain> DKinFitUtils::Build_OutputKinFitChain(const shared_ptr<const DKinFitChain>& locInputKinFitChain, set<shared_ptr<DKinFitParticle>>& locKinFitOutputParticles)
1250 {
1251  if(dDebugLevel > 20)
1252  {
1253  cout << "DKinFitUtils::Build_OutputKinFitChain(): Printing input chain." << endl;
1254  locInputKinFitChain->Print_InfoToScreen();
1255  }
1256 
1257  //First, build map of input -> output
1258  map<shared_ptr<DKinFitParticle>, shared_ptr<DKinFitParticle>> locInputToOutputParticleMap;
1259  for(auto& locParticle : locKinFitOutputParticles)
1260  locInputToOutputParticleMap[dParticleMap_OutputToInput[locParticle]] = locParticle;
1261 
1262  auto locOutputKinFitChain = dResourcePool_KinFitChain->Get_SharedResource();
1263  locOutputKinFitChain->Set_DefinedParticleStepIndex(locInputKinFitChain->Get_DefinedParticleStepIndex());
1264  locOutputKinFitChain->Set_IsInclusiveChannelFlag(locInputKinFitChain->Get_IsInclusiveChannelFlag());
1265 
1266  //loop over steps
1267  for(size_t loc_i = 0; loc_i < locInputKinFitChain->Get_NumKinFitChainSteps(); ++loc_i)
1268  {
1269  auto locInputKinFitChainStep = locInputKinFitChain->Get_KinFitChainStep(loc_i);
1270  auto locOutputKinFitChainStep = dResourcePool_KinFitChainStep->Get_SharedResource();
1271 
1272  locOutputKinFitChainStep->Set_InitialParticleDecayFromStepIndex(locInputKinFitChainStep->Get_InitialParticleDecayFromStepIndex());
1273  locOutputKinFitChainStep->Set_ConstrainDecayingMassFlag(locInputKinFitChainStep->Get_ConstrainDecayingMassFlag());
1274 
1275  auto locInitialParticles = locInputKinFitChainStep->Get_InitialParticles();
1276  for(auto locKinFitParticle : locInitialParticles)
1277  {
1278  if(locKinFitParticle == nullptr)
1279  continue;
1280  auto locMapIterator = locInputToOutputParticleMap.find(locKinFitParticle);
1281  if(locMapIterator != locInputToOutputParticleMap.end())
1282  locKinFitParticle = locMapIterator->second;
1283  locOutputKinFitChainStep->Add_InitialParticle(locKinFitParticle);
1284  if(locKinFitParticle->Get_KinFitParticleType() == d_DecayingParticle)
1285  locOutputKinFitChain->Set_DecayStepIndex(locKinFitParticle, loc_i);
1286  }
1287 
1288  auto locFinalParticles = locInputKinFitChainStep->Get_FinalParticles();
1289  for(auto locKinFitParticle : locFinalParticles)
1290  {
1291  if(locKinFitParticle == nullptr)
1292  continue;
1293  auto locMapIterator = locInputToOutputParticleMap.find(locKinFitParticle);
1294  if(locMapIterator != locInputToOutputParticleMap.end())
1295  locKinFitParticle = locMapIterator->second;
1296  locOutputKinFitChainStep->Add_FinalParticle(locKinFitParticle);
1297  }
1298 
1299  locOutputKinFitChain->Add_KinFitChainStep(locOutputKinFitChainStep);
1300  }
1301 
1302  if(dDebugLevel > 20)
1303  {
1304  cout << "DKinFitUtils::Build_OutputKinFitChain(): Printing output chain." << endl;
1305  locOutputKinFitChain->Print_InfoToScreen();
1306  }
1307 
1308  return locOutputKinFitChain;
1309 }
1310 
1311 void DKinFitUtils::Print_Matrix(const TMatrixD& locMatrix) const
1312 {
1313  for(int loc_i = 0; loc_i < locMatrix.GetNrows(); ++loc_i)
1314  {
1315  for(int loc_j = 0; loc_j < locMatrix.GetNcols(); ++loc_j)
1316  cout << locMatrix(loc_i, loc_j) << ", ";
1317  cout << endl;
1318  }
1319 }
1320 
1321 void DKinFitUtils::Print_Matrix(const TMatrixF& locMatrix) const
1322 {
1323  for(int loc_i = 0; loc_i < locMatrix.GetNrows(); ++loc_i)
1324  {
1325  for(int loc_j = 0; loc_j < locMatrix.GetNcols(); ++loc_j)
1326  cout << locMatrix(loc_i, loc_j) << ", ";
1327  cout << endl;
1328  }
1329 }
1330 
shared_ptr< DKinFitConstraint_Vertex > Clone_KinFitConstraint_Vertex(const DKinFitConstraint_Vertex *locConstraint)
int Get_PID(void) const
bool Get_FitCommonVertexFlag(void) const
char Get_Charge(void) const
shared_ptr< DKinFitConstraint_Vertex > Make_VertexConstraint(const set< shared_ptr< DKinFitParticle >> &locFullConstrainParticles, const set< shared_ptr< DKinFitParticle >> &locNoConstrainParticles, TVector3 locVertexGuess=TVector3())
int Get_CovMatrixVxParamIndex(void) const
char Get_CommonVxParamIndex(void) const
shared_ptr< DKinFitConstraint_Mass > Clone_KinFitConstraint_Mass(const DKinFitConstraint_Mass *locConstraint)
set< shared_ptr< DKinFitParticle > > Get_FromInitialState(void) const
shared_ptr< DKinFitParticle > Make_BeamParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
Definition: DKinFitUtils.cc:56
map< DSpacetimeParticles, shared_ptr< DKinFitConstraint_Spacetime > > dSpacetimeConstraintMap
Definition: DKinFitUtils.h:190
int Get_CovMatrixEParamIndex(void) const
shared_ptr< DKinFitParticle > Make_DetectedParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, double locPathLength, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
DKinFitParticleType
double Get_Mass(void) const
shared_ptr< DResourcePool< DKinFitConstraint_Spacetime > > dResourcePool_SpacetimeConstraint
Definition: DKinFitUtils.h:197
int Get_CovMatrixTParamIndex(void) const
TLorentzVector Calc_DecayingP4_ByP3Derived(const DKinFitParticle *locKinFitParticle, bool locAtP3DerivedFlag, bool locDontPropagateAtAllFlag=false) const
shared_ptr< DKinFitParticle > Make_DetectedShower(int locPID, double locMass, TLorentzVector locSpacetimeVertex, double locShowerEnergy, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
virtual bool Get_IsBFieldNearBeamline(void) const =0
bool dUpdateCovarianceMatricesFlag
Definition: DKinFitUtils.h:142
shared_ptr< DKinFitConstraint_Spacetime > Clone_KinFitConstraint_Spacetime(const DKinFitConstraint_Spacetime *locConstraint)
shared_ptr< DKinFitConstraint_P4 > Clone_KinFitConstraint_P4(const DKinFitConstraint_P4 *locConstraint)
map< pair< set< shared_ptr< DKinFitParticle > >, set< shared_ptr< DKinFitParticle > > >, shared_ptr< DKinFitConstraint_P4 > > dP4ConstraintMap
Definition: DKinFitUtils.h:188
shared_ptr< DKinFitParticle > Make_MissingParticle(int locPID, int locCharge, double locMass)
shared_ptr< DResourcePool< DKinFitConstraint_P4 > > dResourcePool_P4Constraint
Definition: DKinFitUtils.h:195
virtual TVector3 Get_BField(const TVector3 &locPosition) const =0
set< shared_ptr< DKinFitParticle > > Get_FromFinalState(void) const
virtual void Reset_NewEvent(void)
Definition: DKinFitUtils.cc:37
shared_ptr< DResourcePool< DKinFitChain > > dResourcePool_KinFitChain
Definition: DKinFitUtils.h:145
char Get_PxParamIndex(void) const
map< shared_ptr< DKinFitParticle >, shared_ptr< DKinFitConstraint_Mass > > dMassConstraintMap
Definition: DKinFitUtils.h:187
shared_ptr< DKinFitParticle > Make_TargetParticle(int locPID, int locCharge, double locMass)
Definition: DKinFitUtils.cc:82
void Calc_DecayingParticleJacobian(const DKinFitParticle *locKinFitParticle, bool locDontPropagateDecayingP3Flag, double locStateSignMultiplier, int locNumEta, const map< const DKinFitParticle *, int > &locAdditionalPxParamIndices, TMatrixD &locJacobian) const
shared_ptr< DKinFitConstraint_Mass > Make_MassConstraint(const shared_ptr< DKinFitParticle > &locDecayingParticle)
shared_ptr< TMatrixFSym > Get_SymMatrixResource(unsigned int locNumMatrixRows)
Definition: DKinFitUtils.cc:47
set< shared_ptr< DKinFitParticle > > Build_CloneParticleSet(const set< shared_ptr< DKinFitParticle >> &locInputParticles, const map< shared_ptr< DKinFitParticle >, shared_ptr< DKinFitParticle >> &locCloneIOMap) const
shared_ptr< const DKinFitChain > Build_OutputKinFitChain(const shared_ptr< const DKinFitChain > &locInputKinFitChain, set< shared_ptr< DKinFitParticle >> &locKinFitOutputParticles)
void Recycle_LastFitMemory(set< shared_ptr< DKinFitConstraint >> &locKinFitConstraints)
DKinFitUtils(void)
Definition: DKinFitUtils.cc:5
bool Get_IsNeutralShowerFlag(void) const
virtual bool Validate_Constraints(const set< shared_ptr< DKinFitConstraint >> &locKinFitConstraints) const
bool Propagate_TrackInfoToCommonVertex(const DKinFitParticle *locKinFitParticle, const TMatrixDSym *locVXi, TVector3 &locMomentum, TLorentzVector &locSpacetimeVertex, pair< double, double > &locPathLengthPair, pair< double, double > &locRestFrameLifetimePair, TMatrixFSym *locCovarianceMatrix) const
set< shared_ptr< DKinFitConstraint > > Clone_ParticlesAndConstraints(const set< shared_ptr< DKinFitConstraint >> &locInputConstraints)
virtual void Reset_NewFit(void)
Definition: DKinFitUtils.h:40
DKinFitter * dKinFitter
Definition: DKinFitUtils.h:139
shared_ptr< DKinFitConstraint_Spacetime > Make_SpacetimeConstraint(const set< shared_ptr< DKinFitParticle >> &locFullConstrainParticles, const set< shared_ptr< DKinFitParticle >> &locOnlyConstrainTimeParticles, const set< shared_ptr< DKinFitParticle >> &locNoConstrainParticles, TLorentzVector locSpacetimeGuess=TLorentzVector())
bool dLinkVerticesFlag
Definition: DKinFitUtils.h:140
shared_ptr< DKinFitConstraint_P4 > Make_P4Constraint(const set< shared_ptr< DKinFitParticle >> &locInitialParticles, const set< shared_ptr< DKinFitParticle >> &locFinalParticles)
shared_ptr< DResourcePool< DKinFitParticle > > dResourcePool_KinFitParticle
Definition: DKinFitUtils.h:200
bool Get_FitCommonTimeFlag(void) const
map< shared_ptr< DKinFitParticle >, shared_ptr< DKinFitParticle > > dParticleMap_OutputToInput
Definition: DKinFitUtils.h:166
double sqrt(double)
char Get_EParamIndex(void) const
char Get_VxParamIndex(void) const
shared_ptr< const TMatrixFSym > Get_CovarianceMatrix(void) const
bool Calc_PathLength(const DKinFitParticle *locKinFitParticle, const TMatrixDSym *locVXi, const TMatrixFSym *locCovarianceMatrix, pair< double, double > &locPathLengthPair, pair< double, double > &locRestFrameLifetimePair) const
TLorentzVector Calc_DecayingP4(const DKinFitParticle *locKinFitParticle, bool locIsConstrainedParticle, double locStateSignMultiplier, bool locDontPropagateAtAllFlag=false) const
double Get_CommonTime(void) const
char Get_CommonTParamIndex(void) const
bool Get_IsDecayingParticleDefinedByProducts(const DKinFitParticle *locKinFitParticle) const
DKinFitParticleType Get_KinFitParticleType(void) const
map< pair< set< shared_ptr< DKinFitParticle > >, set< shared_ptr< DKinFitParticle > > >, shared_ptr< DKinFitConstraint_Vertex > > dVertexConstraintMap
Definition: DKinFitUtils.h:189
TLorentzVector Calc_DecayingP4_ByVertex(const DKinFitParticle *locKinFitParticle, bool locAtProductionVertexFlag, bool locDontPropagateAtAllFlag=false) const
TVector3 Get_Position(void) const
shared_ptr< DResourcePool< TMatrixFSym > > dResourcePool_TMatrixFSym
Definition: DKinFitUtils.h:199
TLorentzVector Calc_DecayingP4_ByPosition(const DKinFitParticle *locKinFitParticle, bool locAtPositionFlag, bool locDontPropagateAtAllFlag=false) const
shared_ptr< DKinFitParticle > Clone_KinFitParticle(const shared_ptr< DKinFitParticle > &locKinFitParticle)
shared_ptr< DResourcePool< DKinFitConstraint_Mass > > dResourcePool_MassConstraint
Definition: DKinFitUtils.h:194
void Print_Matrix(const TMatrixD &locMatrix) const
double Get_Time(void) const
shared_ptr< DKinFitParticle > Make_DecayingParticle(int locPID, int locCharge, double locMass, const set< shared_ptr< DKinFitParticle >> &locFromInitialState, const set< shared_ptr< DKinFitParticle >> &locFromFinalState)
TVector3 Get_CommonVertex(void) const
shared_ptr< DResourcePool< DKinFitConstraint_Vertex > > dResourcePool_VertexConstraint
Definition: DKinFitUtils.h:196
int Get_CovMatrixPxParamIndex(void) const
TLorentzVector Get_P4(void) const
shared_ptr< DResourcePool< DKinFitChainStep > > dResourcePool_KinFitChainStep
Definition: DKinFitUtils.h:144
shared_ptr< TMatrixFSym > Clone_SymMatrix(const TMatrixFSym *locMatrix)
TVector3 Get_Momentum(void) const
bool Get_VertexP4AtProductionVertex(void) const