CMS 3D CMS Logo

EcalClusterLazyTools.cc
Go to the documentation of this file.
2 
5 
8 
14 
17 
19  ESData const &esData,
23  : geometry_(&esData.caloGeometry),
24  topology_(&esData.caloTopology),
25  ebRecHits_(&edm::get(ev, token1)),
26  eeRecHits_(&edm::get(ev, token2)) {
27  if (token3) {
29  ecalPS_topology_ = std::make_unique<EcalPreshowerTopology>();
30  } else {
31  edm::LogInfo("subdetector geometry not available") << "EcalPreshower geometry is missing" << std::endl;
32  }
33 
34  getESRecHits(ev, *token3);
35  }
36 
37  // get IC's
38  ical = &esData.ecalIntercalibConstants;
39  icalMap = &ical->getMap();
40  // get ADCtoGeV
41  agc = &esData.ecalADCToGeV;
42  // transp corrections
43  laser = &esData.ecalLaserDbService;
44 }
45 
47  edm::EDGetTokenT<EcalRecHitCollection> const &esRecHitsToken) {
48  auto pESRecHits = ev.getHandle(esRecHitsToken);
49  esRecHits_ = pESRecHits.product();
50  // make the map of rechits
51  rechits_map_.clear();
52  if (pESRecHits.isValid()) {
53  for (auto it = pESRecHits->begin(); it != pESRecHits->end(); ++it) {
54  // remove bad ES rechits
55  std::vector<int> badf = {
56  EcalRecHit::ESFlags::kESDead, // 1
57  EcalRecHit::ESFlags::kESTwoGoodRatios,
58  EcalRecHit::ESFlags::kESBadRatioFor12, // 5
59  EcalRecHit::ESFlags::kESBadRatioFor23Upper,
60  EcalRecHit::ESFlags::kESBadRatioFor23Lower,
61  EcalRecHit::ESFlags::kESTS1Largest,
62  EcalRecHit::ESFlags::kESTS3Largest,
63  EcalRecHit::ESFlags::kESTS3Negative, // 10
64  EcalRecHit::ESFlags::kESTS13Sigmas, // 14
65  };
66 
67  if (it->checkFlags(badf))
68  continue;
69 
70  //Make the map of DetID, EcalRecHit pairs
71  rechits_map_.insert(std::make_pair(it->id(), *it));
72  }
73  }
74 }
75 
77  if (cluster.size() == 0) {
78  throw cms::Exception("InvalidCluster") << "The cluster has no crystals!";
79  }
80  DetId id = (cluster.hitsAndFractions()[0]).first; // size is by definition > 0 -- FIXME??
81  const EcalRecHitCollection *recHits = nullptr;
82  if (id.subdetId() == EcalBarrel) {
84  } else if (id.subdetId() == EcalEndcap) {
86  } else {
87  throw cms::Exception("InvalidSubdetector")
88  << "The subdetId() " << id.subdetId() << " does not correspond to EcalBarrel neither EcalEndcap";
89  }
90  return recHits;
91 }
92 
93 // get time of basic cluster seed crystal
96 
97  DetId id = cluster.seed();
98  auto theSeedHit = recHits->find(id);
99  // std::cout << "the seed of the BC has time: "
100  //<< (*theSeedHit).time()
101  //<< "and energy: " << (*theSeedHit).energy() << " collection size: " << recHits->size()
102  //<< "\n" <<std::endl; // GF debug
103 
104  return (*theSeedHit).time();
105 }
106 
107 // error-weighted average of time from constituents of basic cluster
109  auto clusterComponents = (cluster).hitsAndFractions();
110  //std::cout << "BC has this many components: " << clusterComponents.size() << std::endl; // GF debug
111 
113  //std::cout << "BasicClusterClusterTime - rechits are this many: " << recHits->size() << std::endl; // GF debug
114 
115  float weightedTsum = 0;
116  float sumOfWeights = 0;
117 
118  for (auto detitr = clusterComponents.begin(); detitr != clusterComponents.end(); detitr++) {
119  // EcalRecHitCollection::const_iterator theSeedHit = recHits->find (id); // trash this
120  auto oneHit = recHits->find((detitr->first));
121 
122  // in order to get back the ADC counts from the recHit energy, three ingredients are necessary:
123  // 1) get laser correction coefficient
124  float lasercalib = 1.;
125  lasercalib = laser->getLaserCorrection(detitr->first, ev.time());
126  // 2) get intercalibration
127  auto icalit = icalMap->find(detitr->first);
128  EcalIntercalibConstant icalconst = 1.;
129  if (icalit != icalMap->end()) {
130  icalconst = (*icalit);
131  // std::cout << "icalconst set to: " << icalconst << std::endl;
132  } else {
133  edm::LogError("EcalClusterLazyTools")
134  << "No intercalib const found for xtal " << (detitr->first).rawId() << "bailing out";
135  assert(false);
136  }
137  // 3) get adc2GeV
138  float adcToGeV = 1.;
139  if ((detitr->first).subdetId() == EcalBarrel)
140  adcToGeV = float(agc->getEBValue());
141  else if ((detitr->first).subdetId() == EcalEndcap)
142  adcToGeV = float(agc->getEEValue());
143  float adc = 2.;
144  if (icalconst > 0 && lasercalib > 0 && adcToGeV > 0)
145  adc = (*oneHit).energy() / (icalconst * lasercalib * adcToGeV);
146 
147  // don't consider recHits with too little amplitude; take sigma_noise_total into account
148  if ((detitr->first).subdetId() == EcalBarrel && adc < (1.1 * 20))
149  continue;
150  if ((detitr->first).subdetId() == EcalEndcap && adc < (2.2 * 20))
151  continue;
152 
153  // count only on rechits whose error is trusted by the method (ratio)
154  if (!(*oneHit).isTimeErrorValid())
155  continue;
156 
157  float timeError = (*oneHit).timeError();
158  // the constant used to build timeError is largely over-estimated ; remove in quadrature 0.6 and add 0.15 back.
159  // could be prettier if value of constant term was changed at recHit production level
160  if (timeError > 0.6)
161  timeError = sqrt(timeError * timeError - 0.6 * 0.6 + 0.15 * 0.15);
162  else
163  timeError = sqrt(timeError * timeError + 0.15 * 0.15);
164 
165  // do the error weighting
166  weightedTsum += (*oneHit).time() / (timeError * timeError);
167  sumOfWeights += 1. / (timeError * timeError);
168  }
169 
170  // what if no crytal is available for weighted average?
171  if (sumOfWeights == 0)
172  return -999;
173  else
174  return (weightedTsum / sumOfWeights);
175 }
176 
177 // get BasicClusterSeedTime of the seed basic cluser of the supercluster
179  return BasicClusterSeedTime((*cluster.seed()));
180 }
181 
182 // get Preshower effective sigmaIRIR
184  if (!(fabs(cluster.eta()) > 1.6 && fabs(cluster.eta()) < 3.))
185  return 0.;
186 
187  if (!ecalPS_topology_)
188  return 0.;
189 
190  std::vector<float> phoESHitsIXIX =
191  getESHits(cluster.x(), cluster.y(), cluster.z(), rechits_map_, geometry_, ecalPS_topology_.get(), 0, 1);
192  std::vector<float> phoESHitsIYIY =
193  getESHits(cluster.x(), cluster.y(), cluster.z(), rechits_map_, geometry_, ecalPS_topology_.get(), 0, 2);
194  float phoESShapeIXIX = getESShape(phoESHitsIXIX);
195  float phoESShapeIYIY = getESShape(phoESHitsIYIY);
196 
197  return sqrt(phoESShapeIXIX * phoESShapeIXIX + phoESShapeIYIY * phoESShapeIYIY);
198 }
199 
200 // get Preshower effective sigmaIXIX
202  if (!(fabs(cluster.eta()) > 1.6 && fabs(cluster.eta()) < 3.))
203  return 0.;
204 
205  if (!ecalPS_topology_)
206  return 0.;
207 
208  std::vector<float> phoESHitsIXIX =
209  getESHits(cluster.x(), cluster.y(), cluster.z(), rechits_map_, geometry_, ecalPS_topology_.get(), 0, 1);
210  float phoESShapeIXIX = getESShape(phoESHitsIXIX);
211 
212  return phoESShapeIXIX;
213 }
214 
215 // get Preshower effective sigmaIYIY
217  if (!(fabs(cluster.eta()) > 1.6 && fabs(cluster.eta()) < 3.))
218  return 0.;
219 
220  if (!ecalPS_topology_)
221  return 0.;
222 
223  std::vector<float> phoESHitsIYIY =
224  getESHits(cluster.x(), cluster.y(), cluster.z(), rechits_map_, geometry_, ecalPS_topology_.get(), 0, 2);
225  float phoESShapeIYIY = getESShape(phoESHitsIYIY);
226 
227  return phoESShapeIYIY;
228 }
229 
230 // get Preshower Rechits
231 std::vector<float> EcalClusterLazyToolsBase::getESHits(double X,
232  double Y,
233  double Z,
234  const std::map<DetId, EcalRecHit> &_rechits_map,
235  const CaloGeometry *geometry,
236  CaloSubdetectorTopology const *topology_p,
237  int row,
238  int plane) {
239  std::map<DetId, EcalRecHit> rechits_map = _rechits_map;
240  std::vector<float> esHits;
241 
242  const GlobalPoint point(X, Y, Z);
243 
244  const CaloSubdetectorGeometry *geometry_p = geometry->getSubdetectorGeometry(DetId::Ecal, EcalPreshower);
245 
246  DetId esId = (dynamic_cast<const EcalPreshowerGeometry *>(geometry_p))->getClosestCellInPlane(point, plane);
247  ESDetId esDetId = (esId == DetId(0)) ? ESDetId(0) : ESDetId(esId);
248 
249  std::map<DetId, EcalRecHit>::iterator it;
250  ESDetId next;
251  ESDetId strip;
252  strip = esDetId;
253 
254  EcalPreshowerNavigator theESNav(strip, topology_p);
255  theESNav.setHome(strip);
256 
257  if (row == 1) {
258  if (plane == 1 && strip != ESDetId(0))
259  strip = theESNav.north();
260  if (plane == 2 && strip != ESDetId(0))
261  strip = theESNav.east();
262  } else if (row == -1) {
263  if (plane == 1 && strip != ESDetId(0))
264  strip = theESNav.south();
265  if (plane == 2 && strip != ESDetId(0))
266  strip = theESNav.west();
267  }
268 
269  if (strip == ESDetId(0)) {
270  for (int i = 0; i < 31; ++i)
271  esHits.push_back(0);
272  } else {
273  it = rechits_map.find(strip);
274  if (it != rechits_map.end() && it->second.energy() > 1.0e-10)
275  esHits.push_back(it->second.energy());
276  else
277  esHits.push_back(0);
278  //cout<<"center : "<<strip<<" "<<it->second.energy()<<endl;
279 
280  // Front Plane
281  if (plane == 1) {
282  // east road
283  for (int i = 0; i < 15; ++i) {
284  next = theESNav.east();
285  if (next != ESDetId(0)) {
286  it = rechits_map.find(next);
287  if (it != rechits_map.end() && it->second.energy() > 1.0e-10)
288  esHits.push_back(it->second.energy());
289  else
290  esHits.push_back(0);
291  //cout<<"east "<<i<<" : "<<next<<" "<<it->second.energy()<<endl;
292  } else {
293  for (int j = i; j < 15; j++)
294  esHits.push_back(0);
295  break;
296  //cout<<"east "<<i<<" : "<<next<<" "<<0<<endl;
297  }
298  }
299 
300  // west road
301  theESNav.setHome(strip);
302  theESNav.home();
303  for (int i = 0; i < 15; ++i) {
304  next = theESNav.west();
305  if (next != ESDetId(0)) {
306  it = rechits_map.find(next);
307  if (it != rechits_map.end() && it->second.energy() > 1.0e-10)
308  esHits.push_back(it->second.energy());
309  else
310  esHits.push_back(0);
311  //cout<<"west "<<i<<" : "<<next<<" "<<it->second.energy()<<endl;
312  } else {
313  for (int j = i; j < 15; j++)
314  esHits.push_back(0);
315  break;
316  //cout<<"west "<<i<<" : "<<next<<" "<<0<<endl;
317  }
318  }
319  } // End of Front Plane
320 
321  // Rear Plane
322  if (plane == 2) {
323  // north road
324  for (int i = 0; i < 15; ++i) {
325  next = theESNav.north();
326  if (next != ESDetId(0)) {
327  it = rechits_map.find(next);
328  if (it != rechits_map.end() && it->second.energy() > 1.0e-10)
329  esHits.push_back(it->second.energy());
330  else
331  esHits.push_back(0);
332  //cout<<"north "<<i<<" : "<<next<<" "<<it->second.energy()<<endl;
333  } else {
334  for (int j = i; j < 15; j++)
335  esHits.push_back(0);
336  break;
337  //cout<<"north "<<i<<" : "<<next<<" "<<0<<endl;
338  }
339  }
340 
341  // south road
342  theESNav.setHome(strip);
343  theESNav.home();
344  for (int i = 0; i < 15; ++i) {
345  next = theESNav.south();
346  if (next != ESDetId(0)) {
347  it = rechits_map.find(next);
348  if (it != rechits_map.end() && it->second.energy() > 1.0e-10)
349  esHits.push_back(it->second.energy());
350  else
351  esHits.push_back(0);
352  //cout<<"south "<<i<<" : "<<next<<" "<<it->second.energy()<<endl;
353  } else {
354  for (int j = i; j < 15; j++)
355  esHits.push_back(0);
356  break;
357  //cout<<"south "<<i<<" : "<<next<<" "<<0<<endl;
358  }
359  }
360  } // End of Rear Plane
361  } // Fill ES RecHits
362 
363  return esHits;
364 }
365 
366 // get Preshower hit shape
367 float EcalClusterLazyToolsBase::getESShape(const std::vector<float> &ESHits0) {
368  const int nBIN = 21;
369  float esRH[nBIN];
370  for (int idx = 0; idx < nBIN; idx++) {
371  esRH[idx] = 0.;
372  }
373 
374  for (int ibin = 0; ibin < ((nBIN + 1) / 2); ibin++) {
375  if (ibin == 0) {
376  esRH[(nBIN - 1) / 2] = ESHits0[ibin];
377  } else {
378  esRH[(nBIN - 1) / 2 + ibin] = ESHits0[ibin];
379  esRH[(nBIN - 1) / 2 - ibin] = ESHits0[ibin + 15];
380  }
381  }
382 
383  // ---- Effective Energy Deposit Width ---- //
384  double EffWidthSigmaISIS = 0.;
385  double totalEnergyISIS = 0.;
386  double EffStatsISIS = 0.;
387  for (int id_X = 0; id_X < 21; id_X++) {
388  totalEnergyISIS += esRH[id_X];
389  EffStatsISIS += esRH[id_X] * (id_X - 10) * (id_X - 10);
390  }
391  EffWidthSigmaISIS = (totalEnergyISIS > 0.) ? sqrt(fabs(EffStatsISIS / totalEnergyISIS)) : 0.;
392 
393  return EffWidthSigmaISIS;
394 }
const CaloGeometry * geometry_
EcalIntercalibConstantMap const * icalMap
void home() const
move the navigator back to the starting point
Definition: CaloNavigator.h:96
const EcalRecHitCollection * esRecHits_
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:210
std::vector< float > getESHits(double X, double Y, double Z, const std::map< DetId, EcalRecHit > &rechits_map, const CaloGeometry *geometry, CaloSubdetectorTopology const *topology_p, int row=0, int plane=1)
EcalRecHitCollection const * getEcalRecHitCollection(const reco::BasicCluster &cluster) const
float SuperClusterSeedTime(const reco::SuperCluster &cluster)
float BasicClusterTime(const reco::BasicCluster &cluster, const edm::Event &ev)
T north() const
move the navigator north
Definition: CaloNavigator.h:30
float getESShape(const std::vector< float > &ESHits0)
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:219
EcalIntercalibConstants const * ical
EcalIntercalibConstants const & ecalIntercalibConstants
#define X(str)
Definition: MuonsGrabber.cc:38
const EcalRecHitCollection * ebRecHits_
float eseffsixix(const reco::SuperCluster &cluster)
EcalADCToGeVConstant const * agc
T south() const
move the navigator south
Definition: CaloNavigator.h:36
Log< level::Error, false > LogError
double x() const
x coordinate of cluster centroid
Definition: CaloCluster.h:172
assert(be >=bs)
void setHome(const T &startingPoint)
set the starting position
Definition: CaloNavigator.h:90
EcalADCToGeVConstant const & ecalADCToGeV
T sqrt(T t)
Definition: SSEVec.h:23
double z() const
z coordinate of cluster centroid
Definition: CaloCluster.h:178
double y() const
y coordinate of cluster centroid
Definition: CaloCluster.h:175
size_t size() const
size in number of hits (e.g. in crystals for ECAL)
Definition: CaloCluster.h:187
optional
Definition: Types.py:245
float getLaserCorrection(DetId const &xid, edm::Timestamp const &iTime) const
EcalLaserDbService const * laser
const_iterator find(uint32_t rawId) const
Log< level::Info, false > LogInfo
Definition: DetId.h:17
float eseffsiyiy(const reco::SuperCluster &cluster)
EcalClusterLazyToolsBase(const edm::Event &ev, ESData const &esData, edm::EDGetTokenT< EcalRecHitCollection > token1, edm::EDGetTokenT< EcalRecHitCollection > token2, std::optional< edm::EDGetTokenT< EcalRecHitCollection >> token3)
std::unique_ptr< CaloSubdetectorTopology const > ecalPS_topology_
void getESRecHits(const edm::Event &ev, edm::EDGetTokenT< EcalRecHitCollection > const &esRecHitsToken)
T east() const
move the navigator east
Definition: CaloNavigator.h:42
const CaloClusterPtr & seed() const
seed BasicCluster
Definition: SuperCluster.h:79
HLT enums.
const EcalRecHitCollection * eeRecHits_
const_iterator end() const
T west() const
move the navigator west
Definition: CaloNavigator.h:48
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:181
#define get
std::map< DetId, EcalRecHit > rechits_map_
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
EcalLaserDbService const & ecalLaserDbService
float BasicClusterSeedTime(const reco::BasicCluster &cluster)
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
uint16_t *__restrict__ uint16_t const *__restrict__ adc
float EcalIntercalibConstant
float eseffsirir(const reco::SuperCluster &cluster)