Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DParticleComboCreator.cc
Go to the documentation of this file.
4 
5 namespace DAnalysis
6 {
7 
8 DParticleComboCreator::DParticleComboCreator(JEventLoop* locEventLoop, const DSourceComboer* locSourceComboer, DSourceComboTimeHandler* locSourceComboTimeHandler, const DSourceComboVertexer* locSourceComboVertexer) :
9  dSourceComboer(locSourceComboer), dSourceComboTimeHandler(locSourceComboTimeHandler), dSourceComboVertexer(locSourceComboVertexer)
10 {
11  gPARMS->SetDefaultParameter("COMBO:DEBUG_LEVEL", dDebugLevel);
12  dKinFitUtils = new DKinFitUtils_GlueX(locEventLoop);
13 
14  //GET THE GEOMETRY
15  DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
16  DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
17 
18  //TARGET INFORMATION
19  double locTargetCenterZ = 65.0;
20  locGeometry->GetTargetZ(locTargetCenterZ);
21  dTargetCenter.SetXYZ(0.0, 0.0, locTargetCenterZ);
22 
23  dResourcePool_KinematicData.Set_ControlParams(20, 20, 200, 1000, 0);
24  dResourcePool_ParticleCombo.Set_ControlParams(100, 20, 1000, 3000, 0);
25  dResourcePool_ParticleComboStep.Set_ControlParams(100, 50, 1500, 4000, 0);
26 
27  vector<const DNeutralParticleHypothesis*> locNeutralParticleHypotheses;
28  locEventLoop->Get(locNeutralParticleHypotheses); //make sure that brun() is called for the default factory!!!
29  dNeutralParticleHypothesisFactory = static_cast<DNeutralParticleHypothesis_factory*>(locEventLoop->GetFactory("DNeutralParticleHypothesis"));
30 
31  vector<const DChargedTrackHypothesis*> locChargedTrackHypotheses;
32  locEventLoop->Get(locChargedTrackHypotheses); //make sure that brun() is called for the default factory!!!
33  dChargedTrackHypothesisFactory = static_cast<DChargedTrackHypothesis_factory*>(locEventLoop->GetFactory("DChargedTrackHypothesis"));
34 
35  vector<const DBeamPhoton*> locBeamPhotons;
36  locEventLoop->Get(locBeamPhotons); //make sure that brun() is called for the default factory!!!
37  dBeamPhotonfactory = static_cast<DBeamPhoton_factory*>(locEventLoop->GetFactory("DBeamPhoton"));
38 
39  locEventLoop->GetSingle(dParticleID);
40 
41  //error matrix //too lazy to compute properly right now ... need to hack DAnalysisUtilities::Calc_DOCA()
42  dVertexCovMatrix.ResizeTo(4, 4);
43  dVertexCovMatrix.Zero();
44  dVertexCovMatrix(0, 0) = 0.65; //x variance //from monitoring plots of vertex
45  dVertexCovMatrix(1, 1) = 0.65; //y variance //from monitoring plots of vertex
46  dVertexCovMatrix(2, 2) = 1.5; //z variance //a guess, semi-guarding against the worst case scenario //ugh
47  dVertexCovMatrix(3, 3) = 0.0; //t variance //not used
48 }
49 
51 {
52  if(dDebugLevel >= 5)
53  {
54  cout << "Total # of RF Bunches Allocated (All threads): " << dResourcePool_EventRFBunch.Get_NumObjectsAllThreads() << endl;
55  cout << "Total # of Particle Combo Steps Allocated (All threads): " << dResourcePool_ParticleComboStep.Get_NumObjectsAllThreads() << endl;
56  cout << "Total # of Particle Combos Allocated (All threads): " << dResourcePool_ParticleCombo.Get_NumObjectsAllThreads() << endl;
57  cout << "Total # of Charged Hypos (All threads): " << dChargedTrackHypothesisFactory->Get_NumObjectsAllThreads() << endl;
58  cout << "Total # of Neutral Hypos (All threads): " << dNeutralParticleHypothesisFactory->Get_NumObjectsAllThreads() << endl;
59  cout << "Total # of Beam Photons (All threads): " << dBeamPhotonfactory->Get_NumObjectsAllThreads() << endl;
60  cout << "Total # of KinematicDatas (All threads): " << dResourcePool_KinematicData.Get_NumObjectsAllThreads() << endl;
61  }
62 
63  for(const auto& locRFPair : dRFBunchMap)
64  dResourcePool_EventRFBunch.Recycle(locRFPair.second);
65  dRFBunchMap.clear();
66 
68  dComboStepMap.clear();
69 
71  dComboMap.clear();
72 
74  dChargedHypoMap.clear();
75  dKinFitChargedHypoMap.clear();
76 
78  dNeutralHypoMap.clear();
79  dKinFitNeutralHypoMap.clear();
80 
82  dKinFitBeamPhotonMap.clear();
83 
85 
86  //Free the memory held by the vectors //I think recycle does it anyway, but just in case
92  decltype(dCreated_BeamPhoton)().swap(dCreated_BeamPhoton);
93 }
94 
96 {
97  //is there at least one non-fittable vertex that has neutrals?
98  auto locDanglingIterator = dDanglingNeutralsFlagMap.find(locReactionVertexInfo);
99  bool locDanglingNeutralsFlag = false;
100  if(locDanglingIterator != dDanglingNeutralsFlagMap.end())
101  locDanglingNeutralsFlag = locDanglingIterator->second;
102  else
103  {
104  for(auto locStepVertexInfo : locReactionVertexInfo->Get_StepVertexInfos())
105  {
106  if(locStepVertexInfo->Get_FittableVertexFlag())
107  continue;
108  if(!locStepVertexInfo->Get_OnlyConstrainTimeParticles().empty())
109  {
110  locDanglingNeutralsFlag = true; //photons
111  break;
112  }
113  if(!locStepVertexInfo->Get_NoConstrainParticles(true, d_FinalState, d_Neutral, false, false, false).empty())
114  {
115  locDanglingNeutralsFlag = true; //massive neutrals
116  break;
117  }
118  }
119  dDanglingNeutralsFlagMap.emplace(locReactionVertexInfo, locDanglingNeutralsFlag);
120  }
121  return ((locKinFitType != d_NoFit) && ((locKinFitType == d_P4Fit) || locDanglingNeutralsFlag));
122 }
123 
124 const DParticleCombo* DParticleComboCreator::Build_ParticleCombo(const DReactionVertexInfo* locReactionVertexInfo, const DSourceCombo* locFullCombo, const DKinematicData* locBeamParticle, int locRFBunchShift, DKinFitType locKinFitType)
125 {
126  if(dDebugLevel > 0)
127  cout << "Building particle combo" << endl;
128  auto locCreateNeutralErrorMatrixFlag_Combo = Get_CreateNeutralErrorMatrixFlag_Combo(locReactionVertexInfo, locKinFitType);
129  auto locSpactimeIsFitFlag = ((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit));
130  auto locComboTuple = std::make_tuple(locReactionVertexInfo, locFullCombo, locBeamParticle, locRFBunchShift, locCreateNeutralErrorMatrixFlag_Combo);
131  auto locComboIterator = dComboMap.find(locComboTuple);
132  if(locComboIterator != dComboMap.end())
133  {
134  if(dDebugLevel > 0)
135  cout << "Combo previously created, returning." << endl;
136  return locComboIterator->second;
137  }
138 
139  auto locParticleCombo = Get_ParticleComboResource();
140  dComboMap.emplace(locComboTuple, locParticleCombo);
141 
142  auto locReaction = locReactionVertexInfo->Get_Reaction();
143  auto locPrimaryVertexZ = dSourceComboVertexer->Get_PrimaryVertex(locReactionVertexInfo, locFullCombo, locBeamParticle).Z();
144 
145  //Get/Create RF Bunch
146  const DEventRFBunch* locEventRFBunch = nullptr;
147  auto locRFIterator = dRFBunchMap.find(locRFBunchShift);
148  if(locRFIterator != dRFBunchMap.end())
149  locEventRFBunch = locRFIterator->second;
150  else
151  {
152  auto locInitialEventRFBunch = dSourceComboTimeHandler->Get_InitialEventRFBunch();
153  auto locNewEventRFBunch = dResourcePool_EventRFBunch.Get_Resource();
154  locNewEventRFBunch->Reset();
155  auto locRFTime = dSourceComboTimeHandler->Calc_RFTime(locRFBunchShift);
156  locNewEventRFBunch->Set_Content(locInitialEventRFBunch->dTimeSource, locRFTime, locInitialEventRFBunch->dTimeVariance, 0);
157  locEventRFBunch = locNewEventRFBunch;
158  dRFBunchMap.emplace(locRFBunchShift, locEventRFBunch);
159  }
160  locParticleCombo->Set_EventRFBunch(locEventRFBunch);
161  if(dDebugLevel >= 5)
162  cout << "RF Bunch set, shift = " << locRFBunchShift << endl;
163 
164  auto locReactionSteps = locReaction->Get_ReactionSteps();
165  for(size_t loc_i = 0; loc_i < locReactionSteps.size(); ++loc_i)
166  {
167  if(dDebugLevel >= 5)
168  cout << "Step: " << loc_i << endl;
169 
170  auto locReactionStep = locReactionSteps[loc_i];
171  auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(loc_i);
172  auto locStepBeamParticle = (loc_i == 0) ? locBeamParticle : nullptr;
173  auto locIsProductionVertex = locStepVertexInfo->Get_ProductionVertexFlag();
174 
175  auto locVertexPrimaryCombo = dSourceComboer->Get_VertexPrimaryCombo(locFullCombo, locStepVertexInfo);
176  if(dDebugLevel >= 5)
177  {
178  cout << "VERTEX PRIMARY COMBO:" << endl;
179  Print_SourceCombo(locVertexPrimaryCombo);
180  }
181 
182  auto locSourceCombo = (loc_i == 0) ? locFullCombo : dSourceComboer->Get_StepSourceCombo(locReaction, loc_i, locVertexPrimaryCombo, locStepVertexInfo->Get_StepIndices().front());
183  if(dDebugLevel >= 5)
184  {
185  cout << "STEP " << loc_i << ", SOURCE COMBO:" << endl;
186  Print_SourceCombo(locSourceCombo);
187  }
188 
189  bool locCreateNeutralErrorMatrixFlag = (locKinFitType != d_NoFit) && ((locKinFitType == d_P4Fit) || !locStepVertexInfo->Get_FittableVertexFlag());
190  if(locReactionStep->Get_FinalPIDs(false, d_Neutral, false).empty())
191  locCreateNeutralErrorMatrixFlag = false; //no neutrals!
192 
193  //reuse step if already created
194  auto locStepTuple = std::make_tuple(*locReactionStep, locSourceCombo, locCreateNeutralErrorMatrixFlag, locIsProductionVertex, locFullCombo, locBeamParticle);
195  auto locStepIterator = dComboStepMap.find(locStepTuple);
196  if(locStepIterator != dComboStepMap.end())
197  {
198  locParticleCombo->Add_ParticleComboStep(locStepIterator->second);
199  if(dDebugLevel >= 5)
200  cout << "step already created, reuse" << endl;
201  continue;
202  }
203 
204  //Create a new step
205  auto locParticleComboStep = Get_ParticleComboStepResource();
206 
207  //get vertex position and time offset
208  auto locVertex = dSourceComboVertexer->Get_Vertex(locStepVertexInfo, locFullCombo, locBeamParticle, false);
209  if(dDebugLevel >= 20)
210  cout << "vertex: " << locVertex.X() << ", " << locVertex.Y() << ", " << locVertex.Z() << endl;
211  auto locTimeOffset = dSourceComboVertexer->Get_TimeOffset(locReactionVertexInfo, locStepVertexInfo, locFullCombo, locBeamParticle);
212  if(dDebugLevel >= 20)
213  cout << "time offset: " << locTimeOffset << endl;
214 
215  //build spacetime vertex
216  auto locPropagatedRFTime = dSourceComboTimeHandler->Calc_PropagatedRFTime(locPrimaryVertexZ, locRFBunchShift, locTimeOffset);
217  if(dDebugLevel >= 20)
218  cout << "prop rf time: " << locPropagatedRFTime << endl;
219  DLorentzVector locSpacetimeVertex(locVertex, locPropagatedRFTime);
220  if(dDebugLevel >= 5)
221  cout << "spacetime vertex xyzt: " << locSpacetimeVertex.X() << ", " << locSpacetimeVertex.Y() << ", " << locSpacetimeVertex.Z() << ", " << locSpacetimeVertex.T() << endl;
222 
223  //Set initial particle
224  if((locBeamParticle != nullptr) && (loc_i == 0))
225  {
226  if(dDebugLevel >= 5)
227  cout << "beam particle set: " << locBeamParticle << endl;
228  locParticleComboStep->Set_InitialParticle(locBeamParticle);
229  }
230  else
231  locParticleComboStep->Set_InitialParticle(nullptr);
232 
233  //Build final particles
234  auto locFinalPIDs = locReactionStep->Get_FinalPIDs();
235  map<Particle_t, size_t> locPIDCountMap;
236  vector<const DKinematicData*> locFinalParticles;
237  for(size_t loc_j = 0; loc_j < locFinalPIDs.size(); ++loc_j)
238  {
239  //if missing or decaying, nothing to get
240  if((int(loc_j) == locReactionStep->Get_MissingParticleIndex()) || (DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j) >= 0))
241  {
242  locFinalParticles.push_back(nullptr);
243  continue;
244  }
245 
246  //Get source objects, in order
247  auto locPID = locFinalPIDs[loc_j];
248  auto locPIDIterator = locPIDCountMap.find(locPID);
249  if(locPIDIterator != locPIDCountMap.end())
250  ++(locPIDIterator->second);
251  else
252  locPIDCountMap.emplace(locPID, 1);
253 
254  size_t locPIDCountSoFar = 0;
255 
256  auto locSourceParticle = DAnalysis::Get_SourceParticle_ThisStep(locSourceCombo, locPID, locPIDCountMap[locPID], locPIDCountSoFar);
257  if(dDebugLevel >= 5)
258  cout << "pid index, pid, source particle: " << loc_j << ", " << locPID << ", " << locSourceParticle << endl;
259 
260  //build hypo
261  if(ParticleCharge(locPID) == 0) //neutral
262  {
263  auto locNeutralShower = static_cast<const DNeutralShower*>(locSourceParticle);
264  auto locHypoTuple = std::make_tuple(locNeutralShower, locPID, locRFBunchShift, locCreateNeutralErrorMatrixFlag, locIsProductionVertex, locFullCombo, locVertexPrimaryCombo, locBeamParticle); //last 4 needed for spacetime vertex
265  const DNeutralParticleHypothesis* locNewNeutralHypo = nullptr;
266 
267  auto locHypoIterator = dNeutralHypoMap.find(locHypoTuple);
268  if(locHypoIterator != dNeutralHypoMap.end())
269  locNewNeutralHypo = locHypoIterator->second;
270  else
271  {
272  //even if locCreateNeutralErrorMatrixFlag is false, create it anyway if massive neutral and no time constraint!
273  auto locCreateThisNeutralErrorMatrixFlag = locCreateNeutralErrorMatrixFlag ? true : ((ParticleMass(locPID) > 0.0) && !locSpactimeIsFitFlag);
274  auto locVertexCovMatrix = locCreateThisNeutralErrorMatrixFlag ? &dVertexCovMatrix : nullptr;
275  locNewNeutralHypo = dNeutralParticleHypothesisFactory->Create_DNeutralParticleHypothesis(locNeutralShower, locPID, locEventRFBunch, locSpacetimeVertex, locVertexCovMatrix);
276  dCreated_NeutralHypo.push_back(const_cast<DNeutralParticleHypothesis*>(locNewNeutralHypo));
277  dNeutralHypoMap.emplace(locHypoTuple, locNewNeutralHypo);
278  }
279 
280  locFinalParticles.push_back(static_cast<const DKinematicData*>(locNewNeutralHypo));
281  }
282  else //charged
283  {
284  auto locChargedTrack = static_cast<const DChargedTrack*>(locSourceParticle);
285  auto locHypoTuple = std::make_tuple(locChargedTrack, locPID, locRFBunchShift, locIsProductionVertex, locFullCombo, locVertexPrimaryCombo, locBeamParticle);
286  const DChargedTrackHypothesis* locNewChargedHypo = nullptr;
287 
288  auto locHypoIterator = dChargedHypoMap.find(locHypoTuple);
289  if(locHypoIterator != dChargedHypoMap.end())
290  locNewChargedHypo = locHypoIterator->second;
291  else
292  {
293  locNewChargedHypo = Create_ChargedHypo(locChargedTrack, locPID, locPropagatedRFTime, locIsProductionVertex, locFullCombo, locVertexPrimaryCombo, locBeamParticle, locSpacetimeVertex.Vect());
294  dChargedHypoMap.emplace(locHypoTuple, locNewChargedHypo);
295  }
296 
297  locFinalParticles.push_back(static_cast<const DKinematicData*>(locNewChargedHypo));
298  }
299  }
300  locParticleComboStep->Set_Contents(locStepBeamParticle, locFinalParticles, locSpacetimeVertex);
301 
302  //save it
303  locParticleCombo->Add_ParticleComboStep(locParticleComboStep);
304  dComboStepMap.emplace(locStepTuple, locParticleComboStep);
305  }
306 
307  return locParticleCombo;
308 }
309 
310 const DChargedTrackHypothesis* DParticleComboCreator::Create_ChargedHypo(const DChargedTrack* locChargedTrack, Particle_t locPID, double locPropagatedRFTime, bool locIsProductionVertex, const DSourceCombo* locReactionFullCombo, const DSourceCombo* locVertexPrimaryFullCombo, const DKinematicData* locBeamParticle, DVector3 locVertex)
311 {
312  //see if DChargedTrackHypothesis with the desired PID was created by the default factory, AND it passed the PreSelect cuts
313  auto locOrigHypo = locChargedTrack->Get_Hypothesis(locPID);
314  auto locNewHypo = dChargedTrackHypothesisFactory->Get_Resource();
315  dCreated_ChargedHypo.push_back(locNewHypo);
316  locNewHypo->Share_FromInput(locOrigHypo, true, false, true); //share all but timing info
317 
318  auto locTrackPOCAX4 = dSourceComboTimeHandler->Get_ChargedPOCAToVertexX4(locOrigHypo, locIsProductionVertex, locReactionFullCombo, locVertexPrimaryFullCombo, locBeamParticle, false, locVertex);
319  locNewHypo->Set_TimeAtPOCAToVertex(locTrackPOCAX4.T());
320 
321  locNewHypo->Set_T0(locPropagatedRFTime, locOrigHypo->t0_err(), locOrigHypo->t0_detector());
322  locNewHypo->AddAssociatedObject(locChargedTrack);
323 
324  dParticleID->Calc_ChargedPIDFOM(locNewHypo);
325 
326  return locNewHypo;
327 }
328 
329 const DParticleCombo* DParticleComboCreator::Create_KinFitCombo_NewCombo(const DParticleCombo* locOrigCombo, const DReaction* locReaction, const DKinFitResults* locKinFitResults, const shared_ptr<const DKinFitChain>& locKinFitChain)
330 {
331  if(dDebugLevel > 0)
332  cout << "Create kinfit combo" << endl;
334 
335  auto locNewCombo = Get_ParticleComboResource();
336  locNewCombo->Set_KinFitResults(locKinFitResults);
337  locNewCombo->Set_EventRFBunch(locOrigCombo->Get_EventRFBunch());
338  auto locOutputKinFitParticles = locKinFitResults->Get_OutputKinFitParticles();
339  auto locOrigShiftedRFTime = locOrigCombo->Get_EventRFBunch()->dTime;
340 
341  for(size_t loc_j = 0; loc_j < locOrigCombo->Get_NumParticleComboSteps(); ++loc_j)
342  {
343  if(dDebugLevel >= 5)
344  cout << "Step: " << loc_j << endl;
345  auto locComboStep = locOrigCombo->Get_ParticleComboStep(loc_j);
346  auto locReactionStep = locReaction->Get_ReactionStep(loc_j);
347 
348  auto locNewComboStep = Get_ParticleComboStepResource();
349  locNewCombo->Add_ParticleComboStep(locNewComboStep);
350  locNewComboStep->Set_MeasuredParticleComboStep(locComboStep);
351 
352  //SPACETIME VERTEX
353  locNewComboStep->Set_SpacetimeVertex(locComboStep->Get_SpacetimeVertex()); //overridden if kinematic fit
354  Set_SpacetimeVertex(locReaction, locNewCombo, locOrigCombo, locNewComboStep, loc_j, locKinFitResults, locKinFitChain, locOrigShiftedRFTime);
355  auto locSpacetimeVertex = locNewComboStep->Get_SpacetimeVertex();
356  if(dDebugLevel >= 5)
357  cout << "spacetime vertex set" << endl;
358 
359  //INITIAL PARTICLE
360  auto locInitialParticle_Measured = locComboStep->Get_InitialParticle_Measured();
361  if(locInitialParticle_Measured != nullptr) //set beam photon
362  {
363  auto locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locInitialParticle_Measured);
364  if(locKinFitParticle == NULL) //not used in kinfit!!
365  locNewComboStep->Set_InitialParticle(locInitialParticle_Measured);
366  else //create a new one
367  {
368  locNewComboStep->Set_InitialParticle(Create_BeamPhoton_KinFit(static_cast<const DBeamPhoton*>(locInitialParticle_Measured), locKinFitParticle.get(), locSpacetimeVertex));
369  locNewComboStep->Set_InitialKinFitParticle(locKinFitParticle);
370  }
371  }
372  else //decaying particle! //set here for initial state, and in previous step for final state
373  Set_DecayingParticles(locReaction, locNewCombo, locOrigCombo, loc_j, locNewComboStep, locKinFitChain, locKinFitResults);
374 
375  //FINAL PARTICLES
376  for(size_t loc_k = 0; loc_k < locComboStep->Get_NumFinalParticles(); ++loc_k)
377  {
378  auto locKinematicData_Measured = locComboStep->Get_FinalParticle_Measured(loc_k);
379  if(locReactionStep->Get_MissingParticleIndex() == int(loc_k)) //missing!
380  {
381  auto locMissingParticles = locKinFitResults->Get_OutputKinFitParticles(d_MissingParticle);
382  if(!locMissingParticles.empty())
383  {
384  auto locNewKinematicData = Build_KinematicData(locKinFitResults, (*locMissingParticles.begin()).get(), locSpacetimeVertex, true);
385  locNewComboStep->Add_FinalParticle(locNewKinematicData);
386  }
387  else //not used in kinfit: do not create: NULL
388  locNewComboStep->Add_FinalParticle(NULL);
389  }
390  else if(locKinematicData_Measured == nullptr) //decaying
391  locNewComboStep->Add_FinalParticle(nullptr); //is set later, when it's in the initial state
392  else if(ParticleCharge(locKinematicData_Measured->PID()) == 0) //neutral
393  {
394  auto locNeutralHypo = static_cast<const DNeutralParticleHypothesis*>(locKinematicData_Measured);
395  //might have used neutral shower OR neutral hypo. try hypo first
396  auto locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locNeutralHypo);
397  if(locKinFitParticle == NULL)
398  locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locNeutralHypo->Get_NeutralShower());
399  if(locKinFitParticle == NULL) //not used in kinfit!!
400  locNewComboStep->Add_FinalParticle(locKinematicData_Measured);
401  else //create a new one
402  locNewComboStep->Add_FinalParticle(Create_NeutralHypo_KinFit(locNeutralHypo, locKinFitParticle.get(), locSpacetimeVertex.T()));
403  }
404  else //charged
405  {
406  auto locChargedHypo = static_cast<const DChargedTrackHypothesis*>(locKinematicData_Measured);
407  auto locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locChargedHypo);
408  if(locKinFitParticle == NULL) //not used in kinfit!!
409  locNewComboStep->Add_FinalParticle(locKinematicData_Measured);
410  else //create a new one
411  {
412  auto locChargedTrack = static_cast<const DChargedTrack*>(locComboStep->Get_FinalParticle_SourceObject(loc_k));
413  auto locNewHypo = Create_ChargedHypo_KinFit(locChargedTrack, locKinematicData_Measured->PID(), locKinFitParticle.get(), locSpacetimeVertex.T());
414  locNewComboStep->Add_FinalParticle(locNewHypo);
415  }
416  }
417  }
418  }
419 
420  return locNewCombo;
421 }
422 
423 void DParticleComboCreator::Set_SpacetimeVertex(const DReaction* locReaction, const DParticleCombo* locNewParticleCombo, const DParticleCombo* locOldParticleCombo, DParticleComboStep* locNewParticleComboStep, size_t locStepIndex, const DKinFitResults* locKinFitResults, const shared_ptr<const DKinFitChain>& locKinFitChain, double locOrigShiftedRFTime) const
424 {
425  if(dDebugLevel >= 5)
426  cout << "DParticleComboCreator::Set_SpacetimeVertex" << endl;
427 
428  DKinFitType locKinFitType = locReaction->Get_KinFitType();
429  if((locKinFitType == d_NoFit) || (locKinFitType == d_P4Fit))
430  return; //neither vertex nor time was fit: no update to give
431 
432  //mass not fixed: if not initial step, get spacetime vertex from step where this particle was produced
433 
434  //instead, get from common vertex of the other particles
435  auto locAllParticles = locKinFitChain->Get_KinFitChainStep(locStepIndex)->Get_FinalParticles();
436  if(locAllParticles.empty())
437  {
438  if(dDebugLevel >= 5)
439  cout << "somehow no particles at this step" << endl;
440  if(locStepIndex == 0) //get from the first particle you find
441  {
442  size_t locNextStepIndex = 1;
443  while(locAllParticles.empty() && (locNextStepIndex < locKinFitChain->Get_NumKinFitChainSteps()))
444  {
445  locAllParticles = locKinFitChain->Get_KinFitChainStep(locNextStepIndex)->Get_FinalParticles();
446  ++locNextStepIndex;
447  }
448  }
449  else
450  {
451  //get spacetime vertex from step where this particle was produced
452  auto locDecayFromStepIndex = Get_InitialParticleDecayFromIndices(locReaction, locStepIndex).first;
453  auto locPreviousParticleComboStep = locNewParticleCombo->Get_ParticleComboStep(locDecayFromStepIndex);
454  locNewParticleComboStep->Set_SpacetimeVertex(locPreviousParticleComboStep->Get_SpacetimeVertex());
455  return;
456  }
457  }
458 
459  auto locKinFitParticle = locAllParticles[0];
460  auto locParticleType = locKinFitParticle->Get_KinFitParticleType();
461  if(dDebugLevel >= 20)
462  cout << "particle type, common vx param index, vx param index: " << locParticleType << ", " << int(locKinFitParticle->Get_CommonVxParamIndex()) << ", " << int(locKinFitParticle->Get_VxParamIndex()) << endl;
463  if((locParticleType == d_DetectedParticle) && (locKinFitParticle->Get_CommonVxParamIndex() < 0))
464  return; //vertex fit chosen but could not be performed: don't update!
465  if((locParticleType != d_DetectedParticle) && (locKinFitParticle->Get_VxParamIndex() < 0))
466  return; //vertex fit chosen but could not be performed: don't update!
467 
468  //need the spacetime vertex at the production vertex of the particle grabbed
469  TLorentzVector locSpacetimeVertex;
470  if(locKinFitParticle->Get_VertexP4AtProductionVertex()) //"position" is at production vertex
471  locSpacetimeVertex = locKinFitParticle->Get_SpacetimeVertex();
472  else //"position" is at decay vertex
473  locSpacetimeVertex = locKinFitParticle->Get_CommonSpacetimeVertex(); //get production
474  locNewParticleComboStep->Set_SpacetimeVertex(locSpacetimeVertex); //set (for now)
475 
476  //see if we need to update the time
477  if(dDebugLevel >= 20)
478  cout << "particle type, common t param index, t param index: " << locParticleType << ", " << int(locKinFitParticle->Get_CommonTParamIndex()) << ", " << int(locKinFitParticle->Get_TParamIndex()) << endl;
479  if((locParticleType == d_DetectedParticle) && (locKinFitParticle->Get_CommonTParamIndex() >= 0))
480  return; //time was constrained by the kinfit, we're done
481  if((locParticleType != d_DetectedParticle) && (locKinFitParticle->Get_TParamIndex() >= 0))
482  return; //time was constrained by the kinfit, we're done
483 
484  //time not constrained. instead, get from rf time and propagate it
485  if(locStepIndex == 0)
486  {
487  locSpacetimeVertex.SetT(locOrigShiftedRFTime + (locSpacetimeVertex.Z() - dTargetCenter.Z())/SPEED_OF_LIGHT);
488  if(dDebugLevel >= 5)
489  cout << "step 0: orig rf time, vertex-z, targz, shifted rf time: " << locOrigShiftedRFTime << ", " << locSpacetimeVertex.Z() << ", " << dTargetCenter.Z() << ", " << locSpacetimeVertex.T() << endl;
490  }
491  else
492  {
493  auto locDecayFromStepIndices = Get_InitialParticleDecayFromIndices(locReaction, locStepIndex);
494  if(dDebugLevel >= 20)
495  cout << "decay from indices: " << locDecayFromStepIndices.first << ", " << locDecayFromStepIndices.second << endl;
496  auto locPreviousParticleComboStep = locNewParticleCombo->Get_ParticleComboStep(locDecayFromStepIndices.first);
497  auto locPreviousSpacetimeVertex = locPreviousParticleComboStep->Get_SpacetimeVertex();
498  if(dDebugLevel >= 20)
499  cout << "previous spacetime vertex: " << locPreviousSpacetimeVertex.X() << ", " << locPreviousSpacetimeVertex.Y() << ", " << locPreviousSpacetimeVertex.Z() << ", " << locPreviousSpacetimeVertex.T() << endl;
500 
501  auto locDecayingParticle = Get_DecayingParticle(locReaction, locOldParticleCombo, locStepIndex, locKinFitChain, locKinFitResults);
502  if((locDecayingParticle == nullptr) || !IsDetachedVertex(PDGtoPType(locDecayingParticle->Get_PID())))
503  locSpacetimeVertex.SetT(locPreviousSpacetimeVertex.T());
504  else
505  {
506  auto locBeta = locDecayingParticle->Get_P4().Beta();
507  auto locPathLength = (locSpacetimeVertex.Vect() - locPreviousSpacetimeVertex.Vect()).Mag();
508  auto locTime = locPreviousSpacetimeVertex.T() + locPathLength/(locBeta*SPEED_OF_LIGHT);
509  if(dDebugLevel >= 20)
510  cout << "calced beta, path, time: " << locBeta << ", " << locPathLength << ", " << locTime << endl;
511  locSpacetimeVertex.SetT(locTime);
512  }
513  }
514 
515  locNewParticleComboStep->Set_SpacetimeVertex(locSpacetimeVertex);
516 }
517 
518 void DParticleComboCreator::Set_DecayingParticles(const DReaction* locReaction, const DParticleCombo* locNewParticleCombo, const DParticleCombo* locOldParticleCombo, size_t locStepIndex, DParticleComboStep* locNewParticleComboStep, const shared_ptr<const DKinFitChain>& locKinFitChain, const DKinFitResults* locKinFitResults)
519 {
520  auto locKinFitParticle = Get_DecayingParticle(locReaction, locOldParticleCombo, locStepIndex, locKinFitChain, locKinFitResults);
521  if(locKinFitParticle == nullptr) //not used in fit
522  {
523  locNewParticleComboStep->Set_InitialParticle(nullptr);
524  return; //no need to back-set NULL: was set to NULL by default
525  }
526 
527  auto locEventVertex = locOldParticleCombo->Get_ParticleComboStep(0)->Get_SpacetimeVertex().Vect();
528  auto locPID = PDGtoPType(locKinFitParticle->Get_PID());
529  auto locFromStepIndex = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locStepIndex).first;
530 
531  auto locProductionSpacetimeVertex = locNewParticleCombo->Get_ParticleComboStep(locFromStepIndex)->Get_SpacetimeVertex();
532  auto locKinematicData_Production = Build_KinematicData(locKinFitResults, locKinFitParticle.get(), locProductionSpacetimeVertex, true);
533 
534  bool locCreate2ndObjectFlag = (IsDetachedVertex(locPID) && (locStepIndex != 0) && (locFromStepIndex >= 0));
535  auto locDecaySpacetimeVertex = locNewParticleCombo->Get_ParticleComboStep(locStepIndex)->Get_SpacetimeVertex();
536  auto locKinematicData_Decay = locCreate2ndObjectFlag ? Build_KinematicData(locKinFitResults, locKinFitParticle.get(), locDecaySpacetimeVertex, false) : locKinematicData_Production;
537 
538  locNewParticleComboStep->Set_InitialParticle(locKinematicData_Decay);
539  locNewParticleComboStep->Set_InitialKinFitParticle(locKinFitParticle);
540 
541  //now, back-set the particle at the other vertex
542  if((locStepIndex == 0) || (locFromStepIndex < 0))
543  return; //no other place to set it
544 
545  auto locParticleComboStep = const_cast<DParticleComboStep*>(locNewParticleCombo->Get_ParticleComboStep(locFromStepIndex));
546  //find where it is the decaying particle
547  for(size_t loc_i = 0; loc_i < locParticleComboStep->Get_NumFinalParticles(); ++loc_i)
548  {
549  auto locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locFromStepIndex, loc_i);
550  if(locDecayStepIndex != int(locStepIndex))
551  continue;
552  locParticleComboStep->Set_FinalParticle(locKinematicData_Production, loc_i);
553  break;
554  }
555 }
556 
557 shared_ptr<DKinFitParticle> DParticleComboCreator::Get_DecayingParticle(const DReaction* locReaction, const DParticleCombo* locOldParticleCombo, size_t locComboStepIndex, const shared_ptr<const DKinFitChain>& locKinFitChain, const DKinFitResults* locKinFitResults) const
558 {
559  auto locReactionStep = locReaction->Get_ReactionStep(locComboStepIndex);
560  Particle_t locPID = locReactionStep->Get_InitialPID();
561  if(!IsFixedMass(locPID))
562  return nullptr;
563 
564  //find which step in the DKinFitChain this combo step corresponds to
565  for(size_t loc_i = 0; loc_i < locKinFitChain->Get_NumKinFitChainSteps(); ++loc_i)
566  {
567  auto locKinFitChainStep = locKinFitChain->Get_KinFitChainStep(loc_i);
568 
569  //loop over init particles to get the decaying particle (if present)
570  shared_ptr<DKinFitParticle> locDecayingParticle = nullptr;
571  auto locInitialParticles = locKinFitChainStep->Get_InitialParticles();
572  for(auto locKinFitParticle : locInitialParticles)
573  {
574  if(locKinFitParticle == nullptr)
575  continue;
576  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
577  continue; //not a decaying particle
578  locDecayingParticle = locKinFitParticle;
579  break;
580  }
581  if(locDecayingParticle == nullptr)
582  continue; //no decaying particles in this step
583  if(PDGtoPType(locDecayingParticle->Get_PID()) != locPID)
584  continue; //wrong PID
585 
586  //may still not be correct particle. compare decay products: if any of the combo step particles are in the kinfit step, this is it
587  //if all step final particles are decaying, then dive down: through steps
588  //if any step decay product at any step is located as any decay product at any step in the kinfit chain: then matches
589 
590  //get all measured products, then just pick the first one to search for
591  auto locMeasuredParticles = locOldParticleCombo->Get_DecayChainParticles_Measured(locReaction, locComboStepIndex);
592  const DKinematicData* locMeasuredParticle = locMeasuredParticles[0];
593  auto locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locMeasuredParticle);
594  if(locKinFitParticle == NULL) //null: neutral shower. Use shower object
595  {
596  const DNeutralShower* locNeutralShower = static_cast<const DNeutralParticleHypothesis*>(locMeasuredParticle)->Get_NeutralShower();
597  locKinFitParticle = locKinFitResults->Get_OutputKinFitParticle(locNeutralShower);
598  }
599 
600  if(!Search_ForParticleInDecay(locKinFitChain, loc_i, locKinFitParticle))
601  continue;
602 
603  //Found!
604  return locDecayingParticle;
605  }
606 
607  return NULL;
608 }
609 
610 bool DParticleComboCreator::Search_ForParticleInDecay(const shared_ptr<const DKinFitChain>& locKinFitChain, size_t locStepToSearch, const shared_ptr<DKinFitParticle>& locParticleToFind) const
611 {
612  auto locKinFitChainStep = locKinFitChain->Get_KinFitChainStep(locStepToSearch);
613  auto locFinalParticles = locKinFitChainStep->Get_FinalParticles();
614  std::sort(locFinalParticles.begin(), locFinalParticles.end());
615  if(std::binary_search(locFinalParticles.begin(), locFinalParticles.end(), locParticleToFind))
616  return true; //found it
617 
618  //else loop over final state, diving through decays
619  for(auto locKinFitParticle : locFinalParticles)
620  {
621  if(locKinFitParticle == nullptr)
622  continue;
623  if(locKinFitParticle->Get_KinFitParticleType() != d_DecayingParticle)
624  continue; //not a decaying particle
625 
626  int locDecayStepIndex = locKinFitChain->Get_DecayStepIndex(locKinFitParticle);
627  if(Search_ForParticleInDecay(locKinFitChain, locDecayStepIndex, locParticleToFind))
628  return true; //found in in subsequent step
629  }
630  return false; //not found (yet)
631 }
632 
633 const DBeamPhoton* DParticleComboCreator::Create_BeamPhoton_KinFit(const DBeamPhoton* locBeamPhoton, const DKinFitParticle* locKinFitParticle, const DLorentzVector& locSpacetimeVertex)
634 {
635  auto locBeamIterator = dKinFitBeamPhotonMap.find(locKinFitParticle);
636  if(locBeamIterator != dKinFitBeamPhotonMap.end())
637  return locBeamIterator->second;
638 
639  DBeamPhoton* locNewBeamPhoton = dBeamPhotonfactory->Get_Resource();
640  dCreated_BeamPhoton.push_back(locNewBeamPhoton);
641  dKinFitBeamPhotonMap.emplace(locKinFitParticle, locNewBeamPhoton);
642 
643  locNewBeamPhoton->dCounter = locBeamPhoton->dCounter;
644  locNewBeamPhoton->dSystem = locBeamPhoton->dSystem;
645  locNewBeamPhoton->setPID(locBeamPhoton->PID());
646  locNewBeamPhoton->setMomentum(DVector3(locKinFitParticle->Get_Momentum().X(),locKinFitParticle->Get_Momentum().Y(),locKinFitParticle->Get_Momentum().Z()));
647  if(locKinFitParticle->Get_CommonVxParamIndex() >= 0)
648  locNewBeamPhoton->setPosition(DVector3(locKinFitParticle->Get_Position().X(),locKinFitParticle->Get_Position().Y(),locKinFitParticle->Get_Position().Z()));
649  else
650  locNewBeamPhoton->setPosition(locSpacetimeVertex.Vect());
651  if(locKinFitParticle->Get_CommonTParamIndex() >= 0)
652  locNewBeamPhoton->setTime(locKinFitParticle->Get_Time());
653  else
654  locNewBeamPhoton->setTime(locBeamPhoton->time() + (locNewBeamPhoton->position().Z() - locBeamPhoton->position().Z())/SPEED_OF_LIGHT);
655  locNewBeamPhoton->setErrorMatrix(locKinFitParticle->Get_CovarianceMatrix());
656  return locNewBeamPhoton;
657 }
658 
659 const DChargedTrackHypothesis* DParticleComboCreator::Create_ChargedHypo_KinFit(const DChargedTrack* locChargedTrack, Particle_t locPID, const DKinFitParticle* locKinFitParticle, double locPropagatedRFTime)
660 {
661  auto locOrigHypo = locChargedTrack->Get_Hypothesis(locPID);
662  auto locHypoIterator = dKinFitChargedHypoMap.find(locKinFitParticle);
663  if(locHypoIterator != dKinFitChargedHypoMap.end())
664  return locHypoIterator->second;
665 
666  //even if vertex is not fit, p4 is fit: different beta: update time info
667  auto locNewHypo = dChargedTrackHypothesisFactory->Get_Resource();
668  dKinFitChargedHypoMap.emplace(locKinFitParticle, locNewHypo);
669  dCreated_ChargedHypo.push_back(locNewHypo);
670  locNewHypo->setPID(locPID);
671  locNewHypo->AddAssociatedObject(locChargedTrack);
672 
673  //p3 & v3
674  TVector3 locFitMomentum = locKinFitParticle->Get_Momentum();
675  TVector3 locFitVertex = locKinFitParticle->Get_Position();
676  locNewHypo->setMomentum(DVector3(locFitMomentum.X(), locFitMomentum.Y(), locFitMomentum.Z()));
677  locNewHypo->setPosition(DVector3(locFitVertex.X(), locFitVertex.Y(), locFitVertex.Z()));
678 
679  //t & error matrix
680  locNewHypo->setTime(locKinFitParticle->Get_Time()); //is this correct?????
681  locNewHypo->setErrorMatrix(locKinFitParticle->Get_CovarianceMatrix());
682 
683  //if timing was kinfit, there is no chisq to calculate: forced to correct time
684  //therefore, just use measured timing info (pre-kinfit)
685  if(locKinFitParticle->Get_CommonTParamIndex() >= 0)
686  {
687  locNewHypo->Share_FromInput(locOrigHypo, true, true, false); //share all but kinematics
688  return locNewHypo;
689  }
690 
691  //only share tracking info (not timing or kinematics)
692  locNewHypo->Share_FromInput(locOrigHypo, true, false, false);
693 
694  //update timing info
695  if(locKinFitParticle->Get_CommonVxParamIndex() >= 0) //a vertex was fit
696  {
697  //all kinematics propagated to vertex position
698  locNewHypo->Set_T0(locPropagatedRFTime, locOrigHypo->t0_err(), locOrigHypo->t0_detector());
699  locNewHypo->Set_TimeAtPOCAToVertex(locNewHypo->time());
700  }
701  else //only momentum has changed (and thus time)
702  {
703  locNewHypo->Set_T0(locOrigHypo->t0(), locOrigHypo->t0_err(), locOrigHypo->t0_detector());
704  locNewHypo->Set_TimeAtPOCAToVertex(locOrigHypo->Get_TimeAtPOCAToVertex() + locNewHypo->time() - locOrigHypo->time());
705  }
706 
707  dParticleID->Calc_ChargedPIDFOM(locNewHypo);
708  return locNewHypo;
709 }
710 
711 const DNeutralParticleHypothesis* DParticleComboCreator::Create_NeutralHypo_KinFit(const DNeutralParticleHypothesis* locOrigHypo, DKinFitParticle* locKinFitParticle, double locPropagatedRFTime)
712 {
713  auto locHypoIterator = dKinFitNeutralHypoMap.find(locKinFitParticle);
714  if(locHypoIterator != dKinFitNeutralHypoMap.end())
715  return locHypoIterator->second;
716 
717  auto locNewHypo = dNeutralParticleHypothesisFactory->Get_Resource();
718  dCreated_NeutralHypo.push_back(locNewHypo);
719  dKinFitNeutralHypoMap.emplace(locKinFitParticle, locNewHypo);
720  locNewHypo->setPID(locOrigHypo->PID());
721  locNewHypo->Set_NeutralShower(locOrigHypo->Get_NeutralShower());
722 
723  //p3 & v3
724  auto locWasNeutralShowerInFit = (locKinFitParticle->Get_EParamIndex() >= 0);
725  TVector3 locFitMomentum = locKinFitParticle->Get_Momentum();
726  TVector3 locFitVertex = locWasNeutralShowerInFit ? locKinFitParticle->Get_CommonVertex() : locKinFitParticle->Get_Position();
727  locNewHypo->setMomentum(DVector3(locFitMomentum.X(), locFitMomentum.Y(), locFitMomentum.Z()));
728  locNewHypo->setPosition(DVector3(locFitVertex.X(), locFitVertex.Y(), locFitVertex.Z()));
729 
730  //t & error matrix
731  auto locTime = locWasNeutralShowerInFit ? locKinFitParticle->Get_CommonTime() : locKinFitParticle->Get_Time();
732  locNewHypo->setTime(locTime);
733  locNewHypo->setErrorMatrix(locKinFitParticle->Get_CovarianceMatrix());
734 
735  //if timing was kinfit, there is no chisq to calculate: forced to correct time
736  //also, if vertex was not kinfit, no chisq to calc either: photon beta is still 1, no chisq for massive neutrals
737  //therefore, just use measured timing info (pre-kinfit)
738  if((locKinFitParticle->Get_CommonVxParamIndex() < 0) || (locKinFitParticle->Get_CommonTParamIndex() >= 0))
739  {
740  locNewHypo->Share_FromInput(locOrigHypo, true, false); //share timing but not kinematics
741  return locNewHypo;
742  }
743 
744  //update timing info
745  if(dDebugLevel >= 20)
746  cout << "orig hypo time, orig vertz, new hypo time, new hypo vertz, t0: " << locOrigHypo->time() << ", " << locOrigHypo->position().Z() << ", " << locNewHypo->time() << ", " << locNewHypo->position().Z() << ", " << locPropagatedRFTime << endl;
747  locNewHypo->Set_T0(locPropagatedRFTime, locOrigHypo->t0_err(), locOrigHypo->t0_detector());
748 
749  // Calculate DNeutralParticleHypothesis FOM
750  unsigned int locNDF = 0;
751  double locChiSq = 0.0;
752  double locFOM = -1.0; //undefined for non-photons
753  if(locNewHypo->PID() == Gamma)
754  {
755  double locTimePull = 0.0;
756  //for this calc: if rf time part of timing constraint, don't use locKinFitParticle->Get_CommonTime() for chisq calc!!!
757  locChiSq = dParticleID->Calc_TimingChiSq(locNewHypo, locNDF, locTimePull);
758  locFOM = TMath::Prob(locChiSq, locNDF);
759  }
760  locNewHypo->Set_ChiSq_Overall(locChiSq, locNDF, locFOM);
761 
762  return locNewHypo;
763 }
764 
765 DKinematicData* DParticleComboCreator::Build_KinematicData(const DKinFitResults* locKinFitResults, DKinFitParticle* locKinFitParticle, DLorentzVector locSpacetimeVertex, bool locProductionVertexFlag)
766 {
767  auto locKinematicData = dResourcePool_KinematicData.Get_Resource();
768  dCreated_KinematicData.push_back(locKinematicData);
769  auto locPID = PDGtoPType(locKinFitParticle->Get_PID());
770  locKinematicData->setPID(locPID);
771 
772  //want: production vs decay vertex
773  //p4 & position defined at: production vs decay vertex
774  if((locProductionVertexFlag == locKinFitParticle->Get_VertexP4AtProductionVertex()) || (locKinFitParticle->Get_VxParamIndex() < 0) || !IsDetachedVertex(locPID))
775  {
776  locKinematicData->setMomentum(DVector3(locKinFitParticle->Get_Momentum().X(),locKinFitParticle->Get_Momentum().Y(),locKinFitParticle->Get_Momentum().Z()));
777  if(locKinFitParticle->Get_VxParamIndex() < 0) //vertex not fit
778  locKinematicData->setPosition(locSpacetimeVertex.Vect());
779  else
780  {
781  auto locVertex = locKinFitParticle->Get_Position();
782  locKinematicData->setPosition(DVector3(locVertex.X(), locVertex.Y(), locVertex.Z()));
783  }
784  if(locKinFitParticle->Get_TParamIndex() < 0) //time not fit
785  locKinematicData->setTime(locSpacetimeVertex.T());
786  else
787  locKinematicData->setTime(locKinFitParticle->Get_Time());
788  locKinematicData->setErrorMatrix(locKinFitParticle->Get_CovarianceMatrix());
789  }
790  else
791  dKinFitUtils->Propagate_TrackInfoToCommonVertex(locKinematicData, locKinFitParticle, &locKinFitResults->Get_VXi());
792 
793  //We are NOT propagating the error matrix if it's at the wrong vertex!
794  return locKinematicData;
795 }
796 
798 {
799  deque<pair<const DMCThrown*, deque<const DMCThrown*> > > locThrownSteps;
800  if(dAnalysisUtilities == nullptr)
801  locEventLoop->GetSingle(dAnalysisUtilities);
802  dAnalysisUtilities->Get_ThrownParticleSteps(locEventLoop, locThrownSteps);
803  if(locThrownSteps.empty())
804  return nullptr;
805 
806  vector<const DReaction*> locReactions;
807  locEventLoop->Get(locReactions, "Thrown");
808  return Build_ThrownCombo(locEventLoop, locReactions[0], locThrownSteps);
809 }
810 
811 const DParticleCombo* DParticleComboCreator::Build_ThrownCombo(JEventLoop* locEventLoop, const DReaction* locThrownReaction, deque<pair<const DMCThrown*, deque<const DMCThrown*> > >& locThrownSteps)
812 {
813  auto locThrownComboTuple = std::make_tuple((const DReactionVertexInfo*)nullptr, (const DSourceCombo*)nullptr, (const DKinematicData*)nullptr, 1, true);
814  auto locComboMapIterator = dComboMap.find(locThrownComboTuple);
815  if(locComboMapIterator != dComboMap.end())
816  return locComboMapIterator->second;
817 
818  vector<const DMCReaction*> locMCReactions;
819  locEventLoop->Get(locMCReactions);
820 
821  vector<const DEventRFBunch*> locEventRFBunches;
822  locEventLoop->Get(locEventRFBunches, "Thrown");
823 
824  auto locParticleCombo = Get_ParticleComboResource();
825  auto locParticleComboStep = Get_ParticleComboStepResource();
826  locParticleCombo->Set_EventRFBunch(locEventRFBunches[0]);
827 
828  locParticleComboStep->Set_InitialParticle(&locMCReactions[0]->beam);
829  locParticleComboStep->Set_SpacetimeVertex(DLorentzVector(locMCReactions[0]->beam.position(), locMCReactions[0]->beam.time()));
830 
831  for(size_t loc_i = 0; loc_i < locThrownSteps.size(); ++loc_i)
832  {
833  if(loc_i != 0) //else beam & target already set
834  {
835  auto locMCThrown = locThrownSteps[loc_i].first;
836  locParticleComboStep = Get_ParticleComboStepResource();
837 
838  int locInitialParticleDecayFromStepIndex = -1; //the step where this particle is produced at
839  for(size_t loc_j = 0; loc_j < loc_i; ++loc_j)
840  {
841  for(size_t loc_k = 0; loc_k < locThrownSteps[loc_j].second.size(); ++loc_k)
842  {
843  if(locMCThrown != locThrownSteps[loc_j].second[loc_k])
844  continue;
845  locInitialParticleDecayFromStepIndex = loc_j;
846  break;
847  }
848  if(locInitialParticleDecayFromStepIndex != -1)
849  break;
850  }
851  locParticleComboStep->Set_InitialParticle(locMCThrown);
852  locParticleComboStep->Set_SpacetimeVertex(DLorentzVector(locMCThrown->position(), locMCThrown->time()));
853  }
854  for(size_t loc_j = 0; loc_j < locThrownSteps[loc_i].second.size(); ++loc_j)
855  locParticleComboStep->Add_FinalParticle(locThrownSteps[loc_i].second[loc_j]);
856  locParticleCombo->Add_ParticleComboStep(locParticleComboStep);
857  }
858 
859  dComboMap.emplace(locThrownComboTuple, locParticleCombo);
860  return locParticleCombo;
861 }
862 
863 }
DParticleComboCreator(JEventLoop *locEventLoop, const DSourceComboer *locSourceComboer, DSourceComboTimeHandler *locSourceComboTimeHandler, const DSourceComboVertexer *locSourceComboVertexer)
unsigned int dCounter
Definition: DBeamPhoton.h:18
int Get_PID(void) const
void Set_UpdateCovarianceMatricesFlag(bool locUpdateCovarianceMatricesFlag)
Definition: DKinFitUtils.h:52
char Get_TParamIndex(void) const
void Set_InitialKinFitParticle(std::shared_ptr< const DKinFitParticle > locInitialKinFitParticle)
char Get_CommonVxParamIndex(void) const
DResourcePool< DKinematicData > dResourcePool_KinematicData
bool Get_CreateNeutralErrorMatrixFlag_Combo(const DReactionVertexInfo *locReactionVertexInfo, DKinFitType locKinFitType)
const DReaction * Get_Reaction(void) const
#define SPEED_OF_LIGHT
pair< int, int > Get_InitialParticleDecayFromIndices(const DReaction *locReaction, int locStepIndex)
Definition: DReaction.cc:93
void Recycle_Resources(vector< const DBeamPhoton * > &locBeams)
size_t Get_NumParticleComboSteps(void) const
DKinFitType Get_KinFitType(void) const
Definition: DReaction.h:79
DResourcePool< DParticleComboStep > dResourcePool_ParticleComboStep
unordered_map< const DKinFitParticle *, DNeutralParticleHypothesis * > dKinFitNeutralHypoMap
TVector3 DVector3
Definition: DVector3.h:14
DLorentzVector Get_ChargedPOCAToVertexX4(const DChargedTrackHypothesis *locHypothesis, bool locIsProductionVertex, const DSourceCombo *locReactionFullCombo, const DSourceCombo *locVertexPrimaryCombo, const DKinematicData *locBeamPhoton, bool locIsCombo2ndVertex, DVector3 locVertex)
const DBeamPhoton * Create_BeamPhoton_KinFit(const DBeamPhoton *locBeamPhoton, const DKinFitParticle *locKinFitParticle, const DLorentzVector &locSpacetimeVertex)
map< tuple< DReactionStep, const DSourceCombo *, bool, bool, const DSourceCombo *, const DKinematicData * >, const DParticleComboStep * > dComboStepMap
DChargedTrackHypothesis_factory * dChargedTrackHypothesisFactory
const DVector3 & position(void) const
const DParticleCombo * Build_ThrownCombo(JEventLoop *locEventLoop)
static Particle_t PDGtoPType(int locPDG_PID)
const DParticleCombo * Create_KinFitCombo_NewCombo(const DParticleCombo *locOrigCombo, const DReaction *locReaction, const DKinFitResults *locKinFitResults, const shared_ptr< const DKinFitChain > &locKinFitChain)
map< tuple< const DChargedTrack *, Particle_t, int, bool, const DSourceCombo *, const DSourceCombo *, const DKinematicData * >, const DChargedTrackHypothesis * > dChargedHypoMap
static unsigned short int IsDetachedVertex(Particle_t p)
Definition: particleType.h:817
bool Propagate_TrackInfoToCommonVertex(DKinematicData *locKinematicData, DKinFitParticle *locKinFitParticle, const TMatrixDSym *locVXi)
const DChargedTrackHypothesis * Create_ChargedHypo(const DChargedTrack *locChargedTrack, Particle_t locPID, double locPropagatedRFTime, bool locIsProductionVertex, const DSourceCombo *locReactionFullCombo, const DSourceCombo *locVertexPrimaryFullCombo, const DKinematicData *locBeamParticle, DVector3 locVertex)
TLorentzVector DLorentzVector
DVector3 Get_PrimaryVertex(const DReactionVertexInfo *locReactionVertexInfo, const DSourceCombo *locReactionCombo, const DKinematicData *locBeamParticle) const
DParticleComboStep * Get_ParticleComboStepResource(void)
const DEventRFBunch * Get_EventRFBunch(void) const
static int ParticleCharge(Particle_t p)
const DNeutralShower * Get_NeutralShower(void) const
const DChargedTrackHypothesis * Get_Hypothesis(Particle_t locPID) const
Definition: DChargedTrack.h:59
map< tuple< const DReactionVertexInfo *, const DSourceCombo *, const DKinematicData *, int, bool >, DParticleCombo * > dComboMap
DNeutralParticleHypothesis_factory * dNeutralParticleHypothesisFactory
vector< DParticleComboStep * > dCreated_ParticleComboStep
vector< DParticleCombo * > dCreated_ParticleCombo
DKinematicData * Build_KinematicData(const DKinFitResults *locKinFitResults, DKinFitParticle *locKinFitParticle, DLorentzVector locSpacetimeVertex, bool locProductionVertexFlag)
const DAnalysisUtilities * dAnalysisUtilities
map< tuple< const DNeutralShower *, Particle_t, int, bool, bool, const DSourceCombo *, const DSourceCombo *, const DKinematicData * >, const DNeutralParticleHypothesis * > dNeutralHypoMap
vector< DChargedTrackHypothesis * > dCreated_ChargedHypo
unordered_map< int, const DEventRFBunch * > dRFBunchMap
double time(void) const
void Calc_ChargedPIDFOM(DChargedTrackHypothesis *locChargedTrackHypothesis) const
DType * Get_Resource(void)
void Reset(void)
Definition: DEventRFBunch.h:43
size_t Get_NumObjectsAllThreads(void) const
vector< const DKinematicData * > Get_DecayChainParticles_Measured(const DReaction *locReaction, int locStepIndex) const
Particle_t Get_InitialPID(void) const
Definition: DReactionStep.h:81
bool Search_ForParticleInDecay(const shared_ptr< const DKinFitChain > &locKinFitChain, size_t locStepToSearch, const shared_ptr< DKinFitParticle > &locParticleToFind) const
unordered_map< const DReactionVertexInfo *, bool > dDanglingNeutralsFlagMap
const DNeutralParticleHypothesis * Create_NeutralHypo_KinFit(const DNeutralParticleHypothesis *locOrigHypo, DKinFitParticle *locKinFitParticle, double locPropagatedRFTime)
DSourceComboTimeHandler * dSourceComboTimeHandler
const DSourceComboVertexer * dSourceComboVertexer
set< shared_ptr< DKinFitParticle > > Get_OutputKinFitParticles(void) const
vector< DBeamPhoton * > dCreated_BeamPhoton
DGeometry * GetDGeometry(unsigned int run_number)
DChargedTrackHypothesis * Get_Resource(void)
static unsigned short int IsFixedMass(Particle_t p)
Definition: particleType.h:743
void Set_InitialParticle(const DKinematicData *locInitialParticle)
DResourcePool< DParticleCombo > dResourcePool_ParticleCombo
const JObject * Get_SourceParticle_ThisStep(const DSourceCombo *locSourceCombo, Particle_t locPID, size_t locInstance, size_t &locPIDCountSoFar)
Definition: DSourceCombo.h:534
vector< DNeutralParticleHypothesis * > dCreated_NeutralHypo
DLorentzVector Get_SpacetimeVertex(void) const
shared_ptr< DKinFitParticle > Get_OutputKinFitParticle(const JObject *locSourceObject) const
void Get_ThrownParticleSteps(JEventLoop *locEventLoop, deque< pair< const DMCThrown *, deque< const DMCThrown * > > > &locThrownSteps) const
static double ParticleMass(Particle_t p)
vector< const DReactionStepVertexInfo * > Get_StepVertexInfos(void) const
shared_ptr< DKinFitParticle > Get_DecayingParticle(const DReaction *locReaction, const DParticleCombo *locOldParticleCombo, size_t locComboStepIndex, const shared_ptr< const DKinFitChain > &locKinFitChain, const DKinFitResults *locKinFitResults) const
double Calc_TimingChiSq(const DChargedTrackHypothesis *locChargedHypo, unsigned int &locNDF, double &locTimingPull) const
char Get_EParamIndex(void) const
char Get_VxParamIndex(void) const
unordered_map< const DKinFitParticle *, DBeamPhoton * > dKinFitBeamPhotonMap
DetectorSystem_t dSystem
Definition: DBeamPhoton.h:19
shared_ptr< const TMatrixFSym > Get_CovarianceMatrix(void) const
unordered_map< const DKinFitParticle *, DChargedTrackHypothesis * > dKinFitChargedHypoMap
double Calc_RFTime(int locNumRFBunchShifts) const
double Get_CommonTime(void) const
vector< DKinematicData * > dCreated_KinematicData
char Get_CommonTParamIndex(void) const
const TMatrixDSym & Get_VXi(void) const
void Recycle_Hypotheses(vector< const DChargedTrackHypothesis * > &locHypos)
DNeutralParticleHypothesis * Get_Resource(void)
bool Get_KinFitUpdateCovarianceMatricesFlag(void) const
Definition: DReaction.h:80
size_t Get_NumObjectsAllThreads(void) const
const DChargedTrackHypothesis * Create_ChargedHypo_KinFit(const DChargedTrack *locChargedTrack, Particle_t locPID, const DKinFitParticle *locKinFitParticle, double locPropagatedRFTime)
const DEventRFBunch * Get_InitialEventRFBunch(void) const
const DReactionStep * Get_ReactionStep(size_t locStepIndex) const
Definition: DReaction.h:84
void Set_ControlParams(size_t locGetBatchSize, size_t locNumToAllocateAtOnce, size_t locMaxLocalPoolSize)
int Get_DecayStepIndex(const DReaction *locReaction, size_t locStepIndex, size_t locParticleIndex)
Definition: DReaction.cc:135
TVector3 Get_Position(void) const
void Set_SpacetimeVertex(const DLorentzVector &locSpacetimeVertex)
DetectorSystem_t t0_detector(void) const
void Set_SpacetimeVertex(const DReaction *locReaction, const DParticleCombo *locNewParticleCombo, const DParticleCombo *locOldParticleCombo, DParticleComboStep *locNewParticleComboStep, size_t locStepIndex, const DKinFitResults *locKinFitResults, const shared_ptr< const DKinFitChain > &locKinFitChain, double locOrigShiftedRFTime) const
const DParticleComboStep * Get_ParticleComboStep(size_t locStepIndex) const
double Get_Time(void) const
TVector3 Get_CommonVertex(void) const
DBeamPhoton_factory * dBeamPhotonfactory
bool GetTargetZ(double &z_target) const
z-location of center of target
Definition: DGeometry.cc:1933
DResourcePool< DEventRFBunch > dResourcePool_EventRFBunch
void Recycle_Hypotheses(vector< DNeutralParticleHypothesis * > &locHypos)
DBeamPhoton * Get_Resource(void)
Particle_t PID(void) const
TVector3 Get_Momentum(void) const
bool Get_VertexP4AtProductionVertex(void) const
void Set_DecayingParticles(const DReaction *locReaction, const DParticleCombo *locNewParticleCombo, const DParticleCombo *locOldParticleCombo, size_t locStepIndex, DParticleComboStep *locNewParticleComboStep, const shared_ptr< const DKinFitChain > &locKinFitChain, const DKinFitResults *locKinFitResults)
void Print_SourceCombo(const DSourceCombo *locCombo, unsigned char locNumTabs=0)
Definition: DSourceCombo.h:346
Particle_t
Definition: particleType.h:12
void Recycle(const DType *locResource)
DParticleCombo * Get_ParticleComboResource(void)