Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DSourceCombo.h
Go to the documentation of this file.
1 #ifndef DSourceCombo_h
2 #define DSourceCombo_h
3 
4 #include <map>
5 #include <vector>
6 #include <tuple>
7 #include <memory>
8 #include <algorithm>
9 
10 #include "JANA/JObject.h"
11 #include "JANA/JEventLoop.h"
12 
13 #include "particleType.h"
14 #include "DResettable.h"
15 
16 #include "PID/DNeutralShower.h"
17 
18 using namespace std;
19 using namespace jana;
20 
21 namespace DAnalysis
22 {
23 
24 /****************************************************** DEFINE LAMBDAS, USING STATEMENTS, DECLARE FUNCTIONS *******************************************************/
25 
26 //forward declarations
27 class DSourceComboInfo;
28 class DSourceCombo;
29 
30 //DSourceComboUse is what the combo is USED for (the decay of Particle_t (if Unknown then is just a grouping)
31 //signed char: vertex-z bin of the final state (combo contents)
32 //bool: true/false if has/doesn't-have missing decay product (is always false if decay pid == Unknown)
33 //last pid: Rescattering Target PID (target excluded for 1st step) //is always Unknown if decay pid == Unknown)
34 using DSourceComboUse = tuple<Particle_t, signed char, const DSourceComboInfo*, bool, Particle_t>; //e.g. Pi0, zbin, -> 2g, false, Unknown
35 using DSourceCombosByUse_Small = vector<pair<DSourceComboUse, vector<const DSourceCombo*>>>;
36 
37 //DECLARE NAMESPACE-SCOPE FUNCTIONS
38 vector<const JObject*> Get_SourceParticles(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, Particle_t locPID = Unknown);
39 vector<pair<Particle_t, const JObject*>> Get_SourceParticles_ThisVertex(const DSourceCombo* locSourceCombo, Charge_t locCharge = d_AllCharges);
40 vector<const DSourceCombo*> Get_SourceCombos_ThisVertex(const DSourceCombo* locSourceCombo);
41 vector<pair<DSourceComboUse, vector<const DSourceCombo*>>> Get_SourceCombosAndUses_ThisVertex(const DSourceCombo* locSourceCombo);
42 Charge_t Get_ChargeContent(const DSourceComboInfo* locSourceComboInfo);
43 bool Get_HasMassiveNeutrals(const DSourceComboInfo* locComboInfo);
44 const JObject* Get_SourceParticle_ThisStep(const DSourceCombo* locSourceCombo, Particle_t locPID, size_t locInstance, size_t& locPIDCountSoFar);
45 
46 /************************************************************** DEFINE CLASSES ***************************************************************/
47 
48 //In theory, for safety, dynamically-allocated objects should be stored in a shared_ptr
49 //However, the combos take a TON of memory, and a shared_ptr<T*> takes 3x the memory of a regular T* pointer
50 //The info objects will exist for the life of the program, and so don't need to be recycled to a resource pool.
51 //The combo objects will be recycled after every event into a resource pool.
52 
53 //If we REALLY need the memory, we can store these things in std::array instead of vector
54 //These classes would need to have template parameters for the array sizes, and have a common base class
55 //However, the base class would have to return either vectors (need to convert) or raw pointers (need bounds checking) instead of std::arrays (since type unknown to base class)
56 //So it would require more CPU.
57 
58 //THE MOST NUMBER OF PARTICLES OF A GIVEN TYPE IS 255 (# stored in unsigned char)
60 {
61  public:
62 
63  //FORWARD DECLARE COMPARISON STRUCTS
66 
67  //CONSTRUCTOR
68  DSourceComboInfo(void) = delete;
69  DSourceComboInfo(const vector<pair<Particle_t, unsigned char>>& locNumParticles, const vector<pair<DSourceComboUse, unsigned char>>& locFurtherDecays = {});
70 
71  //OPERATORS
72  bool operator< (const DSourceComboInfo& rhs) const;
73 
74  //GET MEMBERS
75  vector<pair<Particle_t, unsigned char>> Get_NumParticles(bool locEntireChainFlag = false) const;
76  vector<pair<DSourceComboUse, unsigned char>> Get_FurtherDecays(void) const{return dFurtherDecays;}
77 
78  //definitions of negative values for any particle index //in order such that operator< returns order expected for string (e.g. gp->...)
79  //Note: If the vertex is UnknowABLE, the bin for the parent vertex is chosen. If the production vertex is Unknowable, then the center of the target is used.
80  static signed char Get_VertexZIndex_OutOfRange(void){return -3;}
81  static signed char Get_VertexZIndex_ZIndependent(void){return -2;}
82  static signed char Get_VertexZIndex_Unknown(void){return -1;}
83 
84  private:
85 
86  //don't have decaying PID a direct member of this combo info
87  //e.g. for a 2g pair, it has no idea whether or not it came from a Pi0, an eta, through direct production, etc.
88  //this way, e.g., the 2g combos can be used for ANY of those possibilities, without creating new objects
89  //it is the responsibility of the containing object to know what the combos are used for: DSourceComboUse
90 
91  vector<pair<Particle_t, unsigned char>> dNumParticles;
92  vector<pair<DSourceComboUse, unsigned char>> dFurtherDecays; //unsigned char: # of (e.g.) pi0s, etc.
93 };
94 
95 inline bool operator<(const DSourceComboUse& lhs, const DSourceComboUse& rhs)
96 {
97  //this puts mixed-charge first, then fully-neutral, then fully-charged
98 
99  //first, special case of nullptr (guard against it)
100  if((std::get<2>(lhs) == nullptr) || (std::get<2>(rhs) == nullptr))
101  {
102  if(std::get<2>(lhs) != std::get<2>(rhs))
103  return (std::get<2>(lhs) == nullptr);
104  if(std::get<3>(lhs) != std::get<3>(rhs))
105  return (std::get<3>(lhs) < std::get<3>(rhs));
106  if(std::get<4>(lhs) != std::get<4>(rhs))
107  return (std::get<4>(lhs) < std::get<4>(rhs));
108 
109  if(std::get<0>(lhs) == std::get<0>(rhs))
110  {
111  if(std::get<1>(lhs) == std::get<1>(rhs))
112  return false;
113  else
114  return std::get<1>(lhs) > std::get<1>(rhs);
115  }
116  if(ParticleMass(std::get<0>(lhs)) == ParticleMass(std::get<0>(rhs)))
117  return std::get<0>(lhs) > std::get<0>(rhs);
118  return (ParticleMass(std::get<0>(lhs)) > ParticleMass(std::get<0>(rhs)));
119  }
120 
121  auto locChargeContent_LHS = Get_ChargeContent(std::get<2>(lhs));
122  auto locChargeContent_RHS = Get_ChargeContent(std::get<2>(rhs));
123  if(locChargeContent_LHS != locChargeContent_RHS)
124  return locChargeContent_LHS > locChargeContent_RHS;
125 
126  if(std::get<3>(lhs) != std::get<3>(rhs))
127  return (std::get<3>(lhs) < std::get<3>(rhs));
128  if(std::get<4>(lhs) != std::get<4>(rhs))
129  return (std::get<4>(lhs) < std::get<4>(rhs));
130 
131  //within each of those, it puts the most-massive particles first
132  if(std::get<0>(lhs) == std::get<0>(rhs))
133  {
134  if(std::get<1>(lhs) == std::get<1>(rhs))
135  return *std::get<2>(rhs) < *std::get<2>(lhs);
136  else
137  return std::get<1>(lhs) > std::get<1>(rhs);
138  }
139  if(ParticleMass(std::get<0>(lhs)) == ParticleMass(std::get<0>(rhs)))
140  return std::get<0>(lhs) > std::get<0>(rhs);
141  return (ParticleMass(std::get<0>(lhs)) > ParticleMass(std::get<0>(rhs)));
142 }
143 
145 {
146  bool operator()(const pair<Particle_t, unsigned char>& lhs, const pair<Particle_t, unsigned char>& rhs) const{return lhs.first < rhs.first;} //sort
147  bool operator()(const pair<Particle_t, unsigned char>& lhs, Particle_t rhs) const{return lhs.first < rhs;} //lookup
148  bool operator()(Particle_t lhs, const pair<Particle_t, unsigned char>& rhs) const{return lhs < rhs.first;} //lookup
149 };
150 
152 {
153  bool operator()(const pair<DSourceComboUse, unsigned char>& lhs, const pair<DSourceComboUse, unsigned char>& rhs) const{return DAnalysis::operator<(lhs.first, rhs.first);} //sort
154  bool operator()(const pair<DSourceComboUse, unsigned char>& lhs, DSourceComboUse rhs) const{return DAnalysis::operator<(lhs.first, rhs);} //lookup
155  bool operator()(DSourceComboUse lhs, const pair<DSourceComboUse, unsigned char>& rhs) const{return DAnalysis::operator<(lhs, rhs.first);} //lookup
156 };
157 
158 class DSourceCombo : public DResettable
159 {
160  public:
161 
162  //FORWARD DECLARE COMPARISON STRUCT
163  struct DCompare_FurtherDecays;
164 
165  //CONSTRUCTOR
166  DSourceCombo(void) = default;
167  DSourceCombo(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, const DSourceCombosByUse_Small& locFurtherDecayCombos, bool locIsZIndependent = false);
168 
169  //SET MEMBERS
170  void Set_Members(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, const DSourceCombosByUse_Small& locFurtherDecayCombos, bool locIsZIndependent = false);
171  void Reset(void);
172  void Release(void){Reset();};
173 
174  //GET MEMBERS
175  vector<pair<Particle_t, const JObject*>> Get_SourceParticles(bool locEntireChainFlag = false, Charge_t locCharge = d_AllCharges) const;
176  DSourceCombosByUse_Small Get_FurtherDecayCombos(void) const{return dFurtherDecayCombos;}
177  bool Get_IsComboingZIndependent(void) const{return dIsComboingZIndependent;}
178 
179  private:
180 
181  //FYI, if use PID is unknown: Vector is guaranteed to be size 1, and none of ITS further decays can have an unknown use PID
182  //Note: Either:
183  //1) The entire content is one PID
184  //2) There is at most one particle of each PID
185  //Otherwise, groupings of 2+ (e.g. 2pi-) will be in the further-decay section (X -> 2pi+)
186 
187  //particles & decays
188  vector<pair<Particle_t, const JObject*>> dSourceParticles; //original DNeutralShower or DChargedTrack
189  DSourceCombosByUse_Small dFurtherDecayCombos; //vector is e.g. size 3 if 3 pi0s needed
190 
191  //everything is z-dependent for massive neutrals.
192  //however the momentum is SO z-dependent, that we can't cut on it until the end when we have the final vertex, AFTER comboing
193  //a mere z-bin is not enough.
194  //So, as far as COMBOING is concerned, massive neutrals are Z-INDEPENDENT
195  bool dIsComboingZIndependent = false; //is false for BCAL photons
196 };
197 
199 {
200  bool operator()(const pair<DSourceComboUse, vector<const DSourceCombo*>>& lhs, const pair<DSourceComboUse, vector<const DSourceCombo*>>& rhs) const{return DAnalysis::operator<(lhs.first, rhs.first);} //sort
201  bool operator()(const pair<DSourceComboUse, vector<const DSourceCombo*>>& lhs, DSourceComboUse rhs) const{return DAnalysis::operator<(lhs.first, rhs);} //lookup
202  bool operator()(DSourceComboUse lhs, const pair<DSourceComboUse, vector<const DSourceCombo*>>& rhs) const{return DAnalysis::operator<(lhs, rhs.first);} //lookup
203 };
204 
206 {
207  //returns true if a particle WAS reused
208  bool operator()(const DSourceCombo* locCombo) const
209  {
210  auto locParticles = DAnalysis::Get_SourceParticles(locCombo->Get_SourceParticles(true), Unknown); //all pids
211  std::sort(locParticles.begin(), locParticles.end());
212  auto locUniqueIterator = std::unique(locParticles.begin(), locParticles.end());
213  return (locUniqueIterator != locParticles.end());
214  }
215 };
216 
217 /*********************************************************** INLINE MEMBER FUNCTION DEFINITIONS ************************************************************/
218 
219 inline DSourceComboInfo::DSourceComboInfo(const vector<pair<Particle_t, unsigned char>>& locNumParticles, const vector<pair<DSourceComboUse, unsigned char>>& locFurtherDecays) :
220  dNumParticles(locNumParticles), dFurtherDecays(locFurtherDecays)
221 {
222  std::sort(dNumParticles.begin(), dNumParticles.end(), DCompare_ParticlePairPIDs());
223  std::sort(dFurtherDecays.begin(), dFurtherDecays.end(), DCompare_FurtherDecays());
224 }
225 
226 inline bool DSourceComboInfo::operator< (const DSourceComboInfo& rhs) const
227 {
228  if(dNumParticles != rhs.dNumParticles)
229  return dNumParticles < rhs.dNumParticles;
230 
231  //check if maps have different sizes
232  if(dFurtherDecays.size() != rhs.dFurtherDecays.size())
233  return dFurtherDecays.size() < rhs.dFurtherDecays.size();
234 
235  //check if there's a mismatch between the maps
236  auto locMismachIterators = std::mismatch(dFurtherDecays.begin(), dFurtherDecays.end(), rhs.dFurtherDecays.begin());
237  if(locMismachIterators.first == dFurtherDecays.end())
238  return false; //maps are identical
239 
240  //check if keys are equal
241  if(locMismachIterators.first->first == locMismachIterators.second->first)
242  return locMismachIterators.first->second < locMismachIterators.second->second; //compare values
243  else
244  return locMismachIterators.first->first < locMismachIterators.second->first; //compare keys
245 }
246 
247 inline vector<pair<Particle_t, unsigned char>> DSourceComboInfo::Get_NumParticles(bool locEntireChainFlag) const
248 {
249  if(!locEntireChainFlag || dFurtherDecays.empty())
250  return dNumParticles;
251 
252  vector<pair<Particle_t, unsigned char>> locToReturnNumParticles = dNumParticles;
253  for(const auto& locDecayPair : dFurtherDecays)
254  {
255  const auto& locDecayComboInfo = std::get<2>(locDecayPair.first);
256  auto locNumDecayParticles = locDecayComboInfo->Get_NumParticles(true);
257 
258  for(const auto& locParticlePair : locNumDecayParticles)
259  {
260  //search through locToReturnNumParticles to retrieve the iterator corresponding to this PID if it's already present
261  auto locIteratorPair = std::equal_range(locToReturnNumParticles.begin(), locToReturnNumParticles.end(), locParticlePair.first, DCompare_ParticlePairPIDs());
262  if(locIteratorPair.first != locIteratorPair.second)
263  (*locIteratorPair.first).second += locParticlePair.second; //it exists: increase it
264  else //doesn't exist. insert it
265  locToReturnNumParticles.insert(locIteratorPair.first, locParticlePair);
266  }
267  }
268 
269  return locToReturnNumParticles;
270 }
271 
272 inline DSourceCombo::DSourceCombo(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, const DSourceCombosByUse_Small& locFurtherDecayCombos, bool locIsZIndependent) :
273  dSourceParticles(locSourceParticles), dFurtherDecayCombos(locFurtherDecayCombos), dIsComboingZIndependent(locIsZIndependent) {}
274 
275 inline void DSourceCombo::Reset(void)
276 {
277  dSourceParticles.clear();
278  dFurtherDecayCombos.clear();
279  dIsComboingZIndependent = false;
280 }
281 
282 inline void DSourceCombo::Set_Members(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, const DSourceCombosByUse_Small& locFurtherDecayCombos, bool locIsZIndependent)
283 {
284  dIsComboingZIndependent = locIsZIndependent;
285  dSourceParticles = locSourceParticles;
286  dFurtherDecayCombos = locFurtherDecayCombos;
288 }
289 
290 inline vector<pair<Particle_t, const JObject*>> DSourceCombo::Get_SourceParticles(bool locEntireChainFlag, Charge_t locCharge) const
291 {
292  vector<pair<Particle_t, const JObject*>> locToReturnParticles = dSourceParticles;
293 
294  auto Charge_Checker = [&locCharge](const pair<Particle_t, const JObject*>& locPair) -> bool {return !Is_CorrectCharge(locPair.first, locCharge);};
295  locToReturnParticles.erase(std::remove_if(locToReturnParticles.begin(), locToReturnParticles.end(), Charge_Checker), locToReturnParticles.end());
296 
297  if(!locEntireChainFlag || dFurtherDecayCombos.empty())
298  return locToReturnParticles;
299 
300  for(const auto& locDecayPair : dFurtherDecayCombos)
301  {
302  const auto& locDecayVector = locDecayPair.second;
303  for(const auto& locDecayCombo : locDecayVector)
304  {
305  auto locDecayParticles = locDecayCombo->Get_SourceParticles(true, locCharge);
306  locToReturnParticles.insert(locToReturnParticles.end(), locDecayParticles.begin(), locDecayParticles.end());
307  }
308  }
309 
310  return locToReturnParticles;
311 }
312 
313 /*********************************************************** INLINE NAMESPACE FUNCTION DEFINITIONS ************************************************************/
314 
315 void Print_SourceComboUse(const DSourceComboUse& locComboUse, unsigned char locNumTabs = 0, bool locIgnoreTabs = false);
316 inline void Print_SourceComboInfo(const DSourceComboInfo* locComboInfo, unsigned char locNumTabs = 0)
317 {
318  if(locComboInfo == nullptr)
319  return;
320 
321  auto locNumParticles = locComboInfo->Get_NumParticles(false);
322  for(decltype(locNumTabs) locTabNum = 0; locTabNum < locNumTabs; ++locTabNum) cout << "\t";
323  cout << "Particles: ";
324  for(auto& locParticlePair : locNumParticles)
325  cout << int(locParticlePair.second) << " " << ParticleType(locParticlePair.first) << ", ";
326  cout << endl;
327 
328  auto locFurtherDecays = locComboInfo->Get_FurtherDecays();
329  for(auto& locDecayPair : locFurtherDecays)
330  {
331  for(decltype(locNumTabs) locTabNum = 0; locTabNum < locNumTabs; ++locTabNum) cout << "\t";
332  cout << int(locDecayPair.second) << " of ";
333  DAnalysis::Print_SourceComboUse(locDecayPair.first, locNumTabs, true);
334  }
335 }
336 
337 inline void Print_SourceComboUse(const DSourceComboUse& locComboUse, unsigned char locNumTabs, bool locIgnoreTabs)
338 {
339  if(!locIgnoreTabs)
340  for(decltype(locNumTabs) locTabNum = 0; locTabNum < locNumTabs; ++locTabNum) cout << "\t";
341  cout << "Use (decay pid, z-bin, combo info, has-missing-decay-product, mass-cut-pid-to-exclude): ";
342  cout << ParticleType(std::get<0>(locComboUse)) << ", " << int(std::get<1>(locComboUse)) << ", " << std::get<2>(locComboUse) << ", " << std::get<3>(locComboUse) << ", " << std::get<4>(locComboUse) << ":" << endl;
343  DAnalysis::Print_SourceComboInfo(std::get<2>(locComboUse), locNumTabs + 1);
344 }
345 
346 inline void Print_SourceCombo(const DSourceCombo* locCombo, unsigned char locNumTabs = 0)
347 {
348  if(locCombo == nullptr)
349  return;
350 
351  for(decltype(locNumTabs) locTabNum = 0; locTabNum < locNumTabs; ++locTabNum) cout << "\t";
352  cout << "pointer: " << locCombo << ", Z-independent?: " << locCombo->Get_IsComboingZIndependent() << ", Particles: ";
353  auto locSourceParticles = locCombo->Get_SourceParticles();
354  for(auto& locParticlePair : locSourceParticles)
355  cout << ParticleType(locParticlePair.first) << " " << locParticlePair.second << ", ";
356  cout << endl;
357 
358  DSourceCombosByUse_Small locFurtherDecayCombos = locCombo->Get_FurtherDecayCombos();
359  for(auto& locDecayPair : locFurtherDecayCombos)
360  {
361  for(decltype(locNumTabs) locTabNum = 0; locTabNum < locNumTabs; ++locTabNum) cout << "\t";
362  cout << locDecayPair.second.size() << " of ";
363  DAnalysis::Print_SourceComboUse(locDecayPair.first, locNumTabs, true);
364  for(auto& locCombo : locDecayPair.second)
365  DAnalysis::Print_SourceCombo(locCombo, locNumTabs + 1);
366  }
367 }
368 
369 inline vector<const JObject*> Get_SourceParticles(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, Particle_t locPID)
370 {
371  //if PID is unknown, then all particles
372  vector<const JObject*> locOutputParticles;
373  for(const auto& locParticlePair : locSourceParticles)
374  {
375  if((locPID == Unknown) || (locParticlePair.first == locPID))
376  locOutputParticles.push_back(locParticlePair.second);
377  }
378  return locOutputParticles;
379 }
380 
381 inline vector<const JObject*> Get_SourceParticles(const vector<pair<Particle_t, const JObject*>>& locSourceParticles, int locCharge)
382 {
383  //ignores the charge magnitude and sign: only considers if ==/!= 0
384  vector<const JObject*> locOutputParticles;
385  for(const auto& locParticlePair : locSourceParticles)
386  {
387  auto locParticleCharge = ParticleCharge(locParticlePair.first);
388  if((locParticleCharge == locCharge) && (locParticleCharge == 0))
389  locOutputParticles.push_back(locParticlePair.second);
390  else if(locParticleCharge*locCharge != 0)
391  locOutputParticles.push_back(locParticlePair.second);
392  }
393  return locOutputParticles;
394 }
395 
396 inline vector<pair<Particle_t, const JObject*>> Get_SourceParticles_ThisVertex(const DSourceCombo* locSourceCombo, Charge_t locCharge)
397 {
398  auto locSourceParticles = locSourceCombo->Get_SourceParticles(false, locCharge);
399  auto locFurtherDecayCombos = locSourceCombo->Get_FurtherDecayCombos();
400  for(const auto& locDecayPair : locFurtherDecayCombos)
401  {
402  auto locDecayPID = std::get<0>(locDecayPair.first);
403  if(IsDetachedVertex(locDecayPID))
404  continue;
405  for(const auto& locDecayCombo : locDecayPair.second)
406  {
407  auto locDecayParticles = Get_SourceParticles_ThisVertex(locDecayCombo, locCharge);
408  locSourceParticles.insert(locSourceParticles.end(), locDecayParticles.begin(), locDecayParticles.end());
409  }
410  }
411 
412  return locSourceParticles;
413 }
414 
415 inline vector<const DSourceCombo*> Get_SourceCombos_ThisVertex(const DSourceCombo* locSourceCombo)
416 {
417  vector<const DSourceCombo*> locVertexCombos = {locSourceCombo};
418  for(const auto& locDecayPair : locSourceCombo->Get_FurtherDecayCombos())
419  {
420  auto locDecayPID = std::get<0>(locDecayPair.first);
421  if(IsDetachedVertex(locDecayPID))
422  continue;
423  for(const auto& locDecayCombo : locDecayPair.second)
424  {
425  auto locDecayVertexCombos = Get_SourceCombos_ThisVertex(locDecayCombo);
426  locVertexCombos.insert(locVertexCombos.end(), locDecayVertexCombos.begin(), locDecayVertexCombos.end());
427  }
428  }
429  return locVertexCombos;
430 }
431 
432 inline vector<pair<DSourceComboUse, vector<const DSourceCombo*>>> Get_SourceCombosAndUses_ThisVertex(const DSourceCombo* locSourceCombo)
433 {
434  //sorted from most- to least-dependent
435  vector<pair<DSourceComboUse, vector<const DSourceCombo*>>> locVertexCombosByUse;
436  for(const auto& locDecayPair : locSourceCombo->Get_FurtherDecayCombos())
437  {
438  auto locDecayPID = std::get<0>(locDecayPair.first);
439  if(IsDetachedVertex(locDecayPID))
440  continue;
441  locVertexCombosByUse.emplace_back(locDecayPair);
442  for(const auto& locDecayCombo : locDecayPair.second)
443  {
444  auto locDecayVertexCombosByUse = Get_SourceCombosAndUses_ThisVertex(locDecayCombo);
445  locVertexCombosByUse.insert(locVertexCombosByUse.end(), locDecayVertexCombosByUse.begin(), locDecayVertexCombosByUse.end());
446  }
447  }
448  return locVertexCombosByUse;
449 }
450 
451 inline Charge_t Get_ChargeContent(const vector<pair<Particle_t, unsigned char>>& locNumParticles)
452 {
453  Charge_t locCharge = d_Charged;
454  auto Charge_Search = [&locCharge](const pair<Particle_t, unsigned char>& locPair) -> bool
455  {return Is_CorrectCharge(locPair.first, locCharge);};
456 
457  if(!std::any_of(locNumParticles.begin(), locNumParticles.end(), Charge_Search))
458  return d_Neutral;
459 
460  locCharge = d_Neutral;
461  if(!std::any_of(locNumParticles.begin(), locNumParticles.end(), Charge_Search))
462  return d_Charged;
463 
464  return d_AllCharges;
465 }
466 
467 inline Charge_t Get_ChargeContent(const DSourceComboInfo* locSourceComboInfo)
468 {
469  return Get_ChargeContent(locSourceComboInfo->Get_NumParticles(true));
470 }
471 
472 inline vector<pair<Particle_t, unsigned char>> Get_NumParticles_ThisVertex(const DSourceComboInfo* locSourceComboInfo)
473 {
474  //return is NOT sorted
475 
476  auto locNumParticles = locSourceComboInfo->Get_NumParticles(false); //only this info, for starters
477  for(const auto& locDecayPair : locSourceComboInfo->Get_FurtherDecays())
478  {
479  auto locDecayPID = std::get<0>(locDecayPair.first);
480  if(IsDetachedVertex(locDecayPID))
481  continue;
482 
483  auto locDecayNumParticles = Get_NumParticles_ThisVertex(std::get<2>(locDecayPair.first));
484  for(const auto& locDecayParticlePair : locDecayNumParticles)
485  {
486  bool locFoundFlag = false;
487  for(auto& locParticlePairSoFar : locNumParticles)
488  {
489  if(locDecayParticlePair.first != locParticlePairSoFar.first)
490  continue;
491  locParticlePairSoFar.second += locDecayParticlePair.second;
492  locFoundFlag = true;
493  break;
494  }
495  if(!locFoundFlag)
496  locNumParticles.push_back(locDecayParticlePair);
497  }
498  }
499 
500  return locNumParticles;
501 }
502 
503 inline Charge_t Get_ChargeContent_ThisVertex(const DSourceComboInfo* locSourceComboInfo)
504 {
505  return Get_ChargeContent(Get_NumParticles_ThisVertex(locSourceComboInfo));
506 }
507 
508 inline bool Get_HasMassiveNeutrals(const DSourceComboInfo* locComboInfo)
509 {
510  //see if the combo info contains a massive neutral particle
511 
512  //search function
513  auto Find_MassiveNeutrals = [](const pair<Particle_t, unsigned char>& locPair) -> bool
514  {return ((ParticleCharge(locPair.first) == 0) && (ParticleMass(locPair.first) > 0.0));};
515 
516  //do search
517  auto locNumParticles = locComboInfo->Get_NumParticles(true); //true: entire chain
518  return std::any_of(locNumParticles.begin(), locNumParticles.end(), Find_MassiveNeutrals);
519 }
520 
521 inline bool Get_HasPhotons(const DSourceComboInfo* locComboInfo)
522 {
523  //see if the combo info contains a massive neutral particle
524 
525  //search function
526  auto Find_MassiveNeutrals = [](const pair<Particle_t, unsigned char>& locPair) -> bool
527  {return ((ParticleCharge(locPair.first) == 0) && (ParticleMass(locPair.first) <= 0.0000000001));};
528 
529  //do search
530  auto locNumParticles = locComboInfo->Get_NumParticles(true); //true: entire chain
531  return std::any_of(locNumParticles.begin(), locNumParticles.end(), Find_MassiveNeutrals);
532 }
533 
534 inline const JObject* Get_SourceParticle_ThisStep(const DSourceCombo* locSourceCombo, Particle_t locPID, size_t locInstance, size_t& locPIDCountSoFar)
535 {
536  auto ParticleFinder = [&locPID, &locInstance, &locPIDCountSoFar](pair<Particle_t, const JObject*>& locPair) -> bool
537  {return ((locPair.first != locPID) ? false : ((++locPIDCountSoFar == locInstance) ? true : false));};
538 
539  auto locParticles = locSourceCombo->Get_SourceParticles();
540  auto locIterator = std::find_if(locParticles.begin(), locParticles.end(), ParticleFinder);
541  if(locIterator != locParticles.end())
542  return locIterator->second;
543 
544  for(const auto& locDecayPair : locSourceCombo->Get_FurtherDecayCombos())
545  {
546  if(std::get<0>(locDecayPair.first) != Unknown)
547  continue; //a new step!
548  for(const auto& locDecayCombo : locDecayPair.second)
549  {
550  auto locParticle = Get_SourceParticle_ThisStep(locDecayCombo, locPID, locInstance, locPIDCountSoFar);
551  if(locParticle != nullptr)
552  return locParticle;
553  }
554  }
555 
556  return nullptr;
557 }
558 
559 inline bool Check_AreDuplicateCombos(const DSourceCombo* lhs, const DSourceCombo* rhs)
560 {
561  //Assumes inputs are from the same source (excluding z)
562  auto locParticles_lhs = lhs->Get_SourceParticles(false);
563  auto locParticles_rhs = rhs->Get_SourceParticles(false);
564  if(locParticles_lhs.size() != locParticles_rhs.size())
565  return false;
566  if(!std::is_permutation(locParticles_lhs.begin(), locParticles_lhs.end(), locParticles_rhs.begin()))
567  return false;
568 
569  auto locDecayCombos_lhs = lhs->Get_FurtherDecayCombos();
570  auto locDecayCombos_rhs = rhs->Get_FurtherDecayCombos();
571  if(locDecayCombos_lhs.size() != locDecayCombos_rhs.size())
572  return false;
573 
574  for(auto& locDecayPair : locDecayCombos_lhs)
575  {
576  auto locIteratorPair = std::equal_range(locDecayCombos_rhs.begin(), locDecayCombos_rhs.end(), locDecayPair.first, DSourceCombo::DCompare_FurtherDecays());
577  if(locIteratorPair.first == locIteratorPair.second)
578  return false; //careful, compares z's!!
579 
580  auto& locDecayCombos_lhs = locDecayPair.second;
581  auto& locDecayCombos_rhs = (*locIteratorPair.first).second;
582  if(locDecayCombos_lhs.size() != locDecayCombos_rhs.size())
583  return false;
584  if(!std::is_permutation(locDecayCombos_lhs.begin(), locDecayCombos_lhs.end(), locDecayCombos_rhs.begin(), Check_AreDuplicateCombos))
585  return false;
586  }
587  return true;
588 }
589 
590 } //end DAnalysis namespace
591 
592 #endif // DSourceCombo_h
DSourceCombosByUse_Small dFurtherDecayCombos
Definition: DSourceCombo.h:189
vector< pair< DSourceComboUse, vector< const DSourceCombo * > > > Get_SourceCombosAndUses_ThisVertex(const DSourceCombo *locSourceCombo)
Definition: DSourceCombo.h:432
vector< pair< DSourceComboUse, unsigned char > > dFurtherDecays
Definition: DSourceCombo.h:92
Charge_t Get_ChargeContent_ThisVertex(const DSourceComboInfo *locSourceComboInfo)
Definition: DSourceCombo.h:503
bool Get_HasPhotons(const DSourceComboInfo *locComboInfo)
Definition: DSourceCombo.h:521
bool operator()(const DSourceCombo *locCombo) const
Definition: DSourceCombo.h:208
bool operator<(const DSourceComboUse &lhs, const DSourceComboUse &rhs)
Definition: DSourceCombo.h:95
bool operator()(const pair< DSourceComboUse, unsigned char > &lhs, const pair< DSourceComboUse, unsigned char > &rhs) const
Definition: DSourceCombo.h:153
bool Check_AreDuplicateCombos(const DSourceCombo *lhs, const DSourceCombo *rhs)
Definition: DSourceCombo.h:559
DSourceCombo(void)=default
bool operator()(const pair< Particle_t, unsigned char > &lhs, Particle_t rhs) const
Definition: DSourceCombo.h:147
void Print_SourceComboInfo(const DSourceComboInfo *locComboInfo, unsigned char locNumTabs=0)
Definition: DSourceCombo.h:316
vector< pair< Particle_t, const JObject * > > dSourceParticles
Definition: DSourceCombo.h:188
vector< pair< DSourceComboUse, vector< const DSourceCombo * >>> DSourceCombosByUse_Small
Definition: DSourceCombo.h:35
bool Get_HasMassiveNeutrals(const DSourceComboInfo *locComboInfo)
Definition: DSourceCombo.h:508
static signed char Get_VertexZIndex_OutOfRange(void)
Definition: DSourceCombo.h:80
static unsigned short int IsDetachedVertex(Particle_t p)
Definition: particleType.h:817
static char * ParticleType(Particle_t p)
Definition: particleType.h:142
static signed char Get_VertexZIndex_Unknown(void)
Definition: DSourceCombo.h:82
vector< pair< Particle_t, unsigned char > > Get_NumParticles(bool locEntireChainFlag=false) const
Definition: DSourceCombo.h:247
static int ParticleCharge(Particle_t p)
Charge_t
static signed char Get_VertexZIndex_ZIndependent(void)
Definition: DSourceCombo.h:81
tuple< Particle_t, signed char, const DSourceComboInfo *, bool, Particle_t > DSourceComboUse
Definition: DSourceCombo.h:34
bool operator()(Particle_t lhs, const pair< Particle_t, unsigned char > &rhs) const
Definition: DSourceCombo.h:148
vector< pair< Particle_t, const JObject * > > Get_SourceParticles(bool locEntireChainFlag=false, Charge_t locCharge=d_AllCharges) const
Definition: DSourceCombo.h:290
Charge_t Get_ChargeContent(const DSourceComboInfo *locSourceComboInfo)
Definition: DSourceCombo.h:467
bool operator()(const pair< Particle_t, unsigned char > &lhs, const pair< Particle_t, unsigned char > &rhs) const
Definition: DSourceCombo.h:146
bool Get_IsComboingZIndependent(void) const
Definition: DSourceCombo.h:177
void Set_Members(const vector< pair< Particle_t, const JObject * >> &locSourceParticles, const DSourceCombosByUse_Small &locFurtherDecayCombos, bool locIsZIndependent=false)
Definition: DSourceCombo.h:282
const JObject * Get_SourceParticle_ThisStep(const DSourceCombo *locSourceCombo, Particle_t locPID, size_t locInstance, size_t &locPIDCountSoFar)
Definition: DSourceCombo.h:534
vector< const JObject * > Get_SourceParticles(const vector< pair< Particle_t, const JObject * >> &locSourceParticles, Particle_t locPID=Unknown)
Definition: DSourceCombo.h:369
vector< pair< DSourceComboUse, unsigned char > > Get_FurtherDecays(void) const
Definition: DSourceCombo.h:76
static int Is_CorrectCharge(Particle_t locPID, Charge_t locCharge)
bool operator()(const pair< DSourceComboUse, vector< const DSourceCombo * >> &lhs, DSourceComboUse rhs) const
Definition: DSourceCombo.h:201
static double ParticleMass(Particle_t p)
bool operator()(const pair< DSourceComboUse, vector< const DSourceCombo * >> &lhs, const pair< DSourceComboUse, vector< const DSourceCombo * >> &rhs) const
Definition: DSourceCombo.h:200
void Print_SourceComboUse(const DSourceComboUse &locComboUse, unsigned char locNumTabs=0, bool locIgnoreTabs=false)
Definition: DSourceCombo.h:337
vector< pair< Particle_t, unsigned char > > Get_NumParticles_ThisVertex(const DSourceComboInfo *locSourceComboInfo)
Definition: DSourceCombo.h:472
vector< const DSourceCombo * > Get_SourceCombos_ThisVertex(const DSourceCombo *locSourceCombo)
Definition: DSourceCombo.h:415
bool operator()(const pair< DSourceComboUse, unsigned char > &lhs, DSourceComboUse rhs) const
Definition: DSourceCombo.h:154
vector< pair< Particle_t, const JObject * > > Get_SourceParticles_ThisVertex(const DSourceCombo *locSourceCombo, Charge_t locCharge=d_AllCharges)
Definition: DSourceCombo.h:396
DSourceCombosByUse_Small Get_FurtherDecayCombos(void) const
Definition: DSourceCombo.h:176
vector< pair< Particle_t, unsigned char > > dNumParticles
Definition: DSourceCombo.h:91
bool operator()(DSourceComboUse lhs, const pair< DSourceComboUse, vector< const DSourceCombo * >> &rhs) const
Definition: DSourceCombo.h:202
bool operator()(DSourceComboUse lhs, const pair< DSourceComboUse, unsigned char > &rhs) const
Definition: DSourceCombo.h:155
bool operator<(const DSourceComboInfo &rhs) const
Definition: DSourceCombo.h:226
void Print_SourceCombo(const DSourceCombo *locCombo, unsigned char locNumTabs=0)
Definition: DSourceCombo.h:346
Particle_t
Definition: particleType.h:12