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 bool isPi0(int pdgId) { return pdgId == 111; }
32 
33  inline bool isEGamma(int pdgId) {
34  pdgId = std::abs(pdgId);
35  return (pdgId == 11) or (pdgId == 22);
36  }
37 
38  inline bool isHadron(int pdgId) {
39  pdgId = std::abs(pdgId) % 10000;
40  return ((pdgId > 100 and pdgId < 900) or (pdgId > 1000 and pdgId < 9000));
41  }
42 } // namespace
43 
45 
47 
49  const std::vector<bool>& rechitMask,
50  const std::vector<bool>& seedable,
52  const SimClusterCollection& simClusters = *simClusterH_;
53  auto const& hits = *input;
54  RealisticHitToClusterAssociator realisticAssociator;
57  realisticAssociator.init(hits.size(), simClusters.size(), numberOfLayers + 1);
58  // for quick indexing back to hit energy
59  std::unordered_map<uint32_t, size_t> detIdToIndex(hits.size());
60  for (uint32_t i = 0; i < hits.size(); ++i) {
61  detIdToIndex[hits[i].detId()] = i;
62  auto ref = makeRefhit(input, i);
63  const auto& hitPos = rhtools_.getPosition(ref->detId());
64 
65  realisticAssociator.insertHitPosition(hitPos.x(), hitPos.y(), hitPos.z(), i);
66  realisticAssociator.insertHitEnergy(ref->energy(), i);
67  realisticAssociator.insertLayerId(rhtools_.getLayerWithOffset(ref->detId()), i);
68  }
69 
70  for (unsigned int ic = 0; ic < simClusters.size(); ++ic) {
71  const auto& sc = simClusters[ic];
72  const auto& hitsAndFractions = sc.hits_and_fractions();
73  for (const auto& hAndF : hitsAndFractions) {
74  auto itr = detIdToIndex.find(hAndF.first);
75  if (itr == detIdToIndex.end()) {
76  continue; // hit wasn't saved in reco or did not pass the SNR threshold
77  }
78  auto hitId = itr->second;
79  auto ref = makeRefhit(input, hitId);
80  float fraction = hAndF.second;
81  float associatedEnergy = fraction * ref->energy();
82  realisticAssociator.insertSimClusterIdAndFraction(ic, fraction, hitId, associatedEnergy);
83  }
84  }
85  realisticAssociator.computeAssociation(
88  realisticAssociator.findCentersOfGravity();
90  realisticAssociator.filterHitsByDistance(maxDistance_);
91 
92  const auto& realisticClusters = realisticAssociator.realisticClusters();
93  unsigned int nClusters = realisticClusters.size();
94  float bin_norm = 1. / (calibMaxEta_ - calibMinEta_);
95  float egamma_bin_norm = egammaCalib_.size() * bin_norm;
96  float hadron_bin_norm = hadronCalib_.size() * bin_norm;
97  for (unsigned ic = 0; ic < nClusters; ++ic) {
98  float highest_energy = 0.0f;
99  output.emplace_back();
100  reco::PFCluster& back = output.back();
102  float energyCorrection = 1.f;
103  float timeRealisticSC = -99.;
104  if (realisticClusters[ic].isVisible()) {
105  int pdgId = simClusters[ic].pdgId();
106  auto abseta = std::abs(simClusters[ic].eta());
107  if ((abseta >= calibMinEta_) and (abseta <= calibMaxEta_)) //protecting range
108  {
109  if ((isEGamma(pdgId) or isPi0(pdgId)) and !egammaCalib_.empty()) {
110  unsigned int etabin = std::floor(((abseta - calibMinEta_) * egamma_bin_norm));
111  energyCorrection = egammaCalib_[etabin];
112  } else if (isHadron(pdgId) and !(isPi0(pdgId)) and
113  !hadronCalib_
114  .empty()) // this function is expensive.. should we treat as hadron everything which is not egamma?
115  {
116  unsigned int etabin = std::floor(((abseta - calibMinEta_) * hadron_bin_norm));
117  energyCorrection = hadronCalib_[etabin];
118  }
119  }
120  std::vector<float> timeHits;
121  const auto& hitsIdsAndFractions = realisticClusters[ic].hitsIdsAndFractions();
122  for (const auto& idAndF : hitsIdsAndFractions) {
123  auto fraction = idAndF.second;
124  if (fraction > 0.f) {
125  auto ref = makeRefhit(input, idAndF.first);
127  const float hit_energy = fraction * ref->energy();
128  if (hit_energy > highest_energy || highest_energy == 0.0) {
129  highest_energy = hit_energy;
130  seed = ref;
131  }
132  //select hits good for timing
133  if (ref->time() > -1.) {
134  int rhLayer = rhtools_.getLayerWithOffset(ref->detId());
135  std::array<float, 3> scPosition = realisticClusters[ic].getCenterOfGravity(rhLayer);
136  float distanceSquared =
137  std::pow((ref->position().x() - scPosition[0]), 2) + std::pow((ref->position().y() - scPosition[1]), 2);
138  if (distanceSquared < maxDforTimingSquared_) {
139  timeHits.push_back(ref->time() - timeOffset_);
140  }
141  }
142  }
143  }
144  //assign time if minimum number of hits
145  if (timeHits.size() >= minNHitsforTiming_)
146  timeRealisticSC = hgcalsimclustertime::fixSizeHighestDensity(timeHits);
147  }
148  if (!back.hitsAndFractions().empty()) {
149  back.setSeed(seed->detId());
150  back.setEnergy(realisticClusters[ic].getEnergy());
151  back.setCorrectedEnergy(energyCorrection * realisticClusters[ic].getEnergy()); //applying energy correction
152  back.setTime(timeRealisticSC);
153  } else {
154  back.setSeed(-1);
155  back.setEnergy(0.f);
156  }
157  }
158 }
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:46
void buildClusters(const edm::Handle< reco::PFRecHitCollection > &, const std::vector< bool > &, const std::vector< bool > &, reco::PFClusterCollection &) override
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
double getEnergy(HBHERecHitCollection::const_iterator hit, int useRaw=0, bool debug=false)
void setTime(float time, float timeError=0)
Definition: PFCluster.h:88
Fraction of a PFRecHit (rechits can be shared between several PFCluster&#39;s)
void setEnergy(double energy)
Definition: CaloCluster.h:135
bool ev
static std::string const input
Definition: EdmProvDump.cc:48
void setSeed(const DetId &id)
Definition: CaloCluster.h:145
reco::PFRecHitRef makeRefhit(const edm::Handle< reco::PFRecHitCollection > &h, const unsigned i) const
void getEventSetup(const edm::EventSetup &)
Definition: RecHitTools.cc:70
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:209
void init(std::size_t numberOfHits, std::size_t numberOfSimClusters, std::size_t numberOfLayers)
void setCorrectedEnergy(double cenergy)
Definition: CaloCluster.h:136
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]
const std::vector< RealisticCluster > & realisticClusters() const
unsigned int lastLayerEE() const
Definition: RecHitTools.h:62
unsigned int getLayer(DetId::Detector type, bool nose=false) const
Definition: RecHitTools.cc:297
void update(const edm::EventSetup &) final
const map< TString, int > numberOfLayers(TString Year="2018")
Definition: DMRtrends.cc:254
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:355
edm::EDGetTokenT< SimClusterCollection > simClusterToken_
void insertHitEnergy(float energy, unsigned int hitIndex)
std::vector< double > egammaCalib_
int getGeometryType() const
Definition: RecHitTools.h:70
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:129
void updateEvent(const edm::Event &) final
void addRecHitFraction(const reco::PFRecHitFraction &frac)
add a given fraction of the rechit
Definition: PFCluster.cc:77
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:30
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:181
unsigned int lastLayerFH() const
Definition: RecHitTools.h:63