CMS 3D CMS Logo

SiPixelCompareTracks.cc
Go to the documentation of this file.
1 // TODO: change file name to SiPixelCompareTracksSoA.cc when CUDA code is removed
2 
3 // -*- C++ -*-
4 // Package: SiPixelCompareTracks
5 // Class: SiPixelCompareTracks
6 //
9 //
10 // Author: Suvankar Roy Chowdhury
11 //
12 
13 // for string manipulations
14 #include <algorithm>
15 #include <fmt/printf.h>
25 // DQM Histograming
29 // DataFormats
32 
33 namespace {
34  // same logic used for the MTV:
35  // cf https://github.com/cms-sw/cmssw/blob/master/Validation/RecoTrack/src/MTVHistoProducerAlgoForTracker.cc
37 
38  void setBinLog(TAxis* axis) {
39  int bins = axis->GetNbins();
40  float from = axis->GetXmin();
41  float to = axis->GetXmax();
42  float width = (to - from) / bins;
43  std::vector<float> new_bins(bins + 1, 0);
44  for (int i = 0; i <= bins; i++) {
45  new_bins[i] = TMath::Power(10, from + i * width);
46  }
47  axis->Set(bins, new_bins.data());
48  }
49 
50  void setBinLogX(TH1* h) {
51  TAxis* axis = h->GetXaxis();
52  setBinLog(axis);
53  }
54  void setBinLogY(TH1* h) {
55  TAxis* axis = h->GetYaxis();
56  setBinLog(axis);
57  }
58 
59  template <typename... Args>
60  dqm::reco::MonitorElement* make2DIfLog(DQMStore::IBooker& ibook, bool logx, bool logy, Args&&... args) {
61  auto h = std::make_unique<TH2I>(std::forward<Args>(args)...);
62  if (logx)
63  setBinLogX(h.get());
64  if (logy)
65  setBinLogY(h.get());
66  const auto& name = h->GetName();
67  return ibook.book2I(name, h.release());
68  }
69 } // namespace
70 
71 // TODO: change class name to SiPixelCompareTracksSoA when CUDA code is removed
72 template <typename T>
74 public:
76 
77  explicit SiPixelCompareTracks(const edm::ParameterSet&);
78  ~SiPixelCompareTracks() override = default;
79  void bookHistograms(DQMStore::IBooker& ibooker, edm::Run const& iRun, edm::EventSetup const& iSetup) override;
80  void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;
81  // analyzeSeparate is templated to accept distinct types of SoAs
82  // The default use case is to use tracks from Alpaka reconstructed on CPU and GPU;
83  template <typename U, typename V>
84  void analyzeSeparate(U tokenRef, V tokenTar, const edm::Event& iEvent);
85  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
86 
87 private:
88  // these two are both on Host but originally they have been produced on Host or on Device
92  const bool useQualityCut_;
94  const float dr2cut_;
119  //1D differences
126 
127  //for matching eff vs region: derive the ratio at harvesting
132 };
133 
134 //
135 // constructors
136 //
137 
138 template <typename T>
140  : tokenSoATrackReference_(consumes<PixelTrackSoA>(iConfig.getParameter<edm::InputTag>("pixelTrackReferenceSoA"))),
141  tokenSoATrackTarget_(consumes<PixelTrackSoA>(iConfig.getParameter<edm::InputTag>("pixelTrackTargetSoA"))),
142  topFolderName_(iConfig.getParameter<std::string>("topFolderName")),
143  useQualityCut_(iConfig.getParameter<bool>("useQualityCut")),
144  minQuality_(pixelTrack::qualityByName(iConfig.getParameter<std::string>("minQuality"))),
145  dr2cut_(iConfig.getParameter<double>("deltaR2cut")) {}
146 
147 template <typename T>
148 template <typename U, typename V>
150  using helper = TracksUtilities<T>;
151 
152  const auto& tsoaHandleRef = iEvent.getHandle(tokenRef);
153  const auto& tsoaHandleTar = iEvent.getHandle(tokenTar);
154 
155  if (not tsoaHandleRef or not tsoaHandleTar) {
156  edm::LogWarning out("SiPixelCompareTracks");
157  if (not tsoaHandleRef) {
158  out << "reference tracks not found; ";
159  }
160  if (not tsoaHandleTar) {
161  out << "target tracks not found; ";
162  }
163  out << "the comparison will not run.";
164  return;
165  }
166 
167  auto const& tsoaRef = *tsoaHandleRef;
168  auto const& tsoaTar = *tsoaHandleTar;
169 
170  auto maxTracksRef = tsoaRef.view().metadata().size(); //this should be same for both?
171  auto maxTracksTar = tsoaTar.view().metadata().size(); //this should be same for both?
172 
173  auto const* qualityRef = tsoaRef.view().quality();
174  auto const* qualityTar = tsoaTar.view().quality();
175 
176  int32_t nTracksRef = 0;
177  int32_t nTracksTar = 0;
178  int32_t nLooseAndAboveTracksRef = 0;
179  int32_t nLooseAndAboveTracksRef_matchedTar = 0;
180  int32_t nLooseAndAboveTracksTar = 0;
181 
182  //Loop over Tar tracks and store the indices of the loose tracks. Whats happens if useQualityCut_ is false?
183  std::vector<int32_t> looseTrkidxTar;
184  for (int32_t jt = 0; jt < maxTracksTar; ++jt) {
185  if (helper::nHits(tsoaTar.view(), jt) == 0)
186  break; // this is a guard
187  if (!(tsoaTar.view()[jt].pt() > 0.))
188  continue;
189  nTracksTar++;
190  if (useQualityCut_ && qualityTar[jt] < minQuality_)
191  continue;
192  nLooseAndAboveTracksTar++;
193  looseTrkidxTar.emplace_back(jt);
194  }
195 
196  //Now loop over Ref tracks//nested loop for loose gPU tracks
197  for (int32_t it = 0; it < maxTracksRef; ++it) {
198  int nHitsRef = helper::nHits(tsoaRef.view(), it);
199 
200  if (nHitsRef == 0)
201  break; // this is a guard
202 
203  float ptRef = tsoaRef.view()[it].pt();
204  float etaRef = tsoaRef.view()[it].eta();
205  float phiRef = reco::phi(tsoaRef.view(), it);
206  float zipRef = reco::zip(tsoaRef.view(), it);
207  float tipRef = reco::tip(tsoaRef.view(), it);
208  auto qRef = reco::charge(tsoaRef.view(), it);
209 
210  if (!(ptRef > 0.))
211  continue;
212  nTracksRef++;
213  if (useQualityCut_ && qualityRef[it] < minQuality_)
214  continue;
215  nLooseAndAboveTracksRef++;
216  //Now loop over loose Tar trk and find the closest in DeltaR//do we need pt cut?
217  const int32_t notFound = -1;
218  int32_t closestTkidx = notFound;
219  float mindr2 = dr2cut_;
220 
221  for (auto gid : looseTrkidxTar) {
222  float etaTar = tsoaTar.view()[gid].eta();
223  float phiTar = reco::phi(tsoaTar.view(), gid);
224  float dr2 = reco::deltaR2(etaRef, phiRef, etaTar, phiTar);
225  if (dr2 > dr2cut_)
226  continue; // this is arbitrary
227  if (mindr2 > dr2) {
228  mindr2 = dr2;
229  closestTkidx = gid;
230  }
231  }
232 
233  hpt_eta_tkAllRef_->Fill(etaRef, ptRef); //all Ref tk
234  hphi_z_tkAllRef_->Fill(phiRef, zipRef);
235  if (closestTkidx == notFound)
236  continue;
237  nLooseAndAboveTracksRef_matchedTar++;
238 
239  hchi2_->Fill(tsoaRef.view()[it].chi2(), tsoaTar.view()[closestTkidx].chi2());
240  hCharge_->Fill(qRef, reco::charge(tsoaTar.view(), closestTkidx));
241  hnHits_->Fill(helper::nHits(tsoaRef.view(), it), helper::nHits(tsoaTar.view(), closestTkidx));
242  hnLayers_->Fill(tsoaRef.view()[it].nLayers(), tsoaTar.view()[closestTkidx].nLayers());
243  hpt_->Fill(ptRef, tsoaTar.view()[closestTkidx].pt());
244  hCurvature_->Fill(qRef / ptRef, reco::charge(tsoaTar.view(), closestTkidx) / tsoaTar.view()[closestTkidx].pt());
245  hptLogLog_->Fill(ptRef, tsoaTar.view()[closestTkidx].pt());
246  heta_->Fill(etaRef, tsoaTar.view()[closestTkidx].eta());
247  hphi_->Fill(phiRef, reco::phi(tsoaTar.view(), closestTkidx));
248  hz_->Fill(zipRef, reco::zip(tsoaTar.view(), closestTkidx));
249  htip_->Fill(tipRef, reco::tip(tsoaTar.view(), closestTkidx));
250  hptdiffMatched_->Fill(ptRef - tsoaTar.view()[closestTkidx].pt());
251  hCurvdiffMatched_->Fill(qRef / ptRef -
252  (reco::charge(tsoaTar.view(), closestTkidx) / tsoaTar.view()[closestTkidx].pt()));
253  hetadiffMatched_->Fill(etaRef - tsoaTar.view()[closestTkidx].eta());
254  hphidiffMatched_->Fill(reco::deltaPhi(phiRef, reco::phi(tsoaTar.view(), closestTkidx)));
255  hzdiffMatched_->Fill(zipRef - reco::zip(tsoaTar.view(), closestTkidx));
256  htipdiffMatched_->Fill(tipRef - reco::tip(tsoaTar.view(), closestTkidx));
257  hpt_eta_tkAllRefMatched_->Fill(etaRef, tsoaRef.view()[it].pt()); //matched to gpu
258  hphi_z_tkAllRefMatched_->Fill(etaRef, zipRef);
259  }
260 
261  // Define a lambda function for filling the histograms
262  auto fillHistogram = [](auto& histogram, auto xValue, auto yValue) { histogram->Fill(xValue, yValue); };
263 
264  // Define a lambda for filling delta histograms
265  auto fillDeltaHistogram = [](auto& histogram, int cpuValue, int gpuValue) {
266  histogram->Fill(std::min(cpuValue, 1000), std::clamp(gpuValue - cpuValue, -100, 100));
267  };
268 
269  // Fill the histograms
270  fillHistogram(hnTracks_, nTracksRef, nTracksTar);
271  fillHistogram(hnLooseAndAboveTracks_, nLooseAndAboveTracksRef, nLooseAndAboveTracksTar);
272  fillHistogram(hnLooseAndAboveTracks_matched_, nLooseAndAboveTracksRef, nLooseAndAboveTracksRef_matchedTar);
273 
274  fillDeltaHistogram(hDeltaNTracks_, nTracksRef, nTracksTar);
275  fillDeltaHistogram(hDeltaNLooseAndAboveTracks_, nLooseAndAboveTracksRef, nLooseAndAboveTracksTar);
276  fillDeltaHistogram(hDeltaNLooseAndAboveTracks_matched_, nLooseAndAboveTracksRef, nLooseAndAboveTracksRef_matchedTar);
277 }
278 
279 //
280 // -- Analyze
281 //
282 template <typename T>
284  // The default use case is to use vertices from Alpaka reconstructed on CPU and GPU;
285  // The function is left templated if any other cases need to be added
286  analyzeSeparate(tokenSoATrackReference_, tokenSoATrackTarget_, iEvent);
287 }
288 
289 //
290 // -- Book Histograms
291 //
292 template <typename T>
294  edm::Run const& iRun,
295  edm::EventSetup const& iSetup) {
296  iBook.cd();
297  iBook.setCurrentFolder(topFolderName_);
298 
299  // Define a helper function for booking histograms
300  std::string toRep = "Number of tracks";
301  auto bookTracksTH2I = [&](const std::string& name,
302  const std::string& title,
303  int xBins,
304  double xMin,
305  double xMax,
306  int yBins,
307  double yMin,
308  double yMax) {
309  return iBook.book2I(name, fmt::sprintf(title, toRep), xBins, xMin, xMax, yBins, yMin, yMax);
310  };
311 
312  // Define common parameters for different histogram types
313  constexpr int xBins = 501;
314  constexpr double xMin = -0.5;
315  constexpr double xMax = 1001.5;
316 
317  constexpr int dXBins = 1001;
318  constexpr double dXMin = -0.5;
319  constexpr double dXMax = 1000.5;
320 
321  constexpr int dYBins = 201;
322  constexpr double dYMin = -100.5;
323  constexpr double dYMax = 100.5;
324 
325  // FIXME: all the 2D correlation plots are quite heavy in terms of memory consumption, so a as soon as DQM supports THnSparse
326  // these should be moved to a less resource consuming format
327 
328  // Book histograms using the helper function
329  // clang-format off
330  hnTracks_ = bookTracksTH2I("nTracks", "%s per event; Reference; Target", xBins, xMin, xMax, xBins, xMin, xMax);
331  hnLooseAndAboveTracks_ = bookTracksTH2I("nLooseAndAboveTracks", "%s (quality #geq loose) per event; Reference; Target", xBins, xMin, xMax, xBins, xMin, xMax);
332  hnLooseAndAboveTracks_matched_ = bookTracksTH2I("nLooseAndAboveTracks_matched", "%s (quality #geq loose) per event; Reference; Target", xBins, xMin, xMax, xBins, xMin, xMax);
333 
334  hDeltaNTracks_ = bookTracksTH2I("deltaNTracks", "%s per event; Reference; Target - Reference", dXBins, dXMin, dXMax, dYBins, dYMin, dYMax);
335  hDeltaNLooseAndAboveTracks_ = bookTracksTH2I("deltaNLooseAndAboveTracks", "%s (quality #geq loose) per event; Reference; Target - Reference", dXBins, dXMin, dXMax, dYBins, dYMin, dYMax);
336  hDeltaNLooseAndAboveTracks_matched_ = bookTracksTH2I("deltaNLooseAndAboveTracks_matched", "%s (quality #geq loose) per event; Reference; Target - Reference", dXBins, dXMin, dXMax, dYBins, dYMin, dYMax);
337 
338  toRep = "Number of all RecHits per track (quality #geq loose)";
339  hnHits_ = iBook.book2I("nRecHits", fmt::sprintf("%s;Reference;Target",toRep), 15, -0.5, 14.5, 15, -0.5, 14.5);
340 
341  toRep = "Number of all layers per track (quality #geq loose)";
342  hnLayers_ = iBook.book2I("nLayers", fmt::sprintf("%s;Reference;Target",toRep), 15, -0.5, 14.5, 15, -0.5, 14.5);
343 
344  toRep = "Track (quality #geq loose) #chi^{2}/ndof";
345  hchi2_ = iBook.book2I("nChi2ndof", fmt::sprintf("%s;Reference;Target",toRep), 40, 0., 20., 40, 0., 20.);
346 
347  toRep = "Track (quality #geq loose) charge";
348  hCharge_ = iBook.book2I("charge",fmt::sprintf("%s;Reference;Target",toRep),3, -1.5, 1.5, 3, -1.5, 1.5);
349 
350  hpt_ = iBook.book2I("pt", "Track (quality #geq loose) p_{T} [GeV];Reference;Target", 200, 0., 200., 200, 0., 200.);
351  hCurvature_ = iBook.book2I("curvature", "Track (quality #geq loose) q/p_{T} [GeV^{-1}];Reference;Target", 60,- 3., 3., 60, -3., 3. );
352  hptLogLog_ = make2DIfLog(iBook, true, true, "ptLogLog", "Track (quality #geq loose) p_{T} [GeV];Reference;Target", 200, log10(0.5), log10(200.), 200, log10(0.5), log10(200.));
353  heta_ = iBook.book2I("eta", "Track (quality #geq loose) #eta;Reference;Target", 30, -3., 3., 30, -3., 3.);
354  hphi_ = iBook.book2I("phi", "Track (quality #geq loose) #phi;Reference;Target", 30, -M_PI, M_PI, 30, -M_PI, M_PI);
355  hz_ = iBook.book2I("z", "Track (quality #geq loose) z [cm];Reference;Target", 30, -30., 30., 30, -30., 30.);
356  htip_ = iBook.book2I("tip", "Track (quality #geq loose) TIP [cm];Reference;Target", 100, -0.5, 0.5, 100, -0.5, 0.5);
357 
358  //1D difference plots
359  hptdiffMatched_ = iBook.book1D("ptdiffmatched", " p_{T} diff [GeV] between matched tracks; #Delta p_{T} [GeV]", 61, -30.5, 30.5);
360  hCurvdiffMatched_ = iBook.book1D("curvdiffmatched", "q/p_{T} diff [GeV^{-1}] between matched tracks; #Delta q/p_{T} [GeV^{-1}]", 61, -3.05, 3.05);
361  hetadiffMatched_ = iBook.book1D("etadiffmatched", " #eta diff between matched tracks; #Delta #eta", 161, -0.045 ,0.045);
362  hphidiffMatched_ = iBook.book1D("phidiffmatched", " #phi diff between matched tracks; #Delta #phi", 161, -0.045 ,0.045);
363  hzdiffMatched_ = iBook.book1D("zdiffmatched", " z diff between matched tracks; #Delta z [cm]", 301, -1.55, 1.55);
364  htipdiffMatched_ = iBook.book1D("tipdiffmatched", " TIP diff between matched tracks; #Delta TIP [cm]", 301, -1.55, 1.55);
365  //2D plots for eff
366  hpt_eta_tkAllRef_ = iBook.book2I("ptetatrkAllReference", "Track (quality #geq loose) on Reference; #eta; p_{T} [GeV];", 30, -M_PI, M_PI, 200, 0., 200.);
367  hpt_eta_tkAllRefMatched_ = iBook.book2I("ptetatrkAllReferencematched", "Track (quality #geq loose) on Reference matched to Target track; #eta; p_{T} [GeV];", 30, -M_PI, M_PI, 200, 0., 200.);
368 
369  hphi_z_tkAllRef_ = iBook.book2I("phiztrkAllReference", "Track (quality #geq loose) on Reference; #phi; z [cm];", 30, -M_PI, M_PI, 30, -30., 30.);
370  hphi_z_tkAllRefMatched_ = iBook.book2I("phiztrkAllReferencematched", "Track (quality #geq loose) on Reference; #phi; z [cm];", 30, -M_PI, M_PI, 30, -30., 30.);
371 
372 }
373 
374 template<typename T>
376  // monitorpixelTrackSoA
378  desc.add<edm::InputTag>("pixelTrackReferenceSoA", edm::InputTag("pixelTracksAlpakaSerial"));
379  desc.add<edm::InputTag>("pixelTrackTargetSoA", edm::InputTag("pixelTracksAlpaka"));
380  desc.add<std::string>("topFolderName", "SiPixelHeterogeneous/PixelTrackCompareDeviceVSHost");
381  desc.add<bool>("useQualityCut", true);
382  desc.add<std::string>("minQuality", "loose");
383  desc.add<double>("deltaR2cut", 0.02 * 0.02)->setComment("deltaR2 cut between track on device and host");
384  descriptions.addWithDefaultLabel(desc);
385 }
386 
387 // TODO: change module names to SiPixel*CompareTracksSoA when CUDA code is removed
388 
392 
396 
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
MonitorElement * hDeltaNTracks_
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
MonitorElement * hnLooseAndAboveTracks_
Definition: helper.py:1
MonitorElement * hnLayersVsPhi_
MonitorElement * hptdiffMatched_
MonitorElement * hphi_z_tkAllRef_
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
Quality qualityByName(std::string const &name)
SiPixelCompareTracks(const edm::ParameterSet &)
const edm::EDGetTokenT< PixelTrackSoA > tokenSoATrackReference_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float zip(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:90
void analyze(const edm::Event &iEvent, const edm::EventSetup &iSetup) override
MonitorElement * hphi_z_tkAllRefMatched_
void analyzeSeparate(U tokenRef, V tokenTar, const edm::Event &iEvent)
T eta() const
Definition: PV3DBase.h:73
MonitorElement * hnLayersVsEta_
MonitorElement * hCurvdiffMatched_
MonitorElement * hnTracks_
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float charge(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:73
MonitorElement * hpt_eta_tkAllRefMatched_
MonitorElement * hnLooseAndAboveTracks_matched_
MonitorElement * hphidiffMatched_
dqm::reco::DQMStore DQMStore
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float tip(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:85
int iEvent
Definition: GenABIO.cc:224
MonitorElement * hpt_eta_tkAllRef_
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t V
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
MonitorElement * hChi2VsEta_
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float phi(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:80
MonitorElement * hnHitsVsEta_
MonitorElement * hDeltaNLooseAndAboveTracks_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
MonitorElement * hDeltaNLooseAndAboveTracks_matched_
MonitorElement * hzdiffMatched_
#define M_PI
~SiPixelCompareTracks() override=default
MonitorElement * hChi2VsPhi_
MonitorElement * hetadiffMatched_
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
MonitorElement * hCurvature_
static const GlobalPoint notFound(0, 0, 0)
const pixelTrack::Quality minQuality_
MonitorElement * htipdiffMatched_
HLT enums.
void bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &iRun, edm::EventSetup const &iSetup) override
const std::string topFolderName_
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
TupleMultiplicity< TrackerTraits > const *__restrict__ uint32_t nHits
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
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:305
MonitorElement * hnHitsVsPhi_
const edm::EDGetTokenT< PixelTrackSoA > tokenSoATrackTarget_
Definition: Run.h:45