Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DKinFitUtils_GlueX.cc
Go to the documentation of this file.
1 #include "DKinFitUtils_GlueX.h"
2 
3 /******************************************************************** INITIALIZE *******************************************************************/
4 
5 DKinFitUtils_GlueX::DKinFitUtils_GlueX(const DMagneticFieldMap* locMagneticFieldMap, const DAnalysisUtilities* locAnalysisUtilities) :
6 dMagneticFieldMap(locMagneticFieldMap), dAnalysisUtilities(locAnalysisUtilities)
7 {
9  dWillBeamHaveErrorsFlag = false; //Until fixed!
10 
11  dApplication = dynamic_cast<DApplication*>(japp);
12  gPARMS->SetDefaultParameter("KINFIT:LINKVERTICES", dLinkVerticesFlag);
13 }
14 
15 DKinFitUtils_GlueX::DKinFitUtils_GlueX(JEventLoop* locEventLoop)
16 {
17  locEventLoop->GetSingle(dAnalysisUtilities);
18 
19  dApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
20  dMagneticFieldMap = dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber());
21 
22  gPARMS->SetDefaultParameter("KINFIT:LINKVERTICES", dLinkVerticesFlag);
23  dWillBeamHaveErrorsFlag = false; //Until fixed!
25 }
26 
27 /*********************************************************** OVERRIDE BASE CLASS FUNCTIONS *********************************************************/
28 
30 {
37 
40 
42 }
43 
45 {
46  return dIncludeBeamlineInVertexFitFlag; //at least until covariance matrix is set for beam photons
47 }
48 
50 {
51  if(dMagneticFieldMap == NULL)
52  return false;
53 
54  return (dynamic_cast<const DMagneticFieldMapNoField*>(dMagneticFieldMap) == NULL);
55 }
56 
57 TVector3 DKinFitUtils_GlueX::Get_BField(const TVector3& locPosition) const
58 {
59  if(dMagneticFieldMap == NULL)
60  return TVector3(0.0, 0.0, 0.0);
61 
62  double locBx, locBy, locBz;
63  dMagneticFieldMap->GetField(locPosition.X(), locPosition.Y(), locPosition.Z(), locBx, locBy, locBz);
64  return (TVector3(locBx, locBy, locBz));
65 }
66 
67 /****************************************************************** MAKE PARTICLES *****************************************************************/
68 
69 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_BeamParticle(const DBeamPhoton* locBeamPhoton)
70 {
71  pair<const DBeamPhoton*, const DEventRFBunch*> locSourcePair(locBeamPhoton, NULL);
73  return dParticleMap_SourceToInput_Beam[locSourcePair]; //not unique, return existing
74 
75  TLorentzVector locSpacetimeVertex(Make_TVector3(locBeamPhoton->position()), locBeamPhoton->time());
76  TVector3 locMomentum = Make_TVector3(locBeamPhoton->momentum());
77  Particle_t locPID = locBeamPhoton->PID();
78 
79  auto locKinFitParticle = DKinFitUtils::Make_BeamParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID), locSpacetimeVertex, locMomentum, locBeamPhoton->errorMatrix());
80  dParticleMap_SourceToInput_Beam[locSourcePair] = locKinFitParticle;
81  dParticleMap_InputToSource_JObject[locKinFitParticle] = locBeamPhoton;
82  return locKinFitParticle;
83 }
84 
85 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_BeamParticle(const DBeamPhoton* locBeamPhoton, const DEventRFBunch* locEventRFBunch)
86 {
87  pair<const DBeamPhoton*, const DEventRFBunch*> locSourcePair(locBeamPhoton, locEventRFBunch);
89  return dParticleMap_SourceToInput_Beam[locSourcePair]; //not unique, return existing
90 
91  //set rf time for beam particle
92  TLorentzVector locSpacetimeVertex(Make_TVector3(locBeamPhoton->position()), locEventRFBunch->dTime);
93  TVector3 locMomentum = Make_TVector3(locBeamPhoton->momentum());
94  Particle_t locPID = locBeamPhoton->PID();
95 
96  //set rf time variance in covariance matrix
97  auto locCovarianceMatrix = Get_SymMatrixResource(7);
98  *locCovarianceMatrix = *(locBeamPhoton->errorMatrix());
99  (*locCovarianceMatrix)(6, 6) = locEventRFBunch->dTimeVariance;
100  //zero the correlation terms
101  for(int loc_i = 0; loc_i < 6; ++loc_i)
102  {
103  (*locCovarianceMatrix)(6, loc_i) = 0.0;
104  (*locCovarianceMatrix)(loc_i, 6) = 0.0;
105  }
106 
107  auto locKinFitParticle = DKinFitUtils::Make_BeamParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID), locSpacetimeVertex, locMomentum, locCovarianceMatrix);
108  dParticleMap_SourceToInput_Beam[locSourcePair] = locKinFitParticle;
109  dParticleMap_InputToSource_JObject[locKinFitParticle] = locBeamPhoton;
110  return locKinFitParticle;
111 }
112 
113 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_DetectedParticle(const DKinematicData* locKinematicData)
114 {
116  return dParticleMap_SourceToInput_DetectedParticle[locKinematicData]; //not unique, return existing
117 
118  TLorentzVector locSpacetimeVertex(Make_TVector3(locKinematicData->position()), locKinematicData->time());
119  TVector3 locMomentum = Make_TVector3(locKinematicData->momentum());
120  Particle_t locPID = locKinematicData->PID();
121 
122  double locPathLength = 0.0;
123  auto locChargedHypo = dynamic_cast<const DChargedTrackHypothesis*>(locKinematicData);
124  if(locChargedHypo != nullptr)
125  locPathLength = locChargedHypo->Get_PathLength();
126  else
127  {
128  auto locNeutralHypo = dynamic_cast<const DNeutralParticleHypothesis*>(locKinematicData);
129  if(locNeutralHypo != nullptr)
130  locPathLength = locNeutralHypo->Get_PathLength();
131  }
132 
133  auto locKinFitParticle = DKinFitUtils::Make_DetectedParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID), locSpacetimeVertex, locMomentum, locPathLength, locKinematicData->errorMatrix());
134  dParticleMap_SourceToInput_DetectedParticle[locKinematicData] = locKinFitParticle;
135  dParticleMap_InputToSource_JObject[locKinFitParticle] = locKinematicData;
136  return locKinFitParticle;
137 }
138 
139 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_DetectedShower(const DNeutralShower* locNeutralShower, Particle_t locPID)
140 {
141  pair<const DNeutralShower*, Particle_t> locSourcePair(locNeutralShower, locPID);
143  return dParticleMap_SourceToInput_Shower[locSourcePair]; //not unique, return existing
144 
145  //use DNeutralShower object (doesn't make assumption about vertex!)
146  TLorentzVector locShowerSpacetime = Make_TLorentzVector(locNeutralShower->dSpacetimeVertex);
147  auto locKinFitParticle = DKinFitUtils::Make_DetectedShower(PDGtype(locPID), ParticleMass(locPID), locShowerSpacetime, locNeutralShower->dEnergy, locNeutralShower->dCovarianceMatrix);
148 
149  dParticleMap_SourceToInput_Shower[locSourcePair] = locKinFitParticle;
150  dParticleMap_InputToSource_JObject[locKinFitParticle] = locNeutralShower;
151  return locKinFitParticle;
152 }
153 
154 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_TargetParticle(Particle_t locPID, size_t locInstance)
155 {
156  auto locTargetPair = std::make_pair(locPID, locInstance);
158  return dParticleMap_SourceToInput_Target[locTargetPair]; //not unique, return existing
159 
160  auto locKinFitParticle = DKinFitUtils::Make_TargetParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID));
161  dParticleMap_SourceToInput_Target[locTargetPair] = locKinFitParticle;
162  return locKinFitParticle;
163 }
164 
165 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_MissingParticle(Particle_t locPID)
166 {
168  return dParticleMap_SourceToInput_Missing[locPID]; //not unique, return existing
169 
170  auto locKinFitParticle = DKinFitUtils::Make_MissingParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID));
171  dParticleMap_SourceToInput_Missing[locPID] = locKinFitParticle;
172  return locKinFitParticle;
173 }
174 
175 shared_ptr<DKinFitParticle> DKinFitUtils_GlueX::Make_DecayingParticle(Particle_t locPID, const set<shared_ptr<DKinFitParticle>>& locFromInitialState, const set<shared_ptr<DKinFitParticle>>& locFromFinalState)
176 {
177  DDecayingParticleInfo locDecayingParticleInfo(locPID, locFromInitialState, locFromFinalState);
178  if(dParticleMap_SourceToInput_Decaying.find(locDecayingParticleInfo) != dParticleMap_SourceToInput_Decaying.end())
179  return dParticleMap_SourceToInput_Decaying[locDecayingParticleInfo]; //not unique, return existing
180 
181  auto locKinFitParticle = DKinFitUtils::Make_DecayingParticle(PDGtype(locPID), ParticleCharge(locPID), ParticleMass(locPID), locFromInitialState, locFromFinalState);
182  dParticleMap_SourceToInput_Decaying[locDecayingParticleInfo] = locKinFitParticle;
183  dParticleMap_InputToSource_Decaying.emplace(locKinFitParticle, locDecayingParticleInfo);
184  return locKinFitParticle;
185 }
186 
187 /**************************************************************** MAKE DKINFITCHAIN ****************************************************************/
188 
189 shared_ptr<const DKinFitChain> DKinFitUtils_GlueX::Make_KinFitChain(const DReactionVertexInfo* locReactionVertexInfo, const DReaction* locReaction, const DParticleCombo* locParticleCombo, DKinFitType locKinFitType)
190 {
191  //locKinFitType input in case want to do a different fit
192  if(dDebugLevel > 10)
193  cout << "DKinFitUtils_GlueX: Create DKinFitChain." << endl;
194 
195  auto locKinFitChain = dResourcePool_KinFitChain->Get_SharedResource();
196  locKinFitChain->Set_DefinedParticleStepIndex(-1); //unless changed below
197 
198  //Make chain, excluding decaying particles
199  //They must be created using the detected particles, so just create those first
200  for(size_t loc_i = 0; loc_i < locParticleCombo->Get_NumParticleComboSteps(); ++loc_i)
201  {
202  //Create it
203  auto locKinFitChainStep = Make_KinFitChainStep(locReactionVertexInfo, locReaction, locParticleCombo, locKinFitType, loc_i, locKinFitChain);
204  locKinFitChain->Add_KinFitChainStep(locKinFitChainStep);
205  }
206 
207  //Now define the decaying particles using the detected & beam particles
208 
209  //start looping from the back, using invariant mass wherever possible
210  //not possible if missing decay product: will then compute via missing mass in the next step
211  //but first, figure out which steps we must use missing mass for (and thus must skip on this pass below)
212  set<size_t> locMissingMassSteps;
213  auto locDefinedParticleStepIndices = DAnalysis::Get_DefinedParticleStepIndex(locReaction);
214  for(int locCurrentStepIndex : locDefinedParticleStepIndices)
215  {
216  while(locCurrentStepIndex != -1)
217  {
218  if((locCurrentStepIndex == 0) && locKinFitChain->Get_KinFitChainStep(0)->Get_InitialParticles().empty())
219  break; //is an open-ended decaying particle in the initial state: is ok to define via invariant mass
220  locMissingMassSteps.insert(locCurrentStepIndex);
221  locCurrentStepIndex = locKinFitChain->Get_KinFitChainStep(locCurrentStepIndex)->Get_InitialParticleDecayFromStepIndex();
222  }
223  }
224 
225  auto locIsVertexFit = (locKinFitType != d_P4Fit);
226 
227  //now create decaying particles
228  //do the invariant mass loop
229  set<size_t> locProcessedSteps;
230  for(int loc_i = locParticleCombo->Get_NumParticleComboSteps() - 1; loc_i >= 0; --loc_i)
231  {
232  //get steps
233  auto locReactionStep = locReaction->Get_ReactionStep(loc_i);
234  auto locKinFitChainStep = std::const_pointer_cast<DKinFitChainStep>(locKinFitChain->Get_KinFitChainStep(loc_i));
235 
236  //skip steps that must defined via missing mass
237  if(locMissingMassSteps.find(loc_i) != locMissingMassSteps.end())
238  continue; //decay products contain a missing or open-ended-decaying particle
239 
240  //check if initial particle already created for this step (i.e. beam)
241  if(locKinFitChainStep->Get_InitialParticle(0) != nullptr)
242  continue; //only do decaying particles
243 
244  //mark the progress
245  locProcessedSteps.insert(loc_i);
246 
247  //don't create particle for omega, etc. (will confuse kinfitter)
248  auto locPID = locReactionStep->Get_InitialPID();
249  if(!IsFixedMass(locPID))
250  continue;
251 
252  if(locIsVertexFit)
253  {
254  //decaying particle MUST be defined by how it is used for finding the vertex (i.e. as in locReactionVertexInfo)
255  //e.g. if Xi0 -> pi0, Lambda, and Xi0 defined BY Lambda (instead of missing mass), then the Xi0 constraints on the Xi0 decay vertex would depend on the lambda constraints: matrix determinant = 0, uninvertable
256  auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(loc_i);
257  auto locDecayParticlePair = std::make_pair(loc_i, DReactionStep::Get_ParticleIndex_Initial());
258  auto locDecayingFullConstrainParticles = locStepVertexInfo->Get_DecayingParticles_FullConstrain(true);
259  if(locDecayingFullConstrainParticles.find(locDecayParticlePair) != locDecayingFullConstrainParticles.end())
260  continue; //must define particle by missing mass instead to be consistent with vertex fit
261  }
262 
263  //since going in reverse order, all decay products are ready: create the decaying particle
264  auto locDecaySourceParticles = Get_StepParticles_NonNull(locKinFitChain, locReaction, loc_i, DReactionStep::Get_ParticleIndex_Initial());
265  auto locDecayingParticle = Make_DecayingParticle(locPID, locDecaySourceParticles.first, locDecaySourceParticles.second);
266 
267  //set decaying particle in the chain
268  locKinFitChainStep->Set_InitialParticle(locDecayingParticle, 0);
269  auto locFromIndices = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, loc_i);
270  if((locFromIndices.first < 0) || (locFromIndices.first == loc_i))
271  continue; //intial-state open-ended decaying particle
272 
273  auto locProductionStep = std::const_pointer_cast<DKinFitChainStep>(locKinFitChain->Get_KinFitChainStep(locFromIndices.first));
274  locProductionStep->Set_FinalParticle(locDecayingParticle, locFromIndices.second);
275  locKinFitChain->Set_DecayStepIndex(locDecayingParticle, loc_i);
276  }
277 
278  //now loop from the front, using missing mass for the rest
279  for(size_t loc_i = 0; loc_i < locParticleCombo->Get_NumParticleComboSteps(); ++loc_i)
280  {
281  auto locParticleComboStep = locParticleCombo->Get_ParticleComboStep(loc_i);
282  if(locProcessedSteps.find(loc_i) != locProcessedSteps.end())
283  continue;
284 
285  auto locReactionStep = locReaction->Get_ReactionStep(loc_i);
286  auto locKinFitChainStep = std::const_pointer_cast<DKinFitChainStep>(locKinFitChain->Get_KinFitChainStep(loc_i));
287 
288  //create decaying particle in final state: first figure out which one needs a particle
289  for(size_t loc_j = 0; loc_j < locParticleComboStep->Get_NumFinalParticles(); ++loc_j)
290  {
291  //DecayStepIndex: >= 0 if decaying, where the # is the step representing the particle decay
292  int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j);
293  if(locDecayStepIndex < 0)
294  continue; //not decaying
295 
296  if(locKinFitChain->Get_KinFitChainStep(locDecayStepIndex)->Get_InitialParticle(0) != nullptr)
297  continue; //decaying particle already created
298 
299  //don't create particle for omega, etc. (will confuse kinfitter)
300  auto locPID = locReactionStep->Get_FinalPID(loc_j);
301  if(!IsFixedMass(locPID))
302  continue;
303 
304  //make decaying particle
305  auto locDecaySourceParticles = Get_StepParticles_NonNull(locKinFitChain, locReaction, loc_i, loc_j);
306  auto locDecayingParticle = Make_DecayingParticle(locPID, locDecaySourceParticles.first, locDecaySourceParticles.second);
307  locKinFitChainStep->Set_FinalParticle(locDecayingParticle, loc_j);
308 
309  auto locDecayStep = std::const_pointer_cast<DKinFitChainStep>(locKinFitChain->Get_KinFitChainStep(locDecayStepIndex));
310  locDecayStep->Set_InitialParticle(locDecayingParticle, 0);
311  locKinFitChain->Set_DecayStepIndex(locDecayingParticle, locDecayStepIndex);
312  }
313  }
314 
315  if(dDebugLevel > 10)
316  {
317  cout << "DKinFitUtils_GlueX: DKinFitChain Created. Printing:" << endl;
318  locKinFitChain->Print_InfoToScreen();
319  }
320 
321  return locKinFitChain;
322 }
323 
324 pair<set<shared_ptr<DKinFitParticle>>, set<shared_ptr<DKinFitParticle>>> DKinFitUtils_GlueX::Get_StepParticles_NonNull(const shared_ptr<const DKinFitChain>& locKinFitChain, const DReaction* locReaction, size_t locStepIndex, int locNonFixedMassParticleIndex) const
325 {
326  //If one of the final particles is null (decaying non-fixed-mass particle), remove it, AND go to its decay step and get ALL particles (put in init or final state)
327  auto locKinFitStep = locKinFitChain->Get_KinFitChainStep(locStepIndex);
328 
329  //Get Initial particles, erase nulls
330  auto locGrabbedInitialParticles = locKinFitStep->Get_InitialParticles();
331  set<shared_ptr<DKinFitParticle>> locInitialParticles(locGrabbedInitialParticles.begin(), locGrabbedInitialParticles.end());
332  locInitialParticles.erase(nullptr); //remove any null particles
333 
334  //Get Final particles, erase nulls
335  auto locGrabbedFinalParticles = locKinFitStep->Get_FinalParticles();
336  set<shared_ptr<DKinFitParticle>> locFinalParticles(locGrabbedFinalParticles.begin(), locGrabbedFinalParticles.end());
337  locFinalParticles.erase(nullptr); //remove any null particles
338 
339  //If nulls in initial state: go to the previous step
340  for(size_t loc_i = 0; loc_i < locGrabbedInitialParticles.size(); ++loc_i)
341  {
342  if((locGrabbedInitialParticles[loc_i] != nullptr) || (locNonFixedMassParticleIndex == DReactionStep::Get_ParticleIndex_Initial()))
343  continue;
344 
345  //null particles in initial state: go to the previous step
346  auto locParticlePair = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locStepIndex);
347  auto locStepParticles = Get_StepParticles_NonNull(locKinFitChain, locReaction, locParticlePair.first, locParticlePair.second);
348  locInitialParticles.insert(locStepParticles.first.begin(), locStepParticles.first.end());
349  locFinalParticles.insert(locStepParticles.second.begin(), locStepParticles.second.end());
350  }
351 
352  //If nulls in final state: go to the next step
353  for(size_t loc_i = 0; loc_i < locGrabbedFinalParticles.size(); ++loc_i)
354  {
355  if((locGrabbedFinalParticles[loc_i] != nullptr) || (locNonFixedMassParticleIndex == int(loc_i)))
356  continue;
357 
358  auto locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locStepIndex, loc_i);
359  auto locStepParticles = Get_StepParticles_NonNull(locKinFitChain, locReaction, locDecayStepIndex, DReactionStep::Get_ParticleIndex_Initial());
360  locInitialParticles.insert(locStepParticles.first.begin(), locStepParticles.first.end());
361  locFinalParticles.insert(locStepParticles.second.begin(), locStepParticles.second.end());
362  }
363 
364  if(dDebugLevel >= 10)
365  {
366  cout << "DKinFitUtils_GlueX::Get_StepParticles_NonNull:" << endl;
367  cout << "reaction, step-index, non-fixed-mass particle index: " << locReaction->Get_ReactionName() << ", " << locStepIndex << ", " << locNonFixedMassParticleIndex << endl;
368  cout << "Chain: " << endl;
369  locKinFitChain->Print_InfoToScreen();
370  cout << "Init-particles:" << endl;
371  for(auto& locParticle : locInitialParticles)
372  cout << locParticle->Get_PID() << ", " << locParticle << endl;
373  cout << "Final-particles:" << endl;
374  for(auto& locParticle : locFinalParticles)
375  cout << locParticle->Get_PID() << ", " << locParticle << endl;
376  }
377  return std::make_pair(locInitialParticles, locFinalParticles);
378 }
379 
380 shared_ptr<DKinFitChainStep> DKinFitUtils_GlueX::Make_KinFitChainStep(const DReactionVertexInfo* locReactionVertexInfo, const DReaction* locReaction, const DParticleCombo* locParticleCombo, DKinFitType locKinFitType, size_t locStepIndex, const shared_ptr<DKinFitChain>& locKinFitChain)
381 {
382  //Start and register new step
383  auto locKinFitChainStep = dResourcePool_KinFitChainStep->Get_SharedResource();
384  locKinFitChainStep->Set_ConstrainDecayingMassFlag(false); //unless changed later
385 
386  //get the steps
387  auto locParticleComboStep = locParticleCombo->Get_ParticleComboStep(locStepIndex);
388  auto locReactionStep = locReaction->Get_ReactionStep(locStepIndex);
389  auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(locStepIndex);
390  int locKinFitStepIndex = locKinFitChain->Get_NumKinFitChainSteps();
391 
392  //if doing a vertex fit, see which neutral particles can be treated as showers
393  bool locSpactimeIsFitFlag = ((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit));
394  bool locVertexIsFitFlag = (locSpactimeIsFitFlag || (locKinFitType == d_VertexFit) || (locKinFitType == d_P4AndVertexFit));
395 
396  //initial beam particle
397  locKinFitChainStep->Set_InitialParticleDecayFromStepIndex(-1); //unless set otherwise below (enclosed decaying particle)
398  auto locBeamPhoton = dynamic_cast<const DBeamPhoton*>(locParticleComboStep->Get_InitialParticle_Measured());
399  if(locBeamPhoton != NULL)
400  locKinFitChainStep->Add_InitialParticle(Make_BeamParticle(locBeamPhoton));
401  else //decaying particle
402  {
403  locKinFitChainStep->Add_InitialParticle(nullptr); //will change later
404  if(locStepIndex == 0) //open-ended
405  locKinFitChain->Set_DefinedParticleStepIndex(locKinFitStepIndex);
406  else //enclosed
407  {
408  int locDecayFromStepIndex = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locStepIndex).first;
409  locKinFitChainStep->Set_InitialParticleDecayFromStepIndex(locDecayFromStepIndex);
410  auto locPID = locReactionStep->Get_InitialPID();
411  auto locConstrainMassFlag = IsFixedMass(locPID) ? locReactionStep->Get_KinFitConstrainInitMassFlag() : false;
412  locKinFitChainStep->Set_ConstrainDecayingMassFlag(locConstrainMassFlag);
413  }
414  //will create decaying particle later
415  }
416 
417  //target particle
418  Particle_t locTargetPID = locReactionStep->Get_TargetPID();
419  if(locTargetPID != Unknown)
420  {
421  size_t locTargetInstance = 0;
422  for(size_t loc_i = 0; loc_i < locStepIndex; ++loc_i)
423  {
424  auto locPreviousStep = locKinFitChain->Get_KinFitChainStep(loc_i);
425  auto locInitialParticles = locPreviousStep->Get_InitialParticles();
426  for(auto& loKinFitParticle : locInitialParticles)
427  {
428  if(loKinFitParticle == nullptr)
429  continue;
430  if(loKinFitParticle->Get_KinFitParticleType() == d_TargetParticle)
431  ++locTargetInstance;
432  }
433  }
434  locKinFitChainStep->Add_InitialParticle(Make_TargetParticle(locTargetPID, locTargetInstance));
435  }
436 
437  //final state particles
438  for(size_t loc_j = 0; loc_j < locParticleComboStep->Get_NumFinalParticles(); ++loc_j)
439  {
440  int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locStepIndex, loc_j);
441  auto locKinematicData = locParticleComboStep->Get_FinalParticle_Measured(loc_j);
442  Particle_t locPID = locReactionStep->Get_FinalPID(loc_j);
443 
444  if(locReactionStep->Get_MissingParticleIndex() == int(loc_j)) //missing particle
445  {
446  locKinFitChain->Set_DefinedParticleStepIndex(locKinFitStepIndex);
447  locKinFitChainStep->Add_FinalParticle(Make_MissingParticle(locPID));
448  }
449  else if(locDecayStepIndex >= 0) //decaying particle
450  locKinFitChainStep->Add_FinalParticle(nullptr); //skip for now, will create later (unless not fixed mass)
451  else if(ParticleCharge(locPID) == 0) //detected neutral
452  {
453  auto locNeutralParticleHypothesis = static_cast<const DNeutralParticleHypothesis*>(locKinematicData);
454 
455  //Determine whether we should use the particle or the shower object
456  bool locNeutralShowerFlag = locVertexIsFitFlag && locStepVertexInfo->Get_FittableVertexFlag();
457  if((ParticleMass(locPID) > 0.0) && !locSpactimeIsFitFlag)
458  locNeutralShowerFlag = false; //massive shower momentum is defined by t, which isn't fit: use particle
459 
460  if(!locNeutralShowerFlag)
461  locKinFitChainStep->Add_FinalParticle(Make_DetectedParticle(locNeutralParticleHypothesis));
462  else //in a vertex constraint: make shower
463  {
464  auto locNeutralShower = locNeutralParticleHypothesis->Get_NeutralShower();
465  locKinFitChainStep->Add_FinalParticle(Make_DetectedShower(locNeutralShower, locNeutralParticleHypothesis->PID()));
466  }
467  }
468  else //detected charged track
469  {
470  auto locChargedTrackHypothesis = static_cast<const DChargedTrackHypothesis*>(locKinematicData);
471  locKinFitChainStep->Add_FinalParticle(Make_DetectedParticle(locChargedTrackHypothesis));
472  }
473  }
474 
475  //Inclusive?
476  if(locReactionStep->Get_MissingParticleIndex() == DReactionStep::Get_ParticleIndex_Inclusive())
477  locKinFitChain->Set_IsInclusiveChannelFlag(true);
478 
479  return locKinFitChainStep;
480 }
481 
482 /**************************************************************** MAKE CONSTRAINTS *****************************************************************/
483 
484 set<shared_ptr<DKinFitConstraint>> DKinFitUtils_GlueX::Create_Constraints(const DReactionVertexInfo* locReactionVertexInfo, const DReaction* locReaction, const DParticleCombo* locParticleCombo, const shared_ptr<const DKinFitChain>& locKinFitChain, DKinFitType locKinFitType, vector<shared_ptr<DKinFitConstraint_Vertex>>& locSortedVertexConstraints)
485 {
486  if(dDebugLevel > 10)
487  cout << "DKinFitUtils_GlueX: Create constraints." << endl;
488 
489  //All constraints
490  set<shared_ptr<DKinFitConstraint>> locAllConstraints;
491 
492  //Create Mass Constraints
493  set<shared_ptr<DKinFitConstraint_Mass>> locMassConstraints;
494  map<shared_ptr<DKinFitParticle>, shared_ptr<DKinFitConstraint_Mass>> locParticleMassConstraintMap;
495  map<shared_ptr<DKinFitParticle>, size_t> locParticleDecayStepMap; //key is decaying particle, value is step index
496  map<size_t, shared_ptr<DKinFitConstraint_Mass>> locStepMassConstraintMap;
497  int locP4StepIndex = 0; //will use to define p4 constraint step, if requested
498  if((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
499  {
500  //loop over steps, but skip init step (if open-ended decaying, do p4 constraint instead)
501  for(size_t loc_i = 1; loc_i < locKinFitChain->Get_NumKinFitChainSteps(); ++loc_i)
502  {
503  auto locKinFitChainStep = locKinFitChain->Get_KinFitChainStep(loc_i);
504  if(!locKinFitChainStep->Get_ConstrainDecayingMassFlag())
505  continue; //don't apply mass constraint to this step
506 
507  for(auto locKinFitParticle : locKinFitChainStep->Get_InitialParticles())
508  {
509  if(locKinFitParticle == nullptr)
510  continue;
511  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
512  continue; //not a decaying particle
513 
514  //if this decay is defined by missing mass, the p4-constrain step CANNOT precede this decay: over-constrained system
515  if(!Get_IsDecayingParticleDefinedByProducts(locKinFitParticle.get()))
516  locP4StepIndex = loc_i; //this can (and must!) be overwritten by further steps if needed (if decay chain continually defined this way)
517 
518  auto locMassConstraint = Make_MassConstraint(locKinFitParticle);
519  locMassConstraints.insert(locMassConstraint);
520  locParticleMassConstraintMap[locKinFitParticle] = locMassConstraint;
521  locParticleDecayStepMap[locKinFitParticle] = loc_i;
522  locStepMassConstraintMap[loc_i] = locMassConstraint;
523  }
524  }
525  }
526 
527  //Create P4 Constraint
528  //don't do if inclusive reaction, or more than one missing particle
529  //pick the step containing the defined (missing or open-ended-decaying) particle
530  //if no defined particle, use the first step
531  shared_ptr<DKinFitConstraint_P4> locP4Constraint = nullptr;
532  auto locDefinedParticleStepIndices = DAnalysis::Get_DefinedParticleStepIndex(locReaction);
533  if(!locKinFitChain->Get_IsInclusiveChannelFlag() && (locDefinedParticleStepIndices.size() <= 1) && ((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit)))
534  {
535  if(!locDefinedParticleStepIndices.empty()) //there is a missing or open-ended decaying particle
536  locP4StepIndex = locDefinedParticleStepIndices.front(); //use it as the p4 constraint step instead
537  auto locStepParticles = Get_StepParticles_NonNull(locKinFitChain, locReaction, locP4StepIndex);
538  locP4Constraint = Make_P4Constraint(locStepParticles.first, locStepParticles.second);
539 
540  //OK, now, check to see if the system is overly constrained:
541  //there must be at least one particle with non-zero errors in the p4 constraint that is NOT in ANY mass constraint
542  bool locNonZeroErrorFlag = false;
543  auto locAllParticles = locP4Constraint->Get_AllParticles();
544  set<size_t> locP4ConstrainedParticleSteps;
545  for(auto& locKinFitParticle : locAllParticles)
546  {
547  DKinFitParticleType locKinFitParticleType = locKinFitParticle->Get_KinFitParticleType();
548 
549  //check if decaying particle mass is not constrained
550  if(locKinFitParticleType == d_DecayingParticle)
551  {
552  if(locParticleMassConstraintMap.find(locKinFitParticle) == locParticleMassConstraintMap.end())
553  {
554  locNonZeroErrorFlag = true; //not constrained: we are OK
555  break;
556  }
557  locP4ConstrainedParticleSteps.insert(locParticleDecayStepMap[locKinFitParticle]);
558  continue;
559  }
560 
561  if(locKinFitParticle->Get_CovarianceMatrix() == NULL)
562  continue;
563  if((locKinFitParticleType == d_BeamParticle) && !dWillBeamHaveErrorsFlag)
564  continue;
565 
566  locNonZeroErrorFlag = true; //this particle has non-zero errors: we are OK
567  break;
568  }
569 
570  if(!locNonZeroErrorFlag)
571  {
572  //system is over-constrained: we must delete a constraint
573  //prefer to delete a mass constraint: it is only 1 degree of freedom, whereas p4 constraint can be 4
574 
575  //remove a mass constraint: delete the one in the earliest step (so consistent)
576  size_t locEarliestStepIndex = *locP4ConstrainedParticleSteps.begin();
577  locMassConstraints.erase(locStepMassConstraintMap[locEarliestStepIndex]); //remove constraint
578  }
579 
580  //set init p3 guess
581  if(locP4Constraint->Get_DefinedParticle() != NULL)
582  {
583  DLorentzVector locDefinedP4;
584  if(locP4Constraint->Get_IsDefinedParticleInFinalState())
585  locDefinedP4 = dAnalysisUtilities->Calc_MissingP4(locReaction, locParticleCombo, false);
586  else
587  locDefinedP4 = dAnalysisUtilities->Calc_FinalStateP4(locReaction, locParticleCombo, 0, false);
588  TVector3 locInitP3Guess(locDefinedP4.Px(), locDefinedP4.Py(), locDefinedP4.Pz());
589  locP4Constraint->Set_InitP3Guess(locInitP3Guess);
590  }
591  else
592  locP4Constraint->Set_InitP3Guess(TVector3(0.0, 0.0, 0.0));
593  }
594 
595  //Set P4 & Mass constraints
596  if(locP4Constraint != NULL)
597  locAllConstraints.insert(locP4Constraint);
598  locAllConstraints.insert(locMassConstraints.begin(), locMassConstraints.end());
599 
600  //Create Vertex Constraints
601  //VERTEX OR SPACETIME: Group particles by detached vertex (one deque for each constraint/vertex)
602  locSortedVertexConstraints.clear();
603  if((locKinFitType == d_VertexFit) || (locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
604  {
605  bool locSpacetimeFitFlag = ((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit));
606  for(auto& locStepVertexInfo : locReactionVertexInfo->Get_StepVertexInfos())
607  {
608  if(!locStepVertexInfo->Get_FittableVertexFlag())
609  continue;
610  auto locDX4 = locParticleCombo->Get_ParticleComboStep(locStepVertexInfo->Get_StepIndices().front())->Get_SpacetimeVertex();
611  TLorentzVector locX4(locDX4.X(), locDX4.Y(), locDX4.Z(), locDX4.T());
612 
613  auto locFullConstrainParticles = Build_ParticleSet(locStepVertexInfo->Get_FullConstrainParticles(true), locKinFitChain);
614  auto locNoConstrainParticles = Build_ParticleSet(locStepVertexInfo->Get_NoConstrainParticles(true), locKinFitChain);
615  auto locOnlyConstrainTimeParticles = Build_ParticleSet(locStepVertexInfo->Get_OnlyConstrainTimeParticles(), locKinFitChain);
616  if(locSpacetimeFitFlag)
617  locSortedVertexConstraints.push_back(Make_SpacetimeConstraint(locFullConstrainParticles, locOnlyConstrainTimeParticles, locNoConstrainParticles, locX4));
618  else
619  {
620  locNoConstrainParticles.insert(locOnlyConstrainTimeParticles.begin(), locOnlyConstrainTimeParticles.end());
621  locSortedVertexConstraints.push_back(Make_VertexConstraint(locFullConstrainParticles, locNoConstrainParticles, locX4.Vect()));
622  }
623  }
624  }
625  locAllConstraints.insert(locSortedVertexConstraints.begin(), locSortedVertexConstraints.end());
626 
627  if(dDebugLevel > 10)
628  cout << "DKinFitUtils_GlueX: All Constraints Created." << endl;
629 
630  return locAllConstraints;
631 }
632 
633 set<shared_ptr<DKinFitParticle>> DKinFitUtils_GlueX::Build_ParticleSet(const vector<pair<int, int>>& locParticleIndices, const shared_ptr<const DKinFitChain>& locKinFitChain)
634 {
635  set<shared_ptr<DKinFitParticle>> locParticles;
636  for(auto& locParticlePair : locParticleIndices)
637  {
638  auto locStep = locKinFitChain->Get_KinFitChainStep(locParticlePair.first);
639  if(locParticlePair.second >= 0)
640  {
641  if(locStep->Get_FinalParticle(locParticlePair.second) != nullptr)
642  locParticles.insert(locStep->Get_FinalParticle(locParticlePair.second));
643  }
644  else if(locParticlePair.second == DReactionStep::Get_ParticleIndex_Initial())
645  {
646  if(locStep->Get_InitialParticle(0) != nullptr)
647  locParticles.insert(locStep->Get_InitialParticle(0));
648  }
649  else
650  locParticles.insert(locStep->Get_InitialParticle(1));
651  }
652  return locParticles;
653 }
654 
655 /************************************************************** CONSTRAINT PREDICTORS **************************************************************/
656 
657 string DKinFitUtils_GlueX::Get_ConstraintInfo(const DReactionVertexInfo* locReactionVertexInfo, const DReaction* locReaction, size_t& locNumConstraints, size_t& locNumUnknowns) const
658 {
659  //returns constraint string, sets # constraints & unknowns
660  //ASSUMES: Detected particles have non-zero errors!
661  string locAllConstraintsString;
662  locNumConstraints = 0;
663  locNumUnknowns = 0;
664 
665  //P4 & Mass Constraints
666  DKinFitType locKinFitType = locReaction->Get_KinFitType();
667  auto locIsVertexFit = ((locKinFitType != d_NoFit) && (locKinFitType != d_P4Fit));
668  if((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
669  {
670  //Mass Constraints
671  //loop over steps, but skip init step (if open-ended decaying, do p4 constraint instead)
672  map<size_t, string> locMassConstraintStrings;
673  int locP4StepIndex = 0; //may be changed below
674  for(size_t loc_i = 1; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
675  {
676  const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(loc_i);
677  if(!locReactionStep->Get_KinFitConstrainInitMassFlag())
678  continue; //don't apply mass constraint to this step
679 
680  Particle_t locPID = locReactionStep->Get_InitialPID();
681  if(!IsFixedMass(locPID))
682  continue; //don't apply mass constraint to this step
683 
684  if(locIsVertexFit)
685  {
686  //decaying particle MUST be defined by how it is used for finding the vertex (i.e. as in locReactionVertexInfo)
687  //e.g. if Xi0 -> pi0, Lambda, and Xi0 defined BY Lambda (instead of missing mass), then the Xi0 constraints on the Xi0 decay vertex would depend on the lambda constraints: matrix determinant = 0, uninvertable
688  auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(loc_i);
689  auto locDecayParticlePair = std::make_pair(loc_i, DReactionStep::Get_ParticleIndex_Initial());
690  auto locDecayingFullConstrainParticles = locStepVertexInfo->Get_DecayingParticles_FullConstrain(true);
691 
692  //if following is true: must define particle by missing mass instead to be consistent with vertex fit
693  //if true: because this decay is defined by missing mass, the p4-constrain step CANNOT precede this decay: over-constrained system
694  if(locDecayingFullConstrainParticles.find(locDecayParticlePair) != locDecayingFullConstrainParticles.end())
695  locP4StepIndex = loc_i; //this can (and must!) be overwritten by further steps if needed (if decay chain continually defined this way)
696  }
697 
698  locMassConstraintStrings[loc_i] = string("#it{m}_{") + string(ParticleName_ROOT(locPID)) + string("}");
699  }
700 
701  //P4 Constraint //don't do if inclusive reaction, or more than 1 missing particle
702  auto locDefinedParticleStepIndices = DAnalysis::Get_DefinedParticleStepIndex(locReaction);
703  if(!locReaction->Get_IsInclusiveFlag() && (locDefinedParticleStepIndices.size() <= 1))
704  {
705  if(!locDefinedParticleStepIndices.empty())
706  locP4StepIndex = locDefinedParticleStepIndices.front();
707  //OK, now, check to see if the system is overly constrained:
708  //there must be at least one particle with non-zero errors in the p4 constraint that is NOT in a mass constraint
709  bool locNonZeroErrorFlag = false;
710 
711  //Find step used for p4 constraint: the one with missing/open-ended-decaying particle (if any: else first step)
712  const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(locP4StepIndex);
713 
714  set<size_t> locP4ConstrainedParticleSteps;
715 
716  //check if initial & final states if have non-zero cov errors:
717  if((locP4StepIndex == 0) && (locReactionStep->Get_TargetPID() != Unknown) && dWillBeamHaveErrorsFlag)
718  locNonZeroErrorFlag = true; //beam: we're good
719  else if((locP4StepIndex != 0) && (locMassConstraintStrings.find(locP4StepIndex) == locMassConstraintStrings.end()))
720  locNonZeroErrorFlag = true; //decaying particle, but mass not constrained: we're good (unless it's e.g. an omega. ugh.)
721  else //check final state
722  {
723  //check if final state has non-zero cov errors (detected):
724  for(size_t loc_i = 0; loc_i < locReactionStep->Get_NumFinalPIDs(); ++loc_i)
725  {
726  if(locReactionStep->Get_MissingParticleIndex() == int(loc_i))
727  continue; //missing
728 
729  int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locP4StepIndex, loc_i);
730  if(locDecayStepIndex > 0) //decaying
731  {
732  if(locMassConstraintStrings.find(locDecayStepIndex) != locMassConstraintStrings.end())
733  {
734  locP4ConstrainedParticleSteps.insert(locDecayStepIndex);
735  continue; //mass constrained
736  }
737  }
738 
739  locNonZeroErrorFlag = true;
740  break; //either detected particle, or unconstrained decaying particle: we're good (unless it's e.g. an omega. ugh.)
741  }
742  }
743 
744  if(!locNonZeroErrorFlag)
745  {
746  //system is over-constrained: we must delete a constraint
747  //prefer to delete a mass constraint: it is only 1 degree of freedom, whereas p4 constraint can be 4
748 
749  //if initial particle is constrained, remove the constraint on that one
750  if((locP4StepIndex != 0) && (locMassConstraintStrings.find(locP4StepIndex) != locMassConstraintStrings.end()))
751  locMassConstraintStrings.erase(locP4StepIndex); //remove constraint
752  else //else delete the one in the earliest step (so consistent)
753  {
754  size_t locEarliestStepIndex = *locP4ConstrainedParticleSteps.begin();
755  locMassConstraintStrings.erase(locEarliestStepIndex); //remove constraint
756  }
757  }
758 
759  //Finally, add p4 constraint
760  locAllConstraintsString = "#it{p}^{4}";
761  locNumConstraints += 4;
762  if(!locDefinedParticleStepIndices.empty())
763  locNumUnknowns += 3;
764  }
765 
766  //Finally, add remaining mass constraints
767  locNumConstraints += locMassConstraintStrings.size();
768  map<size_t, string>::iterator locStringIterator = locMassConstraintStrings.begin();
769  for(; locStringIterator != locMassConstraintStrings.end(); ++locStringIterator)
770  {
771  if(locAllConstraintsString != "")
772  locAllConstraintsString += ", ";
773  locAllConstraintsString += locStringIterator->second;
774  }
775  }
776 
777  //Create Vertex Constraints
778  //VERTEX OR SPACETIME: Group particles by detached vertex (one deque for each constraint/vertex)
779  if((locKinFitType == d_VertexFit) || (locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
780  {
781  bool locSpacetimeFitFlag = ((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit));
782  auto locConstraintTuple = Predict_VertexConstraints(locReactionVertexInfo, locSpacetimeFitFlag);
783  if(std::get<0>(locConstraintTuple) > 0)
784  {
785  locNumConstraints += std::get<0>(locConstraintTuple);
786  locNumUnknowns += std::get<1>(locConstraintTuple);
787  if(locAllConstraintsString != "")
788  locAllConstraintsString += ", ";
789  locAllConstraintsString += std::get<2>(locConstraintTuple);
790  }
791  }
792 
793  return locAllConstraintsString;
794 }
795 
796 tuple<size_t, size_t, string> DKinFitUtils_GlueX::Predict_VertexConstraints(const DReactionVertexInfo* locReactionVertexInfo, bool locSpacetimeFitFlag) const
797 {
798  //returned: #constraints, constraint string
799  size_t locNumConstraints = 0, locNumUnknowns = 0;
800  string locAllConstraintString;
801  auto locStepVertexInfos = locReactionVertexInfo->Get_StepVertexInfos();
802  for(auto& locVertexInfo : locStepVertexInfos)
803  {
804  if(!locVertexInfo->Get_FittableVertexFlag())
805  continue;
806 
807  auto locFullConstrainParticles = locVertexInfo->Get_FullConstrainParticles(true);
808  if(locSpacetimeFitFlag)
809  {
810  locNumConstraints += 3*locFullConstrainParticles.size();
811  locNumConstraints += locVertexInfo->Get_OnlyConstrainTimeParticles().size();
812  locNumUnknowns += 4;
813  }
814  else //vertex only
815  {
816  locNumConstraints += 2*locFullConstrainParticles.size();
817  locNumUnknowns += 3;
818  }
819 
820  //add to the full constraint string
821  if(locAllConstraintString != "")
822  locAllConstraintString += ", ";
823  locAllConstraintString += Build_VertexConstraintString(locVertexInfo, locSpacetimeFitFlag);
824  }
825 
826  return std::make_tuple(locNumConstraints, locNumUnknowns, locAllConstraintString);
827 }
828 
829 string DKinFitUtils_GlueX::Build_VertexConstraintString(const DReactionStepVertexInfo* locVertexInfo, bool locSpacetimeFitFlag) const
830 {
831  auto locReaction = locVertexInfo->Get_Reaction();
832  string locConstraintString = locSpacetimeFitFlag ? "#it{x}^{4}_{" : "#it{x}^{3}_{";
833 
834  //if a decaying particle decays in-place at this vertex, we don't want to put it into the string
835  //this will happen if: the vertex-info represents more than one step
836  //they will be present in the info as non-constrain particles in the final-state
837  auto locStepIndices = locVertexInfo->Get_StepIndices(); //steps are listed in order
838  set<pair<int, int>> locExcludeDecayParticleIndices; //these are final-state indices
839  for(size_t loc_i = 1; loc_i < locStepIndices.size(); ++loc_i)
840  locExcludeDecayParticleIndices.insert(DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locStepIndices[loc_i]));
841 
842  //initial state
843  auto locParticles = locVertexInfo->Get_Particles(d_InitialState);
844  auto locFullConstrainParticles = locVertexInfo->Get_FullConstrainParticles(true, d_InitialState);
845  for(auto locIndices : locParticles)
846  {
847  auto locStep = locReaction->Get_ReactionStep(locIndices.first);
848  Particle_t locPID = locStep->Get_PID(locIndices.second);
849  string locParticleString = ParticleName_ROOT(locPID);
850  if(locIndices.second == locStep->Get_MissingParticleIndex())
851  locConstraintString += string("(") + locParticleString + string(")"); //missing
852  else if(std::binary_search(locFullConstrainParticles.begin(), locFullConstrainParticles.end(), locIndices)) //constraining
853  locConstraintString += string("#color[4]{") + locParticleString + string("}"); //blue
854  else //no-constrain
855  locConstraintString += locParticleString; //plain
856  }
857 
858  //final state
859  locConstraintString += "#rightarrow";
860  locParticles = locVertexInfo->Get_Particles(d_FinalState);
861  locFullConstrainParticles = locVertexInfo->Get_FullConstrainParticles(true, d_FinalState);
862  auto locOnlyConstrainTimeParticles = locVertexInfo->Get_OnlyConstrainTimeParticles();
863  for(auto locIndices : locParticles)
864  {
865  if(locExcludeDecayParticleIndices.find(locIndices) != locExcludeDecayParticleIndices.end())
866  continue; //exclude no-constrain decaying particle
867 
868  auto locStep = locReaction->Get_ReactionStep(locIndices.first);
869  Particle_t locPID = locStep->Get_PID(locIndices.second);
870  string locParticleString = ParticleName_ROOT(locPID);
871 
872  if(locIndices.second == locStep->Get_MissingParticleIndex())
873  locConstraintString += string("(") + locParticleString + string(")"); //missing
874  else if(std::binary_search(locFullConstrainParticles.begin(), locFullConstrainParticles.end(), locIndices)) //constraining
875  locConstraintString += string("#color[4]{") + locParticleString + string("}"); //blue
876  else if(locSpacetimeFitFlag && std::binary_search(locOnlyConstrainTimeParticles.begin(), locOnlyConstrainTimeParticles.end(), locIndices)) //time-only
877  locConstraintString += string("#color[3]{") + locParticleString + string("}"); //green
878  else //no-constrain
879  locConstraintString += locParticleString; //plain
880  }
881 
882  locConstraintString += string("}"); //end of constraint
883 
884  return locConstraintString;
885 }
886 
887 /*************************************************************** CALCULATION ROUTINES **************************************************************/
888 
889 bool DKinFitUtils_GlueX::Propagate_TrackInfoToCommonVertex(DKinematicData* locKinematicData, DKinFitParticle* locKinFitParticle, const TMatrixDSym* locVXi)
890 {
891  //locKinematicData must be generated from locKinFitParticle
892  //this function should only be used on decaying particles involved in two vertex fits:
893  //propagates the track information from the vertex at which it is DEFINED to the OTHER vertex (e.g. production -> decay)
894 
895  TVector3 locMomentum;
896  TLorentzVector locSpacetimeVertex;
897  pair<double, double> locPathLengthPair, locRestFrameLifetimePair;
898  TMatrixFSym locTempCovarianceMatrix(11);
899  if(!DKinFitUtils::Propagate_TrackInfoToCommonVertex(locKinFitParticle, locVXi, locMomentum, locSpacetimeVertex, locPathLengthPair, locRestFrameLifetimePair, &locTempCovarianceMatrix))
900  return false;
901 
902  //Convert 10x10 to 7x7
903  auto locCovarianceMatrix = Get_SymMatrixResource(7);
904  *locCovarianceMatrix = locTempCovarianceMatrix.GetSub(0, 6, *locCovarianceMatrix);
905 
906  locKinematicData->setMomentum(DVector3(locMomentum.X(),locMomentum.Y(),locMomentum.Z()));
907  locKinematicData->setPosition(DVector3(locSpacetimeVertex.Vect().X(),locSpacetimeVertex.Vect().Y(),locSpacetimeVertex.Vect().Z()));
908  locKinematicData->setTime(locSpacetimeVertex.T());
909  locKinematicData->setErrorMatrix(locCovarianceMatrix);
910  return true;
911 }
912 
vector< pair< int, int > > Get_FullConstrainParticles(bool locFitFlag, DReactionState_t locState=d_EitherState, Charge_t locCharge=d_AllCharges, bool locIncludeDecayingFlag=true) const
void setMomentum(const DVector3 &aMomentum)
TVector3 Get_BField(const TVector3 &locPosition) const
shared_ptr< DKinFitConstraint_Vertex > Make_VertexConstraint(const set< shared_ptr< DKinFitParticle >> &locFullConstrainParticles, const set< shared_ptr< DKinFitParticle >> &locNoConstrainParticles, TVector3 locVertexGuess=TVector3())
void setTime(double locTime)
static char * ParticleName_ROOT(Particle_t p)
Definition: particleType.h:851
bool Get_IncludeBeamlineInVertexFitFlag(void) const
pair< int, int > Get_InitialParticleDecayFromIndices(const DReaction *locReaction, int locStepIndex)
Definition: DReaction.cc:93
const DAnalysisUtilities * dAnalysisUtilities
vector< size_t > Get_DefinedParticleStepIndex(const DReaction *locReaction)
Definition: DReaction.cc:192
size_t Get_NumParticleComboSteps(void) const
DKinFitType Get_KinFitType(void) const
Definition: DReaction.h:79
string Build_VertexConstraintString(const DReactionStepVertexInfo *locVertexInfo, bool locSpacetimeFitFlag) const
shared_ptr< DKinFitParticle > Make_BeamParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
Definition: DKinFitUtils.cc:56
TVector3 DVector3
Definition: DVector3.h:14
bool Get_KinFitConstrainInitMassFlag(void) const
Definition: DReactionStep.h:97
shared_ptr< DKinFitParticle > Make_DetectedShower(const DNeutralShower *locNeutralShower, Particle_t locPID)
set< shared_ptr< DKinFitParticle > > Build_ParticleSet(const vector< pair< int, int >> &locParticleIndices, const shared_ptr< const DKinFitChain > &locKinFitChain)
map< pair< const DBeamPhoton *, const DEventRFBunch * >, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_Beam
const DReactionStepVertexInfo * Get_StepVertexInfo(size_t locStepIndex) const
char string[256]
map< Particle_t, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_Missing
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
shared_ptr< DKinFitParticle > Make_DetectedParticle(int locPID, int locCharge, double locMass, TLorentzVector locSpacetimeVertex, TVector3 locMomentum, double locPathLength, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
DKinFitParticleType
const DVector3 & position(void) const
TLorentzVector Make_TLorentzVector(DLorentzVector locDLorentzVector) const
Particle_t Get_TargetPID(void) const
Definition: DReactionStep.h:83
shared_ptr< DKinFitParticle > Make_DetectedShower(int locPID, double locMass, TLorentzVector locSpacetimeVertex, double locShowerEnergy, const shared_ptr< const TMatrixFSym > &locCovarianceMatrix)
shared_ptr< DKinFitParticle > Make_DetectedParticle(const DKinematicData *locKinematicData)
bool Propagate_TrackInfoToCommonVertex(DKinematicData *locKinematicData, DKinFitParticle *locKinFitParticle, const TMatrixDSym *locVXi)
TLorentzVector DLorentzVector
double Get_PathLength(void) const
static int ParticleCharge(Particle_t p)
const DNeutralShower * Get_NeutralShower(void) const
static int PDGtype(Particle_t p)
shared_ptr< DKinFitParticle > Make_BeamParticle(const DBeamPhoton *locBeamPhoton)
TVector3 Make_TVector3(DVector3 locDVector3) const
JApplication * japp
DLorentzVector dSpacetimeVertex
double time(void) const
shared_ptr< DKinFitParticle > Make_MissingParticle(int locPID, int locCharge, double locMass)
const DReaction * Get_Reaction(void) const
string Get_ConstraintInfo(const DReactionVertexInfo *locReactionVertexInfo, const DReaction *locReaction, size_t &locNumConstraints, size_t &locNumUnknowns) const
DLorentzVector Calc_FinalStateP4(const DReaction *locReaction, const DParticleCombo *locParticleCombo, size_t locStepIndex, bool locUseKinFitDataFlag) const
void setErrorMatrix(const shared_ptr< const TMatrixFSym > &aMatrix)
void Set_FinalParticle(const shared_ptr< DKinFitParticle > &locFinalParticle, size_t locIndex)
virtual void Reset_NewEvent(void)
Definition: DKinFitUtils.cc:37
shared_ptr< DResourcePool< DKinFitChain > > dResourcePool_KinFitChain
Definition: DKinFitUtils.h:145
shared_ptr< DKinFitParticle > Make_TargetParticle(int locPID, int locCharge, double locMass)
Definition: DKinFitUtils.cc:82
Particle_t Get_InitialPID(void) const
Definition: DReactionStep.h:81
shared_ptr< DKinFitConstraint_Mass > Make_MassConstraint(const shared_ptr< DKinFitParticle > &locDecayingParticle)
shared_ptr< TMatrixFSym > Get_SymMatrixResource(unsigned int locNumMatrixRows)
Definition: DKinFitUtils.cc:47
DLorentzVector Calc_MissingP4(const DReaction *locReaction, const DParticleCombo *locParticleCombo, bool locUseKinFitDataFlag) const
string Get_ReactionName(void) const
Definition: DReaction.h:75
map< DDecayingParticleInfo, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_Decaying
DApplication * dApplication
static unsigned short int IsFixedMass(Particle_t p)
Definition: particleType.h:743
shared_ptr< TMatrixFSym > dCovarianceMatrix
map< shared_ptr< DKinFitParticle >, DDecayingParticleInfo > dParticleMap_InputToSource_Decaying
bool Propagate_TrackInfoToCommonVertex(const DKinFitParticle *locKinFitParticle, const TMatrixDSym *locVXi, TVector3 &locMomentum, TLorentzVector &locSpacetimeVertex, pair< double, double > &locPathLengthPair, pair< double, double > &locRestFrameLifetimePair, TMatrixFSym *locCovarianceMatrix) const
shared_ptr< DKinFitParticle > Make_MissingParticle(Particle_t locPID)
shared_ptr< DKinFitParticle > Make_DecayingParticle(Particle_t locPID, const set< shared_ptr< DKinFitParticle >> &locFromInitialState, const set< shared_ptr< DKinFitParticle >> &locFromFinalState)
shared_ptr< DKinFitConstraint_Spacetime > Make_SpacetimeConstraint(const set< shared_ptr< DKinFitParticle >> &locFullConstrainParticles, const set< shared_ptr< DKinFitParticle >> &locOnlyConstrainTimeParticles, const set< shared_ptr< DKinFitParticle >> &locNoConstrainParticles, TLorentzVector locSpacetimeGuess=TLorentzVector())
void Set_InitialParticle(const shared_ptr< DKinFitParticle > &locInitialParticle, size_t locIndex)
bool dLinkVerticesFlag
Definition: DKinFitUtils.h:140
map< pair< const DNeutralShower *, Particle_t >, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_Shower
shared_ptr< DKinFitConstraint_P4 > Make_P4Constraint(const set< shared_ptr< DKinFitParticle >> &locInitialParticles, const set< shared_ptr< DKinFitParticle >> &locFinalParticles)
double dTimeVariance
Definition: DEventRFBunch.h:31
int Get_MissingParticleIndex(void) const
Definition: DReactionStep.h:93
pair< set< shared_ptr< DKinFitParticle > >, set< shared_ptr< DKinFitParticle > > > Get_StepParticles_NonNull(const shared_ptr< const DKinFitChain > &locKinFitChain, const DReaction *locReaction, size_t locStepIndex, int locNonFixedMassParticleIndex=-99) const
shared_ptr< DKinFitParticle > Make_TargetParticle(Particle_t locPID, size_t locInstance=0)
static double ParticleMass(Particle_t p)
vector< const DReactionStepVertexInfo * > Get_StepVertexInfos(void) const
set< shared_ptr< DKinFitConstraint > > Create_Constraints(const DReactionVertexInfo *locReactionVertexInfo, const DReaction *locReaction, const DParticleCombo *locParticleCombo, const shared_ptr< const DKinFitChain > &locKinFitChain, DKinFitType locKinFitType, vector< shared_ptr< DKinFitConstraint_Vertex >> &locSortedVertexConstraints)
tuple< size_t, size_t, string > Predict_VertexConstraints(const DReactionVertexInfo *locReactionVertexInfo, bool locSpacetimeFitFlag) const
bool Get_IsBFieldNearBeamline(void) const
size_t Get_NumFinalPIDs(void) const
Definition: DReactionStep.h:89
const DVector3 & momentum(void) const
vector< pair< int, int > > Get_OnlyConstrainTimeParticles(void) const
map< shared_ptr< DKinFitParticle >, const JObject * > dParticleMap_InputToSource_JObject
map< const DKinematicData *, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_DetectedParticle
bool Get_IsDecayingParticleDefinedByProducts(const DKinFitParticle *locKinFitParticle) const
const DReactionStep * Get_ReactionStep(size_t locStepIndex) const
Definition: DReaction.h:84
const DMagneticFieldMap * dMagneticFieldMap
int Get_DecayStepIndex(const DReaction *locReaction, size_t locStepIndex, size_t locParticleIndex)
Definition: DReaction.cc:135
bool Get_IsInclusiveFlag(void) const
Definition: DReaction.h:157
shared_ptr< const TMatrixFSym > errorMatrix(void) const
const DParticleComboStep * Get_ParticleComboStep(size_t locStepIndex) const
void setPosition(const DVector3 &aPosition)
virtual void GetField(const DVector3 &pos, DVector3 &Bout) const =0
vector< size_t > Get_StepIndices(void) const
size_t Get_NumReactionSteps(void) const
Definition: DReaction.h:83
shared_ptr< DKinFitParticle > Make_DecayingParticle(int locPID, int locCharge, double locMass, const set< shared_ptr< DKinFitParticle >> &locFromInitialState, const set< shared_ptr< DKinFitParticle >> &locFromFinalState)
shared_ptr< DResourcePool< DKinFitChainStep > > dResourcePool_KinFitChainStep
Definition: DKinFitUtils.h:144
shared_ptr< DKinFitChainStep > Make_KinFitChainStep(const DReactionVertexInfo *locReactionVertexInfo, const DReaction *locReaction, const DParticleCombo *locParticleCombo, DKinFitType locKinFitType, size_t locStepIndex, const shared_ptr< DKinFitChain > &locKinFitChain)
Particle_t PID(void) const
vector< pair< int, int > > Get_Particles(DReactionState_t locState=d_EitherState, Charge_t locCharge=d_AllCharges, bool locIncludeDecayingFlag=true, bool locIncludeMissingFlag=true, bool locIncludeTargetFlag=true) const
map< pair< Particle_t, size_t >, shared_ptr< DKinFitParticle > > dParticleMap_SourceToInput_Target
shared_ptr< const DKinFitChain > Make_KinFitChain(const DReactionVertexInfo *locReactionVertexInfo, const DReaction *locReaction, const DParticleCombo *locParticleCombo, DKinFitType locKinFitType)
Particle_t
Definition: particleType.h:12