CMS 3D CMS Logo

SiStripHitEfficiencyWorker.cc
Go to the documentation of this file.
1 // Package: CalibTracker/SiStripHitEfficiency
3 // Class: SiStripHitEfficiencyWorker
4 // Original Author: Pieter David
5 //
6 // Adapted from HitEff (Keith Ulmer -- University of Colorado, keith.ulmer@colorado.edu
7 // SiStripHitEffFromCalibTree (Christopher Edelmaier)
9 
61 
63 public:
64  explicit SiStripHitEfficiencyWorker(const edm::ParameterSet& conf);
65  ~SiStripHitEfficiencyWorker() override = default;
66  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
67 
68 private:
69  void bookHistograms(DQMStore::IBooker& booker, const edm::Run& run, const edm::EventSetup& setup) override;
70  void analyze(const edm::Event& e, const edm::EventSetup& c) override;
71  void fillForTraj(const TrajectoryAtInvalidHit& tm,
72  const TrackerTopology* tTopo,
73  const TrackerGeometry* tkgeom,
74  const StripClusterParameterEstimator& stripCPE,
75  const SiStripQuality& stripQuality,
76  const DetIdCollection& fedErrorIds,
77  const edm::Handle<edm::DetSetVector<SiStripRawDigi>>& commonModeDigis,
78  const edmNew::DetSetVector<SiStripCluster>& theClusters,
79  int bunchCrossing,
80  float instLumi,
81  float PU,
82  bool highPurity);
83 
84  // ----------member data ---------------------------
86 
87  // event data tokens
97 
98  // event setup tokens
108 
109  // configurable parameters
111  unsigned int layers_;
112  bool DEBUG_;
113  bool addLumi_;
116  unsigned int trackMultiplicityCut_;
122  float resXSig_;
126  int bunchX_;
129  unsigned int nTEClayers_;
130 
131  // output file
132  std::set<uint32_t> badModules_;
133 
134  // for the missing hits recovery
135  std::vector<unsigned int> hitRecoveryCounters;
136  std::vector<unsigned int> hitTotalCounters;
138  std::vector<int> missHitPerLayer;
139 
140  struct EffME1 {
141  EffME1() : hTotal(nullptr), hFound(nullptr) {}
143 
144  void fill(double x, bool found, float weight = 1.) {
145  hTotal->Fill(x, weight);
146  if (found) {
147  hFound->Fill(x, weight);
148  }
149  }
150 
152  };
153  struct EffTkMap {
154  EffTkMap() : hTotal(nullptr), hFound(nullptr) {}
155  EffTkMap(std::unique_ptr<TkHistoMap>&& total, std::unique_ptr<TkHistoMap>&& found)
156  : hTotal(std::move(total)), hFound(std::move(found)) {}
157 
158  void fill(uint32_t id, bool found, float weight = 1.) {
159  hTotal->fill(id, weight);
160  if (found) {
161  hFound->fill(id, weight);
162  }
163  }
164 
165  bool check(uint32_t id) {
166  if (hTotal->getValue(id) < hFound->getValue(id)) {
167  return false;
168  } else {
169  return true;
170  }
171  }
172 
173  std::unique_ptr<TkHistoMap> hTotal, hFound;
174  };
175 
181  std::vector<MonitorElement*> h_resolution;
182  std::vector<EffME1> h_layer_vsLumi;
183  std::vector<EffME1> h_layer_vsBx;
184  std::vector<EffME1> h_layer_vsPU;
185  std::vector<EffME1> h_layer_vsCM;
186  std::vector<MonitorElement*> h_hotcold;
187 
189 };
190 
191 //
192 // constructors and destructor
193 //
194 
196  : scalerToken_(consumes<LumiScalersCollection>(conf.getParameter<edm::InputTag>("lumiScalers"))),
197  metaDataToken_(consumes<OnlineLuminosityRecord>(conf.getParameter<edm::InputTag>("metadata"))),
198  commonModeToken_(mayConsume<edm::DetSetVector<SiStripRawDigi>>(conf.getParameter<edm::InputTag>("commonMode"))),
199  combinatorialTracks_token_(
200  consumes<reco::TrackCollection>(conf.getParameter<edm::InputTag>("combinatorialTracks"))),
201  trajectories_token_(consumes<std::vector<Trajectory>>(conf.getParameter<edm::InputTag>("trajectories"))),
202  trajTrackAsso_token_(consumes<TrajTrackAssociationCollection>(conf.getParameter<edm::InputTag>("trajectories"))),
203  clusters_token_(
204  consumes<edmNew::DetSetVector<SiStripCluster>>(conf.getParameter<edm::InputTag>("siStripClusters"))),
205  digis_token_(consumes<DetIdCollection>(conf.getParameter<edm::InputTag>("siStripDigis"))),
206  trackerEvent_token_(consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("trackerEvent"))),
207  tTopoToken_(esConsumes()),
208  tkGeomToken_(esConsumes()),
209  stripCPEToken_(esConsumes(edm::ESInputTag{"", "StripCPEfromTrackAngle"})),
210  stripQualityToken_(esConsumes()),
211  magFieldToken_(esConsumes()),
212  measTrackerToken_(esConsumes()),
213  chi2EstimatorToken_(esConsumes(edm::ESInputTag{"", "Chi2"})),
214  propagatorToken_(esConsumes(edm::ESInputTag{"", "PropagatorWithMaterial"})),
215  tkDetMapToken_(esConsumes<edm::Transition::BeginRun>()),
216  dqmDir_(conf.getParameter<std::string>("dqmDir")),
217  layers_(conf.getParameter<int>("Layer")),
218  DEBUG_(conf.getUntrackedParameter<bool>("Debug", false)),
219  addLumi_(conf.getUntrackedParameter<bool>("addLumi", false)),
220  addCommonMode_(conf.getUntrackedParameter<bool>("addCommonMode", false)),
221  cutOnTracks_(conf.getParameter<bool>("cutOnTracks")),
222  trackMultiplicityCut_(conf.getParameter<unsigned int>("trackMultiplicity")),
223  useFirstMeas_(conf.getParameter<bool>("useFirstMeas")),
224  useLastMeas_(conf.getParameter<bool>("useLastMeas")),
225  useAllHitsFromTracksWithMissingHits_(conf.getParameter<bool>("useAllHitsFromTracksWithMissingHits")),
226  doMissingHitsRecovery_(conf.getParameter<bool>("doMissingHitsRecovery")),
227  clusterMatchingMethod_(conf.getParameter<int>("ClusterMatchingMethod")),
228  resXSig_(conf.getParameter<double>("ResXSig")),
229  clusterTracjDist_(conf.getParameter<double>("ClusterTrajDist")),
230  stripsApvEdge_(conf.getParameter<double>("StripsApvEdge")),
231  useOnlyHighPurityTracks_(conf.getParameter<bool>("UseOnlyHighPurityTracks")),
232  bunchX_(conf.getUntrackedParameter<int>("BunchCrossing", 0)),
233  showRings_(conf.getUntrackedParameter<bool>("ShowRings", false)),
234  showTOB6TEC9_(conf.getUntrackedParameter<bool>("ShowTOB6TEC9", false)) {
235  hitRecoveryCounters.resize(k_END_OF_LAYERS, 0);
236  hitTotalCounters.resize(k_END_OF_LAYERS, 0);
237  missHitPerLayer.resize(k_END_OF_LAYERS, 0);
238  totalNbHits = 0;
239 
240  nTEClayers_ = (showRings_ ? 7 : 9); // number of rings or wheels
241 
242  const std::string badModulesFile = conf.getUntrackedParameter<std::string>("BadModulesFile", "");
243  if (!badModulesFile.empty()) {
244  std::ifstream badModules_file(badModulesFile);
245  uint32_t badmodule_detid;
246  int mods, fiber1, fiber2, fiber3;
247  if (badModules_file.is_open()) {
249  while (getline(badModules_file, line)) {
250  if (badModules_file.eof())
251  continue;
252  std::stringstream ss(line);
253  ss >> badmodule_detid >> mods >> fiber1 >> fiber2 >> fiber3;
254  if (badmodule_detid != 0 && mods == 1 && (fiber1 == 1 || fiber2 == 1 || fiber3 == 1))
255  badModules_.insert(badmodule_detid);
256  }
257  badModules_file.close();
258  }
259  }
260  if (!badModules_.empty())
261  LogDebug("SiStripHitEfficiencyWorker") << "Remove additionnal bad modules from the analysis: ";
262  for (const auto badMod : badModules_) {
263  LogDebug("SiStripHitEfficiencyWorker") << " " << badMod;
264  }
265 }
266 
268  const edm::Run& run,
269  const edm::EventSetup& setup) {
270  booker.setCurrentFolder(fmt::format("{}/EventInfo", dqmDir_));
271  h_bx = booker.book1D("bx", "bx", 3600, 0, 3600);
272  h_instLumi = booker.book1D("instLumi", "inst. lumi.", 250, 0, 25000);
273  h_PU = booker.book1D("PU", "PU", 200, 0, 200);
274  h_nTracks = booker.book1D("ntracks", "n.tracks;n. tracks;n.events", 500, -0.5, 499.5);
275  h_nTracksVsPU = booker.bookProfile("nTracksVsPU", "n. tracks vs PU; PU; n.tracks ", 200, 0, 200, 500, -0.5, 499.5);
276 
277  calibData_.EventStats = booker.book2I("EventStats", "Statistics", 3, -0.5, 2.5, 1, 0, 1);
278  calibData_.EventStats->setBinLabel(1, "events count", 1);
279  calibData_.EventStats->setBinLabel(2, "tracks count", 1);
280  calibData_.EventStats->setBinLabel(3, "measurements count", 1);
281 
282  booker.setCurrentFolder(dqmDir_);
283  h_goodLayer = EffME1(booker.book1D("goodlayer_total", "goodlayer_total", 35, 0., 35.),
284  booker.book1D("goodlayer_found", "goodlayer_found", 35, 0., 35.));
285  h_allLayer = EffME1(booker.book1D("alllayer_total", "alllayer_total", 35, 0., 35.),
286  booker.book1D("alllayer_found", "alllayer_found", 35, 0., 35.));
287 
288  h_layer = EffME1(
289  booker.book1D(
290  "layer_found", "layer_found", bounds::k_END_OF_LAYERS, 0., static_cast<float>(bounds::k_END_OF_LAYERS)),
291  booker.book1D(
292  "layer_total", "layer_total", bounds::k_END_OF_LAYERS, 0., static_cast<float>(bounds::k_END_OF_LAYERS)));
293 
294  for (int layer = 1; layer != bounds::k_END_OF_LAYERS; ++layer) {
295  const auto lyrName = ::layerName(layer, showRings_, nTEClayers_);
296 
297  // book resolutions
298  booker.setCurrentFolder(fmt::format("{}/Resolutions", dqmDir_));
299  auto ihres = booker.book1D(Form("resol_layer_%i", layer), lyrName, 125, -125., 125.);
300  ihres->setAxisTitle("trajX-clusX [strip unit]");
301  h_resolution.push_back(ihres);
302 
303  // book plots vs Lumi
304  booker.setCurrentFolder(fmt::format("{}/VsLumi", dqmDir_));
305  h_layer_vsLumi.push_back(EffME1(booker.book1D(Form("layertotal_vsLumi_layer_%i", layer), lyrName, 100, 0, 25000),
306  booker.book1D(Form("layerfound_vsLumi_layer_%i", layer), lyrName, 100, 0, 25000)));
307 
308  // book plots vs Lumi
309  booker.setCurrentFolder(fmt::format("{}/VsPu", dqmDir_));
310  h_layer_vsPU.push_back(EffME1(booker.book1D(Form("layertotal_vsPU_layer_%i", layer), lyrName, 45, 0, 90),
311  booker.book1D(Form("layerfound_vsPU_layer_%i", layer), lyrName, 45, 0, 90)));
312  if (addCommonMode_) {
313  // book plots for common mode
314  booker.setCurrentFolder(fmt::format("{}/CommonMode", dqmDir_));
315  h_layer_vsCM.push_back(EffME1(booker.book1D(Form("layertotal_vsCM_layer_%i", layer), lyrName, 20, 0, 400),
316  booker.book1D(Form("layerfound_vsCM_layer_%i", layer), lyrName, 20, 0, 400)));
317  }
318 
319  // book plots vs Lumi
320  booker.setCurrentFolder(fmt::format("{}/VsBx", dqmDir_));
321  h_layer_vsBx.push_back(EffME1(
322  booker.book1D(Form("totalVsBx_layer%i", layer), Form("layer %i (%s)", layer, lyrName.c_str()), 3565, 0, 3565),
323  booker.book1D(Form("foundVsBx_layer%i", layer), Form("layer %i (%s)", layer, lyrName.c_str()), 3565, 0, 3565)));
324 
325  // book hot and cold
326  booker.setCurrentFolder(fmt::format("{}/MissingHits", dqmDir_));
327  if (layer <= bounds::k_LayersAtTOBEnd) {
328  const bool isTIB = layer <= bounds::k_LayersAtTIBEnd;
329  const auto partition = (isTIB ? "TIB" : "TOB");
330  const auto yMax = (isTIB ? 100 : 120);
331 
332  const auto& tit =
333  Form("%s%i: Map of missing hits", partition, (isTIB ? layer : layer - bounds::k_LayersAtTIBEnd));
334 
335  // histogram name must not contain ":" otherwise it fails upload to the GUI
336  // see https://github.com/cms-DQM/dqmgui_prod/blob/af0a388e8f57c60e51111585d298aeeea943367f/src/cpp/DQM/DQMStore.cc#L56
337  std::string name{tit};
338  ::replaceInString(name, ":", "");
339 
340  auto ihhotcold = booker.book2D(name, tit, 100, -1, 361, 100, -yMax, yMax);
341  ihhotcold->setAxisTitle("#phi [deg]", 1);
342  ihhotcold->setBinLabel(1, "360", 1);
343  ihhotcold->setBinLabel(50, "180", 1);
344  ihhotcold->setBinLabel(100, "0", 1);
345  ihhotcold->setAxisTitle("Global Z [cm]", 2);
346  ihhotcold->setOption("colz");
347  h_hotcold.push_back(ihhotcold);
348  } else {
349  const bool isTID = layer <= bounds::k_LayersAtTIDEnd;
350  const auto partitions =
351  (isTID ? std::vector<std::string>{"TIDplus", "TIDminus"} : std::vector<std::string>{"TECplus", "TECminus"});
352  const auto axMax = (isTID ? 100 : 120);
353  for (const auto& part : partitions) {
354  // create the title by replacing the minus/plus symbols
355  std::string forTitle{part};
356  ::replaceInString(forTitle, "minus", "-");
357  ::replaceInString(forTitle, "plus", "+");
358 
359  // histogram name must not contain ":" otherwise it fails upload to the GUI
360  // see https://github.com/cms-DQM/dqmgui_prod/blob/af0a388e8f57c60e51111585d298aeeea943367f/src/cpp/DQM/DQMStore.cc#L56
361  const auto& name = Form("%s %i Map of Missing Hits",
362  part.c_str(),
363  (isTID ? layer - bounds::k_LayersAtTOBEnd : layer - bounds::k_LayersAtTIDEnd));
364  const auto& tit = Form("%s%i: Map of Missing Hits",
365  forTitle.c_str(),
366  (isTID ? layer - bounds::k_LayersAtTOBEnd : layer - bounds::k_LayersAtTIDEnd));
367 
368  auto ihhotcold = booker.book2D(name, tit, 100, -axMax, axMax, 100, -axMax, axMax);
369  ihhotcold->setAxisTitle("Global Y", 1);
370  ihhotcold->setBinLabel(1, "+Y", 1);
371  ihhotcold->setBinLabel(50, "0", 1);
372  ihhotcold->setBinLabel(100, "-Y", 1);
373  ihhotcold->setAxisTitle("Global X", 2);
374  ihhotcold->setBinLabel(1, "-X", 2);
375  ihhotcold->setBinLabel(50, "0", 2);
376  ihhotcold->setBinLabel(100, "+X", 2);
377  ihhotcold->setOption("colz");
378  h_hotcold.push_back(ihhotcold);
379  }
380  }
381  }
382 
383  // come back to the main folder
384  booker.setCurrentFolder(dqmDir_);
385  const auto tkDetMapFolder = fmt::format("{}/TkDetMaps", dqmDir_);
386 
387  const TkDetMap* tkDetMap = &setup.getData(tkDetMapToken_);
388  h_module =
389  EffTkMap(std::make_unique<TkHistoMap>(tkDetMap, booker, tkDetMapFolder, "perModule_total", 0, false, true),
390  std::make_unique<TkHistoMap>(tkDetMap, booker, tkDetMapFolder, "perModule_found", 0, false, true));
391 
392  // fill the FED Errors
393  booker.setCurrentFolder(dqmDir_);
394  const auto FEDErrorMapFolder = fmt::format("{}/FEDErrorTkDetMaps", dqmDir_);
396  std::make_unique<TkHistoMap>(tkDetMap, booker, FEDErrorMapFolder, "perModule_FEDErrors", 0, false, true);
397 }
398 
400  const auto tTopo = &es.getData(tTopoToken_);
401 
402  // bool DEBUG_ = false;
403 
404  LogDebug("SiStripHitEfficiencyWorker") << "beginning analyze from HitEff";
405 
406  // Step A: Get Inputs
407 
408  // Luminosity informations
411 
412  float instLumi = 0;
413  float PU = 0;
414  if (addLumi_) {
415  if (lumiScalers.isValid() && !lumiScalers->empty()) {
416  if (lumiScalers->begin() != lumiScalers->end()) {
417  instLumi = lumiScalers->begin()->instantLumi();
418  PU = lumiScalers->begin()->pileup();
419  }
420  } else if (metaData.isValid()) {
421  instLumi = metaData->instLumi();
422  PU = metaData->avgPileUp();
423  } else {
424  edm::LogWarning("SiStripHitEfficiencyWorker") << "could not find a source for the Luminosity and PU";
425  }
426  }
427 
428  h_bx->Fill(e.bunchCrossing());
430  h_PU->Fill(PU);
431 
433  if (addCommonMode_)
434  e.getByToken(commonModeToken_, commonModeDigis);
435 
437  e.getByToken(combinatorialTracks_token_, tracksCKF);
438 
439  edm::Handle<std::vector<Trajectory>> TrajectoryCollectionCKF;
440  e.getByToken(trajectories_token_, TrajectoryCollectionCKF);
441 
442  edm::Handle<TrajTrackAssociationCollection> trajTrackAssociationHandle;
443  e.getByToken(trajTrackAsso_token_, trajTrackAssociationHandle);
444 
446  e.getByToken(clusters_token_, theClusters);
447 
448  edm::Handle<DetIdCollection> fedErrorIds;
449  e.getByToken(digis_token_, fedErrorIds);
450 
451  // fill the calibData with the FEDErrors
452  for (const auto& fedErr : *fedErrorIds) {
453  // fill the TkHistoMap occupancy map
454  calibData_.FEDErrorOccupancy->fill(fedErr.rawId(), 1.);
455 
456  // fill the unordered map
457  if (calibData_.fedErrorCounts.find(fedErr.rawId()) != calibData_.fedErrorCounts.end()) {
458  calibData_.fedErrorCounts[fedErr.rawId()] += 1;
459  } else {
460  calibData_.fedErrorCounts.insert(std::make_pair(fedErr.rawId(), 1));
461  }
462  }
463 
466 
467  const auto tkgeom = &es.getData(tkGeomToken_);
468  const auto& stripcpe = es.getData(stripCPEToken_);
469  const auto& stripQuality = es.getData(stripQualityToken_);
470  const auto& magField = es.getData(magFieldToken_);
471  const auto& measTracker = es.getData(measTrackerToken_);
472  const auto& chi2Estimator = es.getData(chi2EstimatorToken_);
473  const auto& prop = es.getData(propagatorToken_);
474 
475  // Tracking
476  LogDebug("SiStripHitEfficiencyWorker") << "number ckf tracks found = " << tracksCKF->size();
477 
478  h_nTracks->Fill(tracksCKF->size());
479  h_nTracksVsPU->Fill(PU, tracksCKF->size());
480 
481  // bin 0: one entry for each event
482  calibData_.EventStats->Fill(0., 0., 1);
483  // bin 1: one entry for each track
484  calibData_.EventStats->Fill(1., 0., tracksCKF->size());
485 
486  if (!tracksCKF->empty()) {
487  if (cutOnTracks_ && (tracksCKF->size() >= trackMultiplicityCut_))
488  return;
489  if (cutOnTracks_)
490  LogDebug("SiStripHitEfficiencyWorker")
491  << "starting checking good event with < " << trackMultiplicityCut_ << " tracks";
492 
493  // actually should do a loop over all the tracks in the event here
494 
495  // Looping over traj-track associations to be able to get traj & track informations
496  for (const auto& trajTrack : *trajTrackAssociationHandle) {
497  // for each track, fill some variables such as number of hits and momentum
498 
499  const bool highPurity = trajTrack.val->quality(reco::TrackBase::TrackQuality::highPurity);
500  auto TMeas = trajTrack.key->measurements();
501  totalNbHits += int(TMeas.size());
502 
503  /*
504  const bool hasMissingHits = std::any_of(std::begin(TMeas), std::end(TMeas), [](const auto& tm) {
505  return tm.recHit()->getType() == TrackingRecHit::Type::missing;
506  });
507  */
508 
509  // Check whether the trajectory has some missing hits
510  bool hasMissingHits{false};
511  int previous_layer{999};
512  std::vector<unsigned int> missedLayers;
513 
514  for (const auto& itm : TMeas) {
515  auto theHit = itm.recHit();
516  unsigned int iidd = theHit->geographicalId().rawId();
517  int layer = ::checkLayer(iidd, tTopo);
518  int missedLayer = layer + 1;
519  int diffPreviousLayer = (layer - previous_layer);
521  //Layers from TIB + TOB
522  if (diffPreviousLayer == -2 && missedLayer > k_LayersStart && missedLayer < k_LayersAtTOBEnd) {
523  missHitPerLayer[missedLayer] += 1;
524  hasMissingHits = true;
525  }
526  //Layers from TID
527  else if (diffPreviousLayer == -2 && (missedLayer > k_LayersAtTOBEnd + 1 && missedLayer <= k_LayersAtTIDEnd)) {
528  missHitPerLayer[missedLayer] += 1;
529  hasMissingHits = true;
530  }
531  //Layers from TEC
532  else if (diffPreviousLayer == -2 && missedLayer > k_LayersAtTIDEnd && missedLayer <= k_LayersAtTECEnd) {
533  missHitPerLayer[missedLayer] += 1;
534  hasMissingHits = true;
535  }
536 
537  //##### TID Layer 11 in transition TID -> TIB : layer is in TIB, previous layer = 12
538  if ((layer > k_LayersStart && layer <= k_LayersAtTIBEnd) && (previous_layer == 12)) {
539  missHitPerLayer[11] += 1;
540  hasMissingHits = true;
541  }
542 
543  //##### TEC Layer 14 in transition TEC -> TOB : layer is in TOB, previous layer = 15
544  if ((layer > k_LayersAtTIBEnd && layer <= k_LayersAtTOBEnd) && (previous_layer == 15)) {
545  missHitPerLayer[14] += 1;
546  hasMissingHits = true;
547  }
548  }
549  if (theHit->getType() == TrackingRecHit::Type::missing)
550  hasMissingHits = true;
551 
552  if (hasMissingHits)
553  missedLayers.push_back(layer);
554  previous_layer = layer;
555  }
556 
557  // Loop on each measurement and take into consideration
558  //--------------------------------------------------------
559  unsigned int prev_TKlayers = 0;
560  for (auto itm = TMeas.cbegin(); itm != TMeas.cend(); ++itm) {
561  const auto theInHit = (*itm).recHit();
562 
563  //bin 2: one entry for each measurement
564  calibData_.EventStats->Fill(2., 0., 1.);
565 
566  LogDebug("SiStripHitEfficiencyWorker") << "theInHit is valid = " << theInHit->isValid();
567 
568  unsigned int iidd = theInHit->geographicalId().rawId();
569 
570  unsigned int TKlayers = ::checkLayer(iidd, tTopo);
571 
572  // do not bother with pixel hits
573  if (DetId(iidd).subdetId() < SiStripSubdetector::TIB)
574  continue;
575 
576  LogDebug("SiStripHitEfficiencyWorker") << "TKlayer from trajectory: " << TKlayers << " from module = " << iidd
577  << " matched/stereo/rphi = " << ((iidd & 0x3) == 0) << "/"
578  << ((iidd & 0x3) == 1) << "/" << ((iidd & 0x3) == 2);
579 
580  // Test first and last points of the trajectory
581  // the list of measurements starts from outer layers !!! This could change -> should add a check
582  bool isFirstMeas = (itm == (TMeas.end() - 1));
583  bool isLastMeas = (itm == (TMeas.begin()));
584 
585  if (!useFirstMeas_ && isFirstMeas)
586  continue;
587  if (!useLastMeas_ && isLastMeas)
588  continue;
589 
590  // In case of missing hit in the track, check whether to use the other hits or not.
591  if (hasMissingHits && theInHit->getType() != TrackingRecHit::Type::missing &&
593  continue;
594 
595  // If Trajectory measurement from TOB 6 or TEC 9, skip it because it's always valid they are filled later
596  if (TKlayers == bounds::k_LayersAtTOBEnd || TKlayers == bounds::k_LayersAtTECEnd) {
597  LogDebug("SiStripHitEfficiencyWorker") << "skipping original TM for TOB 6 or TEC 9";
598  continue;
599  }
600 
601  std::vector<TrajectoryAtInvalidHit> TMs;
602 
603  // Make AnalyticalPropagat // TODO where to save these?or to use in TAVH constructor
605 
606  // for double sided layers check both sensors--if no hit was found on either sensor surface,
607  // the trajectory measurements only have one invalid hit entry on the matched surface
608  // so get the TrajectoryAtInvalidHit for both surfaces and include them in the study
609  if (::isDoubleSided(iidd, tTopo) && ((iidd & 0x3) == 0)) {
610  // do hit eff check twice--once for each sensor
611  //add a TM for each surface
612  TMs.emplace_back(*itm, tTopo, tkgeom, propagator, 1);
613  TMs.emplace_back(*itm, tTopo, tkgeom, propagator, 2);
614  } else if (::isDoubleSided(iidd, tTopo) && (!::check2DPartner(iidd, TMeas))) {
615  // if only one hit was found the trajectory measurement is on that sensor surface, and the other surface from
616  // the matched layer should be added to the study as well
617  TMs.emplace_back(*itm, tTopo, tkgeom, propagator, 1);
618  TMs.emplace_back(*itm, tTopo, tkgeom, propagator, 2);
619  LogDebug("SiStripHitEfficiencyWorker") << " found a hit with a missing partner";
620  } else {
621  //only add one TM for the single surface and the other will be added in the next iteration
622  TMs.emplace_back(*itm, tTopo, tkgeom, propagator);
623  }
624 
625  bool missingHitAdded{false};
626  std::vector<TrajectoryMeasurement> tmpTmeas;
627  unsigned int misLayer = TKlayers + 1;
628  //Use bool doMissingHitsRecovery to add possible missing hits based on actual/previous hit
630  if (int(TKlayers) - int(prev_TKlayers) == -2) {
631  const DetLayer* detlayer = itm->layer();
632  const LayerMeasurements layerMeasurements{measTracker, *measurementTrackerEvent};
633  const TrajectoryStateOnSurface tsos = itm->updatedState();
634  std::vector<DetLayer::DetWithState> compatDets = detlayer->compatibleDets(tsos, prop, chi2Estimator);
635 
636  if (misLayer > k_LayersAtTIDEnd && misLayer < k_LayersAtTECEnd) { //TEC
637  std::vector<ForwardDetLayer const*> negTECLayers = measTracker.geometricSearchTracker()->negTecLayers();
638  std::vector<ForwardDetLayer const*> posTECLayers = measTracker.geometricSearchTracker()->posTecLayers();
639  const DetLayer* tecLayerneg = negTECLayers[misLayer - k_LayersAtTIDEnd - 1];
640  const DetLayer* tecLayerpos = posTECLayers[misLayer - k_LayersAtTIDEnd - 1];
641  if (tTopo->tecSide(iidd) == 1) {
642  tmpTmeas = layerMeasurements.measurements(*tecLayerneg, tsos, prop, chi2Estimator);
643  } else if (tTopo->tecSide(iidd) == 2) {
644  tmpTmeas = layerMeasurements.measurements(*tecLayerpos, tsos, prop, chi2Estimator);
645  }
646  }
647 
648  else if (misLayer == (k_LayersAtTIDEnd - 1) ||
649  misLayer == k_LayersAtTIDEnd) { // This is for TID layers 12 and 13
650  std::vector<ForwardDetLayer const*> negTIDLayers = measTracker.geometricSearchTracker()->negTidLayers();
651  std::vector<ForwardDetLayer const*> posTIDLayers = measTracker.geometricSearchTracker()->posTidLayers();
652  const DetLayer* tidLayerneg = negTIDLayers[misLayer - k_LayersAtTOBEnd - 1];
653  const DetLayer* tidLayerpos = posTIDLayers[misLayer - k_LayersAtTOBEnd - 1];
654 
655  if (tTopo->tidSide(iidd) == 1) {
656  tmpTmeas = layerMeasurements.measurements(*tidLayerneg, tsos, prop, chi2Estimator);
657  } else if (tTopo->tidSide(iidd) == 2) {
658  tmpTmeas = layerMeasurements.measurements(*tidLayerpos, tsos, prop, chi2Estimator);
659  }
660  }
661 
662  if (misLayer > k_LayersStart && misLayer < k_LayersAtTOBEnd) { // Barrel
663 
664  std::vector<BarrelDetLayer const*> barrelTIBLayers = measTracker.geometricSearchTracker()->tibLayers();
665  std::vector<BarrelDetLayer const*> barrelTOBLayers = measTracker.geometricSearchTracker()->tobLayers();
666 
667  if (misLayer > k_LayersStart && misLayer <= k_LayersAtTIBEnd) {
668  const DetLayer* tibLayer = barrelTIBLayers[misLayer - k_LayersStart - 1];
669  tmpTmeas = layerMeasurements.measurements(*tibLayer, tsos, prop, chi2Estimator);
670  } else if (misLayer > k_LayersAtTIBEnd && misLayer < k_LayersAtTOBEnd) {
671  const DetLayer* tobLayer = barrelTOBLayers[misLayer - k_LayersAtTIBEnd - 1];
672  tmpTmeas = layerMeasurements.measurements(*tobLayer, tsos, prop, chi2Estimator);
673  }
674  }
675  }
676  if ((int(TKlayers) > k_LayersStart && int(TKlayers) <= k_LayersAtTIBEnd) && int(prev_TKlayers) == 12) {
677  const DetLayer* detlayer = itm->layer();
678  const LayerMeasurements layerMeasurements{measTracker, *measurementTrackerEvent};
679  const TrajectoryStateOnSurface tsos = itm->updatedState();
680  std::vector<DetLayer::DetWithState> compatDets = detlayer->compatibleDets(tsos, prop, chi2Estimator);
681  std::vector<ForwardDetLayer const*> negTIDLayers = measTracker.geometricSearchTracker()->negTidLayers();
682  std::vector<ForwardDetLayer const*> posTIDLayers = measTracker.geometricSearchTracker()->posTidLayers();
683 
684  const DetLayer* tidLayerneg = negTIDLayers[k_LayersStart];
685  const DetLayer* tidLayerpos = posTIDLayers[k_LayersStart];
686  if (tTopo->tidSide(iidd) == 1) {
687  tmpTmeas = layerMeasurements.measurements(*tidLayerneg, tsos, prop, chi2Estimator);
688  } else if (tTopo->tidSide(iidd) == 2) {
689  tmpTmeas = layerMeasurements.measurements(*tidLayerpos, tsos, prop, chi2Estimator);
690  }
691  }
692 
693  if ((int(TKlayers) > k_LayersAtTIBEnd && int(TKlayers) <= k_LayersAtTOBEnd) && int(prev_TKlayers) == 15) {
694  const DetLayer* detlayer = itm->layer();
695  const LayerMeasurements layerMeasurements{measTracker, *measurementTrackerEvent};
696  const TrajectoryStateOnSurface tsos = itm->updatedState();
697  std::vector<DetLayer::DetWithState> compatDets = detlayer->compatibleDets(tsos, prop, chi2Estimator);
698 
699  std::vector<ForwardDetLayer const*> negTECLayers = measTracker.geometricSearchTracker()->negTecLayers();
700  std::vector<ForwardDetLayer const*> posTECLayers = measTracker.geometricSearchTracker()->posTecLayers();
701 
702  const DetLayer* tecLayerneg = negTECLayers[k_LayersStart];
703  const DetLayer* tecLayerpos = posTECLayers[k_LayersStart];
704  if (tTopo->tecSide(iidd) == 1) {
705  tmpTmeas = layerMeasurements.measurements(*tecLayerneg, tsos, prop, chi2Estimator);
706  } else if (tTopo->tecSide(iidd) == 2) {
707  tmpTmeas = layerMeasurements.measurements(*tecLayerpos, tsos, prop, chi2Estimator);
708  }
709  }
710 
711  if (!tmpTmeas.empty()) {
712  TrajectoryMeasurement TM_tmp(tmpTmeas.back());
713  unsigned int iidd_tmp = TM_tmp.recHit()->geographicalId().rawId();
714  if (iidd_tmp != 0) {
715  LogDebug("SiStripHitEfficiency:HitEff") << " hit actually being added to TM vector";
716  if ((!useAllHitsFromTracksWithMissingHits_ || (!useFirstMeas_ && isFirstMeas)))
717  TMs.clear();
718  if (::isDoubleSided(iidd_tmp, tTopo)) {
719  TMs.push_back(TrajectoryAtInvalidHit(TM_tmp, tTopo, tkgeom, propagator, 1));
720  TMs.push_back(TrajectoryAtInvalidHit(TM_tmp, tTopo, tkgeom, propagator, 2));
721  } else
722  TMs.push_back(TrajectoryAtInvalidHit(TM_tmp, tTopo, tkgeom, propagator));
723  missingHitAdded = true;
724  hitRecoveryCounters[misLayer] += 1;
725  }
726  }
727  }
728 
729  prev_TKlayers = TKlayers;
730  if (!useFirstMeas_ && isFirstMeas && !missingHitAdded)
731  continue;
732  if (!useLastMeas_ && isLastMeas)
733  continue;
734  bool hitsWithBias = false;
735  for (auto ilayer : missedLayers) {
736  if (ilayer < TKlayers)
737  hitsWithBias = true;
738  }
739  if (hasMissingHits && theInHit->getType() != TrackingRecHit::Type::missing && !missingHitAdded &&
740  hitsWithBias && !useAllHitsFromTracksWithMissingHits_) {
741  continue;
742  }
743 
745  //Now check for tracks at TOB6 and TEC9
746 
747  // to make sure we only propagate on the last TOB5 hit check the next entry isn't also in TOB5
748  // to avoid bias, make sure the TOB5 hit is valid (an invalid hit on TOB5 could only exist with a valid hit on TOB6)
749  const auto nextId = (itm + 1 != TMeas.end()) ? (itm + 1)->recHit()->geographicalId() : DetId{}; // null if last
750 
751  if (TKlayers == 9 && theInHit->isValid() && !((!nextId.null()) && (::checkLayer(nextId.rawId(), tTopo) == 9))) {
752  // if ( TKlayers==9 && itm==TMeas.rbegin()) {
753  // if ( TKlayers==9 && (itm==TMeas.back()) ) { // to check for only the last entry in the trajectory for propagation
754  const DetLayer* tob6 = measTracker.geometricSearchTracker()->tobLayers().back();
755  const LayerMeasurements theLayerMeasurements{measTracker, *measurementTrackerEvent};
756  const TrajectoryStateOnSurface tsosTOB5 = itm->updatedState();
757  const auto tmp = theLayerMeasurements.measurements(*tob6, tsosTOB5, prop, chi2Estimator);
758 
759  if (!tmp.empty()) {
760  LogDebug("SiStripHitEfficiencyWorker") << "size of TM from propagation = " << tmp.size();
761 
762  // take the last of the TMs, which is always an invalid hit
763  // if no detId is available, ie detId==0, then no compatible layer was crossed
764  // otherwise, use that TM for the efficiency measurement
765  const auto& tob6TM = tmp.back();
766  const auto& tob6Hit = tob6TM.recHit();
767  if (tob6Hit->geographicalId().rawId() != 0) {
768  LogDebug("SiStripHitEfficiencyWorker") << "tob6 hit actually being added to TM vector";
769  TMs.emplace_back(tob6TM, tTopo, tkgeom, propagator);
770  }
771  }
772  }
773 
774  // same for TEC8
775  if (TKlayers == 21 && theInHit->isValid() &&
776  !((!nextId.null()) && (::checkLayer(nextId.rawId(), tTopo) == 21))) {
777  const DetLayer* tec9pos = measTracker.geometricSearchTracker()->posTecLayers().back();
778  const DetLayer* tec9neg = measTracker.geometricSearchTracker()->negTecLayers().back();
779 
780  const LayerMeasurements theLayerMeasurements{measTracker, *measurementTrackerEvent};
781  const TrajectoryStateOnSurface tsosTEC9 = itm->updatedState();
782 
783  // check if track on positive or negative z
784  if (!(iidd == SiStripSubdetector::TEC))
785  LogDebug("SiStripHitEfficiencyWorker") << "there is a problem with TEC 9 extrapolation";
786 
787  //LogDebug("SiStripHitEfficiencyWorker") << " tec9 id = " << iidd << " and side = " << tTopo->tecSide(iidd) ;
788  std::vector<TrajectoryMeasurement> tmp;
789  if (tTopo->tecSide(iidd) == 1) {
790  tmp = theLayerMeasurements.measurements(*tec9neg, tsosTEC9, prop, chi2Estimator);
791  //LogDebug("SiStripHitEfficiencyWorker") << "on negative side" ;
792  }
793  if (tTopo->tecSide(iidd) == 2) {
794  tmp = theLayerMeasurements.measurements(*tec9pos, tsosTEC9, prop, chi2Estimator);
795  //LogDebug("SiStripHitEfficiencyWorker") << "on positive side" ;
796  }
797 
798  if (!tmp.empty()) {
799  // take the last of the TMs, which is always an invalid hit
800  // if no detId is available, ie detId==0, then no compatible layer was crossed
801  // otherwise, use that TM for the efficiency measurement
802  const auto& tec9TM = tmp.back();
803  const auto& tec9Hit = tec9TM.recHit();
804 
805  const unsigned int tec9id = tec9Hit->geographicalId().rawId();
806  LogDebug("SiStripHitEfficiencyWorker")
807  << "tec9id = " << tec9id << " is Double sided = " << ::isDoubleSided(tec9id, tTopo)
808  << " and 0x3 = " << (tec9id & 0x3);
809 
810  if (tec9Hit->geographicalId().rawId() != 0) {
811  LogDebug("SiStripHitEfficiencyWorker") << "tec9 hit actually being added to TM vector";
812  // in tec the hit can be single or doubled sided. whenever the invalid hit at the end of vector of TMs is
813  // double sided it is always on the matched surface, so we need to split it into the true sensor surfaces
814  if (::isDoubleSided(tec9id, tTopo)) {
815  TMs.emplace_back(tec9TM, tTopo, tkgeom, propagator, 1);
816  TMs.emplace_back(tec9TM, tTopo, tkgeom, propagator, 2);
817  } else
818  TMs.emplace_back(tec9TM, tTopo, tkgeom, propagator);
819  }
820  } //else LogDebug("SiStripHitEfficiencyWorker") << "tec9 tmp empty" ;
821  }
822 
823  for (const auto& tm : TMs) {
824  fillForTraj(tm,
825  tTopo,
826  tkgeom,
827  stripcpe,
828  stripQuality,
829  *fedErrorIds,
830  commonModeDigis,
831  *theClusters,
832  e.bunchCrossing(),
833  instLumi,
834  PU,
835  highPurity);
836  }
837  LogDebug("SiStripHitEfficiencyWorker") << "After looping over TrajAtValidHit list";
838  }
839  LogDebug("SiStripHitEfficiencyWorker") << "end TMeasurement loop";
840  }
841  LogDebug("SiStripHitEfficiencyWorker") << "end of trajectories loop";
842  }
843 }
844 
846  const TrackerTopology* tTopo,
847  const TrackerGeometry* tkgeom,
848  const StripClusterParameterEstimator& stripCPE,
849  const SiStripQuality& stripQuality,
850  const DetIdCollection& fedErrorIds,
851  const edm::Handle<edm::DetSetVector<SiStripRawDigi>>& commonModeDigis,
852  const edmNew::DetSetVector<SiStripCluster>& theClusters,
853  int bunchCrossing,
854  float instLumi,
855  float PU,
856  bool highPurity) {
857  // --> Get trajectory from combinatedStat& e
858  const auto iidd = tm.monodet_id();
859  LogDebug("SiStripHitEfficiencyWorker") << "setting iidd = " << iidd << " before checking efficiency and ";
860 
861  const auto xloc = tm.localX();
862  const auto yloc = tm.localY();
863 
864  const auto xErr = tm.localErrorX();
865  const auto yErr = tm.localErrorY();
866 
867  int TrajStrip = -1;
868 
869  // reget layer from iidd here, to account for TOB 6 and TEC 9 TKlayers being off
870  const auto TKlayers = ::checkLayer(iidd, tTopo);
871 
872  const bool withinAcceptance =
873  tm.withinAcceptance() && (!::isInBondingExclusionZone(iidd, TKlayers, yloc, yErr, tTopo));
874 
875  if ( // (TKlayers > 0) && // FIXME confirm this
876  ((layers_ == TKlayers) ||
877  (layers_ == bounds::k_LayersStart))) { // Look at the layer not used to reconstruct the track
878  LogDebug("SiStripHitEfficiencyWorker") << "Looking at layer under study";
879  unsigned int ModIsBad = 2;
880  unsigned int SiStripQualBad = 0;
881  float commonMode = -100;
882 
883  // RPhi RecHit Efficiency
884 
885  if (!theClusters.empty()) {
886  LogDebug("SiStripHitEfficiencyWorker") << "Checking clusters with size = " << theClusters.size();
887  std::vector<::ClusterInfo> VCluster_info; //fill with X residual, X residual pull, local X
888  const auto idsv = theClusters.find(iidd);
889  if (idsv != theClusters.end()) {
890  //if (DEBUG_) LogDebug("SiStripHitEfficiencyWorker") << "the ID from the dsv = " << dsv.id() ;
891  LogDebug("SiStripHitEfficiencyWorker")
892  << "found (ClusterId == iidd) with ClusterId = " << idsv->id() << " and iidd = " << iidd;
893  const auto stripdet = dynamic_cast<const StripGeomDetUnit*>(tkgeom->idToDetUnit(DetId(iidd)));
894  const StripTopology& Topo = stripdet->specificTopology();
895 
896  float hbedge = 0.0;
897  float htedge = 0.0;
898  float hapoth = 0.0;
899  float uylfac = 0.0;
900  float uxlden = 0.0;
901  if (TKlayers > bounds::k_LayersAtTOBEnd) {
902  const BoundPlane& plane = stripdet->surface();
903  const TrapezoidalPlaneBounds* trapezoidalBounds(
904  dynamic_cast<const TrapezoidalPlaneBounds*>(&(plane.bounds())));
905  std::array<const float, 4> const& parameterTrap = (*trapezoidalBounds).parameters(); // el bueno aqui
906  hbedge = parameterTrap[0];
907  htedge = parameterTrap[1];
908  hapoth = parameterTrap[3];
909  uylfac = (htedge - hbedge) / (htedge + hbedge) / hapoth;
910  uxlden = 1 + yloc * uylfac;
911  }
912 
913  // Need to know position of trajectory in strip number for selecting the right APV later
914  if (TrajStrip == -1) {
915  int nstrips = Topo.nstrips();
916  float pitch = stripdet->surface().bounds().width() / nstrips;
917  TrajStrip = xloc / pitch + nstrips / 2.0;
918  // Need additionnal corrections for endcap
919  if (TKlayers > bounds::k_LayersAtTOBEnd) {
920  const float TrajLocXMid = xloc / (1 + (htedge - hbedge) * yloc / (htedge + hbedge) /
921  hapoth); // radialy extrapolated x loc position at middle
922  TrajStrip = TrajLocXMid / pitch + nstrips / 2.0;
923  }
924  //LogDebug("SiStripHitEfficiency")<<" Layer "<<TKlayers<<" TrajStrip: "<<nstrips<<" "<<pitch<<" "<<TrajStrip;;
925  }
926 
927  for (const auto& clus : *idsv) {
929  float res = (parameters.first.x() - xloc);
930  float sigma = ::checkConsistency(parameters, xloc, xErr);
931  // The consistency is probably more accurately measured with the Chi2MeasurementEstimator. To use it
932  // you need a TransientTrackingRecHit instead of the cluster
933  //theEstimator= new Chi2MeasurementEstimator(30);
934  //const Chi2MeasurementEstimator *theEstimator(100);
935  //theEstimator->estimate(tm.tsos(), TransientTrackingRecHit);
936 
937  if (TKlayers > bounds::k_LayersAtTOBEnd) {
938  res = parameters.first.x() - xloc / uxlden; // radialy extrapolated x loc position at middle
939  sigma = abs(res) / sqrt(parameters.second.xx() + xErr * xErr / uxlden / uxlden +
940  yErr * yErr * xloc * xloc * uylfac * uylfac / uxlden / uxlden / uxlden / uxlden);
941  }
942 
943  VCluster_info.emplace_back(res, sigma, parameters.first.x());
944 
945  LogDebug("SiStripHitEfficiencyWorker") << "Have ID match. residual = " << res << " res sigma = " << sigma;
946  //LogDebug("SiStripHitEfficiencyWorker")
947  // << "trajectory measurement compatability estimate = " << (*itm).estimate() ;
948  LogDebug("SiStripHitEfficiencyWorker")
949  << "hit position = " << parameters.first.x() << " hit error = " << sqrt(parameters.second.xx())
950  << " trajectory position = " << xloc << " traj error = " << xErr;
951  }
952  }
953  ::ClusterInfo finalCluster{1000.0, 1000.0, 0.0};
954  if (!VCluster_info.empty()) {
955  LogDebug("SiStripHitEfficiencyWorker") << "found clusters > 0";
956  if (VCluster_info.size() > 1) {
957  //get the smallest one
958  for (const auto& res : VCluster_info) {
959  if (std::abs(res.xResidualPull) < std::abs(finalCluster.xResidualPull)) {
960  finalCluster = res;
961  }
962  LogDebug("SiStripHitEfficiencyWorker")
963  << "iresidual = " << res.xResidual << " isigma = " << res.xResidualPull
964  << " and FinalRes = " << finalCluster.xResidual;
965  }
966  } else {
967  finalCluster = VCluster_info[0];
968  }
969  VCluster_info.clear();
970  }
971 
972  LogDebug("SiStripHitEfficiencyWorker") << "Final residual in X = " << finalCluster.xResidual << "+-"
973  << (finalCluster.xResidual / finalCluster.xResidualPull);
974  LogDebug("SiStripHitEfficiencyWorker")
975  << "Checking location of trajectory: abs(yloc) = " << abs(yloc) << " abs(xloc) = " << abs(xloc);
976 
977  //
978  // fill ntuple varibles
979 
980  //if ( stripQuality->IsModuleBad(iidd) )
981  if (stripQuality.getBadApvs(iidd) != 0) {
982  SiStripQualBad = 1;
983  LogDebug("SiStripHitEfficiencyWorker") << "strip is bad from SiStripQuality";
984  } else {
985  SiStripQualBad = 0;
986  LogDebug("SiStripHitEfficiencyWorker") << "strip is good from SiStripQuality";
987  }
988 
989  //check for FED-detected errors and include those in SiStripQualBad
990  for (unsigned int ii = 0; ii < fedErrorIds.size(); ii++) {
991  if (iidd == fedErrorIds[ii].rawId())
992  SiStripQualBad = 1;
993  }
994 
995  // CM of APV crossed by traj
996  if (addCommonMode_)
997  if (commonModeDigis.isValid() && TrajStrip >= 0 && TrajStrip <= 768) {
998  const auto digiframe = commonModeDigis->find(iidd);
999  if (digiframe != commonModeDigis->end())
1000  if ((unsigned)TrajStrip / sistrip::STRIPS_PER_APV < digiframe->data.size())
1001  commonMode = digiframe->data.at(TrajStrip / sistrip::STRIPS_PER_APV).adc();
1002  }
1003 
1004  LogDebug("SiStripHitEfficiencyWorker") << "before check good";
1005 
1006  if (finalCluster.xResidualPull < 999.0) { //could make requirement on track/hit consistency, but for
1007  //now take anything with a hit on the module
1008  LogDebug("SiStripHitEfficiencyWorker")
1009  << "hit being counted as good " << finalCluster.xResidual << " FinalRecHit " << iidd << " TKlayers "
1010  << TKlayers << " xloc " << xloc << " yloc " << yloc << " module " << iidd
1011  << " matched/stereo/rphi = " << ((iidd & 0x3) == 0) << "/" << ((iidd & 0x3) == 1) << "/"
1012  << ((iidd & 0x3) == 2);
1013  ModIsBad = 0;
1014  } else {
1015  LogDebug("SiStripHitEfficiencyWorker")
1016  << "hit being counted as bad ######### Invalid RPhi FinalResX " << finalCluster.xResidual
1017  << " FinalRecHit " << iidd << " TKlayers " << TKlayers << " xloc " << xloc << " yloc " << yloc
1018  << " module " << iidd << " matched/stereo/rphi = " << ((iidd & 0x3) == 0) << "/" << ((iidd & 0x3) == 1)
1019  << "/" << ((iidd & 0x3) == 2);
1020  ModIsBad = 1;
1021  LogDebug("SiStripHitEfficiencyWorker")
1022  << " RPhi Error " << sqrt(xErr * xErr + yErr * yErr) << " ErrorX " << xErr << " yErr " << yErr;
1023  }
1024 
1025  LogDebug("SiStripHitEfficiencyWorker")
1026  << "To avoid them staying unused: ModIsBad=" << ModIsBad << ", SiStripQualBad=" << SiStripQualBad
1027  << ", commonMode=" << commonMode << ", highPurity=" << highPurity
1028  << ", withinAcceptance=" << withinAcceptance;
1029 
1030  unsigned int layer = TKlayers;
1031  if (showRings_ && layer > bounds::k_LayersAtTOBEnd) { // use rings instead of wheels
1032  if (layer <= bounds::k_LayersAtTIDEnd) { // TID
1033  layer = bounds::k_LayersAtTOBEnd +
1034  tTopo->tidRing(iidd); // ((iidd >> 9) & 0x3); // 3 disks and also 3 rings -> use the same container
1035  } else { // TEC
1036  layer = bounds::k_LayersAtTIDEnd + tTopo->tecRing(iidd); // ((iidd >> 5) & 0x7);
1037  }
1038  }
1039  unsigned int layerWithSide = layer;
1040  if (layer > bounds::k_LayersAtTOBEnd && layer <= bounds::k_LayersAtTIDEnd) {
1041  const auto side = tTopo->tidSide(iidd); //(iidd >> 13) & 0x3; // TID
1042  if (side == 2)
1043  layerWithSide = layer + 3;
1044  } else if (layer > bounds::k_LayersAtTIDEnd) {
1045  const auto side = tTopo->tecSide(iidd); // (iidd >> 18) & 0x3; // TEC
1046  if (side == 1) {
1047  layerWithSide = layer + 3;
1048  } else if (side == 2) {
1049  layerWithSide = layer + 3 + (showRings_ ? 7 : 9);
1050  }
1051  }
1052 
1053  if ((bunchX_ > 0 && bunchX_ != bunchCrossing) || (!withinAcceptance) ||
1055  (!showTOB6TEC9_ && (TKlayers == bounds::k_LayersAtTOBEnd || TKlayers == bounds::k_LayersAtTECEnd)) ||
1056  (badModules_.end() != badModules_.find(iidd)))
1057  return;
1058 
1059  const bool badquality = (SiStripQualBad == 1);
1060 
1061  //Now that we have a good event, we need to look at if we expected it or not, and the location
1062  //if we didn't
1063  //Fill the missing hit information first
1064  bool badflag = false; // true for hits that are expected but not found
1065  if (resXSig_ < 0) {
1066  if (ModIsBad == 1)
1067  badflag = true; // isBad set to false in the tree when resxsig<999.0
1068  } else {
1069  if (ModIsBad == 1 || finalCluster.xResidualPull > resXSig_)
1070  badflag = true;
1071  }
1072 
1073  // Conversion of positions in strip unit
1074  int nstrips = -9;
1075  float Pitch = -9.0;
1076  const StripGeomDetUnit* stripdet = nullptr;
1077  if (finalCluster.xResidualPull ==
1078  1000.0) { // special treatment, no GeomDetUnit associated in some cases when no cluster found
1079  Pitch = 0.0205; // maximum
1080  nstrips = 768; // maximum
1081  } else {
1082  stripdet = dynamic_cast<const StripGeomDetUnit*>(tkgeom->idToDetUnit(iidd));
1083  const StripTopology& Topo = stripdet->specificTopology();
1084  nstrips = Topo.nstrips();
1085  Pitch = stripdet->surface().bounds().width() / Topo.nstrips();
1086  }
1087  double stripTrajMid = xloc / Pitch + nstrips / 2.0;
1088  double stripCluster = finalCluster.xLocal / Pitch + nstrips / 2.0;
1089  // For trapezoidal modules: extrapolation of x trajectory position to the y middle of the module
1090  // for correct comparison with cluster position
1091  if (stripdet && layer > bounds::k_LayersAtTOBEnd) {
1092  const auto& trapezoidalBounds = dynamic_cast<const TrapezoidalPlaneBounds&>(stripdet->surface().bounds());
1093  std::array<const float, 4> const& parameters = trapezoidalBounds.parameters();
1094  const float hbedge = parameters[0];
1095  const float htedge = parameters[1];
1096  const float hapoth = parameters[3];
1097  const float TrajLocXMid = xloc / (1 + (htedge - hbedge) * yloc / (htedge + hbedge) /
1098  hapoth); // radialy extrapolated x loc position at middle
1099  stripTrajMid = TrajLocXMid / Pitch + nstrips / 2.0;
1100  }
1101 
1102  if ((!badquality) && (layer < h_resolution.size())) {
1103  LogDebug("SiStripHitEfficiencyWorker")
1104  << "layer " << layer << " vector index " << layer - 1 << " before filling h_resolution" << std::endl;
1105  h_resolution[layer - 1]->Fill(finalCluster.xResidualPull != 1000.0 ? stripTrajMid - stripCluster : 1000);
1106  }
1107 
1108  // New matching methods
1109  if (clusterMatchingMethod_ >= 1) {
1110  badflag = false;
1111  if (finalCluster.xResidualPull == 1000.0) {
1112  LogDebug("SiStripHitEfficiencyWorker") << "Marking bad for resxsig=1000";
1113  badflag = true;
1114  } else {
1116  // check the distance between cluster and trajectory position
1117  if (std::abs(stripCluster - stripTrajMid) > clusterTracjDist_) {
1118  LogDebug("SiStripHitEfficiencyWorker") << "Marking bad for cluster-to-traj distance";
1119  badflag = true;
1120  }
1121  }
1123  // cluster and traj have to be in the same APV (don't take edges into accounts)
1124  const int tapv = (int)stripTrajMid / sistrip::STRIPS_PER_APV;
1125  const int capv = (int)stripCluster / sistrip::STRIPS_PER_APV;
1126  float stripInAPV = stripTrajMid - tapv * sistrip::STRIPS_PER_APV;
1127  if (stripInAPV < stripsApvEdge_ || stripInAPV > sistrip::STRIPS_PER_APV - stripsApvEdge_) {
1128  LogDebug("SiStripHitEfficiencyWorker") << "Too close to the edge: " << stripInAPV;
1129  return;
1130  }
1131  if (tapv != capv) {
1132  LogDebug("SiStripHitEfficiencyWorker") << "Marking bad for tapv!=capv";
1133  badflag = true;
1134  }
1135  }
1136  }
1137  }
1138  if (!badquality) {
1139  LogDebug("SiStripHitEfficiencyWorker")
1140  << "Filling measurement for " << iidd << " in layer " << layer << " histograms with bx=" << bunchCrossing
1141  << ", lumi=" << instLumi << ", PU=" << PU << "; bad flag=" << badflag;
1142 
1143  // hot/cold maps of hits that are expected but not found
1144  if (badflag) {
1145  if (layer > bounds::k_LayersStart && layer <= bounds::k_LayersAtTIBEnd) {
1146  //We are in the TIB
1147  float phi = ::calcPhi(tm.globalX(), tm.globalY());
1148  h_hotcold[layer - 1]->Fill(360. - phi, tm.globalZ(), 1.);
1149  } else if (layer > bounds::k_LayersAtTIBEnd && layer <= bounds::k_LayersAtTOBEnd) {
1150  //We are in the TOB
1151  float phi = ::calcPhi(tm.globalX(), tm.globalY());
1152  h_hotcold[layer - 1]->Fill(360. - phi, tm.globalZ(), 1.);
1153  } else if (layer > bounds::k_LayersAtTOBEnd && layer <= bounds::k_LayersAtTIDEnd) {
1154  //We are in the TID
1155  //There are 2 different maps here
1156  int side = tTopo->tidSide(iidd);
1157  if (side == 1)
1158  h_hotcold[(layer - 1) + (layer - 11)]->Fill(-tm.globalY(), tm.globalX(), 1.);
1159  else if (side == 2)
1160  h_hotcold[(layer - 1) + (layer - 10)]->Fill(-tm.globalY(), tm.globalX(), 1.);
1161  } else if (layer > bounds::k_LayersAtTIDEnd) {
1162  //We are in the TEC
1163  //There are 2 different maps here
1164  int side = tTopo->tecSide(iidd);
1165  if (side == 1)
1166  h_hotcold[(layer + 2) + (layer - 14)]->Fill(-tm.globalY(), tm.globalX(), 1.);
1167  else if (side == 2)
1168  h_hotcold[(layer + 2) + (layer - 13)]->Fill(-tm.globalY(), tm.globalX(), 1.);
1169  }
1170  }
1171 
1172  LogDebug("SiStripHitEfficiencyWorker")
1173  << "layer " << layer << " vector index " << layer - 1 << " before filling h_layer_vsSmthg" << std::endl;
1174  h_layer_vsBx[layer - 1].fill(bunchCrossing, !badflag);
1175  if (addLumi_) {
1176  h_layer_vsLumi[layer - 1].fill(instLumi, !badflag);
1177  h_layer_vsPU[layer - 1].fill(PU, !badflag);
1178  }
1179  if (addCommonMode_) {
1180  h_layer_vsCM[layer - 1].fill(commonMode, !badflag);
1181  }
1182  h_goodLayer.fill(layerWithSide, !badflag);
1183  }
1184  // efficiency without bad modules excluded
1185  h_allLayer.fill(layerWithSide, !badflag);
1186 
1187  // efficiency without bad modules excluded
1188  if (TKlayers) {
1189  h_module.fill(iidd, !badflag);
1190  assert(h_module.check(iidd));
1191  }
1192 
1193  /* Used in SiStripHitEffFromCalibTree:
1194  * run -> "run" -> run // e.id().run()
1195  * event -> "event" -> evt // e.id().event()
1196  * ModIsBad -> "ModIsBad" -> isBad
1197  * SiStripQualBad -> "SiStripQualBad"" -> quality
1198  * Id -> "Id" -> id // iidd
1199  * withinAcceptance -> "withinAcceptance" -> accept
1200  * whatlayer -> "layer" -> layer_wheel // Tklayers
1201  * highPurity -> "highPurity" -> highPurity
1202  * TrajGlbX -> "TrajGlbX" -> x // tm.globalX()
1203  * TrajGlbY -> "TrajGlbY" -> y // tm.globalY()
1204  * TrajGlbZ -> "TrajGlbZ" -> z // tm.globalZ()
1205  * ResXSig -> "ResXSig" -> resxsig // finalCluster.xResidualPull;
1206  * TrajLocX -> "TrajLocX" -> TrajLocX // xloc
1207  * TrajLocY -> "TrajLocY" -> TrajLocY // yloc
1208  * ClusterLocX -> "ClusterLocX" -> ClusterLocX // finalCluster.xLocal
1209  * bunchx -> "bunchx" -> bx // e.bunchCrossing()
1210  * instLumi -> "instLumi" -> instLumi ## if addLumi_
1211  * PU -> "PU" -> PU ## if addLumi_
1212  * commonMode -> "commonMode" -> CM ## if addCommonMode_ / _useCM
1213  */
1214  LogDebug("SiStripHitEfficiencyWorker") << "after good location check";
1215  }
1216  LogDebug("SiStripHitEfficiencyWorker") << "after list of clusters";
1217  }
1218  LogDebug("SiStripHitEfficiencyWorker") << "After layers=TKLayers if with TKlayers=" << TKlayers
1219  << ", layers=" << layers_;
1220 }
1221 
1224  desc.add<std::string>("dqmDir", "AlCaReco/SiStripHitEfficiency");
1225  desc.add<bool>("UseOnlyHighPurityTracks", true);
1226  desc.add<bool>("cutOnTracks", false);
1227  desc.add<bool>("doMissingHitsRecovery", false);
1228  desc.add<bool>("useAllHitsFromTracksWithMissingHits", false);
1229  desc.add<bool>("useFirstMeas", false);
1230  desc.add<bool>("useLastMeas", false);
1231  desc.add<double>("ClusterTrajDist", 64.0);
1232  desc.add<double>("ResXSig", -1);
1233  desc.add<double>("StripsApvEdge", 10.0);
1234  desc.add<edm::InputTag>("combinatorialTracks", edm::InputTag{"generalTracks"});
1235  desc.add<edm::InputTag>("commonMode", edm::InputTag{"siStripDigis", "CommonMode"});
1236  desc.add<edm::InputTag>("lumiScalers", edm::InputTag{"scalersRawToDigi"});
1237  desc.add<edm::InputTag>("metadata", edm::InputTag{"onlineMetaDataDigis"});
1238  desc.add<edm::InputTag>("siStripClusters", edm::InputTag{"siStripClusters"});
1239  desc.add<edm::InputTag>("siStripDigis", edm::InputTag{"siStripDigis"});
1240  desc.add<edm::InputTag>("trackerEvent", edm::InputTag{"MeasurementTrackerEvent"});
1241  desc.add<edm::InputTag>("trajectories", edm::InputTag{"generalTracks"});
1242  desc.add<int>("ClusterMatchingMethod", 0);
1243  desc.add<int>("Layer", 0);
1244  desc.add<unsigned int>("trackMultiplicity", 100);
1245  desc.addUntracked<bool>("Debug", false);
1246  desc.addUntracked<bool>("ShowRings", false);
1247  desc.addUntracked<bool>("ShowTOB6TEC9", false);
1248  desc.addUntracked<bool>("addCommonMode", false);
1249  desc.addUntracked<bool>("addLumi", true);
1250  desc.addUntracked<int>("BunchCrossing", 0);
1251  desc.addUntracked<std::string>("BadModulesFile", "");
1252  descriptions.addWithDefaultLabel(desc);
1253 }
1254 
std::pair< LocalPoint, LocalError > LocalValues
const edm::ESGetToken< MeasurementTracker, CkfComponentsRecord > measTrackerToken_
virtual int nstrips() const =0
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
void fill(double x, bool found, float weight=1.)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
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.
std::vector< MonitorElement * > h_resolution
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
EffME1(MonitorElement *total, MonitorElement *found)
const edm::EDGetTokenT< std::vector< Trajectory > > trajectories_token_
std::vector< MonitorElement * > h_hotcold
virtual void localParameters(AClusters const &clusters, ALocalValues &retValues, const GeomDetUnit &gd, const LocalTrajectoryParameters &ltp) const
void bookHistograms(DQMStore::IBooker &booker, const edm::Run &run, const edm::EventSetup &setup) override
unsigned int tidSide(const DetId &id) const
Class to contain the online luminosity from soft FED 1022.
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
unsigned int monodet_id() const
Definition: weight.py:1
const edm::EDGetTokenT< DetIdCollection > digis_token_
float instLumi() const
Return the luminosity for the current nibble.
std::unordered_map< uint32_t, int > fedErrorCounts
assert(be >=bs)
unsigned int tecRing(const DetId &id) const
ring id
Definition: Electron.h:6
missing
Definition: combine.py:5
std::unique_ptr< TkHistoMap > FEDErrorOccupancy
const edm::EDGetTokenT< MeasurementTrackerEvent > trackerEvent_token_
const_iterator end(bool update=false) const
~SiStripHitEfficiencyWorker() override=default
void Fill(long long x)
const edm::ESGetToken< TkDetMap, TrackerTopologyRcd > tkDetMapToken_
void fillForTraj(const TrajectoryAtInvalidHit &tm, const TrackerTopology *tTopo, const TrackerGeometry *tkgeom, const StripClusterParameterEstimator &stripCPE, const SiStripQuality &stripQuality, const DetIdCollection &fedErrorIds, const edm::Handle< edm::DetSetVector< SiStripRawDigi >> &commonModeDigis, const edmNew::DetSetVector< SiStripCluster > &theClusters, int bunchCrossing, float instLumi, float PU, bool highPurity)
const edm::ESGetToken< StripClusterParameterEstimator, TkStripCPERecord > stripCPEToken_
const edm::ESGetToken< Propagator, TrackingComponentsRecord > propagatorToken_
const edm::EDGetTokenT< OnlineLuminosityRecord > metaDataToken_
const edm::ESGetToken< Chi2MeasurementEstimatorBase, TrackingComponentsRecord > chi2EstimatorToken_
unsigned int tecSide(const DetId &id) const
EffTkMap(std::unique_ptr< TkHistoMap > &&total, std::unique_ptr< TkHistoMap > &&found)
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
T sqrt(T t)
Definition: SSEVec.h:19
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomToken_
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
dqm::reco::MonitorElement * EventStats
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
ii
Definition: cuy.py:589
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magFieldToken_
SiStripHitEfficiencyWorker(const edm::ParameterSet &conf)
void analyze(const edm::Event &e, const edm::EventSetup &c) override
std::vector< unsigned int > hitTotalCounters
Definition: DetId.h:17
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
size_type size() const
const edm::EDGetTokenT< TrajTrackAssociationCollection > trajTrackAsso_token_
Constants and enumerated types for FED/FEC systems.
part
Definition: HCALResponse.h:20
virtual const std::array< const float, 4 > parameters() const
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:212
const edm::EDGetTokenT< edmNew::DetSetVector< SiStripCluster > > clusters_token_
bool isValid() const
Definition: HandleBase.h:70
fixed size matrix
HLT enums.
const_iterator find(id_type i, bool update=false) const
size_type size() const
Definition: EDCollection.h:82
static const uint16_t STRIPS_PER_APV
const edm::EDGetTokenT< reco::TrackCollection > combinatorialTracks_token_
const edm::ESGetToken< SiStripQuality, SiStripQualityRcd > stripQualityToken_
const edm::EDGetTokenT< LumiScalersCollection > scalerToken_
std::vector< unsigned int > hitRecoveryCounters
unsigned int tidRing(const DetId &id) const
std::vector< LumiScalers > LumiScalersCollection
Definition: LumiScalers.h:144
void fill(uint32_t id, bool found, float weight=1.)
const edm::EDGetTokenT< edm::DetSetVector< SiStripRawDigi > > commonModeToken_
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
tmp
align.sh
Definition: createJobs.py:716
virtual float width() const =0
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
float avgPileUp() const
Return the average pileup for th current nibble.
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
ConstRecHitPointer const & recHit() const
#define LogDebug(id)
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)
short getBadApvs(uint32_t detid) const
const Bounds & bounds() const
Definition: Surface.h:87