Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DReactionVertexInfo_factory.cc
Go to the documentation of this file.
2 
3 using namespace std;
4 using namespace jana;
5 using namespace DAnalysis;
6 
7 jerror_t DReactionVertexInfo_factory::init(void)
8 {
9  // This is so that the created objects persist throughout the life of the program instead of being cleared each event.
10  SetFactoryFlag(PERSISTANT);
11  dResourcePool_ReactionStepVertexInfo = new DResourcePool<DReactionStepVertexInfo>();
12 
13  gPARMS->SetDefaultParameter("VERTEXINFO:DEBUG_LEVEL", dDebugLevel);
14 
15  return NOERROR;
16 }
17 
18 jerror_t DReactionVertexInfo_factory::evnt(JEventLoop *locEventLoop, uint64_t locEventNumber)
19 {
20  dKinFitUtils = new DKinFitUtils_GlueX(locEventLoop);
21 
22  auto locReactions = DAnalysis::Get_Reactions(locEventLoop);
23  for(auto locReactionIterator = locReactions.begin(); locReactionIterator != locReactions.end(); ++locReactionIterator)
24  {
25  auto locReaction = *locReactionIterator;
26 
27  //see if a reaction that we've already done has an identical channel to this
28  auto Equality_Checker = [&locReaction](const pair<const DReaction*, DReactionVertexInfo*>& locReactionPair) -> bool
29  {return DAnalysis::Check_ChannelEquality(locReaction, locReactionPair.first, true);};
30 
31  //do the check
32  auto locSearchIterator = std::find_if(dVertexInfoMap.begin(), dVertexInfoMap.end(), Equality_Checker);
33  if(locSearchIterator != dVertexInfoMap.end())
34  {
35  //not unique! register reaction and move on
36  auto locVertexInfo = locSearchIterator->second;
37  locVertexInfo->Add_Reaction(locReaction);
38  continue;
39  }
40 
41  //unique channel: create vertex info
42  auto locVertexInfo = Build_VertexInfo(locReaction);
43  if(dDebugLevel > 0)
44  {
45  cout << "CREATED REACTION VERTEX INFO:" << endl;
47  }
48 
49  _data.push_back(locVertexInfo);
50  dVertexInfoMap.emplace(locReaction, locVertexInfo);
51  }
52 
53  return NOERROR;
54 }
55 
56 DReactionVertexInfo* DReactionVertexInfo_factory::Build_VertexInfo(const DReaction* locReaction)
57 {
58  set<size_t> locStepIndexSet;
59  vector<DReactionStepVertexInfo*> locVertexInfos;
60  for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
61  {
62  if(locStepIndexSet.find(loc_i) != locStepIndexSet.end())
63  continue; //already did this step
64 
65  //Start a new vertex, and save when done
66  auto locVertexInfo = Setup_VertexInfo(locReaction, loc_i, nullptr);
67  locVertexInfos.push_back(locVertexInfo);
68 
69  auto locStepIndexVector = locVertexInfo->Get_StepIndices();
70  std::copy(locStepIndexVector.begin(), locStepIndexVector.end(), std::inserter(locStepIndexSet, locStepIndexSet.end()));
71 
72  Group_VertexParticles(locVertexInfo);
73  if(dDebugLevel > 0)
74  {
75  cout << "Grouped vertex info: " << endl;
77  }
78  }
79 
80  //work in reverse: try to build decaying particles out of decay products first, rather than missing mass
81  std::reverse(std::begin(locVertexInfos), std::end(locVertexInfos));
82 
83  //results are sorted by dependency order
84  locVertexInfos = Link_Vertices(locReaction, locVertexInfos, false);
85  if(dDebugLevel > 0)
86  {
87  cout << "Linked vertex infos, fitflag = false: " << endl;
88  for(auto& locVertexInfo : locVertexInfos)
90  }
91  locVertexInfos = Link_Vertices(locReaction, locVertexInfos, true);
92  return new DReactionVertexInfo(locReaction, locVertexInfos);
93 }
94 
95 DReactionStepVertexInfo* DReactionVertexInfo_factory::Setup_VertexInfo(const DReaction* locReaction, size_t locStepIndex, DReactionStepVertexInfo* locVertexInfo)
96 {
97  //create/update vertex info
98  if(locVertexInfo == nullptr)
99  {
100  locVertexInfo = dResourcePool_ReactionStepVertexInfo->Get_Resource();
101  locVertexInfo->Reset();
102  locVertexInfo->Set_Members(locReaction, locStepIndex);
103  }
104  else
105  locVertexInfo->Add_ReactionStep(locStepIndex);
106 
107  //loop over final particles: add to the vertex constraint, dive through decaying particles that decay in-place
108  //if decaying in-place: don't add (would add to constraint, but not here (purely internal))
109  auto locReactionStep = locReaction->Get_ReactionStep(locStepIndex);
110  if(locReactionStep->Get_IsInclusiveFlag())
111  locVertexInfo->Set_IsInclusiveVertexFlag(true);
112  for(size_t loc_i = 0; loc_i < locReactionStep->Get_NumFinalPIDs(); ++loc_i)
113  {
114  //check if particle decays, and if so, if in-place
115  auto locDecayStepIndex = Get_DecayStepIndex(locReaction, locStepIndex, loc_i);
116  auto locPID = locReactionStep->Get_FinalPID(loc_i);
117  if((locDecayStepIndex > 0) && !IsDetachedVertex(locPID)) //yes: combine with the decay products
118  Setup_VertexInfo(locReaction, locDecayStepIndex, locVertexInfo);
119  }
120 
121  return locVertexInfo;
122 }
123 
124 void DReactionVertexInfo_factory::Group_VertexParticles(DReactionStepVertexInfo* locVertexInfo)
125 {
126  auto locReaction = locVertexInfo->Get_Reaction();
127  auto locStepIndices = locVertexInfo->Get_StepIndices();
128  vector<pair<int, int>> locDecayingParticles, locOnlyConstrainTimeParticles;
129  vector<pair<int, int>> locFullConstrainParticles_Fit, locNoConstrainParticles_Fit, locFullConstrainParticles_Recon, locNoConstrainParticles_Recon;
130 
131  //Decaying: Only those that can conceivably be used to constrain: All unless dLinkVerticesFlag disabled (then none)
132  bool locFirstStepFlag = true;
133  for(auto locStepIndex : locStepIndices)
134  {
135  auto locStep = locReaction->Get_ReactionStep(locStepIndex);
136 
137  //beam
138  if((locStepIndex == 0) && Get_IsFirstStepBeam(locReaction)) //production
139  {
140  //beam 1
141  if(locStep->Get_IsBeamMissingFlag())
142  {
143  locNoConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
144  locNoConstrainParticles_Recon.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
145  }
146  else
147  {
148  locFullConstrainParticles_Recon.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
149  if(dKinFitUtils->Get_IncludeBeamlineInVertexFitFlag())
150  locFullConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
151  else //not in fit!
152  locNoConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
153  }
154 
155  //beam 2
156  if(locStep->Get_SecondBeamPID() != Unknown)
157  {
158  if(locStep->Get_IsBeamMissingFlag())
159  {
160  locNoConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_SecondBeam());
161  locNoConstrainParticles_Recon.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_SecondBeam());
162  }
163  else
164  {
165  locFullConstrainParticles_Recon.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_SecondBeam());
166  if(dKinFitUtils->Get_IncludeBeamlineInVertexFitFlag())
167  locFullConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_SecondBeam());
168  else //not in fit!
169  locNoConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_SecondBeam());
170  }
171  }
172  }
173  else if(locFirstStepFlag) //decaying //if false: not detached: only save once at this vertex (in final state), not twice!!
174  locDecayingParticles.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Initial());
175 
176  //target
177  if(locStep->Get_TargetPID() != Unknown) //target
178  {
179  locNoConstrainParticles_Fit.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Target());
180  locNoConstrainParticles_Recon.emplace_back(locStepIndex, DReactionStep::Get_ParticleIndex_Target());
181  }
182 
183  //final state
184  auto locFinalPIDs = locStep->Get_FinalPIDs();
185  for(size_t loc_i = 0; loc_i < locFinalPIDs.size(); ++loc_i)
186  {
187  int locDecayStepIndex = Get_DecayStepIndex(locReaction, locStepIndex, loc_i);
188 
189  if(locDecayStepIndex >= 0) //decaying
190  locDecayingParticles.emplace_back(locStepIndex, loc_i);
191  else if(int(loc_i) == locStep->Get_MissingParticleIndex()) //missing
192  {
193  locNoConstrainParticles_Fit.emplace_back(locStepIndex, loc_i);
194  locNoConstrainParticles_Recon.emplace_back(locStepIndex, loc_i);
195  }
196  else if(ParticleCharge(locFinalPIDs[loc_i]) != 0) //detected charged
197  {
198  locFullConstrainParticles_Fit.emplace_back(locStepIndex, loc_i);
199  locFullConstrainParticles_Recon.emplace_back(locStepIndex, loc_i);
200  }
201  else if(locFinalPIDs[loc_i] == Gamma) //photon
202  locOnlyConstrainTimeParticles.emplace_back(locStepIndex, loc_i);
203  else //massive neutrals can't constrain position or time!
204  {
205  locNoConstrainParticles_Fit.emplace_back(locStepIndex, loc_i);
206  locNoConstrainParticles_Recon.emplace_back(locStepIndex, loc_i);
207  }
208  }
209 
210  locFirstStepFlag = false;
211  }
212 
213  locVertexInfo->Set_ParticleIndices(true, locFullConstrainParticles_Fit, locDecayingParticles, locOnlyConstrainTimeParticles, locNoConstrainParticles_Fit);
214  locVertexInfo->Set_ParticleIndices(false, locFullConstrainParticles_Recon, locDecayingParticles, locOnlyConstrainTimeParticles, locNoConstrainParticles_Recon);
215 }
216 
217 vector<DReactionStepVertexInfo*> DReactionVertexInfo_factory::Link_Vertices(const DReaction* locReaction, vector<DReactionStepVertexInfo*> locVertexInfos, bool locFitFlag) const
218 {
219  //loop over vertex-constraints-to-sort:
220  //find which constraints decaying particles should be defined-by/constrained-to
221  //find order in which constraints need to be constrained
222 
223  bool locProgessMadeFlag = false;
224  bool locTryMissingParticleVertexFlag = false;
225  auto locVertexIterator = locVertexInfos.begin();
226  map<pair<int, int>, DReactionStepVertexInfo*> locDefinedDecayingParticles;
227  vector<DReactionStepVertexInfo*> locSortedVertexInfos; //sorted by dependency
228  while(!locVertexInfos.empty())
229  {
230  if(locVertexIterator == locVertexInfos.end())
231  {
232  //made a full loop through
233  if(!locProgessMadeFlag)
234  {
235  if(locTryMissingParticleVertexFlag)
236  break; //no progress made: cannot constrain remaining vertices
237  locTryMissingParticleVertexFlag = true; //try this now
238  if(dDebugLevel > 0)
239  cout << "try another loop, using missing mass" << endl;
240  }
241 
242  //reset for next pass through
243  locVertexIterator = locVertexInfos.begin();
244  locProgessMadeFlag = false;
245  continue;
246  }
247 
248  //Try a vertex info
249  auto locVertexInfo = *locVertexIterator;
250  if(!locTryMissingParticleVertexFlag && !locVertexInfo->Get_MissingParticles().empty())
251  {
252  ++locVertexIterator; //try again later
253  continue; //first try to reconstruct decaying particles without using the missing mass
254  }
255 
256  locProgessMadeFlag = Associate_DecayingParticles(locFitFlag, true, locVertexInfo, locDefinedDecayingParticles);
257  if(!locProgessMadeFlag)
258  ++locVertexIterator; //try again later
259  else //Erase this vertex from future consideration
260  {
261  locVertexIterator = locVertexInfos.erase(locVertexIterator);
262  locSortedVertexInfos.push_back(locVertexInfo);
263  }
264  }
265 
266  //the remaining vertices are dangling: not enough info to constrain
267  //save dangling info
268  for(auto locVertexInfo : locVertexInfos)
269  {
270  Associate_DecayingParticles(locFitFlag, false, locVertexInfo, locDefinedDecayingParticles);
271  locSortedVertexInfos.push_back(locVertexInfo);
272  }
273 
274  //set parent vertex infos
275  unordered_map<size_t, DReactionStepVertexInfo*> locVertexInfoMap;
276  for(auto locVertexInfo : locSortedVertexInfos)
277  {
278  for(auto locStepIndex : locVertexInfo->Get_StepIndices())
279  locVertexInfoMap[locStepIndex] = locVertexInfo;
280  }
281  for(auto locVertexInfo : locSortedVertexInfos)
282  {
283  auto locPrimaryStepIndex = locVertexInfo->Get_StepIndices().front();
284  if(locPrimaryStepIndex == 0)
285  continue; //for 0 is nullptr, but is nullptr by default
286  auto locParentStepIndex = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locPrimaryStepIndex).first;
287  locVertexInfo->Set_ParentVertexInfo(locVertexInfoMap[locParentStepIndex]);
288  }
289 
290  return locSortedVertexInfos;
291 }
292 
293 bool DReactionVertexInfo_factory::Associate_DecayingParticles(bool locFitFlag, bool locLinkingFlag, DReactionStepVertexInfo* locVertexInfo, map<pair<int, int>, DReactionStepVertexInfo*>& locDefinedDecayingParticles) const
294 {
295  if(dDebugLevel > 0)
296  {
297  cout << "Associate_DecayingParticles: fit flag, link flag, info, #defined decaying: " << locFitFlag << ", " << locLinkingFlag << ", " << locVertexInfo << ", " << locDefinedDecayingParticles.size() << endl;
299  }
300 
301  //find which decaying particles at this vertex have/haven't been previously defined
302  vector<pair<int, int>> locNoConstrainDecayingParticles;
303  map<pair<int, int>, const DReactionStepVertexInfo*> locConstrainingDecayingParticles;
304  auto locDecayingParticles = locVertexInfo->Get_DecayingParticles();
305  for(auto locParticlePair : locDecayingParticles)
306  {
307  auto locIterator = locDefinedDecayingParticles.find(locParticlePair);
308  if(locIterator != locDefinedDecayingParticles.end())
309  locConstrainingDecayingParticles.emplace(*locIterator);
310  else //not found
311  locNoConstrainDecayingParticles.emplace_back(locParticlePair);
312  }
313  if(dDebugLevel > 0)
314  cout << "# decaying particles, constrain/no-constrain: " << locConstrainingDecayingParticles.size() << ", " << locNoConstrainDecayingParticles.size() << endl;
315 
316  //tricky: beamline can be used to find vertex, but not in a kinfit (because the errors are zero)
317  //so, if a production vertex has only one charged/known-decaying track, then:
318  //it's vertex position can be found: not dangling
319  //it's vertex position cannot be fit (not enough constraints)
320  //have a separate flag:
321  //enough tracks for kinfit vs. enough tracks to determine separate vertex
322 
323  //see if enough tracks //if not linking, then don't need "enough": will register as dangling vertex instead
324  auto locNumConstrainingParticles = locConstrainingDecayingParticles.size() + locVertexInfo->Get_FullConstrainParticles(locFitFlag).size();
325  if(locFitFlag)
326  locVertexInfo->Set_FittableVertexFlag((locNumConstrainingParticles >= 2));
327  if(dDebugLevel > 0)
328  cout << "#constraining: " << locNumConstrainingParticles << endl;
329 
330  bool locEnoughTracksFlag = (locNumConstrainingParticles >= 2);
331  if(locLinkingFlag && !locEnoughTracksFlag)
332  return false; //trying to link vertices, not enough tracks yet. try again later
333 
334  //Save results
335  locVertexInfo->Register_DecayingParticleConstraints(locFitFlag, locNoConstrainDecayingParticles, locConstrainingDecayingParticles);
336  //each of the constraining decaying particles was a no-constrain at another vertex. set their vertex-info pointer to the new one
337  for(const auto& locMapPair : locConstrainingDecayingParticles)
338  {
339  auto locDefiningVertexInfo = const_cast<DReactionStepVertexInfo*>(locMapPair.second); //easier this way
340  locDefiningVertexInfo->Register_DecayingNoConstrainUseVertex(locFitFlag, locMapPair.first, locVertexInfo);
341  locDefinedDecayingParticles.erase(locMapPair.first); //can't use the same one twice
342  }
343 
344  if(!locLinkingFlag)
345  {
346  if(!locFitFlag)
347  locVertexInfo->Set_DanglingVertexFlag(true);
348  return false; //this is a dangling vertex, nothing further to do
349  }
350 
351  //The positions of these decaying particles are now defined: Can use to constrain vertices in later constraints
352  //However, we can only do so if their p4 is defined as well! It won't be if there's also a missing particle at this vertex
353  //since we need to match with particles in other constraints, save the OTHER index for the particle
354  //if was in initial state, save final-state pair. and vice versa
355  if(locVertexInfo->Get_IsInclusiveVertexFlag() || !locVertexInfo->Get_MissingParticles().empty())
356  return true; //missing particle: decaying p4 not defined! (have already tried defining it the other way (missing vs invariant) and couldn't)
357  auto locReaction = locVertexInfo->Get_Reaction();
358  for(auto locParticlePair : locNoConstrainDecayingParticles)
359  {
360  if(dDebugLevel > 0)
361  cout << "defined decaying particle indices: " << locParticlePair.first << ", " << locParticlePair.second << endl;
362  if(locParticlePair.second < 0) //was in initial state: save final state
363  {
364  auto locParticlePairToRegister = DAnalysis::Get_InitialParticleDecayFromIndices(locReaction, locParticlePair.first);
365  if(dDebugLevel > 0)
366  cout << "registering decaying particle indices: " << locParticlePairToRegister.first << ", " << locParticlePairToRegister.second << endl;
367  locDefinedDecayingParticles.emplace(locParticlePairToRegister, locVertexInfo);
368  }
369  else //was in final state: save initial state
370  {
371  int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locParticlePair.first, locParticlePair.second);
372  auto locParticlePairToRegister = std::make_pair(locDecayStepIndex, DReactionStep::Get_ParticleIndex_Initial());
373  if(dDebugLevel > 0)
374  cout << "registering decaying particle indices: " << locParticlePairToRegister.first << ", " << locParticlePairToRegister.second << endl;
375  locDefinedDecayingParticles.emplace(locParticlePairToRegister, locVertexInfo);
376  }
377  }
378 
379  return true;
380 }
381 
vector< pair< int, int > > Get_FullConstrainParticles(bool locFitFlag, DReactionState_t locState=d_EitherState, Charge_t locCharge=d_AllCharges, bool locIncludeDecayingFlag=true) const
bool Get_IsFirstStepBeam(const DReaction *locReaction)
Definition: DReaction.h:178
pair< int, int > Get_InitialParticleDecayFromIndices(const DReaction *locReaction, int locStepIndex)
Definition: DReaction.cc:93
void Register_DecayingNoConstrainUseVertex(bool locFitFlag, const pair< int, int > &locDecayingNoConstrainPair, const DReactionStepVertexInfo *locVertexInfo)
bool Check_ChannelEquality(const DReaction *lhs, const DReaction *rhs, bool locSameOrderFlag=true, bool locRightSubsetOfLeftFlag=false)
Definition: DReaction.h:185
vector< const DReaction * > Get_Reactions(JEventLoop *locEventLoop)
Definition: DReaction.cc:218
void Set_Members(const DReaction *locReaction, size_t locStartStepIndex)
void Print_ReactionStepVertexInfo(const DReactionStepVertexInfo *locStepInfo)
void Set_FittableVertexFlag(bool locIsFittableVertexFlag)
static unsigned short int IsDetachedVertex(Particle_t p)
Definition: particleType.h:817
vector< pair< int, int > > Get_MissingParticles(DReactionState_t locState=d_EitherState, Charge_t locCharge=d_AllCharges) const
static int ParticleCharge(Particle_t p)
void Set_ParticleIndices(bool locFitFlag, const vector< pair< int, int >> &locFullConstrainParticles, const vector< pair< int, int >> &locDecayingParticles, const vector< pair< int, int >> &locOnlyConstrainTimeParticles, const vector< pair< int, int >> &locNoConstrainParticles)
void Print_ReactionVertexInfo(const DReactionVertexInfo *locReactionInfo)
void Set_IsInclusiveVertexFlag(bool locIsInclusiveVertexFlag)
const DReaction * Get_Reaction(void) const
void Add_ReactionStep(size_t locStepIndex)
void Set_DanglingVertexFlag(bool locIsDanglingVertexFlag)
void Register_DecayingParticleConstraints(bool locFitFlag, const vector< pair< int, int >> &locNoConstrainDecayingParticles, const map< pair< int, int >, const DReactionStepVertexInfo * > &locFullConstrainDecayingParticles)
vector< pair< int, int > > Get_DecayingParticles(DReactionState_t locState=d_EitherState, Charge_t locCharge=d_AllCharges) const
const DReactionStep * Get_ReactionStep(size_t locStepIndex) const
Definition: DReaction.h:84
int Get_DecayStepIndex(const DReaction *locReaction, size_t locStepIndex, size_t locParticleIndex)
Definition: DReaction.cc:135
vector< size_t > Get_StepIndices(void) const
size_t Get_NumReactionSteps(void) const
Definition: DReaction.h:83