Bug Summary

File:libraries/ANALYSIS/DKinFitter.cc
Location:line 2870, column 18
Description:Called C++ object pointer is null

Annotated Source Code

1#ifdef VTRACE
2#include "vt_user.h"
3#endif
4
5#include "DKinFitter.h"
6
7//CONSTRAINTS:
8 //Constraint types: p4 conservation, common vertex, common spacetime
9 //P4 Conservation Notes:
10 //P4 is required to be conserved between the particles at the common vertex (if it is simultaneously kinematically fit)
11 //For input neutral showers, the momentum is defined-by and updated-with the common vertex (see "Common Vertex Notes")
12 //if a common vertex is not simultaneously kinematically fit for a neutral shower, the fit will return false
13 //To include a neutral shower in a p4 fit without a vertex fit, create a particle from it with a full 7x7 covaraince matrix and input it instead of the neutral shower
14 //If the particle is charged, the magnetic field is taken into account if a common vertex is simultaneously kinematically fit (magnetic field assumed to be constant over the propagation range)
15 //If a common vertex is not defined, the momentum is assumed to be constant with position
16 //Energy loss between the common vertex and the particle position is ignored
17 //Common Vertex Notes:
18 //See "P4 Conservation Notes" section about vertices being used in those constraints.
19 //If the particle is charged, the magnetic field is taken into account (magnetic field assumed to be constant over the propagation range)
20 //You can include the beam particle in the common vertex fit. However, it is ignored if it's xy uncertainties and/or(?) xy parameters are zero (matrix won't invert).
21 //Neutral and missing particles included in the constraint will not be used to constrain the vertex, but will be set with the fit common vertex
22 //This is necessary if you want the neutral particle momentum (from an input shower) to change with the reconstructed vertex
23 //If a decaying particle is set in two vertex constraints (even if one is a spacetime constraint):
24 //It's position will be defined by the point at which it's p4 is constrained, and it will be constrained to have a common vertex at the other vertex
25 //Common Spacetime Notes:
26 //THIS IS CURRENTLY DISABLED
27 //It is not possible to fit a common time without simultaneously fitting a common vertex.
28 //Requiring a common time at a non-common vertex has no meaning, and the fitter is not setup to input a pre-fit common vertex with uncertainties.
29 //If the particle is charged, the magnetic field is taken into account (magnetic field assumed to be constant over the propagation range)
30 //You can include both the beam particle AND the RF time in the common time fit
31 //the RF parameters are defined to be the same as those of the beam particle, except the time and it's uncertainty
32 //Missing particles included in the constraint will not be used to constrain the spacetime, but will be set with the fit common spacetime
33 //If a decaying particle is set in two spacetime constraints:
34 //It's spacetime will be defined by the point at which it's p4 is constrained, and it will be constrained to have a common spacetime at the other vertex
35
36//SETUP:
37 //If setup of a particle or constraint fails, it will return NULL instead of the created object
38 //only input a neutral shower if its vertex will be defined by a simultaneous vertex fit!
39 //else import it as a full detected particle with a 7x7 covariance matrix
40
41DKinFitConstraint::~DKinFitConstraint(void){}
42
43DKinFitter::DKinFitter(void)
44{
45 dLinkVerticesFlag = true;
46 dDebugLevel = 0;
47 dKinFitStatus = d_KinFitSuccessful;
48 dConvergenceChiSqDiff = 0.001;
49 dConvergenceChiSqDiff_LastResort = 0.005;
50
51 dMaxKinFitParticlePoolSize = 100;
52 dMaxKinFitConstraintVertexPoolSize = 25;
53 dMaxKinFitConstraintSpacetimePoolSize = 25;
54 dMaxKinFitConstraintP4PoolSize = 25;
55 dMaxMatrixDSymPoolSize = 100;
56 dMaxLargeMatrixDSymPoolSize = 100;
57
58 dMaxNumIterations = 20;
59
60 Reset_NewEvent();
61}
62
63DKinFitter::~DKinFitter(void)
64{
65 for(size_t loc_i = 0; loc_i < dKinFitParticlePool_All.size(); ++loc_i)
66 delete dKinFitParticlePool_All[loc_i];
67
68 for(size_t loc_i = 0; loc_i < dKinFitConstraintVertexPool_All.size(); ++loc_i)
69 delete dKinFitConstraintVertexPool_All[loc_i];
70
71 for(size_t loc_i = 0; loc_i < dKinFitConstraintSpacetimePool_All.size(); ++loc_i)
72 delete dKinFitConstraintSpacetimePool_All[loc_i];
73
74 for(size_t loc_i = 0; loc_i < dKinFitConstraintP4Pool_All.size(); ++loc_i)
75 delete dKinFitConstraintP4Pool_All[loc_i];
76
77 for(size_t loc_i = 0; loc_i < dMatrixDSymPool_All.size(); ++loc_i)
78 delete dMatrixDSymPool_All[loc_i];
79
80 for(size_t loc_i = 0; loc_i < dLargeMatrixDSymPool_All.size(); ++loc_i)
81 delete dLargeMatrixDSymPool_All[loc_i];
82}
83
84void DKinFitter::Preallocate_MatrixMemory(void)
85{
86 //pre-allocate matrix memory
87 for(size_t loc_i = 0; loc_i < dMaxMatrixDSymPoolSize; ++loc_i)
88 {
89 TMatrixDSym* locMatrix = Get_MatrixDSymResource();
90 locMatrix->ResizeTo(7, 7);
91 }
92
93 //pre-allocate large matrix memory
94 for(size_t loc_i = 0; loc_i < dMaxLargeMatrixDSymPoolSize; ++loc_i)
95 {
96 TMatrixDSym* locMatrix = Get_LargeMatrixDSymResource();
97 locMatrix->ResizeTo(100, 100);
98 }
99
100 Reset_NewEvent();
101}
102
103void DKinFitter::Reset_NewEvent(void)
104{
105 dKinFitParticleCloningOIMap.clear();
106 dKinFitConstraintCloningOIMap.clear();
107
108 // delete pool sizes if too large, preventing memory-leakage-like behavor.
109 if(dKinFitParticlePool_All.size() > dMaxKinFitParticlePoolSize)
110 {
111 for(size_t loc_i = dMaxKinFitParticlePoolSize; loc_i < dKinFitParticlePool_All.size(); ++loc_i)
112 delete dKinFitParticlePool_All[loc_i];
113 dKinFitParticlePool_All.resize(dMaxKinFitParticlePoolSize);
114 }
115 dKinFitParticlePool_Available = dKinFitParticlePool_All;
116
117 if(dKinFitConstraintVertexPool_All.size() > dMaxKinFitConstraintVertexPoolSize)
118 {
119 for(size_t loc_i = dMaxKinFitConstraintVertexPoolSize; loc_i < dKinFitConstraintVertexPool_All.size(); ++loc_i)
120 delete dKinFitConstraintVertexPool_All[loc_i];
121 dKinFitConstraintVertexPool_All.resize(dMaxKinFitConstraintVertexPoolSize);
122 }
123 dKinFitConstraintVertexPool_Available = dKinFitConstraintVertexPool_All;
124
125 if(dKinFitConstraintSpacetimePool_All.size() > dMaxKinFitConstraintSpacetimePoolSize)
126 {
127 for(size_t loc_i = dMaxKinFitConstraintSpacetimePoolSize; loc_i < dKinFitConstraintSpacetimePool_All.size(); ++loc_i)
128 delete dKinFitConstraintSpacetimePool_All[loc_i];
129 dKinFitConstraintSpacetimePool_All.resize(dMaxKinFitConstraintSpacetimePoolSize);
130 }
131 dKinFitConstraintSpacetimePool_Available = dKinFitConstraintSpacetimePool_All;
132
133 if(dKinFitConstraintP4Pool_All.size() > dMaxKinFitConstraintP4PoolSize)
134 {
135 for(size_t loc_i = dMaxKinFitConstraintP4PoolSize; loc_i < dKinFitConstraintP4Pool_All.size(); ++loc_i)
136 delete dKinFitConstraintP4Pool_All[loc_i];
137 dKinFitConstraintP4Pool_All.resize(dMaxKinFitConstraintP4PoolSize);
138 }
139 dKinFitConstraintP4Pool_Available = dKinFitConstraintP4Pool_All;
140
141 if(dMatrixDSymPool_All.size() > dMaxMatrixDSymPoolSize)
142 {
143 for(size_t loc_i = dMaxMatrixDSymPoolSize; loc_i < dMatrixDSymPool_All.size(); ++loc_i)
144 delete dMatrixDSymPool_All[loc_i];
145 dMatrixDSymPool_All.resize(dMaxMatrixDSymPoolSize);
146 }
147 dMatrixDSymPool_Available = dMatrixDSymPool_All;
148
149 if(dLargeMatrixDSymPool_All.size() > dMaxLargeMatrixDSymPoolSize)
150 {
151 for(size_t loc_i = dMaxLargeMatrixDSymPoolSize; loc_i < dLargeMatrixDSymPool_All.size(); ++loc_i)
152 delete dLargeMatrixDSymPool_All[loc_i];
153 dLargeMatrixDSymPool_All.resize(dMaxLargeMatrixDSymPoolSize);
154 }
155 dLargeMatrixDSymPool_Available = dLargeMatrixDSymPool_All;
156
157 Reset_NewFit();
158}
159
160void DKinFitter::Reset_NewFit(void)
161{
162 dKinFitStatus = d_KinFitSuccessful;
163
164 dKinFitConstraints.clear();
165 dKinFitParticles.clear();
166
167 dRFMatchedBeamParticle = NULL__null;
168 dRFTimeParamIndex = -1;
169 dRFTime = 0.0;
170 dRFUncertainty = 0.0;
171
172 dNumXi = 0;
173 dNumEta = 0;
174 dNumF = 0;
175
176 dChiSq = 0.0;
177 dNDF = 0;
178 dConfidenceLevel = 0.0;
179 dPulls.clear();
180
181 dV = Get_LargeMatrixDSymResource();
182 dVXi = Get_LargeMatrixDSymResource();
183 dVEta = Get_LargeMatrixDSymResource();
184}
185
186DKinFitParticle* DKinFitter::Get_KinFitParticleResource(void)
187{
188 DKinFitParticle* locKinFitParticle;
189 if(dKinFitParticlePool_Available.empty())
190 {
191 locKinFitParticle = new DKinFitParticle;
192 dKinFitParticlePool_All.push_back(locKinFitParticle);
193 }
194 else
195 {
196 locKinFitParticle = dKinFitParticlePool_Available.back();
197 locKinFitParticle->Reset();
198 dKinFitParticlePool_Available.pop_back();
199 }
200 return locKinFitParticle;
201}
202
203DKinFitConstraint_Vertex* DKinFitter::Get_KinFitConstraintVertexResource(void)
204{
205 DKinFitConstraint_Vertex* locKinFitConstraint;
206 if(dKinFitConstraintVertexPool_Available.empty())
207 {
208 locKinFitConstraint = new DKinFitConstraint_Vertex;
209 dKinFitConstraintVertexPool_All.push_back(locKinFitConstraint);
210 }
211 else
212 {
213 locKinFitConstraint = dKinFitConstraintVertexPool_Available.back();
214 locKinFitConstraint->Reset();
215 dKinFitConstraintVertexPool_Available.pop_back();
216 }
217 return locKinFitConstraint;
218}
219
220DKinFitConstraint_Spacetime* DKinFitter::Get_KinFitConstraintSpacetimeResource(void)
221{
222 DKinFitConstraint_Spacetime* locKinFitConstraint;
223 if(dKinFitConstraintSpacetimePool_Available.empty())
224 {
225 locKinFitConstraint = new DKinFitConstraint_Spacetime;
226 dKinFitConstraintSpacetimePool_All.push_back(locKinFitConstraint);
227 }
228 else
229 {
230 locKinFitConstraint = dKinFitConstraintSpacetimePool_Available.back();
231 locKinFitConstraint->Reset();
232 dKinFitConstraintSpacetimePool_Available.pop_back();
233 }
234 return locKinFitConstraint;
235}
236
237DKinFitConstraint_P4* DKinFitter::Get_KinFitConstraintP4Resource(void)
238{
239 DKinFitConstraint_P4* locKinFitConstraint;
240 if(dKinFitConstraintP4Pool_Available.empty())
241 {
242 locKinFitConstraint = new DKinFitConstraint_P4;
243 dKinFitConstraintP4Pool_All.push_back(locKinFitConstraint);
244 }
245 else
246 {
247 locKinFitConstraint = dKinFitConstraintP4Pool_Available.back();
248 locKinFitConstraint->Reset();
249 dKinFitConstraintP4Pool_Available.pop_back();
250 }
251 return locKinFitConstraint;
252}
253
254TMatrixDSym* DKinFitter::Get_MatrixDSymResource(void)
255{
256 TMatrixDSym* locMatrixDSym;
257 if(dMatrixDSymPool_Available.empty())
258 {
259 locMatrixDSym = new TMatrixDSym();
260 dMatrixDSymPool_All.push_back(locMatrixDSym);
261 }
262 else
263 {
264 locMatrixDSym = dMatrixDSymPool_Available.back();
265 dMatrixDSymPool_Available.pop_back();
266 }
267 return locMatrixDSym;
268}
269
270TMatrixDSym* DKinFitter::Get_LargeMatrixDSymResource(void)
271{
272 TMatrixDSym* locMatrixDSym;
273 if(dLargeMatrixDSymPool_Available.empty())
274 {
275 locMatrixDSym = new TMatrixDSym();
276 dLargeMatrixDSymPool_All.push_back(locMatrixDSym);
277 }
278 else
279 {
280 locMatrixDSym = dLargeMatrixDSymPool_Available.back();
281 dLargeMatrixDSymPool_Available.pop_back();
282 }
283 return locMatrixDSym;
284}
285
286TMatrixDSym* DKinFitter::Clone_MatrixDSym(const TMatrixDSym* locMatrix)
287{
288 if(locMatrix == NULL__null)
289 return NULL__null;
290 TMatrixDSym* locNewMatrix = Get_MatrixDSymResource();
291 int locMatrixSize = locMatrix->GetNcols();
292 locNewMatrix->ResizeTo(locMatrixSize, locMatrixSize);
293 *locNewMatrix = *locMatrix;
294 return locNewMatrix;
295}
296
297DKinFitParticle* DKinFitter::Clone_KinFitParticle(const DKinFitParticle* locKinFitParticle)
298{
299 DKinFitParticle* locClonedKinFitParticle = Get_KinFitParticleResource();
300 *locClonedKinFitParticle = *locKinFitParticle;
301 dKinFitParticleCloningOIMap[locClonedKinFitParticle] = locKinFitParticle;
302 return locClonedKinFitParticle;
303}
304
305DKinFitConstraint_P4* DKinFitter::Clone_KinFitConstraint_P4(const DKinFitConstraint_P4* locConstraint)
306{
307 //to be called PRIOR to a fit
308 DKinFitConstraint_P4* locClonedConstraint = Get_KinFitConstraintP4Resource();
309 *locClonedConstraint = *locConstraint;
310 dKinFitConstraintCloningOIMap[locClonedConstraint] = locConstraint;
311 return locClonedConstraint;
312}
313
314DKinFitConstraint_Vertex* DKinFitter::Clone_KinFitConstraint_Vertex(const DKinFitConstraint_Vertex* locConstraint)
315{
316 //to be called PRIOR to a fit
317 DKinFitConstraint_Vertex* locClonedConstraint = Get_KinFitConstraintVertexResource();
318 *locClonedConstraint = *locConstraint;
319 dKinFitConstraintCloningOIMap[locClonedConstraint] = locConstraint;
320 return locClonedConstraint;
321}
322
323DKinFitConstraint_Spacetime* DKinFitter::Clone_KinFitConstraint_Spacetime(const DKinFitConstraint_Spacetime* locConstraint)
324{
325 //to be called PRIOR to a fit
326 DKinFitConstraint_Spacetime* locClonedConstraint = Get_KinFitConstraintSpacetimeResource();
327 *locClonedConstraint = *locConstraint;
328 dKinFitConstraintCloningOIMap[locClonedConstraint] = locConstraint;
329 return locClonedConstraint;
330}
331
332const DKinFitParticle* DKinFitter::Make_DecayingParticle(int locPID, int locCharge, double locMass)
333{
334 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
335 locKinFitParticle->Set_PID(locPID);
336 locKinFitParticle->Set_Charge(locCharge);
337 locKinFitParticle->Set_Mass(locMass);
338 locKinFitParticle->Set_KinFitParticleType(d_DecayingParticle);
339
340 if(dDebugLevel > 5)
341 cout << "DKinFitter: Decaying particle set. Pointer, ID, Q, Mass, Pointer = " << locKinFitParticle << ", " << locPID << ", " << locCharge << ", " << locMass << endl;
342
343 return locKinFitParticle;
344}
345
346const DKinFitParticle* DKinFitter::Make_MissingParticle(int locPID, int locCharge, double locMass)
347{
348 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
349 locKinFitParticle->Set_PID(locPID);
350 locKinFitParticle->Set_Charge(locCharge);
351 locKinFitParticle->Set_Mass(locMass);
352 locKinFitParticle->Set_KinFitParticleType(d_MissingParticle);
353
354 if(dDebugLevel > 5)
355 cout << "DKinFitter: Missing particle set. Pointer, ID, Q, Mass = " << locKinFitParticle << ", " << locPID << ", " << locCharge << ", " << locMass << endl;
356
357 return locKinFitParticle;
358}
359
360const DKinFitParticle* DKinFitter::Make_BeamParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, const TMatrixDSym* locCovarianceMatrix)
361{
362 if((locCovarianceMatrix->GetNrows() != 7) || (locCovarianceMatrix->GetNcols() != 7))
363 return NULL__null; //is not 7x7
364
365 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
366 locKinFitParticle->Set_PID(locPID);
367 locKinFitParticle->Set_Charge(locCharge);
368 locKinFitParticle->Set_Mass(locMass);
369 locKinFitParticle->Set_Position(locSpacetimeVertex.Vect());
370 locKinFitParticle->Set_Time(locSpacetimeVertex.T());
371 locKinFitParticle->Set_Momentum(locMomentum);
372 locKinFitParticle->Set_CovarianceMatrix(Clone_MatrixDSym(locCovarianceMatrix));
373
374 locKinFitParticle->Set_KinFitParticleType(d_BeamParticle);
375
376 if(dDebugLevel > 5)
377 cout << "DKinFitter: Beam particle set. Pointer, ID, Q, Mass, P3, V3, T = " << locKinFitParticle << ", " << locPID << ", " << locCharge << ", " << locMass << ", " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
378
379 return locKinFitParticle;
380}
381
382const DKinFitParticle* DKinFitter::Make_TargetParticle(int locPID, int locCharge, double locMass)
383{
384 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
385 locKinFitParticle->Set_PID(locPID);
386 locKinFitParticle->Set_Charge(locCharge);
387 locKinFitParticle->Set_Mass(locMass);
388 locKinFitParticle->Set_KinFitParticleType(d_TargetParticle);
389
390 if(dDebugLevel > 5)
391 cout << "DKinFitter: Target particle set. Pointer, ID, Q, Mass = " << locKinFitParticle << ", " << locPID << ", " << locCharge << ", " << locMass << endl;
392
393 return locKinFitParticle;
394}
395
396const DKinFitParticle* DKinFitter::Make_DetectedParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, const TMatrixDSym* locCovarianceMatrix)
397{
398 if((locCovarianceMatrix->GetNrows() != 7) || (locCovarianceMatrix->GetNcols() != 7))
399 return NULL__null; //is not 7x7
400
401 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
402 locKinFitParticle->Set_PID(locPID);
403 locKinFitParticle->Set_Charge(locCharge);
404 locKinFitParticle->Set_Mass(locMass);
405 locKinFitParticle->Set_Position(locSpacetimeVertex.Vect());
406 locKinFitParticle->Set_Time(locSpacetimeVertex.T());
407 locKinFitParticle->Set_Momentum(locMomentum);
408 locKinFitParticle->Set_CovarianceMatrix(Clone_MatrixDSym(locCovarianceMatrix));
409
410 locKinFitParticle->Set_KinFitParticleType(d_DetectedParticle);
411
412 if(dDebugLevel > 5)
413 cout << "DKinFitter: Detected particle set. Pointer, ID, Q, Mass, P3, V3, T, pz uncert = " << locKinFitParticle << ", " << locPID << ", " << locCharge << ", " << locMass << ", " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << ", " << sqrt((*locCovarianceMatrix)(3, 3)) << endl;
414
415 return locKinFitParticle;
416}
417
418const DKinFitParticle* DKinFitter::Make_DetectedShower(int locPID, double locMass, TLorentzVector locSpacetimeVertex, double locShowerEnergy, const TMatrixDSym* locCovarianceMatrix)
419{
420 if((locCovarianceMatrix->GetNrows() != 5) || (locCovarianceMatrix->GetNcols() != 5))
421 return NULL__null; //is not 5x5
422
423 DKinFitParticle* locKinFitParticle = Get_KinFitParticleResource();
424 locKinFitParticle->Set_PID(locPID);
425 locKinFitParticle->Set_Charge(0);
426 locKinFitParticle->Set_Mass(locMass);
427 locKinFitParticle->Set_IsNeutralShowerFlag(true);
428 locKinFitParticle->Set_Position(locSpacetimeVertex.Vect());
429 locKinFitParticle->Set_Time(locSpacetimeVertex.T());
430 locKinFitParticle->Set_ShowerEnergy(locShowerEnergy);
431 locKinFitParticle->Set_CovarianceMatrix(Clone_MatrixDSym(locCovarianceMatrix));
432
433 locKinFitParticle->Set_KinFitParticleType(d_DetectedParticle);
434
435 if(dDebugLevel > 5)
436 cout << "DKinFitter: Detected shower set. Pointer, ID, Q, Mass, E, V3, T = 0, " << locKinFitParticle << ", " << locPID << ", " << locMass << ", " << locShowerEnergy << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
437
438 return locKinFitParticle;
439}
440
441void DKinFitter::Set_RFTime(double locRFTime, double locRFUncertainty, const DKinFitParticle* locRFMatchedBeamParticle)
442{
443 cout << "ERROR: THIS IS NOT SUPPORTED YET. RETURNING." << endl;
444 return;
445
446 dRFTime = locRFTime;
447 dRFUncertainty = locRFUncertainty;
448 //THIS IS BAD: SHOULD SET THIS POINTER WHEN CLONING THE REST OF THE CONSTRAINT'S PARTICLES
449// dRFMatchedBeamParticle = Clone_KinFitParticle(locRFMatchedBeamParticle);
450 dRFMatchedBeamParticle = const_cast<DKinFitParticle*>(locRFMatchedBeamParticle);
451
452 if(dDebugLevel > 5)
453 cout << "DKinFitter: RF Time set. t = " << locRFTime << endl;
454}
455
456DKinFitConstraint_Vertex* DKinFitter::Make_VertexConstraint(const deque<const DKinFitParticle*>& locInitialParticles, const deque<const DKinFitParticle*>& locFinalParticles, TVector3 locVertexGuess)
457{
458 deque<DKinFitParticle*> locFullConstrainParticles; //charged particles, decaying particles, beam particles
459 deque<pair<DKinFitParticle*, bool> > locDecayingParticles; //bool is true if vertex is production vertex / particle in final state, false if decay vertex / initial state
460 deque<DKinFitParticle*> locNoConstrainParticles; //missing particles & neutral showers //not used to constrain vertex or time, but fit vertex is set for this particle
461
462 //require all of the tracks to pass through a common point
463 //decaying particles are only used to constrain the fit if they are included in exactly two vertex constraints (once as an initial particle, once as a final particle)
464 //else they are treated as dNoConstrainParticles
465 //will set decaying particles in dFullConstrainParticles and dNoConstrainParticles when ready, but not yet!
466
467 //first check to make sure the inputs are ok //can't tell if enough particles until Resolve_DecayingParticleSpacetimeLinks() //due to decaying particles in 2 constraints
468 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
469 {
470 if(locInitialParticles[loc_i] == NULL__null)
471 return NULL__null;
472 }
473 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
474 {
475 if(locFinalParticles[loc_i] == NULL__null)
476 return NULL__null;
477 else if(locFinalParticles[loc_i]->Get_KinFitParticleType() == d_BeamParticle)
478 return NULL__null;
479 else if(locFinalParticles[loc_i]->Get_KinFitParticleType() == d_TargetParticle)
480 return NULL__null;
481 }
482
483 //sort particles by how they'll be used by the constraint
484 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
485 {
486 DKinFitParticle* locParticle = const_cast<DKinFitParticle*>(locInitialParticles[loc_i]);
487 if(locParticle->Get_KinFitParticleType() == d_TargetParticle)
488 locNoConstrainParticles.push_back(locParticle);
489 else if(locParticle->Get_KinFitParticleType() == d_DecayingParticle)
490 {
491 if(dLinkVerticesFlag)
492 locDecayingParticles.push_back(pair<DKinFitParticle*, bool>(locParticle, false));
493 else
494 locNoConstrainParticles.push_back(locParticle);
495 }
496 else if(locParticle->Get_KinFitParticleType() == d_BeamParticle)
497 {
498 //only add if both vx & vy uncertainties are non-zero (else constraints are bad!!)
499 const TMatrixDSym& locCovarianceMatrix = *(locParticle->Get_CovarianceMatrix());
500 if((locCovarianceMatrix(3, 3) > 0.0) && (locCovarianceMatrix(4, 4) > 0.0)) //include beamline in vertex fit!
501 locFullConstrainParticles.push_back(locParticle);
502 else
503 locNoConstrainParticles.push_back(locParticle);
504 }
505 }
506 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
507 {
508 DKinFitParticle* locParticle = const_cast<DKinFitParticle*>(locFinalParticles[loc_i]);
509 if(locParticle->Get_KinFitParticleType() == d_MissingParticle)
510 locNoConstrainParticles.push_back(locParticle);
511 else if(locParticle->Get_KinFitParticleType() == d_DecayingParticle)
512 {
513 if(dLinkVerticesFlag)
514 locDecayingParticles.push_back(pair<DKinFitParticle*, bool>(locParticle, true));
515 else
516 locNoConstrainParticles.push_back(locParticle);
517 }
518 else if(locParticle->Get_Charge() == 0)
519 locNoConstrainParticles.push_back(locParticle);
520 else
521 locFullConstrainParticles.push_back(locParticle);
522 }
523
524 //create the constraint and set its members
525 DKinFitConstraint_Vertex* locKinFitConstraint = Get_KinFitConstraintVertexResource();
526 locKinFitConstraint->Set_FullConstrainParticles(locFullConstrainParticles);
527 locKinFitConstraint->Set_DecayingParticles(locDecayingParticles);
528 locKinFitConstraint->Set_NoConstrainParticles(locNoConstrainParticles);
529 locKinFitConstraint->Set_CommonVertex(locVertexGuess);
530
531 if(dDebugLevel > 5)
532 {
533 cout << "DKinFitter: Vertex constraint created. Constrained particle PID's, q's, masses: " << endl;
534 for(size_t loc_i = 0; loc_i < locFullConstrainParticles.size(); ++loc_i)
535 cout << locFullConstrainParticles[loc_i]->Get_PID() << ", " << locFullConstrainParticles[loc_i]->Get_Charge() << ", " << locFullConstrainParticles[loc_i]->Get_Mass() << endl;
536 cout << "DKinFitter: Unconstrained particle PID's, q's, masses: " << endl;
537 for(size_t loc_i = 0; loc_i < locNoConstrainParticles.size(); ++loc_i)
538 cout << locNoConstrainParticles[loc_i]->Get_PID() << ", " << locNoConstrainParticles[loc_i]->Get_Charge() << ", " << locNoConstrainParticles[loc_i]->Get_Mass() << endl;
539 cout << "DKinFitter: Decaying particle PID's, q's, masses: " << endl;
540 for(size_t loc_i = 0; loc_i < locDecayingParticles.size(); ++loc_i)
541 cout << locDecayingParticles[loc_i].first->Get_PID() << ", " << locDecayingParticles[loc_i].first->Get_Charge() << ", " << locDecayingParticles[loc_i].first->Get_Mass() << endl;
542 }
543
544 return locKinFitConstraint;
545}
546
547DKinFitConstraint_Spacetime* DKinFitter::Make_SpacetimeConstraint(const deque<const DKinFitParticle*>& locInitialParticles, const deque<const DKinFitParticle*>& locFinalParticles, bool locUseRFTimeFlag, TVector3 locVertexGuess, double locCommonTimeGuess)
548{
549 cout << "ERROR: SPACETIME CONSTRAINTS ARE NOT SUPPORTED YET. RETURNING." << endl;
550 return NULL__null;
551
552 deque<DKinFitParticle*> locFullConstrainParticles; //charged particles, decaying particles, beam particles
553 deque<DKinFitParticle*> locOnlyConstrainTimeParticles; //neutral showers //not used to constrain vertex, but fit vertex is used for time constraint
554 deque<pair<DKinFitParticle*, bool> > locDecayingParticles; //bool is true if vertex is production vertex / particle in final state, false if decay vertex / initial state
555 deque<DKinFitParticle*> locNoConstrainParticles; //missing particles //not used to constrain vertex or time, but fit vertex & time are set for this particle
556
557 //require all of the tracks to pass through a common point at a common time
558 //decaying particles are only used to constrain the fit if they are included in exactly two vertex constraints (once as an initial particle, once as a final particle)
559 //else they are treated as dNoConstrainParticles
560 //will set decaying particles in dFullConstrainParticles and dNoConstrainParticles when ready, but not yet!
561
562 //first check to make sure the inputs are ok //can't tell if enough particles until Resolve_DecayingParticleSpacetimeLinks() //due to decaying particles in 2 constraints
563 DKinFitParticle* locBeamParticle = NULL__null;
564 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
565 {
566 if(locInitialParticles[loc_i] == NULL__null)
567 return NULL__null;
568 else if(locInitialParticles[loc_i]->Get_KinFitParticleType() == d_BeamParticle)
569 locBeamParticle = const_cast<DKinFitParticle*>(locInitialParticles[loc_i]);
570 }
571 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
572 {
573 if(locFinalParticles[loc_i] == NULL__null)
574 return NULL__null;
575 else if(locFinalParticles[loc_i]->Get_KinFitParticleType() == d_BeamParticle)
576 return NULL__null;
577 else if(locFinalParticles[loc_i]->Get_KinFitParticleType() == d_TargetParticle)
578 return NULL__null;
579 }
580
581 //sort particles by how they'll be used by the constraint
582 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
583 {
584 DKinFitParticle* locParticle = const_cast<DKinFitParticle*>(locInitialParticles[loc_i]);
585 if(locParticle->Get_KinFitParticleType() == d_MissingParticle)
586 locNoConstrainParticles.push_back(locParticle);
587 else if(locParticle->Get_KinFitParticleType() == d_TargetParticle)
588 locNoConstrainParticles.push_back(locParticle);
589 else if(locParticle->Get_KinFitParticleType() == d_DecayingParticle)
590 {
591 if(dLinkVerticesFlag)
592 locDecayingParticles.push_back(pair<DKinFitParticle*, bool>(locParticle, false));
593 else
594 locNoConstrainParticles.push_back(locParticle);
595 }
596 else if(locParticle->Get_KinFitParticleType() == d_BeamParticle)
597 {
598 //only add if both vx & vy uncertainties are non-zero (else constraints are bad!!)
599 const TMatrixDSym& locCovarianceMatrix = *(locParticle->Get_CovarianceMatrix());
600 if((locCovarianceMatrix(3, 3) > 0.0) && (locCovarianceMatrix(4, 4) > 0.0))
601 locFullConstrainParticles.push_back(locParticle); //include beamline in vertex fit!
602 else
603 locNoConstrainParticles.push_back(locParticle);
604 }
605 }
606 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
607 {
608 DKinFitParticle* locParticle = const_cast<DKinFitParticle*>(locFinalParticles[loc_i]);
609 if(locParticle->Get_KinFitParticleType() == d_MissingParticle)
610 locNoConstrainParticles.push_back(locParticle);
611 else if(locParticle->Get_KinFitParticleType() == d_DecayingParticle)
612 {
613 if(dLinkVerticesFlag)
614 locDecayingParticles.push_back(pair<DKinFitParticle*, bool>(locParticle, true));
615 else
616 locNoConstrainParticles.push_back(locParticle);
617 }
618 else if(locParticle->Get_Charge() == 0)
619 locOnlyConstrainTimeParticles.push_back(locParticle);
620 else
621 locFullConstrainParticles.push_back(locParticle);
622 }
623
624 //create the constraint and set its members
625 DKinFitConstraint_Spacetime* locKinFitConstraint = Get_KinFitConstraintSpacetimeResource();
626 locKinFitConstraint->Set_FullConstrainParticles(locFullConstrainParticles);
627 locKinFitConstraint->Set_OnlyConstrainTimeParticles(locOnlyConstrainTimeParticles);
628 locKinFitConstraint->Set_DecayingParticles(locDecayingParticles);
629 locKinFitConstraint->Set_NoConstrainParticles(locNoConstrainParticles);
630 locKinFitConstraint->Set_CommonVertex(locVertexGuess);
631 locKinFitConstraint->Set_CommonTime(locCommonTimeGuess);
632 locKinFitConstraint->Set_UseRFTimeFlag(locUseRFTimeFlag);
633 locKinFitConstraint->dBeamParticle = locBeamParticle;
634
635 if(dDebugLevel > 5)
636 {
637 cout << "DKinFitter: Spacetime constraint created. Vertex/Time constrained particle PID's, q's, masses: " << endl;
638 for(size_t loc_i = 0; loc_i < locFullConstrainParticles.size(); ++loc_i)
639 cout << locFullConstrainParticles[loc_i]->Get_PID() << ", " << locFullConstrainParticles[loc_i]->Get_Charge() << ", " << locFullConstrainParticles[loc_i]->Get_Mass() << endl;
640 cout << "DKinFitter: Time-only constrained particle PID's, q's, masses: " << endl;
641 for(size_t loc_i = 0; loc_i < locOnlyConstrainTimeParticles.size(); ++loc_i)
642 cout << locOnlyConstrainTimeParticles[loc_i]->Get_PID() << ", " << locOnlyConstrainTimeParticles[loc_i]->Get_Charge() << ", " << locOnlyConstrainTimeParticles[loc_i]->Get_Mass() << endl;
643 cout << "DKinFitter: Unconstrained particle PID's, q's, masses: " << endl;
644 for(size_t loc_i = 0; loc_i < locNoConstrainParticles.size(); ++loc_i)
645 cout << locNoConstrainParticles[loc_i]->Get_PID() << ", " << locNoConstrainParticles[loc_i]->Get_Charge() << ", " << locNoConstrainParticles[loc_i]->Get_Mass() << endl;
646 cout << "DKinFitter: Decaying particle PID's, q's, masses: " << endl;
647 for(size_t loc_i = 0; loc_i < locDecayingParticles.size(); ++loc_i)
648 cout << locDecayingParticles[loc_i].first->Get_PID() << ", " << locDecayingParticles[loc_i].first->Get_Charge() << ", " << locDecayingParticles[loc_i].first->Get_Mass() << endl;
649 }
650
651 return locKinFitConstraint;
652}
653
654DKinFitConstraint_P4* DKinFitter::Make_P4Constraint(const deque<const DKinFitParticle*>& locInitialParticles, const deque<const DKinFitParticle*>& locFinalParticles, bool locConstrainInitialParticleMassFlag)
655{
656 //require p4 is conserved between the tracks
657
658 //first check to make sure the inputs are ok //can't tell if constrained properly until Resolve_Constraints() //due to decaying particles in 2 constraints
659 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
660 {
661 if(locInitialParticles[loc_i] == NULL__null)
662 return NULL__null;
663 }
664 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
665 {
666 if(locFinalParticles[loc_i] == NULL__null)
667 return NULL__null;
668 }
669
670 deque<DKinFitParticle*> locNonConstInitialParticles, locNonConstFinalParticles;
671 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
672 locNonConstInitialParticles.push_back(const_cast<DKinFitParticle*>(locInitialParticles[loc_i]));
673 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
674 locNonConstFinalParticles.push_back(const_cast<DKinFitParticle*>(locFinalParticles[loc_i]));
675
676 //create the constraint and set its members
677 DKinFitConstraint_P4* locKinFitConstraint = Get_KinFitConstraintP4Resource();
678 locKinFitConstraint->Set_InitialParticles(locNonConstInitialParticles);
679 locKinFitConstraint->Set_FinalParticles(locNonConstFinalParticles);
680 locKinFitConstraint->Set_ConstrainInitialParticleMassFlag(locConstrainInitialParticleMassFlag);
681
682 if(dDebugLevel > 5)
683 {
684 cout << "DKinFitter: P4 constraint created. Initial-state particle PID's, q's, masses: " << endl;
685 for(size_t loc_i = 0; loc_i < locInitialParticles.size(); ++loc_i)
686 cout << locInitialParticles[loc_i]->Get_PID() << ", " << locInitialParticles[loc_i]->Get_Charge() << ", " << locInitialParticles[loc_i]->Get_Mass() << endl;
687 cout << "DKinFitter: Final-state particle PID's, q's, masses: " << endl;
688 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
689 cout << locFinalParticles[loc_i]->Get_PID() << ", " << locFinalParticles[loc_i]->Get_Charge() << ", " << locFinalParticles[loc_i]->Get_Mass() << endl;
690 }
691
692 return locKinFitConstraint;
693}
694
695void DKinFitter::Set_Constraint(const DKinFitConstraint_P4* locConstraint)
696{
697 //register a constraint for upcoming fit
698 dKinFitConstraints.push_back(static_cast<DKinFitConstraint*>(const_cast<DKinFitConstraint_P4*>(locConstraint)));
699
700 if(dDebugLevel > 5)
701 {
702 cout << "DKinFitter: P4 constraint set. Initial-state particle PID's, q's, masses: " << endl;
703 for(size_t loc_i = 0; loc_i < locConstraint->dInitialParticles.size(); ++loc_i)
704 cout << locConstraint->dInitialParticles[loc_i]->Get_PID() << ", " << locConstraint->dInitialParticles[loc_i]->Get_Charge() << ", " << locConstraint->dInitialParticles[loc_i]->Get_Mass() << endl;
705 cout << "DKinFitter: Final-state particle PID's, q's, masses: " << endl;
706 for(size_t loc_i = 0; loc_i < locConstraint->dFinalParticles.size(); ++loc_i)
707 cout << locConstraint->dFinalParticles[loc_i]->Get_PID() << ", " << locConstraint->dFinalParticles[loc_i]->Get_Charge() << ", " << locConstraint->dFinalParticles[loc_i]->Get_Mass() << endl;
708 }
709}
710
711void DKinFitter::Set_Constraint(const DKinFitConstraint_Vertex* locConstraint)
712{
713 //register a constraint for upcoming fit
714 dKinFitConstraints.push_back(static_cast<DKinFitConstraint*>(const_cast<DKinFitConstraint_Vertex*>(locConstraint)));
715
716 if(dDebugLevel > 5)
717 {
718 cout << "DKinFitter: Vertex constraint set. Constrained particle PID's, q's, masses: " << endl;
719 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
720 cout << locConstraint->dFullConstrainParticles[loc_i]->Get_PID() << ", " << locConstraint->dFullConstrainParticles[loc_i]->Get_Charge() << ", " << locConstraint->dFullConstrainParticles[loc_i]->Get_Mass() << endl;
721 cout << "DKinFitter: Unconstrained particle PID's, q's, masses: " << endl;
722 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
723 cout << locConstraint->dNoConstrainParticles[loc_i]->Get_PID() << ", " << locConstraint->dNoConstrainParticles[loc_i]->Get_Charge() << ", " << locConstraint->dNoConstrainParticles[loc_i]->Get_Mass() << endl;
724 cout << "DKinFitter: Decaying particle PID's, q's, masses: " << endl;
725 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
726 cout << locConstraint->dDecayingParticles[loc_i].first->Get_PID() << ", " << locConstraint->dDecayingParticles[loc_i].first->Get_Charge() << ", " << locConstraint->dDecayingParticles[loc_i].first->Get_Mass() << endl;
727 }
728}
729
730void DKinFitter::Set_Constraint(const DKinFitConstraint_Spacetime* locConstraint)
731{
732 //register a constraint for upcoming fit
733 cout << "ERROR: SPACETIME CONSTRAINTS ARE NOT SUPPORTED YET. RETURNING." << endl;
734 return;
735
736 //clone particles & constraints so that they can be modified during the fit without overwriting the originals
737 dKinFitConstraints.push_back(static_cast<DKinFitConstraint*>(const_cast<DKinFitConstraint_Spacetime*>(locConstraint)));
738
739 if(dDebugLevel > 5)
740 {
741 cout << "DKinFitter: Spacetime constraint set. Vertex/Time constrained particle PID's, q's, masses: " << endl;
742 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
743 cout << locConstraint->dFullConstrainParticles[loc_i]->Get_PID() << ", " << locConstraint->dFullConstrainParticles[loc_i]->Get_Charge() << ", " << locConstraint->dFullConstrainParticles[loc_i]->Get_Mass() << endl;
744 cout << "DKinFitter: Time-only constrained particle PID's, q's, masses: " << endl;
745 for(size_t loc_i = 0; loc_i < locConstraint->dOnlyConstrainTimeParticles.size(); ++loc_i)
746 cout << locConstraint->dOnlyConstrainTimeParticles[loc_i]->Get_PID() << ", " << locConstraint->dOnlyConstrainTimeParticles[loc_i]->Get_Charge() << ", " << locConstraint->dOnlyConstrainTimeParticles[loc_i]->Get_Mass() << endl;
747 cout << "DKinFitter: Unconstrained particle PID's, q's, masses: " << endl;
748 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
749 cout << locConstraint->dNoConstrainParticles[loc_i]->Get_PID() << ", " << locConstraint->dNoConstrainParticles[loc_i]->Get_Charge() << ", " << locConstraint->dNoConstrainParticles[loc_i]->Get_Mass() << endl;
750 cout << "DKinFitter: Decaying particle PID's, q's, masses: " << endl;
751 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
752 cout << locConstraint->dDecayingParticles[loc_i].first->Get_PID() << ", " << locConstraint->dDecayingParticles[loc_i].first->Get_Charge() << ", " << locConstraint->dDecayingParticles[loc_i].first->Get_Mass() << endl;
753 }
754}
755
756bool DKinFitter::Prepare_Constraint(DKinFitConstraint_P4* locConstraint) const
757{
758 //enforce maximum #constraints per particle: 1 for non-decaying, 2 for decaying
759 for(size_t loc_i = 0; loc_i < locConstraint->dInitialParticles.size(); ++loc_i)
760 {
761 const DKinFitParticle* locParticle = locConstraint->dInitialParticles[loc_i];
762 DKinFitParticleType locKinFitParticleType = locParticle->Get_KinFitParticleType();
763 size_t locNumP4Constraints = locParticle->Get_NumP4Constraints();
764 if((locKinFitParticleType != d_DecayingParticle) && (locNumP4Constraints > 0))
765 {
766 cout << "ERROR: Non-decaying particle cannot be used in more than one P4 constraint. Constraint not added." << endl;
767 return false;
768 }
769 else if(locNumP4Constraints > 1)
770 {
771 cout << "ERROR: Decaying particle cannot be used in more than two P4 constraints. Constraint not added." << endl;
772 return false;
773 }
774 }
775 for(size_t loc_i = 0; loc_i < locConstraint->dFinalParticles.size(); ++loc_i)
776 {
777 const DKinFitParticle* locParticle = locConstraint->dFinalParticles[loc_i];
778 DKinFitParticleType locKinFitParticleType = locParticle->Get_KinFitParticleType();
779 size_t locNumP4Constraints = locParticle->Get_NumP4Constraints();
780 if((locKinFitParticleType != d_DecayingParticle) && (locNumP4Constraints > 0))
781 {
782 cout << "ERROR: Non-decaying particle cannot be used in more than one P4 constraint. Constraint not added." << endl;
783 return false;
784 }
785 else if(locNumP4Constraints > 1)
786 {
787 cout << "ERROR: Decaying particle cannot be used in more than two P4 constraints. Constraint not added." << endl;
788 return false;
789 }
790 }
791
792 //mark constraint in particles
793 for(size_t loc_i = 0; loc_i < locConstraint->dInitialParticles.size(); ++loc_i)
794 locConstraint->dInitialParticles[loc_i]->Add_P4Constraint(locConstraint);
795 for(size_t loc_i = 0; loc_i < locConstraint->dFinalParticles.size(); ++loc_i)
796 locConstraint->dFinalParticles[loc_i]->Add_P4Constraint(locConstraint);
797
798 return true;
799}
800
801bool DKinFitter::Prepare_Constraint(DKinFitConstraint_Vertex* locConstraint) const
802{
803 //enforce maximum #constraints per particle: 1 for non-decaying, 2 for decaying
804 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
805 {
806 const DKinFitParticle* locParticle = locConstraint->dFullConstrainParticles[loc_i];
807 DKinFitParticleType locKinFitParticleType = locParticle->Get_KinFitParticleType();
808 size_t locNumConstraints = locParticle->Get_NumVertexFits();
809 if((locKinFitParticleType != d_DecayingParticle) && (locNumConstraints > 0))
810 {
811 cout << "ERROR: Non-decaying particle cannot be used in more than one vertex constraint. Constraint not added." << endl;
812 return false;
813 }
814 else if(locNumConstraints > 1)
815 {
816 cout << "ERROR: Decaying particle cannot be used in more than two vertex constraints. Constraint not added." << endl;
817 return false;
818 }
819 }
820 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
821 {
822 const DKinFitParticle* locParticle = locConstraint->dDecayingParticles[loc_i].first;
823 size_t locNumConstraints = locParticle->Get_NumVertexFits();
824 if(locNumConstraints > 1)
825 {
826 cout << "ERROR: Decaying particle cannot be used in more than two vertex constraints. Constraint not added." << endl;
827 return false;
828 }
829 }
830
831 //set vertex constraint flags
832 TVector3 locMomentum;
833 unsigned short int locVertexConstraintFlag;
834 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
835 {
836 DKinFitParticle* locParticle = locConstraint->dFullConstrainParticles[loc_i];
837 locMomentum = locParticle->Get_Momentum();
838 if(fabs(locMomentum.Pz()) > fabs(locMomentum.Px()))
839 locVertexConstraintFlag = (fabs(locMomentum.Pz()) > fabs(locMomentum.Py())) ? 1 : 2;
840 else
841 locVertexConstraintFlag = (fabs(locMomentum.Px()) > fabs(locMomentum.Py())) ? 3 : 2;
842 locParticle->Set_VertexConstraintFlag(locVertexConstraintFlag);
843 }
844
845 //set momentum of neutral showers that have 5x5 covariance matrix (shower energy input instead of p3)
846 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
847 {
848 DKinFitParticle* locParticle = locConstraint->dNoConstrainParticles[loc_i];
849 if(!locParticle->Get_IsNeutralShowerFlag())
850 continue; //only do for neutral showers
851
852 double locE = locParticle->Get_ShowerEnergy();
853 double locMass = locParticle->Get_Mass();
854 double locPMag = sqrt(locE*locE - locMass*locMass);
855 TVector3 locMomentum = locParticle->Get_Position() - locParticle->Get_CommonVertex();
856 locMomentum.SetMag(locPMag);
857 locParticle->Set_Momentum(locMomentum);
858 }
859
860 //add constraint to particles
861 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
862 locConstraint->dFullConstrainParticles[loc_i]->Add_CommonVertexAndOrTimeConstraint(locConstraint);
863 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
864 locConstraint->dNoConstrainParticles[loc_i]->Add_CommonVertexAndOrTimeConstraint(locConstraint);
865 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
866 locConstraint->dDecayingParticles[loc_i].first->Add_CommonVertexAndOrTimeConstraint(locConstraint);
867
868 return true;
869}
870
871bool DKinFitter::Prepare_Constraint(DKinFitConstraint_Spacetime* locConstraint) const
872{
873 //prepare a constraint for upcoming fit
874 cout << "ERROR: SPACETIME CONSTRAINTS ARE NOT SUPPORTED YET. RETURNING." << endl;
875 return false;
876
877 //enforce maximum #constraints per particle: 1 for non-decaying, 2 for decaying
878 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
879 {
880 const DKinFitParticle* locParticle = locConstraint->dFullConstrainParticles[loc_i];
881 DKinFitParticleType locKinFitParticleType = locParticle->Get_KinFitParticleType();
882 size_t locNumConstraints = locParticle->Get_NumVertexFits();
883 if((locKinFitParticleType != d_DecayingParticle) && (locNumConstraints > 0))
884 {
885 cout << "ERROR: Non-decaying particle cannot be used in more than one spacetime constraint. Constraint not added." << endl;
886 return false;
887 }
888 else if(locNumConstraints > 1)
889 {
890 cout << "ERROR: Decaying particle cannot be used in more than two spacetime constraints. Constraint not added." << endl;
891 return false;
892 }
893 }
894 for(size_t loc_i = 0; loc_i < locConstraint->dOnlyConstrainTimeParticles.size(); ++loc_i) //neutral showers
895 {
896 const DKinFitParticle* locParticle = locConstraint->dOnlyConstrainTimeParticles[loc_i];
897 DKinFitParticleType locKinFitParticleType = locParticle->Get_KinFitParticleType();
898 size_t locNumConstraints = locParticle->Get_NumVertexFits();
899 if((locKinFitParticleType != d_DecayingParticle) && (locNumConstraints > 0))
900 {
901 cout << "ERROR: Non-decaying particle cannot be used in more than one spacetime constraint. Constraint not added." << endl;
902 return false;
903 }
904 }
905 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
906 {
907 const DKinFitParticle* locParticle = locConstraint->dDecayingParticles[loc_i].first;
908 size_t locNumConstraints = locParticle->Get_NumVertexFits();
909 if(locNumConstraints > 1)
910 {
911 cout << "ERROR: Decaying particle cannot be used in more than two spacetime constraints. Constraint not added." << endl;
912 return false;
913 }
914 }
915
916 //set momentum of neutral showers that have 5x5 covariance matrix (shower energy input instead of p3)
917 for(size_t loc_i = 0; loc_i < locConstraint->dOnlyConstrainTimeParticles.size(); ++loc_i)
918 {
919 DKinFitParticle* locParticle = locConstraint->dOnlyConstrainTimeParticles[loc_i];
920 double locE = locParticle->Get_ShowerEnergy();
921 double locMass = locParticle->Get_Mass();
922 double locPMag = sqrt(locE*locE - locMass*locMass);
923 TVector3 locMomentum = locParticle->Get_Position() - locParticle->Get_CommonVertex();
924 locMomentum.SetMag(locPMag);
925 locParticle->Set_Momentum(locMomentum);
926 }
927
928 //add constraint to particles
929 for(size_t loc_i = 0; loc_i < locConstraint->dFullConstrainParticles.size(); ++loc_i)
930 locConstraint->dFullConstrainParticles[loc_i]->Add_CommonVertexAndOrTimeConstraint(locConstraint);
931 for(size_t loc_i = 0; loc_i < locConstraint->dOnlyConstrainTimeParticles.size(); ++loc_i)
932 locConstraint->dOnlyConstrainTimeParticles[loc_i]->Add_CommonVertexAndOrTimeConstraint(locConstraint);
933 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
934 locConstraint->dNoConstrainParticles[loc_i]->Add_CommonVertexAndOrTimeConstraint(locConstraint);
935 for(size_t loc_i = 0; loc_i < locConstraint->dDecayingParticles.size(); ++loc_i)
936 locConstraint->dDecayingParticles[loc_i].first->Add_CommonVertexAndOrTimeConstraint(locConstraint);
937
938 return true;
939}
940
941bool DKinFitter::Sort_Constraints(const deque<DKinFitConstraint*>& locOriginalConstraints, deque<pair<DKinFitConstraint_VertexBase*, set<DKinFitConstraint_P4*> > >& locSortedConstraints)
942{
943#ifdef VTRACE
944 VT_TRACER("DKinFitter::Sort_Constraints()");
945#endif
946 if(dDebugLevel > 10)
947 cout << "DKinFitter: Sort constraints: Clone constraints." << endl;
948
949 //clone constraints & particles
950 deque<DKinFitConstraint*> locClonedConstraints;
951 Clone_Constraints(locOriginalConstraints, locClonedConstraints);
952
953 if(dDebugLevel > 10)
954 cout << "DKinFitter: Sort constraints: Resolve constraints." << endl;
955
956 deque<DKinFitConstraint_VertexBase*> locSortedVertexConstraints;
957 if(!Resolve_Constraints(locClonedConstraints, locSortedVertexConstraints, true))
958 return false;
959
960 if(dDebugLevel > 10)
961 cout << "DKinFitter: Sort constraints: Group constraints." << endl;
962
963 if(!Group_Constraints(locSortedVertexConstraints, locSortedConstraints))
964 return false;
965
966 //loop over locSortedConstraints, replacing cloned contents with originals
967 for(size_t loc_i = 0; loc_i < locSortedConstraints.size(); ++loc_i)
968 {
969 //vertex
970 locSortedConstraints[loc_i].first = static_cast<DKinFitConstraint_VertexBase*>(const_cast<DKinFitConstraint*>(dKinFitConstraintCloningOIMap[locSortedConstraints[loc_i].first]));
971
972 //p4
973 set<DKinFitConstraint_P4*> locClonedP4Constraints = locSortedConstraints[loc_i].second;
974 locSortedConstraints[loc_i].second.clear();
975 set<DKinFitConstraint_P4*>::iterator locIterator = locClonedP4Constraints.begin();
976 for(; locIterator != locClonedP4Constraints.end(); ++locIterator)
977 locSortedConstraints[loc_i].second.insert(static_cast<DKinFitConstraint_P4*>(const_cast<DKinFitConstraint*>(dKinFitConstraintCloningOIMap[*locIterator])));
978 }
979
980 //recycle the interim objects created
981 Recycle_Constraints(locClonedConstraints);
982
983 return true;
984}
985
986void DKinFitter::Recycle_Constraints(deque<DKinFitConstraint*>& locConstraints)
987{
988 //ONLY CALL THIS IF YOU KNOW !!!EXACTLY!!! WHAT YOU ARE DOING!!!
989 //And if you're calling this, you probably don't (this probably includes me ...)
990
991 //Get all of the particles from the constraints (some particles may be listed in multiple constraints!)
992 //This is why you can't recycle the constraint particles one constraint at a time
993 //Also, recycle the constraints
994 set<const DKinFitParticle*> locAllKinFitParticles;
995 for(size_t loc_i = 0; loc_i < locConstraints.size(); ++loc_i)
996 {
997 set<const DKinFitParticle*> locConstraintKinFitParticles;
998 locConstraints[loc_i]->Get_AllKinFitParticles(locConstraintKinFitParticles);
999 locAllKinFitParticles.insert(locConstraintKinFitParticles.begin(), locConstraintKinFitParticles.end());
1000
1001 dKinFitConstraintCloningOIMap.erase(dKinFitConstraintCloningOIMap.find(locConstraints[loc_i]));
1002
1003 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locConstraints[loc_i]);
1004 DKinFitConstraint_Vertex* locVertexConstraint = dynamic_cast<DKinFitConstraint_Vertex*>(locConstraints[loc_i]);
1005 DKinFitConstraint_Spacetime* locSpacetimeConstraint = dynamic_cast<DKinFitConstraint_Spacetime*>(locConstraints[loc_i]);
1006
1007 if(locP4Constraint != NULL__null)
1008 dKinFitConstraintP4Pool_Available.push_back(locP4Constraint);
1009 else if(locVertexConstraint != NULL__null)
1010 dKinFitConstraintVertexPool_Available.push_back(locVertexConstraint);
1011 else if(locSpacetimeConstraint != NULL__null)
1012 dKinFitConstraintSpacetimePool_Available.push_back(locSpacetimeConstraint);
1013 }
1014
1015 //Recycle the particles and their covariance matrices
1016 set<const DKinFitParticle*>::iterator locIterator = locAllKinFitParticles.begin();
1017 for(; locIterator != locAllKinFitParticles.end(); ++locIterator)
1018 {
1019 dKinFitParticleCloningOIMap.erase(dKinFitParticleCloningOIMap.find(*locIterator));
1020 if((*locIterator)->Get_CovarianceMatrix() != NULL__null)
1021 dMatrixDSymPool_Available.push_back(const_cast<TMatrixDSym*>((*locIterator)->Get_CovarianceMatrix()));
1022 dKinFitParticlePool_Available.push_back(const_cast<DKinFitParticle*>(*locIterator));
1023 }
1024}
1025
1026void DKinFitter::Clone_Constraints(const deque<DKinFitConstraint*>& locInputConstraints, deque<DKinFitConstraint*>& locClonedConstraints)
1027{
1028 locClonedConstraints.clear();
1029
1030 //Get all of the particles from the constraints (some particles may be listed in multiple constraints!)
1031 //This is why you can't clone the constraint particles one constraint at a time
1032 set<const DKinFitParticle*> locAllKinFitParticles;
1033 for(size_t loc_i = 0; loc_i < locInputConstraints.size(); ++loc_i)
1034 {
1035 set<const DKinFitParticle*> locConstraintKinFitParticles;
1036 locInputConstraints[loc_i]->Get_AllKinFitParticles(locConstraintKinFitParticles);
1037 locAllKinFitParticles.insert(locConstraintKinFitParticles.begin(), locConstraintKinFitParticles.end());
1038 }
1039
1040 //Clone all of the particles //keep track of clone IO for this fit
1041 //can't do as an overall class member, because one input may have several cloned outputs (multiple fits). but for this fit, can track here
1042 map<const DKinFitParticle*, DKinFitParticle*> locCloneIOMap; //for this fit
1043 set<const DKinFitParticle*>::iterator locAllParticlesIterator = locAllKinFitParticles.begin();
1044 for(; locAllParticlesIterator != locAllKinFitParticles.end(); ++locAllParticlesIterator)
1045 locCloneIOMap[*locAllParticlesIterator] = Clone_KinFitParticle(*locAllParticlesIterator);
1046
1047 //Clone the constraints, and then set the particles to the cloned particles
1048 for(size_t loc_i = 0; loc_i < locInputConstraints.size(); ++loc_i)
1049 {
1050 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locInputConstraints[loc_i]);
1051 DKinFitConstraint_Vertex* locVertexConstraint = dynamic_cast<DKinFitConstraint_Vertex*>(locInputConstraints[loc_i]);
1052 DKinFitConstraint_Spacetime* locSpacetimeConstraint = dynamic_cast<DKinFitConstraint_Spacetime*>(locInputConstraints[loc_i]);
1053
1054 if(locP4Constraint != NULL__null)
1055 {
1056 DKinFitConstraint_P4* locClonedConstraint = Clone_KinFitConstraint_P4(locP4Constraint);;
1057
1058 for(size_t loc_j = 0; loc_j < locClonedConstraint->dInitialParticles.size(); ++loc_j)
1059 locClonedConstraint->dInitialParticles[loc_j] = locCloneIOMap[locClonedConstraint->dInitialParticles[loc_j]];
1060 for(size_t loc_j = 0; loc_j < locClonedConstraint->dFinalParticles.size(); ++loc_j)
1061 locClonedConstraint->dFinalParticles[loc_j] = locCloneIOMap[locClonedConstraint->dFinalParticles[loc_j]];
1062
1063 locClonedConstraints.push_back(locClonedConstraint);
1064 continue;
1065 }
1066 else if(locVertexConstraint != NULL__null)
1067 {
1068 DKinFitConstraint_Vertex* locClonedConstraint = Clone_KinFitConstraint_Vertex(locVertexConstraint);
1069
1070 for(size_t loc_i = 0; loc_i < locClonedConstraint->dFullConstrainParticles.size(); ++loc_i)
1071 locClonedConstraint->dFullConstrainParticles[loc_i] = locCloneIOMap[locClonedConstraint->dFullConstrainParticles[loc_i]];
1072 for(size_t loc_i = 0; loc_i < locClonedConstraint->dNoConstrainParticles.size(); ++loc_i)
1073 locClonedConstraint->dNoConstrainParticles[loc_i] = locCloneIOMap[locClonedConstraint->dNoConstrainParticles[loc_i]];
1074 for(size_t loc_i = 0; loc_i < locClonedConstraint->dDecayingParticles.size(); ++loc_i)
1075 locClonedConstraint->dDecayingParticles[loc_i].first = locCloneIOMap[locClonedConstraint->dDecayingParticles[loc_i].first];
1076
1077 set<DKinFitParticle*> locDecayingParticlesToAssignClones;
1078 set<DKinFitParticle*>::iterator locSetIterator = locClonedConstraint->dDecayingParticlesToAssign.begin();
1079 for(; locSetIterator != locClonedConstraint->dDecayingParticlesToAssign.end(); ++locSetIterator)
1080 locDecayingParticlesToAssignClones.insert(locCloneIOMap[*locSetIterator]);
1081 locClonedConstraint->dDecayingParticlesToAssign = locDecayingParticlesToAssignClones;
1082
1083 locClonedConstraints.push_back(locClonedConstraint);
1084 continue;
1085 }
1086 else if(locSpacetimeConstraint != NULL__null)
1087 {
1088 DKinFitConstraint_Spacetime* locClonedConstraint = Clone_KinFitConstraint_Spacetime(locSpacetimeConstraint);
1089
1090 for(size_t loc_i = 0; loc_i < locClonedConstraint->dFullConstrainParticles.size(); ++loc_i)
1091 locClonedConstraint->dFullConstrainParticles[loc_i] = locCloneIOMap[locClonedConstraint->dFullConstrainParticles[loc_i]];
1092 for(size_t loc_i = 0; loc_i < locClonedConstraint->dOnlyConstrainTimeParticles.size(); ++loc_i)
1093 locClonedConstraint->dOnlyConstrainTimeParticles[loc_i] = locCloneIOMap[locClonedConstraint->dOnlyConstrainTimeParticles[loc_i]];
1094 for(size_t loc_i = 0; loc_i < locClonedConstraint->dNoConstrainParticles.size(); ++loc_i)
1095 locClonedConstraint->dNoConstrainParticles[loc_i] = locCloneIOMap[locClonedConstraint->dNoConstrainParticles[loc_i]];
1096 for(size_t loc_i = 0; loc_i < locClonedConstraint->dDecayingParticles.size(); ++loc_i)
1097 locClonedConstraint->dDecayingParticles[loc_i].first = locCloneIOMap[locClonedConstraint->dDecayingParticles[loc_i].first];
1098
1099 set<DKinFitParticle*> locDecayingParticlesToAssignClones;
1100 set<DKinFitParticle*>::iterator locSetIterator = locClonedConstraint->dDecayingParticlesToAssign.begin();
1101 for(; locSetIterator != locClonedConstraint->dDecayingParticlesToAssign.end(); ++locSetIterator)
1102 locDecayingParticlesToAssignClones.insert(locCloneIOMap[*locSetIterator]);
1103 locClonedConstraint->dDecayingParticlesToAssign = locDecayingParticlesToAssignClones;
1104
1105 locClonedConstraints.push_back(locClonedConstraint);
1106 continue;
1107 }
1108 }
1109}
1110
1111bool DKinFitter::Resolve_Constraints(void)
1112{
1113 //ONLY CALL THIS METHOD WHEN PERFORMING THE FIT (i.e.not sorting)
1114 //This is because the constraints (dKinFitConstraints, the ones used in the fit) are modified by Resolve_Constraints()
1115 deque<DKinFitConstraint_VertexBase*> locSortedVertexConstraints;
1116 return Resolve_Constraints(dKinFitConstraints, locSortedVertexConstraints, false);
1117}
1118
1119bool DKinFitter::Resolve_Constraints(const deque<DKinFitConstraint*>& locConstraints, deque<DKinFitConstraint_VertexBase*>& locSortedVertexConstraints, bool locSortOnlyFlag) const
1120{
1121#ifdef VTRACE
1122 VT_TRACER("DKinFitter::Resolve_Constraints()");
1123#endif
1124 if(dDebugLevel > 10)
1125 cout << "DKinFitter: Resolve constraints: Prepare " << locConstraints.size() << " constraints." << endl;
1126
1127 //prepare constraints
1128 for(size_t loc_i = 0; loc_i < locConstraints.size(); ++loc_i)
1129 {
1130 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locConstraints[loc_i]);
1131 if(locP4Constraint != NULL__null)
1132 {
1133 if(!Prepare_Constraint(locP4Constraint))
1134 return false;
1135 continue;
1136 }
1137
1138 DKinFitConstraint_Vertex* locVertexConstraint = dynamic_cast<DKinFitConstraint_Vertex*>(locConstraints[loc_i]);
1139 if(locVertexConstraint != NULL__null)
1140 {
1141 if(!Prepare_Constraint(locVertexConstraint))
1142 return false;
1143 continue;
1144 }
1145 DKinFitConstraint_Spacetime* locSpacetimeConstraint = dynamic_cast<DKinFitConstraint_Spacetime*>(locConstraints[loc_i]);
1146 if(locSpacetimeConstraint != NULL__null)
1147 {
1148 if(!Prepare_Constraint(locSpacetimeConstraint))
1149 return false;
1150 continue;
1151 }
1152 }
1153
1154 if(dDebugLevel > 10)
1155 cout << "DKinFitter: Resolve constraints: Constraints Prepared." << endl;
1156
1157 locSortedVertexConstraints.clear();
1158 if(!Resolve_DecayingParticleSpacetimeLinks(locConstraints, locSortedVertexConstraints, locSortOnlyFlag))
1159 return false;
1160
1161 if(dDebugLevel > 10)
1162 cout << "DKinFitter: Resolve constraints: Spacetime resolved." << endl;
1163
1164 if(!Resolve_P4Constraints(locConstraints, locSortOnlyFlag))
1165 return false;
1166
1167 if(dDebugLevel > 10)
1168 cout << "DKinFitter: Resolve constraints: P4 resolved." << endl;
1169
1170 if(!Resolve_P4MassConstraints(locConstraints, locSortOnlyFlag))
1171 return false;
1172
1173 if(dDebugLevel > 10)
1174 cout << "DKinFitter: Resolve constraints: P4/Mass resolved." << endl;
1175
1176 return true;
1177}
1178
1179bool DKinFitter::Resolve_DecayingParticleSpacetimeLinks(const deque<DKinFitConstraint*>& locKinFitConstraints, deque<DKinFitConstraint_VertexBase*>& locSortedConstraints, bool locSortOnlyFlag) const
1180{
1181 //resolve links between vertex & time fits (decaying particles), and return sorted constraints
1182
1183 //if locSortOnlyFlag = true, then cut-out invalid vertex constraints, rather than returning false (done if false)
1184 locSortedConstraints.clear();
1185
1186 //build deque of DKinFitConstraint_VertexBase to sort through
1187 deque<DKinFitConstraint_VertexBase*> locVertexConstraintsToSort;
1188 for(size_t loc_i = 0; loc_i < locKinFitConstraints.size(); ++loc_i)
1189 {
1190 DKinFitConstraint_VertexBase* locKinFitConstraint_VertexBase = dynamic_cast<DKinFitConstraint_VertexBase*>(locKinFitConstraints[loc_i]);
1191 if(locKinFitConstraint_VertexBase != NULL__null)
1192 locVertexConstraintsToSort.push_back(locKinFitConstraint_VertexBase);
1193 }
1194
1195 //loop over vertex-constraints-to-sort:
1196 //find which constraints decaying particles should be defined-by/constrained-to
1197 //find order in which constraints need to be constrained
1198 deque<DKinFitConstraint_VertexBase*>::iterator locSortIterator = locVertexConstraintsToSort.begin();
1199 bool locProgessMadeFlag = false;
1200 bool locLastResortFlag = false;
1201 bool locInitPassFlag = true;
1202 while(true)
1203 {
1204 if(locVertexConstraintsToSort.empty())
1205 break; //all vertex constraints setup successfully
1206 if(locSortIterator == locVertexConstraintsToSort.end())
1207 {
1208 if((!locProgessMadeFlag) && (!locInitPassFlag))
1209 {
1210 if(locLastResortFlag)
1211 {
1212 if(!locSortOnlyFlag)
1213 cout << "ERROR: NOT ENOUGH PARTICLES TO CONSTRAIN VERTEX." << endl;
1214 //no progress made, and was on last resort: cannot constrain remaining vertices
1215 return locSortOnlyFlag; //this is ok if only sorting (skim remaining constraints), but bad if fit time
1216 }
1217 locLastResortFlag = true; //no progress, now on last resort
1218 }
1219 locInitPassFlag = false;
1220 locSortIterator = locVertexConstraintsToSort.begin();
1221 locProgessMadeFlag = false;
1222 continue;
1223 }
1224
1225 DKinFitConstraint_VertexBase* locConstraint = *locSortIterator;
1226 if(locConstraint->dFullConstrainParticles.size() < 2)
1227 {
1228 ++locSortIterator;
1229 continue;
1230 }
1231
1232 //for the init pass through all of the constraints, only accept constraints that don't have 2 decaying/missing particles
1233 //this way, any decaying particles at these vertices have p4's that are defined locally (instead of across many steps)
1234 if(locInitPassFlag)
1235 {
1236 size_t locNumMissingDecayingParticles = locConstraint->Get_DecayingParticles().size();
1237 for(size_t loc_i = 0; loc_i < locConstraint->dNoConstrainParticles.size(); ++loc_i)
1238 {
1239 if(locConstraint->dNoConstrainParticles[loc_i]->Get_KinFitParticleType() != d_MissingParticle)
1240 continue;
1241 ++locNumMissingDecayingParticles;
1242 break;
1243 }
1244 if(locNumMissingDecayingParticles >= 2)
1245 {
1246 ++locSortIterator;
1247 continue;
1248 }
1249 }
1250
1251 if((locConstraint->dDecayingParticlesToAssign.size() >= 2) && (!locLastResortFlag))
1252 {
1253 ++locSortIterator;
1254 continue; //constrain decaying particles with other constraints first, if at all possible (unless last resort!)
1255 }
1256
1257 //any remaining decaying particles can now be defined here (if not already), and added as constraints to their other vertex fits
1258 set<DKinFitParticle*>::iterator locIterator = locConstraint->dDecayingParticlesToAssign.begin();
1259 for(; locIterator != locConstraint->dDecayingParticlesToAssign.end(); ++locIterator)
1260 {
1261 DKinFitParticle* locParticle = *locIterator;
1262 if(locParticle->Get_DefinedAtVertexAndOrTimeConstraint() != NULL__null)
1263 continue; //already defined, meaning already added as a constraint previously as well
1264
1265 //set particle info
1266 locParticle->Set_Position(locConstraint->Get_CommonVertex());
1267 DKinFitConstraint_Spacetime* locSpacetimeConstraint = dynamic_cast<DKinFitConstraint_Spacetime*>(locConstraint);
1268 if(locSpacetimeConstraint != NULL__null)
1269 locParticle->Set_Time(locSpacetimeConstraint->Get_CommonTime());
1270
1271 //set whether it's defined at it the production vertex or decay vertex
1272 //note: if a decaying particle is not in a vertex fit, then this quantity doesn't matter
1273 bool locProductionVertexFlag = true; //bool is true if vertex is production vertex / particle in final state, false if decay vertex / initial state
1274 deque<pair<DKinFitParticle*, bool> > locDecayingParticles = locConstraint->dDecayingParticles;
1275 for(size_t loc_k = 0; loc_k < locDecayingParticles.size(); ++loc_k)
1276 {
1277 if(locDecayingParticles[loc_k].first != locParticle)
1278 continue;
1279 locProductionVertexFlag = locDecayingParticles[loc_k].second;
1280 break;
1281 }
1282 locParticle->Set_DecayingParticleAtProductionVertexFlag(locProductionVertexFlag);
1283
1284 //define it, add to constraints of other vertex fits
1285 locConstraint->Add_NoConstrainParticle(locParticle);
1286 deque<DKinFitConstraint_VertexBase*> locNewVertexConstraints = locParticle->dCommonVertexAndOrTimeConstraints;
1287 for(size_t loc_k = 0; loc_k < locNewVertexConstraints.size(); ++loc_k)
1288 {
1289 if(locNewVertexConstraints[loc_k] == locConstraint)
1290 continue;
1291 //in multiple vertex fits
1292 locNewVertexConstraints[loc_k]->Add_FullConstrainParticle(locParticle);
1293 locNewVertexConstraints[loc_k]->dDecayingParticlesToAssign.erase(locParticle);
1294 //make sure also in a p4 fit so its p4 is defined, else cannot constrain (if linked)
1295 if((!locParticle->Get_IsInP4FitFlag()) && dLinkVerticesFlag)
1296 {
1297 //unrecoverable, even if only-sorting: problem is with the p4 constraints
1298 cout << "ERROR in DKinFitter: Decaying particle constrained in a vertex or spacetime fit with unconstrained momentum!! Exiting." << endl;
1299 return false; //decaying but constrained in a vertex or spacetime fit with unconstrained momentum
1300 }
1301 }
1302 }
1303 locConstraint->dDecayingParticlesToAssign.clear();
1304 locSortedConstraints.push_back(*locSortIterator);
1305 locProgessMadeFlag = true;
1306 locLastResortFlag = false;
1307 locSortIterator = locVertexConstraintsToSort.erase(locSortIterator);
1308 }
1309
1310 return true;
1311}
1312
1313bool DKinFitter::Resolve_P4Constraints(const deque<DKinFitConstraint*>& locKinFitConstraints, bool locSortOnlyFlag) const
1314{
1315 deque<DKinFitConstraint_P4*> locP4Constraints;
1316 set<DKinFitParticle*> locParticlesInP4Constraints;
1317 for(size_t loc_i = 0; loc_i < locKinFitConstraints.size(); ++loc_i)
1318 {
1319 DKinFitConstraint_P4* locKinFitConstraint_P4 = dynamic_cast<DKinFitConstraint_P4*>(locKinFitConstraints[loc_i]);
1320 if(locKinFitConstraint_P4 == NULL__null)
1321 continue;
1322 locP4Constraints.push_back(locKinFitConstraint_P4);
1323
1324 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dInitialParticles.size(); ++loc_j)
1325 locParticlesInP4Constraints.insert(locKinFitConstraint_P4->dInitialParticles[loc_j]);
1326 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dFinalParticles.size(); ++loc_j)
1327 locParticlesInP4Constraints.insert(locKinFitConstraint_P4->dFinalParticles[loc_j]);
1328 }
1329
1330 //snag unconstrained particles
1331 deque<DKinFitParticle*> locUnconstrainedParticles;
1332 set<DKinFitParticle*>::iterator locIterator = locParticlesInP4Constraints.begin();
1333 for(; locIterator != locParticlesInP4Constraints.end(); ++locIterator)
1334 {
1335 DKinFitParticle* locKinFitParticle = *locIterator;
1336 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1337 //make sure there are no neutral showers used in p4 constraints that are not included in a vertex fit
1338 if(locKinFitParticle->Get_IsNeutralShowerFlag() && (!locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag()) && (!locSortOnlyFlag))
1339 {
1340 cout << "ERROR in DKinFitter: Detected neutral shower in a P4 fit but not in a vertex or spacetime fit: P3 is undefined!! Exiting." << endl;
1341 return false; //detected neutral shower in a p4 fit but not in a vertex fit: p3 is undefined!!
1342 }
1343 if((locKinFitParticleType != d_DecayingParticle) && (locKinFitParticleType != d_MissingParticle))
1344 continue;
1345 locUnconstrainedParticles.push_back(locKinFitParticle);
1346 }
1347
1348 //get p4 guesses for each decaying/missing particle
1349 //loop through the p4 constraints, find constraints which contain only one missing or decaying particle: used as starting point for assigning them to different constraints
1350 deque<pair<DKinFitParticle*, DKinFitConstraint_P4*> > locConstrainableParticles;
1351 deque<const DKinFitParticle*> locConstrainedParticles;
1352 while(locConstrainedParticles.size() < locUnconstrainedParticles.size())
1353 {
1354 if(locConstrainableParticles.empty())
1355 {
1356 if(!Find_ConstrainableParticles(locP4Constraints, locConstrainableParticles, locConstrainedParticles))
1357 return false; //more decaying/missing particles than constraints, or circular dependency: cannot fit
1358 }
1359
1360 while(!locConstrainableParticles.empty())
1361 {
1362 bool locAlreadyConstrainedFlag = false;
1363 //see if the particle is already constrained (e.g. constrainable in more than one constraint)
1364 for(size_t loc_j = 0; loc_j < locConstrainedParticles.size(); ++loc_j)
1365 {
1366 if(locConstrainableParticles.back().first != locConstrainedParticles[loc_j])
1367 continue;
1368 locAlreadyConstrainedFlag = true;
1369 break;
1370 }
1371 if(locAlreadyConstrainedFlag)
1372 {
1373 locConstrainableParticles.pop_back();
1374 continue;
1375 }
1376
1377 DKinFitParticle* locParticleToConstrain = locConstrainableParticles.back().first;
1378 DKinFitConstraint_P4* locKinFitConstraint_P4 = locConstrainableParticles.back().second;
1379 locKinFitConstraint_P4->Set_ConstrainedP4Particle(locParticleToConstrain);
1380 TLorentzVector locP4;
1381 Constrain_Particle(locParticleToConstrain, locKinFitConstraint_P4, locP4);
1382 locParticleToConstrain->Set_Momentum(locP4.Vect());
1383 if(locParticleToConstrain->Get_PID() == 0)
1384 locParticleToConstrain->Set_Mass(locP4.M());
1385 if(dDebugLevel > 5)
1386 {
1387 if(locParticleToConstrain->Get_DecayingParticleAtProductionVertexFlag())
1388 cout << "particle is defined at its production vertex (possibly constrained to its decay vertex)" << endl;
1389 else
1390 cout << "particle is defined at its decay vertex (possibly constrained to its production vertex)" << endl;
1391 }
1392
1393 //set vertex constraint flag if decaying particle & in 2 vertex fits
1394 if(locParticleToConstrain->Get_NumVertexFits() == 2)
1395 {
1396 unsigned short int locVertexConstraintFlag;
1397 if(fabs(locP4.Pz()) > fabs(locP4.Px()))
1398 locVertexConstraintFlag = (fabs(locP4.Pz()) > fabs(locP4.Py())) ? 1 : 2;
1399 else
1400 locVertexConstraintFlag = (fabs(locP4.Px()) > fabs(locP4.Py())) ? 3 : 2;
1401 locParticleToConstrain->Set_VertexConstraintFlag(locVertexConstraintFlag);
1402 }
1403
1404 locConstrainedParticles.push_back(locConstrainableParticles.back().first);
1405 locConstrainableParticles.pop_back();
1406 }
1407 }
1408
1409 return true;
1410}
1411
1412bool DKinFitter::Find_ConstrainableParticles(const deque<DKinFitConstraint_P4*>& locP4Constraints, deque<pair<DKinFitParticle*, DKinFitConstraint_P4*> >& locConstrainableParticles, const deque<const DKinFitParticle*>& locConstrainedParticles) const
1413{
1414 for(size_t loc_i = 0; loc_i < locP4Constraints.size(); ++loc_i)
1415 {
1416 if(locP4Constraints[loc_i]->dConstrainedP4Particle != NULL__null)
1417 continue; //constraint already set
1418 size_t locNumParticlesNeedToBeConstrained = 0;
1419 DKinFitParticle* locConstrainableParticle = NULL__null;
1420 deque<DKinFitParticle*> locTempParticles = locP4Constraints[loc_i]->dInitialParticles;
1421 for(size_t loc_j = 0; loc_j < locTempParticles.size(); ++loc_j)
1422 {
1423 DKinFitParticleType locKinFitParticleType = locTempParticles[loc_j]->Get_KinFitParticleType();
1424 if((locKinFitParticleType != d_DecayingParticle) && (locKinFitParticleType != d_MissingParticle))
1425 continue;
1426 bool locParticleAlreadyConstrainedFlag = false;
1427 for(size_t loc_k = 0; loc_k < locConstrainedParticles.size(); ++loc_k)
1428 {
1429 if(locConstrainedParticles[loc_k] != locTempParticles[loc_j])
1430 continue;
1431 locParticleAlreadyConstrainedFlag = true;
1432 break;
1433 }
1434 if(locParticleAlreadyConstrainedFlag)
1435 continue;
1436 ++locNumParticlesNeedToBeConstrained;
1437 locConstrainableParticle = locTempParticles[loc_j];
1438 }
1439 locTempParticles = locP4Constraints[loc_i]->dFinalParticles;
1440 for(size_t loc_j = 0; loc_j < locTempParticles.size(); ++loc_j)
1441 {
1442 DKinFitParticleType locKinFitParticleType = locTempParticles[loc_j]->Get_KinFitParticleType();
1443 if((locKinFitParticleType != d_DecayingParticle) && (locKinFitParticleType != d_MissingParticle))
1444 continue;
1445 bool locParticleAlreadyConstrainedFlag = false;
1446 for(size_t loc_k = 0; loc_k < locConstrainedParticles.size(); ++loc_k)
1447 {
1448 if(locConstrainedParticles[loc_k] != locTempParticles[loc_j])
1449 continue;
1450 locParticleAlreadyConstrainedFlag = true;
1451 break;
1452 }
1453 if(locParticleAlreadyConstrainedFlag)
1454 continue;
1455 ++locNumParticlesNeedToBeConstrained;
1456 locConstrainableParticle = locTempParticles[loc_j];
1457 }
1458 if(locNumParticlesNeedToBeConstrained == 1) //else too many unconstrained particles in it's step to be able to constrain it right away!!
1459 locConstrainableParticles.push_back(pair<DKinFitParticle*, DKinFitConstraint_P4*>(locConstrainableParticle, locP4Constraints[loc_i]));
1460 }
1461 return (!locConstrainableParticles.empty());
1462}
1463
1464void DKinFitter::Constrain_Particle(DKinFitParticle* locParticleToConstrain, DKinFitConstraint_P4* locConstraint, TLorentzVector& locP4) const
1465{
1466 if(dDebugLevel > 5)
1467 cout << "particle to constrain PID, q, mass = " << locParticleToConstrain->Get_PID() << ", " << locParticleToConstrain->Get_Charge() << ", " << locParticleToConstrain->Get_Mass() << endl;
1468
1469 locP4.SetXYZT(0.0, 0.0, 0.0, 0.0);
1470 bool locConstrainedParticleIsInInitialState = false;
1471 for(size_t loc_j = 0; loc_j < locConstraint->dInitialParticles.size(); ++loc_j)
1472 {
1473 DKinFitParticle* locKinFitParticle = locConstraint->dInitialParticles[loc_j];
1474 if(dDebugLevel > 20)
1475 cout << "init particle PID, q, mass = " << locKinFitParticle->Get_PID() << ", " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
1476 if(locKinFitParticle == locParticleToConstrain)
1477 locConstrainedParticleIsInInitialState = true;
1478 else
1479 locP4 += locKinFitParticle->Get_P4();
1480 }
1481 for(size_t loc_j = 0; loc_j < locConstraint->dFinalParticles.size(); ++loc_j)
1482 {
1483 DKinFitParticle* locKinFitParticle = locConstraint->dFinalParticles[loc_j];
1484 if(dDebugLevel > 20)
1485 cout << "final particle PID, q, mass = " << locKinFitParticle->Get_PID() << ", " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
1486 if(locKinFitParticle != locParticleToConstrain)
1487 locP4 -= locKinFitParticle->Get_P4();
1488 }
1489
1490 //set p3 guess
1491 if(locConstrainedParticleIsInInitialState)
1492 locP4 *= -1.0;
1493
1494 if(dDebugLevel > 5)
1495 cout << "particle to constrain: flag, pxyzE = " << locConstrainedParticleIsInInitialState << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locP4.E() << endl;
1496
1497 locConstraint->Set_ConstrainedParticleIsInInitialStateFlag(locConstrainedParticleIsInInitialState);
1498}
1499
1500bool DKinFitter::Resolve_P4MassConstraints(const deque<DKinFitConstraint*>& locKinFitConstraints, bool locSortOnlyFlag) const
1501{
1502 if(!Resolve_InclusiveP4(locKinFitConstraints))
1503 return false; //weird p4 constraints
1504
1505 //remove/return-false if mass + p4 constraints too over-constrain the system (will result in noninvertable matrices)
1506
1507 //first find "the" p4 constraint
1508 DKinFitConstraint_P4* locTheP4Constraint = NULL__null;
1509 for(size_t loc_i = 0; loc_i < locKinFitConstraints.size(); ++loc_i)
1510 {
1511 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locKinFitConstraints[loc_i]);
1512 if(locP4Constraint == NULL__null)
1513 continue;
1514 if(!locP4Constraint->Get_IsActualP4ConstraintFlag())
1515 continue;
1516 locTheP4Constraint = locP4Constraint;
1517 break;
1518 }
1519 if(locTheP4Constraint == NULL__null)
1520 return true; //inclusive fit: not a problem
1521 locTheP4Constraint->dConstrainMassFlag = false;
1522
1523 //ok, now loop over the p4 constraint: if it has a particle with non-zero cov matrix entries that is not in a p4 constraint, then we'll be OK
1524 for(size_t loc_i = 0; loc_i < locTheP4Constraint->dInitialParticles.size(); ++loc_i)
1525 {
1526 DKinFitParticle* locKinFitParticle = locTheP4Constraint->dInitialParticles[loc_i];
1527 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1528 if((locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_MissingParticle))
1529 continue;
1530 if(locKinFitParticle->Get_CovarianceMatrix() == NULL__null)
1531 continue;
1532 if(!(fabs((*locKinFitParticle->Get_CovarianceMatrix())(2, 2)) > 0.0))
1533 continue; //error on pz is zero
1534 return true; //have a particle in the p4 constraint with non-zero errors that is not in the mass constraint
1535 }
1536
1537 deque<DKinFitParticle*> locDecayingParticles;
1538 for(size_t loc_i = 0; loc_i < locTheP4Constraint->dFinalParticles.size(); ++loc_i)
1539 {
1540 DKinFitParticle* locKinFitParticle = locTheP4Constraint->dFinalParticles[loc_i];
1541 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1542 if(locKinFitParticleType == d_DecayingParticle)
1543 {
1544 locDecayingParticles.push_back(locKinFitParticle);
1545 continue;
1546 }
1547 if(locKinFitParticleType == d_MissingParticle)
1548 continue;
1549 if(locKinFitParticle->Get_CovarianceMatrix() == NULL__null)
1550 continue;
1551 if(!(fabs((*locKinFitParticle->Get_CovarianceMatrix())(2, 2)) > 0.0))
1552 continue; //error on pz is zero
1553 return true; //have a particle in the p4 constraint with non-zero errors that is not in the mass constraint
1554 }
1555
1556 if(locDecayingParticles.empty())
1557 return false; //not a single particle with non-zero errors available
1558
1559 //ok, we might have a problem: make sure that a mass constraint is NOT applied to at least one of the decaying particles
1560 for(size_t loc_i = 0; loc_i < locDecayingParticles.size(); ++loc_i)
1561 {
1562 const DKinFitConstraint_P4* locConstraintAsInitial = locDecayingParticles[loc_i]->Get_P4ConstraintWhenInitial();
1563 if(locConstraintAsInitial->dConstrainMassFlag)
1564 continue;
1565 return true; //a decaying particle does not have a mass constraint applied: we're ok
1566 }
1567
1568 //ok, this won't work. if only sorting, disable a mass constraint. else return false
1569 if(locSortOnlyFlag)
1570 {
1571 DKinFitConstraint_P4* locConstraintAsInitial = const_cast<DKinFitConstraint_P4*>(locDecayingParticles[0]->Get_P4ConstraintWhenInitial());
1572 locConstraintAsInitial->dConstrainMassFlag = false; //could disable any of them, but just choose this one
1573 if(dDebugLevel > 0)
1574 cout << "DKinFitter: System too over-constrained, removed mass constraint on PID = " << locDecayingParticles[0]->Get_PID() << endl;
1575 return true;
1576 }
1577
1578 cout << "ERROR: CANNOT APPLY OVERALL P4 CONSTRAINT AND THESE MASS CONSTRAINTS AT THE SAME TIME: SYSTEM IS TOO OVER-CONSTRAINED. RETURNING FALSE" << endl;
1579 return false;
1580}
1581
1582bool DKinFitter::Resolve_InclusiveP4(const deque<DKinFitConstraint*>& locKinFitConstraints) const
1583{
1584 //if is an inclusive fit, will mark mass constraints as missing if necessary
1585 //if not an inclusive fit, will mark which constraint is the actual p4 constraint
1586
1587 //see if there is a missing particle in a p4 constraint that has PID = 0
1588 DKinFitConstraint_P4* locInclusiveP4Constraint = NULL__null;
1589 bool locUnknownParentFoundFlag = false;
1590 for(size_t loc_i = 0; loc_i < locKinFitConstraints.size(); ++loc_i)
1591 {
1592 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locKinFitConstraints[loc_i]);
1593 if(locP4Constraint == NULL__null)
1594 continue;
1595
1596 for(size_t loc_i = 0; loc_i < locP4Constraint->dInitialParticles.size(); ++loc_i)
1597 {
1598 DKinFitParticle* locKinFitParticle = locP4Constraint->dInitialParticles[loc_i];
1599 if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
1600 continue;
1601 if(locKinFitParticle->Get_PID() == 0)
1602 {
1603 locUnknownParentFoundFlag = true;
1604 locInclusiveP4Constraint = locP4Constraint;
1605 if(dDebugLevel > 20)
1606 cout << "Decaying particle with unknown PID found: is inclusive-p4 fit." << endl;
1607 locInclusiveP4Constraint->dConstrainMassByInvariantMassFlag = false;
1608 }
1609 break;
1610 }
1611 if(locUnknownParentFoundFlag)
1612 break;
1613
1614 bool locMissingParticleFoundFlag = false;
1615 for(size_t loc_i = 0; loc_i < locP4Constraint->dFinalParticles.size(); ++loc_i)
1616 {
1617 DKinFitParticle* locKinFitParticle = locP4Constraint->dFinalParticles[loc_i];
1618 if(locKinFitParticle->Get_KinFitParticleType() != d_MissingParticle)
1619 continue;
1620 locMissingParticleFoundFlag = true;
1621 if(locKinFitParticle->Get_PID() == 0)
1622 {
1623 locInclusiveP4Constraint = locP4Constraint;
1624 //if constraining the mass of this initial particle, must do by missing mass (X is a decay product)
1625 if(dDebugLevel > 20)
1626 cout << "Missing particle with unknown PID found: is inclusive-p4 fit." << endl;
1627 locInclusiveP4Constraint->dConstrainMassByInvariantMassFlag = false;
1628 if(dDebugLevel > 5)
1629 cout << "p4 constraint with pid " << locInclusiveP4Constraint->dInitialParticles[0]->Get_PID() << " as parent marked as a missing-mass constraint (if mass constrained at all)" << endl;
1630 }
1631 break;
1632 }
1633 if(locMissingParticleFoundFlag)
1634 break;
1635 }
1636
1637 bool locAreP4ConstraintsFlag = false;
1638 for(size_t loc_i = 0; loc_i < locKinFitConstraints.size(); ++loc_i)
1639 {
1640 DKinFitConstraint_P4* locP4Constraint = dynamic_cast<DKinFitConstraint_P4*>(locKinFitConstraints[loc_i]);
1641 if(locP4Constraint == NULL__null)
1642 continue;
1643 locAreP4ConstraintsFlag = true;
1644 DKinFitParticle* locKinFitParticle = locP4Constraint->dInitialParticles[0];
1645 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1646 if((locKinFitParticleType == d_BeamParticle) || (locKinFitParticleType == d_DetectedParticle))
1647 {
1648 //initial particle is beam particle or detected (is actually a decaying particle treated as detected) particle: p4 constraint instead of mass constraint (if not inclusive)
1649 locP4Constraint->dConstrainMassFlag = false;
1650 if(locInclusiveP4Constraint == NULL__null)
1651 {
1652 if(dDebugLevel > 5)
1653 cout << "p4 constraint with pid " << locKinFitParticle->Get_PID() << " as parent marked as full-p4 constraint" << endl;
1654 locP4Constraint->dIsActualP4ConstraintFlag = true;
1655 return true; //is not inclusive: we're done
1656 }
1657 if(dDebugLevel > 5)
1658 cout << "p4 constraint with pid " << locKinFitParticle->Get_PID() << " as parent marked as no-mass constraint" << endl;
1659 }
1660 else if((locKinFitParticleType == d_DecayingParticle) && (locKinFitParticle->Get_NumP4Constraints() == 1))
1661 {
1662 //initial particle is open-ended decaying particle: p4 constraint instead of mass constraint (if not inclusive)
1663 locP4Constraint->dConstrainMassFlag = false;
1664 if(locInclusiveP4Constraint == NULL__null)
1665 {
1666 if(dDebugLevel > 5)
1667 cout << "p4 constraint with pid " << locKinFitParticle->Get_PID() << " as parent marked as full-p4 constraint" << endl;
1668 locP4Constraint->dIsActualP4ConstraintFlag = true;
1669 return true; //is not inclusive: we're done
1670 }
1671 if(dDebugLevel > 5)
1672 cout << "p4 constraint with pid " << locKinFitParticle->Get_PID() << " as parent marked as no-mass constraint" << endl;
1673 }
1674 else if((locInclusiveP4Constraint != NULL__null) && (!locUnknownParentFoundFlag)) //if unknown parent, all will be invariant mass constraints
1675 Mark_AsMissingMassConstraintIfNecessary(locP4Constraint);
1676 }
1677
1678 if(locInclusiveP4Constraint == NULL__null)
1679 return (!locAreP4ConstraintsFlag); //is not inclusive: if no p4 fit then bad
1680 return true;
1681}
1682
1683void DKinFitter::Mark_AsMissingMassConstraintIfNecessary(DKinFitConstraint_P4* locP4Constraint) const
1684{
1685 if(!locP4Constraint->Get_ConstrainMassByInvariantMassFlag())
1686 return; //already marked as missing mass constraint
1687
1688 for(size_t loc_i = 0; loc_i < locP4Constraint->dFinalParticles.size(); ++loc_i)
1689 {
1690 DKinFitParticle* locKinFitParticle = locP4Constraint->dFinalParticles[loc_i];
1691 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
1692 if(locKinFitParticleType != d_DecayingParticle)
1693 continue;
1694
1695 //decaying particle: dive to the next constraint
1696 deque<DKinFitConstraint_P4*> locP4Constraints = locKinFitParticle->dP4Constraints;
1697 for(size_t loc_j = 0; loc_j < locP4Constraints.size(); ++loc_j)
1698 {
1699 DKinFitConstraint_P4* locP4SubConstraint = locP4Constraints[loc_j];
1700 if(locP4SubConstraint == locP4Constraint)
1701 continue;
1702 if(!locP4SubConstraint->Get_ConstrainMassByInvariantMassFlag())
1703 {
1704 //this next constraint is already by missing mass because X is a decay product of it. therefore, this constraint must be by missing mass also
1705 locP4Constraint->dConstrainMassByInvariantMassFlag = false;
1706 if(dDebugLevel > 5)
1707 cout << "p4 constraint with pid " << locP4Constraint->dInitialParticles[0]->Get_PID() << " as parent marked as a missing-mass constraint" << endl;
1708 }
1709 else
1710 {
1711 Mark_AsMissingMassConstraintIfNecessary(locP4SubConstraint);
1712 if(!locP4SubConstraint->Get_ConstrainMassByInvariantMassFlag())
1713 {
1714 //this next constraint is already by missing mass because X is a decay product of it. therefore, this constraint must be by missing mass also
1715 locP4Constraint->dConstrainMassByInvariantMassFlag = false;
1716 if(dDebugLevel > 5)
1717 cout << "p4 constraint with pid " << locP4Constraint->dInitialParticles[0]->Get_PID() << " as parent marked as a missing-mass constraint" << endl;
1718 }
1719 }
1720 }
1721 }
1722}
1723
1724bool DKinFitter::Group_Constraints(const deque<DKinFitConstraint_VertexBase*>& locSortedVertexConstraints, deque<pair<DKinFitConstraint_VertexBase*, set<DKinFitConstraint_P4*> > >& locSortedConstraints) const
1725{
1726 //loop through the vertex constraints
1727 locSortedConstraints.clear();
1728 set<DKinFitConstraint_P4*> locHandledP4Constraints;
1729 for(size_t loc_i = 0; loc_i < locSortedVertexConstraints.size(); ++loc_i)
1730 {
1731 //find all p4 constraints that the constraining particles in this vertex constraint are constrained to
1732 //first get particles
1733 deque<const DKinFitParticle*> locConstrainParticles = locSortedVertexConstraints[loc_i]->Get_FullConstrainParticles();
1734 //if spacetime fit, get neutral showers as well
1735 DKinFitConstraint_Spacetime* locSpacetimeConstraint = dynamic_cast<DKinFitConstraint_Spacetime*>(locSortedVertexConstraints[loc_i]);
1736 if(locSpacetimeConstraint != NULL__null)
1737 {
1738 deque<const DKinFitParticle*> locTimeConstrainParticles = locSpacetimeConstraint->Get_OnlyConstrainTimeParticles();
1739 locConstrainParticles.insert(locConstrainParticles.end(), locTimeConstrainParticles.begin(), locTimeConstrainParticles.end());
1740 }
1741 //then get unhandled p4 constraints
1742 set<DKinFitConstraint_P4*> locP4Constraints;
1743 for(size_t loc_j = 0; loc_j < locConstrainParticles.size(); ++loc_j)
1744 {
1745 DKinFitConstraint_P4* locConstraint = const_cast<DKinFitConstraint_P4*>(locConstrainParticles[loc_j]->Get_ConstrainedAtP4Constraint());
1746 if(locConstraint != NULL__null)
1747 locP4Constraints.insert(locConstraint);
1748 }
1749 pair<DKinFitConstraint_VertexBase*, set<DKinFitConstraint_P4*> > locConstraintPair(locSortedVertexConstraints[loc_i], locP4Constraints);
1750 locSortedConstraints.push_back(locConstraintPair);
1751 }
1752
1753 return true;
1754}
1755
1756bool DKinFitter::Fit_Reaction(void)
1757{
1758#ifdef VTRACE
1759 VT_TRACER("DKinFitter::Fit_Reaction()");
1760#endif
1761 Clone_ConstraintsForFit();
1762
1763 if(!Resolve_Constraints())
1764 {
1765 dKinFitStatus = d_KinFitFailedSetup;
1766 return false;
1767 }
1768
1769 Register_ParticlesForFit();
1770 Set_MatrixSizes();
1771 Resize_Matrices();
1772 Fill_InputMatrices();
1773
1774 if(dDebugLevel > 20)
1775 {
1776 cout << "DKinFitter: dEta: " << endl;
1777 Print_Matrix(dEta);
1778 cout << "DKinFitter: dVY: " << endl;
1779 Print_Matrix(dVY);
1780 cout << "DKinFitter: dXi: " << endl;
1781 Print_Matrix(dXi);
1782 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
1783 Print_ParticleParams(dKinFitParticles[loc_i]);
1784 }
1785
1786 dChiSq = 9.9E99;
1787 double locPreviousChiSq = 0.0;
1788 int locNumIterations = -1;
1789 TMatrixD locR(dNumF, 1);
1790 do
1791 {
1792 ++locNumIterations;
1793 if(locNumIterations >= int(dMaxNumIterations))
1794 {
1795 //sometimes the chisq will walk (very slightly) forever, without any real meaningful change in the variables
1796 if(dDebugLevel > 10)
1797 cout << "DKinFitter: At maximum number of iterations, this chisq, last chisq, last resort cutoff = " << dChiSq << ", " << locPreviousChiSq << ", " << dConvergenceChiSqDiff_LastResort << endl;
1798 if((fabs(dChiSq - locPreviousChiSq) <= dConvergenceChiSqDiff_LastResort) && (dChiSq >= 0.0))
1799 break; //close enough
1800 if(dDebugLevel > 10)
1801 cout << "DKinFitter: Exceeded maximum number of iterations. Returning false." << endl;
1802 dKinFitStatus = d_KinFitTooManyIterations;
1803 return false; //diverging!
1804 }
1805
1806 locPreviousChiSq = dChiSq;
1807 if(dDebugLevel > 20)
1808 cout << "DKinFitter: Begin iteration" << endl;
1809
1810 Calc_dF();
1811 if(dDebugLevel > 20)
1812 {
1813 cout << "DKinFitter: dF: " << endl;
1814 Print_Matrix(dF);
1815 cout << "DKinFitter: dF_dXi: " << endl;
1816 Print_Matrix(dF_dXi);
1817 cout << "DKinFitter: dF_dEta: " << endl;
1818 Print_Matrix(dF_dEta);
1819 }
1820
1821 locR = dF + dF_dEta*(dY - dEta);
1822
1823 if(!Calc_dS())
1824 {
1825 if(dDebugLevel > 10)
1826 cout << "DKinFitter: Failed S-matrix inversion. Returning false." << endl;
1827 dKinFitStatus = d_KinFitFailedInversion;
1828 return false; // matrix is not invertible
1829 }
1830
1831 if(dNumXi > 0)
1832 {
1833 if(!Calc_dU())
1834 {
1835 if(dDebugLevel > 10)
1836 cout << "DKinFitter: Failed VXi-matrix inversion. Returning false." << endl;
1837 dKinFitStatus = d_KinFitFailedInversion;
1838 return false; // matrix is not invertible
1839 }
1840
1841 TMatrixD locDeltaXi(dNumXi, 1);
1842 locDeltaXi = -1.0*dU*dF_dXi_T*dS_Inverse*locR;
1843
1844 if(dDebugLevel > 20)
1845 {
1846 cout << "DKinFitter: locDeltaXi: " << endl;
1847 Print_Matrix(locDeltaXi);
1848 }
1849
1850 dXi += locDeltaXi;
1851 if(dDebugLevel > 20)
1852 {
1853 cout << "DKinFitter: dXi: " << endl;
1854 Print_Matrix(dXi);
1855 }
1856
1857 dLambda = dS_Inverse*(locR + dF_dXi*locDeltaXi);
1858 }
1859 else
1860 {
1861 dLambda = dS_Inverse*locR;
1862 }
1863
1864 dLambda_T.Transpose(dLambda);
1865
1866 if(dDebugLevel > 20)
1867 {
1868 cout << "DKinFitter: dLambda: " << endl;
1869 Print_Matrix(dLambda);
1870 }
1871
1872 dEta = dY - dVY*dF_dEta_T*dLambda;
1873 if(dDebugLevel > 20)
1874 {
1875 cout << "DKinFitter: dEta: " << endl;
1876 Print_Matrix(dEta);
1877 }
1878
1879 TMatrixDSym locTempMatrix5 = dS;
1880 dChiSq = (locTempMatrix5.SimilarityT(dLambda) + 2.0*dLambda_T*dF)(0, 0);
1881
1882 if(dDebugLevel > 20)
1883 cout << "DKinFitter: dChiSq = " << dChiSq << endl;
1884
1885 Update_ParticleParams(); //input eta & xi info into particle objects
1886 if(dDebugLevel > 20)
1887 {
1888 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
1889 Print_ParticleParams(dKinFitParticles[loc_i]);
1890 }
1891 }
1892 while((fabs(dChiSq - locPreviousChiSq) > dConvergenceChiSqDiff) || (dChiSq < 0.0));
1893
1894 // dVXi
1895 if(dNumXi > 0)
1896 *dVXi = dU;
1897
1898 // dVEta & dV
1899 TMatrixDSym locG = dS_Inverse;
1900 locG.SimilarityT(dF_dEta);
1901 if(dNumXi > 0)
1902 {
1903 TMatrixD locH = dF_dEta_T*dS_Inverse*dF_dXi;
1904 TMatrixDSym locTempMatrix11 = *dVXi;
1905 *dVEta = dVY - (locG - locTempMatrix11.Similarity(locH)).Similarity(dVY);
1906
1907 //dV:
1908 TMatrixD locEtaXiCovariance = -1.0*dVY*locH*dU;
1909 for(unsigned int loc_i = 0; loc_i < dNumEta; ++loc_i)
1910 {
1911 for(unsigned int loc_j = 0; loc_j < dNumEta; ++loc_j)
1912 (*dV)(loc_i, loc_j) = (*dVEta)(loc_i, loc_j);
1913 }
1914 for(unsigned int loc_i = 0; loc_i < dNumXi; ++loc_i)
1915 {
1916 for(unsigned int loc_j = 0; loc_j < dNumXi; ++loc_j)
1917 (*dV)(loc_i + dNumEta, loc_j + dNumEta) = (*dVXi)(loc_i, loc_j);
1918 }
1919 for(unsigned int loc_i = 0; loc_i < dNumEta; ++loc_i)
1920 {
1921 for(unsigned int loc_j = 0; loc_j < dNumXi; ++loc_j)
1922 {
1923 (*dV)(loc_i, loc_j + dNumEta) = locEtaXiCovariance(loc_i, loc_j);
1924 (*dV)(loc_j + dNumEta, loc_i) = locEtaXiCovariance(loc_i, loc_j);
1925 }
1926 }
1927 }
1928 else
1929 {
1930 *dVEta = dVY - locG.Similarity(dVY); //destroys locG, but it's not needed anymore
1931 *dV = *dVEta;
1932 }
1933
1934 dEpsilon = dY - dEta;
1935
1936 Calc_Pulls();
1937 dNDF = dNumF - dNumXi;
1938 dConfidenceLevel = TMath::Prob(dChiSq, dNDF);
1939
1940 Set_FinalTrackInfo();
1941
1942 if(dDebugLevel > 5)
1943 cout << "DKinFitter: Final dChiSq, dNDF, dConfidenceLevel = " << dChiSq << ", " << dNDF << ", " << dConfidenceLevel << endl;
1944
1945 dKinFitStatus = d_KinFitSuccessful;
1946 return true;
1947}
1948
1949bool DKinFitter::Calc_dS(void)
1950{
1951 TMatrixDSym locTempMatrix = dVY;
1952 locTempMatrix.Similarity(dF_dEta);
1953 dS = locTempMatrix;
1954 if(dDebugLevel > 20)
1955 {
1956 cout << "DKinFitter: dS: " << endl;
1957 Print_Matrix(dS);
1958 cout << "determinant magnitude = " << fabs(dS.Determinant()) << endl;
1959 }
1960 TDecompLU locDecompLU_S(dS);
1961 //check to make sure that the matrix is decomposable and has a non-zero determinant
1962 if((!locDecompLU_S.Decompose()) || (fabs(dS.Determinant()) < 1.0E-300))
1963 {
1964 if(dDebugLevel > 10)
1965 cout << "DKinFitter: dS not invertible. Returning false." << endl;
1966 return false; // matrix is not invertible
1967 }
1968 dS_Inverse = dS;
1969 dS_Inverse.Invert();
1970 if(dDebugLevel > 20)
1971 {
1972 cout << "DKinFitter: dS_Inverse: " << endl;
1973 Print_Matrix(dS_Inverse);
1974 }
1975
1976 return true;
1977}
1978
1979bool DKinFitter::Calc_dU(void)
1980{
1981 TMatrixDSym locTempMatrix = dS_Inverse;
1982 locTempMatrix.SimilarityT(dF_dXi);
1983 dU_Inverse = locTempMatrix;
1984 if(dDebugLevel > 20)
1985 {
1986 cout << "DKinFitter: dU_Inverse: " << endl;
1987 Print_Matrix(dU_Inverse);
1988 cout << "determinant magnitude = " << fabs(dU_Inverse.Determinant()) << endl;
1989 }
1990 TDecompLU locDecompLU_VXiInv(dU_Inverse);
1991 //check to make sure that the matrix is decomposable and has a non-zero determinant
1992 if((!locDecompLU_VXiInv.Decompose()) || (fabs(dU_Inverse.Determinant()) < 1.0E-300))
1993 {
1994 if(dDebugLevel > 10)
1995 cout << "DKinFitter: dU_Inverse not invertible. Returning false." << endl;
1996 return false; // matrix is not invertible
1997 }
1998 dU = dU_Inverse;
1999 dU.Invert();
2000 if(dDebugLevel > 20)
2001 {
2002 cout << "DKinFitter: dU: " << endl;
2003 Print_Matrix(dU);
2004 }
2005 return true;
2006}
2007
2008void DKinFitter::Print_Matrix(const TMatrixD& locMatrix) const
2009{
2010 for(int loc_i = 0; loc_i < locMatrix.GetNrows(); ++loc_i)
2011 {
2012 for(int loc_j = 0; loc_j < locMatrix.GetNcols(); ++loc_j)
2013 cout << locMatrix(loc_i, loc_j) << ", ";
2014 cout << endl;
2015 }
2016}
2017
2018void DKinFitter::Print_ParticleParams(const DKinFitParticle* locKinFitParticle) const
2019{
2020 int locCharge = locKinFitParticle->Get_Charge();
2021 double locMass = locKinFitParticle->Get_Mass();
2022 TLorentzVector locP4 = locKinFitParticle->Get_P4();
2023 TLorentzVector locSpacetimeVertex = locKinFitParticle->Get_SpacetimeVertex();
2024 const TMatrixDSym* locCovarianceMatrix = locKinFitParticle->Get_CovarianceMatrix();
2025 cout << "DKinFitter: Particle Type Enum: " << locKinFitParticle->Get_KinFitParticleType() << endl;
2026 cout << "DKinFitter: Particle PID, Q, Mass, E, P3, V3, T = " << locKinFitParticle->Get_PID() << ", " << locCharge << ", " << locMass << ", " << locP4.E() << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
2027 if(locCovarianceMatrix != NULL__null)
2028 {
2029 cout << "DKinFitter: CovMatrix Diagonal Terms: ";
2030 for(int loc_i = 0; loc_i < locCovarianceMatrix->GetNcols(); ++loc_i)
2031 cout << (*locCovarianceMatrix)(loc_i, loc_i) << ", ";
2032 cout << endl;
2033 }
2034 cout << "DKinFitter: Particle E, Px, Vx, Common Vx, T, Common T, L indices = " << locKinFitParticle->Get_EParamIndex() << ", " << locKinFitParticle->Get_PxParamIndex() << ", " << locKinFitParticle->Get_VxParamIndex() << ", " << locKinFitParticle->Get_CommonVxParamIndex() << ", " << locKinFitParticle->Get_TParamIndex() << ", " << locKinFitParticle->Get_CommonTParamIndex() << ", " << locKinFitParticle->Get_LParamIndex() << endl;
2035 cout << "DKinFitter: Particle CovMatrix E, Px, Vx, T indices = " << locKinFitParticle->Get_CovMatrixEParamIndex() << ", " << locKinFitParticle->Get_CovMatrixPxParamIndex() << ", " << locKinFitParticle->Get_CovMatrixVxParamIndex() << ", " << locKinFitParticle->Get_CovMatrixTParamIndex() << endl;
2036}
2037
2038void DKinFitter::Clone_ConstraintsForFit(void)
2039{
2040 deque<DKinFitConstraint*> locClonedConstraints;
2041 Clone_Constraints(dKinFitConstraints, locClonedConstraints);
2042 dKinFitConstraints = locClonedConstraints;
2043}
2044
2045void DKinFitter::Register_ParticlesForFit(void)
2046{
2047 set<const DKinFitParticle*> locAllKinFitParticles;
2048 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
2049 {
2050 set<const DKinFitParticle*> locConstraintKinFitParticles;
2051 dKinFitConstraints[loc_i]->Get_AllKinFitParticles(locConstraintKinFitParticles);
2052 locAllKinFitParticles.insert(locConstraintKinFitParticles.begin(), locConstraintKinFitParticles.end());
2053 }
2054
2055 set<const DKinFitParticle*>::iterator locIterator = locAllKinFitParticles.begin();
2056 for(; locIterator != locAllKinFitParticles.end(); ++locIterator)
2057 dKinFitParticles.push_back(const_cast<DKinFitParticle*>(*locIterator));
2058}
2059
2060void DKinFitter::Set_MatrixSizes(void)
2061{
2062 //set matrix sizes
2063 dNumXi = 0; //num unknowns
2064 dNumEta = 0; //num measurables
2065 dNumF = 0; //num constraint eqs
2066
2067 //Calculate dNumEta
2068 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
2069 {
2070 DKinFitParticle* locKinFitParticle = dKinFitParticles[loc_i];
2071 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2072 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_TargetParticle))
2073 continue;
2074
2075 if(!locKinFitParticle->Get_IsNeutralShowerFlag())
2076 {
2077 if((locKinFitParticle->Get_IsInP4FitFlag()) || (locKinFitParticle->Get_ConstrainedAtVertexAndOrTimeConstraint() != NULL__null))
2078 dNumEta += 3; //p3
2079 if(locKinFitParticle->Get_ConstrainedAtVertexAndOrTimeConstraint() != NULL__null)
2080 dNumEta += 3; //v3
2081 }
2082 else //neutral shower
2083 {
2084 if((locKinFitParticle->Get_IsInP4FitFlag()) && (locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag()))
2085 dNumEta += 4; //E + v3 (p4 fit needs p3, which is derived from v3 + kinfit vertex)
2086 }
2087 if(locKinFitParticle->Get_IsInSpacetimeFitFlag())
2088 ++dNumEta; //t
2089 }
2090 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i) //check if RF time
2091 {
2092 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2093 if(locKinFitConstraint_Spacetime == NULL__null)
2094 continue;
2095 if((dRFMatchedBeamParticle != NULL__null) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
2096 ++dNumEta; //RF t
2097 }
2098
2099 //Calculate dNumXi and dNumF
2100 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
2101 {
2102 DKinFitConstraint_P4* locKinFitConstraint_P4 = dynamic_cast<DKinFitConstraint_P4*>(dKinFitConstraints[loc_i]);
2103 if(locKinFitConstraint_P4 != NULL__null)
2104 {
2105 if(locKinFitConstraint_P4->Get_IsActualP4ConstraintFlag())
2106 dNumF += 4; //p4 constraint
2107 else if(locKinFitConstraint_P4->Get_ConstrainInitialParticleMassFlag())
2108 dNumF += 1; //mass constraint
2109
2110 deque<DKinFitParticle*> locInitialParticles = locKinFitConstraint_P4->dInitialParticles;
2111 deque<DKinFitParticle*> locFinalParticles = locKinFitConstraint_P4->dFinalParticles;
2112 for(size_t loc_j = 0; loc_j < locInitialParticles.size(); ++loc_j)
2113 {
2114 DKinFitParticleType locKinFitParticleType = locInitialParticles[loc_j]->Get_KinFitParticleType();
2115 if((locKinFitParticleType == d_DecayingParticle) && (locInitialParticles[loc_j]->Get_NumP4Constraints() == 1))
2116 {
2117 dNumXi += 3; //p3 //decaying particle included in only one p4 constraint
2118 break;
2119 }
2120 }
2121 for(size_t loc_j = 0; loc_j < locFinalParticles.size(); ++loc_j)
2122 {
2123 DKinFitParticleType locKinFitParticleType = locFinalParticles[loc_j]->Get_KinFitParticleType();
2124 if(((locKinFitParticleType == d_MissingParticle) && (locFinalParticles[loc_j]->Get_PID() != 0)) || ((locKinFitParticleType == d_DecayingParticle) && (locFinalParticles[loc_j]->Get_NumP4Constraints() == 1)))
2125 {
2126 dNumXi += 3; //p3 //missing particle or decaying particle included in only one p4 constraint
2127 break;
2128 }
2129 }
2130 continue;
2131 }
2132 DKinFitConstraint_Vertex* locKinFitConstraint_Vertex = dynamic_cast<DKinFitConstraint_Vertex*>(dKinFitConstraints[loc_i]);
2133 if(locKinFitConstraint_Vertex != NULL__null)
2134 {
2135 dNumXi += 3; //v3
2136 dNumF += 2*locKinFitConstraint_Vertex->dFullConstrainParticles.size();
2137 if(dDebugLevel > 10)
2138 {
2139 cout << "q's, masses of vertex constraining particles: ";
2140 for(size_t loc_j = 0; loc_j < locKinFitConstraint_Vertex->dFullConstrainParticles.size(); ++loc_j)
2141 cout << locKinFitConstraint_Vertex->dFullConstrainParticles[loc_j]->Get_Charge() << ", " << locKinFitConstraint_Vertex->dFullConstrainParticles[loc_j]->Get_Mass() << "; ";
2142 cout << endl;
2143 }
2144 continue;
2145 }
2146 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2147 if(locKinFitConstraint_Spacetime != NULL__null)
2148 {
2149 dNumXi += 4; //v3, t
2150 deque<DKinFitParticle*> locFullConstrainParticles = locKinFitConstraint_Spacetime->dFullConstrainParticles;
2151 for(size_t loc_j = 0; loc_j < locFullConstrainParticles.size(); ++loc_j)
2152 dNumF += 3;
2153 if(dDebugLevel > 10)
2154 {
2155 cout << "q's, masses of spacetime vertex constraining particles: ";
2156 for(size_t loc_j = 0; loc_j < locFullConstrainParticles.size(); ++loc_j)
2157 cout << locFullConstrainParticles[loc_j]->Get_Charge() << ", " << locFullConstrainParticles[loc_j]->Get_Mass() << ";";
2158 cout << endl;
2159 }
2160 if(Get_IsBFieldNearBeamline())
2161 {
2162 size_t locNumChargedConstraintParticles = 0;
2163 size_t locNumDecayingChargedConstraintParticles = 0;
2164 for(size_t loc_j = 0; loc_j < locFullConstrainParticles.size(); ++loc_j)
2165 {
2166 if(locFullConstrainParticles[loc_j]->Get_Charge() == 0)
2167 continue;
2168 ++locNumChargedConstraintParticles;
2169 if(locFullConstrainParticles[loc_j]->Get_KinFitParticleType() == d_DecayingParticle)
2170 ++locNumDecayingChargedConstraintParticles;
2171 }
2172 dNumXi += locNumChargedConstraintParticles; //path length (l) for each accelerating particle
2173 dNumF += locNumChargedConstraintParticles; //extra constraint due to extra unknown (path length (l) for each accelerating particle)
2174 }
2175 dNumF += locKinFitConstraint_Spacetime->dOnlyConstrainTimeParticles.size(); //for each neutral shower
2176 if((dRFMatchedBeamParticle != NULL__null) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
2177 ++dNumF;
2178 }
2179 }
2180
2181 if(dDebugLevel > 10)
2182 cout << "DKinFitter: Num measurables, unknowns, constraints = " << dNumEta << ", " << dNumXi << ", " << dNumF << endl;
2183}
2184
2185void DKinFitter::Resize_Matrices(void)
2186{
2187 if(dF.GetNrows() != static_cast<int>(dNumF))
2188 {
2189 dF.ResizeTo(dNumF, 1);
2190 dS.ResizeTo(dNumF, dNumF);
2191 dS_Inverse.ResizeTo(dNumF, dNumF);
2192 dLambda.ResizeTo(dNumF, 1);
2193 dLambda_T.ResizeTo(1, dNumF);
2194 dF_dEta.ResizeTo(dNumF, dNumEta);
2195 dF_dEta_T.ResizeTo(dNumEta, dNumF);
2196 dF_dXi.ResizeTo(dNumF, dNumXi);
2197 dF_dXi_T.ResizeTo(dNumXi, dNumF);
2198 }
2199 else
2200 {
2201 if(dF_dEta.GetNcols() != static_cast<int>(dNumEta))
2202 {
2203 dF_dEta.ResizeTo(dNumF, dNumEta);
2204 dF_dEta_T.ResizeTo(dNumEta, dNumF);
2205 }
2206 if(dF_dXi.GetNcols() != static_cast<int>(dNumXi))
2207 {
2208 dF_dXi.ResizeTo(dNumF, dNumXi);
2209 dF_dXi_T.ResizeTo(dNumXi, dNumF);
2210 }
2211 }
2212
2213 if(dY.GetNrows() != static_cast<int>(dNumEta))
2214 {
2215 dY.ResizeTo(dNumEta, 1);
2216 dEta.ResizeTo(dNumEta, 1);
2217 dEpsilon.ResizeTo(dNumEta, 1);
2218 dVY.ResizeTo(dNumEta, dNumEta);
2219 }
2220 dVEta->ResizeTo(dNumEta, dNumEta);
2221
2222 if(dXi.GetNrows() != static_cast<int>(dNumXi))
2223 {
2224 dXi.ResizeTo(dNumXi, 1);
2225 dU.ResizeTo(dNumXi, dNumXi);
2226 dU_Inverse.ResizeTo(dNumXi, dNumXi);
2227 }
2228 dVXi->ResizeTo(dNumXi, dNumXi);
2229
2230 dV->ResizeTo(dNumEta + dNumXi, dNumEta + dNumXi);
2231
2232 Zero_Matrices(); //zeroes all class matrices
2233}
2234
2235void DKinFitter::Zero_Matrices(void)
2236{
2237 dXi.Zero();
2238 dEta.Zero();
2239 dY.Zero();
2240 dVY.Zero();
2241 dF.Zero();
2242 dEpsilon.Zero();
2243
2244 dLambda.Zero();
2245 dLambda_T.Zero();
2246 dF_dEta.Zero();
2247 dF_dEta_T.Zero();
2248 dF_dXi.Zero();
2249 dF_dXi_T.Zero();
2250
2251 dS.Zero();
2252 dS_Inverse.Zero();
2253 dU.Zero();
2254 dU_Inverse.Zero();
2255
2256 dVXi->Zero();
2257 dVEta->Zero();
2258 dV->Zero();
2259}
2260
2261void DKinFitter::Fill_InputMatrices(void)
2262{
2263 //fill dY, dEta, dVY, dXi
2264
2265 DKinFitParticle* locKinFitParticle;
2266 DKinFitParticleType locKinFitParticleType;
2267 int locParamIndex, locConstraintIndex_Eta, locConstraintIndex_Xi;
2268 TVector3 locMomentum, locPosition;
2269
2270 //SETUP dY
2271 locParamIndex = 0;
2272 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
2273 {
2274 locKinFitParticle = dKinFitParticles[loc_i];
2275 locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2276
2277 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_TargetParticle))
2278 continue;
2279
2280 locMomentum = locKinFitParticle->Get_Momentum();
2281 locPosition = locKinFitParticle->Get_Position();
2282
2283 if(!locKinFitParticle->Get_IsNeutralShowerFlag()) //non-neutral shower
2284 {
2285 if((locKinFitParticle->Get_IsInP4FitFlag()) || (locKinFitParticle->Get_ConstrainedAtVertexAndOrTimeConstraint() != NULL__null)) //p3
2286 {
2287 locKinFitParticle->Set_PxParamIndex(locParamIndex);
2288 dY(locParamIndex, 0) = locMomentum.Px();
2289 dY(locParamIndex + 1, 0) = locMomentum.Py();
2290 dY(locParamIndex + 2, 0) = locMomentum.Pz();
2291 locParamIndex += 3;
2292 }
2293 if(locKinFitParticle->Get_ConstrainedAtVertexAndOrTimeConstraint() != NULL__null)
2294 {
2295 locKinFitParticle->Set_VxParamIndex(locParamIndex);
2296 dY(locParamIndex, 0) = locPosition.Px();
2297 dY(locParamIndex + 1, 0) = locPosition.Py();
2298 dY(locParamIndex + 2, 0) = locPosition.Pz();
2299 locParamIndex += 3;
2300 }
2301 }
2302 else //neutral shower
2303 {
2304 if((locKinFitParticle->Get_IsInP4FitFlag()) && (locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag()))
2305 {
2306 //E + v3 (p4 fit needs p3, which is derived from v3 + kinfit vertex)
2307 locKinFitParticle->Set_EParamIndex(locParamIndex);
2308 dY(locParamIndex, 0) = locKinFitParticle->Get_ShowerEnergy();
2309 ++locParamIndex;
2310
2311 locKinFitParticle->Set_VxParamIndex(locParamIndex);
2312 dY(locParamIndex, 0) = locPosition.Px();
2313 dY(locParamIndex + 1, 0) = locPosition.Py();
2314 dY(locParamIndex + 2, 0) = locPosition.Pz();
2315 locParamIndex += 3;
2316 }
2317 }
2318
2319 if(locKinFitParticle->Get_IsInSpacetimeFitFlag())
2320 {
2321 locKinFitParticle->Set_TParamIndex(locParamIndex);
2322 dY(locParamIndex, 0) = locKinFitParticle->Get_Time();
2323 ++locParamIndex;
2324 }
2325 }
2326 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i) //set RF time
2327 {
2328 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2329 if(locKinFitConstraint_Spacetime == NULL__null)
2330 continue;
2331 if((dRFMatchedBeamParticle != NULL__null) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
2332 {
2333 dRFTimeParamIndex = locParamIndex;
2334 dY(locParamIndex, 0) = dRFTime;
2335 ++locParamIndex;
2336 }
2337 }
2338
2339 //SETUP dEta
2340 dEta = dY; //use measurements as first guess
2341
2342 //SETUP dXi (with initial guesses) and constraint equation indices
2343 locParamIndex = 0;
2344 locConstraintIndex_Eta = 0;
2345 locConstraintIndex_Xi = 0;
2346 deque<DKinFitParticle*> locNoConstrainParticles;
2347 deque<DKinFitParticle*> locConstrainParticles;
2348 bool locRFTimeConstrainedFlag = false;
2349
2350 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
2351 {
2352 DKinFitConstraint_P4* locKinFitConstraint_P4 = dynamic_cast<DKinFitConstraint_P4*>(dKinFitConstraints[loc_i]);
2353 if(locKinFitConstraint_P4 != NULL__null)
2354 {
2355 locKinFitConstraint_P4->Set_FIndex(locConstraintIndex_Eta);
2356
2357 if(locKinFitConstraint_P4->Get_IsActualP4ConstraintFlag())
2358 locConstraintIndex_Eta += 4; //p4
2359 else if(locKinFitConstraint_P4->Get_ConstrainInitialParticleMassFlag())
2360 locConstraintIndex_Eta += 1; //mass
2361 else
2362 locKinFitConstraint_P4->Set_FIndex(-1);
2363
2364 DKinFitParticle* locConstrainedKinFitParticle = locKinFitConstraint_P4->dConstrainedP4Particle;
2365 if(locConstrainedKinFitParticle == NULL__null)
2366 continue; //no missing particles or no unknown p3 (p3 is derivable from known p3's (p4 constraint already applied elsewhere))
2367 DKinFitParticleType locKinFitParticleType = locConstrainedKinFitParticle->Get_KinFitParticleType();
2368 if(((locKinFitParticleType == d_MissingParticle) && (locConstrainedKinFitParticle->Get_PID() != 0)) || ((locKinFitParticleType == d_DecayingParticle) && (locConstrainedKinFitParticle->Get_NumP4Constraints() == 1)))
2369 {
2370 //set initial p3 guess
2371 TVector3 locMomentum = locConstrainedKinFitParticle->Get_Momentum();
2372 dXi(locParamIndex, 0) = locMomentum.Px();
2373 dXi(locParamIndex + 1, 0) = locMomentum.Py();
2374 dXi(locParamIndex + 2, 0) = locMomentum.Pz();
2375 locConstrainedKinFitParticle->Set_PxParamIndex(locParamIndex);
2376 locParamIndex += 3;
2377 }
2378 continue;
2379 }
2380 DKinFitConstraint_Vertex* locKinFitConstraint_Vertex = dynamic_cast<DKinFitConstraint_Vertex*>(dKinFitConstraints[loc_i]);
2381 if(locKinFitConstraint_Vertex != NULL__null)
2382 {
2383 locPosition = locKinFitConstraint_Vertex->Get_CommonVertex();
2384 dXi(locParamIndex, 0) = locPosition.X();
2385 dXi(locParamIndex + 1, 0) = locPosition.Y();
2386 dXi(locParamIndex + 2, 0) = locPosition.Z();
2387 locKinFitConstraint_Vertex->Set_VxParamIndex(locParamIndex);
2388 locNoConstrainParticles = locKinFitConstraint_Vertex->dNoConstrainParticles;
2389 for(size_t loc_j = 0; loc_j < locNoConstrainParticles.size(); ++loc_j)
2390 {
2391 if((locNoConstrainParticles[loc_j]->Get_KinFitParticleType() == d_MissingParticle) || (locNoConstrainParticles[loc_j]->Get_KinFitParticleType() == d_DecayingParticle))
2392 locNoConstrainParticles[loc_j]->Set_VxParamIndex(locParamIndex); //not included in fit, but particle vertex is defined by the fit result
2393 }
2394 locParamIndex += 3;
2395 locConstrainParticles = locKinFitConstraint_Vertex->dFullConstrainParticles;
2396 for(size_t loc_j = 0; loc_j < locConstrainParticles.size(); ++loc_j)
2397 {
2398 locKinFitConstraint_Vertex->Set_FIndex(locConstrainParticles[loc_j], locConstraintIndex_Eta);
2399 locConstraintIndex_Eta += 2;
2400 }
2401 continue;
2402 }
2403 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2404 if(locKinFitConstraint_Spacetime != NULL__null)
2405 {
2406 locPosition = locKinFitConstraint_Spacetime->Get_CommonVertex();
2407 dXi(locParamIndex, 0) = locPosition.X();
2408 dXi(locParamIndex + 1, 0) = locPosition.Y();
2409 dXi(locParamIndex + 2, 0) = locPosition.Z();
2410 dXi(locParamIndex + 3, 0) = locKinFitConstraint_Spacetime->Get_CommonTime();
2411 locKinFitConstraint_Spacetime->Set_VxParamIndex(locParamIndex);
2412 locKinFitConstraint_Spacetime->Set_TParamIndex(locParamIndex + 3);
2413
2414 locNoConstrainParticles = locKinFitConstraint_Spacetime->dNoConstrainParticles;
2415 for(size_t loc_j = 0; loc_j < locNoConstrainParticles.size(); ++loc_j)
2416 {
2417 if((locNoConstrainParticles[loc_j]->Get_KinFitParticleType() != d_MissingParticle) && (locNoConstrainParticles[loc_j]->Get_KinFitParticleType() != d_DecayingParticle))
2418 continue;
2419 locNoConstrainParticles[loc_j]->Set_VxParamIndex(locParamIndex); //not included in fit, but particle vertex is defined by the fit result
2420 locNoConstrainParticles[loc_j]->Set_TParamIndex(locParamIndex + 3); //not included in fit, but particle time is defined by the fit result
2421 }
2422 locParamIndex += 4;
2423
2424 locConstrainParticles = locKinFitConstraint_Spacetime->dFullConstrainParticles;
2425 for(size_t loc_j = 0; loc_j < locConstrainParticles.size(); ++loc_j)
2426 {
2427 if(locConstrainParticles[loc_j]->Get_KinFitParticleType() == d_DecayingParticle)
2428 {
2429 locKinFitConstraint_Spacetime->Set_FIndex(locConstrainParticles[loc_j], locConstraintIndex_Xi);
2430 locConstraintIndex_Xi += 3;
2431 }
2432 else
2433 {
2434 locKinFitConstraint_Spacetime->Set_FIndex(locConstrainParticles[loc_j], locConstraintIndex_Eta);
2435 locConstraintIndex_Eta += 3;
2436 }
2437 }
2438
2439 if(Get_IsBFieldNearBeamline())
2440 {
2441 for(size_t loc_j = 0; loc_j < locConstrainParticles.size(); ++loc_j)
2442 {
2443 if(locConstrainParticles[loc_j]->Get_Charge() == 0)
2444 continue;
2445 locConstrainParticles[loc_j]->Set_LParamIndex(locParamIndex);
2446 dXi(locParamIndex, 0) = locConstrainParticles[loc_j]->Get_PathLength();
2447 ++locParamIndex;
2448 if(locConstrainParticles[loc_j]->Get_KinFitParticleType() == d_DecayingParticle)
2449 ++locConstraintIndex_Xi;
2450 else
2451 ++locConstraintIndex_Eta;
2452 }
2453 }
2454 locConstrainParticles = locKinFitConstraint_Spacetime->dOnlyConstrainTimeParticles;
2455 for(size_t loc_j = 0; loc_j < locConstrainParticles.size(); ++loc_j) //neutral showers
2456 {
2457 locKinFitConstraint_Spacetime->Set_FIndex(locConstrainParticles[loc_j], locConstraintIndex_Eta);
2458 ++locConstraintIndex_Eta;
2459 }
2460 if((dRFMatchedBeamParticle != NULL__null) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
2461 {
2462 locRFTimeConstrainedFlag = true;
2463 locKinFitConstraint_Spacetime->Set_FIndex(NULL__null, locConstraintIndex_Eta);
2464 ++locConstraintIndex_Eta;
2465 }
2466 continue;
2467 }
2468 }
2469
2470 //SETUP dVY
2471 int locPxParamIndex;
2472 int locVxParamIndex;
2473 int locTParamIndex;
2474 int locEParamIndex;
2475
2476 int locCovMatrixEParamIndex;
2477 int locCovMatrixPxParamIndex;
2478 int locCovMatrixVxParamIndex;
2479 int locCovMatrixTParamIndex;
2480 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
2481 {
2482 locKinFitParticle = dKinFitParticles[loc_i];
2483 locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2484
2485 if((locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_TargetParticle))
2486 continue; //uncertainties of target particle momentum are zero
2487
2488 locMomentum = locKinFitParticle->Get_Momentum();
2489 locPosition = locKinFitParticle->Get_Position();
2490 const TMatrixDSym& locCovarianceMatrix = *(locKinFitParticle->Get_CovarianceMatrix());
2491
2492 locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
2493 locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
2494 locTParamIndex = locKinFitParticle->Get_TParamIndex();
2495 locEParamIndex = locKinFitParticle->Get_EParamIndex();
2496
2497 locCovMatrixEParamIndex = locKinFitParticle->Get_CovMatrixEParamIndex();
2498 locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
2499 locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
2500 locCovMatrixTParamIndex = locKinFitParticle->Get_CovMatrixTParamIndex();
2501
2502 //localized terms (E, p, v, t)
2503 if(locEParamIndex >= 0)
2504 dVY(locEParamIndex, locEParamIndex) = locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixEParamIndex);
2505 if(locPxParamIndex >= 0)
2506 {
2507 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2508 {
2509 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
2510 dVY(locPxParamIndex + loc_j, locPxParamIndex + loc_k) = locCovarianceMatrix(loc_j + locCovMatrixPxParamIndex, loc_k + locCovMatrixPxParamIndex);
2511 }
2512 }
2513 if(locVxParamIndex >= 0)
2514 {
2515 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2516 {
2517 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
2518 dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_k) = locCovarianceMatrix(loc_j + locCovMatrixVxParamIndex, loc_k + locCovMatrixVxParamIndex);
2519 }
2520 }
2521 if(locTParamIndex >= 0)
2522 dVY(locTParamIndex, locTParamIndex) = locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixTParamIndex);
2523
2524 //cross terms
2525 if((locEParamIndex >= 0) && (locVxParamIndex >= 0))
2526 {
2527 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2528 {
2529 dVY(locEParamIndex + 0, locVxParamIndex + loc_j) = locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j);
2530 dVY(locVxParamIndex + loc_j, locEParamIndex + 0) = locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0);
2531 }
2532 }
2533 if((locEParamIndex >= 0) && (locTParamIndex >= 0))
2534 {
2535 dVY(locEParamIndex, locTParamIndex) = locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex);
2536 dVY(locTParamIndex, locEParamIndex) = locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex);
2537 }
2538 if((locPxParamIndex >= 0) && (locVxParamIndex >= 0))
2539 {
2540 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2541 {
2542 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
2543 {
2544 dVY(locPxParamIndex + loc_j, locVxParamIndex + loc_k) = locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k);
2545 dVY(locVxParamIndex + loc_k, locPxParamIndex + loc_j) = locCovarianceMatrix(locCovMatrixVxParamIndex + loc_k, locCovMatrixPxParamIndex + loc_j);
2546 }
2547 }
2548 }
2549 if((locPxParamIndex >= 0) && (locTParamIndex >= 0))
2550 {
2551 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2552 {
2553 dVY(locPxParamIndex + loc_j, locTParamIndex + 0) = locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0);
2554 dVY(locTParamIndex + 0, locPxParamIndex + loc_j) = locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j);
2555 }
2556 }
2557 if((locVxParamIndex >= 0) && (locTParamIndex >= 0))
2558 {
2559 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
2560 {
2561 dVY(locVxParamIndex + loc_j, locTParamIndex + 0) = locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0);
2562 dVY(locTParamIndex + 0, locVxParamIndex + loc_j) = locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j);
2563 }
2564 }
2565 }
2566 if(locRFTimeConstrainedFlag)
2567 dVY(dRFTimeParamIndex, dRFTimeParamIndex) = dRFUncertainty*dRFUncertainty;
2568}
2569
2570void DKinFitter::Update_ParticleParams(void)
2571{
2572 // translate data from Eta to particles
2573 DKinFitParticle* locKinFitParticle;
2574 DKinFitParticleType locKinFitParticleType;
2575 int locParamIndex;
2576
2577 // update constraint information
2578 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
2579 {
2580 DKinFitConstraint_Vertex* locKinFitConstraint_Vertex = dynamic_cast<DKinFitConstraint_Vertex*>(dKinFitConstraints[loc_i]);
2581 if(locKinFitConstraint_Vertex != NULL__null)
2582 {
2583 locParamIndex = locKinFitConstraint_Vertex->Get_VxParamIndex();
2584 locKinFitConstraint_Vertex->Set_CommonVertex(TVector3(dXi(locParamIndex, 0), dXi(locParamIndex + 1, 0), dXi(locParamIndex + 2, 0)));
2585 continue;
2586 }
2587 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2588 if(locKinFitConstraint_Spacetime != NULL__null)
2589 {
2590 locParamIndex = locKinFitConstraint_Spacetime->Get_TParamIndex();
2591 locKinFitConstraint_Spacetime->Set_CommonTime(dXi(locParamIndex, 0));
2592 locParamIndex = locKinFitConstraint_Spacetime->Get_VxParamIndex();
2593 locKinFitConstraint_Spacetime->Set_CommonVertex(TVector3(dXi(locParamIndex, 0), dXi(locParamIndex + 1, 0), dXi(locParamIndex + 2, 0)));
2594
2595 if(!Get_IsBFieldNearBeamline())
2596 continue;
2597
2598 deque<DKinFitParticle*> locFullConstrainParticles = locKinFitConstraint_Spacetime->dFullConstrainParticles;
2599 for(size_t loc_j = 0; loc_j < locFullConstrainParticles.size(); ++loc_j)
2600 {
2601 if(locFullConstrainParticles[loc_j]->Get_Charge() == 0)
2602 continue;
2603 locParamIndex = locFullConstrainParticles[loc_j]->Get_LParamIndex();
2604 if(locParamIndex > 0)
2605 locFullConstrainParticles[loc_j]->Set_PathLength(dXi(locParamIndex, 0));
2606 }
2607 continue;
2608 }
2609 }
2610
2611 // update particle information
2612 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
2613 {
2614 locKinFitParticle = dKinFitParticles[loc_i];
2615 locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2616 if(locKinFitParticleType == d_TargetParticle)
2617 continue; //nothing to update
2618 else if((locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_MissingParticle))
2619 {
2620 locParamIndex = locKinFitParticle->Get_PxParamIndex();
2621 if(locParamIndex >= 0)
2622 locKinFitParticle->Set_Momentum(TVector3(dXi(locParamIndex, 0), dXi(locParamIndex + 1, 0), dXi(locParamIndex + 2, 0)));
2623 locParamIndex = locKinFitParticle->Get_VxParamIndex();
2624 if(locParamIndex >= 0)
2625 locKinFitParticle->Set_Position(TVector3(dXi(locParamIndex, 0), dXi(locParamIndex + 1, 0), dXi(locParamIndex + 2, 0)));
2626 locParamIndex = locKinFitParticle->Get_TParamIndex();
2627 if(locParamIndex >= 0)
2628 locKinFitParticle->Set_Time(dXi(locParamIndex, 0));
2629 //calc energy of missing unknown particle (if present), and set mass appropriately
2630 if((locKinFitParticleType == d_MissingParticle) && (locKinFitParticle->Get_PID() == 0))
2631 {
2632 DKinFitConstraint_P4* locKinFitConstraint_P4 = const_cast<DKinFitConstraint_P4*>(locKinFitParticle->Get_DefinedAtP4Constraint());
2633 if(locKinFitConstraint_P4 != NULL__null)
2634 {
2635 TLorentzVector locP4;
2636 Constrain_Particle(locKinFitParticle, locKinFitConstraint_P4, locP4);
2637 locKinFitParticle->Set_Mass(locP4.M());
2638 }
2639 }
2640 }
2641 else //initial or detected
2642 {
2643 locParamIndex = locKinFitParticle->Get_PxParamIndex();
2644 if(locParamIndex >= 0)
2645 locKinFitParticle->Set_Momentum(TVector3(dEta(locParamIndex, 0), dEta(locParamIndex + 1, 0), dEta(locParamIndex + 2, 0)));
2646 locParamIndex = locKinFitParticle->Get_VxParamIndex();
2647 if(locParamIndex >= 0)
2648 locKinFitParticle->Set_Position(TVector3(dEta(locParamIndex, 0), dEta(locParamIndex + 1, 0), dEta(locParamIndex + 2, 0)));
2649 locParamIndex = locKinFitParticle->Get_TParamIndex();
2650 if(locParamIndex >= 0)
2651 locKinFitParticle->Set_Time(dEta(locParamIndex, 0));
2652 locParamIndex = locKinFitParticle->Get_EParamIndex();
2653 if(locParamIndex >= 0) //set momentum also //must be after Vx & common vertex are set
2654 {
2655 double locE = dEta(locParamIndex, 0);
2656 locKinFitParticle->Set_ShowerEnergy(locE);
2657 double locPMag = sqrt(locE*locE - locKinFitParticle->Get_Mass()*locKinFitParticle->Get_Mass());
2658 TVector3 locMomentum = locKinFitParticle->Get_Position() - locKinFitParticle->Get_CommonVertex();
2659 locMomentum.SetMag(locPMag);
2660 locKinFitParticle->Set_Momentum(locMomentum);
2661 }
2662 }
2663 }
2664
2665 // calc non-unknown decaying particle momentum (derived from other particles)
2666 //must do last because assumes all other particle p3's are updated
2667 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
2668 {
2669 DKinFitConstraint_P4* locKinFitConstraint_P4 = dynamic_cast<DKinFitConstraint_P4*>(dKinFitConstraints[loc_i]);
2670 if(locKinFitConstraint_P4 == NULL__null)
2671 continue;
2672 deque<DKinFitParticle*> locInitialParticles = locKinFitConstraint_P4->dInitialParticles;
2673 DKinFitParticle* locKinFitParticle = locInitialParticles[0];
2674 if(locKinFitParticle->Get_PxParamIndex() >= 0)
2675 continue; //already updated
2676 //what if a decay product is a missing particle of unknown mass? it's fine: only setting p3 anyway, which is derived
2677 //locKinFitParticle is now definitely an enclosed decaying particle
2678 if(locKinFitParticle->Get_DecayingParticleAtProductionVertexFlag())
2679 locKinFitParticle->Set_Momentum(Calc_DecayingP4(locKinFitConstraint_P4, false).Vect()); //returns p4 at production vertex
2680 else
2681 locKinFitParticle->Set_Momentum(Calc_DecayingP4(locKinFitConstraint_P4, true).Vect()); //returns p4 at decay vertex
2682 }
2683
2684 if(dRFTimeParamIndex > 0)
2685 dRFTime = dEta(dRFTimeParamIndex, 0);
2686}
2687
2688TLorentzVector DKinFitter::Calc_DecayingP4(DKinFitConstraint_P4* locP4Constraint, bool locDecayMomentumFlag) const
2689{
2690 //uses decay products to calculate decaying particle information
2691 //locDecayMomentumFlag = true to return momentum at the decay vertex, false at the production vertex
2692 TLorentzVector locP4;
2693
2694 if(!locDecayMomentumFlag)
2695 {
2696 //propagate decaying particle momentum from the decay vertex to the production vertex
2697 deque<DKinFitParticle*> locInitialParticles = locP4Constraint->dInitialParticles;
2698 DKinFitParticle* locKinFitParticle = locInitialParticles[0]; //the decaying particle
2699
2700 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
2701 bool locEnoughVertexFitsFlag = (locNumVertexFits == 2);
2702 int locCharge = locKinFitParticle->Get_Charge();
2703 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
2704
2705 if(locEnoughVertexFitsFlag && locChargedBFieldFlag)
2706 {
2707 TVector3 locPosition = locKinFitParticle->Get_Position();
2708 TVector3 locDeltaX = locKinFitParticle->Get_CommonVertex() - locPosition;
2709 TVector3 locBField = Get_BField(locPosition);
2710 TVector3 locH = locBField.Unit();
2711 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
2712 locP4.SetVect(locP4.Vect() - locDeltaX.Cross(locA*locH));
2713 }
2714 }
2715
2716 deque<DKinFitParticle*> locFinalParticles = locP4Constraint->dFinalParticles;
2717 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
2718 {
2719 DKinFitParticle* locKinFitParticle = locFinalParticles[loc_i];
2720
2721 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
2722 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2723 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
2724 int locCharge = locKinFitParticle->Get_Charge();
2725 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
2726
2727 if(locEnoughVertexFitsFlag && locChargedBFieldFlag && (locKinFitParticleType != d_MissingParticle) && (locKinFitParticleType != d_TargetParticle))
2728 {
2729 TVector3 locPosition = locKinFitParticle->Get_Position();
2730 TVector3 locDeltaX = locKinFitParticle->Get_CommonVertex() - locPosition;
2731 TVector3 locBField = Get_BField(locPosition);
2732 TVector3 locH = locBField.Unit();
2733 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
2734 locP4.SetVect(locP4.Vect() - locDeltaX.Cross(locA*locH));
2735 }
2736
2737 if((locFinalParticles[loc_i]->Get_KinFitParticleType() == d_DecayingParticle) && (locFinalParticles[loc_i]->Get_PxParamIndex() == -1))
2738 {
2739 //decaying particle whose momentum must also be derived
2740 deque<DKinFitConstraint_P4*> locP4Constraints = locFinalParticles[loc_i]->dP4Constraints;
2741 for(size_t loc_j = 0; loc_j < locP4Constraints.size(); ++loc_j)
2742 {
2743 if(locP4Constraints[loc_j] == locP4Constraint)
2744 continue;
2745 locP4 += Calc_DecayingP4(locP4Constraints[loc_j], true);
2746 break;
2747 }
2748 }
2749 else
2750 locP4 += locFinalParticles[loc_i]->Get_P4();
2751 }
2752 return locP4;
2753}
2754
2755void DKinFitter::Calc_dF(void)
2756{
2757 dF.Zero();
2758 dF_dXi.Zero();
2759 dF_dEta.Zero();
2760 size_t locFIndex = 0;
2761 DKinFitParticle* locKinFitParticle;
2762 bool locIsDecayingFlag = false;
2763 for(size_t loc_i = 0; loc_i < dKinFitConstraints.size(); ++loc_i)
1
Loop condition is true. Entering loop body
5
Loop condition is true. Entering loop body
9
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
2764 {
2765 DKinFitConstraint_P4* locKinFitConstraint_P4 = dynamic_cast<DKinFitConstraint_P4*>(dKinFitConstraints[loc_i]);
2766 if(locKinFitConstraint_P4 != NULL__null)
2
Taking false branch
6
Taking false branch
10
Taking false branch
14
Taking false branch
2767 {
2768 int locFIndex = locKinFitConstraint_P4->Get_FIndex();
2769 if(dDebugLevel > 10)
2770 cout << "DKinFitter: F index = " << locFIndex << endl;
2771 if(locFIndex < 0)
2772 continue; //e.g. a p4 constraint with a decaying particle as an enclosed parent that has no mass constraint
2773
2774 if(locKinFitConstraint_P4->Get_IsActualP4ConstraintFlag())
2775 {
2776 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dInitialParticles.size(); ++loc_j)
2777 {
2778 locKinFitParticle = (locKinFitConstraint_P4->dInitialParticles)[loc_j];
2779 Calc_dF_P4(locKinFitConstraint_P4, locKinFitParticle, true, NULL__null);
2780 }
2781 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dFinalParticles.size(); ++loc_j)
2782 {
2783 locKinFitParticle = (locKinFitConstraint_P4->dFinalParticles)[loc_j];
2784 Calc_dF_P4(locKinFitConstraint_P4, locKinFitParticle, false, NULL__null);
2785 }
2786 }
2787 else if(locKinFitConstraint_P4->Get_ConstrainInitialParticleMassFlag())
2788 {
2789 //mass constraint
2790 double locTargetedMass = (locKinFitConstraint_P4->dInitialParticles)[0]->Get_Mass();
2791 if(locKinFitConstraint_P4->Get_ConstrainMassByInvariantMassFlag())
2792 {
2793 //invariant mass constraint: loop over decay products
2794 if(dDebugLevel > 10)
2795 cout << "invariant mass constraint: loop over decay products" << endl;
2796 TLorentzVector locDecayingParticleDerivedP4;
2797 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dFinalParticles.size(); ++loc_j)
2798 {
2799 locKinFitParticle = (locKinFitConstraint_P4->dFinalParticles)[loc_j];
2800 locDecayingParticleDerivedP4 += Calc_dF_MassP4(locKinFitConstraint_P4, locKinFitParticle, false, true, NULL__null);
2801 }
2802 if(dDebugLevel > 30)
2803 cout << "Final decaying pxyzE is: " << locDecayingParticleDerivedP4.Px() << ", " << locDecayingParticleDerivedP4.Py() << ", " << locDecayingParticleDerivedP4.Pz() << ", " << locDecayingParticleDerivedP4.E() << endl;
2804 dF(locFIndex, 0) += locDecayingParticleDerivedP4.M2() - locTargetedMass*locTargetedMass;
2805 for(size_t loc_j = 0; loc_j < locKinFitConstraint_P4->dFinalParticles.size(); ++loc_j)
2806 {
2807 locKinFitParticle = (locKinFitConstraint_P4->dFinalParticles)[loc_j];
2808 Calc_dF_MassDerivs(locKinFitConstraint_P4, locKinFitParticle, locDecayingParticleDerivedP4, false, true, NULL__null);
2809 }
2810 }
2811 else //missing particle with unknown mass is a decay product: constrain by missing mass
2812 {
2813 //missing mass constraint: use this particle to get the next
2814 if(dDebugLevel > 10)
2815 cout << "missing mass constraint: use this particle to get the next" << endl;
2816 locKinFitParticle = locKinFitConstraint_P4->dInitialParticles[0];
2817 TLorentzVector locDecayingParticleDerivedP4 = Calc_dF_MassP4(locKinFitConstraint_P4, locKinFitParticle, true, false, NULL__null);
2818 if(dDebugLevel > 30)
2819 cout << "Final decaying pxyzE is: " << locDecayingParticleDerivedP4.Px() << ", " << locDecayingParticleDerivedP4.Py() << ", " << locDecayingParticleDerivedP4.Pz() << ", " << locDecayingParticleDerivedP4.E() << endl;
2820 Calc_dF_MassDerivs(locKinFitConstraint_P4, locKinFitParticle, locDecayingParticleDerivedP4, true, false, NULL__null);
2821 dF(locFIndex, 0) += locDecayingParticleDerivedP4.M2() - locTargetedMass*locTargetedMass;
2822 }
2823 }
2824 continue;
2825 }
2826
2827 DKinFitConstraint_Vertex* locKinFitConstraint_Vertex = dynamic_cast<DKinFitConstraint_Vertex*>(dKinFitConstraints[loc_i]);
15
'locKinFitConstraint_Vertex' initialized here
2828 if(locKinFitConstraint_Vertex != NULL__null)
3
Taking false branch
7
Taking false branch
11
Taking false branch
16
Assuming pointer value is null
17
Taking false branch
2829 {
2830 for(size_t loc_j = 0; loc_j < locKinFitConstraint_Vertex->dFullConstrainParticles.size(); ++loc_j)
2831 {
2832 locKinFitParticle = (locKinFitConstraint_Vertex->dFullConstrainParticles)[loc_j];
2833 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2834
2835 locIsDecayingFlag = (locKinFitParticleType == d_DecayingParticle);
2836 locFIndex = locKinFitConstraint_Vertex->Get_FIndex(locKinFitParticle);
2837 if(dDebugLevel > 10)
2838 cout << "DKinFitter: F index, locIsDecayingFlag = " << locFIndex << ", " << locIsDecayingFlag << endl;
2839
2840 bool locInitialStateFlag = false; //unless set otherwise
2841 if(locKinFitParticleType == d_BeamParticle)
2842 locInitialStateFlag = true;
2843 //for locDecayingParticles: bool is true if vertex is production vertex / particle in final state, false if decay vertex / initial state
2844 deque<pair<DKinFitParticle*, bool> > locDecayingParticles = locKinFitConstraint_Vertex->dDecayingParticles;
2845 for(size_t loc_k = 0; loc_k < locDecayingParticles.size(); ++loc_k)
2846 {
2847 if(locDecayingParticles[loc_k].first != locKinFitParticle)
2848 continue;
2849 locInitialStateFlag = !locDecayingParticles[loc_k].second;
2850 break;
2851 }
2852
2853 Calc_dF_Vertex(locFIndex, locKinFitParticle, NULL__null, locInitialStateFlag, locInitialStateFlag);
2854 }
2855 }
2856
2857 DKinFitConstraint_Spacetime* locKinFitConstraint_Spacetime = dynamic_cast<DKinFitConstraint_Spacetime*>(dKinFitConstraints[loc_i]);
2858 if(locKinFitConstraint_Spacetime != NULL__null)
4
Taking false branch
8
Taking false branch
12
Taking false branch
18
Taking true branch
2859 {
2860 for(size_t loc_j = 0; loc_j < locKinFitConstraint_Spacetime->dFullConstrainParticles.size(); ++loc_j)
19
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
23
Loop condition is true. Entering loop body
25
Loop condition is true. Entering loop body
2861 {
2862 locKinFitParticle = (locKinFitConstraint_Spacetime->dFullConstrainParticles)[loc_j];
2863 locIsDecayingFlag = (locKinFitParticle->Get_KinFitParticleType() == d_DecayingParticle);
2864 locFIndex = locKinFitConstraint_Spacetime->Get_FIndex(locKinFitParticle);
2865 if(dDebugLevel > 10)
20
Taking false branch
22
Taking false branch
24
Taking false branch
26
Taking false branch
2866 cout << "DKinFitter: F index, locIsDecayingFlag = " << locFIndex << ", " << locIsDecayingFlag << endl;
2867 Calc_dF_Time(locFIndex, locKinFitParticle, false);
2868 if((locKinFitParticle == dRFMatchedBeamParticle) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
27
Taking true branch
2869 {
2870 locFIndex = locKinFitConstraint_Vertex->Get_FIndex(NULL__null);
28
Called C++ object pointer is null
2871 if(dDebugLevel > 10)
2872 cout << "DKinFitter: F index, locIsDecayingFlag = " << locFIndex << ", " << locIsDecayingFlag << endl;
2873 Calc_dF_Time(locFIndex, dRFMatchedBeamParticle, true);
2874 }
2875 }
2876 }
2877 }
2878 dF_dEta_T.Transpose(dF_dEta);
2879 dF_dXi_T.Transpose(dF_dXi);
2880}
2881
2882void DKinFitter::Calc_dF_P4(DKinFitConstraint_P4* locKinFitConstraint_P4, const DKinFitParticle* locKinFitParticle, bool locInitialStateFlag, DKinFitConstraint_P4* locKinFitSubConstraint_P4)
2883{
2884 int locFIndex = locKinFitConstraint_P4->Get_FIndex();
2885
2886 //E, px, py, pz
2887 int locCharge = locKinFitParticle->Get_Charge();
2888 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
2889
2890 TLorentzVector locP4 = locKinFitParticle->Get_P4();
2891 TVector3 locPosition = locKinFitParticle->Get_Position();
2892 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
2893 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
2894 TVector3 locDeltaX = locCommonVertex - locPosition;
2895
2896 TVector3 locH = locBField.Unit();
2897 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
2898
2899 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
2900 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
2901 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
2902 double locSignMultiplier = locInitialStateFlag ? 1.0 : -1.0;
2903 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
2904
2905 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
2906 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
2907 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
2908 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
2909
2910 if((locKinFitParticleType != d_DecayingParticle) || (locKinFitParticle->Get_NumP4Constraints() == 1))
2911 {
2912 //all but enclosed decaying particle: will instead get p4 from decay products (may still need to propagate it below)
2913 dF(locFIndex, 0) += locSignMultiplier*locP4.E();
2914 dF(locFIndex + 1, 0) += locSignMultiplier*locP4.Px();
2915 dF(locFIndex + 2, 0) += locSignMultiplier*locP4.Py();
2916 dF(locFIndex + 3, 0) += locSignMultiplier*locP4.Pz();
2917 }
2918
2919 if(dDebugLevel > 30)
2920 cout << "q, mass, sign, pxyzE = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << ", " << locSignMultiplier << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locP4.E() << endl;
2921
2922 if(locEnoughVertexFitsFlag && locChargedBFieldFlag && (locKinFitParticleType != d_MissingParticle) && (locKinFitParticleType != d_TargetParticle))
2923 {
2924 //fitting vertex of charged track in magnetic field: momentum changes as function of vertex
2925 //check decaying particles: don't include propagation factor if p4 is used where it is defined (already propagated)
2926 //if initial particle is a "detected" particle (actually a decaying particle treated as detected): still propagate vertex (assume p3/v3 defined at production vertex)
2927
2928 TVector3 locDeltaXCrossH = locDeltaX.Cross(locH);
2929 if(dDebugLevel > 30)
2930 cout << "propagate pxyz by: " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.X() << ", " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.Y() << ", " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.Z() << endl;
2931 dF(locFIndex + 1, 0) -= locSignMultiplier*locA*locDeltaXCrossH.X();
2932 dF(locFIndex + 2, 0) -= locSignMultiplier*locA*locDeltaXCrossH.Y();
2933 dF(locFIndex + 3, 0) -= locSignMultiplier*locA*locDeltaXCrossH.Z();
2934 }
2935
2936 if(locKinFitParticleType == d_TargetParticle)
2937 {
2938 if(dDebugLevel > 30)
2939 cout << "DKinFitter: Calc_dF_P4() Section 1; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
2940 return; //target params are fixed: no partial derivatives
2941 }
2942 else if(locChargedBFieldFlag && locEnoughVertexFitsFlag && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)))
2943 {
2944 //detected charged particle in b-field (can be beam particle) & in vertex fit
2945 if(dDebugLevel > 30)
2946 cout << "DKinFitter: Calc_dF_P4() Section 2; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
2947
2948 dF_dEta(locFIndex, locPxParamIndex) = locSignMultiplier*locP4.Px()/locP4.E();
2949 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locP4.Py()/locP4.E();
2950 dF_dEta(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locP4.Pz()/locP4.E();
2951
2952 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier;
2953 dF_dEta(locFIndex + 2, locPxParamIndex + 1) = locSignMultiplier;
2954 dF_dEta(locFIndex + 3, locPxParamIndex + 2) = locSignMultiplier;
2955
2956 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locSignMultiplier*locA*locH.Z();
2957 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = -1.0*locSignMultiplier*locA*locH.Y();
2958
2959 dF_dEta(locFIndex + 2, locVxParamIndex) = -1.0*locSignMultiplier*locA*locH.Z();
2960 dF_dEta(locFIndex + 2, locVxParamIndex + 2) = locSignMultiplier*locA*locH.X();
2961
2962 dF_dEta(locFIndex + 3, locVxParamIndex) = locSignMultiplier*locA*locH.Y();
2963 dF_dEta(locFIndex + 3, locVxParamIndex + 1) = -1.0*locSignMultiplier*locA*locH.X();
2964
2965 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
2966 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
2967
2968 dF_dXi(locFIndex + 2, locCommonVxParamIndex) -= dF_dEta(locFIndex + 2, locVxParamIndex);
2969 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 2, locVxParamIndex + 2);
2970
2971 dF_dXi(locFIndex + 3, locCommonVxParamIndex) -= dF_dEta(locFIndex + 3, locVxParamIndex);
2972 dF_dXi(locFIndex + 3, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 3, locVxParamIndex + 1);
2973 }
2974 else if(locNeutralShowerFlag)
2975 {
2976 if(dDebugLevel > 30)
2977 cout << "DKinFitter: Calc_dF_P4() Section 3; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
2978
2979 dF_dEta(locFIndex, locEParamIndex) = locSignMultiplier;
2980
2981 double locEOverPSq = locP4.E()/locP4.Vect().Mag2();
2982 dF_dEta(locFIndex + 1, locEParamIndex) = locSignMultiplier*locEOverPSq*locP4.Px();
2983 dF_dEta(locFIndex + 2, locEParamIndex) = locSignMultiplier*locEOverPSq*locP4.Py();
2984 dF_dEta(locFIndex + 3, locEParamIndex) = locSignMultiplier*locEOverPSq*locP4.Pz();
2985
2986 TVector3 locDeltaXOverMagDeltaXSq = locDeltaX*(1.0/locDeltaX.Mag2());
2987
2988 dF_dEta(locFIndex + 1, locVxParamIndex) = locSignMultiplier*locP4.Px()*(locDeltaXOverMagDeltaXSq.X() - 1.0/locDeltaX.X());
2989 dF_dEta(locFIndex + 2, locVxParamIndex + 1) = locSignMultiplier*locP4.Py()*(locDeltaXOverMagDeltaXSq.Y() - 1.0/locDeltaX.Y());
2990 dF_dEta(locFIndex + 3, locVxParamIndex + 2) = locSignMultiplier*locP4.Pz()*(locDeltaXOverMagDeltaXSq.Z() - 1.0/locDeltaX.Z());
2991
2992 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locSignMultiplier*locP4.Px()*locDeltaXOverMagDeltaXSq.Y();
2993 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locSignMultiplier*locP4.Px()*locDeltaXOverMagDeltaXSq.Z();
2994
2995 dF_dEta(locFIndex + 2, locVxParamIndex) = locSignMultiplier*locP4.Py()*locDeltaXOverMagDeltaXSq.X();
2996 dF_dEta(locFIndex + 2, locVxParamIndex + 2) = locSignMultiplier*locP4.Py()*locDeltaXOverMagDeltaXSq.Z();
2997
2998 dF_dEta(locFIndex + 3, locVxParamIndex) = locSignMultiplier*locP4.Pz()*locDeltaXOverMagDeltaXSq.X();
2999 dF_dEta(locFIndex + 3, locVxParamIndex + 1) = locSignMultiplier*locP4.Pz()*locDeltaXOverMagDeltaXSq.Y();
3000
3001 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
3002 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 2, locVxParamIndex + 1);
3003 dF_dXi(locFIndex + 3, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 3, locVxParamIndex + 2);
3004
3005 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3006 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3007
3008 dF_dXi(locFIndex + 2, locCommonVxParamIndex) -= dF_dEta(locFIndex + 2, locVxParamIndex);
3009 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 2, locVxParamIndex + 2);
3010
3011 dF_dXi(locFIndex + 3, locCommonVxParamIndex) -= dF_dEta(locFIndex + 3, locVxParamIndex);
3012 dF_dXi(locFIndex + 3, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 3, locVxParamIndex + 1);
3013 }
3014 else if((locKinFitParticleType == d_MissingParticle) || ((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex >= 0)))
3015 {
3016 //missing or open-ended-decaying particle: p3 is unknown (not derivable) //must be the constrained particle
3017 if(dDebugLevel > 30)
3018 cout << "DKinFitter: Calc_dF_P4() Section 4; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3019
3020 dF_dXi(locFIndex, locPxParamIndex) = locSignMultiplier*locP4.Px()/locP4.E();
3021 dF_dXi(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locP4.Py()/locP4.E();
3022 dF_dXi(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locP4.Pz()/locP4.E();
3023
3024 dF_dXi(locFIndex + 1, locPxParamIndex) = locSignMultiplier;
3025 dF_dXi(locFIndex + 2, locPxParamIndex + 1) = locSignMultiplier;
3026 dF_dXi(locFIndex + 3, locPxParamIndex + 2) = locSignMultiplier;
3027 }
3028 else if(locKinFitParticleType == d_DecayingParticle)
3029 {
3030 //enclosed decaying particle
3031 if(dDebugLevel > 30)
3032 cout << "DKinFitter: Calc_dF_P4() Section 5; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3033 if((locCharge != 0) && Get_IsBFieldNearBeamline() && (locKinFitParticle->Get_NumVertexFits() == 2))
3034 {
3035 if(dDebugLevel > 30)
3036 cout << "DKinFitter: Calc_dF_P4() Section 5a" << endl;
3037 //vertex factors
3038 dF_dXi(locFIndex + 1, locVxParamIndex + 1) += locSignMultiplier*locA*locH.Z();
3039 dF_dXi(locFIndex + 1, locVxParamIndex + 2) += -1.0*locSignMultiplier*locA*locH.Y();
3040
3041 dF_dXi(locFIndex + 2, locVxParamIndex) += -1.0*locSignMultiplier*locA*locH.Z();
3042 dF_dXi(locFIndex + 2, locVxParamIndex + 2) += locSignMultiplier*locA*locH.X();
3043
3044 dF_dXi(locFIndex + 3, locVxParamIndex) += locSignMultiplier*locA*locH.Y();
3045 dF_dXi(locFIndex + 3, locVxParamIndex + 1) += -1.0*locSignMultiplier*locA*locH.X();
3046
3047 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex + 1, locVxParamIndex + 1);
3048 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex + 1, locVxParamIndex + 2);
3049
3050 dF_dXi(locFIndex + 2, locCommonVxParamIndex) -= dF_dXi(locFIndex + 2, locVxParamIndex);
3051 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex + 2, locVxParamIndex + 2);
3052
3053 dF_dXi(locFIndex + 3, locCommonVxParamIndex) -= dF_dXi(locFIndex + 3, locVxParamIndex);
3054 dF_dXi(locFIndex + 3, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex + 3, locVxParamIndex + 1);
3055 }
3056
3057 deque<DKinFitConstraint_P4*> locP4Constraints = locKinFitParticle->dP4Constraints;
3058 for(size_t loc_i = 0; loc_i < locP4Constraints.size(); ++loc_i)
3059 {
3060 DKinFitConstraint_P4* locNewKinFitSubConstraint_P4 = locP4Constraints[loc_i];
3061 if(locNewKinFitSubConstraint_P4 == locKinFitConstraint_P4)
3062 continue;
3063 if(locNewKinFitSubConstraint_P4 == locKinFitSubConstraint_P4)
3064 continue;
3065
3066 //if this constraint contains the decaying particle, replace it with the other particles it's momentum is derived from
3067 deque<DKinFitParticle*> locInitialParticles = locNewKinFitSubConstraint_P4->dInitialParticles;
3068 deque<DKinFitParticle*> locFinalParticles = locNewKinFitSubConstraint_P4->dFinalParticles;
3069 for(size_t loc_j = 0; loc_j < locInitialParticles.size(); ++loc_j)
3070 {
3071 if(locInitialParticles[loc_j] == locKinFitParticle)
3072 continue;
3073 //detected: +/- if init/final
3074 //p-replacement: factor of +/- if same/different state
3075 //so if ORIG decaying was init/final (+/-), and detected is init (+), then should call as if it was (+/+): init
3076 //so if ORIG decaying was init/final (+/-), and detected is final (-), then should call as if it was (-/-): final
3077 if(dDebugLevel > 30)
3078 cout << "decaying, partially replace with init-state q, mass = " << locInitialParticles[loc_j]->Get_Charge() << ", " << locInitialParticles[loc_j]->Get_Mass() << endl;
3079 Calc_dF_P4(locKinFitConstraint_P4, locInitialParticles[loc_j], true, locNewKinFitSubConstraint_P4); //else !locInitialStateFlag
3080 }
3081 for(size_t loc_j = 0; loc_j < locFinalParticles.size(); ++loc_j)
3082 {
3083 if(locFinalParticles[loc_j] == locKinFitParticle)
3084 continue;
3085 if(dDebugLevel > 30)
3086 cout << "decaying, partially replace with final-state q, mass = " << locFinalParticles[loc_j]->Get_Charge() << ", " << locFinalParticles[loc_j]->Get_Mass() << endl;
3087 Calc_dF_P4(locKinFitConstraint_P4, locFinalParticles[loc_j], false, locNewKinFitSubConstraint_P4);
3088 }
3089 }
3090 }
3091 else
3092 {
3093 // either no common vertex constraint, charged and detected but b-field = 0, or neutral particle with pre-ordained vertex (e.g. beam particle)
3094 if(dDebugLevel > 30)
3095 cout << "DKinFitter: Calc_dF_P4() Section 6; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3096
3097 dF_dEta(locFIndex, locPxParamIndex) = locSignMultiplier*locP4.Px()/locP4.E();
3098 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locP4.Py()/locP4.E();
3099 dF_dEta(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locP4.Pz()/locP4.E();
3100
3101 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier;
3102 dF_dEta(locFIndex + 2, locPxParamIndex + 1) = locSignMultiplier;
3103 dF_dEta(locFIndex + 3, locPxParamIndex + 2) = locSignMultiplier;
3104 }
3105}
3106
3107TLorentzVector DKinFitter::Calc_dF_MassP4(DKinFitConstraint_P4* locKinFitConstraint_P4, const DKinFitParticle* locKinFitParticle, bool locInitialStateFlag, bool locIsInvariantMassConstraint, DKinFitConstraint_P4* locKinFitSubConstraint_P4)
3108{
3109 //locIsInvariantMassConstraint: true/false if constraining invariant/missing mass
3110 //E, px, py, pz
3111 int locCharge = locKinFitParticle->Get_Charge();
3112 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3113
3114 TLorentzVector locP4 = locKinFitParticle->Get_P4();
3115 TVector3 locPosition = locKinFitParticle->Get_Position();
3116 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
3117 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
3118 TVector3 locDeltaX = locCommonVertex - locPosition;
3119
3120 TVector3 locH = locBField.Unit();
3121 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3122
3123 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
3124 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
3125 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
3126 double locSignMultiplier = (locInitialStateFlag != locIsInvariantMassConstraint) ? 1.0 : -1.0;
3127
3128 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
3129
3130 TLorentzVector locP4Sum;
3131 if((locKinFitParticleType != d_DecayingParticle) || (locKinFitParticle->Get_NumP4Constraints() == 1))
3132 locP4Sum += locSignMultiplier*locP4; //all but enclosed decaying particle: will instead get p4 from decay products (may still need to propagate it below)
3133
3134 if(dDebugLevel > 30)
3135 cout << "q, mass, sign, pxyzE = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << ", " << locSignMultiplier << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locP4.E() << endl;
3136
3137 if(locEnoughVertexFitsFlag && locChargedBFieldFlag && (locKinFitParticleType != d_MissingParticle) && (locKinFitParticleType != d_TargetParticle) && ((locKinFitParticleType != d_DecayingParticle) || (locKinFitSubConstraint_P4 != NULL__null)))
3138 {
3139 //fitting vertex of charged track in magnetic field: momentum changes as function of vertex
3140 //check decaying particles: don't include propagation factor if p4 is used where it is defined (already propagated)
3141 //if initial particle is a "detected" particle (actually a decaying particle treated as detected): still propagate vertex (assume p3/v3 defined at production vertex)
3142
3143 TVector3 locDeltaXCrossH = locDeltaX.Cross(locH);
3144 if(dDebugLevel > 30)
3145 cout << "propagate pxyz by: " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.X() << ", " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.Y() << ", " << -1.0*locSignMultiplier*locA*locDeltaXCrossH.Z() << endl;
3146
3147 locP4Sum.SetVect(locP4Sum.Vect() - locSignMultiplier*locA*locDeltaXCrossH);
3148 }
3149
3150 if((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex < 0))
3151 {
3152 //enclosed decaying particle
3153 if(dDebugLevel > 30)
3154 cout << "DKinFitter: Calc_dF_MassP4() Decaying Particle; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3155
3156 //get the other p4 constraint its in and loop over the particles in it
3157 deque<DKinFitConstraint_P4*> locP4Constraints = locKinFitParticle->dP4Constraints;
3158 for(size_t loc_i = 0; loc_i < locP4Constraints.size(); ++loc_i)
3159 {
3160 DKinFitConstraint_P4* locNewKinFitSubConstraint_P4 = locP4Constraints[loc_i];
3161 if(locNewKinFitSubConstraint_P4 == locKinFitConstraint_P4)
3162 continue;
3163 if(locNewKinFitSubConstraint_P4 == locKinFitSubConstraint_P4)
3164 continue;
3165
3166 //if this constraint contains the decaying particle, replace it with the other particles it's momentum is derived from
3167 deque<DKinFitParticle*> locInitialParticles = locNewKinFitSubConstraint_P4->dInitialParticles;
3168 deque<DKinFitParticle*> locFinalParticles = locNewKinFitSubConstraint_P4->dFinalParticles;
3169 for(size_t loc_j = 0; loc_j < locInitialParticles.size(); ++loc_j)
3170 {
3171 if(locInitialParticles[loc_j] == locKinFitParticle)
3172 continue;
3173 //detected: +/- if init/final
3174 //p-replacement: factor of +/- if same/different state
3175 //so if ORIG decaying was init/final (+/-), and detected is init (+), then should call as if it was (+/+): init
3176 //so if ORIG decaying was init/final (+/-), and detected is final (-), then should call as if it was (-/-): final
3177 if(dDebugLevel > 30)
3178 cout << "decaying, partially replace with init-state q, mass = " << locInitialParticles[loc_j]->Get_Charge() << ", " << locInitialParticles[loc_j]->Get_Mass() << endl;
3179 locP4Sum += Calc_dF_MassP4(locKinFitConstraint_P4, locInitialParticles[loc_j], true, locIsInvariantMassConstraint, locNewKinFitSubConstraint_P4); //else !locInitialStateFlag
3180 if(dDebugLevel > 30)
3181 cout << "pxyzE sum is: " << locP4Sum.Px() << ", " << locP4Sum.Py() << ", " << locP4Sum.Pz() << ", " << locP4Sum.E() << endl;
3182 }
3183 for(size_t loc_j = 0; loc_j < locFinalParticles.size(); ++loc_j)
3184 {
3185 if(locFinalParticles[loc_j] == locKinFitParticle)
3186 continue;
3187 if(dDebugLevel > 30)
3188 cout << "decaying, partially replace with final-state q, mass = " << locFinalParticles[loc_j]->Get_Charge() << ", " << locFinalParticles[loc_j]->Get_Mass() << endl;
3189 locP4Sum += Calc_dF_MassP4(locKinFitConstraint_P4, locFinalParticles[loc_j], false, locIsInvariantMassConstraint, locNewKinFitSubConstraint_P4);
3190 if(dDebugLevel > 30)
3191 cout << "pxyzE sum is: " << locP4Sum.Px() << ", " << locP4Sum.Py() << ", " << locP4Sum.Pz() << ", " << locP4Sum.E() << endl;
3192 }
3193 }
3194 }
3195 return locP4Sum;
3196}
3197
3198void DKinFitter::Calc_dF_MassDerivs(DKinFitConstraint_P4* locKinFitConstraint_P4, const DKinFitParticle* locKinFitParticle, TLorentzVector locDecayingParticleDerivedP4, bool locInitialStateFlag, bool locIsInvariantMassConstraint, DKinFitConstraint_P4* locKinFitSubConstraint_P4)
3199{
3200 int locFIndex = locKinFitConstraint_P4->Get_FIndex();
3201
3202 //E, px, py, pz
3203 int locCharge = locKinFitParticle->Get_Charge();
3204 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3205
3206 TLorentzVector locP4 = locKinFitParticle->Get_P4();
3207 TVector3 locPosition = locKinFitParticle->Get_Position();
3208 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
3209 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
3210 TVector3 locDeltaX = locCommonVertex - locPosition;
3211
3212 TVector3 locH = locBField.Unit();
3213 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3214
3215 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
3216 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
3217 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
3218// double locSignMultiplier = locInitialStateFlag ? 1.0 : -1.0;
3219 double locSignMultiplier = (locInitialStateFlag != locIsInvariantMassConstraint) ? 1.0 : -1.0;
3220 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
3221
3222 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
3223 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
3224 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
3225 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
3226
3227 TVector3 locPXCrossHi = locDecayingParticleDerivedP4.Vect().Cross(locH);
3228
3229 if(dDebugLevel > 30)
3230 cout << "q, mass, sign, pxyzE = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << ", " << locSignMultiplier << ", " << locP4.Px() << ", " << locP4.Py() << ", " << locP4.Pz() << ", " << locP4.E() << endl;
3231
3232 if(locKinFitParticleType == d_TargetParticle)
3233 {
3234 if(dDebugLevel > 30)
3235 cout << "DKinFitter: Calc_dF_MassDerivs() Section 1; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3236 return; //target params are fixed: no partial derivatives
3237 }
3238 else if(locChargedBFieldFlag && locEnoughVertexFitsFlag && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)))
3239 {
3240 //detected charged particle in b-field (can be beam particle) & in vertex fit
3241 if(dDebugLevel > 30)
3242 cout << "DKinFitter: Calc_dF_MassDerivs() Section 2; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3243
3244 dF_dEta(locFIndex, locPxParamIndex) = 2.0*locSignMultiplier*(locP4.Px()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Px());
3245 dF_dEta(locFIndex, locPxParamIndex + 1) = 2.0*locSignMultiplier*(locP4.Py()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Py());
3246 dF_dEta(locFIndex, locPxParamIndex + 2) = 2.0*locSignMultiplier*(locP4.Pz()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Pz());
3247
3248 dF_dEta(locFIndex, locVxParamIndex) = 2.0*locSignMultiplier*locA*locPXCrossHi.X();
3249 dF_dEta(locFIndex, locVxParamIndex + 1) = 2.0*locSignMultiplier*locA*locPXCrossHi.Y();
3250 dF_dEta(locFIndex, locVxParamIndex + 2) = 2.0*locSignMultiplier*locA*locPXCrossHi.Z();
3251
3252 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3253 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3254 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3255 }
3256 else if(locNeutralShowerFlag)
3257 {
3258 if(dDebugLevel > 30)
3259 cout << "DKinFitter: Calc_dF_MassDerivs() Section 3; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3260
3261 double locEOverPSq = locP4.E()/locP4.Vect().Mag2();
3262 dF_dEta(locFIndex, locEParamIndex) = 2.0*locSignMultiplier*(locDecayingParticleDerivedP4.E() - locEOverPSq*locDecayingParticleDerivedP4.Vect().Dot(locP4.Vect()));
3263
3264 double locDeltaXDotPXOverMagDeltaXSq = locDeltaX.Dot(locDecayingParticleDerivedP4.Vect())/(locDeltaX.Mag2());
3265 dF_dEta(locFIndex, locVxParamIndex) = 2.0*locSignMultiplier*locP4.Px()*(locDecayingParticleDerivedP4.Px()/locDeltaX.X() - locDeltaXDotPXOverMagDeltaXSq);
3266 dF_dEta(locFIndex, locVxParamIndex + 1) = 2.0*locSignMultiplier*locP4.Py()*(locDecayingParticleDerivedP4.Py()/locDeltaX.Y() - locDeltaXDotPXOverMagDeltaXSq);
3267 dF_dEta(locFIndex, locVxParamIndex + 2) = 2.0*locSignMultiplier*locP4.Pz()*(locDecayingParticleDerivedP4.Pz()/locDeltaX.Z() - locDeltaXDotPXOverMagDeltaXSq);
3268
3269 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3270 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3271 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3272 }
3273 else if((locKinFitParticleType == d_MissingParticle) || ((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex >= 0)))
3274 {
3275 //missing or open-ended-decaying particle: p3 is unknown (not derivable) //must be the constrained particle
3276 if(dDebugLevel > 30)
3277 cout << "DKinFitter: Calc_dF_MassDerivs() Section 4; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3278
3279 dF_dXi(locFIndex, locPxParamIndex) = 2.0*locSignMultiplier*(locP4.Px()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Px());
3280 dF_dXi(locFIndex, locPxParamIndex + 1) = 2.0*locSignMultiplier*(locP4.Py()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Py());
3281 dF_dXi(locFIndex, locPxParamIndex + 2) = 2.0*locSignMultiplier*(locP4.Pz()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Pz());
3282 }
3283 else if(locKinFitParticleType == d_DecayingParticle)
3284 {
3285 //enclosed decaying particle
3286 if(dDebugLevel > 30)
3287 cout << "DKinFitter: Calc_dF_MassDerivs() Section 5; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3288 if((locCharge != 0) && Get_IsBFieldNearBeamline() && (locKinFitParticle->Get_NumVertexFits() == 2) && (locKinFitSubConstraint_P4 != NULL__null))
3289 {
3290 //if locKinFitSubConstraint_P4 is NULL is first particle; don't include: replace it
3291 if(dDebugLevel > 30)
3292 cout << "DKinFitter: Calc_dF_MassDerivs() Section 5a" << endl;
3293
3294 dF_dXi(locFIndex, locVxParamIndex) += 2.0*locSignMultiplier*locA*locPXCrossHi.X();
3295 dF_dXi(locFIndex, locVxParamIndex + 1) += 2.0*locSignMultiplier*locA*locPXCrossHi.Y();
3296 dF_dXi(locFIndex, locVxParamIndex + 2) += 2.0*locSignMultiplier*locA*locPXCrossHi.Z();
3297
3298 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dXi(locFIndex, locVxParamIndex);
3299 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex, locVxParamIndex + 1);
3300 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex, locVxParamIndex + 2);
3301 }
3302
3303 deque<DKinFitConstraint_P4*> locP4Constraints = locKinFitParticle->dP4Constraints;
3304 for(size_t loc_i = 0; loc_i < locP4Constraints.size(); ++loc_i)
3305 {
3306 DKinFitConstraint_P4* locNewKinFitSubConstraint_P4 = locP4Constraints[loc_i];
3307 if(locNewKinFitSubConstraint_P4 == locKinFitConstraint_P4)
3308 continue;
3309 if(locNewKinFitSubConstraint_P4 == locKinFitSubConstraint_P4)
3310 continue;
3311
3312 //if this constraint contains the decaying particle, replace it with the other particles it's momentum is derived from
3313 deque<DKinFitParticle*> locInitialParticles = locNewKinFitSubConstraint_P4->dInitialParticles;
3314 deque<DKinFitParticle*> locFinalParticles = locNewKinFitSubConstraint_P4->dFinalParticles;
3315 for(size_t loc_j = 0; loc_j < locInitialParticles.size(); ++loc_j)
3316 {
3317 if(locInitialParticles[loc_j] == locKinFitParticle)
3318 continue;
3319 //detected: +/- if init/final
3320 //p-replacement: factor of +/- if same/different state
3321 //so if ORIG decaying was init/final (+/-), and detected is init (+), then should call as if it was (+/+): init
3322 //so if ORIG decaying was init/final (+/-), and detected is final (-), then should call as if it was (-/-): final
3323 if(dDebugLevel > 30)
3324 cout << "decaying, partially replace with init-state q, mass = " << locInitialParticles[loc_j]->Get_Charge() << ", " << locInitialParticles[loc_j]->Get_Mass() << endl;
3325 Calc_dF_MassDerivs(locKinFitConstraint_P4, locInitialParticles[loc_j], locDecayingParticleDerivedP4, true, locIsInvariantMassConstraint, locNewKinFitSubConstraint_P4); //else !locInitialStateFlag
3326 }
3327 for(size_t loc_j = 0; loc_j < locFinalParticles.size(); ++loc_j)
3328 {
3329 if(locFinalParticles[loc_j] == locKinFitParticle)
3330 continue;
3331 if(dDebugLevel > 30)
3332 cout << "decaying, partially replace with final-state q, mass = " << locFinalParticles[loc_j]->Get_Charge() << ", " << locFinalParticles[loc_j]->Get_Mass() << endl;
3333 Calc_dF_MassDerivs(locKinFitConstraint_P4, locFinalParticles[loc_j], locDecayingParticleDerivedP4, false, locIsInvariantMassConstraint, locNewKinFitSubConstraint_P4);
3334 }
3335 }
3336 }
3337 else
3338 {
3339 // either no common vertex constraint, charged and detected but b-field = 0, or neutral particle with pre-ordained vertex (e.g. beam particle)
3340 if(dDebugLevel > 30)
3341 cout << "DKinFitter: Calc_dF_MassDerivs() Section 6; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3342
3343 dF_dEta(locFIndex, locPxParamIndex) = 2.0*locSignMultiplier*(locP4.Px()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Px());
3344 dF_dEta(locFIndex, locPxParamIndex + 1) = 2.0*locSignMultiplier*(locP4.Py()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Py());
3345 dF_dEta(locFIndex, locPxParamIndex + 2) = 2.0*locSignMultiplier*(locP4.Pz()*locDecayingParticleDerivedP4.E()/locP4.E() - locDecayingParticleDerivedP4.Pz());
3346 }
3347}
3348
3349void DKinFitter::Calc_dF_Vertex(size_t locFIndex, const DKinFitParticle* locKinFitParticle, const DKinFitParticle* locKinFitParticle_DecayingSource, bool locInitialStateFlag, bool locOriginalInitialStateFlag)
3350{
3351 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3352
3353 if(locKinFitParticleType == d_TargetParticle)
3354 {
3355 if(dDebugLevel > 30)
3356 cout << "DKinFitter: Calc_dF_Vertex() Section 1; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3357 return; //no partial derivatives
3358 }
3359
3360 if(locKinFitParticle_DecayingSource == NULL__null)
3361 Calc_dF_Vertex_NotDecaying(locFIndex, locKinFitParticle);
3362 else
3363 {
3364 int locCharge = locKinFitParticle_DecayingSource->Get_Charge();
3365 if((locCharge != 0) && Get_IsBFieldNearBeamline())
3366 Calc_dF_Vertex_Decaying_Accel(locFIndex, locKinFitParticle, locKinFitParticle_DecayingSource, locInitialStateFlag, locOriginalInitialStateFlag);
3367 else
3368 Calc_dF_Vertex_Decaying_NonAccel(locFIndex, locKinFitParticle, locKinFitParticle_DecayingSource, locInitialStateFlag, locOriginalInitialStateFlag);
3369 }
3370
3371 if(locKinFitParticleType == d_DecayingParticle)
3372 {
3373 //replace the momentum with it's component tracks
3374 deque<DKinFitConstraint_P4*> locP4Constraints = locKinFitParticle->dP4Constraints;
3375 DKinFitConstraint_P4* locKinFitConstraint_P4 = NULL__null;
3376
3377 //true if the object's p3, v3, & t are defined at its production vertex (when its a final state particle). else at it's decay vertex (when initial state)
3378 bool locAtProductionVertexFlag = locKinFitParticle->Get_DecayingParticleAtProductionVertexFlag();
3379
3380 // find the p4 constraint where the decaying particle momentum is defined //this is the point where the position is defined as well
3381 //why this constraint? because if you choose the other one, the momentum has to be propagated across a distance, requiring a different (& MUCH more complicated) partial derivative
3382 for(size_t loc_i = 0; loc_i < locP4Constraints.size(); ++loc_i)
3383 {
3384 deque<const DKinFitParticle*> locParticlesToSearch = locAtProductionVertexFlag ? locP4Constraints[loc_i]->Get_FinalParticles() : locP4Constraints[loc_i]->Get_InitialParticles();
3385 bool locMatchFoundFlag = false;
3386 for(size_t loc_j = 0; loc_j < locParticlesToSearch.size(); ++loc_j)
3387 {
3388 if(locParticlesToSearch[loc_j] != locKinFitParticle)
3389 continue;
3390 locMatchFoundFlag = true;
3391 break;
3392 }
3393 if(!locMatchFoundFlag)
3394 continue;
3395 locKinFitConstraint_P4 = locP4Constraints[loc_i];
3396 break;
3397 }
3398 if(locKinFitConstraint_P4 == NULL__null)
3399 return; //shouldn't be possible...
3400
3401 //ok, now replace the contribution of the decay particle with that of the other particles it's momentum is derived from
3402 deque<DKinFitParticle*> locInitialParticles = locKinFitConstraint_P4->dInitialParticles;
3403 deque<DKinFitParticle*> locFinalParticles = locKinFitConstraint_P4->dFinalParticles;
3404 for(size_t loc_j = 0; loc_j < locInitialParticles.size(); ++loc_j)
3405 {
3406 if(locInitialParticles[loc_j] == locKinFitParticle)
3407 continue;
3408//detected: +/- if init/final
3409//p-replacement: factor of +/- if same/different state
3410//so if ORIG decaying was init/final (+/-), and detected is init (+), then should call as if it was (+/+): init
3411//so if ORIG decaying was init/final (+/-), and detected is final (-), then should call as if it was (-/-): final
3412 if(dDebugLevel > 30)
3413 cout << "decaying, partially replace with init-state q, mass = " << locInitialParticles[loc_j]->Get_Charge() << ", " << locInitialParticles[loc_j]->Get_Mass() << endl;
3414 Calc_dF_Vertex(locFIndex, locInitialParticles[loc_j], locKinFitParticle, true, locOriginalInitialStateFlag);
3415 }
3416 for(size_t loc_j = 0; loc_j < locFinalParticles.size(); ++loc_j)
3417 {
3418 if(locFinalParticles[loc_j] == locKinFitParticle)
3419 continue;
3420 if(dDebugLevel > 30)
3421 cout << "decaying, partially replace with final-state q, mass = " << locFinalParticles[loc_j]->Get_Charge() << ", " << locFinalParticles[loc_j]->Get_Mass() << endl;
3422 Calc_dF_Vertex(locFIndex, locFinalParticles[loc_j], locKinFitParticle, false, locOriginalInitialStateFlag);
3423 }
3424 }
3425}
3426
3427void DKinFitter::Calc_dF_Vertex_NotDecaying(size_t locFIndex, const DKinFitParticle* locKinFitParticle)
3428{
3429 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3430 int locCharge = locKinFitParticle->Get_Charge();
3431
3432 TVector3 locPosition = locKinFitParticle->Get_Position();
3433 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
3434 TVector3 locDeltaX = locCommonVertex - locPosition;
3435 TVector3 locMomentum = locKinFitParticle->Get_Momentum();
3436
3437 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
3438 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
3439 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
3440
3441 if((locCharge != 0) && Get_IsBFieldNearBeamline() && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle))) //DONE
3442 {
3443 //detected charged particle in b-field (can be beam particle)
3444 if(dDebugLevel > 30)
3445 cout << "DKinFitter: Calc_dF_Vertex() Section 2; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3446
3447 TVector3 locBField = Get_BField(locPosition);
3448 TVector3 locH = locBField.Unit();
3449 TVector3 locPCrossH = locMomentum.Cross(locH);
3450 TVector3 locPCrossDeltaX = locMomentum.Cross(locDeltaX);
3451 TVector3 locDeltaXCrossH = locDeltaX.Cross(locH);
3452
3453 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3454 double locDeltaXDotH = locDeltaX.Dot(locH);
3455 double locPDotH = locMomentum.Dot(locH);
3456
3457 TVector3 locQ, locM, locD;
3458 double locJ;
3459 Calc_Vertex_Params(locKinFitParticle, locJ, locQ, locM, locD);
3460
3461 dF(locFIndex, 0) = locPCrossDeltaX.Dot(locH) - 0.5*locA*(locDeltaX.Mag2() - locDeltaXDotH*locDeltaXDotH);
3462 dF(locFIndex + 1, 0) = locDeltaXDotH - (locPDotH/locA)*asin(locJ);
3463
3464 dF_dEta(locFIndex, locPxParamIndex) = locDeltaXCrossH.X();
3465 dF_dEta(locFIndex, locPxParamIndex + 1) = locDeltaXCrossH.Y();
3466 dF_dEta(locFIndex, locPxParamIndex + 2) = locDeltaXCrossH.Z();
3467
3468 dF_dEta(locFIndex, locVxParamIndex) = (locPCrossH + locA*locM).X();
3469 dF_dEta(locFIndex, locVxParamIndex + 1) = (locPCrossH + locA*locM).Y();
3470 dF_dEta(locFIndex, locVxParamIndex + 2) = (locPCrossH + locA*locM).Z();
3471
3472 dF_dEta(locFIndex + 1, locPxParamIndex) = locQ.X();
3473 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = locQ.Y();
3474 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locQ.Z();
3475
3476 dF_dEta(locFIndex + 1, locVxParamIndex) = locD.X();
3477 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locD.Y();
3478 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locD.Z();
3479
3480 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3481 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3482 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3483
3484 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
3485 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3486 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3487 }
3488 else if((locCharge != 0) && Get_IsBFieldNearBeamline() && (locKinFitParticleType == d_DecayingParticle)) //DONE
3489 {
3490 //constraining this decaying charged particle in b-field //one-time contributions from decaying particle, does not include the particles it is replaced by (elsewhere)
3491 if(dDebugLevel > 30)
3492 cout << "DKinFitter: Calc_dF_Vertex() Section 3; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3493
3494 TVector3 locQ, locM, locD;
3495 double locJ;
3496 Calc_Vertex_Params(locKinFitParticle, locJ, locQ, locM, locD);
3497
3498 TVector3 locBField = Get_BField(locPosition);
3499 TVector3 locH = locBField.Unit();
3500 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3501
3502 TVector3 locPCrossH = locMomentum.Cross(locH);
3503 TVector3 locPCrossDeltaX = locMomentum.Cross(locDeltaX);
3504 double locDeltaXDotH = locDeltaX.Dot(locH);
3505 double locPDotH = locMomentum.Dot(locH);
3506
3507 dF(locFIndex, 0) = locPCrossDeltaX.Dot(locH) - 0.5*locA*(locDeltaX.Mag2() - locDeltaXDotH*locDeltaXDotH);
3508 dF(locFIndex + 1, 0) = locDeltaXDotH - (locPDotH/locA)*asin(locJ);
3509
3510 dF_dXi(locFIndex, locVxParamIndex) = locPCrossH.X() + locA*locM.X();
3511 dF_dXi(locFIndex, locVxParamIndex + 1) = locPCrossH.Y() + locA*locM.Y();
3512 dF_dXi(locFIndex, locVxParamIndex + 2) = locPCrossH.Z() + locA*locM.Z();
3513
3514 dF_dXi(locFIndex + 1, locVxParamIndex) = locD.X();
3515 dF_dXi(locFIndex + 1, locVxParamIndex + 1) = locD.Y();
3516 dF_dXi(locFIndex + 1, locVxParamIndex + 2) = locD.Z();
3517
3518 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dXi(locFIndex, locVxParamIndex);
3519 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex, locVxParamIndex + 1);
3520 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex, locVxParamIndex + 2);
3521
3522 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dXi(locFIndex + 1, locVxParamIndex);
3523 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex + 1, locVxParamIndex + 1);
3524 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex + 1, locVxParamIndex + 2);
3525 }
3526 else if(locKinFitParticleType == d_DecayingParticle) //non-accel decaying particle //DONE
3527 {
3528 //constraining this decaying non-accel particle //one-time contributions from decaying particle, does not include the particles it is replaced by (elsewhere)
3529
3530 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
3531 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
3532 {
3533 dF(locFIndex, 0) = locMomentum.Y()*locDeltaX.Z() - locMomentum.Z()*locDeltaX.Y();
3534 dF(locFIndex + 1, 0) = locMomentum.Z()*locDeltaX.X() - locMomentum.X()*locDeltaX.Z();
3535
3536 if(dDebugLevel > 30)
3537 cout << "DKinFitter: Calc_dF_Vertex() Section 4a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3538
3539 dF_dXi(locFIndex, locVxParamIndex + 1) = locMomentum.Z();
3540 dF_dXi(locFIndex, locVxParamIndex + 2) = -1.0*locMomentum.Y();
3541 dF_dXi(locFIndex + 1, locVxParamIndex) = -1.0*locMomentum.Z();
3542 dF_dXi(locFIndex + 1, locVxParamIndex + 2) = locMomentum.X();
3543
3544 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = -1.0*dF_dXi(locFIndex, locVxParamIndex + 1);
3545 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dXi(locFIndex, locVxParamIndex + 2);
3546 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex);
3547 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex + 2);
3548 }
3549 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
3550 {
3551 dF(locFIndex, 0) = locMomentum.Y()*locDeltaX.Z() - locMomentum.Z()*locDeltaX.Y();
3552 dF(locFIndex + 1, 0) = locMomentum.X()*locDeltaX.Y() - locMomentum.Y()*locDeltaX.X();
3553
3554 if(dDebugLevel > 30)
3555 cout << "DKinFitter: Calc_dF_Vertex() Section 4b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3556
3557 dF_dXi(locFIndex, locVxParamIndex + 1) = locMomentum.Z();
3558 dF_dXi(locFIndex, locVxParamIndex + 2) = -1.0*locMomentum.Y();
3559 dF_dXi(locFIndex + 1, locVxParamIndex) = locMomentum.Y();
3560 dF_dXi(locFIndex + 1, locVxParamIndex + 1) = -1.0*locMomentum.X();
3561
3562 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = -1.0*dF_dXi(locFIndex, locVxParamIndex + 1);
3563 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dXi(locFIndex, locVxParamIndex + 2);
3564 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex);
3565 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex + 1);
3566 }
3567 else //2 & 3 //px is largest
3568 {
3569 dF(locFIndex, 0) = locMomentum.Z()*locDeltaX.X() - locMomentum.X()*locDeltaX.Z();
3570 dF(locFIndex + 1, 0) = locMomentum.X()*locDeltaX.Y() - locMomentum.Y()*locDeltaX.X();
3571
3572 if(dDebugLevel > 30)
3573 cout << "DKinFitter: Calc_dF_Vertex() Section 4c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3574
3575 dF_dXi(locFIndex, locVxParamIndex) = -1.0*locMomentum.Z();
3576 dF_dXi(locFIndex, locVxParamIndex + 2) = locMomentum.X();
3577 dF_dXi(locFIndex + 1, locVxParamIndex) = locMomentum.Y();
3578 dF_dXi(locFIndex + 1, locVxParamIndex + 1) = -1.0*locMomentum.X();
3579
3580 dF_dXi(locFIndex, locCommonVxParamIndex) = -1.0*dF_dXi(locFIndex, locVxParamIndex);
3581 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dXi(locFIndex, locVxParamIndex + 2);
3582 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex);
3583 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex + 1);
3584 }
3585 }
3586 else //neutral detected or beam particle, or no magnetic field //DONE
3587 {
3588 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
3589 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
3590 {
3591 dF(locFIndex, 0) = locMomentum.Y()*locDeltaX.Z() - locMomentum.Z()*locDeltaX.Y();
3592 dF(locFIndex + 1, 0) = locMomentum.Z()*locDeltaX.X() - locMomentum.X()*locDeltaX.Z();
3593
3594 if(dDebugLevel > 30)
3595 cout << "DKinFitter: Calc_dF_Vertex() Section 5a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3596
3597 dF_dEta(locFIndex, locPxParamIndex + 1) = locDeltaX.Z();
3598 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX.Y();
3599 dF_dEta(locFIndex + 1, locPxParamIndex) = -1.0*locDeltaX.Z();
3600 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locDeltaX.X();
3601
3602 dF_dEta(locFIndex, locVxParamIndex + 1) = locMomentum.Z();
3603 dF_dEta(locFIndex, locVxParamIndex + 2) = -1.0*locMomentum.Y();
3604 dF_dEta(locFIndex + 1, locVxParamIndex) = -1.0*locMomentum.Z();
3605 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locMomentum.X();
3606
3607 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 1);
3608 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 2);
3609 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex);
3610 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3611 }
3612 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
3613 {
3614 dF(locFIndex, 0) = locMomentum.Y()*locDeltaX.Z() - locMomentum.Z()*locDeltaX.Y();
3615 dF(locFIndex + 1, 0) = locMomentum.X()*locDeltaX.Y() - locMomentum.Y()*locDeltaX.X();
3616
3617 if(dDebugLevel > 30)
3618 cout << "DKinFitter: Calc_dF_Vertex() Section 5b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3619
3620 dF_dEta(locFIndex, locPxParamIndex + 1) = locDeltaX.Z();
3621 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX.Y();
3622 dF_dEta(locFIndex + 1, locPxParamIndex) = locDeltaX.Y();
3623 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX.X();
3624
3625 dF_dEta(locFIndex, locVxParamIndex + 1) = locMomentum.Z();
3626 dF_dEta(locFIndex, locVxParamIndex + 2) = -1.0*locMomentum.Y();
3627 dF_dEta(locFIndex + 1, locVxParamIndex) = locMomentum.Y();
3628 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0*locMomentum.X();
3629
3630 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 1);
3631 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 2);
3632 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex);
3633 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3634 }
3635 else //2 & 3 //px is largest
3636 {
3637 dF(locFIndex, 0) = locMomentum.Z()*locDeltaX.X() - locMomentum.X()*locDeltaX.Z();
3638 dF(locFIndex + 1, 0) = locMomentum.X()*locDeltaX.Y() - locMomentum.Y()*locDeltaX.X();
3639
3640 if(dDebugLevel > 30)
3641 cout << "DKinFitter: Calc_dF_Vertex() Section 5c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3642
3643 dF_dEta(locFIndex, locPxParamIndex) = -1.0*locDeltaX.Z();
3644 dF_dEta(locFIndex, locPxParamIndex + 2) = locDeltaX.X();
3645 dF_dEta(locFIndex + 1, locPxParamIndex) = locDeltaX.Y();
3646 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX.X();
3647
3648 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locMomentum.Z();
3649 dF_dEta(locFIndex, locVxParamIndex + 2) = locMomentum.X();
3650 dF_dEta(locFIndex + 1, locVxParamIndex) = locMomentum.Y();
3651 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0*locMomentum.X();
3652
3653 dF_dXi(locFIndex, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex, locVxParamIndex);
3654 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 2);
3655 dF_dXi(locFIndex + 1, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex);
3656 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3657 }
3658 }
3659}
3660
3661void DKinFitter::Calc_dF_Vertex_Decaying_Accel(size_t locFIndex, const DKinFitParticle* locKinFitParticle, const DKinFitParticle* locKinFitParticle_DecayingSource, bool locInitialStateFlag, bool locOriginalInitialStateFlag)
3662{
3663 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3664 int locCharge = locKinFitParticle->Get_Charge();
3665
3666 double locEnergy = locKinFitParticle->Get_P4().E();
3667 TVector3 locPosition = locKinFitParticle->Get_Position();
3668 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
3669 TVector3 locDeltaX = locCommonVertex - locPosition;
3670 TVector3 locMomentum = locKinFitParticle->Get_Momentum();
3671
3672 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
3673 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
3674 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
3675 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
3676
3677 if((locCharge != 0) && Get_IsBFieldNearBeamline() && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle))) //DONE
3678 {
3679 //detected charged particle in b-field (can be beam particle)
3680 if(dDebugLevel > 30)
3681 cout << "DKinFitter: Calc_dF_Vertex() Section 6; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3682
3683 TVector3 locQ, locM, locD;
3684 double locJ;
3685 Calc_Vertex_Params(locKinFitParticle_DecayingSource, locJ, locQ, locM, locD);
3686
3687 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3688 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3689 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3690 TVector3 locMomentum_DecayingSource = locKinFitParticle_DecayingSource->Get_Momentum();
3691
3692 TVector3 locBField_DecayingSource = Get_BField(locPosition_DecayingSource);
3693 TVector3 locH_DecayingSource = locBField_DecayingSource.Unit();
3694 TVector3 locBField = Get_BField(locPosition);
3695 TVector3 locH = locBField.Unit();
3696 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3697
3698 TVector3 locDeltaXCrossH_DecayingSource = locDeltaX_DecayingSource.Cross(locH_DecayingSource);
3699 TVector3 locDeltaXCrossH_DecayingSource_CrossH = locDeltaXCrossH_DecayingSource.Cross(locH);
3700 TVector3 locQCrossH = locQ.Cross(locH);
3701
3702 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3703
3704 dF_dEta(locFIndex, locPxParamIndex) = locSignMultiplier*locDeltaXCrossH_DecayingSource.X();
3705 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Y();
3706 dF_dEta(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Z();
3707
3708 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.X();
3709 dF_dEta(locFIndex, locVxParamIndex + 1) = -1.0*locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.Y();
3710 dF_dEta(locFIndex, locVxParamIndex + 2) = -1.0*locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.Z();
3711
3712 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier*locQ.X();
3713 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = locSignMultiplier*locQ.Y();
3714 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locSignMultiplier*locQ.Z();
3715
3716 dF_dEta(locFIndex + 1, locVxParamIndex) = -1.0*locSignMultiplier*locA*locQCrossH.X();
3717 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0*locSignMultiplier*locA*locQCrossH.Y();
3718 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = -1.0*locSignMultiplier*locA*locQCrossH.Z();
3719
3720 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3721 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3722 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3723
3724 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
3725 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3726 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3727 }
3728 else if(locKinFitParticle->Get_IsNeutralShowerFlag()) //DONE
3729 {
3730 if(dDebugLevel > 30)
3731 cout << "DKinFitter: Calc_dF_Vertex() Section 7; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3732
3733 TVector3 locQ, locM, locD;
3734 double locJ;
3735 Calc_Vertex_Params(locKinFitParticle, locJ, locQ, locM, locD);
3736
3737 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3738 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3739 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3740 TVector3 locMomentum_DecayingSource = locKinFitParticle_DecayingSource->Get_Momentum();
3741
3742 TVector3 locBField_DecayingSource = Get_BField(locPosition_DecayingSource);
3743 TVector3 locH_DecayingSource = locBField_DecayingSource.Unit();
3744
3745 TVector3 locDeltaXCrossH_DecayingSource = locDeltaX_DecayingSource.Cross(locH_DecayingSource);
3746 double locXTerm = locDeltaXCrossH_DecayingSource.Dot(locDeltaX)/(locDeltaX.Mag2());
3747 double locQTerm = locQ.Dot(locDeltaX)/(locDeltaX.Mag2());
3748
3749 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3750
3751 dF_dEta(locFIndex, locEParamIndex) = locSignMultiplier*locEnergy*(locDeltaXCrossH_DecayingSource.Dot(locMomentum))/(locMomentum.Mag2());
3752 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locSignMultiplier*locMomentum.Px()*(locDeltaXCrossH_DecayingSource.X()/(locDeltaX.X()) - locXTerm);
3753 dF_dEta(locFIndex, locVxParamIndex + 1) = -1.0*locSignMultiplier*locMomentum.Py()*(locDeltaXCrossH_DecayingSource.Y()/(locDeltaX.Y()) - locXTerm);
3754 dF_dEta(locFIndex, locVxParamIndex + 2) = -1.0*locSignMultiplier*locMomentum.Pz()*(locDeltaXCrossH_DecayingSource.Z()/(locDeltaX.Z()) - locXTerm);
3755
3756 dF_dEta(locFIndex + 1, locEParamIndex) = locSignMultiplier*locEnergy*(locMomentum.Dot(locQ))/(locMomentum.Mag2());
3757 dF_dEta(locFIndex + 1, locVxParamIndex) = -1.0*locSignMultiplier*locMomentum.Px()*(locQ.X()/(locDeltaX.X()) - locQTerm);
3758 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0*locSignMultiplier*locMomentum.Py()*(locQ.Y()/(locDeltaX.Y()) - locQTerm);
3759 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = -1.0*locSignMultiplier*locMomentum.Pz()*(locQ.Z()/(locDeltaX.Z()) - locQTerm);
3760
3761 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3762 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3763 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3764
3765 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
3766 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3767 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3768 }
3769 else if((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)) //DONE
3770 {
3771 if(dDebugLevel > 30)
3772 cout << "DKinFitter: Calc_dF_Vertex() Section 8; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3773
3774 //detected/beam, non-accelerating particle
3775 TVector3 locQ, locM, locD;
3776 double locJ;
3777 Calc_Vertex_Params(locKinFitParticle_DecayingSource, locJ, locQ, locM, locD);
3778
3779 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3780 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3781 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3782 TVector3 locMomentum_DecayingSource = locKinFitParticle_DecayingSource->Get_Momentum();
3783
3784 TVector3 locBField_DecayingSource = Get_BField(locPosition_DecayingSource);
3785 TVector3 locH_DecayingSource = locBField_DecayingSource.Unit();
3786
3787 TVector3 locDeltaXCrossH_DecayingSource = locDeltaX_DecayingSource.Cross(locH_DecayingSource);
3788
3789 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3790
3791 dF_dEta(locFIndex, locPxParamIndex) = locSignMultiplier*locDeltaXCrossH_DecayingSource.X();
3792 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Y();
3793 dF_dEta(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Z();
3794
3795 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier*locQ.X();
3796 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = locSignMultiplier*locQ.Y();
3797 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locSignMultiplier*locQ.Z();
3798 }
3799 else if(locKinFitParticleType == d_MissingParticle) //DONE
3800 {
3801 if(dDebugLevel > 30)
3802 cout << "DKinFitter: Calc_dF_Vertex() Section 9; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3803
3804 //missing particle
3805 TVector3 locQ, locM, locD;
3806 double locJ;
3807 Calc_Vertex_Params(locKinFitParticle_DecayingSource, locJ, locQ, locM, locD);
3808
3809 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3810 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3811 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3812 TVector3 locMomentum_DecayingSource = locKinFitParticle_DecayingSource->Get_Momentum();
3813
3814 TVector3 locBField_DecayingSource = Get_BField(locPosition_DecayingSource);
3815 TVector3 locH_DecayingSource = locBField_DecayingSource.Unit();
3816
3817 TVector3 locDeltaXCrossH_DecayingSource = locDeltaX_DecayingSource.Cross(locH_DecayingSource);
3818
3819 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3820
3821 dF_dXi(locFIndex, locPxParamIndex) = locSignMultiplier*locDeltaXCrossH_DecayingSource.X();
3822 dF_dXi(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Y();
3823 dF_dXi(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locDeltaXCrossH_DecayingSource.Z();
3824
3825 dF_dXi(locFIndex + 1, locPxParamIndex) = locSignMultiplier*locQ.X();
3826 dF_dXi(locFIndex + 1, locPxParamIndex + 1) = locSignMultiplier*locQ.Y();
3827 dF_dXi(locFIndex + 1, locPxParamIndex + 2) = locSignMultiplier*locQ.Z();
3828 }
3829 else if((locCharge != 0) && Get_IsBFieldNearBeamline() && (locKinFitParticleType == d_DecayingParticle)) //DONE
3830 {
3831 //decaying charged particle in b-field (doesn't include contributions from the particles it is replaced by here)
3832 if(dDebugLevel > 30)
3833 cout << "DKinFitter: Calc_dF_Vertex() Section 10; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3834
3835 TVector3 locQ, locM, locD;
3836 double locJ;
3837 Calc_Vertex_Params(locKinFitParticle_DecayingSource, locJ, locQ, locM, locD);
3838
3839 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3840 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3841 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3842 TVector3 locMomentum_DecayingSource = locKinFitParticle_DecayingSource->Get_Momentum();
3843
3844 TVector3 locBField_DecayingSource = Get_BField(locPosition_DecayingSource);
3845 TVector3 locH_DecayingSource = locBField_DecayingSource.Unit();
3846 TVector3 locBField = Get_BField(locPosition);
3847 TVector3 locH = locBField.Unit();
3848 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3849
3850 TVector3 locDeltaXCrossH_DecayingSource = locDeltaX_DecayingSource.Cross(locH_DecayingSource);
3851 TVector3 locDeltaXCrossH_DecayingSource_CrossH = locDeltaXCrossH_DecayingSource.Cross(locH);
3852 TVector3 locQCrossH = locQ.Cross(locH);
3853
3854 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3855
3856 dF_dXi(locFIndex, locVxParamIndex) -= locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.X();
3857 dF_dXi(locFIndex, locVxParamIndex + 1) -= locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.Y();
3858 dF_dXi(locFIndex, locVxParamIndex + 2) -= locSignMultiplier*locA*locDeltaXCrossH_DecayingSource_CrossH.Z();
3859
3860 dF_dXi(locFIndex + 1, locVxParamIndex) -= locSignMultiplier*locA*locQCrossH.X();
3861 dF_dXi(locFIndex + 1, locVxParamIndex + 1) -= locSignMultiplier*locA*locQCrossH.Y();
3862 dF_dXi(locFIndex + 1, locVxParamIndex + 2) -= locSignMultiplier*locA*locQCrossH.Z();
3863
3864 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dXi(locFIndex, locVxParamIndex);
3865 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex, locVxParamIndex + 1);
3866 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex, locVxParamIndex + 2);
3867
3868 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dXi(locFIndex + 1, locVxParamIndex);
3869 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex + 1, locVxParamIndex + 1);
3870 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex + 1, locVxParamIndex + 2);
3871 }
3872}
3873
3874void DKinFitter::Calc_dF_Vertex_Decaying_NonAccel(size_t locFIndex, const DKinFitParticle* locKinFitParticle, const DKinFitParticle* locKinFitParticle_DecayingSource, bool locInitialStateFlag, bool locOriginalInitialStateFlag)
3875{
3876 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
3877 int locCharge = locKinFitParticle->Get_Charge();
3878
3879 double locEnergy = locKinFitParticle->Get_P4().E();
3880 TVector3 locPosition = locKinFitParticle->Get_Position();
3881 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
3882 TVector3 locDeltaX = locCommonVertex - locPosition;
3883 TVector3 locMomentum = locKinFitParticle->Get_Momentum();
3884
3885 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
3886 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
3887 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
3888 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
3889
3890 if((locCharge != 0) && Get_IsBFieldNearBeamline() && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle))) //DONE
3891 {
3892 //detected charged particle in b-field (can be beam particle)
3893 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3894 TVector3 locBField = Get_BField(locPosition);
3895 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
3896 TVector3 locH = locBField.Unit();
3897
3898 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3899 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3900 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3901
3902 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
3903 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
3904 {
3905 if(dDebugLevel > 30)
3906 cout << "DKinFitter: Calc_dF_Vertex() Section 11a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3907
3908 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locDeltaX_DecayingSource.Z();
3909 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.Y();
3910 dF_dEta(locFIndex + 1, locPxParamIndex) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.Z();
3911 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locSignMultiplier*locDeltaX_DecayingSource.X();
3912
3913 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.Y()*locH.Y() + locDeltaX_DecayingSource.Z()*locH.Z());
3914 dF_dEta(locFIndex, locVxParamIndex + 1) = locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.X();
3915 dF_dEta(locFIndex, locVxParamIndex + 2) = locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.X();
3916 dF_dEta(locFIndex + 1, locVxParamIndex) = locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Y();
3917 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Z()*locH.Z());
3918 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.Y();
3919 }
3920 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
3921 {
3922 if(dDebugLevel > 30)
3923 cout << "DKinFitter: Calc_dF_Vertex() Section 11b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3924
3925 dF_dEta(locFIndex, locPxParamIndex + 1) = locSignMultiplier*locDeltaX_DecayingSource.Z();
3926 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.Y();
3927 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier*locDeltaX_DecayingSource.Y();
3928 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.X();
3929
3930 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.Y()*locH.Y() + locDeltaX_DecayingSource.Z()*locH.Z());
3931 dF_dEta(locFIndex, locVxParamIndex + 1) = locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.X();
3932 dF_dEta(locFIndex, locVxParamIndex + 2) = locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.X();
3933 dF_dEta(locFIndex + 1, locVxParamIndex) = locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Z();
3934 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.Z();
3935 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Y()*locH.Y());
3936 }
3937 else //2 & 3 //px is largest
3938 {
3939 if(dDebugLevel > 30)
3940 cout << "DKinFitter: Calc_dF_Vertex() Section 11c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3941
3942 dF_dEta(locFIndex, locPxParamIndex) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.Z();
3943 dF_dEta(locFIndex, locPxParamIndex + 2) = locSignMultiplier*locDeltaX_DecayingSource.X();
3944 dF_dEta(locFIndex + 1, locPxParamIndex) = locSignMultiplier*locDeltaX_DecayingSource.Y();
3945 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locSignMultiplier*locDeltaX_DecayingSource.X();
3946
3947 dF_dEta(locFIndex, locVxParamIndex) = locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Y();
3948 dF_dEta(locFIndex, locVxParamIndex + 1) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Z()*locH.Z());
3949 dF_dEta(locFIndex, locVxParamIndex + 2) = locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.Y();
3950 dF_dEta(locFIndex + 1, locVxParamIndex) = locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Z();
3951 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.Z();
3952 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = -1.0*locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Y()*locH.Y());
3953 }
3954 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
3955 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
3956 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
3957 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
3958 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
3959 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
3960 }
3961 else if(locKinFitParticle->Get_IsNeutralShowerFlag()) //DONE
3962 {
3963 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
3964 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
3965 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
3966
3967 TVector3 locPiCrossDeltaXX = locMomentum.Cross(locDeltaX_DecayingSource);
3968 TVector3 locDeltaXCrossDeltaXX = locDeltaX.Cross(locDeltaX_DecayingSource);
3969 double locDeltaXiMagSq = locDeltaX.Mag2();
3970 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
3971
3972 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
3973 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
3974 {
3975 if(dDebugLevel > 30)
3976 cout << "DKinFitter: Calc_dF_Vertex() Section 12a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3977
3978 dF_dEta(locFIndex, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.X()/locMomentum.Mag2();
3979 dF_dEta(locFIndex + 1, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.Y()/locMomentum.Mag2();
3980
3981 dF_dEta(locFIndex, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq;
3982 dF_dEta(locFIndex, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq - locMomentum.Y()*locDeltaX_DecayingSource.Z()/locDeltaX.Y();
3983 dF_dEta(locFIndex, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq + locMomentum.Z()*locDeltaX_DecayingSource.Y()/locDeltaX.Z();
3984 dF_dEta(locFIndex + 1, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq + locMomentum.X()*locDeltaX_DecayingSource.Z()/locDeltaX.X();
3985 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq;
3986 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq - locMomentum.Z()*locDeltaX_DecayingSource.X()/locDeltaX.Z();
3987 }
3988 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
3989 {
3990 if(dDebugLevel > 30)
3991 cout << "DKinFitter: Calc_dF_Vertex() Section 12b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
3992
3993 dF_dEta(locFIndex, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.X()/locMomentum.Mag2();
3994 dF_dEta(locFIndex + 1, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.Z()/locMomentum.Mag2();
3995
3996 dF_dEta(locFIndex, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq;
3997 dF_dEta(locFIndex, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq - locMomentum.Y()*locDeltaX_DecayingSource.Z()/locDeltaX.Y();
3998 dF_dEta(locFIndex, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.X()/locDeltaXiMagSq + locMomentum.Z()*locDeltaX_DecayingSource.Y()/locDeltaX.Z();
3999 dF_dEta(locFIndex + 1, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq - locMomentum.X()*locDeltaX_DecayingSource.Y()/locDeltaX.X();
4000 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq + locMomentum.Y()*locDeltaX_DecayingSource.X()/locDeltaX.Y();
4001 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq;
4002 }
4003 else //2 & 3 //px is largest
4004 {
4005 if(dDebugLevel > 30)
4006 cout << "DKinFitter: Calc_dF_Vertex() Section 12c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4007
4008 dF_dEta(locFIndex, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.Y()/locMomentum.Mag2();
4009 dF_dEta(locFIndex + 1, locEParamIndex) = locSignMultiplier*locEnergy*locPiCrossDeltaXX.Z()/locMomentum.Mag2();
4010
4011 dF_dEta(locFIndex, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq + locMomentum.X()*locDeltaX_DecayingSource.Z()/locDeltaX.X();
4012 dF_dEta(locFIndex, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq;
4013 dF_dEta(locFIndex, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.Y()/locDeltaXiMagSq - locMomentum.Z()*locDeltaX_DecayingSource.X()/locDeltaX.Z();
4014 dF_dEta(locFIndex + 1, locVxParamIndex) = locSignMultiplier*locMomentum.X()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq - locMomentum.X()*locDeltaX_DecayingSource.Y()/locDeltaX.X();
4015 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locSignMultiplier*locMomentum.Y()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq + locMomentum.Y()*locDeltaX_DecayingSource.X()/locDeltaX.Y();
4016 dF_dEta(locFIndex + 1, locVxParamIndex + 2) = locSignMultiplier*locMomentum.Z()*locDeltaXCrossDeltaXX.Z()/locDeltaXiMagSq;
4017 }
4018 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dEta(locFIndex, locVxParamIndex);
4019 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex, locVxParamIndex + 1);
4020 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex, locVxParamIndex + 2);
4021 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dEta(locFIndex + 1, locVxParamIndex);
4022 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dEta(locFIndex + 1, locVxParamIndex + 1);
4023 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dEta(locFIndex + 1, locVxParamIndex + 2);
4024 }
4025 else if((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)) //DONE
4026 {
4027 //detected/beam, non-accelerating particle
4028 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
4029 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
4030 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
4031
4032 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
4033 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
4034 {
4035 if(dDebugLevel > 30)
4036 cout << "DKinFitter: Calc_dF_Vertex() Section 13a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4037
4038 dF_dEta(locFIndex, locPxParamIndex + 1) = locDeltaX_DecayingSource.Z();
4039 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX_DecayingSource.Y();
4040 dF_dEta(locFIndex + 1, locPxParamIndex) = -1.0*locDeltaX_DecayingSource.Z();
4041 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locDeltaX_DecayingSource.X();
4042 }
4043 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
4044 {
4045 if(dDebugLevel > 30)
4046 cout << "DKinFitter: Calc_dF_Vertex() Section 13b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4047
4048 dF_dEta(locFIndex, locPxParamIndex + 1) = locDeltaX_DecayingSource.Z();
4049 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX_DecayingSource.Y();
4050 dF_dEta(locFIndex + 1, locPxParamIndex) = locDeltaX_DecayingSource.Y();
4051 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX_DecayingSource.X();
4052 }
4053 else //2 & 3 //px is largest
4054 {
4055 if(dDebugLevel > 30)
4056 cout << "DKinFitter: Calc_dF_Vertex() Section 13c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4057
4058 dF_dEta(locFIndex, locPxParamIndex) = -1.0*locDeltaX_DecayingSource.Z();
4059 dF_dEta(locFIndex, locPxParamIndex + 2) = locDeltaX_DecayingSource.X();
4060 dF_dEta(locFIndex + 1, locPxParamIndex) = locDeltaX_DecayingSource.Y();
4061 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX_DecayingSource.X();
4062 }
4063 }
4064 else if(locKinFitParticleType == d_MissingParticle)
4065 {
4066 //missing
4067 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
4068 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
4069 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
4070
4071 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
4072 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
4073 {
4074 if(dDebugLevel > 30)
4075 cout << "DKinFitter: Calc_dF_Vertex() Section 14a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4076
4077 dF_dXi(locFIndex, locPxParamIndex + 1) = locDeltaX_DecayingSource.Z();
4078 dF_dXi(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX_DecayingSource.Y();
4079 dF_dXi(locFIndex + 1, locPxParamIndex) = -1.0*locDeltaX_DecayingSource.Z();
4080 dF_dXi(locFIndex + 1, locPxParamIndex + 2) = locDeltaX_DecayingSource.X();
4081 }
4082 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
4083 {
4084 if(dDebugLevel > 30)
4085 cout << "DKinFitter: Calc_dF_Vertex() Section 14b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4086
4087 dF_dXi(locFIndex, locPxParamIndex + 1) = locDeltaX_DecayingSource.Z();
4088 dF_dXi(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaX_DecayingSource.Y();
4089 dF_dXi(locFIndex + 1, locPxParamIndex) = locDeltaX_DecayingSource.Y();
4090 dF_dXi(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX_DecayingSource.X();
4091 }
4092 else //2 & 3 //px is largest
4093 {
4094 if(dDebugLevel > 30)
4095 cout << "DKinFitter: Calc_dF_Vertex() Section 14c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4096
4097 dF_dXi(locFIndex, locPxParamIndex) = -1.0*locDeltaX_DecayingSource.Z();
4098 dF_dXi(locFIndex, locPxParamIndex + 2) = locDeltaX_DecayingSource.X();
4099 dF_dXi(locFIndex + 1, locPxParamIndex) = locDeltaX_DecayingSource.Y();
4100 dF_dXi(locFIndex + 1, locPxParamIndex + 1) = -1.0*locDeltaX_DecayingSource.X();
4101 }
4102 }
4103 else if((locCharge != 0) && Get_IsBFieldNearBeamline() && (locKinFitParticleType == d_DecayingParticle)) //DONE
4104 {
4105 //decaying charged particle in b-field (doesn't include contributions from the particles it is replaced by here)
4106 double locSignMultiplier = (locInitialStateFlag == locOriginalInitialStateFlag) ? 1.0 : -1.0;
4107 TVector3 locBField = Get_BField(locPosition);
4108 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
4109 TVector3 locH = locBField.Unit();
4110
4111 TVector3 locPosition_DecayingSource = locKinFitParticle_DecayingSource->Get_Position();
4112 TVector3 locCommonVertex_DecayingSource = locKinFitParticle_DecayingSource->Get_CommonVertex();
4113 TVector3 locDeltaX_DecayingSource = locCommonVertex_DecayingSource - locPosition_DecayingSource;
4114
4115 unsigned short int locVertexConstraintFlag = locKinFitParticle->Get_VertexConstraintFlag();
4116 if(locVertexConstraintFlag == 1) //1 & 2 //pz is largest
4117 {
4118 if(dDebugLevel > 30)
4119 cout << "DKinFitter: Calc_dF_Vertex() Section 15a; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4120
4121 dF_dXi(locFIndex, locVxParamIndex) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.Y()*locH.Y() + locDeltaX_DecayingSource.Z()*locH.Z());
4122 dF_dXi(locFIndex, locVxParamIndex + 1) += locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.X();
4123 dF_dXi(locFIndex, locVxParamIndex + 2) += locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.X();
4124 dF_dXi(locFIndex + 1, locVxParamIndex) += locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Y();
4125 dF_dXi(locFIndex + 1, locVxParamIndex + 1) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Z()*locH.Z());
4126 dF_dXi(locFIndex + 1, locVxParamIndex + 2) += locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.Y();
4127 }
4128 else if(locVertexConstraintFlag == 2) //1 & 3 //py is largest
4129 {
4130 if(dDebugLevel > 30)
4131 cout << "DKinFitter: Calc_dF_Vertex() Section 15b; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4132
4133 dF_dXi(locFIndex, locVxParamIndex) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.Y()*locH.Y() + locDeltaX_DecayingSource.Z()*locH.Z());
4134 dF_dXi(locFIndex, locVxParamIndex + 1) += locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.X();
4135 dF_dXi(locFIndex, locVxParamIndex + 2) += locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.X();
4136 dF_dXi(locFIndex + 1, locVxParamIndex) += locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Z();
4137 dF_dXi(locFIndex + 1, locVxParamIndex + 1) += locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.Z();
4138 dF_dXi(locFIndex + 1, locVxParamIndex + 2) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Y()*locH.Y());
4139 }
4140 else //2 & 3 //px is largest
4141 {
4142 if(dDebugLevel > 30)
4143 cout << "DKinFitter: Calc_dF_Vertex() Section 15c; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4144
4145 dF_dXi(locFIndex, locVxParamIndex) += locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Y();
4146 dF_dXi(locFIndex, locVxParamIndex + 1) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Z()*locH.Z());
4147 dF_dXi(locFIndex, locVxParamIndex + 2) += locA*locSignMultiplier*locDeltaX_DecayingSource.Z()*locH.Y();
4148 dF_dXi(locFIndex + 1, locVxParamIndex) += locA*locSignMultiplier*locDeltaX_DecayingSource.X()*locH.Z();
4149 dF_dXi(locFIndex + 1, locVxParamIndex + 1) += locA*locSignMultiplier*locDeltaX_DecayingSource.Y()*locH.Z();
4150 dF_dXi(locFIndex + 1, locVxParamIndex + 2) -= locA*locSignMultiplier*(locDeltaX_DecayingSource.X()*locH.X() + locDeltaX_DecayingSource.Y()*locH.Y());
4151 }
4152 dF_dXi(locFIndex, locCommonVxParamIndex) -= dF_dXi(locFIndex, locVxParamIndex);
4153 dF_dXi(locFIndex, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex, locVxParamIndex + 1);
4154 dF_dXi(locFIndex, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex, locVxParamIndex + 2);
4155 dF_dXi(locFIndex + 1, locCommonVxParamIndex) -= dF_dXi(locFIndex + 1, locVxParamIndex);
4156 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) -= dF_dXi(locFIndex + 1, locVxParamIndex + 1);
4157 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 2) -= dF_dXi(locFIndex + 1, locVxParamIndex + 2);
4158 }
4159}
4160
4161void DKinFitter::Calc_Vertex_Params(const DKinFitParticle* locKinFitParticle, double& locJ, TVector3& locQ, TVector3& locM, TVector3& locD)
4162{
4163 int locCharge = locKinFitParticle->Get_Charge();
4164 TVector3 locPosition = locKinFitParticle->Get_Position();
4165 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
4166 TVector3 locDeltaX = locCommonVertex - locPosition;
4167 TVector3 locMomentum = locKinFitParticle->Get_Momentum();
4168
4169 TVector3 locBField = Get_BField(locPosition);
4170 TVector3 locH = locBField.Unit();
4171 TVector3 locPCrossH = locMomentum.Cross(locH);
4172 TVector3 locPCrossDeltaX = locMomentum.Cross(locDeltaX);
4173 double locPCrossHMagSq = locPCrossH.Mag2();
4174
4175 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
4176 double locDeltaXDotH = locDeltaX.Dot(locH);
4177 double locPDotH = locMomentum.Dot(locH);
4178 double locPDotDeltaX = locMomentum.Dot(locDeltaX);
4179
4180 TVector3 locDeltaXCrossH = locDeltaX.Cross(locH);
4181 double locK = locPDotDeltaX - locPDotH*locDeltaXDotH;
4182 locJ = locA*locK/locPCrossHMagSq;
4183 double locC = locPDotH/(locPCrossHMagSq*sqrt(1.0 - locJ*locJ));
4184
4185 TVector3 locPCrossHCrossH = locPCrossH.Cross(locH);
4186
4187 locM = locDeltaX - locDeltaXDotH*locH;
4188 locD = locC*(locMomentum - locPDotH*locH) - locH;
4189 locQ = -1.0*locH*(asin(locJ)/locA) - locC*(locM + 2.0*(locK/locPCrossHMagSq)*locPCrossHCrossH);
4190}
4191
4192void DKinFitter::Calc_dF_Time(size_t locFIndex, const DKinFitParticle* locKinFitParticle, bool locUseRFTimeFlag)
4193{
4194//make sure that the particle properties of the beam used for the RF time constraint are done properly (point to correct cov matrix elements, etc.)
4195//for beam particles: be careful about time constraint
4196
4197//charged accel: 4 constraints, 5 unknowns
4198
4199//other: 3 constraints
4200
4201 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
4202 int locCharge = locKinFitParticle->Get_Charge();
4203 double locShowerEnergy = locKinFitParticle->Get_ShowerEnergy();
4204 double locEnergy = locKinFitParticle->Get_Energy();
4205 double locMass = locKinFitParticle->Get_Mass();
4206
4207 double locPathLength = locKinFitParticle->Get_PathLength();
4208
4209 TVector3 locPosition = locKinFitParticle->Get_Position();
4210 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
4211 TVector3 locDeltaX = locCommonVertex - locPosition;
4212 TVector3 locMomentum = locKinFitParticle->Get_Momentum();
4213
4214 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
4215 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
4216 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
4217 int locTParamIndex = locKinFitParticle->Get_TParamIndex();
4218 int locLParamIndex = locKinFitParticle->Get_LParamIndex();
4219 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
4220 int locCommonTParamIndex = locKinFitParticle->Get_CommonTParamIndex();
4221
4222 double locTime = locUseRFTimeFlag ? dRFTime : locKinFitParticle->Get_Time();
4223 double locDeltaT = locKinFitParticle->Get_CommonTime() - locTime;
4224
4225 double locEOverC = locEnergy/29.9792458;
4226 if(locUseRFTimeFlag && (locCharge != 0) && Get_IsBFieldNearBeamline()) //beam particle: charged & b-field
4227 {
4228 if(dDebugLevel > 30)
4229 cout << "DKinFitter: Calc_dF_Time() Section 1; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4230
4231 dF(locFIndex, 0) = locDeltaT - locPathLength*locEOverC/locMomentum.Mag();
4232
4233 TVector3 locMomentumTerm = locMomentum*locMass*locMass*locPathLength*(1.0/(29.9792458*locEnergy*locMomentum.Mag()*locMomentum.Mag2()));
4234 dF_dEta(locFIndex, locPxParamIndex) = locMomentumTerm.X();
4235 dF_dEta(locFIndex, locPxParamIndex + 1) = locMomentumTerm.Y();
4236 dF_dEta(locFIndex, locPxParamIndex + 2) = locMomentumTerm.Z();
4237 dF_dEta(locFIndex, locTParamIndex) = -1.0;
4238
4239 dF_dXi(locFIndex, locCommonTParamIndex) = 1.0;
4240 dF_dXi(locFIndex, locLParamIndex) = -1.0*locEOverC/locMomentum.Mag();
4241 }
4242 else if(locUseRFTimeFlag) //beam particle: neutral or no b-field
4243 {
4244 if(dDebugLevel > 30)
4245 cout << "DKinFitter: Calc_dF_Time() Section 2; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4246
4247 double locPDotDeltaX = locDeltaX.Dot(locMomentum);
4248 double locPMagSq = locMomentum.Mag2();
4249
4250 dF(locFIndex, 0) = locDeltaT - locEOverC*locPDotDeltaX/locPMagSq;
4251
4252 TVector3 locW = locMomentum*locPDotDeltaX*(locEnergy*locEnergy + locMass*locMass)*(1.0/(29.9792458*locEnergy*locPMagSq*locPMagSq)) - locDeltaX*(locEOverC/locPMagSq);
4253
4254 dF_dEta(locFIndex, locPxParamIndex) = locW.X();
4255 dF_dEta(locFIndex, locPxParamIndex + 1) = locW.Y();
4256 dF_dEta(locFIndex, locPxParamIndex + 2) = locW.Z();
4257
4258 TVector3 locVertexTerm = locMomentum*(locEOverC/locPMagSq);
4259
4260 dF_dEta(locFIndex, locVxParamIndex) = locVertexTerm.X();
4261 dF_dEta(locFIndex, locVxParamIndex + 1) = locVertexTerm.Y();
4262 dF_dEta(locFIndex, locVxParamIndex + 2) = locVertexTerm.Z();
4263 dF_dEta(locFIndex, locTParamIndex) = -1.0;
4264
4265 dF_dXi(locFIndex, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex, locVxParamIndex);
4266 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 1);
4267 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex, locVxParamIndex + 2);
4268 dF_dXi(locFIndex, locCommonTParamIndex) = 1.0;
4269 }
4270 else if(locKinFitParticle->Get_IsNeutralShowerFlag()) //neutral shower
4271 {
4272 if(dDebugLevel > 30)
4273 cout << "DKinFitter: Calc_dF_Time() Section 3; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4274
4275 dF(locFIndex, 0) = locDeltaT + locShowerEnergy*locDeltaX.Mag()/(29.9792458*locMomentum.Mag());
4276
4277 dF_dEta(locFIndex, locEParamIndex) = -1.0*locMass*locMass*locDeltaX.Mag()/(29.9792458*locMomentum.Mag()*locMomentum.Mag2());
4278
4279 TVector3 locPositionTerm = locDeltaX.Unit()*(locEOverC/(locMomentum.Mag()));
4280
4281 dF_dEta(locFIndex, locVxParamIndex) = -1.0*locPositionTerm.X();
4282 dF_dEta(locFIndex, locVxParamIndex + 1) = -1.0*locPositionTerm.Y();
4283 dF_dEta(locFIndex, locVxParamIndex + 2) = -1.0*locPositionTerm.Z();
4284 dF_dEta(locFIndex, locTParamIndex) = -1.0;
4285
4286 dF_dXi(locFIndex, locCommonVxParamIndex) = locPositionTerm.X();
4287 dF_dXi(locFIndex, locCommonVxParamIndex + 1) = locPositionTerm.Y();
4288 dF_dXi(locFIndex, locCommonVxParamIndex + 2) = locPositionTerm.Z();
4289 dF_dXi(locFIndex, locCommonTParamIndex) = 1.0;
4290 }
4291 else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //charged track in magnetic field
4292 {
4293 TVector3 locBField = Get_BField(locPosition);
4294
4295 TVector3 locH = locBField.Unit();
4296 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
4297
4298 TVector3 locPCrossH = locMomentum.Cross(locH);
4299 TVector3 locPCrossHCrossH = locPCrossH.Cross(locH);
4300 double locPMag = locMomentum.Mag();
4301 double locPMagCubed = locMomentum.Mag2()*locPMag;
4302 double locALOverPMag = locA*locPathLength/locPMag;
4303 double locPDotH = locMomentum.Dot(locH);
4304 double locSinALOverPMag = sin(locALOverPMag);
4305 double locCosALOverPMag = cos(locALOverPMag);
4306 double locC = 1.0 - locCosALOverPMag;
4307
4308 TVector3 locVertexConstraints = locPCrossHCrossH*(locSinALOverPMag/locA) + locPCrossH*(locC/locA) - (locPDotH*locPathLength/locPMag)*locH;
4309
4310 dF(locFIndex, 0) = locVertexConstraints.X();
4311 dF(locFIndex + 1, 0) = locVertexConstraints.Y();
4312 dF(locFIndex + 2, 0) = locVertexConstraints.Z();
4313 dF(locFIndex + 3, 0) = locDeltaT - locPathLength*locEOverC/locPMag;
4314
4315 //kx := k = x, etc.
4316 TVector3 locLPOverPCubed = locMomentum*(locPathLength/locPMagCubed);
4317 TVector3 locLHOverPMag = locH*(locPathLength/locPMag);
4318 TVector3 locYkx = locLPOverPCubed*(locPDotH*locH.X() - locPCrossHCrossH.X()*locCosALOverPMag - locPCrossH.X()*locSinALOverPMag) - locLHOverPMag*locH.X();
4319 TVector3 locYky = locLPOverPCubed*(locPDotH*locH.Y() - locPCrossHCrossH.Y()*locCosALOverPMag - locPCrossH.Y()*locSinALOverPMag) - locLHOverPMag*locH.Y();
4320 TVector3 locYkz = locLPOverPCubed*(locPDotH*locH.Z() - locPCrossHCrossH.Z()*locCosALOverPMag - locPCrossH.Z()*locSinALOverPMag) - locLHOverPMag*locH.Z();
4321
4322 TVector3 locDkx = locYkx + locH*(locH.X()*locSinALOverPMag/locA);
4323 TVector3 locDky = locYkz + locH*(locH.Y()*locSinALOverPMag/locA);
4324 TVector3 locDkz = locYky + locH*(locH.Z()*locSinALOverPMag/locA);
4325
4326 TVector3 locG(locYkx.X() - (1.0 - locH.X()*locH.X())*locSinALOverPMag/locA, locYky.Y() - (1.0 - locH.Y()*locH.Y())*locSinALOverPMag/locA, locYkz.Z() - (1.0 - locH.Z()*locH.Z())*locSinALOverPMag/locA);
4327 double locZ = locPathLength*locMass*locMass/(29.9792458*locEnergy*locPMagCubed);
4328
4329 TVector3 locHlocCOverA = locH*(locC/locA);
4330
4331 TVector3 locR = locDeltaX - locLHOverPMag*locPDotH + locPCrossH*(locC/locA) + locPCrossHCrossH*(locSinALOverPMag/locA);
4332
4333 if(locKinFitParticleType == d_DecayingParticle) //decaying charged particle
4334 {
4335 if(dDebugLevel > 30)
4336 cout << "DKinFitter: Calc_dF_Time() Section 4; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4337
4338 dF_dXi(locFIndex, locPxParamIndex) = locG.X();
4339 dF_dXi(locFIndex + 1, locPxParamIndex + 1) = locG.Y();
4340 dF_dXi(locFIndex + 2, locPxParamIndex + 2) = locG.Z();
4341
4342 dF_dXi(locFIndex, locPxParamIndex + 1) = locDkx.Y() + locHlocCOverA.Z();
4343 dF_dXi(locFIndex, locPxParamIndex + 2) = locDkx.Z() - locHlocCOverA.Y();
4344
4345 dF_dXi(locFIndex + 1, locPxParamIndex) = locDky.X() - locHlocCOverA.Z();
4346 dF_dXi(locFIndex + 1, locPxParamIndex + 2) = locDky.Z() + locHlocCOverA.X();
4347
4348 dF_dXi(locFIndex + 2, locPxParamIndex) = locDkz.X() + locHlocCOverA.Y();
4349 dF_dXi(locFIndex + 2, locPxParamIndex + 1) = locDkz.Y() - locHlocCOverA.X();
4350
4351 dF_dXi(locFIndex + 3, locPxParamIndex) = locZ*locMomentum.X();
4352 dF_dXi(locFIndex + 3, locPxParamIndex + 1) = locZ*locMomentum.Y();
4353 dF_dXi(locFIndex + 3, locPxParamIndex + 2) = locZ*locMomentum.Z();
4354
4355 dF_dXi(locFIndex, locVxParamIndex) = -1.0;
4356 dF_dXi(locFIndex + 1, locVxParamIndex + 1) = -1.0;
4357 dF_dXi(locFIndex + 2, locVxParamIndex + 2) = -1.0;
4358 dF_dXi(locFIndex + 3, locTParamIndex) = -1.0;
4359
4360 dF_dXi(locFIndex, locCommonVxParamIndex) = 1.0;
4361 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = 1.0;
4362 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) = 1.0;
4363 dF_dXi(locFIndex + 3, locCommonTParamIndex) = 1.0;
4364
4365 dF_dXi(locFIndex, locLParamIndex) = locR.X();
4366 dF_dXi(locFIndex + 1, locLParamIndex + 1) = locR.Y();
4367 dF_dXi(locFIndex + 2, locLParamIndex + 2) = locR.Z();
4368 dF_dXi(locFIndex + 3, locLParamIndex) = -1.0*locEOverC/locPMag;
4369 }
4370 else //detected particle or beam particle
4371 {
4372 if(dDebugLevel > 30)
4373 cout << "DKinFitter: Calc_dF_Time() Section 5; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4374
4375 dF_dEta(locFIndex, locPxParamIndex) = locG.X();
4376 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = locG.Y();
4377 dF_dEta(locFIndex + 2, locPxParamIndex + 2) = locG.Z();
4378
4379 dF_dEta(locFIndex, locPxParamIndex + 1) = locDkx.Y() + locHlocCOverA.Z();
4380 dF_dEta(locFIndex, locPxParamIndex + 2) = locDkx.Z() - locHlocCOverA.Y();
4381
4382 dF_dEta(locFIndex + 1, locPxParamIndex) = locDky.X() - locHlocCOverA.Z();
4383 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = locDky.Z() + locHlocCOverA.X();
4384
4385 dF_dEta(locFIndex + 2, locPxParamIndex) = locDkz.X() + locHlocCOverA.Y();
4386 dF_dEta(locFIndex + 2, locPxParamIndex + 1) = locDkz.Y() - locHlocCOverA.X();
4387
4388 dF_dEta(locFIndex + 3, locPxParamIndex) = locZ*locMomentum.X();
4389 dF_dEta(locFIndex + 3, locPxParamIndex + 1) = locZ*locMomentum.Y();
4390 dF_dEta(locFIndex + 3, locPxParamIndex + 2) = locZ*locMomentum.Z();
4391
4392 dF_dEta(locFIndex, locVxParamIndex) = -1.0;
4393 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = -1.0;
4394 dF_dEta(locFIndex + 2, locVxParamIndex + 2) = -1.0;
4395 dF_dEta(locFIndex + 3, locTParamIndex) = -1.0;
4396
4397 dF_dXi(locFIndex, locCommonVxParamIndex) = 1.0;
4398 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = 1.0;
4399 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) = 1.0;
4400 dF_dXi(locFIndex + 3, locCommonTParamIndex) = 1.0;
4401
4402 dF_dXi(locFIndex, locLParamIndex) = locR.X();
4403 dF_dXi(locFIndex + 1, locLParamIndex + 1) = locR.Y();
4404 dF_dXi(locFIndex + 2, locLParamIndex + 2) = locR.Z();
4405 dF_dXi(locFIndex + 3, locLParamIndex) = -1.0*locEOverC/locPMag;
4406 }
4407 }
4408 else //non-accelerating charged particles, decaying neutral particles, detected neutral particles with a pre-ordained momentum
4409 {
4410 dF(locFIndex, 0) = locDeltaT - locEOverC*locDeltaX.X()/locMomentum.X();
4411 dF(locFIndex + 1, 0) = locDeltaT - locEOverC*locDeltaX.Y()/locMomentum.Y();
4412 dF(locFIndex + 2, 0) = locDeltaT - locEOverC*locDeltaX.Z()/locMomentum.Z();
4413
4414 TVector3 locDeltaXOverPComponents(locDeltaX.X()/locMomentum.X(), locDeltaX.Y()/locMomentum.Y(), locDeltaX.Z()/locMomentum.Z());
4415 TVector3 locEOverCP(locEOverC/locMomentum.X(), locEOverC/locMomentum.Y(), locEOverC/locMomentum.Z());
4416 TVector3 locDeltaXOverCE = locDeltaX*(1.0/(29.9792458*locEnergy));
4417 TVector3 locPOverCE = locMomentum*(1.0/(29.9792458*locEnergy));
4418
4419 if(locKinFitParticleType == d_DecayingParticle) //decaying particle
4420 {
4421 if(dDebugLevel > 30)
4422 cout << "DKinFitter: Calc_dF_Time() Section 6; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4423
4424 dF_dXi(locFIndex, locPxParamIndex) = locEOverCP.X()*locDeltaXOverPComponents.X() - locDeltaXOverCE.X();
4425 dF_dXi(locFIndex + 1, locPxParamIndex + 1) = locEOverCP.Y()*locDeltaXOverPComponents.Y() - locDeltaXOverCE.Y();
4426 dF_dXi(locFIndex + 2, locPxParamIndex + 2) = locEOverCP.Z()*locDeltaXOverPComponents.Z() - locDeltaXOverCE.Z();
4427
4428 dF_dXi(locFIndex, locPxParamIndex + 1) = -1.0*locDeltaXOverPComponents.X()*locPOverCE.Y();
4429 dF_dXi(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaXOverPComponents.X()*locPOverCE.Z();
4430
4431 dF_dXi(locFIndex + 1, locPxParamIndex) = -1.0*locDeltaXOverPComponents.Y()*locPOverCE.X();
4432 dF_dXi(locFIndex + 1, locPxParamIndex + 2) = -1.0*locDeltaXOverPComponents.Y()*locPOverCE.Z();
4433
4434 dF_dXi(locFIndex + 2, locPxParamIndex) = -1.0*locDeltaXOverPComponents.Z()*locPOverCE.X();
4435 dF_dXi(locFIndex + 2, locPxParamIndex + 1) = -1.0*locDeltaXOverPComponents.Z()*locPOverCE.Y();
4436
4437 dF_dXi(locFIndex, locVxParamIndex) = locEOverCP.X();
4438 dF_dXi(locFIndex + 1, locVxParamIndex + 1) = locEOverCP.Y();
4439 dF_dXi(locFIndex + 2, locVxParamIndex + 2) = locEOverCP.Z();
4440
4441 dF_dXi(locFIndex, locTParamIndex) = -1.0;
4442 dF_dXi(locFIndex + 1, locTParamIndex) = -1.0;
4443 dF_dXi(locFIndex + 2, locTParamIndex) = -1.0;
4444
4445 dF_dXi(locFIndex, locCommonVxParamIndex) = -1.0*dF_dXi(locFIndex, locVxParamIndex);
4446 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dXi(locFIndex + 1, locVxParamIndex + 1);
4447 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) = -1.0*dF_dXi(locFIndex + 2, locVxParamIndex + 2);
4448
4449 dF_dXi(locFIndex, locCommonTParamIndex) = 1.0;
4450 dF_dXi(locFIndex + 1, locCommonTParamIndex) = 1.0;
4451 dF_dXi(locFIndex + 2, locCommonTParamIndex) = 1.0;
4452 }
4453 else //detected particle or beam particle
4454 {
4455 if(dDebugLevel > 30)
4456 cout << "DKinFitter: Calc_dF_Time() Section 7; q, mass = " << locKinFitParticle->Get_Charge() << ", " << locKinFitParticle->Get_Mass() << endl;
4457
4458 dF_dEta(locFIndex, locPxParamIndex) = locEOverCP.X()*locDeltaXOverPComponents.X() - locDeltaXOverCE.X();
4459 dF_dEta(locFIndex + 1, locPxParamIndex + 1) = locEOverCP.Y()*locDeltaXOverPComponents.Y() - locDeltaXOverCE.Y();
4460 dF_dEta(locFIndex + 2, locPxParamIndex + 2) = locEOverCP.Z()*locDeltaXOverPComponents.Z() - locDeltaXOverCE.Z();
4461
4462 dF_dEta(locFIndex, locPxParamIndex + 1) = -1.0*locDeltaXOverPComponents.X()*locPOverCE.Y();
4463 dF_dEta(locFIndex, locPxParamIndex + 2) = -1.0*locDeltaXOverPComponents.X()*locPOverCE.Z();
4464
4465 dF_dEta(locFIndex + 1, locPxParamIndex) = -1.0*locDeltaXOverPComponents.Y()*locPOverCE.X();
4466 dF_dEta(locFIndex + 1, locPxParamIndex + 2) = -1.0*locDeltaXOverPComponents.Y()*locPOverCE.Z();
4467
4468 dF_dEta(locFIndex + 2, locPxParamIndex) = -1.0*locDeltaXOverPComponents.Z()*locPOverCE.X();
4469 dF_dEta(locFIndex + 2, locPxParamIndex + 1) = -1.0*locDeltaXOverPComponents.Z()*locPOverCE.Y();
4470
4471 dF_dEta(locFIndex, locVxParamIndex) = locEOverCP.X();
4472 dF_dEta(locFIndex + 1, locVxParamIndex + 1) = locEOverCP.Y();
4473 dF_dEta(locFIndex + 2, locVxParamIndex + 2) = locEOverCP.Z();
4474
4475 dF_dEta(locFIndex, locTParamIndex) = -1.0;
4476 dF_dEta(locFIndex + 1, locTParamIndex) = -1.0;
4477 dF_dEta(locFIndex + 2, locTParamIndex) = -1.0;
4478
4479 dF_dXi(locFIndex, locCommonVxParamIndex) = -1.0*dF_dEta(locFIndex, locVxParamIndex);
4480 dF_dXi(locFIndex + 1, locCommonVxParamIndex + 1) = -1.0*dF_dEta(locFIndex + 1, locVxParamIndex + 1);
4481 dF_dXi(locFIndex + 2, locCommonVxParamIndex + 2) = -1.0*dF_dEta(locFIndex + 2, locVxParamIndex + 2);
4482
4483 dF_dXi(locFIndex, locCommonTParamIndex) = 1.0;
4484 dF_dXi(locFIndex + 1, locCommonTParamIndex) = 1.0;
4485 dF_dXi(locFIndex + 2, locCommonTParamIndex) = 1.0;
4486 }
4487 }
4488}
4489
4490void DKinFitter::Calc_Pulls(void)
4491{
4492 dPulls.clear();
4493 map<DKinFitPullType, double> locParticlePulls;
4494 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4495 {
4496 DKinFitParticle* locKinFitParticle = dKinFitParticles[loc_i];
4497 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
4498
4499 if((locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_TargetParticle))
4500 continue;
4501 locParticlePulls.clear();
4502
4503 if(dDebugLevel >= 50)
4504 {
4505 cout << "pulls: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4506 cout << "e, px, vx, t param indices = " << dKinFitParticles[loc_i]->Get_EParamIndex() << ", " << dKinFitParticles[loc_i]->Get_PxParamIndex() << ", " << dKinFitParticles[loc_i]->Get_VxParamIndex() << ", " << dKinFitParticles[loc_i]->Get_TParamIndex() << endl;
4507 }
4508
4509 int locParamIndex = locKinFitParticle->Get_EParamIndex();
4510 if(locParamIndex >= 0) //E
4511 {
4512 double locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4513 locParticlePulls[d_EPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4514 }
4515
4516 locParamIndex = locKinFitParticle->Get_PxParamIndex();
4517 if(locParamIndex >= 0) //px, py, pz
4518 {
4519 double locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4520 locParticlePulls[d_PxPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4521 ++locParamIndex;
4522 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4523 locParticlePulls[d_PyPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4524 ++locParamIndex;
4525 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4526 locParticlePulls[d_PzPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4527 }
4528
4529 locParamIndex = locKinFitParticle->Get_VxParamIndex();
4530 if(locParamIndex >= 0) //vx, vy, vz
4531 {
4532 double locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4533 locParticlePulls[d_XxPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4534 ++locParamIndex;
4535 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4536 locParticlePulls[d_XyPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4537 ++locParamIndex;
4538 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4539 locParticlePulls[d_XzPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4540 }
4541
4542 locParamIndex = locKinFitParticle->Get_TParamIndex();
4543 if(locParamIndex >= 0) //T
4544 {
4545 double locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4546 locParticlePulls[d_TPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4547 }
4548
4549 if(!locParticlePulls.empty())
4550 dPulls[locKinFitParticle] = locParticlePulls;
4551 }
4552
4553 //RF BUNCH
4554 int locParamIndex = dRFTimeParamIndex;
4555 if(locParamIndex >= 0)
4556 {
4557 locParticlePulls.clear();
4558 double locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4559 locParticlePulls[d_TPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4560 dPulls[NULL__null] = locParticlePulls;
4561 }
4562
4563 if(dDebugLevel > 20)
4564 {
4565 cout << "DKinFitter: dEpsilon: " << endl;
4566 Print_Matrix(dEpsilon);
4567 cout << "DKinFitter: dVY: " << endl;
4568 Print_Matrix(dVY);
4569 cout << "DKinFitter: dVEta: " << endl;
4570 Print_Matrix(*dVEta);
4571 cout << "DKinFitter: Pulls: " << endl;
4572 map<const DKinFitParticle*, map<DKinFitPullType, double> >::iterator locIterator;
4573 map<DKinFitPullType, double>::iterator locIterator2;
4574 for(locIterator = dPulls.begin(); locIterator != dPulls.end(); ++locIterator)
4575 {
4576 map<DKinFitPullType, double>& locTempParticlePulls = locIterator->second;
4577 const DKinFitParticle* locTempKinFitParticle = locIterator->first;
4578 TVector3 locMomentum = locTempKinFitParticle->Get_Momentum();
4579 cout << "particle q, p3 = " << locTempKinFitParticle->Get_Charge() << ", " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ":" << endl;
4580 for(size_t loc_i = 0; loc_i < 8; ++loc_i)
4581 {
4582 if(locTempParticlePulls.find((DKinFitPullType)loc_i) != locTempParticlePulls.end())
4583 cout << locTempParticlePulls[(DKinFitPullType)loc_i] << ", ";
4584 }
4585 cout << endl;
4586 }
4587 }
4588}
4589
4590void DKinFitter::Set_FinalTrackInfo(void)
4591{
4592 TVector3 locMomentum;
4593 TLorentzVector locSpacetimeVertex;
4594 DKinFitParticleType locKinFitParticleType;
4595 int locPxParamIndex, locVxParamIndex, locTParamIndex, locEParamIndex;
4596 int locCovMatrixEParamIndex, locCovMatrixPxParamIndex, locCovMatrixVxParamIndex, locCovMatrixTParamIndex;
4597 double locUncertaintyRatio;
4598
4599 // first update the covariance matrices of each particle with the fit results (prior to any propagation)
4600 //correlations between fit and unfit measured parameters:
4601 //assume that the correlations remain unchanged: the changes in the parameters and their uncertainties should be small wrst their values
4602 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4603 {
4604 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4605 if(locKinFitParticleType == d_TargetParticle)
4606 continue;
4607
4608 // The covariance matrix object is likely shared amongst several DKinFitParticle objects.
4609 // Make sure this object now has a unique object (and set its data)
4610 bool locReconstructedParticleFlag = ((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle));
4611 TMatrixDSym& locKinFitMatrix = locReconstructedParticleFlag ? *dVXi : *dVEta;
4612 if(locReconstructedParticleFlag) //Brand new particle: Set the covariance matrix from scratch
4613 {
4614 TMatrixDSym* locCovarianceMatrix = Get_MatrixDSymResource();
4615 locCovarianceMatrix->ResizeTo(7, 7);
4616 locCovarianceMatrix->Zero();
4617 dKinFitParticles[loc_i]->Set_CovarianceMatrix(locCovarianceMatrix);
4618 }
4619 else //A measured particle. //Use the existing covariance matrix as a starting point
4620 dKinFitParticles[loc_i]->Set_CovarianceMatrix(Clone_MatrixDSym(dKinFitParticles[loc_i]->dCovarianceMatrix));
4621 TMatrixDSym& locCovarianceMatrix = *(dKinFitParticles[loc_i]->dCovarianceMatrix); //need to update the values, so don't call Get_CovarianceMatrix() function (returns const matrix) //saves memory this way
4622
4623 locPxParamIndex = dKinFitParticles[loc_i]->Get_PxParamIndex();
4624 locVxParamIndex = dKinFitParticles[loc_i]->Get_VxParamIndex();
4625 locTParamIndex = dKinFitParticles[loc_i]->Get_TParamIndex();
4626 locEParamIndex = dKinFitParticles[loc_i]->Get_EParamIndex();
4627
4628 locCovMatrixEParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixEParamIndex();
4629 locCovMatrixPxParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixPxParamIndex();
4630 locCovMatrixVxParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixVxParamIndex();
4631 locCovMatrixTParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixTParamIndex();
4632
4633 if(dDebugLevel >= 50)
4634 {
4635 cout << "SETTING FINAL TRACK INFO: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4636 cout << "E, px, vx, t param indices = " << locEParamIndex << ", " << locPxParamIndex << ", " << locVxParamIndex << ", " << locTParamIndex << endl;
4637 cout << "E, px, vx, t cov matrix indices = " << locCovMatrixEParamIndex << ", " << locCovMatrixPxParamIndex << ", " << locCovMatrixVxParamIndex << ", " << locCovMatrixTParamIndex << endl;
4638 cout << "sizes = " << locCovarianceMatrix.GetNrows() << ", " << locCovarianceMatrix.GetNcols() << ", " << locKinFitMatrix.GetNrows() << ", " << locKinFitMatrix.GetNcols() << endl;
4639 }
4640
4641 //decaying particles with momentum derived from other particles
4642 if((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex < 0))
4643 {
4644 //enclosed decaying particle: the momentum is derived from the momentum of its decay products
4645 deque<DKinFitConstraint_P4*> locConstraints = dKinFitParticles[loc_i]->dP4Constraints;
4646 DKinFitConstraint_P4* locConstraintAsParent = NULL__null;
4647 for(size_t loc_j = 0; loc_j < locConstraints.size(); ++loc_j)
4648 {
4649 if((locConstraints[loc_j]->Get_InitialParticles())[0] != dKinFitParticles[loc_i])
4650 continue;
4651 locConstraintAsParent = locConstraints[loc_j];
4652 break;
4653 }
4654 if(locConstraintAsParent != NULL__null)
4655 {
4656 //decaying particle used in a p4 constraint
4657 TMatrixD locJacobian(7, dNumEta + dNumXi);
4658 locJacobian.Zero();
4659 if(dKinFitParticles[loc_i]->Get_DecayingParticleAtProductionVertexFlag())
4660 Calc_DecayingParticleJacobian(locConstraintAsParent, false, locJacobian); //computes jacobian at production vertex
4661 else
4662 Calc_DecayingParticleJacobian(locConstraintAsParent, true, locJacobian); //computes jacobian at decay vertex
4663
4664 //set vertex & time terms
4665 if(locVxParamIndex >= 0)
4666 {
4667 locJacobian(locCovMatrixVxParamIndex, locVxParamIndex + dNumEta) = 1.0;
4668 locJacobian(locCovMatrixVxParamIndex + 1, locVxParamIndex + dNumEta + 1) = 1.0;
4669 locJacobian(locCovMatrixVxParamIndex + 2, locVxParamIndex + dNumEta + 2) = 1.0;
4670 }
4671 int locTParamIndex = dKinFitParticles[loc_i]->Get_TParamIndex();
4672 if(locTParamIndex >= 0)
4673 locJacobian(6, locTParamIndex + dNumEta) = 1.0;
4674
4675 TMatrixDSym locTempMatrix = *dV;
4676 locCovarianceMatrix = locTempMatrix.Similarity(locJacobian);
4677 }
4678 else
4679 {
4680 //decaying particle not used in a p4 constraint (e.g. vertex-only fit)
4681 if(locVxParamIndex >= 0)
4682 {
4683 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4684 {
4685 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4686 locCovarianceMatrix(loc_j + locCovMatrixVxParamIndex, loc_k + locCovMatrixVxParamIndex) = (*dVXi)(locVxParamIndex + loc_j, locVxParamIndex + loc_k);
4687 }
4688 }
4689 if(locTParamIndex >= 0)
4690 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixTParamIndex) = (*dVXi)(locTParamIndex, locTParamIndex);
4691 if((locVxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4692 {
4693 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4694 {
4695 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = (*dVXi)(locVxParamIndex + loc_j, locTParamIndex + 0);
4696 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = (*dVXi)(locTParamIndex + 0, locVxParamIndex + loc_j);
4697 }
4698 }
4699 }
4700
4701 if(dDebugLevel >= 50)
4702 {
4703 cout << "FINAL COV MATRIX (enclosed decaying particle):" << endl;
4704 Print_Matrix(locCovarianceMatrix);
4705 }
4706 continue;
4707 }
4708
4709 //set localized terms first
4710 if(locEParamIndex >= 0)
4711 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixEParamIndex) = locKinFitMatrix(locEParamIndex, locEParamIndex);
4712 if(locPxParamIndex >= 0)
4713 {
4714 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4715 {
4716 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4717 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixPxParamIndex + loc_k) = locKinFitMatrix(loc_j + locPxParamIndex, loc_k + locPxParamIndex);
4718 }
4719 }
4720 if(locVxParamIndex >= 0)
4721 {
4722 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4723 {
4724 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4725 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) = locKinFitMatrix(loc_j + locVxParamIndex, loc_k + locVxParamIndex);
4726 }
4727 }
4728 if(locTParamIndex >= 0)
4729 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixTParamIndex) = locKinFitMatrix(locTParamIndex, locTParamIndex);
4730
4731 //cross terms: E & V (neutral shower)
4732 if((locEParamIndex >= 0) && (locVxParamIndex >= 0)) //both included in the fit
4733 {
4734 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4735 {
4736 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = locKinFitMatrix(locEParamIndex + 0, locVxParamIndex + loc_j);
4737 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) = locKinFitMatrix(locVxParamIndex + loc_j, locEParamIndex + 0);
4738 }
4739 }
4740 else if(!locReconstructedParticleFlag && (locEParamIndex >= 0) && (locVxParamIndex < 0)) //only E included in the fit
4741 {
4742 double locDenominator = sqrt(dVY(locEParamIndex, locEParamIndex));
4743 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locEParamIndex, locEParamIndex))/locDenominator : 0.0;
4744 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4745 {
4746 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4747 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) *= locUncertaintyRatio;
4748 }
4749 }
4750 else if(!locReconstructedParticleFlag && (locEParamIndex < 0) && (locVxParamIndex >= 0) && (locCovMatrixEParamIndex >= 0)) //only V included in the fit //E may not be in the covariance matrix!!
4751 {
4752 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4753 {
4754 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4755 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4756 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4757 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) *= locUncertaintyRatio;
4758 }
4759 }
4760
4761 //cross terms: E & T (neutral shower)
4762 if((locEParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4763 {
4764 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) = locKinFitMatrix(locEParamIndex, locTParamIndex);
4765 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) = locKinFitMatrix(locTParamIndex, locEParamIndex);
4766 }
4767 else if(!locReconstructedParticleFlag && (locEParamIndex >= 0) && (locTParamIndex < 0)) //only E included in the fit
4768 {
4769 double locDenominator = sqrt(dVY(locEParamIndex, locEParamIndex));
4770 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locEParamIndex, locEParamIndex))/locDenominator : 0.0;
4771 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) *= locUncertaintyRatio;
4772 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) *= locUncertaintyRatio;
4773 }
4774 else if(!locReconstructedParticleFlag && (locEParamIndex < 0) && (locTParamIndex >= 0) && (locCovMatrixEParamIndex >= 0)) //only T included in the fit //E may not be in the covariance matrix!!
4775 {
4776 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4777 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4778 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) *= locUncertaintyRatio;
4779 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) *= locUncertaintyRatio;
4780 }
4781
4782 //cross terms: P & V
4783 if((locPxParamIndex >= 0) && (locVxParamIndex >= 0)) //both included in the fit
4784 {
4785 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4786 {
4787 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4788 {
4789 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) = locKinFitMatrix(locPxParamIndex + loc_j, locVxParamIndex + loc_k);
4790 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_k, locCovMatrixPxParamIndex + loc_j) = locKinFitMatrix(locVxParamIndex + loc_k, locPxParamIndex + loc_j);
4791 }
4792 }
4793 }
4794 else if(!locReconstructedParticleFlag && (locPxParamIndex >= 0) && (locVxParamIndex < 0)) //only P included in the fit
4795 {
4796 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4797 {
4798 double locDenominator = sqrt(dVY(locPxParamIndex + loc_j, locPxParamIndex + loc_j));
4799 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locPxParamIndex + loc_j, locPxParamIndex + loc_j))/locDenominator : 0.0;
4800 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4801 {
4802 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) *= locUncertaintyRatio;
4803 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_k, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4804 }
4805 }
4806 }
4807 else if(!locReconstructedParticleFlag && (locPxParamIndex < 0) && (locVxParamIndex >= 0)) //only V included in the fit
4808 {
4809 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4810 {
4811 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4812 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4813 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4814 {
4815 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_k, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4816 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixPxParamIndex + loc_k) *= locUncertaintyRatio;
4817 }
4818 }
4819 }
4820
4821 //cross terms: P & T
4822 if((locPxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4823 {
4824 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4825 {
4826 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = locKinFitMatrix(locPxParamIndex + loc_j, locTParamIndex + 0);
4827 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) = locKinFitMatrix(locTParamIndex + 0, locPxParamIndex + loc_j);
4828 }
4829 }
4830 else if(!locReconstructedParticleFlag && (locPxParamIndex >= 0) && (locTParamIndex < 0)) //only P included in the fit
4831 {
4832 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4833 {
4834 double locDenominator = sqrt(dVY(locPxParamIndex + loc_j, locPxParamIndex + loc_j));
4835 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locPxParamIndex + loc_j, locPxParamIndex + loc_j))/locDenominator : 0.0;
4836 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4837 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4838 }
4839 }
4840 else if(!locReconstructedParticleFlag && (locPxParamIndex < 0) && (locTParamIndex >= 0)) //only T included in the fit
4841 {
4842 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4843 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4844 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4845 {
4846 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4847 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4848 }
4849 }
4850
4851 //cross terms: V & T
4852 if((locVxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4853 {
4854 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4855 {
4856 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = locKinFitMatrix(locVxParamIndex + loc_j, locTParamIndex + 0);
4857 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = locKinFitMatrix(locTParamIndex + 0, locVxParamIndex + loc_j);
4858 }
4859 }
4860 else if(!locReconstructedParticleFlag && (locVxParamIndex >= 0) && (locTParamIndex < 0)) //only V included in the fit
4861 {
4862 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4863 {
4864 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4865 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4866 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4867 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4868 }
4869 }
4870 else if(!locReconstructedParticleFlag && (locVxParamIndex < 0) && (locTParamIndex >= 0)) //only T included in the fit
4871 {
4872 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4873 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4874 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4875 {
4876 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4877 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4878 }
4879 }
4880
4881 if(dDebugLevel >= 50)
4882 {
4883 cout << "FINAL COV MATRIX:" << endl;
4884 Print_Matrix(locCovarianceMatrix);
4885 }
4886 } //end set cov matrix loop
4887
4888 // propagate the track parameters
4889 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4890 {
4891 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4892
4893 if(!dKinFitParticles[loc_i]->Get_IsInVertexOrSpacetimeFitFlag())
4894 continue; // no distance over which to propagate
4895
4896 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
4897 continue; // particle properties already defined at the fit vertex
4898
4899 pair<double, double> locPathLengthPair;
4900 TMatrixDSym& locCovarianceMatrix = *(dKinFitParticles[loc_i]->dCovarianceMatrix);
4901
4902 if(!Propagate_TrackInfoToCommonVertex(dKinFitParticles[loc_i], dVXi, locMomentum, locSpacetimeVertex, locPathLengthPair, locCovarianceMatrix))
4903 continue; // info not propagated
4904
4905 if(dDebugLevel >= 50)
4906 {
4907 cout << "PROPAGATED FINAL TRACK INFO: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4908 cout << "p_xyz, v_xyzt = " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
4909 cout << "common v_xyzt = " << dKinFitParticles[loc_i]->Get_CommonVertex().X() << ", " << dKinFitParticles[loc_i]->Get_CommonVertex().Y() << ", " << dKinFitParticles[loc_i]->Get_CommonVertex().Z() << ", " << dKinFitParticles[loc_i]->Get_CommonTime() << endl;
4910 cout << "path length & uncert = " << locPathLengthPair.first << ", " << locPathLengthPair.second << endl;
4911 cout << "sizes = " << locCovarianceMatrix.GetNrows() << ", " << locCovarianceMatrix.GetNcols() << endl;
4912 }
4913
4914 //no need to set the covariance matrix: already updated (passed in a reference to it)
4915 dKinFitParticles[loc_i]->Set_Momentum(locMomentum);
4916 dKinFitParticles[loc_i]->Set_Position(locSpacetimeVertex.Vect());
4917 dKinFitParticles[loc_i]->Set_Time(locSpacetimeVertex.T());
4918 dKinFitParticles[loc_i]->Set_PathLength(locPathLengthPair.first);
4919 dKinFitParticles[loc_i]->Set_PathLengthUncertainty(locPathLengthPair.second);
4920 }
4921
4922 //calculate the path length of decaying particles involved in 2 vertex fits
4923 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4924 {
4925 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4926
4927 if((locKinFitParticleType != d_DecayingParticle) || (dKinFitParticles[loc_i]->Get_NumVertexFits() != 2))
4928 continue;
4929
4930 pair<double, double> locPathLengthPair;
4931 const TMatrixDSym& locCovarianceMatrix = *(dKinFitParticles[loc_i]->Get_CovarianceMatrix());
4932 if(Calc_PathLength(dKinFitParticles[loc_i], dVXi, locCovarianceMatrix, locPathLengthPair))
4933 {
4934 dKinFitParticles[loc_i]->Set_PathLength(locPathLengthPair.first);
4935 dKinFitParticles[loc_i]->Set_PathLengthUncertainty(locPathLengthPair.second);
4936 }
4937 }
4938}
4939
4940void DKinFitter::Calc_DecayingParticleJacobian(DKinFitConstraint_P4* locP4Constraint, bool locDecayVertexFlag, TMatrixD& locJacobian) const
4941{
4942 //locJacobian: matrix used to convert dV to the decaying particle covariance matrix: indices are px, py, pz, x, y, z, t
4943 //dimensions are: 7, (dNumXi + dNumEta);
4944 //uses decay products to calculate decaying particle information
4945 //locDecayVertexFlag = true to compute jacobian at the decay vertex, false at the production vertex
4946
4947 if(!locDecayVertexFlag)
4948 {
4949 if(dDebugLevel > 50)
4950 cout << "compute jacobian at production vertex" << endl;
4951 //propagate decaying particle momentum from the decay vertex to the production vertex (if necessary: charged, b-field, etc.)
4952 deque<DKinFitParticle*> locInitialParticles = locP4Constraint->dInitialParticles;
4953 DKinFitParticle* locKinFitParticle = locInitialParticles[0]; //the decaying particle
4954
4955 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
4956 int locCharge = locKinFitParticle->Get_Charge();
4957 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
4958
4959 if(locChargedBFieldFlag && (locNumVertexFits == 2))
4960 {
4961 if(dDebugLevel > 50)
4962 cout << "charged, enclosed decaying particle in a b-field in vertex fits" << endl;
4963 //charged, enclosed decaying particle in a b-field in vertex fits
4964 TVector3 locPosition = locKinFitParticle->Get_Position();
4965 TVector3 locBField = Get_BField(locPosition);
4966 TVector3 locH = locBField.Unit();
4967 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
4968
4969 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex() + dNumEta;
4970 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex() + dNumEta;
4971
4972 //vertex factors
4973 locJacobian(0, locVxParamIndex + 1) += locA*locH.Z();
4974 locJacobian(0, locVxParamIndex + 2) += -1.0*locA*locH.Y();
4975
4976 locJacobian(1, locVxParamIndex) += -1.0*locA*locH.Z();
4977 locJacobian(1, locVxParamIndex + 2) += locA*locH.X();
4978
4979 locJacobian(2, locVxParamIndex) += locA*locH.Y();
4980 locJacobian(2, locVxParamIndex + 1) += -1.0*locA*locH.X();
4981
4982 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
4983 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
4984
4985 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
4986 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
4987
4988 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
4989 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
4990 }
4991 }
4992
4993 deque<DKinFitParticle*> locFinalParticles = locP4Constraint->dFinalParticles;
4994 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
4995 {
4996 DKinFitParticle* locKinFitParticle = locFinalParticles[loc_i];
4997 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
4998
4999 int locCharge = locKinFitParticle->Get_Charge();
5000 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5001 TVector3 locPosition = locKinFitParticle->Get_Position();
5002 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5003 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5004 TVector3 locDeltaX = locCommonVertex - locPosition;
5005 if(dDebugLevel > 50)
5006 cout << "jacobian: decay product: q, mass = " << locCharge << ", " << locKinFitParticle->Get_Mass() << endl;
5007
5008 TVector3 locH = locBField.Unit();
5009 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
5010
5011 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
5012 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
5013 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
5014 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
5015
5016 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
5017 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
5018 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
5019 locPxParamIndex += dNumEta;
5020 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
5021 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
5022 locVxParamIndex += dNumEta;
5023 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex() + dNumEta;
5024
5025 if(locKinFitParticleType == d_TargetParticle)
5026 continue;
5027 else if(locChargedBFieldFlag && locEnoughVertexFitsFlag && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)))
5028 {
5029 if(dDebugLevel > 50)
5030 cout << "jacobian: partials part 1" << endl;
5031
5032 locJacobian(0, locPxParamIndex) = 1.0;
5033 locJacobian(1, locPxParamIndex + 1) = 1.0;
5034 locJacobian(2, locPxParamIndex + 2) = 1.0;
5035
5036 locJacobian(0, locVxParamIndex + 1) = locA*locH.Z();
5037 locJacobian(0, locVxParamIndex + 2) = -1.0*locA*locH.Y();
5038
5039 locJacobian(1, locVxParamIndex) = -1.0*locA*locH.Z();
5040 locJacobian(1, locVxParamIndex + 2) = locA*locH.X();
5041
5042 locJacobian(2, locVxParamIndex) = locA*locH.Y();
5043 locJacobian(2, locVxParamIndex + 1) = -1.0*locA*locH.X();
5044
5045 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5046 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5047
5048 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5049 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5050
5051 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5052 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5053 }
5054 else if(locNeutralShowerFlag)
5055 {
5056 if(dDebugLevel > 50)
5057 cout << "jacobian: partials part 2" << endl;
5058
5059 double locEOverPSq = locP4.E()/locP4.Vect().Mag2();
5060 locJacobian(0, locEParamIndex) = locEOverPSq*locP4.Px();
5061 locJacobian(1, locEParamIndex) = locEOverPSq*locP4.Py();
5062 locJacobian(2, locEParamIndex) = locEOverPSq*locP4.Pz();
5063
5064 TVector3 locDeltaXOverMagDeltaXSq = locDeltaX*(1.0/locDeltaX.Mag2());
5065
5066 locJacobian(0, locVxParamIndex) = locP4.Px()*(locDeltaXOverMagDeltaXSq.X() - 1.0/locDeltaX.X());
5067 locJacobian(1, locVxParamIndex + 1) = locP4.Py()*(locDeltaXOverMagDeltaXSq.Y() - 1.0/locDeltaX.Y());
5068 locJacobian(2, locVxParamIndex + 2) = locP4.Pz()*(locDeltaXOverMagDeltaXSq.Z() - 1.0/locDeltaX.Z());
5069
5070 locJacobian(0, locVxParamIndex + 1) = locP4.Px()*locDeltaXOverMagDeltaXSq.Y();
5071 locJacobian(0, locVxParamIndex + 2) = locP4.Px()*locDeltaXOverMagDeltaXSq.Z();
5072
5073 locJacobian(1, locVxParamIndex) = locP4.Py()*locDeltaXOverMagDeltaXSq.X();
5074 locJacobian(1, locVxParamIndex + 2) = locP4.Py()*locDeltaXOverMagDeltaXSq.Z();
5075
5076 locJacobian(2, locVxParamIndex) = locP4.Pz()*locDeltaXOverMagDeltaXSq.X();
5077 locJacobian(2, locVxParamIndex + 1) = locP4.Pz()*locDeltaXOverMagDeltaXSq.Y();
5078
5079 locJacobian(0, locCommonVxParamIndex) -= locJacobian(0, locVxParamIndex);
5080 locJacobian(1, locCommonVxParamIndex + 1) -= locJacobian(1, locVxParamIndex + 1);
5081 locJacobian(2, locCommonVxParamIndex + 2) -= locJacobian(2, locVxParamIndex + 2);
5082
5083 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5084 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5085
5086 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5087 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5088
5089 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5090 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5091 }
5092 else if((locKinFitParticleType == d_MissingParticle) || ((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex >= 0)))
5093 {
5094 if(dDebugLevel > 50)
5095 cout << "jacobian: partials part 3" << endl;
5096
5097 //missing or open-ended-decaying particle: p3 is unknown (not derivable)
5098 locJacobian(0, locPxParamIndex) = 1.0;
5099 locJacobian(1, locPxParamIndex + 1) = 1.0;
5100 locJacobian(2, locPxParamIndex + 2) = 1.0;
5101 }
5102 else if(locKinFitParticleType == d_DecayingParticle)
5103 {
5104 if(dDebugLevel > 50)
5105 cout << "jacobian: partials part 4" << endl;
5106
5107 //charged, enclosed decaying particle in a b-field
5108 if(locChargedBFieldFlag && (locKinFitParticle->Get_NumVertexFits() == 2))
5109 {
5110 if(dDebugLevel > 50)
5111 cout << "jacobian: partials part 4a" << endl;
5112
5113 //vertex factors
5114 locJacobian(0, locVxParamIndex + 1) += locA*locH.Z();
5115 locJacobian(0, locVxParamIndex + 2) += -1.0*locA*locH.Y();
5116
5117 locJacobian(1, locVxParamIndex) += -1.0*locA*locH.Z();
5118 locJacobian(1, locVxParamIndex + 2) += locA*locH.X();
5119
5120 locJacobian(2, locVxParamIndex) += locA*locH.Y();
5121 locJacobian(2, locVxParamIndex + 1) += -1.0*locA*locH.X();
5122
5123 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5124 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5125
5126 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5127 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5128
5129 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5130 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5131 }
5132
5133 //p4 is derived from other particles:
5134 deque<DKinFitConstraint_P4*> locP4Constraints = locFinalParticles[loc_i]->dP4Constraints;
5135 for(size_t loc_j = 0; loc_j < locP4Constraints.size(); ++loc_j)
5136 {
5137 if(locP4Constraints[loc_j] == locP4Constraint)
5138 continue;
5139 if(dDebugLevel > 50)
5140 cout << "jacobian: partials part 4b" << endl;
5141 Calc_DecayingParticleJacobian(locP4Constraints[loc_j], true, locJacobian);
5142 break;
5143 }
5144 }
5145 else
5146 {
5147 if(dDebugLevel > 50)
5148 cout << "jacobian: partials part 5" << endl;
5149
5150 // either no common vertex constraint, charged and detected but b-field = 0, or neutral particle with pre-ordained vertex (e.g. beam particle)
5151 locJacobian(0, locPxParamIndex) = 1.0;
5152 locJacobian(1, locPxParamIndex + 1) = 1.0;
5153 locJacobian(2, locPxParamIndex + 2) = 1.0;
5154 }
5155 }
5156}
5157
5158// propagates the track info to the fit common vertex
5159 //returns false if nothing changed (info not propagated: e.g. missing particle), else returns true
5160//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
5161// this function acts in the following way on each particle, IN THIS ORDER OF EXECUTION:
5162 // if a common vertex was not fit, then the current results are returned
5163 // if this is either a target particle, a missing particle, or a decaying particle that is present in only one vertex fit:
5164 // the current info is defined to be at the common vertex: just return it
5165 // if this is a decaying particle that is present in two vertex fits: the returned info is the info at the "other" vertex
5166 // "other" is the opposite of where the particle info is defined to be:
5167 // e.g. if dDecayingParticleAtProductionVertexFlag == true, then the "other" vertex is the decay vertex
5168 // for the remaining types (including decaying particles):
5169 // the vertex is set to the common vertex
5170 // if the time was fit, then the time is set to the common time, else it is propagated to the common vertex
5171 // if the path length was fit then the fit result is used; otherwise it is propagated
5172 // momentum:
5173 // if this is a neutral shower: momentum is redefined by the new vertex //already done by Update_ParticleParams()
5174 // if this is a neutral particle (either detected, beam, or decaying) or a charged particle without a b-field: the momentum is unchanged
5175 // if this is a charged particle in a b-field (either beam, detected, or decaying): the momentum is propagated to the common vertex
5176 //propagating the covariance matrix:
5177 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5178 //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
5179 //transform to 7x7: common v3 & common t are just copied to the measured spots
5180//the output covariance matrix is 7x7, even if the particle represents a neutral shower (5x5)
5181//the only thing this function uses that depends on the state of the fitter itself is the magnetic field map
5182bool DKinFitter::Propagate_TrackInfoToCommonVertex(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, TVector3& locMomentum, TLorentzVector& locSpacetimeVertex, pair<double, double>& locPathLengthPair, TMatrixDSym& locCovarianceMatrix) const
5183{
5184 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
5185
5186 if(!locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag())
5187 return false; // no distance over which to propagate
5188
5189 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
5190 return false; // particle properties already defined at the fit vertex
5191
5192 if((locKinFitParticleType == d_DecayingParticle) && (locKinFitParticle->Get_NumVertexFits() != 2))
5193 return false; // particle properties already defined at the fit vertex
5194
5195 locCovarianceMatrix = *(locKinFitParticle->Get_CovarianceMatrix());
5196 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
5197
5198 int locCharge = locKinFitParticle->Get_Charge();
5199 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5200
5201 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5202 TVector3 locPosition = locKinFitParticle->Get_Position();
5203 TVector3 locDeltaX = locCommonVertex - locPosition;
5204 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5205 TVector3 locH = locBField.Unit();
5206 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
5207 double locCommonTime;
5208
5209 // covariance matrix
5210 int locCovMatrixEParamIndex = locKinFitParticle->Get_CovMatrixEParamIndex();
5211 int locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
5212 int locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
5213 int locCovMatrixTParamIndex = locKinFitParticle->Get_CovMatrixTParamIndex();
5214 int locCommonVxParamIndex_TempMatrix, locCommonTParamIndex_TempMatrix;
5215
5216 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
5217 int locCommonTParamIndex = locKinFitParticle->Get_CommonTParamIndex();
5218
5219 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5220 locCommonVxParamIndex_TempMatrix = locCovarianceMatrix.GetNcols();
5221 locCovarianceMatrix.ResizeTo(locCommonVxParamIndex_TempMatrix + 3, locCommonVxParamIndex_TempMatrix + 3);
5222 for(size_t loc_i = 0; loc_i < 3; ++loc_i)
5223 {
5224 for(size_t loc_j = 0; loc_j < 3; ++loc_j)
5225 locCovarianceMatrix(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
5226 }
5227 // done: no correlations between common vertex and measured params!!!
5228 locSpacetimeVertex.SetVect(locCommonVertex);
5229
5230 //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
5231 //note that if the common time is not kinfit, then the true uncertainty is overestimated: cannot be obtained without a kinematic fit (3 equations (xyz), one unknown (time))
5232 locCommonTParamIndex_TempMatrix = locCovarianceMatrix.GetNcols();
5233 if(locKinFitParticle->Get_IsInSpacetimeFitFlag()) //spacetime was fit
5234 {
5235 locCommonTime = locKinFitParticle->Get_CommonTime();
5236 locCovarianceMatrix.ResizeTo(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols() + 1);
5237 locCovarianceMatrix(locCommonTParamIndex_TempMatrix, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonTParamIndex, locCommonTParamIndex);
5238 for(size_t loc_i = 0; loc_i < 3; ++loc_i) //correlations to common v3
5239 {
5240 locCovarianceMatrix(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + loc_i) = (*locVXi)(locCommonTParamIndex, locCommonVxParamIndex + loc_i);
5241 locCovarianceMatrix(locCommonVxParamIndex_TempMatrix + loc_i, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonTParamIndex);
5242 }
5243 }
5244 else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
5245 {
5246 double locDeltaXDotH = locDeltaX.Dot(locH);
5247 double locPDotH = locP4.Vect().Dot(locH);
5248 locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotH*locP4.E()/(29.9792458*locPDotH);
5249
5250 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5251 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5252 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5253
5254 TVector3 locDCommonTimeDP3 = (locDeltaXDotH/(29.9792458*locPDotH)) * ((1.0/locP4.E())*locP4.Vect() - (locP4.E()/locPDotH)*locH);
5255 TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locPDotH))*locH;
5256 TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
5257
5258 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
5259 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
5260 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
5261
5262 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5263 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5264 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5265
5266 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5267 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5268 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5269
5270 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5271
5272 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5273 }
5274 else if(!locNeutralShowerFlag) //non-accelerating, non-shower
5275 {
5276 double locDeltaXDotP = locDeltaX.Dot(locP4.Vect());
5277 locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotP*locP4.E()/(29.9792458*locP4.Vect().Mag2());
5278
5279 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5280 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5281 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5282
5283 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());
5284 TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locP4.Vect().Mag2()))*locP4.Vect();
5285 TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
5286
5287 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
5288 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
5289 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
5290
5291 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5292 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5293 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5294
5295 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5296 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5297 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5298
5299 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5300
5301 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5302 }
5303 else //neutral shower
5304 {
5305 locCommonTime = locKinFitParticle->Get_Time() - locDeltaX.Mag()*locP4.E()/(29.9792458*locP4.P());
5306
5307 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5308 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5309 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5310
5311 double locDCommonTimeDEnergy = locDeltaX.Mag()*locP4.M2()/(29.9792458*locP4.P()*locP4.Vect().Mag2());
5312 TVector3 locDCommonTimeDPosition = (locP4.E()/(29.9792458*locP4.P()*locDeltaX.Mag()))*locDeltaX;
5313 TVector3 locDCommonTimeDCommonVertex = -1.0*locDCommonTimeDPosition;
5314
5315 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixEParamIndex) = locDCommonTimeDEnergy;
5316
5317 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5318 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5319 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5320
5321 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5322 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5323 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5324
5325 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5326
5327 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5328 }
5329 locSpacetimeVertex.SetT(locCommonTime);
5330
5331 //transform to 7x7: common v3 & common t are just copied to the measured spots; p is propagated if in bfield, else is copied
5332 TMatrixD locTransformationMatrix_Propagation(7, locCovarianceMatrix.GetNcols());
5333 //p3
5334 if((locCharge != 0) && Get_IsBFieldNearBeamline()) //charged & in b-field
5335 {
5336 locMomentum = locP4.Vect() - locDeltaX.Cross(locA*locH);
5337
5338 locTransformationMatrix_Propagation(0, locCovMatrixPxParamIndex) = 1.0;
5339 locTransformationMatrix_Propagation(1, locCovMatrixPxParamIndex + 1) = 1.0;
5340 locTransformationMatrix_Propagation(2, locCovMatrixPxParamIndex + 2) = 1.0;
5341
5342 locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 1) = -1.0*locA*locH.Z();
5343 locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 2) = locA*locH.Y();
5344
5345 locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex) = locA*locH.Z();
5346 locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex + 2) = -1.0*locA*locH.X();
5347
5348 locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex) = -1.0*locA*locH.Y();
5349 locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex + 1) = locA*locH.X();
5350
5351 locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 1) = locA*locH.Z();
5352 locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 2) = -1.0*locA*locH.Y();
5353
5354 locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix) = -1.0*locA*locH.Z();
5355 locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix + 2) = locA*locH.X();
5356
5357 locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix) = locA*locH.Y();
5358 locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix + 1) = -1.0*locA*locH.X();
5359 }
5360 else //constant: either neutral or no b-field
5361 {
5362 locMomentum = locP4.Vect();
5363 for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
5364 locTransformationMatrix_Propagation(loc_i, locCovMatrixPxParamIndex + loc_i) = 1.0;
5365 }
5366 //v3
5367 for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
5368 locTransformationMatrix_Propagation(3 + loc_i, locCommonVxParamIndex_TempMatrix + loc_i) = 1.0;
5369 //t
5370 locTransformationMatrix_Propagation(6, locCommonTParamIndex_TempMatrix) = 1.0;
5371 //transform!!
5372 locCovarianceMatrix.Similarity(locTransformationMatrix_Propagation); //FINALLY!!!
5373
5374 return Calc_PathLength(locKinFitParticle, locVXi, locCovarianceMatrix, locPathLengthPair);
5375}
5376
5377bool DKinFitter::Calc_PathLength(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, const TMatrixDSym& locCovarianceMatrix, pair<double, double>& locPathLengthPair) const
5378{
5379 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
5380
5381 if(!locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag())
5382 return false; // no distance over which to propagate
5383
5384 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
5385 return false; // particle properties already defined at the fit vertex
5386
5387 if((locKinFitParticleType == d_DecayingParticle) && (locKinFitParticle->Get_NumVertexFits() != 2))
5388 return false; // particle properties already defined at the fit vertex
5389
5390 double locPathLength, locPathLengthUncertainty;
5391 int locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
5392 int locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
5393 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
5394
5395 int locCharge = locKinFitParticle->Get_Charge();
5396 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5397 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5398 TVector3 locPosition = locKinFitParticle->Get_Position();
5399 TVector3 locDeltaX = locCommonVertex - locPosition;
5400 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5401 TVector3 locH = locBField.Unit();
5402
5403 int locLParamIndex = locKinFitParticle->Get_LParamIndex();
5404
5405 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5406 TMatrixDSym locTempMatrix(locCovarianceMatrix);
5407 int locCommonVxParamIndex_TempMatrix = locTempMatrix.GetNcols();
5408 locTempMatrix.ResizeTo(locCommonVxParamIndex_TempMatrix + 3, locCommonVxParamIndex_TempMatrix + 3);
5409 for(size_t loc_i = 0; loc_i < 3; ++loc_i)
5410 {
5411 for(size_t loc_j = 0; loc_j < 3; ++loc_j)
5412 locTempMatrix(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
5413 }
5414
5415 //find path length & its uncertainty
5416 if(locKinFitParticle->Get_IsInSpacetimeFitFlag() && (locCharge != 0) && Get_IsBFieldNearBeamline()) //path length was fit
5417 {
5418 locPathLength = locKinFitParticle->Get_PathLength();
5419 locPathLengthUncertainty = (*locVXi)(locLParamIndex, locLParamIndex);
5420 }
5421 else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
5422 {
5423 double locDeltaXDotH = locDeltaX.Dot(locH);
5424 double locPDotH = locP4.Vect().Dot(locH);
5425 double locPMag = locP4.P();
5426 locPathLength = locDeltaXDotH*locPMag/locPDotH; //cos(theta_helix) = p.dot(h)/|p| = x.dot(h)/l (l = path length)
5427
5428 TMatrixD locTransformationMatrix_PathLength(1, locTempMatrix.GetNcols());
5429
5430 TVector3 locDPathDP3 = (locDeltaXDotH/locPDotH)*((1.0/locPMag)*locP4.Vect() - (locPMag/locPDotH)*locH);
5431 TVector3 locDPathDCommon = (locPMag/locPDotH)*locH;
5432 TVector3 locDPathDPosition = -1.0*locDPathDCommon;
5433
5434 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex) = locDPathDP3.X();
5435 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex + 1) = locDPathDP3.Y();
5436 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex + 2) = locDPathDP3.Z();
5437
5438 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
5439 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
5440 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
5441
5442 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
5443 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
5444 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
5445
5446 locTempMatrix.Similarity(locTransformationMatrix_PathLength);
5447 locPathLengthUncertainty = sqrt(locTempMatrix(0, 0));
5448 }
5449 else // non-accelerating
5450 {
5451 locPathLength = locDeltaX.Mag();
5452
5453 TMatrixD locTransformationMatrix_PathLength(1, locTempMatrix.GetNcols());
5454
5455 TVector3 locDPathDCommon = locDeltaX.Unit();
5456 TVector3 locDPathDPosition = -1.0*locDPathDCommon;
5457
5458 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
5459 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
5460 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
5461
5462 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
5463 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
5464 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
5465
5466 locTempMatrix.Similarity(locTransformationMatrix_PathLength);
5467 locPathLengthUncertainty = sqrt(locTempMatrix(0, 0));
5468 }
5469 locPathLengthPair.first = locPathLength;
5470 locPathLengthPair.second = locPathLengthUncertainty;
5471
5472 return true;
5473}
5474