Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:06:47

0001 #ifndef PROJECTIONS_ALICECOMMON_HH
0002 #define PROJECTIONS_ALICECOMMON_HH
0003 
0004 #include "Rivet/Tools/AliceCommon.hh"
0005 #include "Rivet/Projections/FinalState.hh"
0006 #include "Rivet/Projections/SingleValueProjection.hh"
0007 #include "Rivet/Projections/TriggerProjection.hh"
0008 #include "Rivet/Projections/PrimaryParticles.hh"
0009 
0010 namespace Rivet {
0011   namespace ALICE {
0012 
0013 
0014     /// Template for ALICE V0 multiplicity projection.   Which
0015     /// acceptance to look in depends on the template argument @a MODE:
0016     ///
0017     /// - @c MODE=-1  Check the V0-C acceptance (@f$-3.7<\eta<-1.7@f$)
0018     /// - @c MODE=+1  Check the V0-A acceptance (@f$+2.8<\eta<+5.1@f$)
0019     /// - @c MODE=0   Check both V0-A and -C acceptances (sum)
0020     ///
0021     /// @ingroup alice_rivet
0022     template <int MODE>
0023     class V0Multiplicity : public SingleValueProjection {
0024     public:
0025       using SingleValueProjection::operator=;
0026       V0Multiplicity() : SingleValueProjection() {
0027         setName(MODE<0 ? "ALICE::V0CMultiplicity":
0028                 MODE>0 ? "ALICE::V0AMultiplicity":
0029                 "ALICE::V0MMultiplicity");
0030         Cut cut;
0031         if      (MODE < 0) cut = V0Cacceptance;
0032         else if (MODE > 0) cut = V0Aacceptance;
0033         else               cut = (V0Aacceptance || V0Cacceptance);
0034         // Declare our projection.  Note, the cuts stipulate charged
0035         // particles, so we just use a final state (rather than
0036         // charged-final state) projection here.
0037         const FinalState fs(cut);
0038         this->declare(fs, "FinalState");
0039       }
0040 
0041       /// Destructor
0042       virtual ~V0Multiplicity() {}
0043 
0044       /// Do the projection.  Sums number of charged final state
0045       /// particles within the acceptances of the specified V0
0046       /// sub-detectors.
0047       ///
0048       /// @param e Event to project from
0049       virtual void project(const Event& e) {
0050         clear();
0051         setValue(apply<FinalState>(e,"FinalState").particles().size());
0052       }
0053 
0054       /// Clone this projection
0055       ///
0056       /// @return New wrapped pointer to object of this class
0057       virtual std::unique_ptr<Rivet::Projection> clone() const {
0058         return std::unique_ptr<Projection>(new V0Multiplicity<MODE>(*this));
0059       }
0060 
0061       /// Import to avoid warnings about overload-hiding
0062       using Projection::operator =;
0063 
0064       /// Compare to another projection
0065       ///
0066       /// @param p Projection to compare against
0067       virtual CmpState compare(const Projection& p) const {
0068         return dynamic_cast<const V0Multiplicity<MODE>*>(&p) ?
0069           CmpState::EQ : CmpState::NEQ;
0070       }
0071 
0072     };
0073 
0074 
0075     /// Convenience typedef for A-side multiplicity
0076     ///
0077     /// @ingroup alice_rivet
0078     typedef V0Multiplicity<+1> V0AMultiplicity;
0079 
0080     /// Convenience typedef for C-side multiplicity
0081     ///
0082     /// @ingroup alice_rivet
0083     typedef V0Multiplicity<-1> V0CMultiplicity;
0084 
0085     /// Convenience typedef for A & C multiplicity
0086     ///
0087     /// @ingroup alice_rivet
0088     typedef V0Multiplicity<0> V0MMultiplicity;
0089 
0090 
0091 
0092     /// Template for ALICE CL multiplicity projection.  Which
0093     /// acceptance to look in depends on the template argument @a INNER:
0094     ///
0095     /// - @c INNER=true Check the inner SPD layer
0096     /// - @c INNER=false  Check the outer SPD layer
0097     ///
0098     /// @ingroup alice_rivet
0099     template <bool INNER>
0100     class CLMultiplicity : public SingleValueProjection {
0101     public:
0102 
0103       /// Constructor
0104       CLMultiplicity() : SingleValueProjection() {
0105         setName("ALICE::CLMultiplicity");
0106         Cut cut;
0107         if   (INNER) cut = CL0acceptance;
0108         else         cut = CL1acceptance;
0109         // Declare our projection.  Note, the cuts stipulate charged
0110         // particles, so we just use a final state (rather than
0111         // charged-final state) projection here.
0112         const FinalState fs(cut);
0113         this->declare(fs, "FinalState");
0114       }
0115 
0116       /// Destructor
0117       virtual ~CLMultiplicity() {}
0118 
0119       /// Do the projection.  Sums number of charged final state
0120       /// particles within the acceptances of the specified CL
0121       /// sub-detectors.
0122       ///
0123       /// @param e Event to project from
0124       virtual void project(const Event& e) {
0125         clear();
0126         set(apply<FinalState>(e,"FinalState").particles().size());
0127       }
0128 
0129       /// Clone this projection
0130       ///
0131       /// @return New wrapped pointer to object of this class
0132       virtual std::unique_ptr<Rivet::Projection> clone() const {
0133         return std::unique_ptr<Projection>(new CLMultiplicity<INNER>(*this));
0134       }
0135 
0136       /// Import to avoid warnings about overload-hiding
0137       using Projection::operator =;
0138 
0139       /// Compare to another projection
0140       ///
0141       /// @param p Projection to compare against
0142       virtual CmpState compare(const Projection& p) const {
0143         return dynamic_cast<const CLMultiplicity<INNER>*>(&p) ?
0144           CmpState::EQ : CmpState::NEQ;
0145       }
0146 
0147     };
0148 
0149 
0150     /// Convenience typedef for inside-CL multiplicity
0151     ///
0152     /// @ingroup alice_rivet
0153     typedef CLMultiplicity<true>  CL0Multiplicity;
0154 
0155     /// Convenience typedef for outside-CL multiplicity
0156     ///
0157     /// @ingroup alice_rivet
0158     typedef CLMultiplicity<false> CL1Multiplicity;
0159 
0160 
0161 
0162     /// A template of ALICE V0-based triggers.
0163     ///
0164     /// - @c MODE=-1  Check in the V0-C acceptance (@f$-3.7<\eta<-1.7@f$)
0165     /// - @c MODE=+1  Check in the V0-A acceptance (@f$+2.8<\eta<+5.1@f$)
0166     /// - @c MODE=0   Check in both V0-A and -C acceptances (V0-OR)
0167     ///
0168     /// @ingroup alice_rivet
0169     template <int MODE>
0170     class V0Trigger : public TriggerProjection {
0171     public:
0172 
0173       /// Constructor
0174       V0Trigger() : TriggerProjection() {
0175         setName("ALICE::V0Trigger");
0176         // Declare our projection.  Note, the cuts stipulate charged
0177         // particles, so we just use a final state (rather than
0178         // charged-final state) projection here.
0179         const V0Multiplicity<MODE> fs;
0180         this->declare(fs, "FinalState");
0181       }
0182 
0183       /// Destructor
0184       virtual ~V0Trigger() {}
0185 
0186       /// Do the projection.  Checks if the number of projected
0187       /// particles is larger than 0
0188       ///
0189       /// @param e Event to project from
0190       virtual void project(const Event& e) {
0191         fail(); // Assume failure
0192         if (apply<V0Multiplicity<MODE>>(e, "FinalState")() > 0) pass();
0193       }
0194 
0195       /// Clone this projection
0196       ///
0197       /// @return New wrapped pointer to object of this class
0198       virtual std::unique_ptr<Rivet::Projection> clone() const {
0199         return std::unique_ptr<Projection>(new V0Trigger<MODE>(*this));
0200       }
0201 
0202       /// Import to avoid warnings about overload-hiding
0203       using Projection::operator =;
0204 
0205       /// Compare to projections.
0206       ///
0207       /// @param p Projection to compare to.
0208       ///
0209       /// @return true (EQUIVALENT) if the projection @a p is of the same
0210       /// type as this.
0211       virtual CmpState compare(const Projection& p) const {
0212         return dynamic_cast<const V0Trigger<MODE>*>(&p) ?
0213           CmpState::EQ : CmpState::NEQ;
0214       }
0215 
0216     };
0217 
0218 
0219     /// Convenience typedef for V0 A trigger
0220     ///
0221     /// @ingroup alice_rivet
0222     using V0ATrigger = V0Trigger<-1>;
0223 
0224     /// Convenience typedef for V0 C trigger
0225     ///
0226     /// @ingroup alice_rivet
0227     using V0CTrigger = V0Trigger<+1>;
0228 
0229     /// Convenience typedef for V0 A-or-C trigger
0230     ///
0231     /// @ingroup alice_rivet
0232     using V0OrTrigger = V0Trigger<0>;
0233 
0234 
0235 
0236     /// Trigger projection for the ALICE V0-AND (a.k.a. CINT7) requirement
0237     class V0AndTrigger : public TriggerProjection {
0238     public:
0239 
0240       /// Constructor
0241       V0AndTrigger() : TriggerProjection() {
0242         const V0ATrigger v0a;
0243         const V0CTrigger v0c;
0244         this->declare(v0a, "V0A");
0245         this->declare(v0c, "V0C");
0246       }
0247 
0248       /// Destructor
0249       virtual ~V0AndTrigger() {}
0250 
0251       /// Do the projection.  Checks if the numbers of projected
0252       /// particles on both sides, are larger than 0
0253       ///
0254       /// @param e Event to project from
0255       virtual void project(const Event& e) {
0256         fail(); // Assume failure
0257         if (apply<V0ATrigger>(e,"V0A")() && apply<V0CTrigger>(e,"V0C")()) pass();
0258       }
0259 
0260       /// Compare to projections.
0261       ///
0262       /// @param p Projection to compare to.
0263       virtual CmpState compare(const Projection& p) const
0264       {
0265         return dynamic_cast<const V0AndTrigger*>(&p) ?
0266           CmpState::EQ : CmpState::NEQ;
0267       }
0268 
0269       /// Clone this projection
0270       ///
0271       /// @return New wrapped pointer to object of this class
0272       virtual std::unique_ptr<Rivet::Projection> clone() const {
0273         return std::unique_ptr<Projection>(new V0AndTrigger(*this));
0274       }
0275 
0276       /// Import to avoid warnings about overload-hiding
0277       using Projection::operator =;
0278 
0279     };
0280 
0281 
0282     /// @brief Standard ALICE primary particle definition
0283     ///
0284     /// Primary particle definition according to public note
0285     /// <a href="https://cds.cern.ch/record/2270008">ALICE-PUBLIC-2017-005</a>
0286     ///
0287     /// @ingroup alice_rivet
0288     class PrimaryParticles : public Rivet::PrimaryParticles {
0289     public:
0290 
0291       PrimaryParticles(const Cut& c=Cuts::open())
0292         : Rivet::PrimaryParticles({}, c)
0293       { }
0294 
0295       /// Compare to projections.
0296       ///
0297       /// @param p Projection to compare to.
0298       ///
0299       /// @return true (EQUIVALENT) if the projection @a p is of the same
0300       /// type as this, if the cuts are equal, and that the list of PDG
0301       /// IDs are the same.
0302       virtual CmpState compare(const Projection& p) const {
0303         const PrimaryParticles* o = dynamic_cast<const PrimaryParticles*>(&p);
0304         if (_cuts != o->_cuts) return CmpState::NEQ;
0305         return mkPCmp(*o,"PrimaryParticles");
0306       }
0307 
0308       /// Clone this projection
0309       virtual std::unique_ptr<Rivet::Projection> clone() const {
0310         return std::unique_ptr<Projection>(new PrimaryParticles(*this));
0311       }
0312 
0313       /// Import to avoid warnings about overload-hiding
0314       using Projection::operator =;
0315 
0316 
0317     protected:
0318 
0319       /// Check PDG ID of particle @a p is in the list of accepted
0320       /// primaries.
0321       ///
0322       /// @param p Particle to investigate.
0323       ///
0324       /// @return true if the particle PDG ID is in the list of known
0325       /// primary PDG IDs.
0326       ///
0327       /// @note We explicitly override this to allow for nuclei, and we
0328       /// explicitly check for a specific set of particles (and
0329       /// anti-particles).  This means we do not use the base class
0330       /// list of particles.  Therefore, we also need to override the
0331       /// compare method.
0332       bool isPrimaryPID(ConstGenParticlePtr p) const {
0333         const int pdg = abs(p->pdg_id());
0334         // Check for nucleus
0335         if (pdg > 1000000000) return true;
0336 
0337         switch (pdg) {
0338         case Rivet::PID::MUON:
0339         case Rivet::PID::ELECTRON:
0340         case Rivet::PID::GAMMA:
0341         case Rivet::PID::PIPLUS:
0342         case Rivet::PID::KPLUS:
0343         case Rivet::PID::K0S:
0344         case Rivet::PID::K0L:
0345         case Rivet::PID::PROTON:
0346         case Rivet::PID::NEUTRON:
0347         case Rivet::PID::LAMBDA:
0348         case Rivet::PID::SIGMAMINUS:
0349         case Rivet::PID::SIGMAPLUS:
0350         case Rivet::PID::XIMINUS:
0351         case Rivet::PID::XI0:
0352         case Rivet::PID::OMEGAMINUS:
0353         case Rivet::PID::NU_E:
0354         case Rivet::PID::NU_MU:
0355         case Rivet::PID::NU_TAU:
0356           return true;
0357         }
0358         return false;
0359       }
0360 
0361     };
0362 
0363 
0364   }
0365 }
0366 
0367 #endif