CMS 3D CMS Logo

RealisticSimClusterMapper.cc
Go to the documentation of this file.
1 // Author: Felice Pantaleo
3 // Date: 30/06/2017
4 // Email: felice@cern.ch
6 #include <unordered_map>
9 
14 
15 #ifdef PFLOW_DEBUG
16 #define LOGVERB(x) edm::LogVerbatim(x)
17 #define LOGWARN(x) edm::LogWarning(x)
18 #define LOGERR(x) edm::LogError(x)
19 #define LOGDRESSED(x) edm::LogInfo(x)
20 #else
21 #define LOGVERB(x) LogTrace(x)
22 #define LOGWARN(x) edm::LogWarning(x)
23 #define LOGERR(x) edm::LogError(x)
24 #define LOGDRESSED(x) LogDebug(x)
25 #endif
26 
27 namespace {
28 
29 inline
30 bool isPi0(int pdgId)
31 {
32  return pdgId == 111;
33 }
34 
35 inline
36 bool isEGamma(int pdgId)
37 {
38  pdgId = std::abs(pdgId);
39  return (pdgId == 11) or (pdgId == 22);
40 }
41 
42 inline
43 bool isHadron(int pdgId)
44 {
45  pdgId = std::abs(pdgId) % 10000;
46  return ((pdgId > 100 and pdgId < 900) or
47  (pdgId > 1000 and pdgId < 9000));
48 }
49 }
50 
52 {
54 }
55 
57 {
59 }
60 
62  const std::vector<bool>& rechitMask, const std::vector<bool>& seedable,
64 {
65  const SimClusterCollection& simClusters = *simClusterH_;
66  auto const& hits = *input;
67  RealisticHitToClusterAssociator realisticAssociator;
68  const int numberOfLayers = rhtools_.getLayer(ForwardSubdetector::ForwardEmpty);
69  realisticAssociator.init(hits.size(), simClusters.size(), numberOfLayers + 1);
70  // for quick indexing back to hit energy
71  std::unordered_map < uint32_t, size_t > detIdToIndex(hits.size());
72  for (uint32_t i = 0; i < hits.size(); ++i)
73  {
74  detIdToIndex[hits[i].detId()] = i;
75  auto ref = makeRefhit(input, i);
76  const auto& hitPos = rhtools_.getPosition(ref->detId());
77 
78  realisticAssociator.insertHitPosition(hitPos.x(), hitPos.y(), hitPos.z(), i);
79  realisticAssociator.insertHitEnergy(ref->energy(), i);
80  realisticAssociator.insertLayerId(rhtools_.getLayerWithOffset(ref->detId()), i);
81 
82  }
83 
84  for (unsigned int ic = 0; ic < simClusters.size(); ++ic)
85  {
86  const auto & sc = simClusters[ic];
87  const auto& hitsAndFractions = sc.hits_and_fractions();
88  for (const auto& hAndF : hitsAndFractions)
89  {
90  auto itr = detIdToIndex.find(hAndF.first);
91  if (itr == detIdToIndex.end())
92  {
93  continue; // hit wasn't saved in reco or did not pass the SNR threshold
94  }
95  auto hitId = itr->second;
96  auto ref = makeRefhit(input, hitId);
97  float fraction = hAndF.second;
98  float associatedEnergy = fraction * ref->energy();
99  realisticAssociator.insertSimClusterIdAndFraction(ic, fraction, hitId,
100  associatedEnergy);
101  }
102  }
106  realisticAssociator.findCentersOfGravity();
108  realisticAssociator.filterHitsByDistance(maxDistance_);
109 
110  const auto& realisticClusters = realisticAssociator.realisticClusters();
111  unsigned int nClusters = realisticClusters.size();
112  for (unsigned ic = 0; ic < nClusters; ++ic)
113  {
114  float highest_energy = 0.0f;
115  output.emplace_back();
116  reco::PFCluster& back = output.back();
118  float energyCorrection = 1.f;
119  if (realisticClusters[ic].isVisible())
120  {
121  int pdgId = simClusters[ic].pdgId();
122  auto abseta = std::abs(simClusters[ic].eta());
123  if ((abseta >= calibMinEta_) and (abseta <= calibMaxEta_)) //protecting range
124  {
125  if ((isEGamma(pdgId) or isPi0(pdgId)) and !egammaCalib_.empty())
126  {
127  unsigned int etabin = std::floor(
128  ((abseta - calibMinEta_) * egammaCalib_.size())
129  / (calibMaxEta_ - calibMinEta_));
130 
131  energyCorrection = egammaCalib_[etabin];
132  }
133  else if (isHadron(pdgId) and !(isPi0(pdgId)) and !hadronCalib_.empty()) // this function is expensive.. should we treat as hadron everything which is not egamma?
134  {
135  unsigned int etabin = std::floor(
136  ((abseta - calibMinEta_) * hadronCalib_.size())
137  / (calibMaxEta_ - calibMinEta_));
138  energyCorrection = hadronCalib_[etabin];
139  }
140 
141  }
142  const auto& hitsIdsAndFractions = realisticClusters[ic].hitsIdsAndFractions();
143  for (const auto& idAndF : hitsIdsAndFractions)
144  {
145  auto fraction = idAndF.second;
146  if (fraction > 0.f)
147  {
148  auto ref = makeRefhit(input, idAndF.first);
150  const float hit_energy = fraction * ref->energy();
151  if (hit_energy > highest_energy || highest_energy == 0.0)
152  {
153  highest_energy = hit_energy;
154  seed = ref;
155  }
156  }
157  }
158  }
159  if (!back.hitsAndFractions().empty())
160  {
161  back.setSeed(seed->detId());
162  back.setEnergy(realisticClusters[ic].getEnergy());
163  back.setCorrectedEnergy(energyCorrection*realisticClusters[ic].getEnergy()); //applying energy correction
164  }
165  else
166  {
167  back.setSeed(-1);
168  back.setEnergy(0.f);
169  }
170  }
171 }
172 
void insertLayerId(unsigned int layerId, unsigned int hitIndex)
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
void buildClusters(const edm::Handle< reco::PFRecHitCollection > &, const std::vector< bool > &, const std::vector< bool > &, reco::PFClusterCollection &) override
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:210
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:519
double getEnergy(HBHERecHitCollection::const_iterator hit, int useRaw=0, bool debug=false)
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
void setEnergy(double energy)
Definition: CaloCluster.h:111
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:195
bool ev
static std::string const input
Definition: EdmProvDump.cc:44
void setSeed(const DetId &id)
Definition: CaloCluster.h:121
reco::PFRecHitRef makeRefhit(const edm::Handle< reco::PFRecHitCollection > &h, const unsigned i) const
void getEventSetup(const edm::EventSetup &)
Definition: RecHitTools.cc:61
void init(std::size_t numberOfHits, std::size_t numberOfSimClusters, std::size_t numberOfLayers)
void setCorrectedEnergy(double cenergy)
Definition: CaloCluster.h:112
void insertSimClusterIdAndFraction(unsigned int scIdx, float fraction, unsigned int hitIndex, float associatedEnergy)
void computeAssociation(float exclusiveFraction, bool useMCFractionsForExclEnergy, unsigned int fhOffset, unsigned int bhOffset)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void findAndMergeInvisibleClusters(float invisibleFraction, float exclusiveFraction)
void insertHitPosition(float x, float y, float z, unsigned int hitIndex)
double f[11][100]
unsigned int lastLayerEE() const
Definition: RecHitTools.h:52
void update(const edm::EventSetup &) final
unsigned int getLayer(ForwardSubdetector type) const
Definition: RecHitTools.cc:134
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:179
edm::EDGetTokenT< SimClusterCollection > simClusterToken_
void insertHitEnergy(float energy, unsigned int hitIndex)
std::vector< double > egammaCalib_
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:77
void updateEvent(const edm::Event &) final
const std::vector< RealisticCluster > & realisticClusters() const
void addRecHitFraction(const reco::PFRecHitFraction &frac)
add a given fraction of the rechit
Definition: PFCluster.cc:99
std::vector< double > hadronCalib_
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
edm::Handle< SimClusterCollection > simClusterH_
std::vector< SimCluster > SimClusterCollection
Definition: SimClusterFwd.h:8
unsigned int lastLayerFH() const
Definition: RecHitTools.h:53