CMS 3D CMS Logo

SiStripGainsPCLWorker.cc
Go to the documentation of this file.
4 
5 #include <iostream>
6 #include <sstream>
7 
8 //********************************************************************************//
10  MinTrackMomentum = iConfig.getUntrackedParameter<double>("minTrackMomentum", 3.0);
11  MaxTrackMomentum = iConfig.getUntrackedParameter<double>("maxTrackMomentum", 99999.0);
12  MinTrackEta = iConfig.getUntrackedParameter<double>("minTrackEta", -5.0);
13  MaxTrackEta = iConfig.getUntrackedParameter<double>("maxTrackEta", 5.0);
14  MaxNrStrips = iConfig.getUntrackedParameter<unsigned>("maxNrStrips", 2);
15  MinTrackHits = iConfig.getUntrackedParameter<unsigned>("MinTrackHits", 8);
16  MaxTrackChiOverNdf = iConfig.getUntrackedParameter<double>("MaxTrackChiOverNdf", 3);
17  MaxTrackingIteration = iConfig.getUntrackedParameter<int>("MaxTrackingIteration", 7);
18  AllowSaturation = iConfig.getUntrackedParameter<bool>("AllowSaturation", false);
19  FirstSetOfConstants = iConfig.getUntrackedParameter<bool>("FirstSetOfConstants", true);
20  Validation = iConfig.getUntrackedParameter<bool>("Validation", false);
21  OldGainRemoving = iConfig.getUntrackedParameter<bool>("OldGainRemoving", false);
22  useCalibration = iConfig.getUntrackedParameter<bool>("UseCalibration", false);
23  doChargeMonitorPerPlane = iConfig.getUntrackedParameter<bool>("doChargeMonitorPerPlane", false);
24  m_DQMdir = iConfig.getUntrackedParameter<std::string>("DQMdir", "AlCaReco/SiStripGains");
25  m_calibrationMode = iConfig.getUntrackedParameter<std::string>("calibrationMode", "StdBunch");
26  VChargeHisto = iConfig.getUntrackedParameter<std::vector<std::string>>("ChargeHisto");
27 
28  // fill in the mapping between the histogram indices and the (id,side,plane) tuple
29  std::vector<std::pair<std::string, std::string>> hnames =
31  for (unsigned int i = 0; i < hnames.size(); i++) {
32  int id = APVGain::subdetectorId((hnames[i]).first);
33  int side = APVGain::subdetectorSide((hnames[i]).first);
34  int plane = APVGain::subdetectorPlane((hnames[i]).first);
35  int thick = APVGain::thickness((hnames[i]).first);
36  std::string s = hnames[i].first;
37 
38  auto loc = APVloc(thick, id, side, plane, s);
39  theTopologyMap.insert(std::make_pair(i, loc));
40  }
41 
42  //Set the monitoring element tag and store
43  dqm_tag_.reserve(7);
44  dqm_tag_.clear();
45  dqm_tag_.push_back("StdBunch"); // statistic collection from Standard Collision Bunch @ 3.8 T
46  dqm_tag_.push_back("StdBunch0T"); // statistic collection from Standard Collision Bunch @ 0 T
47  dqm_tag_.push_back("AagBunch"); // statistic collection from First Collision After Abort Gap @ 3.8 T
48  dqm_tag_.push_back("AagBunch0T"); // statistic collection from First Collision After Abort Gap @ 0 T
49  dqm_tag_.push_back("IsoMuon"); // statistic collection from Isolated Muon @ 3.8 T
50  dqm_tag_.push_back("IsoMuon0T"); // statistic collection from Isolated Muon @ 0 T
51  dqm_tag_.push_back("Harvest"); // statistic collection: Harvest
52 
53  m_tracks_token = consumes<edm::View<reco::Track>>(iConfig.getParameter<edm::InputTag>("tracks"));
54  m_association_token = consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("tracks"));
55 
57  tTopoTokenBR_ = esConsumes<edm::Transition::BeginRun>();
58  tkGeomTokenBR_ = esConsumes<edm::Transition::BeginRun>();
59  tkGeomToken_ = esConsumes<>();
60  gainToken_ = esConsumes<edm::Transition::BeginRun>();
61  qualityToken_ = esConsumes<edm::Transition::BeginRun>();
62 }
63 
64 //********************************************************************************//
66  edm::EventSetup const& iSetup,
68  using namespace edm;
69  static constexpr float defaultGainTick = 690. / 640.;
70 
71  // fills the APV collections at each begin run
72  const TrackerGeometry* bareTkGeomPtr = &iSetup.getData(tkGeomTokenBR_);
73  const TrackerTopology* bareTkTopoPtr = &iSetup.getData(tTopoTokenBR_);
74  checkBookAPVColls(bareTkGeomPtr, bareTkTopoPtr, histograms);
75 
76  const auto gainHandle = iSetup.getHandle(gainToken_);
77  if (!gainHandle.isValid()) {
78  edm::LogError("SiStripGainPCLWorker") << "gainHandle is not valid\n";
79  exit(0);
80  }
81 
82  const auto& siStripQuality = iSetup.getData(qualityToken_);
83 
84  for (unsigned int a = 0; a < histograms.APVsCollOrdered.size(); a++) {
85  std::shared_ptr<stAPVGain> APV = histograms.APVsCollOrdered[a];
86 
88  continue;
89 
90  APV->isMasked = siStripQuality.IsApvBad(APV->DetId, APV->APVId);
91 
92  if (gainHandle->getNumberOfTags() != 2) {
93  edm::LogError("SiStripGainPCLWorker") << "NUMBER OF GAIN TAG IS EXPECTED TO BE 2\n";
94  fflush(stdout);
95  exit(0);
96  };
97  float newPreviousGain = gainHandle->getApvGain(APV->APVId, gainHandle->getRange(APV->DetId, 1), 1);
98  if (APV->PreviousGain != 1 and newPreviousGain != APV->PreviousGain)
99  edm::LogWarning("SiStripGainPCLWorker") << "WARNING: ParticleGain in the global tag changed\n";
100  APV->PreviousGain = newPreviousGain;
101 
102  float newPreviousGainTick =
103  APV->isMasked ? defaultGainTick : gainHandle->getApvGain(APV->APVId, gainHandle->getRange(APV->DetId, 0), 0);
104  if (APV->PreviousGainTick != 1 and newPreviousGainTick != APV->PreviousGainTick) {
105  edm::LogWarning("SiStripGainPCLWorker")
106  << "WARNING: TickMarkGain in the global tag changed\n"
107  << std::endl
108  << " APV->SubDet: " << APV->SubDet << " APV->APVId:" << APV->APVId << std::endl
109  << " APV->PreviousGainTick: " << APV->PreviousGainTick << " newPreviousGainTick: " << newPreviousGainTick
110  << std::endl;
111  }
112  APV->PreviousGainTick = newPreviousGainTick;
113  }
114 }
115 
116 namespace {
117  struct HitCluster {
118  uint32_t det;
119  const SiStripCluster* strip;
120  const SiPixelCluster* pixel;
121  HitCluster(uint32_t detId, const SiStripCluster* strip, const SiPixelCluster* pixel)
122  : det(detId), strip(strip), pixel(pixel) {}
123  };
124  std::vector<HitCluster> getClusters(const TrackingRecHit* hit) {
125  const auto simple1d = dynamic_cast<const SiStripRecHit1D*>(hit);
126  const auto simple = dynamic_cast<const SiStripRecHit2D*>(hit);
127  const auto matched = dynamic_cast<const SiStripMatchedRecHit2D*>(hit);
128  const auto pixel = dynamic_cast<const SiPixelRecHit*>(hit);
129  std::vector<HitCluster> clusters;
130  if (matched) {
131  clusters.emplace_back(matched->monoId(), &matched->monoCluster(), nullptr);
132  clusters.emplace_back(matched->stereoId(), &matched->stereoCluster(), nullptr);
133  } else if (simple) {
134  clusters.emplace_back(simple->geographicalId().rawId(), simple->cluster().get(), nullptr);
135  } else if (simple1d) {
136  clusters.emplace_back(simple1d->geographicalId().rawId(), simple1d->cluster().get(), nullptr);
137  } else if (pixel) {
138  clusters.emplace_back(pixel->geographicalId().rawId(), nullptr, pixel->cluster().get());
139  }
140  return clusters;
141  }
142 
143  bool isFarFromBorder(const TrajectoryStateOnSurface& trajState, uint32_t detId, const TrackerGeometry* tGeom) {
144  const auto gdu = tGeom->idToDetUnit(detId);
145  if ((!dynamic_cast<const StripGeomDetUnit*>(gdu)) && (!dynamic_cast<const PixelGeomDetUnit*>(gdu))) {
146  edm::LogWarning("SiStripGainCalibTableProducer")
147  << "DetId " << detId << " does not seem to belong to the tracker";
148  return false;
149  }
150  const auto plane = gdu->surface();
151  const auto trapBounds = dynamic_cast<const TrapezoidalPlaneBounds*>(&plane.bounds());
152  const auto rectBounds = dynamic_cast<const RectangularPlaneBounds*>(&plane.bounds());
153 
154  static constexpr double distFromBorder = 1.0;
155  double halfLength = 0.;
156  if (trapBounds) {
157  halfLength = trapBounds->parameters()[3];
158  } else if (rectBounds) {
159  halfLength = .5 * gdu->surface().bounds().length();
160  } else {
161  return false;
162  }
163 
164  const auto pos = trajState.localPosition();
165  const auto posError = trajState.localError().positionError();
166  if (std::abs(pos.y()) + posError.yy() >= (halfLength - distFromBorder))
167  return false;
168 
169  return true;
170  }
171 } // namespace
172 
173 //********************************************************************************//
174 // ------------ method called for each event ------------
176  edm::EventSetup const& iSetup,
177  APVGain::APVGainHistograms const& histograms) const {
178  using namespace edm;
179 
180  unsigned int eventnumber = iEvent.id().event();
181  unsigned int runnumber = iEvent.id().run();
182 
183  edm::LogInfo("SiStripGainsPCLWorker") << "Processing run " << runnumber << " and event " << eventnumber << std::endl;
184 
185  const TrackerTopology* topo = &iSetup.getData(tTopoToken_);
186  const TrackerGeometry* tGeom = &iSetup.getData(tkGeomToken_);
187 
188  // Event data handles
190  iEvent.getByToken(m_tracks_token, tracks);
191  edm::Handle<TrajTrackAssociationCollection> trajTrackAssociations;
192  iEvent.getByToken(m_association_token, trajTrackAssociations);
193 
194  for (const auto& elem : theTopologyMap) {
195  LogDebug("SiStripGainsPCLWorker") << elem.first << " - " << elem.second.m_string << " "
196  << elem.second.m_subdetectorId << " " << elem.second.m_subdetectorSide << " "
197  << elem.second.m_subdetectorPlane << std::endl;
198  }
199 
200  LogDebug("SiStripGainsPCLWorker") << "for mode" << m_calibrationMode << std::endl;
201 
202  int elepos = statCollectionFromMode(m_calibrationMode.c_str());
203 
204  std::size_t nStoredClusters{0};
205  for (const auto& assoc : *trajTrackAssociations) {
206  const auto traj = assoc.key.get();
207  const auto track = assoc.val.get();
208 
209  if ((track->eta() < MinTrackEta) || (track->eta() > MaxTrackEta) || (track->p() < MinTrackMomentum) ||
210  (track->p() > MaxTrackMomentum) || (track->numberOfValidHits() < MinTrackHits) ||
211  ((track->chi2() / track->ndof()) > MaxTrackChiOverNdf) || (track->algo() > MaxTrackingIteration))
212  continue;
213 
214  int iCluster{-1};
215  for (const auto& meas : traj->measurements()) {
216  const auto& trajState = meas.updatedState();
217  if (!trajState.isValid())
218  continue;
219 
220  // there can be 2 (stereo module), 1 (no stereo module), or 0 (no pixel or strip hit) clusters
221  auto clusters = getClusters(meas.recHit()->hit());
222  for (const auto hitCluster : clusters) {
223  ++iCluster;
224  bool saturation = false;
225  bool overlapping = false;
226  unsigned int charge = 0;
227  int firstStrip = 0;
228  unsigned int nStrips = 0;
229  if (hitCluster.strip) {
230  const auto& ampls = hitCluster.strip->amplitudes();
231  firstStrip = hitCluster.strip->firstStrip();
232  nStrips = ampls.size();
233  charge = hitCluster.strip->charge();
234  saturation = std::any_of(ampls.begin(), ampls.end(), [](uint8_t amp) { return amp >= 254; });
235 
236  overlapping = (((firstStrip % 128) == 0) || ((firstStrip / 128) != ((firstStrip + int(nStrips)) / 128)));
237  } else if (hitCluster.pixel) {
238  const auto& ampls = hitCluster.pixel->pixelADC();
239  const int firstRow = hitCluster.pixel->minPixelRow();
240  const int firstCol = hitCluster.pixel->minPixelCol();
241  firstStrip = ((firstRow / 80) << 3 | (firstCol / 52)) * 128; //Hack to save the APVId
242  nStrips = 0;
243  for (const auto amp : ampls) {
244  charge += amp;
245  if (amp >= 254)
246  saturation = true;
247  }
248  }
249  // works for both strip and pixel thanks to firstStrip encoding for pixel above, as in the calibTree
250  std::shared_ptr<stAPVGain> APV = histograms.APVsColl.at((hitCluster.det << 4) | (firstStrip / 128));
251 
252  const auto farFromEdge = (hitCluster.strip ? isFarFromBorder(trajState, hitCluster.det, tGeom) : true);
253  if ((APV->SubDet > 2) &&
254  ((!farFromEdge) || overlapping || (saturation && !AllowSaturation) || (nStrips > MaxNrStrips)))
255  continue;
256 
257  int clusterCharge = 0;
258  if (APV->SubDet > 2) { // strip
260  saturation = false;
261  for (const auto origCharge : hitCluster.strip->amplitudes()) {
262  int stripCharge;
263  if (useCalibration) {
264  if (FirstSetOfConstants) {
265  stripCharge = int(origCharge / APV->CalibGain);
266  } else {
267  stripCharge = int(origCharge * (APV->PreviousGain / APV->CalibGain));
268  }
269  } else {
270  if (FirstSetOfConstants) {
271  stripCharge = origCharge;
272  } else {
273  stripCharge = int(origCharge * APV->PreviousGain);
274  }
275  }
276  if (stripCharge > 1024) {
277  stripCharge = 255;
278  saturation = true;
279  } else if (stripCharge > 254) {
280  stripCharge = 254;
281  saturation = true;
282  }
283  clusterCharge += stripCharge;
284  }
285  if (saturation && !AllowSaturation)
286  continue;
287  } else {
288  clusterCharge = charge;
289  }
290  } else { // pixel
291  clusterCharge = charge / 265.0; //expected scale factor between pixel and strip charge
292  }
293 
294  const auto trackDir = trajState.localDirection();
295  const auto path = (10. * APV->Thickness) / std::abs(trackDir.z() / trackDir.mag());
296  double ClusterChargeOverPath = ((double)clusterCharge) / path;
297  if (APV->SubDet > 2) {
298  if (Validation) {
299  ClusterChargeOverPath /= APV->PreviousGain;
300  }
301  if (OldGainRemoving) {
302  ClusterChargeOverPath *= APV->PreviousGain;
303  }
304  } else {
305  // keep processing of pixel cluster charge until here
306  continue;
307  }
308  ++nStoredClusters;
309 
310  // real histogram for calibration
311  histograms.Charge_Vs_Index[elepos]->Fill(APV->Index, ClusterChargeOverPath);
312  LogDebug("SiStripGainsPCLWorker")
313  << " for mode " << m_calibrationMode << "\n"
314  << " i " << iCluster << " useCalibration " << useCalibration << " FirstSetOfConstants "
315  << FirstSetOfConstants << " APV->PreviousGain " << APV->PreviousGain << " APV->CalibGain " << APV->CalibGain
316  << " APV->DetId " << APV->DetId << " APV->Index " << APV->Index << " Charge " << clusterCharge << " Path "
317  << path << " ClusterChargeOverPath " << ClusterChargeOverPath << std::endl;
318 
319  // Fill monitoring histograms
320  int mCharge1 = 0;
321  for (const auto sCharge : hitCluster.strip->amplitudes()) {
322  if (sCharge > 254) {
323  mCharge1 += 254;
324  } else {
325  mCharge1 += sCharge;
326  }
327  }
328  // Revome gains for monitoring
329  int mCharge2 = mCharge1 * APV->PreviousGain; // remove G2
330  int mCharge3 = mCharge1 * APV->PreviousGainTick; // remove G1
331  int mCharge4 = mCharge1 * APV->PreviousGain * APV->PreviousGainTick; // remove G1 and G2
332 
333  LogDebug("SiStripGainsPCLWorker") << " full charge " << mCharge1 << " remove G2 " << mCharge2 << " remove G1 "
334  << mCharge3 << " remove G1*G2 " << mCharge4 << std::endl;
335 
336  auto indices = APVGain::FetchIndices(theTopologyMap, hitCluster.det, topo);
337 
338  for (auto m : indices)
339  histograms.Charge_1[elepos][m]->Fill(((double)mCharge1) / path);
340  for (auto m : indices)
341  histograms.Charge_2[elepos][m]->Fill(((double)mCharge2) / path);
342  for (auto m : indices)
343  histograms.Charge_3[elepos][m]->Fill(((double)mCharge3) / path);
344  for (auto m : indices)
345  histograms.Charge_4[elepos][m]->Fill(((double)mCharge4) / path);
346 
347  if (APV->SubDet == StripSubdetector::TIB) {
348  histograms.Charge_Vs_PathlengthTIB[elepos]->Fill(path, clusterCharge); // TIB
349 
350  } else if (APV->SubDet == StripSubdetector::TOB) {
351  histograms.Charge_Vs_PathlengthTOB[elepos]->Fill(path, clusterCharge); // TOB
352 
353  } else if (APV->SubDet == StripSubdetector::TID) {
354  if (APV->Eta < 0) {
355  histograms.Charge_Vs_PathlengthTIDM[elepos]->Fill(path, clusterCharge);
356  } // TID minus
357  else if (APV->Eta > 0) {
358  histograms.Charge_Vs_PathlengthTIDP[elepos]->Fill(path, clusterCharge);
359  } // TID plus
360 
361  } else if (APV->SubDet == StripSubdetector::TEC) {
362  if (APV->Eta < 0) {
363  if (APV->Thickness < 0.04) {
364  histograms.Charge_Vs_PathlengthTECM1[elepos]->Fill(path, clusterCharge);
365  } // TEC minus, type 1
366  else if (APV->Thickness > 0.04) {
367  histograms.Charge_Vs_PathlengthTECM2[elepos]->Fill(path, clusterCharge);
368  } // TEC minus, type 2
369  } else if (APV->Eta > 0) {
370  if (APV->Thickness < 0.04) {
371  histograms.Charge_Vs_PathlengthTECP1[elepos]->Fill(path, clusterCharge);
372  } // TEC plus, type 1
373  else if (APV->Thickness > 0.04) {
374  histograms.Charge_Vs_PathlengthTECP2[elepos]->Fill(path, clusterCharge);
375  } // TEC plus, type 2
376  }
377  }
378  }
379  }
380  }
381 
382  histograms.EventStats->Fill(0., 0., 1);
383  histograms.EventStats->Fill(1., 0., tracks->size());
384  histograms.EventStats->Fill(2., 0., nStoredClusters);
385 
386  //LogDebug("SiStripGainsPCLWorker")<<" for mode"<< m_calibrationMode
387  // <<" entries in histogram:"<< histograms.Charge_Vs_Index[elepos].getEntries()
388  // <<std::endl;
389 }
390 
391 //********************************************************************************//
392 // ------------ method called once each job just before starting event loop ------------
394  const TrackerTopology* bareTkTopoPtr,
396  if (bareTkGeomPtr) { // pointer not yet set: called the first time => fill the APVColls
397  auto const& Det = bareTkGeomPtr->dets();
398 
399  edm::LogInfo("SiStripGainsPCLWorker") << " Resetting APV struct" << std::endl;
400 
401  unsigned int Index = 0;
402 
403  for (unsigned int i = 0; i < Det.size(); i++) {
404  DetId Detid = Det[i]->geographicalId();
405  int SubDet = Detid.subdetId();
406 
409  auto DetUnit = dynamic_cast<const StripGeomDetUnit*>(Det[i]);
410  if (!DetUnit)
411  continue;
412 
413  const StripTopology& Topo = DetUnit->specificTopology();
414  unsigned int NAPV = Topo.nstrips() / 128;
415 
416  for (unsigned int j = 0; j < NAPV; j++) {
417  auto APV = std::make_shared<stAPVGain>();
418  APV->Index = Index;
419  APV->Bin = -1;
420  APV->DetId = Detid.rawId();
421  APV->Side = 0;
422 
423  if (SubDet == StripSubdetector::TID) {
424  APV->Side = bareTkTopoPtr->tidSide(Detid);
425  } else if (SubDet == StripSubdetector::TEC) {
426  APV->Side = bareTkTopoPtr->tecSide(Detid);
427  }
428 
429  APV->APVId = j;
430  APV->SubDet = SubDet;
431  APV->FitMPV = -1;
432  APV->FitMPVErr = -1;
433  APV->FitWidth = -1;
434  APV->FitWidthErr = -1;
435  APV->FitChi2 = -1;
436  APV->FitNorm = -1;
437  APV->Gain = -1;
438  APV->PreviousGain = 1;
439  APV->PreviousGainTick = 1;
440  APV->x = DetUnit->position().basicVector().x();
441  APV->y = DetUnit->position().basicVector().y();
442  APV->z = DetUnit->position().basicVector().z();
443  APV->Eta = DetUnit->position().basicVector().eta();
444  APV->Phi = DetUnit->position().basicVector().phi();
445  APV->R = DetUnit->position().basicVector().transverse();
446  APV->Thickness = DetUnit->surface().bounds().thickness();
447  APV->NEntries = 0;
448  APV->isMasked = false;
449 
450  histograms.APVsCollOrdered.push_back(APV);
451  histograms.APVsColl[(APV->DetId << 4) | APV->APVId] = APV;
452  Index++;
453  histograms.NStripAPVs++;
454  } // loop on APVs
455  } // if is Strips
456  } // loop on dets
457 
458  for (unsigned int i = 0; i < Det.size();
459  i++) { //Make two loop such that the Pixel information is added at the end --> make transition simpler
460  DetId Detid = Det[i]->geographicalId();
461  int SubDet = Detid.subdetId();
463  auto DetUnit = dynamic_cast<const PixelGeomDetUnit*>(Det[i]);
464  if (!DetUnit)
465  continue;
466 
467  const PixelTopology& Topo = DetUnit->specificTopology();
468  unsigned int NROCRow = Topo.nrows() / (80.);
469  unsigned int NROCCol = Topo.ncolumns() / (52.);
470 
471  for (unsigned int j = 0; j < NROCRow; j++) {
472  for (unsigned int i = 0; i < NROCCol; i++) {
473  auto APV = std::make_shared<stAPVGain>();
474  APV->Index = Index;
475  APV->Bin = -1;
476  APV->DetId = Detid.rawId();
477  APV->Side = 0;
478  APV->APVId = (j << 3 | i);
479  APV->SubDet = SubDet;
480  APV->FitMPV = -1;
481  APV->FitMPVErr = -1;
482  APV->FitWidth = -1;
483  APV->FitWidthErr = -1;
484  APV->FitChi2 = -1;
485  APV->Gain = -1;
486  APV->PreviousGain = 1;
487  APV->PreviousGainTick = 1;
488  APV->x = DetUnit->position().basicVector().x();
489  APV->y = DetUnit->position().basicVector().y();
490  APV->z = DetUnit->position().basicVector().z();
491  APV->Eta = DetUnit->position().basicVector().eta();
492  APV->Phi = DetUnit->position().basicVector().phi();
493  APV->R = DetUnit->position().basicVector().transverse();
494  APV->Thickness = DetUnit->surface().bounds().thickness();
495  APV->isMasked = false; //SiPixelQuality_->IsModuleBad(Detid.rawId());
496  APV->NEntries = 0;
497 
498  histograms.APVsCollOrdered.push_back(APV);
499  histograms.APVsColl[(APV->DetId << 4) | APV->APVId] = APV;
500  Index++;
501  histograms.NPixelDets++;
502 
503  } // loop on ROC cols
504  } // loop on ROC rows
505  } // if Pixel
506  } // loop on Dets
507  } //if (!bareTkGeomPtr_) ...
508 }
509 
510 //********************************************************************************//
513  desc.setUnknown();
514  descriptions.addDefault(desc);
515 }
516 
517 //********************************************************************************//
519  edm::Run const& run,
520  edm::EventSetup const& setup,
522  ibooker.cd();
523  std::string dqm_dir = m_DQMdir;
524  const char* tag = dqm_tag_[statCollectionFromMode(m_calibrationMode.c_str())].c_str();
525 
526  edm::LogInfo("SiStripGainsPCLWorker") << "Setting " << dqm_dir << " in DQM and booking histograms for tag " << tag
527  << std::endl;
528 
529  ibooker.setCurrentFolder(dqm_dir);
530 
531  // this MonitorElement is created to log the number of events / tracks and clusters used
532  // by the calibration algorithm
533 
534  histograms.EventStats = ibooker.book2I("EventStats", "Statistics", 3, -0.5, 2.5, 1, 0, 1);
535  histograms.EventStats->setBinLabel(1, "events count", 1);
536  histograms.EventStats->setBinLabel(2, "tracks count", 1);
537  histograms.EventStats->setBinLabel(3, "clusters count", 1);
538 
539  std::string stag(tag);
540  if (!stag.empty() && stag[0] != '_')
541  stag.insert(0, 1, '_');
542 
543  std::string cvi = std::string("Charge_Vs_Index") + stag;
544  std::string cvpTIB = std::string("Charge_Vs_PathlengthTIB") + stag;
545  std::string cvpTOB = std::string("Charge_Vs_PathlengthTOB") + stag;
546  std::string cvpTIDP = std::string("Charge_Vs_PathlengthTIDP") + stag;
547  std::string cvpTIDM = std::string("Charge_Vs_PathlengthTIDM") + stag;
548  std::string cvpTECP1 = std::string("Charge_Vs_PathlengthTECP1") + stag;
549  std::string cvpTECP2 = std::string("Charge_Vs_PathlengthTECP2") + stag;
550  std::string cvpTECM1 = std::string("Charge_Vs_PathlengthTECM1") + stag;
551  std::string cvpTECM2 = std::string("Charge_Vs_PathlengthTECM2") + stag;
552 
553  int elepos = statCollectionFromMode(tag);
554 
555  histograms.Charge_Vs_Index.reserve(dqm_tag_.size());
556  histograms.Charge_Vs_PathlengthTIB.reserve(dqm_tag_.size());
557  histograms.Charge_Vs_PathlengthTOB.reserve(dqm_tag_.size());
558  histograms.Charge_Vs_PathlengthTIDP.reserve(dqm_tag_.size());
559  histograms.Charge_Vs_PathlengthTIDM.reserve(dqm_tag_.size());
560  histograms.Charge_Vs_PathlengthTECP1.reserve(dqm_tag_.size());
561  histograms.Charge_Vs_PathlengthTECP2.reserve(dqm_tag_.size());
562  histograms.Charge_Vs_PathlengthTECM1.reserve(dqm_tag_.size());
563  histograms.Charge_Vs_PathlengthTECM2.reserve(dqm_tag_.size());
564 
565  // The cluster charge is stored by exploiting a non uniform binning in order
566  // reduce the histogram memory size. The bin width is relaxed with a falling
567  // exponential function and the bin boundaries are stored in the binYarray.
568  // The binXarray is used to provide as many bins as the APVs.
569  //
570  // More details about this implementations are here:
571  // https://indico.cern.ch/event/649344/contributions/2672267/attachments/1498323/2332518/OptimizeChHisto.pdf
572 
573  std::vector<float> binXarray;
574  binXarray.reserve(histograms.NStripAPVs + 1);
575  for (unsigned int a = 0; a <= histograms.NStripAPVs; a++) {
576  binXarray.push_back((float)a);
577  }
578 
579  std::array<float, 688> binYarray;
580  double p0 = 5.445;
581  double p1 = 0.002113;
582  double p2 = 69.01576;
583  double y = 0.;
584  for (int b = 0; b < 687; b++) {
585  binYarray[b] = y;
586  if (y <= 902.)
587  y = y + 2.;
588  else
589  y = (p0 - log(exp(p0 - p1 * y) - p2 * p1)) / p1;
590  }
591  binYarray[687] = 4000.;
592 
593  histograms.Charge_1[elepos].clear();
594  histograms.Charge_2[elepos].clear();
595  histograms.Charge_3[elepos].clear();
596  histograms.Charge_4[elepos].clear();
597 
598  auto it = histograms.Charge_Vs_Index.begin();
599  histograms.Charge_Vs_Index.insert(
600  it + elepos,
601  ibooker.book2S(cvi.c_str(), cvi.c_str(), histograms.NStripAPVs, &binXarray[0], 687, binYarray.data()));
602 
603  it = histograms.Charge_Vs_PathlengthTIB.begin();
604  histograms.Charge_Vs_PathlengthTIB.insert(it + elepos,
605  ibooker.book2S(cvpTIB.c_str(), cvpTIB.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
606 
607  it = histograms.Charge_Vs_PathlengthTOB.begin();
608  histograms.Charge_Vs_PathlengthTOB.insert(it + elepos,
609  ibooker.book2S(cvpTOB.c_str(), cvpTOB.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
610 
611  it = histograms.Charge_Vs_PathlengthTIDP.begin();
612  histograms.Charge_Vs_PathlengthTIDP.insert(
613  it + elepos, ibooker.book2S(cvpTIDP.c_str(), cvpTIDP.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
614 
615  it = histograms.Charge_Vs_PathlengthTIDM.begin();
616  histograms.Charge_Vs_PathlengthTIDM.insert(
617  it + elepos, ibooker.book2S(cvpTIDM.c_str(), cvpTIDM.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
618 
619  it = histograms.Charge_Vs_PathlengthTECP1.begin();
620  histograms.Charge_Vs_PathlengthTECP1.insert(
621  it + elepos, ibooker.book2S(cvpTECP1.c_str(), cvpTECP1.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
622 
623  it = histograms.Charge_Vs_PathlengthTECP2.begin();
624  histograms.Charge_Vs_PathlengthTECP2.insert(
625  it + elepos, ibooker.book2S(cvpTECP2.c_str(), cvpTECP2.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
626 
627  it = histograms.Charge_Vs_PathlengthTECM1.begin();
628  histograms.Charge_Vs_PathlengthTECM1.insert(
629  it + elepos, ibooker.book2S(cvpTECM1.c_str(), cvpTECM1.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
630 
631  it = histograms.Charge_Vs_PathlengthTECM2.begin();
632  histograms.Charge_Vs_PathlengthTECM2.insert(
633  it + elepos, ibooker.book2S(cvpTECM2.c_str(), cvpTECM2.c_str(), 20, 0.3, 1.3, 250, 0, 2000));
634 
635  std::vector<std::pair<std::string, std::string>> hnames =
637  for (unsigned int i = 0; i < hnames.size(); i++) {
638  std::string htag = (hnames[i]).first + stag;
639  histograms.Charge_1[elepos].push_back(ibooker.book1DD(htag.c_str(), (hnames[i]).second.c_str(), 100, 0., 1000.));
640  }
641 
643  for (unsigned int i = 0; i < hnames.size(); i++) {
644  std::string htag = (hnames[i]).first + stag;
645  histograms.Charge_2[elepos].push_back(ibooker.book1DD(htag.c_str(), (hnames[i]).second.c_str(), 100, 0., 1000.));
646  }
647 
649  for (unsigned int i = 0; i < hnames.size(); i++) {
650  std::string htag = (hnames[i]).first + stag;
651  histograms.Charge_3[elepos].push_back(ibooker.book1DD(htag.c_str(), (hnames[i]).second.c_str(), 100, 0., 1000.));
652  }
653 
655  for (unsigned int i = 0; i < hnames.size(); i++) {
656  std::string htag = (hnames[i]).first + stag;
657  histograms.Charge_4[elepos].push_back(ibooker.book1DD(htag.c_str(), (hnames[i]).second.c_str(), 100, 0., 1000.));
658  }
659 }
static constexpr auto TEC
virtual int nstrips() const =0
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
std::vector< unsigned int > FetchIndices(std::map< unsigned int, APVloc >, uint32_t, const TrackerTopology *topo=nullptr)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const TrackerGeomDet * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
const LocalTrajectoryError & localError() const
MonitorElement * book2S(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:254
edm::ESGetToken< SiStripQuality, SiStripQualityRcd > qualityToken_
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
virtual int ncolumns() const =0
int statCollectionFromMode(const char *tag) const
unsigned int tidSide(const DetId &id) const
void dqmBeginRun(edm::Run const &, edm::EventSetup const &, APVGain::APVGainHistograms &) const override
SiStripGainsPCLWorker(const edm::ParameterSet &)
virtual int nrows() const =0
int subdetectorPlane(uint32_t, const TrackerTopology *)
const DetContainer & dets() const override
Returm a vector of all GeomDet (including all GeomDetUnits)
Log< level::Error, false > LogError
edm::EDGetTokenT< edm::View< reco::Track > > m_tracks_token
LocalError positionError() const
edm::EDGetTokenT< TrajTrackAssociationCollection > m_association_token
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
T getUntrackedParameter(std::string const &, T const &) const
std::vector< std::string > dqm_tag_
U second(std::pair< T, U > const &p)
void dqmAnalyze(edm::Event const &, edm::EventSetup const &, APVGain::APVGainHistograms const &) const override
MonitorElement * book1DD(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:155
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
unsigned int tecSide(const DetId &id) const
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomTokenBR_
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomToken_
LocalVector localDirection() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isFarFromBorder(const TrajectoryStateOnSurface &trajState, const GeomDetUnit *it)
Definition: DeDxTools.cc:426
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
std::map< unsigned int, APVloc > theTopologyMap
void checkBookAPVColls(const TrackerGeometry *bareTkGeomPtr, const TrackerTopology *bareTkTopoPtr, APVGain::APVGainHistograms &histograms) const
static constexpr auto TOB
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
Log< level::Info, false > LogInfo
edm::ESGetToken< SiStripGain, SiStripGainRcd > gainToken_
Definition: DetId.h:17
static constexpr auto TIB
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
int subdetectorSide(uint32_t, const TrackerTopology *)
double b
Definition: hdecay.h:120
std::vector< std::string > VChargeHisto
int thickness(uint32_t)
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoTokenBR_
Pixel cluster – collection of neighboring pixels above threshold.
HLT enums.
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &, APVGain::APVGainHistograms &) const override
double a
Definition: hdecay.h:121
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
Log< level::Warning, false > LogWarning
std::vector< std::pair< std::string, std::string > > monHnames(std::vector< std::string >, bool, const char *tag)
MonitorElement * book2I(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:296
static constexpr auto TID
int subdetectorId(uint32_t)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: Run.h:45
Our base class.
Definition: SiPixelRecHit.h:23
#define LogDebug(id)
def exit(msg="")