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 
16 
17 #ifdef PFLOW_DEBUG
18 #define LOGVERB(x) edm::LogVerbatim(x)
19 #define LOGWARN(x) edm::LogWarning(x)
20 #define LOGERR(x) edm::LogError(x)
21 #define LOGDRESSED(x) edm::LogInfo(x)
22 #else
23 #define LOGVERB(x) LogTrace(x)
24 #define LOGWARN(x) edm::LogWarning(x)
25 #define LOGERR(x) edm::LogError(x)
26 #define LOGDRESSED(x) LogDebug(x)
27 #endif
28 
29 namespace {
30 
31 inline
32 bool isPi0(int pdgId)
33 {
34  return pdgId == 111;
35 }
36 
37 inline
38 bool isEGamma(int pdgId)
39 {
40  pdgId = std::abs(pdgId);
41  return (pdgId == 11) or (pdgId == 22);
42 }
43 
44 inline
45 bool isHadron(int pdgId)
46 {
47  pdgId = std::abs(pdgId) % 10000;
48  return ((pdgId > 100 and pdgId < 900) or
49  (pdgId > 1000 and pdgId < 9000));
50 }
51 }
52 
54 {
56 }
57 
59 {
61 }
62 
64  const std::vector<bool>& rechitMask, const std::vector<bool>& seedable,
66 {
67  const SimClusterCollection& simClusters = *simClusterH_;
68  auto const& hits = *input;
69  RealisticHitToClusterAssociator realisticAssociator;
71  realisticAssociator.init(hits.size(), simClusters.size(), numberOfLayers + 1);
72  // for quick indexing back to hit energy
73  std::unordered_map < uint32_t, size_t > detIdToIndex(hits.size());
74  for (uint32_t i = 0; i < hits.size(); ++i)
75  {
76  detIdToIndex[hits[i].detId()] = i;
77  auto ref = makeRefhit(input, i);
78  const auto& hitPos = rhtools_.getPosition(ref->detId());
79 
80  realisticAssociator.insertHitPosition(hitPos.x(), hitPos.y(), hitPos.z(), i);
81  realisticAssociator.insertHitEnergy(ref->energy(), i);
82  realisticAssociator.insertLayerId(rhtools_.getLayerWithOffset(ref->detId()), i);
83 
84  }
85 
86  for (unsigned int ic = 0; ic < simClusters.size(); ++ic)
87  {
88  const auto & sc = simClusters[ic];
89  const auto& hitsAndFractions = sc.hits_and_fractions();
90  for (const auto& hAndF : hitsAndFractions)
91  {
92  auto itr = detIdToIndex.find(hAndF.first);
93  if (itr == detIdToIndex.end())
94  {
95  continue; // hit wasn't saved in reco or did not pass the SNR threshold
96  }
97  auto hitId = itr->second;
98  auto ref = makeRefhit(input, hitId);
99  float fraction = hAndF.second;
100  float associatedEnergy = fraction * ref->energy();
101  realisticAssociator.insertSimClusterIdAndFraction(ic, fraction, hitId,
102  associatedEnergy);
103  }
104  }
108  realisticAssociator.findCentersOfGravity();
110  realisticAssociator.filterHitsByDistance(maxDistance_);
111 
112  const auto& realisticClusters = realisticAssociator.realisticClusters();
113  unsigned int nClusters = realisticClusters.size();
114  float bin_norm = 1. / (calibMaxEta_ - calibMinEta_);
115  float egamma_bin_norm = egammaCalib_.size() * bin_norm;
116  float hadron_bin_norm = hadronCalib_.size() * bin_norm;
117  for (unsigned ic = 0; ic < nClusters; ++ic)
118  {
119  float highest_energy = 0.0f;
120  output.emplace_back();
121  reco::PFCluster& back = output.back();
123  float energyCorrection = 1.f;
124  float timeRealisticSC = -99.;
125  if (realisticClusters[ic].isVisible())
126  {
127  int pdgId = simClusters[ic].pdgId();
128  auto abseta = std::abs(simClusters[ic].eta());
129  if ((abseta >= calibMinEta_) and (abseta <= calibMaxEta_)) //protecting range
130  {
131  if ((isEGamma(pdgId) or isPi0(pdgId)) and !egammaCalib_.empty())
132  {
133  unsigned int etabin = std::floor(
134  ((abseta - calibMinEta_) * egamma_bin_norm));
135  energyCorrection = egammaCalib_[etabin];
136  }
137  else if (isHadron(pdgId) and !(isPi0(pdgId)) and !hadronCalib_.empty()) // this function is expensive.. should we treat as hadron everything which is not egamma?
138  {
139  unsigned int etabin = std::floor(
140  ((abseta - calibMinEta_) * hadron_bin_norm));
141  energyCorrection = hadronCalib_[etabin];
142  }
143 
144  }
145  std::vector<float> timeHits;
146  const auto& hitsIdsAndFractions = realisticClusters[ic].hitsIdsAndFractions();
147  for (const auto& idAndF : hitsIdsAndFractions)
148  {
149  auto fraction = idAndF.second;
150  if (fraction > 0.f)
151  {
152  auto ref = makeRefhit(input, idAndF.first);
154  const float hit_energy = fraction * ref->energy();
155  if (hit_energy > highest_energy || highest_energy == 0.0)
156  {
157  highest_energy = hit_energy;
158  seed = ref;
159  }
160  //select hits good for timing
161  if(ref->time() > -1. ){
162  int rhLayer = rhtools_.getLayerWithOffset(ref->detId());
163  std::array<float,3> scPosition = realisticClusters[ic].getCenterOfGravity(rhLayer);
164  float distanceSquared = std::pow((ref->position().x() - scPosition[0]),2) + std::pow((ref->position().y() - scPosition[1]),2);
165  if(distanceSquared < maxDforTimingSquared_){
166  timeHits.push_back(ref->time() - timeOffset_);
167  }
168  }
169  }
170  }
171  //assign time if minimum number of hits
172  if(timeHits.size() >= minNHitsforTiming_) timeRealisticSC = hgcalsimclustertime::fixSizeHighestDensity(timeHits);
173  }
174  if (!back.hitsAndFractions().empty())
175  {
176  back.setSeed(seed->detId());
177  back.setEnergy(realisticClusters[ic].getEnergy());
178  back.setCorrectedEnergy(energyCorrection*realisticClusters[ic].getEnergy()); //applying energy correction
179  back.setTime(timeRealisticSC);
180  }
181  else
182  {
183  back.setSeed(-1);
184  back.setEnergy(0.f);
185  }
186  }
187 }
188 
float fixSizeHighestDensity(std::vector< float > &t, float deltaT=0.210, float timeWidthBy=0.5)
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:579
double getEnergy(HBHERecHitCollection::const_iterator hit, int useRaw=0, bool debug=false)
unsigned int getLayer(DetId::Detector type) const
Definition: RecHitTools.cc:249
void setTime(float time, float timeError=0)
Definition: PFCluster.h:92
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
void setEnergy(double energy)
Definition: CaloCluster.h:113
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:197
bool ev
static std::string const input
Definition: EdmProvDump.cc:44
void setSeed(const DetId &id)
Definition: CaloCluster.h:123
reco::PFRecHitRef makeRefhit(const edm::Handle< reco::PFRecHitCollection > &h, const unsigned i) const
void getEventSetup(const edm::EventSetup &)
Definition: RecHitTools.cc:79
void init(std::size_t numberOfHits, std::size_t numberOfSimClusters, std::size_t numberOfLayers)
void setCorrectedEnergy(double cenergy)
Definition: CaloCluster.h:114
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:58
void update(const edm::EventSetup &) final
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:294
edm::EDGetTokenT< SimClusterCollection > simClusterToken_
void insertHitEnergy(float energy, unsigned int hitIndex)
std::vector< double > egammaCalib_
int getGeometryType() const
Definition: RecHitTools.h:61
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:116
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
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
unsigned int lastLayerFH() const
Definition: RecHitTools.h:59