Bug Summary

File:libraries/ANALYSIS/DKinFitter.cc
Location:line 2864, column 17
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
2861 {
2862 locKinFitParticle = (locKinFitConstraint_Spacetime->dFullConstrainParticles)[loc_j];
2863 locIsDecayingFlag = (locKinFitParticle->Get_KinFitParticleType() == d_DecayingParticle);
2864 locFIndex = locKinFitConstraint_Vertex->Get_FIndex(locKinFitParticle);
20
Called C++ object pointer is null
2865 if(dDebugLevel > 10)
2866 cout << "DKinFitter: F index, locIsDecayingFlag = " << locFIndex << ", " << locIsDecayingFlag << endl;
2867 Calc_dF_Time(locFIndex, locKinFitParticle, false);
2868 if((locKinFitParticle == dRFMatchedBeamParticle) && locKinFitConstraint_Spacetime->Get_UseRFTimeFlag())
2869 {
2870 locFIndex = locKinFitConstraint_Vertex->Get_FIndex(NULL__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 DKinFitParticle* locKinFitParticle;
4493 DKinFitParticleType locKinFitParticleType;
4494 int locParamIndex;
4495 double locDenominator;
4496
4497 locParamIndex = 0;
4498 dPulls.clear();
4499 map<DKinFitPullType, double> locParticlePulls;
4500 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4501 {
4502 locKinFitParticle = dKinFitParticles[loc_i];
4503 locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
4504
4505 if((locKinFitParticleType == d_DecayingParticle) || (locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_TargetParticle))
4506 continue;
4507 locParticlePulls.clear();
4508
4509 if(dDebugLevel >= 50)
4510 {
4511 cout << "pulls: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4512 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;
4513 }
4514
4515 locParamIndex = locKinFitParticle->Get_EParamIndex();
4516 if(locParamIndex >= 0) //E
4517 {
4518 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4519 locParticlePulls[d_EPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4520 }
4521
4522 locParamIndex = locKinFitParticle->Get_PxParamIndex();
4523 if(locParamIndex >= 0) //px, py, pz
4524 {
4525 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4526 locParticlePulls[d_PxPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4527 ++locParamIndex;
4528 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4529 locParticlePulls[d_PyPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4530 ++locParamIndex;
4531 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4532 locParticlePulls[d_PzPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4533 }
4534
4535 locParamIndex = locKinFitParticle->Get_VxParamIndex();
4536 if(locParamIndex >= 0) //vx, vy, vz
4537 {
4538 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4539 locParticlePulls[d_XxPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4540 ++locParamIndex;
4541 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4542 locParticlePulls[d_XyPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4543 ++locParamIndex;
4544 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4545 locParticlePulls[d_XzPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4546 }
4547
4548 locParamIndex = locKinFitParticle->Get_TParamIndex();
4549 if(locParamIndex >= 0) //T
4550 {
4551 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4552 locParticlePulls[d_TPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4553 }
4554
4555 if(!locParticlePulls.empty())
4556 dPulls[locKinFitParticle] = locParticlePulls;
4557 }
4558
4559 //RF BUNCH
4560 locParamIndex = dRFTimeParamIndex;
4561 if(locParamIndex >= 0)
4562 {
4563 locParticlePulls.clear();
4564 locDenominator = sqrt(fabs(dVY(locParamIndex, locParamIndex) - (*dVEta)(locParamIndex, locParamIndex)));
4565 locParticlePulls[d_TPull] = (locDenominator > 0.0) ? dEpsilon(locParamIndex, 0)/locDenominator : std::numeric_limits<double>::quiet_NaN();
4566 dPulls[NULL__null] = locParticlePulls;
4567 }
4568
4569 if(dDebugLevel > 20)
4570 {
4571 cout << "DKinFitter: dEpsilon: " << endl;
4572 Print_Matrix(dEpsilon);
4573 cout << "DKinFitter: dVY: " << endl;
4574 Print_Matrix(dVY);
4575 cout << "DKinFitter: dVEta: " << endl;
4576 Print_Matrix(*dVEta);
4577 cout << "DKinFitter: Pulls: " << endl;
4578 map<const DKinFitParticle*, map<DKinFitPullType, double> >::iterator locIterator;
4579 map<DKinFitPullType, double>::iterator locIterator2;
4580 for(locIterator = dPulls.begin(); locIterator != dPulls.end(); ++locIterator)
4581 {
4582 map<DKinFitPullType, double>& locTempParticlePulls = locIterator->second;
4583 const DKinFitParticle* locTempKinFitParticle = locIterator->first;
4584 TVector3 locMomentum = locTempKinFitParticle->Get_Momentum();
4585 cout << "particle q, p3 = " << locTempKinFitParticle->Get_Charge() << ", " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ":" << endl;
4586 for(size_t loc_i = 0; loc_i < 8; ++loc_i)
4587 {
4588 if(locTempParticlePulls.find((DKinFitPullType)loc_i) != locTempParticlePulls.end())
4589 cout << locTempParticlePulls[(DKinFitPullType)loc_i] << ", ";
4590 }
4591 cout << endl;
4592 }
4593 }
4594}
4595
4596void DKinFitter::Set_FinalTrackInfo(void)
4597{
4598 TVector3 locMomentum;
4599 TLorentzVector locSpacetimeVertex;
4600 DKinFitParticleType locKinFitParticleType;
4601 int locPxParamIndex, locVxParamIndex, locTParamIndex, locEParamIndex;
4602 int locCovMatrixEParamIndex, locCovMatrixPxParamIndex, locCovMatrixVxParamIndex, locCovMatrixTParamIndex;
4603 double locUncertaintyRatio;
4604
4605 // first update the covariance matrices of each particle with the fit results (prior to any propagation)
4606 //correlations between fit and unfit measured parameters:
4607 //assume that the correlations remain unchanged: the changes in the parameters and their uncertainties should be small wrst their values
4608 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4609 {
4610 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4611 if(locKinFitParticleType == d_TargetParticle)
4612 continue;
4613
4614 // The covariance matrix object is likely shared amongst several DKinFitParticle objects.
4615 // Make sure this object now has a unique object (and set its data)
4616 bool locReconstructedParticleFlag = ((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle));
4617 TMatrixDSym& locKinFitMatrix = locReconstructedParticleFlag ? *dVXi : *dVEta;
4618 if(locReconstructedParticleFlag) //Brand new particle: Set the covariance matrix from scratch
4619 {
4620 TMatrixDSym* locCovarianceMatrix = Get_MatrixDSymResource();
4621 locCovarianceMatrix->ResizeTo(7, 7);
4622 locCovarianceMatrix->Zero();
4623 dKinFitParticles[loc_i]->Set_CovarianceMatrix(locCovarianceMatrix);
4624 }
4625 else //A measured particle. //Use the existing covariance matrix as a starting point
4626 dKinFitParticles[loc_i]->Set_CovarianceMatrix(Clone_MatrixDSym(dKinFitParticles[loc_i]->dCovarianceMatrix));
4627 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
4628
4629 locPxParamIndex = dKinFitParticles[loc_i]->Get_PxParamIndex();
4630 locVxParamIndex = dKinFitParticles[loc_i]->Get_VxParamIndex();
4631 locTParamIndex = dKinFitParticles[loc_i]->Get_TParamIndex();
4632 locEParamIndex = dKinFitParticles[loc_i]->Get_EParamIndex();
4633
4634 locCovMatrixEParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixEParamIndex();
4635 locCovMatrixPxParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixPxParamIndex();
4636 locCovMatrixVxParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixVxParamIndex();
4637 locCovMatrixTParamIndex = dKinFitParticles[loc_i]->Get_CovMatrixTParamIndex();
4638
4639 if(dDebugLevel >= 50)
4640 {
4641 cout << "SETTING FINAL TRACK INFO: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4642 cout << "E, px, vx, t param indices = " << locEParamIndex << ", " << locPxParamIndex << ", " << locVxParamIndex << ", " << locTParamIndex << endl;
4643 cout << "E, px, vx, t cov matrix indices = " << locCovMatrixEParamIndex << ", " << locCovMatrixPxParamIndex << ", " << locCovMatrixVxParamIndex << ", " << locCovMatrixTParamIndex << endl;
4644 cout << "sizes = " << locCovarianceMatrix.GetNrows() << ", " << locCovarianceMatrix.GetNcols() << ", " << locKinFitMatrix.GetNrows() << ", " << locKinFitMatrix.GetNcols() << endl;
4645 }
4646
4647 //decaying particles with momentum derived from other particles
4648 if((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex < 0))
4649 {
4650 //enclosed decaying particle: the momentum is derived from the momentum of its decay products
4651 deque<DKinFitConstraint_P4*> locConstraints = dKinFitParticles[loc_i]->dP4Constraints;
4652 DKinFitConstraint_P4* locConstraintAsParent = NULL__null;
4653 for(size_t loc_j = 0; loc_j < locConstraints.size(); ++loc_j)
4654 {
4655 if((locConstraints[loc_j]->Get_InitialParticles())[0] != dKinFitParticles[loc_i])
4656 continue;
4657 locConstraintAsParent = locConstraints[loc_j];
4658 break;
4659 }
4660 if(locConstraintAsParent != NULL__null)
4661 {
4662 //decaying particle used in a p4 constraint
4663 TMatrixD locJacobian(7, dNumEta + dNumXi);
4664 locJacobian.Zero();
4665 if(dKinFitParticles[loc_i]->Get_DecayingParticleAtProductionVertexFlag())
4666 Calc_DecayingParticleJacobian(locConstraintAsParent, false, locJacobian); //computes jacobian at production vertex
4667 else
4668 Calc_DecayingParticleJacobian(locConstraintAsParent, true, locJacobian); //computes jacobian at decay vertex
4669
4670 //set vertex & time terms
4671 if(locVxParamIndex >= 0)
4672 {
4673 locJacobian(locCovMatrixVxParamIndex, locVxParamIndex + dNumEta) = 1.0;
4674 locJacobian(locCovMatrixVxParamIndex + 1, locVxParamIndex + dNumEta + 1) = 1.0;
4675 locJacobian(locCovMatrixVxParamIndex + 2, locVxParamIndex + dNumEta + 2) = 1.0;
4676 }
4677 int locTParamIndex = dKinFitParticles[loc_i]->Get_TParamIndex();
4678 if(locTParamIndex >= 0)
4679 locJacobian(6, locTParamIndex + dNumEta) = 1.0;
4680
4681 TMatrixDSym locTempMatrix = *dV;
4682 locCovarianceMatrix = locTempMatrix.Similarity(locJacobian);
4683 }
4684 else
4685 {
4686 //decaying particle not used in a p4 constraint (e.g. vertex-only fit)
4687 if(locVxParamIndex >= 0)
4688 {
4689 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4690 {
4691 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4692 locCovarianceMatrix(loc_j + locCovMatrixVxParamIndex, loc_k + locCovMatrixVxParamIndex) = (*dVXi)(locVxParamIndex + loc_j, locVxParamIndex + loc_k);
4693 }
4694 }
4695 if(locTParamIndex >= 0)
4696 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixTParamIndex) = (*dVXi)(locTParamIndex, locTParamIndex);
4697 if((locVxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4698 {
4699 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4700 {
4701 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = (*dVXi)(locVxParamIndex + loc_j, locTParamIndex + 0);
4702 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = (*dVXi)(locTParamIndex + 0, locVxParamIndex + loc_j);
4703 }
4704 }
4705 }
4706
4707 if(dDebugLevel >= 50)
4708 {
4709 cout << "FINAL COV MATRIX (enclosed decaying particle):" << endl;
4710 Print_Matrix(locCovarianceMatrix);
4711 }
4712 continue;
4713 }
4714
4715 //set localized terms first
4716 if(locEParamIndex >= 0)
4717 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixEParamIndex) = locKinFitMatrix(locEParamIndex, locEParamIndex);
4718 if(locPxParamIndex >= 0)
4719 {
4720 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4721 {
4722 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4723 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixPxParamIndex + loc_k) = locKinFitMatrix(loc_j + locPxParamIndex, loc_k + locPxParamIndex);
4724 }
4725 }
4726 if(locVxParamIndex >= 0)
4727 {
4728 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4729 {
4730 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4731 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) = locKinFitMatrix(loc_j + locVxParamIndex, loc_k + locVxParamIndex);
4732 }
4733 }
4734 if(locTParamIndex >= 0)
4735 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixTParamIndex) = locKinFitMatrix(locTParamIndex, locTParamIndex);
4736
4737 //cross terms: E & V (neutral shower)
4738 if((locEParamIndex >= 0) && (locVxParamIndex >= 0)) //both included in the fit
4739 {
4740 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4741 {
4742 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = locKinFitMatrix(locEParamIndex + 0, locVxParamIndex + loc_j);
4743 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) = locKinFitMatrix(locVxParamIndex + loc_j, locEParamIndex + 0);
4744 }
4745 }
4746 else if(!locReconstructedParticleFlag && (locEParamIndex >= 0) && (locVxParamIndex < 0)) //only E included in the fit
4747 {
4748 double locDenominator = sqrt(dVY(locEParamIndex, locEParamIndex));
4749 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locEParamIndex, locEParamIndex))/locDenominator : 0.0;
4750 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4751 {
4752 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4753 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) *= locUncertaintyRatio;
4754 }
4755 }
4756 else if(!locReconstructedParticleFlag && (locEParamIndex < 0) && (locVxParamIndex >= 0) && (locCovMatrixEParamIndex >= 0)) //only V included in the fit //E may not be in the covariance matrix!!
4757 {
4758 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4759 {
4760 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4761 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4762 locCovarianceMatrix(locCovMatrixEParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4763 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixEParamIndex + 0) *= locUncertaintyRatio;
4764 }
4765 }
4766
4767 //cross terms: E & T (neutral shower)
4768 if((locEParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4769 {
4770 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) = locKinFitMatrix(locEParamIndex, locTParamIndex);
4771 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) = locKinFitMatrix(locTParamIndex, locEParamIndex);
4772 }
4773 else if(!locReconstructedParticleFlag && (locEParamIndex >= 0) && (locTParamIndex < 0)) //only E included in the fit
4774 {
4775 double locDenominator = sqrt(dVY(locEParamIndex, locEParamIndex));
4776 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locEParamIndex, locEParamIndex))/locDenominator : 0.0;
4777 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) *= locUncertaintyRatio;
4778 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) *= locUncertaintyRatio;
4779 }
4780 else if(!locReconstructedParticleFlag && (locEParamIndex < 0) && (locTParamIndex >= 0) && (locCovMatrixEParamIndex >= 0)) //only T included in the fit //E may not be in the covariance matrix!!
4781 {
4782 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4783 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4784 locCovarianceMatrix(locCovMatrixEParamIndex, locCovMatrixTParamIndex) *= locUncertaintyRatio;
4785 locCovarianceMatrix(locCovMatrixTParamIndex, locCovMatrixEParamIndex) *= locUncertaintyRatio;
4786 }
4787
4788 //cross terms: P & V
4789 if((locPxParamIndex >= 0) && (locVxParamIndex >= 0)) //both included in the fit
4790 {
4791 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4792 {
4793 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4794 {
4795 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) = locKinFitMatrix(locPxParamIndex + loc_j, locVxParamIndex + loc_k);
4796 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_k, locCovMatrixPxParamIndex + loc_j) = locKinFitMatrix(locVxParamIndex + loc_k, locPxParamIndex + loc_j);
4797 }
4798 }
4799 }
4800 else if(!locReconstructedParticleFlag && (locPxParamIndex >= 0) && (locVxParamIndex < 0)) //only P included in the fit
4801 {
4802 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4803 {
4804 double locDenominator = sqrt(dVY(locPxParamIndex + loc_j, locPxParamIndex + loc_j));
4805 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locPxParamIndex + loc_j, locPxParamIndex + loc_j))/locDenominator : 0.0;
4806 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4807 {
4808 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixVxParamIndex + loc_k) *= locUncertaintyRatio;
4809 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_k, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4810 }
4811 }
4812 }
4813 else if(!locReconstructedParticleFlag && (locPxParamIndex < 0) && (locVxParamIndex >= 0)) //only V included in the fit
4814 {
4815 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4816 {
4817 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4818 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4819 for(unsigned int loc_k = 0; loc_k < 3; ++loc_k)
4820 {
4821 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_k, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4822 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixPxParamIndex + loc_k) *= locUncertaintyRatio;
4823 }
4824 }
4825 }
4826
4827 //cross terms: P & T
4828 if((locPxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4829 {
4830 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4831 {
4832 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = locKinFitMatrix(locPxParamIndex + loc_j, locTParamIndex + 0);
4833 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) = locKinFitMatrix(locTParamIndex + 0, locPxParamIndex + loc_j);
4834 }
4835 }
4836 else if(!locReconstructedParticleFlag && (locPxParamIndex >= 0) && (locTParamIndex < 0)) //only P included in the fit
4837 {
4838 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4839 {
4840 double locDenominator = sqrt(dVY(locPxParamIndex + loc_j, locPxParamIndex + loc_j));
4841 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locPxParamIndex + loc_j, locPxParamIndex + loc_j))/locDenominator : 0.0;
4842 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4843 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4844 }
4845 }
4846 else if(!locReconstructedParticleFlag && (locPxParamIndex < 0) && (locTParamIndex >= 0)) //only T included in the fit
4847 {
4848 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4849 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4850 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4851 {
4852 locCovarianceMatrix(locCovMatrixPxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4853 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixPxParamIndex + loc_j) *= locUncertaintyRatio;
4854 }
4855 }
4856
4857 //cross terms: V & T
4858 if((locVxParamIndex >= 0) && (locTParamIndex >= 0)) //both included in the fit
4859 {
4860 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4861 {
4862 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) = locKinFitMatrix(locVxParamIndex + loc_j, locTParamIndex + 0);
4863 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) = locKinFitMatrix(locTParamIndex + 0, locVxParamIndex + loc_j);
4864 }
4865 }
4866 else if(!locReconstructedParticleFlag && (locVxParamIndex >= 0) && (locTParamIndex < 0)) //only V included in the fit
4867 {
4868 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4869 {
4870 double locDenominator = sqrt(dVY(locVxParamIndex + loc_j, locVxParamIndex + loc_j));
4871 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locVxParamIndex + loc_j, locVxParamIndex + loc_j))/locDenominator : 0.0;
4872 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4873 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4874 }
4875 }
4876 else if(!locReconstructedParticleFlag && (locVxParamIndex < 0) && (locTParamIndex >= 0)) //only T included in the fit
4877 {
4878 double locDenominator = sqrt(dVY(locTParamIndex, locTParamIndex));
4879 locUncertaintyRatio = (fabs(locDenominator) > 0.0) ? sqrt(locKinFitMatrix(locTParamIndex, locTParamIndex))/locDenominator : 0.0;
4880 for(unsigned int loc_j = 0; loc_j < 3; ++loc_j)
4881 {
4882 locCovarianceMatrix(locCovMatrixVxParamIndex + loc_j, locCovMatrixTParamIndex + 0) *= locUncertaintyRatio;
4883 locCovarianceMatrix(locCovMatrixTParamIndex + 0, locCovMatrixVxParamIndex + loc_j) *= locUncertaintyRatio;
4884 }
4885 }
4886
4887 if(dDebugLevel >= 50)
4888 {
4889 cout << "FINAL COV MATRIX:" << endl;
4890 Print_Matrix(locCovarianceMatrix);
4891 }
4892 } //end set cov matrix loop
4893
4894 // propagate the track parameters
4895 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4896 {
4897 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4898
4899 if(!dKinFitParticles[loc_i]->Get_IsInVertexOrSpacetimeFitFlag())
4900 continue; // no distance over which to propagate
4901
4902 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
4903 continue; // particle properties already defined at the fit vertex
4904
4905 pair<double, double> locPathLengthPair;
4906 TMatrixDSym& locCovarianceMatrix = *(dKinFitParticles[loc_i]->dCovarianceMatrix);
4907
4908 if(!Propagate_TrackInfoToCommonVertex(dKinFitParticles[loc_i], dVXi, locMomentum, locSpacetimeVertex, locPathLengthPair, locCovarianceMatrix))
4909 continue; // info not propagated
4910
4911 if(dDebugLevel >= 50)
4912 {
4913 cout << "PROPAGATED FINAL TRACK INFO: q, mass = " << dKinFitParticles[loc_i]->Get_Charge() << ", " << dKinFitParticles[loc_i]->Get_Mass() << endl;
4914 cout << "p_xyz, v_xyzt = " << locMomentum.Px() << ", " << locMomentum.Py() << ", " << locMomentum.Pz() << ", " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
4915 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;
4916 cout << "path length & uncert = " << locPathLengthPair.first << ", " << locPathLengthPair.second << endl;
4917 cout << "sizes = " << locCovarianceMatrix.GetNrows() << ", " << locCovarianceMatrix.GetNcols() << endl;
4918 }
4919
4920 //no need to set the covariance matrix: already updated (passed in a reference to it)
4921 dKinFitParticles[loc_i]->Set_Momentum(locMomentum);
4922 dKinFitParticles[loc_i]->Set_Position(locSpacetimeVertex.Vect());
4923 dKinFitParticles[loc_i]->Set_Time(locSpacetimeVertex.T());
4924 dKinFitParticles[loc_i]->Set_PathLength(locPathLengthPair.first);
4925 dKinFitParticles[loc_i]->Set_PathLengthUncertainty(locPathLengthPair.second);
4926 }
4927
4928 //calculate the path length of decaying particles involved in 2 vertex fits
4929 for(size_t loc_i = 0; loc_i < dKinFitParticles.size(); ++loc_i)
4930 {
4931 locKinFitParticleType = dKinFitParticles[loc_i]->Get_KinFitParticleType();
4932
4933 if((locKinFitParticleType != d_DecayingParticle) || (dKinFitParticles[loc_i]->Get_NumVertexFits() != 2))
4934 continue;
4935
4936 pair<double, double> locPathLengthPair;
4937 const TMatrixDSym& locCovarianceMatrix = *(dKinFitParticles[loc_i]->Get_CovarianceMatrix());
4938 if(Calc_PathLength(dKinFitParticles[loc_i], dVXi, locCovarianceMatrix, locPathLengthPair))
4939 {
4940 dKinFitParticles[loc_i]->Set_PathLength(locPathLengthPair.first);
4941 dKinFitParticles[loc_i]->Set_PathLengthUncertainty(locPathLengthPair.second);
4942 }
4943 }
4944}
4945
4946void DKinFitter::Calc_DecayingParticleJacobian(DKinFitConstraint_P4* locP4Constraint, bool locDecayVertexFlag, TMatrixD& locJacobian) const
4947{
4948 //locJacobian: matrix used to convert dV to the decaying particle covariance matrix: indices are px, py, pz, x, y, z, t
4949 //dimensions are: 7, (dNumXi + dNumEta);
4950 //uses decay products to calculate decaying particle information
4951 //locDecayVertexFlag = true to compute jacobian at the decay vertex, false at the production vertex
4952
4953 if(!locDecayVertexFlag)
4954 {
4955 if(dDebugLevel > 50)
4956 cout << "compute jacobian at production vertex" << endl;
4957 //propagate decaying particle momentum from the decay vertex to the production vertex (if necessary: charged, b-field, etc.)
4958 deque<DKinFitParticle*> locInitialParticles = locP4Constraint->dInitialParticles;
4959 DKinFitParticle* locKinFitParticle = locInitialParticles[0]; //the decaying particle
4960
4961 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
4962 int locCharge = locKinFitParticle->Get_Charge();
4963 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
4964
4965 if(locChargedBFieldFlag && (locNumVertexFits == 2))
4966 {
4967 if(dDebugLevel > 50)
4968 cout << "charged, enclosed decaying particle in a b-field in vertex fits" << endl;
4969 //charged, enclosed decaying particle in a b-field in vertex fits
4970 TVector3 locPosition = locKinFitParticle->Get_Position();
4971 TVector3 locBField = Get_BField(locPosition);
4972 TVector3 locH = locBField.Unit();
4973 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
4974
4975 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex() + dNumEta;
4976 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex() + dNumEta;
4977
4978 //vertex factors
4979 locJacobian(0, locVxParamIndex + 1) += locA*locH.Z();
4980 locJacobian(0, locVxParamIndex + 2) += -1.0*locA*locH.Y();
4981
4982 locJacobian(1, locVxParamIndex) += -1.0*locA*locH.Z();
4983 locJacobian(1, locVxParamIndex + 2) += locA*locH.X();
4984
4985 locJacobian(2, locVxParamIndex) += locA*locH.Y();
4986 locJacobian(2, locVxParamIndex + 1) += -1.0*locA*locH.X();
4987
4988 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
4989 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
4990
4991 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
4992 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
4993
4994 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
4995 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
4996 }
4997 }
4998
4999 deque<DKinFitParticle*> locFinalParticles = locP4Constraint->dFinalParticles;
5000 for(size_t loc_i = 0; loc_i < locFinalParticles.size(); ++loc_i)
5001 {
5002 DKinFitParticle* locKinFitParticle = locFinalParticles[loc_i];
5003 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
5004
5005 int locCharge = locKinFitParticle->Get_Charge();
5006 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5007 TVector3 locPosition = locKinFitParticle->Get_Position();
5008 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5009 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5010 TVector3 locDeltaX = locCommonVertex - locPosition;
5011 if(dDebugLevel > 50)
5012 cout << "jacobian: decay product: q, mass = " << locCharge << ", " << locKinFitParticle->Get_Mass() << endl;
5013
5014 TVector3 locH = locBField.Unit();
5015 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
5016
5017 size_t locNumVertexFits = locKinFitParticle->Get_NumVertexFits();
5018 bool locEnoughVertexFitsFlag = (locNumVertexFits > 0) && ((locNumVertexFits == 2) || (locKinFitParticleType != d_DecayingParticle));
5019 bool locChargedBFieldFlag = (locCharge != 0) && Get_IsBFieldNearBeamline();
5020 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
5021
5022 int locEParamIndex = locKinFitParticle->Get_EParamIndex();
5023 int locPxParamIndex = locKinFitParticle->Get_PxParamIndex();
5024 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
5025 locPxParamIndex += dNumEta;
5026 int locVxParamIndex = locKinFitParticle->Get_VxParamIndex();
5027 if((locKinFitParticleType == d_MissingParticle) || (locKinFitParticleType == d_DecayingParticle))
5028 locVxParamIndex += dNumEta;
5029 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex() + dNumEta;
5030
5031 if(locKinFitParticleType == d_TargetParticle)
5032 continue;
5033 else if(locChargedBFieldFlag && locEnoughVertexFitsFlag && ((locKinFitParticleType == d_DetectedParticle) || (locKinFitParticleType == d_BeamParticle)))
5034 {
5035 if(dDebugLevel > 50)
5036 cout << "jacobian: partials part 1" << endl;
5037
5038 locJacobian(0, locPxParamIndex) = 1.0;
5039 locJacobian(1, locPxParamIndex + 1) = 1.0;
5040 locJacobian(2, locPxParamIndex + 2) = 1.0;
5041
5042 locJacobian(0, locVxParamIndex + 1) = locA*locH.Z();
5043 locJacobian(0, locVxParamIndex + 2) = -1.0*locA*locH.Y();
5044
5045 locJacobian(1, locVxParamIndex) = -1.0*locA*locH.Z();
5046 locJacobian(1, locVxParamIndex + 2) = locA*locH.X();
5047
5048 locJacobian(2, locVxParamIndex) = locA*locH.Y();
5049 locJacobian(2, locVxParamIndex + 1) = -1.0*locA*locH.X();
5050
5051 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5052 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5053
5054 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5055 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5056
5057 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5058 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5059 }
5060 else if(locNeutralShowerFlag)
5061 {
5062 if(dDebugLevel > 50)
5063 cout << "jacobian: partials part 2" << endl;
5064
5065 double locEOverPSq = locP4.E()/locP4.Vect().Mag2();
5066 locJacobian(0, locEParamIndex) = locEOverPSq*locP4.Px();
5067 locJacobian(1, locEParamIndex) = locEOverPSq*locP4.Py();
5068 locJacobian(2, locEParamIndex) = locEOverPSq*locP4.Pz();
5069
5070 TVector3 locDeltaXOverMagDeltaXSq = locDeltaX*(1.0/locDeltaX.Mag2());
5071
5072 locJacobian(0, locVxParamIndex) = locP4.Px()*(locDeltaXOverMagDeltaXSq.X() - 1.0/locDeltaX.X());
5073 locJacobian(1, locVxParamIndex + 1) = locP4.Py()*(locDeltaXOverMagDeltaXSq.Y() - 1.0/locDeltaX.Y());
5074 locJacobian(2, locVxParamIndex + 2) = locP4.Pz()*(locDeltaXOverMagDeltaXSq.Z() - 1.0/locDeltaX.Z());
5075
5076 locJacobian(0, locVxParamIndex + 1) = locP4.Px()*locDeltaXOverMagDeltaXSq.Y();
5077 locJacobian(0, locVxParamIndex + 2) = locP4.Px()*locDeltaXOverMagDeltaXSq.Z();
5078
5079 locJacobian(1, locVxParamIndex) = locP4.Py()*locDeltaXOverMagDeltaXSq.X();
5080 locJacobian(1, locVxParamIndex + 2) = locP4.Py()*locDeltaXOverMagDeltaXSq.Z();
5081
5082 locJacobian(2, locVxParamIndex) = locP4.Pz()*locDeltaXOverMagDeltaXSq.X();
5083 locJacobian(2, locVxParamIndex + 1) = locP4.Pz()*locDeltaXOverMagDeltaXSq.Y();
5084
5085 locJacobian(0, locCommonVxParamIndex) -= locJacobian(0, locVxParamIndex);
5086 locJacobian(1, locCommonVxParamIndex + 1) -= locJacobian(1, locVxParamIndex + 1);
5087 locJacobian(2, locCommonVxParamIndex + 2) -= locJacobian(2, locVxParamIndex + 2);
5088
5089 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5090 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5091
5092 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5093 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5094
5095 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5096 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5097 }
5098 else if((locKinFitParticleType == d_MissingParticle) || ((locKinFitParticleType == d_DecayingParticle) && (locPxParamIndex >= 0)))
5099 {
5100 if(dDebugLevel > 50)
5101 cout << "jacobian: partials part 3" << endl;
5102
5103 //missing or open-ended-decaying particle: p3 is unknown (not derivable)
5104 locJacobian(0, locPxParamIndex) = 1.0;
5105 locJacobian(1, locPxParamIndex + 1) = 1.0;
5106 locJacobian(2, locPxParamIndex + 2) = 1.0;
5107 }
5108 else if(locKinFitParticleType == d_DecayingParticle)
5109 {
5110 if(dDebugLevel > 50)
5111 cout << "jacobian: partials part 4" << endl;
5112
5113 //charged, enclosed decaying particle in a b-field
5114 if(locChargedBFieldFlag && (locKinFitParticle->Get_NumVertexFits() == 2))
5115 {
5116 if(dDebugLevel > 50)
5117 cout << "jacobian: partials part 4a" << endl;
5118
5119 //vertex factors
5120 locJacobian(0, locVxParamIndex + 1) += locA*locH.Z();
5121 locJacobian(0, locVxParamIndex + 2) += -1.0*locA*locH.Y();
5122
5123 locJacobian(1, locVxParamIndex) += -1.0*locA*locH.Z();
5124 locJacobian(1, locVxParamIndex + 2) += locA*locH.X();
5125
5126 locJacobian(2, locVxParamIndex) += locA*locH.Y();
5127 locJacobian(2, locVxParamIndex + 1) += -1.0*locA*locH.X();
5128
5129 locJacobian(0, locCommonVxParamIndex + 1) -= locJacobian(0, locVxParamIndex + 1);
5130 locJacobian(0, locCommonVxParamIndex + 2) -= locJacobian(0, locVxParamIndex + 2);
5131
5132 locJacobian(1, locCommonVxParamIndex) -= locJacobian(1, locVxParamIndex);
5133 locJacobian(1, locCommonVxParamIndex + 2) -= locJacobian(1, locVxParamIndex + 2);
5134
5135 locJacobian(2, locCommonVxParamIndex) -= locJacobian(2, locVxParamIndex);
5136 locJacobian(2, locCommonVxParamIndex + 1) -= locJacobian(2, locVxParamIndex + 1);
5137 }
5138
5139 //p4 is derived from other particles:
5140 deque<DKinFitConstraint_P4*> locP4Constraints = locFinalParticles[loc_i]->dP4Constraints;
5141 for(size_t loc_j = 0; loc_j < locP4Constraints.size(); ++loc_j)
5142 {
5143 if(locP4Constraints[loc_j] == locP4Constraint)
5144 continue;
5145 if(dDebugLevel > 50)
5146 cout << "jacobian: partials part 4b" << endl;
5147 Calc_DecayingParticleJacobian(locP4Constraints[loc_j], true, locJacobian);
5148 break;
5149 }
5150 }
5151 else
5152 {
5153 if(dDebugLevel > 50)
5154 cout << "jacobian: partials part 5" << endl;
5155
5156 // either no common vertex constraint, charged and detected but b-field = 0, or neutral particle with pre-ordained vertex (e.g. beam particle)
5157 locJacobian(0, locPxParamIndex) = 1.0;
5158 locJacobian(1, locPxParamIndex + 1) = 1.0;
5159 locJacobian(2, locPxParamIndex + 2) = 1.0;
5160 }
5161 }
5162}
5163
5164// propagates the track info to the fit common vertex
5165 //returns false if nothing changed (info not propagated: e.g. missing particle), else returns true
5166//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
5167// this function acts in the following way on each particle, IN THIS ORDER OF EXECUTION:
5168 // if a common vertex was not fit, then the current results are returned
5169 // if this is either a target particle, a missing particle, or a decaying particle that is present in only one vertex fit:
5170 // the current info is defined to be at the common vertex: just return it
5171 // if this is a decaying particle that is present in two vertex fits: the returned info is the info at the "other" vertex
5172 // "other" is the opposite of where the particle info is defined to be:
5173 // e.g. if dDecayingParticleAtProductionVertexFlag == true, then the "other" vertex is the decay vertex
5174 // for the remaining types (including decaying particles):
5175 // the vertex is set to the common vertex
5176 // if the time was fit, then the time is set to the common time, else it is propagated to the common vertex
5177 // if the path length was fit then the fit result is used; otherwise it is propagated
5178 // momentum:
5179 // if this is a neutral shower: momentum is redefined by the new vertex //already done by Update_ParticleParams()
5180 // if this is a neutral particle (either detected, beam, or decaying) or a charged particle without a b-field: the momentum is unchanged
5181 // if this is a charged particle in a b-field (either beam, detected, or decaying): the momentum is propagated to the common vertex
5182 //propagating the covariance matrix:
5183 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5184 //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
5185 //transform to 7x7: common v3 & common t are just copied to the measured spots
5186//the output covariance matrix is 7x7, even if the particle represents a neutral shower (5x5)
5187//the only thing this function uses that depends on the state of the fitter itself is the magnetic field map
5188bool DKinFitter::Propagate_TrackInfoToCommonVertex(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, TVector3& locMomentum, TLorentzVector& locSpacetimeVertex, pair<double, double>& locPathLengthPair, TMatrixDSym& locCovarianceMatrix) const
5189{
5190 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
5191
5192 if(!locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag())
5193 return false; // no distance over which to propagate
5194
5195 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
5196 return false; // particle properties already defined at the fit vertex
5197
5198 if((locKinFitParticleType == d_DecayingParticle) && (locKinFitParticle->Get_NumVertexFits() != 2))
5199 return false; // particle properties already defined at the fit vertex
5200
5201 locCovarianceMatrix = *(locKinFitParticle->Get_CovarianceMatrix());
5202 bool locNeutralShowerFlag = locKinFitParticle->Get_IsNeutralShowerFlag();
5203
5204 int locCharge = locKinFitParticle->Get_Charge();
5205 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5206
5207 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5208 TVector3 locPosition = locKinFitParticle->Get_Position();
5209 TVector3 locDeltaX = locCommonVertex - locPosition;
5210 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5211 TVector3 locH = locBField.Unit();
5212 double locA = -0.00299792458*(double(locCharge))*locBField.Mag();
5213 double locCommonTime;
5214
5215 // covariance matrix
5216 int locCovMatrixEParamIndex = locKinFitParticle->Get_CovMatrixEParamIndex();
5217 int locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
5218 int locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
5219 int locCovMatrixTParamIndex = locKinFitParticle->Get_CovMatrixTParamIndex();
5220 int locCommonVxParamIndex_TempMatrix, locCommonTParamIndex_TempMatrix;
5221
5222 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
5223 int locCommonTParamIndex = locKinFitParticle->Get_CommonTParamIndex();
5224
5225 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5226 locCommonVxParamIndex_TempMatrix = locCovarianceMatrix.GetNcols();
5227 locCovarianceMatrix.ResizeTo(locCommonVxParamIndex_TempMatrix + 3, locCommonVxParamIndex_TempMatrix + 3);
5228 for(size_t loc_i = 0; loc_i < 3; ++loc_i)
5229 {
5230 for(size_t loc_j = 0; loc_j < 3; ++loc_j)
5231 locCovarianceMatrix(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
5232 }
5233 // done: no correlations between common vertex and measured params!!!
5234 locSpacetimeVertex.SetVect(locCommonVertex);
5235
5236 //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
5237 //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))
5238 locCommonTParamIndex_TempMatrix = locCovarianceMatrix.GetNcols();
5239 if(locKinFitParticle->Get_IsInSpacetimeFitFlag()) //spacetime was fit
5240 {
5241 locCommonTime = locKinFitParticle->Get_CommonTime();
5242 locCovarianceMatrix.ResizeTo(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols() + 1);
5243 locCovarianceMatrix(locCommonTParamIndex_TempMatrix, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonTParamIndex, locCommonTParamIndex);
5244 for(size_t loc_i = 0; loc_i < 3; ++loc_i) //correlations to common v3
5245 {
5246 locCovarianceMatrix(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + loc_i) = (*locVXi)(locCommonTParamIndex, locCommonVxParamIndex + loc_i);
5247 locCovarianceMatrix(locCommonVxParamIndex_TempMatrix + loc_i, locCommonTParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonTParamIndex);
5248 }
5249 }
5250 else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
5251 {
5252 double locDeltaXDotH = locDeltaX.Dot(locH);
5253 double locPDotH = locP4.Vect().Dot(locH);
5254 locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotH*locP4.E()/(29.9792458*locPDotH);
5255
5256 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5257 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5258 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5259
5260 TVector3 locDCommonTimeDP3 = (locDeltaXDotH/(29.9792458*locPDotH)) * ((1.0/locP4.E())*locP4.Vect() - (locP4.E()/locPDotH)*locH);
5261 TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locPDotH))*locH;
5262 TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
5263
5264 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
5265 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
5266 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
5267
5268 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5269 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5270 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5271
5272 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5273 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5274 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5275
5276 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5277
5278 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5279 }
5280 else if(!locNeutralShowerFlag) //non-accelerating, non-shower
5281 {
5282 double locDeltaXDotP = locDeltaX.Dot(locP4.Vect());
5283 locCommonTime = locKinFitParticle->Get_Time() + locDeltaXDotP*locP4.E()/(29.9792458*locP4.Vect().Mag2());
5284
5285 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5286 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5287 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5288
5289 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());
5290 TVector3 locDCommonTimeDCommonVertex = (locP4.E()/(29.9792458*locP4.Vect().Mag2()))*locP4.Vect();
5291 TVector3 locDCommonTimeDPosition = -1.0*locDCommonTimeDCommonVertex;
5292
5293 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex) = locDCommonTimeDP3.X();
5294 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 1) = locDCommonTimeDP3.Y();
5295 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixPxParamIndex + 2) = locDCommonTimeDP3.Z();
5296
5297 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5298 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5299 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5300
5301 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5302 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5303 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5304
5305 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5306
5307 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5308 }
5309 else //neutral shower
5310 {
5311 locCommonTime = locKinFitParticle->Get_Time() - locDeltaX.Mag()*locP4.E()/(29.9792458*locP4.P());
5312
5313 TMatrixD locTransformationMatrix_CommonTime(locCovarianceMatrix.GetNcols() + 1, locCovarianceMatrix.GetNcols());
5314 for(unsigned int loc_i = 0; int(loc_i) < locCovarianceMatrix.GetNcols(); ++loc_i)
5315 locTransformationMatrix_CommonTime(loc_i, loc_i) = 1.0; //other params are unchanged
5316
5317 double locDCommonTimeDEnergy = locDeltaX.Mag()*locP4.M2()/(29.9792458*locP4.P()*locP4.Vect().Mag2());
5318 TVector3 locDCommonTimeDPosition = (locP4.E()/(29.9792458*locP4.P()*locDeltaX.Mag()))*locDeltaX;
5319 TVector3 locDCommonTimeDCommonVertex = -1.0*locDCommonTimeDPosition;
5320
5321 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixEParamIndex) = locDCommonTimeDEnergy;
5322
5323 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex) = locDCommonTimeDPosition.X();
5324 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 1) = locDCommonTimeDPosition.Y();
5325 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixVxParamIndex + 2) = locDCommonTimeDPosition.Z();
5326
5327 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix) = locDCommonTimeDCommonVertex.X();
5328 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 1) = locDCommonTimeDCommonVertex.Y();
5329 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCommonVxParamIndex_TempMatrix + 2) = locDCommonTimeDCommonVertex.Z();
5330
5331 locTransformationMatrix_CommonTime(locCommonTParamIndex_TempMatrix, locCovMatrixTParamIndex) = 1.0;
5332
5333 locCovarianceMatrix.Similarity(locTransformationMatrix_CommonTime);
5334 }
5335 locSpacetimeVertex.SetT(locCommonTime);
5336
5337 //transform to 7x7: common v3 & common t are just copied to the measured spots; p is propagated if in bfield, else is copied
5338 TMatrixD locTransformationMatrix_Propagation(7, locCovarianceMatrix.GetNcols());
5339 //p3
5340 if((locCharge != 0) && Get_IsBFieldNearBeamline()) //charged & in b-field
5341 {
5342 locMomentum = locP4.Vect() - locDeltaX.Cross(locA*locH);
5343
5344 locTransformationMatrix_Propagation(0, locCovMatrixPxParamIndex) = 1.0;
5345 locTransformationMatrix_Propagation(1, locCovMatrixPxParamIndex + 1) = 1.0;
5346 locTransformationMatrix_Propagation(2, locCovMatrixPxParamIndex + 2) = 1.0;
5347
5348 locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 1) = -1.0*locA*locH.Z();
5349 locTransformationMatrix_Propagation(0, locCovMatrixVxParamIndex + 2) = locA*locH.Y();
5350
5351 locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex) = locA*locH.Z();
5352 locTransformationMatrix_Propagation(1, locCovMatrixVxParamIndex + 2) = -1.0*locA*locH.X();
5353
5354 locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex) = -1.0*locA*locH.Y();
5355 locTransformationMatrix_Propagation(2, locCovMatrixVxParamIndex + 1) = locA*locH.X();
5356
5357 locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 1) = locA*locH.Z();
5358 locTransformationMatrix_Propagation(0, locCommonVxParamIndex_TempMatrix + 2) = -1.0*locA*locH.Y();
5359
5360 locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix) = -1.0*locA*locH.Z();
5361 locTransformationMatrix_Propagation(1, locCommonVxParamIndex_TempMatrix + 2) = locA*locH.X();
5362
5363 locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix) = locA*locH.Y();
5364 locTransformationMatrix_Propagation(2, locCommonVxParamIndex_TempMatrix + 1) = -1.0*locA*locH.X();
5365 }
5366 else //constant: either neutral or no b-field
5367 {
5368 locMomentum = locP4.Vect();
5369 for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
5370 locTransformationMatrix_Propagation(loc_i, locCovMatrixPxParamIndex + loc_i) = 1.0;
5371 }
5372 //v3
5373 for(unsigned int loc_i = 0; loc_i < 3; ++loc_i)
5374 locTransformationMatrix_Propagation(3 + loc_i, locCommonVxParamIndex_TempMatrix + loc_i) = 1.0;
5375 //t
5376 locTransformationMatrix_Propagation(6, locCommonTParamIndex_TempMatrix) = 1.0;
5377 //transform!!
5378 locCovarianceMatrix.Similarity(locTransformationMatrix_Propagation); //FINALLY!!!
5379
5380 return Calc_PathLength(locKinFitParticle, locVXi, locCovarianceMatrix, locPathLengthPair);
5381}
5382
5383bool DKinFitter::Calc_PathLength(const DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi, const TMatrixDSym& locCovarianceMatrix, pair<double, double>& locPathLengthPair) const
5384{
5385 DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
5386
5387 if(!locKinFitParticle->Get_IsInVertexOrSpacetimeFitFlag())
5388 return false; // no distance over which to propagate
5389
5390 if((locKinFitParticleType == d_TargetParticle) || (locKinFitParticleType == d_MissingParticle))
5391 return false; // particle properties already defined at the fit vertex
5392
5393 if((locKinFitParticleType == d_DecayingParticle) && (locKinFitParticle->Get_NumVertexFits() != 2))
5394 return false; // particle properties already defined at the fit vertex
5395
5396 double locPathLength, locPathLengthUncertainty;
5397 int locCovMatrixPxParamIndex = locKinFitParticle->Get_CovMatrixPxParamIndex();
5398 int locCovMatrixVxParamIndex = locKinFitParticle->Get_CovMatrixVxParamIndex();
5399 int locCommonVxParamIndex = locKinFitParticle->Get_CommonVxParamIndex();
5400
5401 int locCharge = locKinFitParticle->Get_Charge();
5402 TVector3 locCommonVertex = locKinFitParticle->Get_CommonVertex();
5403 TLorentzVector locP4 = locKinFitParticle->Get_P4();
5404 TVector3 locPosition = locKinFitParticle->Get_Position();
5405 TVector3 locDeltaX = locCommonVertex - locPosition;
5406 TVector3 locBField = Get_IsBFieldNearBeamline() ? Get_BField(locPosition) : TVector3(0.0, 0.0, 0.0);
5407 TVector3 locH = locBField.Unit();
5408
5409 int locLParamIndex = locKinFitParticle->Get_LParamIndex();
5410
5411 //add common v3 to matrix: 10x10 or 8x8 (neutral shower)
5412 TMatrixDSym locTempMatrix(locCovarianceMatrix);
5413 int locCommonVxParamIndex_TempMatrix = locTempMatrix.GetNcols();
5414 locTempMatrix.ResizeTo(locCommonVxParamIndex_TempMatrix + 3, locCommonVxParamIndex_TempMatrix + 3);
5415 for(size_t loc_i = 0; loc_i < 3; ++loc_i)
5416 {
5417 for(size_t loc_j = 0; loc_j < 3; ++loc_j)
5418 locTempMatrix(loc_i + locCommonVxParamIndex_TempMatrix, loc_j + locCommonVxParamIndex_TempMatrix) = (*locVXi)(locCommonVxParamIndex + loc_i, locCommonVxParamIndex + loc_j);
5419 }
5420
5421 //find path length & its uncertainty
5422 if(locKinFitParticle->Get_IsInSpacetimeFitFlag() && (locCharge != 0) && Get_IsBFieldNearBeamline()) //path length was fit
5423 {
5424 locPathLength = locKinFitParticle->Get_PathLength();
5425 locPathLengthUncertainty = (*locVXi)(locLParamIndex, locLParamIndex);
5426 }
5427 else if((locCharge != 0) && Get_IsBFieldNearBeamline()) //in b-field & charged
5428 {
5429 double locDeltaXDotH = locDeltaX.Dot(locH);
5430 double locPDotH = locP4.Vect().Dot(locH);
5431 double locPMag = locP4.P();
5432 locPathLength = locDeltaXDotH*locPMag/locPDotH; //cos(theta_helix) = p.dot(h)/|p| = x.dot(h)/l (l = path length)
5433
5434 TMatrixD locTransformationMatrix_PathLength(1, locTempMatrix.GetNcols());
5435
5436 TVector3 locDPathDP3 = (locDeltaXDotH/locPDotH)*((1.0/locPMag)*locP4.Vect() - (locPMag/locPDotH)*locH);
5437 TVector3 locDPathDCommon = (locPMag/locPDotH)*locH;
5438 TVector3 locDPathDPosition = -1.0*locDPathDCommon;
5439
5440 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex) = locDPathDP3.X();
5441 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex + 1) = locDPathDP3.Y();
5442 locTransformationMatrix_PathLength(0, locCovMatrixPxParamIndex + 2) = locDPathDP3.Z();
5443
5444 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
5445 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
5446 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
5447
5448 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
5449 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
5450 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
5451
5452 locTempMatrix.Similarity(locTransformationMatrix_PathLength);
5453 locPathLengthUncertainty = sqrt(locTempMatrix(0, 0));
5454 }
5455 else // non-accelerating
5456 {
5457 locPathLength = locDeltaX.Mag();
5458
5459 TMatrixD locTransformationMatrix_PathLength(1, locTempMatrix.GetNcols());
5460
5461 TVector3 locDPathDCommon = locDeltaX.Unit();
5462 TVector3 locDPathDPosition = -1.0*locDPathDCommon;
5463
5464 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex) = locDPathDPosition.X();
5465 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 1) = locDPathDPosition.Y();
5466 locTransformationMatrix_PathLength(0, locCovMatrixVxParamIndex + 2) = locDPathDPosition.Z();
5467
5468 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix) = locDPathDCommon.X();
5469 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 1) = locDPathDCommon.Y();
5470 locTransformationMatrix_PathLength(0, locCommonVxParamIndex_TempMatrix + 2) = locDPathDCommon.Z();
5471
5472 locTempMatrix.Similarity(locTransformationMatrix_PathLength);
5473 locPathLengthUncertainty = sqrt(locTempMatrix(0, 0));
5474 }
5475 locPathLengthPair.first = locPathLength;
5476 locPathLengthPair.second = locPathLengthUncertainty;
5477
5478 return true;
5479}
5480