diff --git a/DataFormats/Candidate/interface/Particle.h b/DataFormats/Candidate/interface/Particle.h index fd3c7397eea2f..555973ee1fab5 100755 --- a/DataFormats/Candidate/interface/Particle.h +++ b/DataFormats/Candidate/interface/Particle.h @@ -9,6 +9,9 @@ * * */ +#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__) +#include +#endif #include "DataFormats/Math/interface/Point3D.h" #include "DataFormats/Math/interface/Vector3D.h" #include "DataFormats/Math/interface/LorentzVector.h" @@ -29,136 +32,101 @@ namespace reco { /// point in the space typedef math::XYZVector Vector; /// default constructor - Particle() : - qx3_(0), pt_(0), eta_(0), phi_(0), mass_(0), - vertex_(0, 0, 0), pdgId_(0), status_(0), - cachePolarFixed_( false ) { } + Particle(); /// constructor from values Particle( Charge q, const LorentzVector & p4, const Point & vertex = Point( 0, 0, 0 ), - int pdgId = 0, int status = 0, bool integerCharge = true ) : - qx3_( q ), pt_( p4.pt() ), eta_( p4.eta() ), phi_( p4.phi() ), mass_( p4.mass() ), - vertex_( vertex ), pdgId_( pdgId ), status_( status ), - cachePolarFixed_( false ), cacheCartesianFixed_( false ) { - if ( integerCharge ) qx3_ *= 3; - } + int pdgId = 0, int status = 0, bool integerCharge = true ); /// constructor from values Particle( Charge q, const PolarLorentzVector & p4, const Point & vertex = Point( 0, 0, 0 ), - int pdgId = 0, int status = 0, bool integerCharge = true ) : - qx3_( q ), pt_( p4.pt() ), eta_( p4.eta() ), phi_( p4.phi() ), mass_( p4.mass() ), - vertex_( vertex ), pdgId_( pdgId ), status_( status ), - cachePolarFixed_( false ), cacheCartesianFixed_( false ) { - if ( integerCharge ) qx3_ *= 3; - } + int pdgId = 0, int status = 0, bool integerCharge = true ); + void swap(Particle& other); /// destructor - virtual ~Particle() { } + virtual ~Particle(); + // copy ctor + Particle(const Particle& srv); + // assignment operator + Particle& operator=(const Particle& rhs); /// electric charge - int charge() const { return qx3_ / 3; } + int charge() const; /// set electric charge - void setCharge( Charge q ) { qx3_ = q * 3; } + void setCharge( Charge q ); /// electric charge - int threeCharge() const { return qx3_; } + int threeCharge() const; /// set electric charge - void setThreeCharge( Charge qx3 ) { qx3_ = qx3; } + void setThreeCharge( Charge qx3 ); /// four-momentum Lorentz vector - const LorentzVector & p4() const { cacheCartesian(); return p4Cartesian_; } + const LorentzVector & p4() const; /// four-momentum Lorentz vector - const PolarLorentzVector & polarP4() const { cachePolar(); return p4Polar_; } + const PolarLorentzVector & polarP4() const; /// spatial momentum vector - Vector momentum() const { cacheCartesian(); return p4Cartesian_.Vect(); } + Vector momentum() const; /// boost vector to boost a Lorentz vector /// to the particle center of mass system - Vector boostToCM() const { cacheCartesian(); return p4Cartesian_.BoostToCM(); } + Vector boostToCM() const; /// magnitude of momentum vector - double p() const { cacheCartesian(); return p4Cartesian_.P(); } + double p() const; /// energy - double energy() const { cacheCartesian(); return p4Cartesian_.E(); } + double energy() const; /// transverse energy - double et() const { cachePolar(); return p4Polar_.Et(); } + double et() const; /// mass - double mass() const { return mass_; } + double mass() const; /// mass squared - double massSqr() const { return mass_ * mass_; } + double massSqr() const; /// transverse mass - double mt() const { cachePolar(); return p4Polar_.Mt(); } + double mt() const; /// transverse mass squared - double mtSqr() const { cachePolar(); return p4Polar_.Mt2(); } + double mtSqr() const; /// x coordinate of momentum vector - double px() const { cacheCartesian(); return p4Cartesian_.Px(); } + double px() const; /// y coordinate of momentum vector - double py() const { cacheCartesian(); return p4Cartesian_.Py(); } + double py() const; /// z coordinate of momentum vector - double pz() const { cacheCartesian(); return p4Cartesian_.Pz(); } + double pz() const; /// transverse momentum - double pt() const { return pt_; } + double pt() const; /// momentum azimuthal angle - double phi() const { return phi_; } + double phi() const; /// momentum polar angle - double theta() const { cacheCartesian(); return p4Cartesian_.Theta(); } + double theta() const; /// momentum pseudorapidity - double eta() const { return eta_; } + double eta() const; /// repidity - double rapidity() const { cachePolar(); return p4Polar_.Rapidity(); } + double rapidity() const; /// repidity - double y() const { return rapidity(); } + double y() const; /// set 4-momentum - void setP4( const LorentzVector & p4 ) { - p4Cartesian_ = p4; - p4Polar_ = p4; - pt_ = p4Polar_.pt(); - eta_ = p4Polar_.eta(); - phi_ = p4Polar_.phi(); - mass_ = p4Polar_.mass(); - cachePolarFixed_ = true; - cacheCartesianFixed_ = true; - } + void setP4( const LorentzVector & p4 ); /// set 4-momentum - void setP4( const PolarLorentzVector & p4 ) { - p4Polar_ = p4; - pt_ = p4Polar_.pt(); - eta_ = p4Polar_.eta(); - phi_ = p4Polar_.phi(); - mass_ = p4Polar_.mass(); - cachePolarFixed_ = true; - cacheCartesianFixed_ = false; - } + void setP4( const PolarLorentzVector & p4 ); /// set particle mass - void setMass( double m ) { - mass_ = m; - clearCache(); - } - void setPz( double pz ) { - cacheCartesian(); - p4Cartesian_.SetPz(pz); - p4Polar_ = p4Cartesian_; - pt_ = p4Polar_.pt(); - eta_ = p4Polar_.eta(); - phi_ = p4Polar_.phi(); - mass_ = p4Polar_.mass(); - } + void setMass( double m ); + /// set Pz + void setPz( double pz ); /// vertex position - const Point & vertex() const { return vertex_; } + const Point & vertex() const; /// x coordinate of vertex position - double vx() const { return vertex_.X(); } + double vx() const; /// y coordinate of vertex position - double vy() const { return vertex_.Y(); } + double vy() const; /// z coordinate of vertex position - double vz() const { return vertex_.Z(); } + double vz() const; /// set vertex - void setVertex( const Point & vertex ) { vertex_ = vertex; } + void setVertex( const Point & vertex ); /// PDG identifier - int pdgId() const { return pdgId_; } + int pdgId() const; // set PDG identifier - void setPdgId( int pdgId ) { pdgId_ = pdgId; } + void setPdgId( int pdgId ); /// status word - int status() const { return status_; } + int status() const; /// set status word - void setStatus( int status ) { status_ = status; } + void setStatus( int status ); /// long lived flag static const unsigned int longLivedTag; /// set long lived flag - void setLongLived() { status_ |= longLivedTag; } + void setLongLived(); /// is long lived? - bool longLived() const { return status_ & longLivedTag; } + bool longLived() const; protected: /// electric charge @@ -171,30 +139,23 @@ namespace reco { int pdgId_; /// status word int status_; +#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__) + /// internal cache for p4 + mutable std::atomic p4Polar_; /// internal cache for p4 - mutable PolarLorentzVector p4Polar_; + mutable std::atomic p4Cartesian_; +#else /// internal cache for p4 - mutable LorentzVector p4Cartesian_; - /// has cache been set? - mutable bool cachePolarFixed_, cacheCartesianFixed_; + mutable PolarLorentzVector* p4Polar_; + /// internal cache for p4 + mutable LorentzVector* p4Cartesian_; +#endif /// set internal cache - inline void cachePolar() const { - if ( cachePolarFixed_ ) return; - p4Polar_ = PolarLorentzVector( pt_, eta_, phi_, mass_ ); - cachePolarFixed_ = true; - } + void cachePolar() const; /// set internal cache - inline void cacheCartesian() const { - if ( cacheCartesianFixed_ ) return; - cachePolar(); - p4Cartesian_ = p4Polar_; - cacheCartesianFixed_ = true; - } + void cacheCartesian() const; /// clear internal cache - inline void clearCache() const { - cachePolarFixed_ = false; - cacheCartesianFixed_ = false; - } + void clearCache() const; }; } diff --git a/DataFormats/Candidate/src/Particle.cc b/DataFormats/Candidate/src/Particle.cc index 71a37155f4643..dda3527823d3f 100755 --- a/DataFormats/Candidate/src/Particle.cc +++ b/DataFormats/Candidate/src/Particle.cc @@ -1,3 +1,295 @@ #include "DataFormats/Candidate/interface/Particle.h" +#include const unsigned int reco::Particle::longLivedTag = 65536; + +using namespace reco; + +/// default constructor +Particle::Particle() + : qx3_(0), pt_(0), eta_(0), phi_(0), mass_(0), + vertex_(0, 0, 0), pdgId_(0), status_(0), + p4Polar_(nullptr), p4Cartesian_(nullptr) +{ +} +/// constructor from values +Particle::Particle( Charge q, const LorentzVector & p4, const Point & vertex, + int pdgId, int status, bool integerCharge) + : qx3_( q ), pt_( p4.pt() ), eta_( p4.eta() ), phi_( p4.phi() ), mass_( p4.mass() ), + vertex_( vertex ), pdgId_( pdgId ), status_( status ), + p4Polar_(nullptr), p4Cartesian_(nullptr) +{ + if ( integerCharge ) qx3_ *= 3; +} +/// constructor from values +Particle::Particle( Charge q, const PolarLorentzVector & p4, const Point & vertex, + int pdgId, int status, bool integerCharge) + : qx3_( q ), pt_( p4.pt() ), eta_( p4.eta() ), phi_( p4.phi() ), mass_( p4.mass() ), + vertex_( vertex ), pdgId_( pdgId ), status_( status ), + p4Polar_(nullptr), p4Cartesian_(nullptr) +{ + if ( integerCharge ) qx3_ *= 3; +} +// copy-ctor +Particle::Particle(const Particle& src) + : qx3_(src.qx3_), pt_(src.pt_), eta_(src.eta_), phi_(src.phi_), mass_(src.mass_), + vertex_(src.vertex_), pdgId_(src.pdgId_), status_(src.status_), + p4Polar_(nullptr), p4Cartesian_(nullptr) +{ +} +// copy assignment operator +Particle& +Particle::operator=(const Particle& rhs) { + Particle temp(rhs); + temp.swap(*this); + return *this; +} +// public swap function +void Particle::swap(Particle& other) { + std::swap(qx3_, other.qx3_); + std::swap(pt_, other.pt_); + std::swap(eta_, other.eta_); + std::swap(phi_, other.phi_); + std::swap(mass_, other.mass_); + std::swap(vertex_, other.vertex_); + std::swap(pdgId_, other.pdgId_); + std::swap(status_, other.status_); + other.p4Polar_.exchange( + p4Polar_.exchange(other.p4Polar_, std::memory_order_acq_rel), + std::memory_order_acq_rel); + other.p4Cartesian_.exchange( + p4Cartesian_.exchange(other.p4Cartesian_, std::memory_order_acq_rel), + std::memory_order_acq_rel); +} +/// dtor +Particle::~Particle() { + clearCache(); +} + +/// electric charge +int Particle::charge() const { + return qx3_ / 3; +} +/// set electric charge +void Particle::setCharge( Charge q ) { + qx3_ = q * 3; +} +/// electric charge +int Particle::threeCharge() const { + return qx3_; +} +/// set electric charge +void Particle::setThreeCharge( Charge qx3 ) { + qx3_ = qx3; +} +/// four-momentum Lorentz vector +const Particle::LorentzVector & Particle::p4() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)); +} +/// four-momentum Lorentz vector +const Particle::PolarLorentzVector & Particle::polarP4() const { + cachePolar(); + return (*p4Polar_.load(std::memory_order_acquire)); +} +/// spatial momentum vector +Particle::Vector Particle::momentum() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).Vect(); +} +/// boost vector to boost a Lorentz vector +/// to the particle center of mass system +Particle::Vector Particle::boostToCM() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).BoostToCM(); +} +/// magnitude of momentum vector +double Particle::p() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).P(); +} +/// energy +double Particle::energy() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).E(); +} +/// transverse energy +double Particle::et() const { + cachePolar(); + return (*p4Polar_.load(std::memory_order_acquire)).Et(); +} +/// mass +double Particle::mass() const { + return mass_; +} +/// mass squared +double Particle::massSqr() const { + return mass_ * mass_; +} +/// transverse mass +double Particle::mt() const { + cachePolar(); + return (*p4Polar_.load(std::memory_order_acquire)).Mt(); +} +/// transverse mass squared +double Particle::mtSqr() const { + cachePolar(); + return (*p4Polar_.load(std::memory_order_acquire)).Mt2(); +} +/// x coordinate of momentum vector +double Particle::px() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).Px(); +} +/// y coordinate of momentum vector +double Particle::py() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).Py(); +} +/// z coordinate of momentum vector +double Particle::pz() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).Pz(); +} +/// transverse momentum +double Particle::pt() const { + return pt_; +} +/// momentum azimuthal angle +double Particle::phi() const { + return phi_; +} +/// momentum polar angle +double Particle::theta() const { + cacheCartesian(); + return (*p4Cartesian_.load(std::memory_order_acquire)).Theta(); +} +/// momentum pseudorapidity +double Particle::eta() const { + return eta_; +} +/// repidity +double Particle::rapidity() const { + cachePolar(); + return (*p4Polar_.load(std::memory_order_acquire)).Rapidity(); +} +/// repidity +double Particle::y() const { + return rapidity(); +} + +/// set 4-momentum +void Particle::setP4( const LorentzVector & p4 ) { + // ensure that we have non-null pointers + cacheCartesian(); + *p4Cartesian_.load(std::memory_order_acquire) = p4; + // ensure that we have non-null pointers + cachePolar(); + *p4Polar_.load(std::memory_order_acquire) = p4; + auto const* p4Polar = p4Polar_.load(std::memory_order_acquire); + pt_ = p4Polar->pt(); + eta_ = p4Polar->eta(); + phi_ = p4Polar->phi(); + mass_ = p4Polar->mass(); +} +/// set 4-momentum +void Particle::setP4( const PolarLorentzVector & p4 ) { + // ensure that we have non-null pointers + cachePolar(); + *p4Polar_.load(std::memory_order_acquire) = p4; + auto const* p4Polar = p4Polar_.load(std::memory_order_acquire); + pt_ = p4Polar->pt(); + eta_ = p4Polar->eta(); + phi_ = p4Polar->phi(); + mass_ = p4Polar->mass(); + delete p4Cartesian_.exchange(nullptr, std::memory_order_acq_rel); +} +/// set particle mass +void Particle::setMass( double m ) { + mass_ = m; + clearCache(); +} +void Particle::setPz( double pz ) { + // ensure that we have non-null pointers + cacheCartesian(); + (*p4Cartesian_.load(std::memory_order_acquire)).SetPz(pz); + // ensure that we have non-null pointers + cachePolar(); + (*p4Polar_.load(std::memory_order_acquire)) = (*p4Cartesian_.load(std::memory_order_acquire)); + auto const* p4Polar = p4Polar_.load(std::memory_order_acquire); + pt_ = p4Polar->pt(); + eta_ = p4Polar->eta(); + phi_ = p4Polar->phi(); + mass_ = p4Polar->mass(); +} + +const Particle::Point & Particle::vertex() const { + return vertex_; +} +/// x coordinate of vertex position +double Particle::vx() const { + return vertex_.X(); +} +/// y coordinate of vertex position +double Particle::vy() const { + return vertex_.Y(); +} +/// z coordinate of vertex position +double Particle::vz() const { + return vertex_.Z(); +} +/// set vertex +void Particle::setVertex( const Point & vertex ) { + vertex_ = vertex; +} +/// PDG identifier +int Particle::pdgId() const { + return pdgId_; +} +// set PDG identifier +void Particle::setPdgId( int pdgId ) { + pdgId_ = pdgId; +} +/// status word +int Particle::status() const { + return status_; +} +/// set status word +void Particle::setStatus( int status ) { + status_ = status; +} +/// set long lived flag +void Particle::setLongLived() { + status_ |= longLivedTag; +} +/// is long lived? +bool Particle::longLived() const { + return status_ & longLivedTag; +} + +/// set internal cache +void Particle::cachePolar() const { + if(!p4Polar_.load(std::memory_order_acquire)) { + std::unique_ptr ptr{new PolarLorentzVector(pt_,eta_,phi_,mass_)}; + PolarLorentzVector* expect = nullptr; + if(p4Polar_.compare_exchange_strong(expect, ptr.get(), std::memory_order_acq_rel)) { + ptr.release(); + } + } +} +/// set internal cache +void Particle::cacheCartesian() const { + if(!p4Cartesian_.load(std::memory_order_acquire)) { + cachePolar(); + std::unique_ptr ptr{new LorentzVector(*p4Polar_.load(std::memory_order_acquire))}; + LorentzVector* expected = nullptr; + if( p4Cartesian_.compare_exchange_strong(expected, ptr.get(), std::memory_order_acq_rel) ) { + ptr.release(); + } + } +} +/// clear internal cache +void Particle::clearCache() const { + delete p4Polar_.exchange(nullptr, std::memory_order_acq_rel); + delete p4Cartesian_.exchange(nullptr, std::memory_order_acq_rel); +} diff --git a/DataFormats/Candidate/src/classes_def.xml b/DataFormats/Candidate/src/classes_def.xml index 05783b226c30e..c2f2e7dc26d61 100755 --- a/DataFormats/Candidate/src/classes_def.xml +++ b/DataFormats/Candidate/src/classes_def.xml @@ -4,16 +4,14 @@ - - - - + + - - + + diff --git a/DataFormats/HLTReco/BuildFile.xml b/DataFormats/HLTReco/BuildFile.xml index ffe7152e21193..5e5d9f9af7cef 100644 --- a/DataFormats/HLTReco/BuildFile.xml +++ b/DataFormats/HLTReco/BuildFile.xml @@ -1,6 +1,7 @@ +