Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-03 02:23:29

0001 #ifndef DataFormats_ParticleFlowReco_PFCluster_h
0002 #define DataFormats_ParticleFlowReco_PFCluster_h
0003 
0004 #include <iostream>
0005 #include <vector>
0006 #include <algorithm>
0007 
0008 #include <Rtypes.h>
0009 
0010 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
0011 #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
0012 #include "DataFormats/Math/interface/Point3D.h"
0013 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
0014 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
0015 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
0016 #include "Math/GenVector/PositionVector3D.h"
0017 
0018 class PFClusterAlgo;
0019 
0020 namespace reco {
0021 
0022   /**\class PFCluster
0023      \brief Particle flow cluster, see clustering algorithm in PFClusterAlgo
0024      
0025      A particle flow cluster is defined by its energy and position, which are 
0026      calculated from a vector of PFRecHitFraction. This calculation is 
0027      performed in PFClusterAlgo.
0028 
0029      \todo Clean up this class to a common base (talk to Paolo Meridiani)
0030      the extra internal stuff (like the vector of PFRecHitFraction's)
0031      could be moved to a PFClusterExtra.
0032      
0033      \todo Now that PFRecHitFraction's hold a reference to the PFRecHit's, 
0034      put back the calculation of energy and position to PFCluster. 
0035 
0036 
0037      \todo Add an operator+=
0038 
0039      \author Colin Bernet
0040      \date   July 2006
0041   */
0042   class PFCluster : public CaloCluster {
0043   public:
0044     typedef std::vector<std::pair<CaloClusterPtr::key_type, edm::Ptr<PFCluster>>> EEtoPSAssociation;
0045     // Next typedef uses double in ROOT 6 rather than Double32_t due to a bug in ROOT 5,
0046     // which otherwise would make ROOT5 files unreadable in ROOT6.  This does not increase
0047     // the size on disk, because due to the bug, double was actually stored on disk in ROOT 5.
0048     typedef ROOT::Math::PositionVector3D<ROOT::Math::CylindricalEta3D<double>> REPPoint;
0049 
0050     PFCluster() : CaloCluster(CaloCluster::particleFlow), time_(-99.0), layer_(PFLayer::NONE) {}
0051 
0052     /// constructor
0053     PFCluster(PFLayer::Layer layer, double energy, double x, double y, double z);
0054 
0055     /// resets clusters parameters
0056     void reset();
0057 
0058     /// reset only hits and fractions
0059     void resetHitsAndFractions();
0060 
0061     /// add a given fraction of the rechit
0062     void addRecHitFraction(const reco::PFRecHitFraction& frac);
0063 
0064     /// vector of rechit fractions
0065     const std::vector<reco::PFRecHitFraction>& recHitFractions() const { return rechits_; }
0066 
0067     /// set layer
0068     void setLayer(PFLayer::Layer layer);
0069 
0070     /// cluster layer, see PFLayer.h in this directory
0071     PFLayer::Layer layer() const;
0072 
0073     /// cluster energy
0074     double energy() const { return energy_; }
0075 
0076     /// \return cluster time
0077     float time() const { return time_; }
0078     /// \return the timing uncertainty
0079     float timeError() const { return timeError_; }
0080 
0081     /// cluster depth
0082     double depth() const { return depth_; }
0083 
0084     void setTime(float time, float timeError = 0) {
0085       time_ = time;
0086       timeError_ = timeError;
0087     }
0088     void setTimeError(float timeError) { timeError_ = timeError; }
0089     void setDepth(double depth) { depth_ = depth; }
0090 
0091     /// cluster position: rho, eta, phi
0092     const REPPoint& positionREP() const { return posrep_; }
0093 
0094     /// computes posrep_ once and for all
0095     void calculatePositionREP() { posrep_.SetCoordinates(position_.Rho(), position_.Eta(), position_.Phi()); }
0096 
0097     /// \todo move to PFClusterTools
0098     static double getDepthCorrection(double energy, bool isBelowPS = false, bool isHadron = false);
0099 
0100     PFCluster& operator=(const PFCluster&);
0101 
0102     /// some classes to make this fit into a template footprint
0103     /// for RecoPFClusterRefCandidate so we can make jets and MET
0104     /// out of PFClusters.
0105 
0106     /// dummy charge
0107     double charge() const { return 0; }
0108 
0109     /// transverse momentum, massless approximation
0110     double pt() const { return (energy() * sin(position_.theta())); }
0111 
0112     /// angle
0113     double theta() const { return position_.theta(); }
0114 
0115     /// dummy vertex access
0116     math::XYZPoint const& vertex() const { return dummyVtx_; }
0117     double vx() const { return vertex().x(); }
0118     double vy() const { return vertex().y(); }
0119     double vz() const { return vertex().z(); }
0120 
0121 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0122     template <typename pruner>
0123     void pruneUsing(pruner prune) {
0124       // remove_if+erase algo applied to both vectors...
0125       auto iter = std::find_if_not(rechits_.begin(), rechits_.end(), prune);
0126       if (iter == rechits_.end())
0127         return;
0128       auto first = iter - rechits_.begin();
0129       for (auto i = first; ++i < int(rechits_.size());) {
0130         if (prune(rechits_[i])) {
0131           rechits_[first] = std::move(rechits_[i]);
0132           hitsAndFractions_[first] = std::move(hitsAndFractions_[i]);
0133           ++first;
0134         }
0135       }
0136       rechits_.erase(rechits_.begin() + first, rechits_.end());
0137       hitsAndFractions_.erase(hitsAndFractions_.begin() + first, hitsAndFractions_.end());
0138     }
0139 #endif
0140 
0141   private:
0142     /// vector of rechit fractions (transient)
0143     std::vector<reco::PFRecHitFraction> rechits_;
0144 
0145     /// cluster position: rho, eta, phi (transient)
0146     REPPoint posrep_;
0147 
0148     /// Michalis: add timing and depth information
0149     float time_;
0150     float timeError_{0};
0151     double depth_{0};
0152 
0153     /// transient layer
0154     PFLayer::Layer layer_;
0155 
0156     /// depth corrections
0157     static const constexpr double depthCorA_ = 0.89;
0158     static const constexpr double depthCorB_ = 7.3;
0159     static const constexpr double depthCorAp_ = 0.89;
0160     static const constexpr double depthCorBp_ = 4.0;
0161 
0162     static const math::XYZPoint dummyVtx_;
0163   };
0164 
0165   std::ostream& operator<<(std::ostream& out, const PFCluster& cluster);
0166 
0167 }  // namespace reco
0168 
0169 #endif  // DataFormats_ParticleFlowReco_PFCluster_h