CMS 3D CMS Logo

SplitVertexResolution.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Alignment/OfflineValidation
4 // Class: SplitVertexResolution
5 //
9 //
10 // Original Author: Marco Musich
11 // Created: Mon, 13 Jun 2016 15:07:11 GMT
12 //
13 //
14 
15 // system include files
16 #include <memory>
17 #include <algorithm> // std::sort
18 #include <vector> // std::vector
19 #include <chrono>
20 #include <iostream>
21 #include <random>
22 #include <fmt/printf.h>
23 #include <boost/range/adaptor/indexed.hpp>
24 
25 // ROOT include files
26 #include "TTree.h"
27 #include "TProfile.h"
28 #include "TF1.h"
29 #include "TMath.h"
30 
31 // user include files
35 
43 
45 
50 
54 
60 
63 
64 //
65 // useful code
66 //
67 
68 namespace statmode {
69  using fitParams = std::pair<Measurement1D, Measurement1D>;
70 }
71 
72 //
73 // class declaration
74 //
75 
76 class SplitVertexResolution : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::SharedResources> {
77 public:
79  ~SplitVertexResolution() override;
80 
81  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
82  static bool mysorter(reco::Track i, reco::Track j) { return (i.pt() > j.pt()); }
83 
84 private:
85  void beginJob() override;
86  void beginRun(edm::Run const& iEvent, edm::EventSetup const&) override;
87  virtual void beginEvent() final;
88  void analyze(const edm::Event&, const edm::EventSetup&) override;
89  void endJob() override;
90  void endRun(edm::Run const&, edm::EventSetup const&) override {}
91 
92  template <std::size_t SIZE>
93  bool checkBinOrdering(std::array<float, SIZE>& bins);
94  std::vector<TH1F*> bookResidualsHistogram(TFileDirectory dir,
95  unsigned int theNOfBins,
96  TString resType,
97  TString varType);
98 
99  void fillTrendPlotByIndex(TH1F* trendPlot, std::vector<TH1F*>& h, PVValHelper::estimator fitPar_);
100  statmode::fitParams fitResiduals(TH1* hist, bool singleTime = false);
102 
103  std::pair<long long, long long> getRunTime(const edm::EventSetup& iSetup) const;
104 
105  // counters
106  int ievt;
107  int itrks;
108 
109  // compression settings
111 
112  // switch to keep the ntuple
114 
115  // storing integrated luminosity
116  double intLumi_;
117  bool debug_;
118 
121 
124 
125  edm::InputTag triggerResultsTag_ = edm::InputTag("TriggerResults", "", "HLT"); //InputTag tag("TriggerResults");
127 
128  // ES Tokens
131 
132  double minVtxNdf_;
133  double minVtxWgt_;
134 
135  // checks on the run to be processed
136 
138  std::vector<unsigned int> runControlNumbers_;
139 
140  static constexpr double cmToUm = 10000.;
141 
143 
146 
147  std::map<unsigned int, std::pair<long long, long long>> runNumbersTimesLog_;
150 
151  TH1F* h_diffX;
152  TH1F* h_diffY;
153  TH1F* h_diffZ;
154 
158 
159  TH1F* h_errX;
160  TH1F* h_errY;
161  TH1F* h_errZ;
162 
163  TH1F* h_pullX;
164  TH1F* h_pullY;
165  TH1F* h_pullZ;
166 
167  TH1F* h_ntrks;
168  TH1F* h_sumPt;
169  TH1F* h_avgSumPt;
170 
171  TH1F* h_sumPt1;
172  TH1F* h_sumPt2;
173 
174  TH1F* h_wTrks1;
175  TH1F* h_wTrks2;
176 
177  TH1F* h_minWTrks1;
178  TH1F* h_minWTrks2;
179 
182 
183  TH1F* h_runNumber;
184 
186  TH1I* h_nVertices;
189 
190  // trigger results
191 
194 
195  // resolutions
196 
197  std::vector<TH1F*> h_resolX_sumPt_;
198  std::vector<TH1F*> h_resolY_sumPt_;
199  std::vector<TH1F*> h_resolZ_sumPt_;
200 
201  std::vector<TH1F*> h_resolX_Ntracks_;
202  std::vector<TH1F*> h_resolY_Ntracks_;
203  std::vector<TH1F*> h_resolZ_Ntracks_;
204 
205  std::vector<TH1F*> h_resolX_Nvtx_;
206  std::vector<TH1F*> h_resolY_Nvtx_;
207  std::vector<TH1F*> h_resolZ_Nvtx_;
208 
212 
216 
220 
221  // pulls
222  std::vector<TH1F*> h_pullX_sumPt_;
223  std::vector<TH1F*> h_pullY_sumPt_;
224  std::vector<TH1F*> h_pullZ_sumPt_;
225 
226  std::vector<TH1F*> h_pullX_Ntracks_;
227  std::vector<TH1F*> h_pullY_Ntracks_;
228  std::vector<TH1F*> h_pullZ_Ntracks_;
229 
230  std::vector<TH1F*> h_pullX_Nvtx_;
231  std::vector<TH1F*> h_pullY_Nvtx_;
232  std::vector<TH1F*> h_pullZ_Nvtx_;
233 
237 
241 
245 
247 
248  std::mt19937 engine_;
249 
251  TTree* tree_;
252 
253  // ----------member data ---------------------------
254  const float sumpTStartScale_;
255  const float sumpTEndScale_;
256  static const int nPtBins_ = 30;
257  std::array<float, nPtBins_ + 1> mypT_bins_;
258 
259  static const int nTrackBins_ = 120;
260  const double nVisTrackBins_; // will be configured
261  std::array<float, nTrackBins_ + 1> myNTrack_bins_;
262 
263  static const int nVtxBins_ = 60;
264  const double nVisVtxBins_; // will be configured
265  std::array<float, nVtxBins_ + 1> myNVtx_bins_;
266 
267  std::map<std::string, std::pair<int, int>> triggerMap_;
268 };
269 
271  : compressionSettings_(iConfig.getUntrackedParameter<int>("compressionSettings", -1)),
272  storeNtuple_(iConfig.getParameter<bool>("storeNtuple")),
273  intLumi_(iConfig.getUntrackedParameter<double>("intLumi", 0.)),
274  debug_(iConfig.getUntrackedParameter<bool>("Debug", false)),
275  pvsTag_(iConfig.getParameter<edm::InputTag>("vtxCollection")),
276  pvsToken_(consumes<reco::VertexCollection>(pvsTag_)),
277  tracksTag_(iConfig.getParameter<edm::InputTag>("trackCollection")),
278  tracksToken_(consumes<reco::TrackCollection>(tracksTag_)),
279  triggerResultsToken_(consumes<edm::TriggerResults>(triggerResultsTag_)),
280  transientTrackBuilderToken_(
281  esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))),
282  runInfoToken_(esConsumes<RunInfo, RunInfoRcd, edm::Transition::BeginRun>()),
283  minVtxNdf_(iConfig.getUntrackedParameter<double>("minVertexNdf")),
284  minVtxWgt_(iConfig.getUntrackedParameter<double>("minVertexMeanWeight")),
285  runControl_(iConfig.getUntrackedParameter<bool>("runControl", false)),
286  // binning
287  sumpTStartScale_(iConfig.getUntrackedParameter<double>("sumpTStartScale", 1.)),
288  sumpTEndScale_(iConfig.getUntrackedParameter<double>("sumpTEndScale", 1e3)),
289  nVisTrackBins_(iConfig.getUntrackedParameter<double>("nTrackBins", 120.)),
290  nVisVtxBins_(iConfig.getUntrackedParameter<double>("nVtxBins", 60.)) {
291  usesResource(TFileService::kSharedResource);
292 
293  std::vector<unsigned int> defaultRuns;
294  defaultRuns.push_back(0);
295  runControlNumbers_ = iConfig.getUntrackedParameter<std::vector<unsigned int>>("runControlNumber", defaultRuns);
296 
297  mypT_bins_ = PVValHelper::makeLogBins<float, nPtBins_>(sumpTStartScale_, sumpTEndScale_);
298 
299  // IMPORTANT
300  // first argument is start, second argument is the range so it's [-0.5;nTracksBins_-0.5]
301  std::vector<float> vect = PVValHelper::generateBins(nTrackBins_ + 1, -0.5, nTrackBins_);
302  std::copy(vect.begin(), vect.begin() + nTrackBins_ + 1, myNTrack_bins_.begin());
303 
304  vect.clear();
305 
306  // IMPORTANT
307  // first argument is start, second argument is the range so it's [-0.5;nVtxBins_-0.5]
308  vect = PVValHelper::generateBins(nVtxBins_ + 1, -0.5, nVtxBins_);
309  std::copy(vect.begin(), vect.begin() + nVtxBins_ + 1, myNVtx_bins_.begin());
310 
311  if (debug_) {
312  std::string toOutput = "";
313  for (const auto& pTbin : mypT_bins_ | boost::adaptors::indexed(1)) {
314  if (pTbin.index() != 1) {
315  toOutput += " ";
316  }
317  toOutput += fmt::sprintf("%.2f", pTbin.value());
318  if (pTbin.index() != nPtBins_ + 1) {
319  toOutput += ",";
320  }
321  }
322  edm::LogVerbatim("SplitVertexResolution") << "sum(pT) bins = [" << toOutput << "] \n";
323 
324  toOutput.clear();
325  for (const auto& tkbin : myNTrack_bins_ | boost::adaptors::indexed(1)) {
326  if (tkbin.index() != 1) {
327  toOutput += " ";
328  }
329  toOutput += fmt::sprintf("%.1f", tkbin.value());
330  if (tkbin.index() != nTrackBins_ + 1) {
331  toOutput += ",";
332  }
333  }
334  edm::LogVerbatim("SplitVertexResolution") << "n. track bins = [" << toOutput << "] \n";
335 
336  toOutput.clear();
337  for (const auto& vtxbin : myNVtx_bins_ | boost::adaptors::indexed(1)) {
338  if (vtxbin.index() != 1) {
339  toOutput += " ";
340  }
341  toOutput += fmt::sprintf("%.1f", vtxbin.value());
342  if (vtxbin.index() != nVtxBins_ + 1) {
343  toOutput += ",";
344  }
345  }
346  edm::LogVerbatim("SplitVertexResolution") << "n. vertices bins = [" << toOutput << "] \n";
347  }
348 }
349 
351 
352 // ------------ method called for each event ------------
354  using namespace edm;
355 
356  // deterministic seed from the event number
357  // should not bias the result as the event number is already
358  // assigned randomly-enough
359  engine_.seed(iEvent.id().event() + (iEvent.id().luminosityBlock() << 10) + (iEvent.id().run() << 20));
360 
361  // first check if the event passes the run control
362  bool passesRunControl = false;
363 
364  if (runControl_) {
365  for (const auto& runControlNumber : runControlNumbers_) {
366  if (iEvent.eventAuxiliary().run() == runControlNumber) {
367  if (debug_) {
368  edm::LogInfo("SplitVertexResolution")
369  << " run number: " << iEvent.eventAuxiliary().run() << " keeping run:" << runControlNumber;
370  }
371  passesRunControl = true;
372  break;
373  }
374  }
375  if (!passesRunControl)
376  return;
377  }
378 
379  // Fill general info
380  h_runNumber->Fill(iEvent.id().run());
381 
382  ievt++;
385 
386  const edm::TriggerNames& triggerNames_ = iEvent.triggerNames(*hltresults);
387  int ntrigs = hltresults->size();
388  //const std::vector<std::string>& triggernames = triggerNames_.triggerNames();
389 
390  beginEvent();
391 
392  // Fill general info
393  event_.runNumber = iEvent.id().run();
394  event_.luminosityBlockNumber = iEvent.id().luminosityBlock();
395  event_.eventNumber = iEvent.id().event();
396 
398 
400  iEvent.getByToken(pvsToken_, vertices);
401  const reco::VertexCollection pvtx = *(vertices.product());
402 
403  event_.nVtx = pvtx.size();
404  int nOfflineVtx = pvtx.size();
405  h_nOfflineVertices->Fill(nOfflineVtx);
406 
408  iEvent.getByToken(tracksToken_, tracks);
409  itrks += tracks.product()->size();
410 
411  for (int itrig = 0; itrig != ntrigs; ++itrig) {
412  const std::string& trigName = triggerNames_.triggerName(itrig);
413  bool accept = hltresults->accept(itrig);
414  if (accept == 1) {
415  triggerMap_[trigName].first += 1;
416  triggerMap_[trigName].second += tracks.product()->size();
417  // triggerInfo.push_back(pair <string, int> (trigName, accept));
418  }
419  }
420 
421  int counter = 0;
422  int noFakecounter = 0;
423  int goodcounter = 0;
424 
425  for (auto pvIt = pvtx.cbegin(); pvIt != pvtx.cend(); ++pvIt) {
426  const reco::Vertex& iPV = *pvIt;
427  counter++;
428  if (iPV.isFake())
429  continue;
430  noFakecounter++;
431 
432  // vertex selection as in bs code
433  if (iPV.ndof() < minVtxNdf_ || (iPV.ndof() + 3.) / iPV.tracksSize() < 2 * minVtxWgt_)
434  continue;
435 
436  goodcounter++;
438  reco::TrackCollection groupOne, groupTwo;
439  for (auto trki = iPV.tracks_begin(); trki != iPV.tracks_end(); ++trki) {
440  if (trki->isNonnull()) {
441  reco::TrackRef trk_now(tracks, (*trki).key());
442  allTracks.push_back(*trk_now);
443  }
444  }
445 
446  if (goodcounter > 1)
447  continue;
448 
449  // order with decreasing pt
450  std::sort(allTracks.begin(), allTracks.end(), mysorter);
451 
452  int ntrks = allTracks.size();
453  h_ntrks->Fill(ntrks);
454 
455  // discard lowest pt track
456  uint even_ntrks;
457  ntrks % 2 == 0 ? even_ntrks = ntrks : even_ntrks = ntrks - 1;
458 
459  // split into two sets equally populated
460  for (uint tracksIt = 0; tracksIt < even_ntrks; tracksIt = tracksIt + 2) {
461  reco::Track firstTrk = allTracks.at(tracksIt);
462  reco::Track secondTrk = allTracks.at(tracksIt + 1);
463  auto dis = std::uniform_int_distribution<>(0, 1); // [0, 1]
464 
465  if (dis(engine_) > 0.5) {
466  groupOne.push_back(firstTrk);
467  groupTwo.push_back(secondTrk);
468  } else {
469  groupOne.push_back(secondTrk);
470  groupTwo.push_back(firstTrk);
471  }
472  }
473 
474  if (!(groupOne.size() >= 2 && groupTwo.size() >= 2))
475  continue;
476 
477  h_OrigVertexErrX->Fill(iPV.xError() * cmToUm);
478  h_OrigVertexErrY->Fill(iPV.yError() * cmToUm);
479  h_OrigVertexErrZ->Fill(iPV.zError() * cmToUm);
480 
481  float sumPt = 0, sumPt1 = 0, sumPt2 = 0, avgSumPt = 0;
482 
483  // refit the two sets of tracks
484  std::vector<reco::TransientTrack> groupOne_ttks;
485  groupOne_ttks.clear();
486  for (auto itrk = groupOne.cbegin(); itrk != groupOne.cend(); itrk++) {
487  reco::TransientTrack tmpTransientTrack = theB.build(*itrk);
488  groupOne_ttks.push_back(tmpTransientTrack);
489  sumPt1 += itrk->pt();
490  sumPt += itrk->pt();
491  }
492 
493  AdaptiveVertexFitter pvFitter;
494  TransientVertex pvOne = pvFitter.vertex(groupOne_ttks);
495  if (!pvOne.isValid())
496  continue;
497 
498  reco::Vertex onePV = pvOne;
499 
500  std::vector<reco::TransientTrack> groupTwo_ttks;
501  groupTwo_ttks.clear();
502  for (auto itrk = groupTwo.cbegin(); itrk != groupTwo.cend(); itrk++) {
503  reco::TransientTrack tmpTransientTrack = theB.build(*itrk);
504  groupTwo_ttks.push_back(tmpTransientTrack);
505  sumPt2 += itrk->pt();
506  sumPt += itrk->pt();
507  }
508 
509  // average sumPt
510  avgSumPt = (sumPt1 + sumPt2) / 2.;
511  h_avgSumPt->Fill(avgSumPt);
512 
513  TransientVertex pvTwo = pvFitter.vertex(groupTwo_ttks);
514  if (!pvTwo.isValid())
515  continue;
516 
517  reco::Vertex twoPV = pvTwo;
518 
519  float theminW1 = 1.;
520  float theminW2 = 1.;
521  for (auto otrk = pvOne.originalTracks().cbegin(); otrk != pvOne.originalTracks().cend(); ++otrk) {
522  h_wTrks1->Fill(pvOne.trackWeight(*otrk));
523  if (pvOne.trackWeight(*otrk) < theminW1) {
524  theminW1 = pvOne.trackWeight(*otrk);
525  }
526  }
527  for (auto otrk = pvTwo.originalTracks().cbegin(); otrk != pvTwo.originalTracks().end(); ++otrk) {
528  h_wTrks2->Fill(pvTwo.trackWeight(*otrk));
529  if (pvTwo.trackWeight(*otrk) < theminW2) {
530  theminW2 = pvTwo.trackWeight(*otrk);
531  }
532  }
533 
534  h_sumPt->Fill(sumPt);
535 
536  int half_trks = twoPV.nTracks();
537 
538  const double invSqrt2 = 1. / std::sqrt(2.);
539 
540  double deltaX = (twoPV.x() - onePV.x());
541  double deltaY = (twoPV.y() - onePV.y());
542  double deltaZ = (twoPV.z() - onePV.z());
543 
544  double resX = deltaX * invSqrt2;
545  double resY = deltaY * invSqrt2;
546  double resZ = deltaZ * invSqrt2;
547 
548  h_diffX->Fill(resX * cmToUm);
549  h_diffY->Fill(resY * cmToUm);
550  h_diffZ->Fill(resZ * cmToUm);
551 
552  double errX = sqrt(pow(twoPV.xError(), 2) + pow(onePV.xError(), 2));
553  double errY = sqrt(pow(twoPV.yError(), 2) + pow(onePV.yError(), 2));
554  double errZ = sqrt(pow(twoPV.zError(), 2) + pow(onePV.zError(), 2));
555 
556  h_errX->Fill(errX * cmToUm);
557  h_errY->Fill(errY * cmToUm);
558  h_errZ->Fill(errZ * cmToUm);
559 
560  h_pullX->Fill(deltaX / errX);
561  h_pullY->Fill(deltaY / errY);
562  h_pullZ->Fill(deltaZ / errZ);
563 
564  // filling the pT-binned distributions
565 
566  for (int ipTBin = 0; ipTBin < nPtBins_; ipTBin++) {
567  float pTF = mypT_bins_[ipTBin];
568  float pTL = mypT_bins_[ipTBin + 1];
569 
570  if (avgSumPt >= pTF && avgSumPt < pTL) {
571  PVValHelper::fillByIndex(h_resolX_sumPt_, ipTBin, resX * cmToUm, "1");
572  PVValHelper::fillByIndex(h_resolY_sumPt_, ipTBin, resY * cmToUm, "2");
573  PVValHelper::fillByIndex(h_resolZ_sumPt_, ipTBin, resZ * cmToUm, "3");
574 
575  PVValHelper::fillByIndex(h_pullX_sumPt_, ipTBin, deltaX / errX, "4");
576  PVValHelper::fillByIndex(h_pullY_sumPt_, ipTBin, deltaY / errY, "5");
578  }
579  }
580 
581  // filling the track multeplicity binned distributions
582 
583  for (int inTrackBin = 0; inTrackBin < nTrackBins_; inTrackBin++) {
584  float nTrackF = myNTrack_bins_[inTrackBin];
585  float nTrackL = myNTrack_bins_[inTrackBin + 1];
586  if (ntrks >= nTrackF && ntrks < nTrackL) {
587  //if (ntrks == inTrackBin) {
588  PVValHelper::fillByIndex(h_resolX_Ntracks_, inTrackBin, resX * cmToUm, "7");
589  PVValHelper::fillByIndex(h_resolY_Ntracks_, inTrackBin, resY * cmToUm, "8");
590  PVValHelper::fillByIndex(h_resolZ_Ntracks_, inTrackBin, resZ * cmToUm, "9");
591 
592  PVValHelper::fillByIndex(h_pullX_Ntracks_, inTrackBin, deltaX / errX, "10");
593  PVValHelper::fillByIndex(h_pullY_Ntracks_, inTrackBin, deltaY / errY, "11");
595  }
596  }
597 
598  // filling the vertex multeplicity binned distributions
599 
600  for (int inVtxBin = 0; inVtxBin < nVtxBins_; inVtxBin++) {
601  float nVtxF = myNVtx_bins_[inVtxBin];
602  float nVtxL = myNVtx_bins_[inVtxBin + 1];
603  if (nOfflineVtx >= nVtxF && nOfflineVtx < nVtxL) {
604  //if (nOfflineVtx == inVtxBin) {
605  PVValHelper::fillByIndex(h_resolX_Nvtx_, inVtxBin, deltaX * cmToUm, "7");
606  PVValHelper::fillByIndex(h_resolY_Nvtx_, inVtxBin, deltaY * cmToUm, "8");
608 
609  PVValHelper::fillByIndex(h_pullX_Nvtx_, inVtxBin, deltaX / errX, "10");
610  PVValHelper::fillByIndex(h_pullY_Nvtx_, inVtxBin, deltaY / errY, "11");
612  }
613  }
614 
615  h_sumPt1->Fill(sumPt1);
616  h_sumPt2->Fill(sumPt2);
617 
618  h_minWTrks1->Fill(theminW1);
619  h_minWTrks2->Fill(theminW2);
620 
621  h_PVCL_subVtx1->Fill(TMath::Prob(pvOne.totalChiSquared(), (int)(pvOne.degreesOfFreedom())));
622  h_PVCL_subVtx2->Fill(TMath::Prob(pvTwo.totalChiSquared(), (int)(pvTwo.degreesOfFreedom())));
623 
624  // fill ntuples
625  pvCand thePV;
626  thePV.ipos = counter;
627  thePV.nTrks = ntrks;
628 
629  thePV.x_origVtx = iPV.x();
630  thePV.y_origVtx = iPV.y();
631  thePV.z_origVtx = iPV.z();
632 
633  thePV.xErr_origVtx = iPV.xError();
634  thePV.yErr_origVtx = iPV.yError();
635  thePV.zErr_origVtx = iPV.zError();
636 
637  thePV.n_subVtx1 = half_trks;
638  thePV.x_subVtx1 = onePV.x();
639  thePV.y_subVtx1 = onePV.y();
640  thePV.z_subVtx1 = onePV.z();
641 
642  thePV.xErr_subVtx1 = onePV.xError();
643  thePV.yErr_subVtx1 = onePV.yError();
644  thePV.zErr_subVtx1 = onePV.zError();
645  thePV.sumPt_subVtx1 = sumPt1;
646 
647  thePV.n_subVtx2 = half_trks;
648  thePV.x_subVtx2 = twoPV.x();
649  thePV.y_subVtx2 = twoPV.y();
650  thePV.z_subVtx2 = twoPV.z();
651 
652  thePV.xErr_subVtx2 = twoPV.xError();
653  thePV.yErr_subVtx2 = twoPV.yError();
654  thePV.zErr_subVtx2 = twoPV.zError();
655  thePV.sumPt_subVtx2 = sumPt2;
656 
657  thePV.CL_subVtx1 = TMath::Prob(pvOne.totalChiSquared(), (int)(pvOne.degreesOfFreedom()));
658  thePV.CL_subVtx2 = TMath::Prob(pvTwo.totalChiSquared(), (int)(pvTwo.degreesOfFreedom()));
659 
660  thePV.minW_subVtx1 = theminW1;
661  thePV.minW_subVtx2 = theminW2;
662 
663  event_.pvs.push_back(thePV);
664 
665  } // loop on the vertices
666 
667  // fill the histogram of vertices per event
668  h_nVertices->Fill(counter);
669  h_nNonFakeVertices->Fill(noFakecounter);
670  h_nFinalVertices->Fill(goodcounter);
671 
672  if (storeNtuple_) {
673  tree_->Fill();
674  }
675 }
676 
678  event_.pvs.clear();
679  event_.nVtx = -1;
680 }
681 
683  unsigned int RunNumber_ = run.run();
684 
685  if (!runNumbersTimesLog_.count(RunNumber_)) {
686  auto times = getRunTime(iSetup);
687 
688  if (debug_) {
689  const time_t start_time = times.first / 1.0e+6;
690  edm::LogInfo("SplitVertexResolution")
691  << RunNumber_ << " has start time: " << times.first << " - " << times.second << std::endl;
692  edm::LogInfo("SplitVertexResolution")
693  << "human readable time: " << std::asctime(std::gmtime(&start_time)) << std::endl;
694  }
695  runNumbersTimesLog_[RunNumber_] = times;
696  }
697 }
698 
699 // ------------ method called once each job just before starting event loop ------------
701  ievt = 0;
702  itrks = 0;
703 
704  if (compressionSettings_ > 0) {
705  outfile_->file().SetCompressionSettings(compressionSettings_);
706  }
707 
708  // binning histogram
709  TFileDirectory BinningFeatures = outfile_->mkdir("BinningFeatures");
710  // sumpT
711  h_profileBinnings = BinningFeatures.make<TH1F>("h_profileBinnings", "profile binnings", 4, -0.5, 3.5);
712  h_profileBinnings->GetXaxis()->SetBinLabel(1, "#sum p_{T} min");
713  h_profileBinnings->GetXaxis()->SetBinLabel(2, "#sum p_{T} max");
714  // n. tracks
715  h_profileBinnings->GetXaxis()->SetBinLabel(3, "n. track bins");
716  // n. vertices
717  h_profileBinnings->GetXaxis()->SetBinLabel(4, "n. vertices bins");
718 
719  // fill the binning book-keeping
720  h_profileBinnings->SetBinContent(1, sumpTStartScale_);
721  h_profileBinnings->SetBinContent(2, sumpTEndScale_);
722  h_profileBinnings->SetBinContent(3, nVisTrackBins_);
723  h_profileBinnings->SetBinContent(4, nVisVtxBins_);
724 
725  // luminosity histo
726  TFileDirectory EventFeatures = outfile_->mkdir("EventFeatures");
728  EventFeatures.make<TH1F>("h_lumiFromConfig", "luminosity from config;;luminosity of present run", 1, -0.5, 0.5);
729  h_lumiFromConfig->SetBinContent(1, intLumi_);
730 
731  h_runFromConfig = EventFeatures.make<TH1I>("h_runFromConfig",
732  "run number from config;;run number (from configuration)",
733  runControlNumbers_.size(),
734  0.,
735  runControlNumbers_.size());
736 
737  for (const auto& run : runControlNumbers_ | boost::adaptors::indexed(1)) {
738  h_runFromConfig->SetBinContent(run.index(), run.value());
739  }
740 
741  // resolutions
742 
744  edm::LogError("SplitVertexResolution") << " Warning - the vector of pT bins is not ordered " << std::endl;
745  }
746 
748  edm::LogError("SplitVertexResolution") << " Warning -the vector of n. tracks bins is not ordered " << std::endl;
749  }
750 
752  edm::LogError("SplitVertexResolution") << " Warning -the vector of n. vertices bins is not ordered " << std::endl;
753  }
754 
755  TFileDirectory xResolSumPt = outfile_->mkdir("xResolSumPt");
756  h_resolX_sumPt_ = bookResidualsHistogram(xResolSumPt, nPtBins_, "resolX", "sumPt");
757 
758  TFileDirectory yResolSumPt = outfile_->mkdir("yResolSumPt");
759  h_resolY_sumPt_ = bookResidualsHistogram(yResolSumPt, nPtBins_, "resolY", "sumPt");
760 
761  TFileDirectory zResolSumPt = outfile_->mkdir("zResolSumPt");
762  h_resolZ_sumPt_ = bookResidualsHistogram(zResolSumPt, nPtBins_, "resolZ", "sumPt");
763 
764  TFileDirectory xResolNtracks_ = outfile_->mkdir("xResolNtracks");
765  h_resolX_Ntracks_ = bookResidualsHistogram(xResolNtracks_, nTrackBins_, "resolX", "Ntracks");
766 
767  TFileDirectory yResolNtracks_ = outfile_->mkdir("yResolNtracks");
768  h_resolY_Ntracks_ = bookResidualsHistogram(yResolNtracks_, nTrackBins_, "resolY", "Ntracks");
769 
770  TFileDirectory zResolNtracks_ = outfile_->mkdir("zResolNtracks");
771  h_resolZ_Ntracks_ = bookResidualsHistogram(zResolNtracks_, nTrackBins_, "resolZ", "Ntracks");
772 
773  TFileDirectory xResolNvtx_ = outfile_->mkdir("xResolNvtx");
774  h_resolX_Nvtx_ = bookResidualsHistogram(xResolNvtx_, nVtxBins_, "resolX", "Nvtx");
775 
776  TFileDirectory yResolNvtx_ = outfile_->mkdir("yResolNvtx");
777  h_resolY_Nvtx_ = bookResidualsHistogram(yResolNvtx_, nVtxBins_, "resolY", "Nvtx");
778 
779  TFileDirectory zResolNvtx_ = outfile_->mkdir("zResolNvtx");
780  h_resolZ_Nvtx_ = bookResidualsHistogram(zResolNvtx_, nVtxBins_, "resolZ", "Nvtx");
781 
782  // pulls
783 
784  TFileDirectory xPullSumPt = outfile_->mkdir("xPullSumPt");
785  h_pullX_sumPt_ = bookResidualsHistogram(xPullSumPt, nPtBins_, "pullX", "sumPt");
786 
787  TFileDirectory yPullSumPt = outfile_->mkdir("yPullSumPt");
788  h_pullY_sumPt_ = bookResidualsHistogram(yPullSumPt, nPtBins_, "pullY", "sumPt");
789 
790  TFileDirectory zPullSumPt = outfile_->mkdir("zPullSumPt");
791  h_pullZ_sumPt_ = bookResidualsHistogram(zPullSumPt, nPtBins_, "pullZ", "sumPt");
792 
793  TFileDirectory xPullNtracks_ = outfile_->mkdir("xPullNtracks");
794  h_pullX_Ntracks_ = bookResidualsHistogram(xPullNtracks_, nTrackBins_, "pullX", "Ntracks");
795 
796  TFileDirectory yPullNtracks_ = outfile_->mkdir("yPullNtracks");
797  h_pullY_Ntracks_ = bookResidualsHistogram(yPullNtracks_, nTrackBins_, "pullY", "Ntracks");
798 
799  TFileDirectory zPullNtracks_ = outfile_->mkdir("zPullNtracks");
800  h_pullZ_Ntracks_ = bookResidualsHistogram(zPullNtracks_, nTrackBins_, "pullZ", "Ntracks");
801 
802  TFileDirectory xPullNvtx_ = outfile_->mkdir("xPullNvtx");
803  h_pullX_Nvtx_ = bookResidualsHistogram(xPullNvtx_, nVtxBins_, "pullX", "Nvtx");
804 
805  TFileDirectory yPullNvtx_ = outfile_->mkdir("yPullNvtx");
806  h_pullY_Nvtx_ = bookResidualsHistogram(yPullNvtx_, nVtxBins_, "pullY", "Nvtx");
807 
808  TFileDirectory zPullNvtx_ = outfile_->mkdir("zPullNvtx");
809  h_pullZ_Nvtx_ = bookResidualsHistogram(zPullNvtx_, nVtxBins_, "pullZ", "Nvtx");
810 
811  // control plots
812  h_runNumber = outfile_->make<TH1F>("h_runNumber", "run number;run number;n_{events}", 100000, 250000., 350000.);
813 
814  h_nOfflineVertices = outfile_->make<TH1I>("h_nOfflineVertices", "n. of vertices;n. vertices; events", 100, 0, 100);
815  h_nVertices = outfile_->make<TH1I>("h_nVertices", "n. of vertices;n. vertices; events", 100, 0, 100);
817  outfile_->make<TH1I>("h_nRealVertices", "n. of non-fake vertices;n. vertices; events", 100, 0, 100);
819  outfile_->make<TH1I>("h_nSelectedVertices", "n. of selected vertices vertices;n. vertices; events", 100, 0, 100);
820 
821  h_diffX = outfile_->make<TH1F>(
822  "h_diffX", "x-coordinate vertex resolution;vertex resolution (x) [#mum];vertices", 100, -300, 300.);
823  h_diffY = outfile_->make<TH1F>(
824  "h_diffY", "y-coordinate vertex resolution;vertex resolution (y) [#mum];vertices", 100, -300, 300.);
825  h_diffZ = outfile_->make<TH1F>(
826  "h_diffZ", "z-coordinate vertex resolution;vertex resolution (z) [#mum];vertices", 100, -500, 500.);
827 
828  h_OrigVertexErrX = outfile_->make<TH1F>(
829  "h_OrigVertexErrX", "x-coordinate vertex error;vertex error (x) [#mum];vertices", 300, 0., 300.);
830  h_OrigVertexErrY = outfile_->make<TH1F>(
831  "h_OrigVertexErrY", "y-coordinate vertex error;vertex error (y) [#mum];vertices", 300, 0., 300.);
832  h_OrigVertexErrZ = outfile_->make<TH1F>(
833  "h_OrigVertexErrZ", "z-coordinate vertex error;vertex error (z) [#mum];vertices", 500, 0., 500.);
834 
835  h_errX = outfile_->make<TH1F>(
836  "h_errX", "x-coordinate vertex resolution error;vertex resoltuion error (x) [#mum];vertices", 300, 0., 300.);
837  h_errY = outfile_->make<TH1F>(
838  "h_errY", "y-coordinate vertex resolution error;vertex resolution error (y) [#mum];vertices", 300, 0., 300.);
839  h_errZ = outfile_->make<TH1F>(
840  "h_errZ", "z-coordinate vertex resolution error;vertex resolution error (z) [#mum];vertices", 500, 0., 500.);
841 
842  h_pullX = outfile_->make<TH1F>("h_pullX", "x-coordinate vertex pull;vertex pull (x);vertices", 500, -10, 10.);
843  h_pullY = outfile_->make<TH1F>("h_pullY", "y-coordinate vertex pull;vertex pull (y);vertices", 500, -10, 10.);
844  h_pullZ = outfile_->make<TH1F>("h_pullZ", "z-coordinate vertex pull;vertex pull (z);vertices", 500, -10, 10.);
845 
846  h_ntrks = outfile_->make<TH1F>("h_ntrks",
847  "number of tracks in vertex;vertex multeplicity;vertices",
848  myNTrack_bins_.size() - 1,
849  myNTrack_bins_.data());
850 
851  h_sumPt = outfile_->make<TH1F>(
852  "h_sumPt", "#Sigma p_{T};#sum p_{T} [GeV];vertices", mypT_bins_.size() - 1, mypT_bins_.data());
853 
854  h_avgSumPt = outfile_->make<TH1F>(
855  "h_avgSumPt", "#LT #Sigma p_{T} #GT;#LT #sum p_{T} #GT [GeV];vertices", mypT_bins_.size() - 1, mypT_bins_.data());
856 
857  h_sumPt1 = outfile_->make<TH1F>("h_sumPt1",
858  "#Sigma p_{T} sub-vertex 1;#sum p_{T} sub-vertex 1 [GeV];subvertices",
859  mypT_bins_.size() - 1,
860  mypT_bins_.data());
861  h_sumPt2 = outfile_->make<TH1F>("h_sumPt2",
862  "#Sigma p_{T} sub-vertex 2;#sum p_{T} sub-vertex 2 [GeV];subvertices",
863  mypT_bins_.size() - 1,
864  mypT_bins_.data());
865 
866  h_wTrks1 = outfile_->make<TH1F>("h_wTrks1", "weight of track for sub-vertex 1;track weight;subvertices", 500, 0., 1.);
867  h_wTrks2 = outfile_->make<TH1F>("h_wTrks2", "weithg of track for sub-vertex 2;track weight;subvertices", 500, 0., 1.);
868 
869  h_minWTrks1 = outfile_->make<TH1F>(
870  "h_minWTrks1", "minimum weight of track for sub-vertex 1;minimum track weight;subvertices", 500, 0., 1.);
871  h_minWTrks2 = outfile_->make<TH1F>(
872  "h_minWTrks2", "minimum weithg of track for sub-vertex 2;minimum track weight;subvertices", 500, 0., 1.);
873 
875  outfile_->make<TH1F>("h_PVCL_subVtx1",
876  "#chi^{2} probability for sub-vertex 1;Prob(#chi^{2},ndof) for sub-vertex 1;subvertices",
877  100,
878  0.,
879  1);
881  outfile_->make<TH1F>("h_PVCL_subVtx2",
882  "#chi^{2} probability for sub-vertex 2;Prob(#chi^{2},ndof) for sub-vertex 2;subvertices",
883  100,
884  0.,
885  1);
886 
887  // resolutions
888 
889  p_resolX_vsSumPt = outfile_->make<TH1F>("p_resolX_vsSumPt",
890  "x-resolution vs #Sigma p_{T};#sum p_{T} [GeV]; x vertex resolution [#mum]",
891  mypT_bins_.size() - 1,
892  mypT_bins_.data());
893  p_resolY_vsSumPt = outfile_->make<TH1F>("p_resolY_vsSumPt",
894  "y-resolution vs #Sigma p_{T};#sum p_{T} [GeV]; y vertex resolution [#mum]",
895  mypT_bins_.size() - 1,
896  mypT_bins_.data());
897  p_resolZ_vsSumPt = outfile_->make<TH1F>("p_resolZ_vsSumPt",
898  "z-resolution vs #Sigma p_{T};#sum p_{T} [GeV]; z vertex resolution [#mum]",
899  mypT_bins_.size() - 1,
900  mypT_bins_.data());
901 
902  p_resolX_vsNtracks = outfile_->make<TH1F>("p_resolX_vsNtracks",
903  "x-resolution vs n_{tracks};n_{tracks}; x vertex resolution [#mum]",
904  myNTrack_bins_.size() - 1,
905  myNTrack_bins_.data());
906  p_resolY_vsNtracks = outfile_->make<TH1F>("p_resolY_vsNtracks",
907  "y-resolution vs n_{tracks};n_{tracks}; y vertex resolution [#mum]",
908  myNTrack_bins_.size() - 1,
909  myNTrack_bins_.data());
910  p_resolZ_vsNtracks = outfile_->make<TH1F>("p_resolZ_vsNtracks",
911  "z-resolution vs n_{tracks};n_{tracks}; z vertex resolution [#mum]",
912  myNTrack_bins_.size() - 1,
913  myNTrack_bins_.data());
914 
915  p_resolX_vsNvtx = outfile_->make<TH1F>("p_resolX_vsNvtx",
916  "x-resolution vs n_{vertices};n_{vertices}; x vertex resolution [#mum]",
917  myNVtx_bins_.size() - 1,
918  myNVtx_bins_.data());
919  p_resolY_vsNvtx = outfile_->make<TH1F>("p_resolY_vsNvtx",
920  "y-resolution vs n_{vertices};n_{vertices}; y vertex resolution [#mum]",
921  myNVtx_bins_.size() - 1,
922  myNVtx_bins_.data());
923  p_resolZ_vsNvtx = outfile_->make<TH1F>("p_resolZ_vsNvtx",
924  "z-resolution vs n_{vertices};n_{vertices}; z vertex resolution [#mum]",
925  myNVtx_bins_.size() - 1,
926  myNVtx_bins_.data());
927 
928  // pulls
929 
930  p_pullX_vsSumPt = outfile_->make<TH1F>("p_pullX_vsSumPt",
931  "x-pull vs #Sigma p_{T};#sum p_{T} [GeV]; x vertex pull",
932  mypT_bins_.size() - 1,
933  mypT_bins_.data());
934  p_pullY_vsSumPt = outfile_->make<TH1F>("p_pullY_vsSumPt",
935  "y-pull vs #Sigma p_{T};#sum p_{T} [GeV]; y vertex pull",
936  mypT_bins_.size() - 1,
937  mypT_bins_.data());
938  p_pullZ_vsSumPt = outfile_->make<TH1F>("p_pullZ_vsSumPt",
939  "z-pull vs #Sigma p_{T};#sum p_{T} [GeV]; z vertex pull",
940  mypT_bins_.size() - 1,
941  mypT_bins_.data());
942 
943  p_pullX_vsNtracks = outfile_->make<TH1F>("p_pullX_vsNtracks",
944  "x-pull vs n_{tracks};n_{tracks}; x vertex pull",
945  myNTrack_bins_.size() - 1,
946  myNTrack_bins_.data());
947  p_pullY_vsNtracks = outfile_->make<TH1F>("p_pullY_vsNtracks",
948  "y-pull vs n_{tracks};n_{tracks}; y vertex pull",
949  myNTrack_bins_.size() - 1,
950  myNTrack_bins_.data());
951  p_pullZ_vsNtracks = outfile_->make<TH1F>("p_pullZ_vsNtracks",
952  "z-pull vs n_{tracks};n_{tracks}; z vertex pull",
953  myNTrack_bins_.size() - 1,
954  myNTrack_bins_.data());
955 
956  p_pullX_vsNvtx = outfile_->make<TH1F>("p_pullX_vsNvtx",
957  "x-pull vs n_{vertices};n_{vertices}; x vertex pull",
958  myNVtx_bins_.size() - 1,
959  myNVtx_bins_.data());
960  p_pullY_vsNvtx = outfile_->make<TH1F>("p_pullY_vsNvtx",
961  "y-pull vs n_{vertices};n_{vertices}; y vertex pull",
962  myNVtx_bins_.size() - 1,
963  myNVtx_bins_.data());
964  p_pullZ_vsNvtx = outfile_->make<TH1F>("p_pullZ_vsNvtx",
965  "z-pull vs n_{vertices};n_{vertices}; z vertex pull",
966  myNVtx_bins_.size() - 1,
967  myNVtx_bins_.data());
968 
969  tree_ = outfile_->make<TTree>("pvTree", "pvTree");
970  tree_->Branch("event", &event_, 64000, 2);
971 }
972 
973 //*************************************************************
974 // Generic booker function
975 //*************************************************************
977  unsigned int theNOfBins,
978  TString resType,
979  TString varType) {
980  TH1F::SetDefaultSumw2(kTRUE);
981 
982  double up = 500.;
983  double down = -500.;
984 
985  if (resType.Contains("pull")) {
986  up *= 0.01;
987  down *= 0.01;
988  }
989 
990  std::vector<TH1F*> h;
991  h.reserve(theNOfBins);
992 
993  const char* auxResType = (resType.ReplaceAll("_", "")).Data();
994 
995  for (unsigned int i = 0; i < theNOfBins; i++) {
996  TH1F* htemp = dir.make<TH1F>(Form("histo_%s_%s_plot%i", resType.Data(), varType.Data(), i),
997  Form("%s vs %s - bin %i;%s;vertices", auxResType, varType.Data(), i, auxResType),
998  250,
999  down,
1000  up);
1001  h.push_back(htemp);
1002  }
1003 
1004  return h;
1005 }
1006 
1007 // ------------ method called once each job just after ending the event loop ------------
1009  edm::LogVerbatim("SplitVertexResolution") << "*******************************" << std::endl;
1010  edm::LogVerbatim("SplitVertexResolution") << "Events run in total: " << ievt << std::endl;
1011  edm::LogVerbatim("SplitVertexResolution") << "n. tracks: " << itrks << std::endl;
1012  edm::LogVerbatim("SplitVertexResolution") << "*******************************" << std::endl;
1013 
1014  int nFiringTriggers = triggerMap_.size();
1015  edm::LogVerbatim("SplitVertexResolution") << "firing triggers: " << nFiringTriggers << std::endl;
1016  edm::LogVerbatim("SplitVertexResolution") << "*******************************" << std::endl;
1017 
1018  tksByTrigger_ = outfile_->make<TH1D>(
1019  "tksByTrigger", "tracks by HLT path;;% of # traks", nFiringTriggers, -0.5, nFiringTriggers - 0.5);
1020  evtsByTrigger_ = outfile_->make<TH1D>(
1021  "evtsByTrigger", "events by HLT path;;% of # events", nFiringTriggers, -0.5, nFiringTriggers - 0.5);
1022 
1023  int i = 0;
1024  for (std::map<std::string, std::pair<int, int>>::iterator it = triggerMap_.begin(); it != triggerMap_.end(); ++it) {
1025  i++;
1026 
1027  double trkpercent = ((it->second).second) * 100. / double(itrks);
1028  double evtpercent = ((it->second).first) * 100. / double(ievt);
1029 
1030  edm::LogVerbatim("SplitVertexResolution")
1031  << "HLT path: " << std::setw(60) << std::left << it->first << " | events firing: " << std::right << std::setw(8)
1032  << (it->second).first << " (" << std::setw(8) << std::fixed << std::setprecision(4) << evtpercent << "%)"
1033  << " | tracks collected: " << std::setw(8) << (it->second).second << " (" << std::setw(8) << std::fixed
1034  << std::setprecision(4) << trkpercent << "%)";
1035 
1036  tksByTrigger_->SetBinContent(i, trkpercent);
1037  tksByTrigger_->GetXaxis()->SetBinLabel(i, (it->first).c_str());
1038 
1039  evtsByTrigger_->SetBinContent(i, evtpercent);
1040  evtsByTrigger_->GetXaxis()->SetBinLabel(i, (it->first).c_str());
1041  }
1042 
1043  TFileDirectory RunFeatures = outfile_->mkdir("RunFeatures");
1044  h_runStartTimes = RunFeatures.make<TH1I>(
1045  "runStartTimes", "run start times", runNumbersTimesLog_.size(), 0, runNumbersTimesLog_.size());
1046  h_runEndTimes =
1047  RunFeatures.make<TH1I>("runEndTimes", "run end times", runNumbersTimesLog_.size(), 0, runNumbersTimesLog_.size());
1048 
1049  unsigned int count = 1;
1050  for (const auto& run : runNumbersTimesLog_) {
1051  // strip down the microseconds
1052  h_runStartTimes->SetBinContent(count, run.second.first / 10e6);
1053  h_runStartTimes->GetXaxis()->SetBinLabel(count, (std::to_string(run.first)).c_str());
1054 
1055  h_runEndTimes->SetBinContent(count, run.second.second / 10e6);
1056  h_runEndTimes->GetXaxis()->SetBinLabel(count, (std::to_string(run.first)).c_str());
1057 
1058  count++;
1059  }
1060 
1061  // resolutions
1062 
1066 
1070 
1074 
1075  // pulls
1076 
1080 
1084 
1088 }
1089 
1090 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
1093  desc.setComment(
1094  "Validates alignment payloads by evaluating the resulting Primary Vertex Resolution via vertex splitting method");
1095 
1096  desc.addUntracked<int>("compressionSettings", -1);
1097  desc.add<bool>("storeNtuple", false);
1098  desc.addUntracked<double>("intLumi", 0.);
1099  desc.addUntracked<bool>("Debug", false);
1100  desc.add<edm::InputTag>("vtxCollection", edm::InputTag("offlinePrimaryVertices"));
1101  desc.add<edm::InputTag>("trackCollection", edm::InputTag("generalTracks"));
1102  desc.addUntracked<double>("minVertexNdf", 10);
1103  desc.addUntracked<double>("minVertexMeanWeight", 0.5);
1104  desc.addUntracked<bool>("runControl", false);
1105  desc.addUntracked<std::vector<unsigned int>>("runControlNumber", {});
1106  desc.addUntracked<double>("sumpTStartScale", 1.);
1107  desc.addUntracked<double>("sumpTEndScale", 1e3);
1108  desc.addUntracked<double>("nTrackBins", 120.);
1109  desc.addUntracked<double>("nVtxBins", 60.);
1110  descriptions.addWithDefaultLabel(desc);
1111 }
1112 
1113 //*************************************************************
1114 std::pair<long long, long long> SplitVertexResolution::getRunTime(const edm::EventSetup& iSetup) const
1115 //*************************************************************
1116 {
1117  const auto& runInfo = iSetup.getData(runInfoToken_);
1118  if (debug_) {
1119  edm::LogInfo("SplitVertexResolution")
1120  << "start time: " << runInfo.m_start_time_str << " - stop time: " << runInfo.m_stop_time_str << std::endl;
1121  }
1122  return std::make_pair(runInfo.m_start_time_ll, runInfo.m_stop_time_ll);
1123 }
1124 
1125 //*************************************************************
1126 void SplitVertexResolution::fillTrendPlotByIndex(TH1F* trendPlot, std::vector<TH1F*>& h, PVValHelper::estimator fitPar_)
1127 //*************************************************************
1128 {
1129  for (auto iterator = h.begin(); iterator != h.end(); iterator++) {
1130  unsigned int bin = std::distance(h.begin(), iterator) + 1;
1131  statmode::fitParams myFit = fitResiduals((*iterator));
1132 
1133  switch (fitPar_) {
1134  case PVValHelper::MEAN: {
1135  float mean_ = myFit.first.value();
1136  float meanErr_ = myFit.first.error();
1137  trendPlot->SetBinContent(bin, mean_);
1138  trendPlot->SetBinError(bin, meanErr_);
1139  break;
1140  }
1141  case PVValHelper::WIDTH: {
1142  float width_ = myFit.second.value();
1143  float widthErr_ = myFit.second.error();
1144  trendPlot->SetBinContent(bin, width_);
1145  trendPlot->SetBinError(bin, widthErr_);
1146  break;
1147  }
1148  case PVValHelper::MEDIAN: {
1149  float median_ = PVValHelper::getMedian((*iterator)).value();
1150  float medianErr_ = PVValHelper::getMedian((*iterator)).error();
1151  trendPlot->SetBinContent(bin, median_);
1152  trendPlot->SetBinError(bin, medianErr_);
1153  break;
1154  }
1155  case PVValHelper::MAD: {
1156  float mad_ = PVValHelper::getMAD((*iterator)).value();
1157  float madErr_ = PVValHelper::getMAD((*iterator)).error();
1158  trendPlot->SetBinContent(bin, mad_);
1159  trendPlot->SetBinError(bin, madErr_);
1160  break;
1161  }
1162  default:
1163  edm::LogWarning("SplitVertexResolution")
1164  << "fillTrendPlotByIndex() " << fitPar_ << " unknown estimator!" << std::endl;
1165  break;
1166  }
1167  }
1168 }
1169 
1170 //*************************************************************
1172 //*************************************************************
1173 {
1174  if (hist->GetEntries() < 10) {
1175  LogDebug("SplitVertexResolution") << "hist name: " << hist->GetName() << " has less than 10 entries" << std::endl;
1176  return std::make_pair(Measurement1D(0., 0.), Measurement1D(0., 0.));
1177  }
1178 
1179  float maxHist = hist->GetXaxis()->GetXmax();
1180  float minHist = hist->GetXaxis()->GetXmin();
1181  float mean = hist->GetMean();
1182  float sigma = hist->GetRMS();
1183 
1184  if (edm::isNotFinite(mean) || edm::isNotFinite(sigma)) {
1185  mean = 0;
1186  //sigma= - hist->GetXaxis()->GetBinLowEdge(1) + hist->GetXaxis()->GetBinLowEdge(hist->GetNbinsX()+1);
1187  sigma = -minHist + maxHist;
1188  edm::LogWarning("SplitVertexResolution")
1189  << "FitPVResiduals::fitResiduals(): histogram" << hist->GetName() << " mean or sigma are NaN!!" << std::endl;
1190  }
1191 
1192  TF1 func("tmp", "gaus", mean - 2. * sigma, mean + 2. * sigma);
1193  if (0 == hist->Fit(&func, "QNR")) { // N: do not blow up file by storing fit!
1194  mean = func.GetParameter(1);
1195  sigma = func.GetParameter(2);
1196 
1197  if (!singleTime) {
1198  // second fit: three sigma of first fit around mean of first fit
1199  func.SetRange(std::max(mean - 3 * sigma, minHist), std::min(mean + 3 * sigma, maxHist));
1200  // I: integral gives more correct results if binning is too wide
1201  // L: Likelihood can treat empty bins correctly (if hist not weighted...)
1202  if (0 == hist->Fit(&func, "Q0LR")) {
1203  if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn:
1204  hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw);
1205  }
1206  }
1207  }
1208  }
1209 
1210  float res_mean = func.GetParameter(1);
1211  float res_width = func.GetParameter(2);
1212 
1213  float res_mean_err = func.GetParError(1);
1214  float res_width_err = func.GetParError(2);
1215 
1216  Measurement1D resultM(res_mean, res_mean_err);
1217  Measurement1D resultW(res_width, res_width_err);
1218 
1219  statmode::fitParams result = std::make_pair(resultM, resultW);
1220  return result;
1221 }
1222 
1223 //*************************************************************
1225 //*************************************************************
1226 {
1227  float mean = hist->GetMean();
1228  float sigma = hist->GetRMS();
1229 
1230  TF1 func("tmp", "gaus", mean - 1.5 * sigma, mean + 1.5 * sigma);
1231  if (0 == hist->Fit(&func, "QNR")) { // N: do not blow up file by storing fit!
1232  mean = func.GetParameter(1);
1233  sigma = func.GetParameter(2);
1234  // second fit: three sigma of first fit around mean of first fit
1235  func.SetRange(mean - 2 * sigma, mean + 2 * sigma);
1236  // I: integral gives more correct results if binning is too wide
1237  // L: Likelihood can treat empty bins correctly (if hist not weighted...)
1238  if (0 == hist->Fit(&func, "Q0LR")) {
1239  if (hist->GetFunction(func.GetName())) { // Take care that it is later on drawn:
1240  hist->GetFunction(func.GetName())->ResetBit(TF1::kNotDraw);
1241  }
1242  }
1243  }
1244 
1245  float res_mean = func.GetParameter(1);
1246  float res_width = func.GetParameter(2);
1247 
1248  float res_mean_err = func.GetParError(1);
1249  float res_width_err = func.GetParError(2);
1250 
1251  Measurement1D resultM(res_mean, res_mean_err);
1252  Measurement1D resultW(res_width, res_width_err);
1253 
1254  statmode::fitParams result = std::make_pair(resultM, resultW);
1255  return result;
1256 }
1257 
1258 //*************************************************************
1259 template <std::size_t SIZE>
1260 bool SplitVertexResolution::checkBinOrdering(std::array<float, SIZE>& bins)
1261 //*************************************************************
1262 {
1263  int i = 1;
1264 
1265  if (std::is_sorted(bins.begin(), bins.end())) {
1266  return true;
1267  } else {
1268  for (const auto& bin : bins) {
1269  edm::LogInfo("SplitVertexResolution") << "bin: " << i << " : " << bin << std::endl;
1270  i++;
1271  }
1272  edm::LogInfo("SplitVertexResolution") << "--------------------------------" << std::endl;
1273  return false;
1274  }
1275 }
1276 
1277 //define this as a plug-in
static const std::string kSharedResource
Definition: TFileService.h:76
Definition: BitonicSort.h:7
Log< level::Info, true > LogVerbatim
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
Measurement1D getMedian(TH1F *histo)
int eventNumber
Definition: pvTree.h:58
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
float totalChiSquared() const
float z_origVtx
Definition: pvTree.h:16
std::vector< TH1F * > h_resolZ_Nvtx_
std::vector< TH1F * > h_pullY_sumPt_
std::pair< long long, long long > getRunTime(const edm::EventSetup &iSetup) const
float sumPt_subVtx2
Definition: pvTree.h:40
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void beginRun(edm::Run const &iEvent, edm::EventSetup const &) override
SplitVertexResolution(const edm::ParameterSet &)
double z() const
z coordinate
Definition: Vertex.h:134
int nVtx
Definition: pvTree.h:60
bool isFake() const
Definition: Vertex.h:77
std::vector< TH1F * > h_pullZ_sumPt_
float y_subVtx1
Definition: pvTree.h:24
std::vector< TH1F * > h_resolX_sumPt_
void endRun(edm::Run const &, edm::EventSetup const &) override
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
float zErr_subVtx1
Definition: pvTree.h:29
std::vector< float > generateBins(int n, float start, float range)
edm::EDGetTokenT< reco::VertexCollection > pvsToken_
float y_origVtx
Definition: pvTree.h:15
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
statmode::fitParams fitResiduals_v0(TH1 *hist)
int runNumber
Definition: pvTree.h:56
float minW_subVtx1
Definition: pvTree.h:45
float x_origVtx
Definition: pvTree.h:14
Log< level::Error, false > LogError
double zError() const
error on z
Definition: Vertex.h:142
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &) const override
double ndof() const
Definition: Vertex.h:124
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:31
float degreesOfFreedom() const
Measurement1D getMAD(TH1F *histo)
double xError() const
error on x
Definition: Vertex.h:138
std::vector< TH1F * > h_pullY_Ntracks_
float CL_subVtx2
Definition: pvTree.h:43
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.h:111
edm::ESGetToken< RunInfo, RunInfoRcd > runInfoToken_
std::pair< Measurement1D, Measurement1D > fitParams
static std::string to_string(const XMLCh *ch)
Definition: pvTree.h:9
size_t tracksSize() const
number of tracks
Definition: Vertex.h:113
float y_subVtx2
Definition: pvTree.h:34
T getUntrackedParameter(std::string const &, T const &) const
reco::TransientTrack build(const reco::Track *p) const
U second(std::pair< T, U > const &p)
T * make(const Args &...args) const
make new ROOT object
float x_subVtx1
Definition: pvTree.h:23
float minW_subVtx2
Definition: pvTree.h:46
std::array< float, nPtBins_+1 > mypT_bins_
int n_subVtx2
Definition: pvTree.h:32
int iEvent
Definition: GenABIO.cc:224
static constexpr double cmToUm
runControlNumber
Definition: PV_cfg.py:170
void fillTrendPlotByIndex(TH1F *trendPlot, std::vector< TH1F *> &h, PVValHelper::estimator fitPar_)
bool isValid() const
T sqrt(T t)
Definition: SSEVec.h:23
std::vector< pvCand > pvs
Definition: pvTree.h:62
float zErr_origVtx
Definition: pvTree.h:20
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
unsigned int nTracks(float minWeight=0.5) const
Returns the number of tracks in the vertex with weight above minWeight.
Definition: Vertex.cc:131
Transition
Definition: Transition.h:12
float sumPt_subVtx1
Definition: pvTree.h:30
std::vector< reco::TransientTrack > const & originalTracks() const
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.h:109
float x_subVtx2
Definition: pvTree.h:33
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int n_subVtx1
Definition: pvTree.h:22
double x() const
x coordinate
Definition: Vertex.h:130
std::array< float, nVtxBins_+1 > myNVtx_bins_
std::vector< TH1F * > h_resolX_Nvtx_
edm::EDGetTokenT< edm::TriggerResults > triggerResultsToken_
float xErr_subVtx1
Definition: pvTree.h:27
double y() const
y coordinate
Definition: Vertex.h:132
edm::Service< TFileService > outfile_
std::map< std::string, std::pair< int, int > > triggerMap_
int nTrks
Definition: pvTree.h:11
int ipos
Definition: pvTree.h:12
Log< level::Info, false > LogInfo
~SplitVertexResolution() override
static bool mysorter(reco::Track i, reco::Track j)
std::array< float, nTrackBins_+1 > myNTrack_bins_
std::map< unsigned int, std::pair< long long, long long > > runNumbersTimesLog_
std::vector< TH1F * > h_pullY_Nvtx_
std::vector< TH1F * > h_resolZ_Ntracks_
TFileDirectory mkdir(const std::string &dir, const std::string &descr="")
create a new subdirectory
Definition: TFileService.h:69
float z_subVtx1
Definition: pvTree.h:25
std::vector< TH1F * > h_pullX_Nvtx_
virtual void beginEvent() final
float CL_subVtx1
Definition: pvTree.h:42
int luminosityBlockNumber
Definition: pvTree.h:57
statmode::fitParams fitResiduals(TH1 *hist, bool singleTime=false)
std::string const & triggerName(unsigned int index) const
Definition: TriggerNames.cc:50
float yErr_subVtx2
Definition: pvTree.h:38
float xErr_subVtx2
Definition: pvTree.h:37
std::vector< TH1F * > h_pullZ_Nvtx_
double value() const
Definition: Measurement1D.h:25
std::vector< TH1F * > bookResidualsHistogram(TFileDirectory dir, unsigned int theNOfBins, TString resType, TString varType)
std::vector< TH1F * > h_resolY_Nvtx_
float z_subVtx2
Definition: pvTree.h:35
fixed size matrix
HLT enums.
float yErr_origVtx
Definition: pvTree.h:19
double yError() const
error on y
Definition: Vertex.h:140
static std::atomic< unsigned int > counter
Definition: pvTree.h:54
double error() const
Definition: Measurement1D.h:27
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > transientTrackBuilderToken_
std::vector< TH1F * > h_pullX_sumPt_
float trackWeight(const reco::TransientTrack &track) const
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
float zErr_subVtx2
Definition: pvTree.h:39
float xErr_origVtx
Definition: pvTree.h:18
Log< level::Warning, false > LogWarning
float yErr_subVtx1
Definition: pvTree.h:28
std::vector< TH1F * > h_pullX_Ntracks_
bool checkBinOrdering(std::array< float, SIZE > &bins)
void fillByIndex(std::vector< TH1F *> &h, unsigned int index, double x, std::string tag="")
edm::EDGetTokenT< reco::TrackCollection > tracksToken_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
std::vector< TH1F * > h_pullZ_Ntracks_
std::vector< TH1F * > h_resolY_sumPt_
std::vector< unsigned int > runControlNumbers_
std::vector< TH1F * > h_resolX_Ntracks_
void analyze(const edm::Event &, const edm::EventSetup &) override
std::vector< TH1F * > h_resolY_Ntracks_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
Definition: Run.h:45
std::vector< TH1F * > h_resolZ_sumPt_
#define LogDebug(id)
TFile & file() const
return opened TFile
Definition: TFileService.h:37