|
|
|||
File indexing completed on 2025-12-13 10:26:19
0001 // -*- C++ -*- 0002 #ifndef RIVET_Particle_HH 0003 #define RIVET_Particle_HH 0004 0005 #include "Rivet/Particle.fhh" 0006 #include "Rivet/ParticleBase.hh" 0007 #include "Rivet/Config/RivetCommon.hh" 0008 #include "Rivet/Tools/Cuts.hh" 0009 #include "Rivet/Tools/Utils.hh" 0010 #include "Rivet/Tools/RivetFastJet.hh" 0011 #include "Rivet/Math/LorentzTrans.hh" 0012 // NOTE: Rivet/Tools/ParticleUtils.hh included at the end 0013 0014 namespace Rivet { 0015 0016 0017 /// @brief Specialised vector of Particle objects. 0018 /// 0019 /// A specialised version of vector<Particle> which is able to implicitly and 0020 /// explicitly convert to a vector of FourMomentum. 0021 class Particles : public std::vector<Particle> { 0022 public: 0023 using base = std::vector<Particle>; //< using-declarations don't like template syntax 0024 using base::base; //< import base-class constructors 0025 Particles(); 0026 Particles(const std::vector<Particle>& vps); 0027 FourMomenta moms() const; 0028 PseudoJets pseudojets() const; 0029 operator FourMomenta () const { return moms(); } 0030 operator PseudoJets () const { return pseudojets(); } 0031 Particles& operator += (const Particle& p); 0032 Particles& operator += (const Particles& ps); 0033 }; 0034 0035 Particles operator + (const Particles& a, const Particles& b); 0036 0037 /// Typedef for a pair of Particle objects. 0038 typedef std::pair<Particle, Particle> ParticlePair; 0039 0040 0041 ///////////////////// 0042 0043 0044 /// Particle representation, either from a HepMC::GenEvent or reconstructed. 0045 class Particle : public ParticleBase { 0046 public: 0047 0048 /// @name Constructors 0049 /// @{ 0050 0051 /// Default constructor. 0052 /// @note A particle without info is useless. This only exists to keep STL containers happy. 0053 Particle() 0054 : ParticleBase(), 0055 _original(nullptr), _id(PID::ANY), _isDirect(4, std::make_pair(false,false)) 0056 { } 0057 0058 /// Constructor from PID and momentum. 0059 Particle(PdgId pid, const FourMomentum& mom, const FourVector& pos=FourVector(), ConstGenParticlePtr gp=nullptr) 0060 : ParticleBase(), 0061 _original(gp), _id(pid), 0062 _momentum(mom), _origin(pos), 0063 _isDirect(4, std::make_pair(false,false)) 0064 { } 0065 0066 /// Constructor from PID, momentum, and a GenParticle for relational links. 0067 Particle(PdgId pid, const FourMomentum& mom, ConstGenParticlePtr gp, const FourVector& pos=FourVector()) 0068 : Particle(pid, mom, pos, gp) 0069 { } 0070 0071 /// Constructor from a HepMC GenParticle pointer. 0072 Particle(ConstGenParticlePtr gp) 0073 : ParticleBase(), 0074 _original(gp), _id(gp->pdg_id()), 0075 _momentum(gp->momentum()), 0076 _isDirect(4, std::make_pair(false,false)) 0077 { 0078 ConstGenVertexPtr vprod = gp->production_vertex(); 0079 if (vprod != nullptr) { 0080 setOrigin(vprod->position().t(), vprod->position().x(), vprod->position().y(), vprod->position().z()); 0081 } 0082 } 0083 0084 /// Constructor from a HepMC GenParticle reference. 0085 Particle(const RivetHepMC::GenParticle& gp) 0086 : Particle(HepMCUtils::getParticlePtr(gp)) 0087 { } 0088 0089 /// @} 0090 0091 0092 /// @name Kinematic properties 0093 /// @{ 0094 0095 /// The momentum. 0096 const FourMomentum& momentum() const { 0097 return _momentum; 0098 } 0099 0100 /// Set the momentum. 0101 Particle& setMomentum(const FourMomentum& momentum) { 0102 _momentum = momentum; 0103 return *this; 0104 } 0105 0106 /// Set the momentum via components. 0107 Particle& setMomentum(double E, double px, double py, double pz) { 0108 _momentum = FourMomentum(E, px, py, pz); 0109 return *this; 0110 } 0111 0112 /// Apply an active Lorentz transform to this particle 0113 Particle& transformBy(const LorentzTransform& lt); 0114 0115 /// @} 0116 0117 0118 /// @name Positional properties 0119 /// @{ 0120 0121 /// The origin position (and time). 0122 const FourVector& origin() const { 0123 return _origin; 0124 } 0125 /// Set the origin position. 0126 Particle& setOrigin(const FourVector& position) { 0127 _origin = position; 0128 return *this; 0129 } 0130 /// Set the origin position via components. 0131 Particle& setOrigin(double t, double x, double y, double z) { 0132 _origin = FourMomentum(t, x, y, z); 0133 return *this; 0134 } 0135 0136 /// @} 0137 0138 0139 /// @name Displacement-projection properties 0140 /// @{ 0141 0142 /// Find the point of closest approach to the primary vertex 0143 Vector3 closestApproach() const { 0144 const FourVector& v0 = origin(); 0145 /// @todo Check that this works with all angles 0146 const double rho0 = origin().perp() / sin(this->phi() - origin().phi()); 0147 const double phi0 = M_PI/2 - this->phi(); 0148 const double x0 = rho0 * cos(phi0); 0149 const double y0 = rho0 * sin(phi0); 0150 const double z0 = origin().z() - v0.perp()/tan(this->theta()); 0151 return Vector3(x0, y0, z0); 0152 } 0153 0154 /// @} 0155 0156 0157 /// @name Other representations and implicit casts to momentum-like objects 0158 /// @{ 0159 0160 /// Converter to FastJet3 PseudoJet 0161 virtual fastjet::PseudoJet pseudojet() const { 0162 return fastjet::PseudoJet(mom().px(), mom().py(), mom().pz(), mom().E()); 0163 } 0164 0165 /// Cast operator to FastJet3 PseudoJet 0166 operator PseudoJet () const { return pseudojet(); } 0167 0168 0169 /// Set a const pointer to the original GenParticle 0170 Particle& setGenParticle(ConstGenParticlePtr gp) { 0171 _original = gp; 0172 return *this; 0173 } 0174 0175 /// Get a const pointer to the original GenParticle 0176 ConstGenParticlePtr genParticle() const { 0177 return _original; 0178 } 0179 0180 /// Cast operator for conversion to GenParticle* 0181 /// @note Not implicit since that would enable accidental Particle::operator== comparisons 0182 explicit operator ConstGenParticlePtr () const { return genParticle(); } 0183 0184 /// @} 0185 0186 0187 /// @name Particle ID code accessors 0188 /// @{ 0189 0190 /// This Particle's PDG ID code. 0191 PdgId pid() const { return _id; } 0192 /// Absolute value of the PDG ID code. 0193 PdgId abspid() const { return std::abs(_id); } 0194 0195 /// @} 0196 0197 0198 /// @name Charge 0199 /// @{ 0200 0201 /// The charge of this Particle. 0202 double charge() const { return PID::charge(pid()); } 0203 0204 /// The absolute charge of this Particle. 0205 double abscharge() const { return PID::abscharge(pid()); } 0206 0207 /// Three times the charge of this Particle (i.e. integer multiple of smallest quark charge). 0208 int charge3() const { return PID::charge3(pid()); } 0209 0210 /// Three times the absolute charge of this Particle (i.e. integer multiple of smallest quark charge). 0211 int abscharge3() const { return PID::abscharge3(pid()); } 0212 0213 /// Is this Particle charged? 0214 bool isCharged() const { return charge3() != 0; } 0215 0216 /// @} 0217 0218 0219 /// @name Particle species 0220 /// @{ 0221 0222 /// Is this a hadron? 0223 bool isHadron() const { return PID::isHadron(pid()); } 0224 0225 /// Is this a meson? 0226 bool isMeson() const { return PID::isMeson(pid()); } 0227 0228 /// Is this a baryon? 0229 bool isBaryon() const { return PID::isBaryon(pid()); } 0230 0231 /// Is this a lepton? 0232 bool isLepton() const { return PID::isLepton(pid()); } 0233 0234 /// Is this a charged lepton? 0235 bool isChargedLepton() const { return PID::isChargedLepton(pid()); } 0236 0237 /// Is this a neutrino? 0238 bool isNeutrino() const { return PID::isNeutrino(pid()); } 0239 0240 /// Does this (hadron) contain a b quark? 0241 bool hasBottom() const { return PID::hasBottom(pid()); } 0242 0243 /// Does this (hadron) contain a c quark? 0244 bool hasCharm() const { return PID::hasCharm(pid()); } 0245 0246 // /// Does this (hadron) contain an s quark? 0247 // bool hasStrange() const { return PID::hasStrange(pid()); } 0248 0249 /// Is this particle potentially visible in a detector? 0250 bool isVisible() const; 0251 0252 /// Is this a parton? (Hopefully not very often... fiducial FTW) 0253 bool isParton() const { return PID::isParton(pid()); } 0254 0255 /// @} 0256 0257 0258 /// @name Constituents (for composite particles) 0259 /// @{ 0260 0261 /// Set direct constituents of this particle 0262 virtual void setConstituents(const Particles& cs, bool setmom=false); 0263 0264 /// Add a single direct constituent to this particle 0265 virtual void addConstituent(const Particle& c, bool addmom=false); 0266 0267 /// Add direct constituents to this particle 0268 virtual void addConstituents(const Particles& cs, bool addmom=false); 0269 0270 0271 /// Determine if this Particle is a composite of other Rivet Particles 0272 bool isComposite() const { return !constituents().empty(); } 0273 0274 0275 /// @brief Direct constituents of this particle, returned by reference 0276 /// 0277 /// The returned vector will be empty if this particle is non-composite, 0278 /// and its entries may themselves be composites. 0279 const Particles& constituents() const { return _constituents; } 0280 0281 /// @brief Direct constituents of this particle, sorted by a functor 0282 /// @note Returns a copy, thanks to the sorting 0283 const Particles constituents(const ParticleSorter& sorter) const { 0284 return sortBy(constituents(), sorter); 0285 } 0286 0287 /// @brief Direct constituents of this particle, filtered by a Cut 0288 /// @note Returns a copy, thanks to the filtering 0289 const Particles constituents(const Cut& c) const { 0290 return select(constituents(), c); 0291 } 0292 0293 /// @brief Direct constituents of this particle, sorted by a functor 0294 /// @note Returns a copy, thanks to the filtering and sorting 0295 const Particles constituents(const Cut& c, const ParticleSorter& sorter) const { 0296 return sortBy(constituents(c), sorter); 0297 } 0298 0299 /// @brief Direct constituents of this particle, filtered by a selection functor 0300 /// @note Returns a copy, thanks to the filtering 0301 const Particles constituents(const ParticleSelector& selector) const { 0302 return select(constituents(), selector); 0303 } 0304 0305 /// @brief Direct constituents of this particle, filtered and sorted by functors 0306 /// @note Returns a copy, thanks to the filtering and sorting 0307 const Particles constituents(const ParticleSelector& selector, const ParticleSorter& sorter) const { 0308 return sortBy(constituents(selector), sorter); 0309 } 0310 0311 0312 /// @brief Fundamental constituents of this particle 0313 /// @note Returns {{*this}} if this particle is non-composite. 0314 Particles rawConstituents() const; 0315 0316 /// @brief Fundamental constituents of this particle, sorted by a functor 0317 /// @note Returns a copy, thanks to the sorting 0318 const Particles rawConstituents(const ParticleSorter& sorter) const { 0319 return sortBy(rawConstituents(), sorter); 0320 } 0321 0322 /// @brief Fundamental constituents of this particle, filtered by a Cut 0323 /// @note Returns a copy, thanks to the filtering 0324 const Particles rawConstituents(const Cut& c) const { 0325 return select(rawConstituents(), c); 0326 } 0327 0328 /// @brief Fundamental constituents of this particle, sorted by a functor 0329 /// @note Returns a copy, thanks to the filtering and sorting 0330 const Particles rawConstituents(const Cut& c, const ParticleSorter& sorter) const { 0331 return sortBy(rawConstituents(c), sorter); 0332 } 0333 0334 /// @brief Fundamental constituents of this particle, filtered by a selection functor 0335 /// @note Returns a copy, thanks to the filtering 0336 const Particles rawConstituents(const ParticleSelector& selector) const { 0337 return select(rawConstituents(), selector); 0338 } 0339 0340 /// @brief Fundamental constituents of this particle, filtered and sorted by functors 0341 /// @note Returns a copy, thanks to the filtering and sorting 0342 const Particles rawConstituents(const ParticleSelector& selector, const ParticleSorter& sorter) const { 0343 return sortBy(rawConstituents(selector), sorter); 0344 } 0345 0346 /// @} 0347 0348 0349 /// @name Ancestry (for fundamental particles with a HepMC link) 0350 /// @{ 0351 0352 /// Get a list of the direct parents of the current particle (with optional selection Cut) 0353 /// 0354 /// @note This is valid in MC, but may not be answerable 0355 /// experimentally -- use this function with care when replicating 0356 /// experimental analyses! 0357 Particles parents(const Cut& c=Cuts::OPEN) const; 0358 0359 /// Get a list of the direct parents of the current particle (with selector function) 0360 /// 0361 /// @note This is valid in MC, but may not be answerable 0362 /// experimentally -- use this function with care when replicating 0363 /// experimental analyses! 0364 Particles parents(const ParticleSelector& f) const { 0365 return select(parents(), f); 0366 } 0367 0368 /// Check whether any particle in the particle's parent list has the requested property 0369 /// 0370 /// @note This question is valid in MC, but may not be answerable 0371 /// experimentally -- use this function with care when replicating 0372 /// experimental analyses! 0373 bool hasParentWith(const ParticleSelector& f) const { 0374 return !parents(f).empty(); 0375 } 0376 /// Check whether any particle in the particle's parent list has the requested property 0377 /// 0378 /// @note This question is valid in MC, but may not be answerable 0379 /// experimentally -- use this function with care when replicating 0380 /// experimental analyses! 0381 bool hasParentWith(const Cut& c) const; 0382 0383 /// Check whether any particle in the particle's parent list does not have the requested property 0384 /// 0385 /// @note This question is valid in MC, but may not be answerable 0386 /// experimentally -- use this function with care when replicating 0387 /// experimental analyses! 0388 bool hasParentWithout(const ParticleSelector& f) const { 0389 return hasParentWith([&](const Particle& p){ return !f(p); }); 0390 } 0391 /// Check whether any particle in the particle's parent list does not have the requested property 0392 /// 0393 /// @note This question is valid in MC, but may not be answerable 0394 /// experimentally -- use this function with care when replicating 0395 /// experimental analyses! 0396 bool hasParentWithout(const Cut& c) const; 0397 0398 0399 /// Get a list of the ancestors of the current particle (with optional selection Cut) 0400 /// 0401 /// @note By default only physical ancestors, with status=2, are returned. 0402 /// 0403 /// @note This is valid in MC, but may not be answerable experimentally -- 0404 /// use this function with care when replicating experimental analyses! 0405 Particles ancestors(const Cut& c=Cuts::OPEN, bool only_physical=true) const; 0406 0407 /// Get a list of the direct parents of the current particle (with selector function) 0408 /// 0409 /// @note By default only physical ancestors, with status=2, are returned. 0410 /// 0411 /// @note This is valid in MC, but may not be answerable experimentally -- 0412 /// use this function with care when replicating experimental analyses! 0413 Particles ancestors(const ParticleSelector& f, bool only_physical=true) const { 0414 return select(ancestors(Cuts::OPEN, only_physical), f); 0415 } 0416 0417 /// Check whether any particle in the particle's ancestor list has the requested property 0418 /// 0419 /// @note This question is valid in MC, but may not be answerable 0420 /// experimentally -- use this function with care when replicating 0421 /// experimental analyses! 0422 bool hasAncestorWith(const ParticleSelector& f, bool only_physical=true) const { 0423 return !ancestors(f, only_physical).empty(); 0424 } 0425 /// Check whether any particle in the particle's ancestor list has the requested property 0426 /// 0427 /// @note This question is valid in MC, but may not be answerable 0428 /// experimentally -- use this function with care when replicating 0429 /// experimental analyses! 0430 bool hasAncestorWith(const Cut& c, bool only_physical=true) const; 0431 0432 /// Check whether any particle in the particle's ancestor list does not have the requested property 0433 /// 0434 /// @note This question is valid in MC, but may not be answerable 0435 /// experimentally -- use this function with care when replicating 0436 /// experimental analyses! 0437 bool hasAncestorWithout(const ParticleSelector& f, bool only_physical=true) const { 0438 return hasAncestorWith([&](const Particle& p){ return !f(p); }, only_physical); 0439 } 0440 /// Check whether any particle in the particle's ancestor list does not have the requested property 0441 /// 0442 /// @note This question is valid in MC, but may not be answerable 0443 /// experimentally -- use this function with care when replicating 0444 /// experimental analyses! 0445 bool hasAncestorWithout(const Cut& c, bool only_physical=true) const; 0446 0447 /// @brief Determine whether the particle is from a b-hadron decay 0448 /// 0449 /// @note This question is valid in MC, but may not be perfectly answerable 0450 /// experimentally -- use this function with care when replicating 0451 /// experimental analyses! 0452 bool fromBottom() const; 0453 0454 /// @brief Determine whether the particle is from a c-hadron decay 0455 /// 0456 /// @note If a hadron contains b and c quarks it is considered a bottom 0457 /// hadron and NOT a charm hadron. 0458 /// 0459 /// @note This question is valid in MC, but may not be perfectly answerable 0460 /// experimentally -- use this function with care when replicating 0461 /// experimental analyses! 0462 bool fromCharm() const; 0463 0464 // /// @brief Determine whether the particle is from a s-hadron decay 0465 // /// 0466 // /// @note If a hadron contains b or c quarks as well as strange it is 0467 // /// considered a b or c hadron, but NOT a strange hadron. 0468 // /// 0469 // /// @note This question is valid in MC, but may not be perfectly answerable 0470 // /// experimentally -- use this function with care when replicating 0471 // /// experimental analyses! 0472 // bool fromStrange() const; 0473 0474 /// @brief Determine whether the particle is from a hadron decay 0475 /// 0476 /// @note This question is valid in MC, but may not be perfectly answerable 0477 /// experimentally -- use this function with care when replicating 0478 /// experimental analyses! 0479 bool fromHadron() const; 0480 0481 /// @brief Determine whether the particle is from a tau decay 0482 /// 0483 /// @note This question is valid in MC, but may not be perfectly answerable 0484 /// experimentally -- use this function with care when replicating 0485 /// experimental analyses! 0486 bool fromTau(bool prompt_taus_only=false) const; 0487 0488 /// @brief Determine whether the particle is from a prompt tau decay 0489 /// 0490 /// @note This question is valid in MC, but may not be perfectly answerable 0491 /// experimentally -- use this function with care when replicating 0492 /// experimental analyses! 0493 bool fromPromptTau() const { return fromTau(true); } 0494 0495 /// @brief Determine whether the particle is from a tau which decayed hadronically 0496 /// 0497 /// @note This question is valid in MC, but may not be perfectly answerable 0498 /// experimentally -- use this function with care when replicating 0499 /// experimental analyses! 0500 bool fromHadronicTau(bool prompt_taus_only=false) const; 0501 0502 /// @brief Shorthand definition of 'promptness' based on set definition flags 0503 /// 0504 /// A "direct" particle is one directly connected to the hard process. It is a 0505 /// preferred alias for "prompt", since it has no confusing implications about 0506 /// distinguishability by timing information. 0507 /// 0508 /// The boolean arguments allow a decay lepton to be considered direct if 0509 /// its parent was a "real" direct lepton. 0510 /// 0511 /// @note This one doesn't make any judgements about final-stateness 0512 bool isDirect(bool allow_from_direct_tau=false, bool allow_from_direct_mu=false) const; 0513 0514 /// Alias for isDirect 0515 bool isPrompt(bool allow_from_prompt_tau=false, bool allow_from_prompt_mu=false) const { 0516 return isDirect(allow_from_prompt_tau, allow_from_prompt_mu); 0517 } 0518 0519 /// @} 0520 0521 0522 /// @name Decay info 0523 /// @{ 0524 0525 /// Whether this particle is stable according to the generator 0526 bool isStable() const; 0527 0528 /// @todo isDecayed? How to restrict to physical particles? 0529 0530 0531 /// Get a list of the direct descendants from the current particle (with optional selection Cut) 0532 Particles children(const Cut& c=Cuts::OPEN) const; 0533 0534 /// Get a list of the direct descendants from the current particle (with selector function) 0535 Particles children(const ParticleSelector& f) const { 0536 return select(children(), f); 0537 } 0538 0539 /// Check whether any direct child of this particle has the requested property 0540 /// 0541 /// @note This question is valid in MC, but may not be answerable 0542 /// experimentally -- use this function with care when replicating 0543 /// experimental analyses! 0544 bool hasChildWith(const ParticleSelector& f) const { 0545 return !children(f).empty(); 0546 } 0547 /// Check whether any direct child of this particle has the requested property 0548 /// 0549 /// @note This question is valid in MC, but may not be answerable 0550 /// experimentally -- use this function with care when replicating 0551 /// experimental analyses! 0552 bool hasChildWith(const Cut& c) const; 0553 0554 /// Check whether any direct child of this particle does not have the requested property 0555 /// 0556 /// @note This question is valid in MC, but may not be answerable 0557 /// experimentally -- use this function with care when replicating 0558 /// experimental analyses! 0559 bool hasChildWithout(const ParticleSelector& f) const { 0560 return hasChildWith([&](const Particle& p){ return !f(p); }); 0561 } 0562 /// Check whether any direct child of this particle does not have the requested property 0563 /// 0564 /// @note This question is valid in MC, but may not be answerable 0565 /// experimentally -- use this function with care when replicating 0566 /// experimental analyses! 0567 bool hasChildWithout(const Cut& c) const; 0568 0569 0570 /// Get a list of all the descendants from the current particle (with optional selection Cut) 0571 Particles allDescendants(const Cut& c=Cuts::OPEN, bool remove_duplicates=true) const; 0572 0573 /// Get a list of all the descendants from the current particle (with selector function) 0574 Particles allDescendants(const ParticleSelector& f, bool remove_duplicates=true) const { 0575 return select(allDescendants(Cuts::OPEN, remove_duplicates), f); 0576 } 0577 0578 /// Check whether any descendant of this particle has the requested property 0579 /// 0580 /// @note This question is valid in MC, but may not be answerable 0581 /// experimentally -- use this function with care when replicating 0582 /// experimental analyses! 0583 bool hasDescendantWith(const ParticleSelector& f, bool remove_duplicates=true) const { 0584 return !allDescendants(f, remove_duplicates).empty(); 0585 } 0586 /// Check whether any descendant of this particle has the requested property 0587 /// 0588 /// @note This question is valid in MC, but may not be answerable 0589 /// experimentally -- use this function with care when replicating 0590 /// experimental analyses! 0591 bool hasDescendantWith(const Cut& c, bool remove_duplicates=true) const; 0592 0593 /// Check whether any descendant of this particle does not have the requested property 0594 /// 0595 /// @note This question is valid in MC, but may not be answerable 0596 /// experimentally -- use this function with care when replicating 0597 /// experimental analyses! 0598 bool hasDescendantWithout(const ParticleSelector& f, bool remove_duplicates=true) const { 0599 return hasDescendantWith([&](const Particle& p){ return !f(p); }, remove_duplicates); 0600 } 0601 /// Check whether any descendant of this particle does not have the requested property 0602 /// 0603 /// @note This question is valid in MC, but may not be answerable 0604 /// experimentally -- use this function with care when replicating 0605 /// experimental analyses! 0606 bool hasDescendantWithout(const Cut& c, bool remove_duplicates=true) const; 0607 0608 0609 /// Get a list of all the stable descendants from the current particle (with optional selection Cut) 0610 /// 0611 /// @todo Use recursion through replica-avoiding MCUtils functions to avoid bookkeeping duplicates 0612 /// @todo Insist that the current particle is post-hadronization, otherwise throw an exception? 0613 Particles stableDescendants(const Cut& c=Cuts::OPEN) const; 0614 0615 /// Get a list of all the stable descendants from the current particle (with selector function) 0616 Particles stableDescendants(const ParticleSelector& f) const { 0617 return select(stableDescendants(), f); 0618 } 0619 0620 /// Check whether any stable descendant of this particle has the requested property 0621 /// 0622 /// @note This question is valid in MC, but may not be answerable 0623 /// experimentally -- use this function with care when replicating 0624 /// experimental analyses! 0625 bool hasStableDescendantWith(const ParticleSelector& f) const { 0626 return !stableDescendants(f).empty(); 0627 } 0628 /// Check whether any stable descendant of this particle has the requested property 0629 /// 0630 /// @note This question is valid in MC, but may not be answerable 0631 /// experimentally -- use this function with care when replicating 0632 /// experimental analyses! 0633 bool hasStableDescendantWith(const Cut& c) const; 0634 0635 /// Check whether any stable descendant of this particle does not have the requested property 0636 /// 0637 /// @note This question is valid in MC, but may not be answerable 0638 /// experimentally -- use this function with care when replicating 0639 /// experimental analyses! 0640 bool hasStableDescendantWithout(const ParticleSelector& f) const { 0641 return hasStableDescendantWith([&](const Particle& p){ return !f(p); }); 0642 } 0643 /// Check whether any stable descendant of this particle does not have the requested property 0644 /// 0645 /// @note This question is valid in MC, but may not be answerable 0646 /// experimentally -- use this function with care when replicating 0647 /// experimental analyses! 0648 bool hasStableDescendantWithout(const Cut& c) const; 0649 0650 0651 /// Flight length of the particle from origin to decay 0652 /// 0653 /// @note Divide by mm or cm as usual to get the appropriate units. 0654 double flightLength() const; 0655 0656 /// @} 0657 0658 0659 /// @name Duplicate testing 0660 /// @{ 0661 0662 /// @brief Determine whether a particle is the first in a decay chain to meet the function requirement 0663 inline bool isFirstWith(const ParticleSelector& f) const { 0664 if (!f(*this)) return false; //< This doesn't even meet f, let alone being the last to do so 0665 if (any(parents(), f)) return false; //< If a direct parent has this property, this isn't the first 0666 return true; 0667 } 0668 0669 /// @brief Determine whether a particle is the first in a decay chain not to meet the function requirement 0670 inline bool isFirstWithout(const ParticleSelector& f) const { 0671 return isFirstWith([&](const Particle& p){ return !f(p); }); 0672 } 0673 0674 /// @brief Determine whether a particle is the last in a decay chain to meet the function requirement 0675 inline bool isLastWith(const ParticleSelector& f) const { 0676 if (!f(*this)) return false; //< This doesn't even meet f, let alone being the last to do so 0677 if (any(children(), f)) return false; //< If a child has this property, this isn't the last 0678 return true; 0679 } 0680 0681 /// @brief Determine whether a particle is the last in a decay chain not to meet the function requirement 0682 inline bool isLastWithout(const ParticleSelector& f) const { 0683 return isLastWith([&](const Particle& p){ return !f(p); }); 0684 } 0685 0686 /// @} 0687 0688 0689 /// @name Comparison 0690 /// @{ 0691 0692 /// Compare particles, based on "external" characteristics, with a little angular tolerance 0693 /// 0694 /// @note Not a deep comparison: GenParticle ptr and constituents are not used in the comparison 0695 bool isSame(const Particle& other) const { 0696 if (pid() != other.pid()) return false; 0697 if (!isZero((mom() - other.mom()).mod())) return false; 0698 if (!isZero((origin() - other.origin()).mod())) return false; 0699 return true; 0700 } 0701 0702 /// @} 0703 0704 0705 protected: 0706 0707 /// A pointer to the original GenParticle from which this Particle is projected. 0708 ConstGenParticlePtr _original; 0709 0710 /// Constituent particles if this is a composite (may be empty) 0711 Particles _constituents; 0712 0713 /// The PDG ID code for this Particle. 0714 PdgId _id; 0715 0716 /// The momentum of this particle. 0717 FourMomentum _momentum; 0718 0719 /// The creation position of this particle. 0720 FourVector _origin; 0721 0722 /// Cached computation of directness, via ancestry. Second element is cache status 0723 /// @todo Replace this awkward caching with C++17 std::optional 0724 mutable std::vector<std::pair<bool,bool> > _isDirect; 0725 0726 }; 0727 0728 0729 /// @name String representation and streaming support 0730 /// @{ 0731 0732 /// Allow a Particle to be passed to an ostream. 0733 std::ostream& operator << (std::ostream& os, const Particle& p); 0734 0735 /// Allow ParticlePair to be passed to an ostream. 0736 std::ostream& operator << (std::ostream& os, const ParticlePair& pp); 0737 0738 /// @} 0739 0740 0741 } 0742 0743 0744 #include "Rivet/Tools/ParticleUtils.hh" 0745 0746 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|