CMS 3D CMS Logo

PrimaryVertexAnalyzer4PUSlimmed.cc
Go to the documentation of this file.
2 
7 
8 // reco track and vertex
11 
12 // TrackingParticle
15 
16 // associator
19 
20 // DQM
22 
23 #include <numeric>
24 
25 namespace {
26  template <typename T, size_t N>
27  std::array<T, N+1> makeLogBins(const double min, const double max) {
28  const double minLog10 = std::log10(min);
29  const double maxLog10 = std::log10(max);
30  const double width = (maxLog10-minLog10)/N;
31  std::array<T, N+1> ret;
32  ret[0] = std::pow(10,minLog10);
33  const double mult = std::pow(10, width);
34  for(size_t i=1; i<= N; ++i) {
35  ret[i] = ret[i-1]*mult;
36  }
37  return ret;
38  }
39 }
40 
41 //
42 // constructors and destructor
43 //
45  const edm::ParameterSet& iConfig)
46  : verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
47  use_only_charged_tracks_(iConfig.getUntrackedParameter<bool>(
48  "use_only_charged_tracks", true)),
49  do_generic_sim_plots_(iConfig.getUntrackedParameter<bool>("do_generic_sim_plots")),
50  root_folder_(
51  iConfig.getUntrackedParameter<std::string>("root_folder",
52  "Validation/Vertices")),
53  vecPileupSummaryInfoToken_(consumes<std::vector<PileupSummaryInfo> >(
54  edm::InputTag(std::string("addPileupInfo")))),
55  trackingParticleCollectionToken_(consumes<TrackingParticleCollection>(
56  iConfig.getUntrackedParameter<edm::InputTag>("trackingParticleCollection"))),
57  trackingVertexCollectionToken_(consumes<TrackingVertexCollection>(
58  iConfig.getUntrackedParameter<edm::InputTag>("trackingVertexCollection"))),
59  simToRecoAssociationToken_(consumes<reco::SimToRecoCollection>(
60  iConfig.getUntrackedParameter<edm::InputTag>("trackAssociatorMap"))),
61  recoToSimAssociationToken_(consumes<reco::RecoToSimCollection>(
62  iConfig.getUntrackedParameter<edm::InputTag>("trackAssociatorMap"))),
63  vertexAssociatorToken_(consumes<reco::VertexToTrackingVertexAssociator>(
64  iConfig.getUntrackedParameter<edm::InputTag>("vertexAssociator"))) {
65  reco_vertex_collections_ = iConfig.getParameter<std::vector<edm::InputTag> >(
66  "vertexRecoCollections");
67  for (auto const& l : reco_vertex_collections_) {
71  }
72  errorPrintedForColl_.resize(reco_vertex_collections_.size(), false);
73 }
74 
76 
77 //
78 // member functions
79 //
81  DQMStore::IBooker& i, edm::Run const& iRun, edm::EventSetup const& iSetup) {
82  // TODO(rovere) make this booking method shorter and smarter,
83  // factorizing similar histograms with different prefix in a single
84  // method call.
85  float log_bins[31] = {
86  0.0, 0.0002, 0.0004, 0.0006, 0.0008, 0.001, 0.002,
87  0.004, 0.006, 0.008, 0.01, 0.02,
88  0.04, 0.06, 0.08, 0.1, 0.2,
89  0.4, 0.6, 0.8, 1.0, 2.0,
90  4.0, 6.0, 8.0, 10.0, 20.0,
91  40.0, 60.0, 80.0, 100.0
92  };
93  auto const log_mergez_bins = makeLogBins<float, 16>(1e-4, 1); // 4 bins / 10x
94 
95  auto const log_pt_bins = makeLogBins<float, 100>(0.1, 1e4);
96  float log_pt2_bins[16] = {
97  0.0, 0.1, 0.5,
98  1.0, 2.0, 5.0,
99  10.0, 20.0, 50.0,
100  100.0, 200.0, 500.0,
101  1000.0, 2000.0, 5000.0,10000.0
102  };
103  float log_ntrk_bins[25] = {
104  0., 2.0, 4.0, 6.0, 8.0, 10.,
105  12.0, 14.0, 16.0, 18.0, 22.0,
106  26.0, 30.0, 35.0, 40.0,
107  45.0, 50.0, 55.0, 60.0, 70.0,
108  80.0, 90.0, 100.0, 150.0, 200.0
109  };
110 
111  // TODO(rovere) Possibly change or add the main DQMStore booking
112  // interface to allow booking a TProfile with variable bin-width
113  // using an array of floats, as done for the TH1F case, not of
114  // doubles.
115  double log_pt2_bins_double[16] = {
116  0.0, 0.1, 0.5,
117  1.0, 2.0, 5.0,
118  10.0, 20.0, 50.0,
119  100.0, 200.0, 500.0,
120  1000.0, 2000.0, 5000.0,10000.0
121  };
122 
125  mes_["root_folder"]["GenVtx_vs_BX"] =
126  i.book2D("GenVtx_vs_BX", "GenVtx_vs_BX", 16, -12.5, 3.5, 200, 0., 200.);
127  // Generated Primary Vertex Plots
128  mes_["root_folder"]["GenPV_X"] =
129  i.book1D("GenPV_X", "GeneratedPV_X", 120, -0.6, 0.6);
130  mes_["root_folder"]["GenPV_Y"] =
131  i.book1D("GenPV_Y", "GeneratedPV_Y", 120, -0.6, 0.6);
132  mes_["root_folder"]["GenPV_Z"] =
133  i.book1D("GenPV_Z", "GeneratedPV_Z", 120, -60., 60.);
134  mes_["root_folder"]["GenPV_R"] =
135  i.book1D("GenPV_R", "GeneratedPV_R", 120, 0, 0.6);
136  mes_["root_folder"]["GenPV_Pt2"] =
137  i.book1D("GenPV_Pt2", "GeneratedPV_Sum-pt2", 15, &log_pt2_bins[0]);
138  mes_["root_folder"]["GenPV_NumTracks"] =
139  i.book1D("GenPV_NumTracks", "GeneratedPV_NumTracks", 24, &log_ntrk_bins[0]);
140  mes_["root_folder"]["GenPV_ClosestDistanceZ"] =
141  i.book1D("GenPV_ClosestDistanceZ", "GeneratedPV_ClosestDistanceZ", 30,
142  &log_bins[0]);
143 
144  // All Generated Vertices, used for efficiency plots
145  mes_["root_folder"]["GenAllV_NumVertices"] = i.book1D(
146  "GenAllV_NumVertices", "GeneratedAllV_NumVertices", 100, 0., 200.);
147  mes_["root_folder"]["GenAllV_X"] =
148  i.book1D("GenAllV_X", "GeneratedAllV_X", 120, -0.6, 0.6);
149  mes_["root_folder"]["GenAllV_Y"] =
150  i.book1D("GenAllV_Y", "GeneratedAllV_Y", 120, -0.6, 0.6);
151  mes_["root_folder"]["GenAllV_Z"] =
152  i.book1D("GenAllV_Z", "GeneratedAllV_Z", 120, -60, 60);
153  mes_["root_folder"]["GenAllV_R"] =
154  i.book1D("GenAllV_R", "GeneratedAllV_R", 120, 0, 0.6);
155  mes_["root_folder"]["GenAllV_Pt2"] =
156  i.book1D("GenAllV_Pt2", "GeneratedAllV_Sum-pt2", 15, &log_pt2_bins[0]);
157  mes_["root_folder"]["GenAllV_NumTracks"] =
158  i.book1D("GenAllV_NumTracks", "GeneratedAllV_NumTracks", 24, &log_ntrk_bins[0]);
159  mes_["root_folder"]["GenAllV_ClosestDistanceZ"] =
160  i.book1D("GenAllV_ClosestDistanceZ", "GeneratedAllV_ClosestDistanceZ", 30,
161  &log_bins[0]);
162  mes_["root_folder"]["GenAllV_PairDistanceZ"] =
163  i.book1D("GenAllV_PairDistanceZ", "GeneratedAllV_PairDistanceZ",
164  1000, 0, 20);
165  mes_["root_folder"]["SignalIsHighestPt2"] =
166  i.book1D("SignalIsHighestPt2", "SignalIsHighestPt2", 2, -0.5, 1.5);
167  }
168 
169  for (auto const& l : reco_vertex_collections_) {
170  std::string label = l.label();
171  std::string current_folder = root_folder_ + "/" + label;
172  i.setCurrentFolder(current_folder);
173 
174  auto book1d = [&](const char *name, int bins, double min, double max) {
175  mes_[label][name] = i.book1D(name, name, bins, min, max);
176  };
177  auto book1dlogx = [&](const char *name, int bins, const float *xbinedges) {
178  mes_[label][name] = i.book1D(name, name, bins, xbinedges);
179  };
180  auto book2d = [&](const char *name,
181  int xbins, double xmin, double xmax,
182  int ybins, double ymin, double ymax) {
183  mes_[label][name] = i.book2D(name, name, xbins,xmin,xmax, ybins,ymin,ymax);
184  };
185  auto book2dlogx = [&](const char *name,
186  int xbins, const float *xbinedges,
187  int ybins, double ymin, double ymax) {
188  auto me = i.book2D(name, name, xbins,xbinedges[0],xbinedges[xbins], ybins,ymin,ymax);
189  me->getTH2F()->GetXaxis()->Set(xbins, xbinedges);
190  mes_[label][name] = me;
191  };
192 
193 
194  mes_[label]["RecoVtx_vs_GenVtx"] = i.bookProfile(
195  "RecoVtx_vs_GenVtx", "RecoVtx_vs_GenVtx", 125, 0., 250., 250, 0., 250.);
196  mes_[label]["MatchedRecoVtx_vs_GenVtx"] =
197  i.bookProfile("MatchedRecoVtx_vs_GenVtx", "MatchedRecoVtx_vs_GenVtx",
198  125, 0., 250., 250, 0., 250.);
199  mes_[label]["KindOfSignalPV"] =
200  i.book1D("KindOfSignalPV", "KindOfSignalPV", 9, -0.5, 8.5);
201  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(1, "!Highest!Assoc2Any");
202  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(2, "Highest!Assoc2Any");
203  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(3, "!HighestAssoc2First");
204  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(4, "HighestAssoc2First");
205  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(5, "!HighestAssoc2!First");
206  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(6, "HighestAssoc2!First");
207  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(7, "!HighestAssoc2First");
208  mes_[label]["KindOfSignalPV"]->getTH1()->GetXaxis()->SetBinLabel(8, "HighestAssoc2First");
209  mes_[label]["MisTagRate"] =
210  i.book1D("MisTagRate", "MisTagRate", 2, -0.5, 1.5);
211  mes_[label]["MisTagRate_vs_PU"] =
212  i.bookProfile("MisTagRate_vs_PU", "MisTagRate_vs_PU", 125, 0., 250.,
213  2, 0., 1.);
214  mes_[label]["MisTagRate_vs_sum-pt2"] =
215  i.bookProfile("MisTagRate_vs_sum-pt2", "MisTagRate_vs_sum-pt2",
216  15, &log_pt2_bins_double[0], 2, 0., 1.);
217  mes_[label]["MisTagRate_vs_Z"] =
218  i.bookProfile("MisTagRate_vs_Z", "MisTagRate_vs_Z",
219  120, -60., 60., 2, 0., 1.);
220  mes_[label]["MisTagRate_vs_R"] =
221  i.bookProfile("MisTagRate_vs_R", "MisTagRate_vs_R",
222  120, 0., 0.6, 2, 0., 1.);
223  mes_[label]["MisTagRate_vs_NumTracks"] =
224  i.bookProfile("MisTagRate_vs_NumTracks", "MisTagRate_vs_NumTracks",
225  100, 0., 200, 2, 0., 1.);
226  mes_[label]["MisTagRateSignalIsHighest"] =
227  i.book1D("MisTagRateSignalIsHighest",
228  "MisTagRateSignalIsHighest", 2, -0.5, 1.5);
229  mes_[label]["MisTagRateSignalIsHighest_vs_PU"] =
230  i.bookProfile("MisTagRateSignalIsHighest_vs_PU",
231  "MisTagRateSignalIsHighest_vs_PU", 125, 0., 250.,
232  2, 0., 1.);
233  mes_[label]["MisTagRateSignalIsHighest_vs_sum-pt2"] =
234  i.bookProfile("MisTagRateSignalIsHighest_vs_sum-pt2",
235  "MisTagRateSignalIsHighest_vs_sum-pt2",
236  15, &log_pt2_bins_double[0], 2, 0., 1.);
237  mes_[label]["MisTagRateSignalIsHighest_vs_Z"] =
238  i.bookProfile("MisTagRateSignalIsHighest_vs_Z",
239  "MisTagRateSignalIsHighest_vs_Z",
240  120, -60., 60., 2, 0., 1.);
241  mes_[label]["MisTagRateSignalIsHighest_vs_R"] =
242  i.bookProfile("MisTagRateSignalIsHighest_vs_R",
243  "MisTagRateSignalIsHighest_vs_R",
244  120, 0., 0.6, 2, 0., 1.);
245  mes_[label]["MisTagRateSignalIsHighest_vs_NumTracks"] =
246  i.bookProfile("MisTagRateSignalIsHighest_vs_NumTracks",
247  "MisTagRateSignalIsHighest_vs_NumTracks",
248  100, 0., 200, 2, 0., 1.);
249  mes_[label]["MisTagRateSignalIsNotHighest"] =
250  i.book1D("MisTagRateSignalIsNotHighest",
251  "MisTagRateSignalIsNotHighest", 2, -0.5, 1.5);
252  mes_[label]["MisTagRateSignalIsNotHighest_vs_PU"] =
253  i.bookProfile("MisTagRateSignalIsNotHighest_vs_PU",
254  "MisTagRateSignalIsNotHighest_vs_PU", 125, 0., 250.,
255  2, 0., 1.);
256  mes_[label]["MisTagRateSignalIsNotHighest_vs_sum-pt2"] =
257  i.bookProfile("MisTagRateSignalIsNotHighest_vs_sum-pt2",
258  "MisTagRateSignalIsNotHighest_vs_sum-pt2",
259  15, &log_pt2_bins_double[0], 2, 0., 1.);
260  mes_[label]["MisTagRateSignalIsNotHighest_vs_Z"] =
261  i.bookProfile("MisTagRateSignalIsNotHighest_vs_Z",
262  "MisTagRateSignalIsNotHighest_vs_Z",
263  120, -60., 60., 2, 0., 1.);
264  mes_[label]["MisTagRateSignalIsNotHighest_vs_R"] =
265  i.bookProfile("MisTagRateSignalIsNotHighest_vs_R",
266  "MisTagRateSignalIsNotHighest_vs_R",
267  120, 0., 0.6, 2, 0., 1.);
268  mes_[label]["MisTagRateSignalIsNotHighest_vs_NumTracks"] =
269  i.bookProfile("MisTagRateSignalIsNotHighest_vs_NumTracks",
270  "MisTagRateSignalIsNotHighest_vs_NumTracks",
271  100, 0., 200, 2, 0., 1.);
272  mes_[label]["TruePVLocationIndex"] =
273  i.book1D("TruePVLocationIndex",
274  "TruePVLocationIndexInRecoVertexCollection", 12, -1.5, 10.5);
275  mes_[label]["TruePVLocationIndexCumulative"] =
276  i.book1D("TruePVLocationIndexCumulative",
277  "TruePVLocationIndexInRecoVertexCollectionCumulative",
278  3, -1.5, 1.5);
279  mes_[label]["TruePVLocationIndexSignalIsHighest"] =
280  i.book1D("TruePVLocationIndexSignalIsHighest",
281  "TruePVLocationIndexSignalIsHighestInRecoVertexCollection",
282  12, -1.5, 10.5);
283  mes_[label]["TruePVLocationIndexSignalIsNotHighest"] =
284  i.book1D("TruePVLocationIndexSignalIsNotHighest",
285  "TruePVLocationIndexSignalIsNotHighestInRecoVertexCollection",
286  12, -1.5, 10.5);
287  // All Generated Vertices. Used for Efficiency plots We kind of
288  // duplicate plots here in case we want to perform more detailed
289  // studies on a selection of generated vertices, not on all of them.
290  mes_[label]["GenAllAssoc2Reco_NumVertices"] =
291  i.book1D("GenAllAssoc2Reco_NumVertices",
292  "GeneratedAllAssoc2Reco_NumVertices", 100, 0., 200.);
293  mes_[label]["GenAllAssoc2Reco_X"] = i.book1D(
294  "GenAllAssoc2Reco_X", "GeneratedAllAssoc2Reco_X", 120, -0.6, 0.6);
295  mes_[label]["GenAllAssoc2Reco_Y"] = i.book1D(
296  "GenAllAssoc2Reco_Y", "GeneratedAllAssoc2Reco_Y", 120, -0.6, 0.6);
297  mes_[label]["GenAllAssoc2Reco_Z"] = i.book1D(
298  "GenAllAssoc2Reco_Z", "GeneratedAllAssoc2Reco_Z", 120, -60, 60);
299  mes_[label]["GenAllAssoc2Reco_R"] =
300  i.book1D("GenAllAssoc2Reco_R", "GeneratedAllAssoc2Reco_R", 120, 0, 0.6);
301  mes_[label]["GenAllAssoc2Reco_Pt2"] =
302  i.book1D("GenAllAssoc2Reco_Pt2", "GeneratedAllAssoc2Reco_Sum-pt2", 15,
303  &log_pt2_bins[0]);
304  mes_[label]["GenAllAssoc2Reco_NumTracks"] =
305  i.book1D("GenAllAssoc2Reco_NumTracks",
306  "GeneratedAllAssoc2Reco_NumTracks", 24, &log_ntrk_bins[0]);
307  mes_[label]["GenAllAssoc2Reco_ClosestDistanceZ"] =
308  i.book1D("GenAllAssoc2Reco_ClosestDistanceZ",
309  "GeneratedAllAssoc2Reco_ClosestDistanceZ", 30, &log_bins[0]);
310  book1d("GenPVAssoc2RecoPV_X", 120, -0.6, 0.6);
311  book1d("GenPVAssoc2RecoPV_Y", 120, -0.6, 0.6);
312  book1d("GenPVAssoc2RecoPV_Z", 120, -60, 60);
313 
314  // All Generated Vertices Matched to a Reconstructed vertex. Used
315  // for Efficiency plots
316  mes_[label]["GenAllAssoc2RecoMatched_NumVertices"] =
317  i.book1D("GenAllAssoc2RecoMatched_NumVertices",
318  "GeneratedAllAssoc2RecoMatched_NumVertices", 100, 0., 200.);
319  mes_[label]["GenAllAssoc2RecoMatched_X"] =
320  i.book1D("GenAllAssoc2RecoMatched_X", "GeneratedAllAssoc2RecoMatched_X",
321  120, -0.6, 0.6);
322  mes_[label]["GenAllAssoc2RecoMatched_Y"] =
323  i.book1D("GenAllAssoc2RecoMatched_Y", "GeneratedAllAssoc2RecoMatched_Y",
324  120, -0.6, 0.6);
325  mes_[label]["GenAllAssoc2RecoMatched_Z"] =
326  i.book1D("GenAllAssoc2RecoMatched_Z", "GeneratedAllAssoc2RecoMatched_Z",
327  120, -60, 60);
328  mes_[label]["GenAllAssoc2RecoMatched_R"] =
329  i.book1D("GenAllAssoc2RecoMatched_R", "GeneratedAllAssoc2RecoMatched_R",
330  120, 0, 0.6);
331  mes_[label]["GenAllAssoc2RecoMatched_Pt2"] =
332  i.book1D("GenAllAssoc2RecoMatched_Pt2",
333  "GeneratedAllAssoc2RecoMatched_Sum-pt2", 15, &log_pt2_bins[0]);
334  mes_[label]["GenAllAssoc2RecoMatched_NumTracks"] =
335  i.book1D("GenAllAssoc2RecoMatched_NumTracks",
336  "GeneratedAllAssoc2RecoMatched_NumTracks", 24, &log_ntrk_bins[0]);
337  mes_[label]["GenAllAssoc2RecoMatched_ClosestDistanceZ"] = i.book1D(
338  "GenAllAssoc2RecoMatched_ClosestDistanceZ",
339  "GeneratedAllAssoc2RecoMatched_ClosestDistanceZ", 30, &log_bins[0]);
340  book1d("GenPVAssoc2RecoPVMatched_X", 120, -0.6, 0.6);
341  book1d("GenPVAssoc2RecoPVMatched_Y", 120, -0.6, 0.6);
342  book1d("GenPVAssoc2RecoPVMatched_Z", 120, -60, 60);
343 
344  // All Generated Vertices Multi-Matched to a Reconstructed vertex. Used
345  // for Duplicate rate plots
346  mes_[label]["GenAllAssoc2RecoMultiMatched_NumVertices"] = i.book1D(
347  "GenAllAssoc2RecoMultiMatched_NumVertices",
348  "GeneratedAllAssoc2RecoMultiMatched_NumVertices", 100, 0., 200.);
349  mes_[label]["GenAllAssoc2RecoMultiMatched_X"] =
350  i.book1D("GenAllAssoc2RecoMultiMatched_X",
351  "GeneratedAllAssoc2RecoMultiMatched_X", 120, -0.6, 0.6);
352  mes_[label]["GenAllAssoc2RecoMultiMatched_Y"] =
353  i.book1D("GenAllAssoc2RecoMultiMatched_Y",
354  "GeneratedAllAssoc2RecoMultiMatched_Y", 120, -0.6, 0.6);
355  mes_[label]["GenAllAssoc2RecoMultiMatched_Z"] =
356  i.book1D("GenAllAssoc2RecoMultiMatched_Z",
357  "GeneratedAllAssoc2RecoMultiMatched_Z", 120, -60, 60);
358  mes_[label]["GenAllAssoc2RecoMultiMatched_R"] =
359  i.book1D("GenAllAssoc2RecoMultiMatched_R",
360  "GeneratedAllAssoc2RecoMultiMatched_R", 120, 0, 0.6);
361  mes_[label]["GenAllAssoc2RecoMultiMatched_Pt2"] =
362  i.book1D("GenAllAssoc2RecoMultiMatched_Pt2",
363  "GeneratedAllAssoc2RecoMultiMatched_Sum-pt2",
364  15, &log_pt2_bins[0]);
365  mes_[label]["GenAllAssoc2RecoMultiMatched_NumTracks"] =
366  i.book1D("GenAllAssoc2RecoMultiMatched_NumTracks",
367  "GeneratedAllAssoc2RecoMultiMatched_NumTracks", 24, &log_ntrk_bins[0]);
368  mes_[label]["GenAllAssoc2RecoMultiMatched_ClosestDistanceZ"] = i.book1D(
369  "GenAllAssoc2RecoMultiMatched_ClosestDistanceZ",
370  "GeneratedAllAssoc2RecoMultiMatched_ClosestDistanceZ",
371  30, &log_bins[0]);
372 
373  // All Reco Vertices. Used for {Fake,Duplicate}-Rate plots
374  mes_[label]["RecoAllAssoc2Gen_NumVertices"] =
375  i.book1D("RecoAllAssoc2Gen_NumVertices",
376  "ReconstructedAllAssoc2Gen_NumVertices", 100, 0., 200.);
377  mes_[label]["RecoAllAssoc2Gen_X"] = i.book1D(
378  "RecoAllAssoc2Gen_X", "ReconstructedAllAssoc2Gen_X", 120, -0.6, 0.6);
379  mes_[label]["RecoAllAssoc2Gen_Y"] = i.book1D(
380  "RecoAllAssoc2Gen_Y", "ReconstructedAllAssoc2Gen_Y", 120, -0.6, 0.6);
381  mes_[label]["RecoAllAssoc2Gen_Z"] = i.book1D(
382  "RecoAllAssoc2Gen_Z", "ReconstructedAllAssoc2Gen_Z", 120, -60, 60);
383  mes_[label]["RecoAllAssoc2Gen_R"] = i.book1D(
384  "RecoAllAssoc2Gen_R", "ReconstructedAllAssoc2Gen_R", 120, 0, 0.6);
385  mes_[label]["RecoAllAssoc2Gen_Pt2"] =
386  i.book1D("RecoAllAssoc2Gen_Pt2", "ReconstructedAllAssoc2Gen_Sum-pt2",
387  15, &log_pt2_bins[0]);
388  mes_[label]["RecoAllAssoc2Gen_Ndof"] =
389  i.book1D("RecoAllAssoc2Gen_Ndof",
390  "ReconstructedAllAssoc2Gen_Ndof", 120, 0., 240.);
391  mes_[label]["RecoAllAssoc2Gen_NumTracks"] =
392  i.book1D("RecoAllAssoc2Gen_NumTracks",
393  "ReconstructedAllAssoc2Gen_NumTracks", 24, &log_ntrk_bins[0]);
394  mes_[label]["RecoAllAssoc2Gen_PU"] =
395  i.book1D("RecoAllAssoc2Gen_PU",
396  "ReconstructedAllAssoc2Gen_PU", 125, 0., 250.);
397  mes_[label]["RecoAllAssoc2Gen_ClosestDistanceZ"] =
398  i.book1D("RecoAllAssoc2Gen_ClosestDistanceZ",
399  "ReconstructedAllAssoc2Gen_ClosestDistanceZ",
400  30, &log_bins[0]);
401  mes_[label]["RecoAllAssoc2GenProperties"] =
402  i.book1D("RecoAllAssoc2GenProperties",
403  "ReconstructedAllAssoc2Gen_Properties", 8, -0.5, 7.5);
404  mes_[label]["RecoAllAssoc2Gen_PairDistanceZ"] =
405  i.book1D("RecoAllAssoc2Gen_PairDistanceZ",
406  "RecoAllAssoc2Gen_PairDistanceZ", 1000, 0, 20);
407 
408  // All Reconstructed Vertices Matched to a Generated vertex. Used
409  // for Fake-Rate plots
410  mes_[label]["RecoAllAssoc2GenMatched_NumVertices"] =
411  i.book1D("RecoAllAssoc2GenMatched_NumVertices",
412  "ReconstructedAllAssoc2GenMatched_NumVertices", 100, 0., 200.);
413  mes_[label]["RecoAllAssoc2GenMatched_X"] =
414  i.book1D("RecoAllAssoc2GenMatched_X",
415  "ReconstructedAllAssoc2GenMatched_X", 120, -0.6, 0.6);
416  mes_[label]["RecoAllAssoc2GenMatched_Y"] =
417  i.book1D("RecoAllAssoc2GenMatched_Y",
418  "ReconstructedAllAssoc2GenMatched_Y", 120, -0.6, 0.6);
419  mes_[label]["RecoAllAssoc2GenMatched_Z"] =
420  i.book1D("RecoAllAssoc2GenMatched_Z",
421  "ReconstructedAllAssoc2GenMatched_Z", 120, -60, 60);
422  mes_[label]["RecoAllAssoc2GenMatched_R"] =
423  i.book1D("RecoAllAssoc2GenMatched_R",
424  "ReconstructedAllAssoc2GenMatched_R", 120, 0, 0.6);
425  mes_[label]["RecoAllAssoc2GenMatched_Pt2"] =
426  i.book1D("RecoAllAssoc2GenMatched_Pt2",
427  "ReconstructedAllAssoc2GenMatched_Sum-pt2",
428  15, &log_pt2_bins[0]);
429  mes_[label]["RecoAllAssoc2GenMatched_Ndof"] =
430  i.book1D("RecoAllAssoc2GenMatched_Ndof",
431  "ReconstructedAllAssoc2GenMatched_Ndof", 120, 0., 240.);
432  mes_[label]["RecoAllAssoc2GenMatched_NumTracks"] =
433  i.book1D("RecoAllAssoc2GenMatched_NumTracks",
434  "ReconstructedAllAssoc2GenMatched_NumTracks", 24, &log_ntrk_bins[0]);
435  mes_[label]["RecoAllAssoc2GenMatched_PU"] =
436  i.book1D("RecoAllAssoc2GenMatched_PU",
437  "ReconstructedAllAssoc2GenMatched_PU", 125, 0., 250.);
438  mes_[label]["RecoAllAssoc2GenMatched_ClosestDistanceZ"] = i.book1D(
439  "RecoAllAssoc2GenMatched_ClosestDistanceZ",
440  "ReconstructedAllAssoc2GenMatched_ClosestDistanceZ", 30, &log_bins[0]);
441 
442  // All Reconstructed Vertices Multi-Matched to a Generated vertex. Used
443  // for Merge-Rate plots
444  mes_[label]["RecoAllAssoc2GenMultiMatched_NumVertices"] = i.book1D(
445  "RecoAllAssoc2GenMultiMatched_NumVertices",
446  "ReconstructedAllAssoc2GenMultiMatched_NumVertices", 100, 0., 200.);
447  mes_[label]["RecoAllAssoc2GenMultiMatched_X"] =
448  i.book1D("RecoAllAssoc2GenMultiMatched_X",
449  "ReconstructedAllAssoc2GenMultiMatched_X", 120, -0.6, 0.6);
450  mes_[label]["RecoAllAssoc2GenMultiMatched_Y"] =
451  i.book1D("RecoAllAssoc2GenMultiMatched_Y",
452  "ReconstructedAllAssoc2GenMultiMatched_Y", 120, -0.6, 0.6);
453  mes_[label]["RecoAllAssoc2GenMultiMatched_Z"] =
454  i.book1D("RecoAllAssoc2GenMultiMatched_Z",
455  "ReconstructedAllAssoc2GenMultiMatched_Z", 120, -60, 60);
456  mes_[label]["RecoAllAssoc2GenMultiMatched_R"] =
457  i.book1D("RecoAllAssoc2GenMultiMatched_R",
458  "ReconstructedAllAssoc2GenMultiMatched_R", 120, 0, 0.6);
459  mes_[label]["RecoAllAssoc2GenMultiMatched_Pt2"] = i.book1D(
460  "RecoAllAssoc2GenMultiMatched_Pt2",
461  "ReconstructedAllAssoc2GenMultiMatched_Sum-pt2", 15, &log_pt2_bins[0]);
462  mes_[label]["RecoAllAssoc2GenMultiMatched_NumTracks"] = i.book1D(
463  "RecoAllAssoc2GenMultiMatched_NumTracks",
464  "ReconstructedAllAssoc2GenMultiMatched_NumTracks", 24, &log_ntrk_bins[0]);
465  mes_[label]["RecoAllAssoc2GenMultiMatched_PU"] =
466  i.book1D("RecoAllAssoc2GenMultiMatched_PU",
467  "ReconstructedAllAssoc2GenMultiMatched_PU", 125, 0., 250.);
468  mes_[label]["RecoAllAssoc2GenMultiMatched_ClosestDistanceZ"] =
469  i.book1D("RecoAllAssoc2GenMultiMatched_ClosestDistanceZ",
470  "ReconstructedAllAssoc2GenMultiMatched_ClosestDistanceZ",
471  log_mergez_bins.size()-1, &log_mergez_bins[0]);
472 
473  // All Reconstructed Vertices Matched to a Multi-Matched Gen
474  // Vertex. Used for Duplicate rate plots done w.r.t. Reco
475  // Quantities. We basically want to ask how many times a RecoVTX
476  // has been reconstructed and associated to a SimulatedVTX that
477  // has been linked to at least another RecoVTX. In this sense this
478  // RecoVTX is a duplicate of the same, real GenVTX.
479  mes_[label]["RecoAllAssoc2MultiMatchedGen_NumVertices"] = i.book1D(
480  "RecoAllAssoc2MultiMatchedGen_NumVertices",
481  "RecoAllAssoc2MultiMatchedGen_NumVertices", 100, 0., 200.);
482  mes_[label]["RecoAllAssoc2MultiMatchedGen_X"] =
483  i.book1D("RecoAllAssoc2MultiMatchedGen_X",
484  "RecoAllAssoc2MultiMatchedGen_X", 120, -0.6, 0.6);
485  mes_[label]["RecoAllAssoc2MultiMatchedGen_Y"] =
486  i.book1D("RecoAllAssoc2MultiMatchedGen_Y",
487  "RecoAllAssoc2MultiMatchedGen_Y", 120, -0.6, 0.6);
488  mes_[label]["RecoAllAssoc2MultiMatchedGen_Z"] =
489  i.book1D("RecoAllAssoc2MultiMatchedGen_Z",
490  "RecoAllAssoc2MultiMatchedGen_Z", 120, -60, 60);
491  mes_[label]["RecoAllAssoc2MultiMatchedGen_R"] =
492  i.book1D("RecoAllAssoc2MultiMatchedGen_R",
493  "RecoAllAssoc2MultiMatchedGen_R", 120, 0, 0.6);
494  mes_[label]["RecoAllAssoc2MultiMatchedGen_Pt2"] =
495  i.book1D("RecoAllAssoc2MultiMatchedGen_Pt2",
496  "RecoAllAssoc2MultiMatchedGen_Sum-pt2", 15, &log_pt2_bins[0]);
497  mes_[label]["RecoAllAssoc2MultiMatchedGen_NumTracks"] =
498  i.book1D("RecoAllAssoc2MultiMatchedGen_NumTracks",
499  "RecoAllAssoc2MultiMatchedGen_NumTracks", 24, &log_ntrk_bins[0]);
500  mes_[label]["RecoAllAssoc2MultiMatchedGen_PU"] =
501  i.book1D("RecoAllAssoc2MultiMatchedGen_PU",
502  "RecoAllAssoc2MultiMatchedGen_PU", 125, 0., 250.);
503  mes_[label]["RecoAllAssoc2MultiMatchedGen_ClosestDistanceZ"] = i.book1D(
504  "RecoAllAssoc2MultiMatchedGen_ClosestDistanceZ",
505  "RecoAllAssoc2MultiMatchedGen_ClosestDistanceZ", 30, &log_bins[0]);
506  mes_[label]["RecoAllAssoc2GenSimForMerge_ClosestDistanceZ"] = i.book1D(
507  "RecoAllAssoc2GenSimForMerge_ClosestDistanceZ",
508  "RecoAllAssoc2GenSimForMerge_ClosestDistanceZ",
509  log_mergez_bins.size()-1, &log_mergez_bins[0]);
510 
511 
512  // Resolution and pull histograms
513  const double resolpt2 = 10;
514 
515  const double minPull = -10;
516  const double maxPull = 10;
517  const double nPull = 100;
518 
519  auto bookResolPull = [&](const std::string& prefix, const double resolx, const double resoly, const double resolz) {
520  book1d((prefix+"_ResolX" ).c_str(), 100,-resolx,resolx);
521  book1d((prefix+"_ResolY" ).c_str(), 100,-resoly,resoly);
522  book1d((prefix+"_ResolZ" ).c_str(), 100,-resolz,resolz);
523  book1d((prefix+"_ResolPt2").c_str(), 100,-resolpt2,resolpt2);
524  book1d((prefix+"_PullX" ).c_str(), 250,-25,25);
525  book1d((prefix+"_PullY" ).c_str(), 250,-25,25);
526  book1d((prefix+"_PullZ" ).c_str(), 250,-25,25);
527 
528  book2d((prefix+"_ResolX_vs_PU" ).c_str(), 125,0.,250., 100,-resolx,resolx);
529  book2d((prefix+"_ResolY_vs_PU" ).c_str(), 125,0.,250., 100,-resoly,resoly);
530  book2d((prefix+"_ResolZ_vs_PU" ).c_str(), 125,0.,250., 100,-resolz,resolz);
531  book2d((prefix+"_ResolPt2_vs_PU").c_str(), 125,0.,250., 100,-resolpt2,resolpt2);
532  book2d((prefix+"_PullX_vs_PU" ).c_str(), 125,0.,250., nPull,minPull,maxPull);
533  book2d((prefix+"_PullY_vs_PU" ).c_str(), 125,0.,250., nPull,minPull,maxPull);
534  book2d((prefix+"_PullZ_vs_PU" ).c_str(), 125,0.,250., nPull,minPull,maxPull);
535 
536  book2dlogx((prefix+"_ResolX_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], 100,-resolx,resolx);
537  book2dlogx((prefix+"_ResolY_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], 100,-resoly,resoly);
538  book2dlogx((prefix+"_ResolZ_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], 100,-resolz,resolz);
539  book2dlogx((prefix+"_ResolPt2_vs_NumTracks").c_str(), 24,&log_ntrk_bins[0], 100,-resolpt2,resolpt2);
540  book2dlogx((prefix+"_PullX_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], nPull,minPull,maxPull);
541  book2dlogx((prefix+"_PullY_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], nPull,minPull,maxPull);
542  book2dlogx((prefix+"_PullZ_vs_NumTracks" ).c_str(), 24,&log_ntrk_bins[0], nPull,minPull,maxPull);
543 
544  book2d((prefix+"_ResolX_vs_Z" ).c_str(), 120,-60,60, 100,-resolx,resolx);
545  book2d((prefix+"_ResolY_vs_Z" ).c_str(), 120,-60,60, 100,-resoly,resoly);
546  book2d((prefix+"_ResolZ_vs_Z" ).c_str(), 120,-60,60, 100,-resolz,resolz);
547  book2d((prefix+"_ResolPt2_vs_Z").c_str(), 120,-60,60, 100,-resolpt2,resolpt2);
548  book2d((prefix+"_PullX_vs_Z" ).c_str(), 120,-60,60, nPull,minPull,maxPull);
549  book2d((prefix+"_PullY_vs_Z" ).c_str(), 120,-60,60, nPull,minPull,maxPull);
550  book2d((prefix+"_PullZ_vs_Z" ).c_str(), 120,-60,60, nPull,minPull,maxPull);
551 
552  book2dlogx((prefix+"_ResolX_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], 100,-resolx,resolx);
553  book2dlogx((prefix+"_ResolY_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], 100,-resoly,resoly);
554  book2dlogx((prefix+"_ResolZ_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], 100,-resolz,resolz);
555  book2dlogx((prefix+"_ResolPt2_vs_Pt").c_str(), log_pt_bins.size()-1,&log_pt_bins[0], 100,-resolpt2,resolpt2);
556  book2dlogx((prefix+"_PullX_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], nPull,minPull,maxPull);
557  book2dlogx((prefix+"_PullY_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], nPull,minPull,maxPull);
558  book2dlogx((prefix+"_PullZ_vs_Pt" ).c_str(), log_pt_bins.size()-1,&log_pt_bins[0], nPull,minPull,maxPull);
559  };
560 
561  bookResolPull("RecoAllAssoc2GenMatched" , 0.1 , 0.1 , 0.1 ); // Non-merged vertices
562  bookResolPull("RecoAllAssoc2GenMatchedMerged", 0.1 , 0.1 , 0.1 ); // Merged vertices
563  bookResolPull("RecoPVAssoc2GenPVMatched" , 0.01, 0.01, 0.01); // PV, when correctly matched, regardless if merged or not
564 
565  // Purity histograms
566  // Reco PV (vtx0) matched to hard-scatter gen vertex
567  book1d("RecoPVAssoc2GenPVMatched_Purity", 50, 0, 1);
568  book1d("RecoPVAssoc2GenPVMatched_Missing", 50, 0, 1);
569  book2d("RecoPVAssoc2GenPVMatched_Purity_vs_Index", 100,0,100, 50,0,1);
570 
571  // RECO PV (vtx0) not matched to hard-scatter gen vertex
572  book1d("RecoPVAssoc2GenPVNotMatched_Purity", 50, 0, 1);
573  book1d("RecoPVAssoc2GenPVNotMatched_Missing", 50, 0, 1);
574  book2d("RecoPVAssoc2GenPVNotMatched_Purity_vs_Index", 100,0,100, 50,0,1);
575 
576  // Purity vs. fake rate
577  book1d("RecoAllAssoc2Gen_Purity", 50, 0, 1); // denominator
578  book1d("RecoAllAssoc2GenMatched_Purity", 50, 0, 1); // 1-numerator
579 
580  // Vertex sum(pt2)
581  // The first two are orthogonal (i.e. their sum includes all reco vertices)
582  book1dlogx("RecoAssoc2GenPVMatched_Pt2", 15, &log_pt2_bins[0]);
583  book1dlogx("RecoAssoc2GenPVNotMatched_Pt2", 15, &log_pt2_bins[0]);
584 
585  book1dlogx("RecoAssoc2GenPVMatchedNotHighest_Pt2", 15, &log_pt2_bins[0]);
586  book1dlogx("RecoAssoc2GenPVNotMatched_GenPVTracksRemoved_Pt2", 15, &log_pt2_bins[0]);
587 
588  // Shared tracks
589  book1d("RecoAllAssoc2GenSingleMatched_SharedTrackFractionReco", 50, 0, 1);
590  book1d("RecoAllAssoc2GenMultiMatched_SharedTrackFractionReco", 50, 0, 1);
591  book1d("RecoAllAssoc2GenSingleMatched_SharedTrackFractionRecoMatched", 50, 0, 1);
592  book1d("RecoAllAssoc2GenMultiMatched_SharedTrackFractionRecoMatched", 50, 0, 1);
593 
594  book1d("RecoAllAssoc2GenSingleMatched_SharedTrackFractionSim", 50, 0, 1);
595  book1d("RecoAllAssoc2GenMultiMatched_SharedTrackFractionSim", 50, 0, 1);
596  book1d("RecoAllAssoc2GenSingleMatched_SharedTrackFractionSimMatched", 50, 0, 1);
597  book1d("RecoAllAssoc2GenMultiMatched_SharedTrackFractionSimMatched", 50, 0, 1);
598  }
599 }
600 
602  const simPrimaryVertex& v) {
603  if (v.eventId.event() == 0) {
604  mes_["root_folder"]["GenPV_X"]->Fill(v.x);
605  mes_["root_folder"]["GenPV_Y"]->Fill(v.y);
606  mes_["root_folder"]["GenPV_Z"]->Fill(v.z);
607  mes_["root_folder"]["GenPV_R"]->Fill(v.r);
608  mes_["root_folder"]["GenPV_Pt2"]->Fill(v.ptsq);
609  mes_["root_folder"]["GenPV_NumTracks"]->Fill(v.nGenTrk);
610  if (v.closest_vertex_distance_z > 0.)
611  mes_["root_folder"]["GenPV_ClosestDistanceZ"]
612  ->Fill(v.closest_vertex_distance_z);
613  }
614  mes_["root_folder"]["GenAllV_X"]->Fill(v.x);
615  mes_["root_folder"]["GenAllV_Y"]->Fill(v.y);
616  mes_["root_folder"]["GenAllV_Z"]->Fill(v.z);
617  mes_["root_folder"]["GenAllV_R"]->Fill(v.r);
618  mes_["root_folder"]["GenAllV_Pt2"]->Fill(v.ptsq);
619  mes_["root_folder"]["GenAllV_NumTracks"]->Fill(v.nGenTrk);
620  if (v.closest_vertex_distance_z > 0.)
621  mes_["root_folder"]["GenAllV_ClosestDistanceZ"]
622  ->Fill(v.closest_vertex_distance_z);
623 }
624 
626  const std::string& label,
628  mes_[label]["GenAllAssoc2Reco_X"]->Fill(v.x);
629  mes_[label]["GenAllAssoc2Reco_Y"]->Fill(v.y);
630  mes_[label]["GenAllAssoc2Reco_Z"]->Fill(v.z);
631  mes_[label]["GenAllAssoc2Reco_R"]->Fill(v.r);
632  mes_[label]["GenAllAssoc2Reco_Pt2"]->Fill(v.ptsq);
633  mes_[label]["GenAllAssoc2Reco_NumTracks"]->Fill(v.nGenTrk);
634  if (v.closest_vertex_distance_z > 0.)
635  mes_[label]["GenAllAssoc2Reco_ClosestDistanceZ"]
636  ->Fill(v.closest_vertex_distance_z);
637  if (v.rec_vertices.size()) {
638  mes_[label]["GenAllAssoc2RecoMatched_X"]->Fill(v.x);
639  mes_[label]["GenAllAssoc2RecoMatched_Y"]->Fill(v.y);
640  mes_[label]["GenAllAssoc2RecoMatched_Z"]->Fill(v.z);
641  mes_[label]["GenAllAssoc2RecoMatched_R"]->Fill(v.r);
642  mes_[label]["GenAllAssoc2RecoMatched_Pt2"]->Fill(v.ptsq);
643  mes_[label]["GenAllAssoc2RecoMatched_NumTracks"]->Fill(v.nGenTrk);
644  if (v.closest_vertex_distance_z > 0.)
645  mes_[label]["GenAllAssoc2RecoMatched_ClosestDistanceZ"]
646  ->Fill(v.closest_vertex_distance_z);
647  }
648  if (v.rec_vertices.size() > 1) {
649  mes_[label]["GenAllAssoc2RecoMultiMatched_X"]->Fill(v.x);
650  mes_[label]["GenAllAssoc2RecoMultiMatched_Y"]->Fill(v.y);
651  mes_[label]["GenAllAssoc2RecoMultiMatched_Z"]->Fill(v.z);
652  mes_[label]["GenAllAssoc2RecoMultiMatched_R"]->Fill(v.r);
653  mes_[label]["GenAllAssoc2RecoMultiMatched_Pt2"]->Fill(v.ptsq);
654  mes_[label]["GenAllAssoc2RecoMultiMatched_NumTracks"]->Fill(v.nGenTrk);
655  if (v.closest_vertex_distance_z > 0.)
656  mes_[label]["GenAllAssoc2RecoMultiMatched_ClosestDistanceZ"]
657  ->Fill(v.closest_vertex_distance_z);
658  }
659 }
660 
662  const std::string& label,
664  bool genPVMatchedToRecoPV) {
665  mes_[label]["GenPVAssoc2RecoPV_X"]->Fill(v.x);
666  mes_[label]["GenPVAssoc2RecoPV_Y"]->Fill(v.y);
667  mes_[label]["GenPVAssoc2RecoPV_Z"]->Fill(v.z);
668  if (genPVMatchedToRecoPV) {
669  mes_[label]["GenPVAssoc2RecoPVMatched_X"]->Fill(v.x);
670  mes_[label]["GenPVAssoc2RecoPVMatched_Y"]->Fill(v.y);
671  mes_[label]["GenPVAssoc2RecoPVMatched_Z"]->Fill(v.z);
672  }
673 }
674 
676  const std::string& label,
677  int num_pileup_vertices,
679  mes_[label]["RecoAllAssoc2Gen_X"]->Fill(v.x);
680  mes_[label]["RecoAllAssoc2Gen_Y"]->Fill(v.y);
681  mes_[label]["RecoAllAssoc2Gen_Z"]->Fill(v.z);
682  mes_[label]["RecoAllAssoc2Gen_R"]->Fill(v.r);
683  mes_[label]["RecoAllAssoc2Gen_Pt2"]->Fill(v.ptsq);
684  mes_[label]["RecoAllAssoc2Gen_Ndof"]->Fill(v.recVtx->ndof());
685  mes_[label]["RecoAllAssoc2Gen_NumTracks"]->Fill(v.nRecoTrk);
686  mes_[label]["RecoAllAssoc2Gen_PU"]->Fill(num_pileup_vertices);
687  mes_[label]["RecoAllAssoc2Gen_Purity"]->Fill(v.purity);
688  if (v.closest_vertex_distance_z > 0.)
689  mes_[label]["RecoAllAssoc2Gen_ClosestDistanceZ"]
690  ->Fill(v.closest_vertex_distance_z);
691  if (v.sim_vertices.size()) {
693  mes_[label]["RecoAllAssoc2GenMatched_X"]->Fill(v.x);
694  mes_[label]["RecoAllAssoc2GenMatched_Y"]->Fill(v.y);
695  mes_[label]["RecoAllAssoc2GenMatched_Z"]->Fill(v.z);
696  mes_[label]["RecoAllAssoc2GenMatched_R"]->Fill(v.r);
697  mes_[label]["RecoAllAssoc2GenMatched_Pt2"]->Fill(v.ptsq);
698  mes_[label]["RecoAllAssoc2GenMatched_Ndof"]->Fill(v.recVtx->ndof());
699  mes_[label]["RecoAllAssoc2GenMatched_NumTracks"]->Fill(v.nRecoTrk);
700  mes_[label]["RecoAllAssoc2GenMatched_PU"]->Fill(num_pileup_vertices);
701  mes_[label]["RecoAllAssoc2GenMatched_Purity"]->Fill(v.purity);
702  if (v.closest_vertex_distance_z > 0.)
703  mes_[label]["RecoAllAssoc2GenMatched_ClosestDistanceZ"]
704  ->Fill(v.closest_vertex_distance_z);
705 
706  // Fill resolution and pull plots here (as in MultiTrackValidator)
707  fillResolutionAndPullHistograms(label, num_pileup_vertices, v, false);
708 
709  // Now keep track of all RecoVTX associated to a SimVTX that
710  // itself is associated to more than one RecoVTX, for
711  // duplicate-rate plots on reco quantities.
712  if (v.sim_vertices_internal[0]->rec_vertices.size() > 1) {
714  mes_[label]["RecoAllAssoc2MultiMatchedGen_X"]->Fill(v.x);
715  mes_[label]["RecoAllAssoc2MultiMatchedGen_Y"]->Fill(v.y);
716  mes_[label]["RecoAllAssoc2MultiMatchedGen_Z"]->Fill(v.z);
717  mes_[label]["RecoAllAssoc2MultiMatchedGen_R"]->Fill(v.r);
718  mes_[label]["RecoAllAssoc2MultiMatchedGen_Pt2"]->Fill(v.ptsq);
719  mes_[label]["RecoAllAssoc2MultiMatchedGen_NumTracks"]->Fill(v.nRecoTrk);
720  mes_[label]["RecoAllAssoc2MultiMatchedGen_PU"]->Fill(num_pileup_vertices);
721  if (v.closest_vertex_distance_z > 0.)
722  mes_[label]["RecoAllAssoc2MultiMatchedGen_ClosestDistanceZ"]
723  ->Fill(v.closest_vertex_distance_z);
724  }
725  // This is meant to be used as "denominator" for the merge-rate
726  // plots produced starting from reco quantities. We enter here
727  // only if the reco vertex has been associated, since we need info
728  // from the SimVTX associated to it. In this regard, the final
729  // merge-rate plot coming from reco is not to be intended as a
730  // pure efficiency-like plot, since the normalization is biased.
731  if (v.sim_vertices_internal[0]->closest_vertex_distance_z > 0.)
732  mes_[label]["RecoAllAssoc2GenSimForMerge_ClosestDistanceZ"]
733  ->Fill(v.sim_vertices_internal[0]->closest_vertex_distance_z);
734  }
735  // this plots are meant to be used to compute the merge rate
736  if (v.sim_vertices.size() > 1) {
738  mes_[label]["RecoAllAssoc2GenMultiMatched_X"]->Fill(v.x);
739  mes_[label]["RecoAllAssoc2GenMultiMatched_Y"]->Fill(v.y);
740  mes_[label]["RecoAllAssoc2GenMultiMatched_Z"]->Fill(v.z);
741  mes_[label]["RecoAllAssoc2GenMultiMatched_R"]->Fill(v.r);
742  mes_[label]["RecoAllAssoc2GenMultiMatched_Pt2"]->Fill(v.ptsq);
743  mes_[label]["RecoAllAssoc2GenMultiMatched_NumTracks"]->Fill(v.nRecoTrk);
744  mes_[label]["RecoAllAssoc2GenMultiMatched_PU"]->Fill(num_pileup_vertices);
745  if (v.sim_vertices_internal[0]->closest_vertex_distance_z > 0.)
746  mes_[label]["RecoAllAssoc2GenMultiMatched_ClosestDistanceZ"]
747  ->Fill(v.sim_vertices_internal[0]->closest_vertex_distance_z);
748  }
749  mes_[label]["RecoAllAssoc2GenProperties"]->Fill(v.kind_of_vertex);
750 
751 
753  if(v.sim_vertices.size() == 1) {
754  prefix = "RecoAllAssoc2GenSingleMatched_SharedTrackFraction";
755  }
756  else if(v.sim_vertices.size() > 1) {
757  prefix = "RecoAllAssoc2GenMultiMatched_SharedTrackFraction";
758  }
759 
760  for(size_t i=0; i<v.sim_vertices.size(); ++i) {
761  const double sharedTracks = v.sim_vertices_num_shared_tracks[i];
762  const simPrimaryVertex *simV = v.sim_vertices_internal[i];
763  mes_[label][prefix+"Reco"]->Fill(sharedTracks/v.nRecoTrk);
764  mes_[label][prefix+"RecoMatched"]->Fill(sharedTracks/v.num_matched_sim_tracks);
765  mes_[label][prefix+"Sim"]->Fill(sharedTracks/simV->nGenTrk);
766  mes_[label][prefix+"SimMatched"]->Fill(sharedTracks/simV->num_matched_reco_tracks);
767  }
768 }
769 
771  const std::string& label,
772  int num_pileup_vertices,
774  bool isPV) {
775 
776  std::string prefix = "RecoAllAssoc2GenMatched";
777  if(v.sim_vertices_internal.size() > 1) {
778  prefix += "Merged";
779  }
780  if(isPV) {
781  prefix = "RecoPVAssoc2GenPVMatched";
782  }
783 
784  // Use the best match as defined by the vertex truth associator
785  // reco-tracks as the best match
787  const double xres = v.x - bestMatch.x;
788  const double yres = v.y - bestMatch.y;
789  const double zres = v.z - bestMatch.z;
790  const double pt2res = v.ptsq - bestMatch.ptsq;
791 
792  const double xresol = xres;
793  const double yresol = yres;
794  const double zresol = zres;
795  const double pt2resol = pt2res/v.ptsq;
796  const double xpull = xres/v.recVtx->xError();
797  const double ypull = yres/v.recVtx->yError();
798  const double zpull = zres/v.recVtx->zError();
799 
800  mes_[label][prefix+"_ResolX"]->Fill(xresol);
801  mes_[label][prefix+"_ResolY"]->Fill(yresol);
802  mes_[label][prefix+"_ResolZ"]->Fill(zresol);
803  mes_[label][prefix+"_ResolPt2"]->Fill(pt2resol);
804  mes_[label][prefix+"_PullX"]->Fill(xpull);
805  mes_[label][prefix+"_PullY"]->Fill(ypull);
806  mes_[label][prefix+"_PullZ"]->Fill(zpull);
807 
808  mes_[label][prefix+"_ResolX_vs_PU"]->Fill(num_pileup_vertices, xresol);
809  mes_[label][prefix+"_ResolY_vs_PU"]->Fill(num_pileup_vertices, yresol);
810  mes_[label][prefix+"_ResolZ_vs_PU"]->Fill(num_pileup_vertices, zresol);
811  mes_[label][prefix+"_ResolPt2_vs_PU"]->Fill(num_pileup_vertices, pt2resol);
812  mes_[label][prefix+"_PullX_vs_PU"]->Fill(num_pileup_vertices, xpull);
813  mes_[label][prefix+"_PullY_vs_PU"]->Fill(num_pileup_vertices, ypull);
814  mes_[label][prefix+"_PullZ_vs_PU"]->Fill(num_pileup_vertices, zpull);
815 
816  mes_[label][prefix+"_ResolX_vs_NumTracks"]->Fill(v.nRecoTrk, xresol);
817  mes_[label][prefix+"_ResolY_vs_NumTracks"]->Fill(v.nRecoTrk, yresol);
818  mes_[label][prefix+"_ResolZ_vs_NumTracks"]->Fill(v.nRecoTrk, zresol);
819  mes_[label][prefix+"_ResolPt2_vs_NumTracks"]->Fill(v.nRecoTrk, pt2resol);
820  mes_[label][prefix+"_PullX_vs_NumTracks"]->Fill(v.nRecoTrk, xpull);
821  mes_[label][prefix+"_PullY_vs_NumTracks"]->Fill(v.nRecoTrk, ypull);
822  mes_[label][prefix+"_PullZ_vs_NumTracks"]->Fill(v.nRecoTrk, zpull);
823 
824  mes_[label][prefix+"_ResolX_vs_Z"]->Fill(v.z, xresol);
825  mes_[label][prefix+"_ResolY_vs_Z"]->Fill(v.z, yresol);
826  mes_[label][prefix+"_ResolZ_vs_Z"]->Fill(v.z, zresol);
827  mes_[label][prefix+"_ResolPt2_vs_Z"]->Fill(v.z, pt2resol);
828  mes_[label][prefix+"_PullX_vs_Z"]->Fill(v.z, xpull);
829  mes_[label][prefix+"_PullY_vs_Z"]->Fill(v.z, ypull);
830  mes_[label][prefix+"_PullZ_vs_Z"]->Fill(v.z, zpull);
831 
832  mes_[label][prefix+"_ResolX_vs_Pt"]->Fill(v.pt, xresol);
833  mes_[label][prefix+"_ResolY_vs_Pt"]->Fill(v.pt, yresol);
834  mes_[label][prefix+"_ResolZ_vs_Pt"]->Fill(v.pt, zresol);
835  mes_[label][prefix+"_ResolPt2_vs_Pt"]->Fill(v.pt, pt2resol);
836  mes_[label][prefix+"_PullX_vs_Pt"]->Fill(v.pt, xpull);
837  mes_[label][prefix+"_PullY_vs_Pt"]->Fill(v.pt, ypull);
838  mes_[label][prefix+"_PullZ_vs_Pt"]->Fill(v.pt, zpull);
839 }
840 
842  auto found = r2s_->find(recoTrack);
843 
844  // reco track not matched to any TP
845  if(found == r2s_->end())
846  return false;
847 
848  // reco track matched to some TP from signal vertex
849  for(const auto& tp: found->val) {
850  if(tp.first->eventId().bunchCrossing() == 0 && tp.first->eventId().event() == 0)
851  return true;
852  }
853 
854  // reco track not matched to any TP from signal vertex
855  return false;
856 }
857 
859  const std::string& label,
860  std::vector<recoPrimaryVertex>& recopvs,
861  int genpv_position_in_reco_collection,
862  bool signal_is_highest_pt) {
863  if(recopvs.empty()) return;
864 
865  std::vector<double> vtx_sumpt_sigmatched;
866  std::vector<double> vtx_sumpt2_sigmatched;
867 
868  vtx_sumpt_sigmatched.reserve(recopvs.size());
869  vtx_sumpt2_sigmatched.reserve(recopvs.size());
870 
871  // Calculate purity
872  for(auto& v: recopvs) {
873  double sumpt_all = 0;
874  double sumpt_sigmatched = 0;
875  double sumpt2_sigmatched = 0;
876  const reco::Vertex *vertex = v.recVtx;
877  for(auto iTrack = vertex->tracks_begin(); iTrack != vertex->tracks_end(); ++iTrack) {
878  double pt = (*iTrack)->pt();
879  sumpt_all += pt;
880  if(matchRecoTrack2SimSignal(*iTrack)) {
881  sumpt_sigmatched += pt;
882  sumpt2_sigmatched += pt*pt;
883  }
884  }
885  v.purity = sumpt_sigmatched / sumpt_all;
886 
887  vtx_sumpt_sigmatched.push_back(sumpt_sigmatched);
888  vtx_sumpt2_sigmatched.push_back(sumpt2_sigmatched);
889  }
890 
891  const double vtxAll_sumpt_sigmatched = std::accumulate(vtx_sumpt_sigmatched.begin(), vtx_sumpt_sigmatched.end(), 0.0);
892  const double vtxNot0_sumpt_sigmatched = vtxAll_sumpt_sigmatched - vtx_sumpt_sigmatched[0];
893  const double missing = vtxNot0_sumpt_sigmatched / vtxAll_sumpt_sigmatched;
894 
895  // Fill purity
896  std::string prefix = "RecoPVAssoc2GenPVNotMatched_";
897  if(genpv_position_in_reco_collection == 0)
898  prefix = "RecoPVAssoc2GenPVMatched_";
899 
900  mes_[label][prefix+"Purity"]->Fill(recopvs[0].purity);
901  mes_[label][prefix+"Missing"]->Fill(missing);
902  auto hpurity = mes_[label][prefix+"Purity_vs_Index"];
903  for(size_t i=0; i<recopvs.size(); ++i) {
904  hpurity->Fill(i, recopvs[i].purity);
905  }
906 
907  // Fill sumpt2
908  for(size_t i=0; i<recopvs.size(); ++i) {
909  if(static_cast<int>(i) == genpv_position_in_reco_collection) {
910  mes_[label]["RecoAssoc2GenPVMatched_Pt2"]->Fill(recopvs[i].ptsq);
911  }
912  else {
913  double pt2 = recopvs[i].ptsq;
914  mes_[label]["RecoAssoc2GenPVNotMatched_Pt2"]->Fill(pt2);
915  // Subtract hard-scatter track pt2 from the pileup pt2
916  double pt2_pu = pt2-vtx_sumpt2_sigmatched[i];
917  mes_[label]["RecoAssoc2GenPVNotMatched_GenPVTracksRemoved_Pt2"]->Fill(pt2_pu);
918  }
919  }
920  if(!signal_is_highest_pt && genpv_position_in_reco_collection >= 0)
921  mes_[label]["RecoAssoc2GenPVMatchedNotHighest_Pt2"]->Fill(recopvs[genpv_position_in_reco_collection].ptsq);
922 }
923 
924 /* Extract information form TrackingParticles/TrackingVertex and fill
925  * the helper class simPrimaryVertex with proper generation-level
926  * information */
927 std::vector<PrimaryVertexAnalyzer4PUSlimmed::simPrimaryVertex>
930  std::vector<PrimaryVertexAnalyzer4PUSlimmed::simPrimaryVertex> simpv;
931  int current_event = -1;
932 
933  if (verbose_) {
934  std::cout << "getSimPVs TrackingVertexCollection " << std::endl;
935  }
936 
937  for (TrackingVertexCollection::const_iterator v = tVC->begin();
938  v != tVC->end(); ++v) {
939  if (verbose_) {
940  std::cout << "BunchX.EventId: " << v->eventId().bunchCrossing() << "."
941  << (v->eventId()).event() << " Position: " << v->position()
942  << " G4/HepMC Vertices: " << v->g4Vertices().size() << "/"
943  << v->genVertices().size()
944  << " t = " << v->position().t() * 1.e12
945  << " == 0:" << (v->position().t() > 0) << std::endl;
946  for (TrackingVertex::g4v_iterator gv = v->g4Vertices_begin();
947  gv != v->g4Vertices_end(); gv++) {
948  std::cout << *gv << std::endl;
949  }
950  std::cout << "----------" << std::endl;
951 
952  } // end of verbose_ session
953 
954  // I'd rather change this and select only vertices that come from
955  // BX=0. We should keep only the first vertex from all the events
956  // at BX=0.
957  if (v->eventId().bunchCrossing() != 0) continue;
958  if (v->eventId().event() != current_event) {
959  current_event = v->eventId().event();
960  } else {
961  continue;
962  }
963  // TODO(rovere) is this really necessary?
964  if (fabs(v->position().z()) > 1000) continue; // skip funny junk vertices
965 
966  // could be a new vertex, check all primaries found so far to avoid
967  // multiple entries
968  simPrimaryVertex sv(v->position().x(), v->position().y(),
969  v->position().z());
970  sv.eventId = v->eventId();
971  sv.sim_vertex = TrackingVertexRef(tVC, std::distance(tVC->begin(), v));
972 
973  for (TrackingParticleRefVector::iterator iTrack = v->daughterTracks_begin();
974  iTrack != v->daughterTracks_end(); ++iTrack) {
975  // TODO(rovere) isn't it always the case? Is it really worth
976  // checking this out?
977  // sv.eventId = (**iTrack).eventId();
978  assert((**iTrack).eventId().bunchCrossing() == 0);
979  }
980  // TODO(rovere) maybe get rid of this old logic completely ... ?
981  simPrimaryVertex* vp = NULL; // will become non-NULL if a vertex
982  // is found and then point to it
983  for (std::vector<simPrimaryVertex>::iterator v0 = simpv.begin();
984  v0 != simpv.end(); v0++) {
985  if ((sv.eventId == v0->eventId) && (fabs(sv.x - v0->x) < 1e-5) &&
986  (fabs(sv.y - v0->y) < 1e-5) && (fabs(sv.z - v0->z) < 1e-5)) {
987  vp = &(*v0);
988  break;
989  }
990  }
991  if (!vp) {
992  // this is a new vertex, add it to the list of sim-vertices
993  simpv.push_back(sv);
994  vp = &simpv.back();
995  if (verbose_) {
996  std::cout << "this is a new vertex " << sv.eventId.event() << " "
997  << sv.x << " " << sv.y << " " << sv.z << std::endl;
998  }
999  } else {
1000  if (verbose_) {
1001  std::cout << "this is not a new vertex" << sv.x << " " << sv.y << " "
1002  << sv.z << std::endl;
1003  }
1004  }
1005 
1006  // Loop over daughter track(s) as Tracking Particles
1007  for (TrackingVertex::tp_iterator iTP = v->daughterTracks_begin();
1008  iTP != v->daughterTracks_end(); ++iTP) {
1009  auto momentum = (*(*iTP)).momentum();
1010  const reco::Track* matched_best_reco_track = nullptr;
1011  double match_quality = -1;
1012  if (use_only_charged_tracks_ && (**iTP).charge() == 0)
1013  continue;
1014  if (s2r_->find(*iTP) != s2r_->end()) {
1015  matched_best_reco_track = (*s2r_)[*iTP][0].first.get();
1016  match_quality = (*s2r_)[*iTP][0].second;
1017  }
1018  if (verbose_) {
1019  std::cout << " Daughter momentum: " << momentum;
1020  std::cout << " Daughter type " << (*(*iTP)).pdgId();
1021  std::cout << " matched: " << (matched_best_reco_track != nullptr);
1022  std::cout << " match-quality: " << match_quality;
1023  std::cout << std::endl;
1024  }
1025  vp->ptot.setPx(vp->ptot.x() + momentum.x());
1026  vp->ptot.setPy(vp->ptot.y() + momentum.y());
1027  vp->ptot.setPz(vp->ptot.z() + momentum.z());
1028  vp->ptot.setE(vp->ptot.e() + (**iTP).energy());
1029  vp->ptsq += ((**iTP).pt() * (**iTP).pt());
1030  // TODO(rovere) only select charged sim-particles? If so, maybe
1031  // put it as a configuration parameter?
1032  if (matched_best_reco_track) {
1033  vp->num_matched_reco_tracks++;
1034  vp->average_match_quality += match_quality;
1035  }
1036  // TODO(rovere) get rid of cuts on sim-tracks
1037  // TODO(rovere) be consistent between simulated tracks and
1038  // reconstructed tracks selection
1039  // count relevant particles
1040  if (((**iTP).pt() > 0.2) && (fabs((**iTP).eta()) < 2.5) &&
1041  (**iTP).charge() != 0) {
1042  vp->nGenTrk++;
1043  }
1044  } // End of for loop on daughters sim-particles
1045  if (vp->num_matched_reco_tracks)
1046  vp->average_match_quality /=
1047  static_cast<float>(vp->num_matched_reco_tracks);
1048  if (verbose_) {
1049  std::cout << "average number of associated tracks: "
1050  << vp->num_matched_reco_tracks / static_cast<float>(vp->nGenTrk)
1051  << " with average quality: " << vp->average_match_quality
1052  << std::endl;
1053  }
1054  } // End of for loop on tracking vertices
1055 
1056  if (verbose_) {
1057  std::cout << "------- PrimaryVertexAnalyzer4PUSlimmed simPVs from "
1058  "TrackingVertices "
1059  "-------" << std::endl;
1060  for (std::vector<simPrimaryVertex>::iterator v0 = simpv.begin();
1061  v0 != simpv.end(); v0++) {
1062  std::cout << "z=" << v0->z << " event=" << v0->eventId.event()
1063  << std::endl;
1064  }
1065  std::cout << "-----------------------------------------------" << std::endl;
1066  } // End of for summary on discovered simulated primary vertices.
1067 
1068  // In case of no simulated vertices, break here
1069  if(simpv.empty())
1070  return simpv;
1071 
1072  // Now compute the closest distance in z between all simulated vertex
1073  // first initialize
1074  auto prev_z = simpv.back().z;
1075  for(simPrimaryVertex& vsim: simpv) {
1076  vsim.closest_vertex_distance_z = std::abs(vsim.z - prev_z);
1077  prev_z = vsim.z;
1078  }
1079  // then calculate
1080  for (std::vector<simPrimaryVertex>::iterator vsim = simpv.begin();
1081  vsim != simpv.end(); vsim++) {
1082  std::vector<simPrimaryVertex>::iterator vsim2 = vsim;
1083  vsim2++;
1084  for (; vsim2 != simpv.end(); vsim2++) {
1085  double distance = std::abs(vsim->z - vsim2->z);
1086  // need both to be complete
1087  vsim->closest_vertex_distance_z = std::min(vsim->closest_vertex_distance_z, distance);
1088  vsim2->closest_vertex_distance_z = std::min(vsim2->closest_vertex_distance_z, distance);
1089  }
1090  }
1091  return simpv;
1092 }
1093 
1094 /* Extract information form recoVertex and fill the helper class
1095  * recoPrimaryVertex with proper reco-level information */
1096 std::vector<PrimaryVertexAnalyzer4PUSlimmed::recoPrimaryVertex>
1098  const edm::Handle<edm::View<reco::Vertex>>& tVC) {
1099  std::vector<PrimaryVertexAnalyzer4PUSlimmed::recoPrimaryVertex> recopv;
1100 
1101  if (verbose_) {
1102  std::cout << "getRecoPVs TrackingVertexCollection " << std::endl;
1103  }
1104 
1105  for (auto v = tVC->begin(); v != tVC->end(); ++v) {
1106  if (verbose_) {
1107  std::cout << " Position: " << v->position() << std::endl;
1108  }
1109 
1110  // Skip junk vertices
1111  if (fabs(v->z()) > 1000) continue;
1112  if (v->isFake() || !v->isValid()) continue;
1113 
1114  recoPrimaryVertex sv(v->position().x(), v->position().y(),
1115  v->position().z());
1116  sv.recVtx = &(*v);
1117  sv.recVtxRef = reco::VertexBaseRef(tVC, std::distance(tVC->begin(), v));
1118  // this is a new vertex, add it to the list of reco-vertices
1119  recopv.push_back(sv);
1121 
1122  // Loop over daughter track(s)
1123  for (auto iTrack = v->tracks_begin(); iTrack != v->tracks_end(); ++iTrack) {
1124  auto momentum = (*(*iTrack)).innerMomentum();
1125  // TODO(rovere) better handle the pixelVertices, whose tracks
1126  // do not have the innerMomentum defined. This is a temporary
1127  // hack to overcome this problem.
1128  if (momentum.mag2() == 0)
1129  momentum = (*(*iTrack)).momentum();
1130  if (verbose_) {
1131  std::cout << " Daughter momentum: " << momentum;
1132  std::cout << std::endl;
1133  }
1134  vp->pt += std::sqrt(momentum.perp2());
1135  vp->ptsq += (momentum.perp2());
1136  vp->nRecoTrk++;
1137 
1138  auto matched = r2s_->find(*iTrack);
1139  if(matched != r2s_->end()) {
1140  vp->num_matched_sim_tracks++;
1141  }
1142 
1143  } // End of for loop on daughters reconstructed tracks
1144  } // End of for loop on tracking vertices
1145 
1146  if (verbose_) {
1147  std::cout << "------- PrimaryVertexAnalyzer4PUSlimmed recoPVs from "
1148  "VertexCollection "
1149  "-------" << std::endl;
1150  for (std::vector<recoPrimaryVertex>::iterator v0 = recopv.begin();
1151  v0 != recopv.end(); v0++) {
1152  std::cout << "z=" << v0->z << std::endl;
1153  }
1154  std::cout << "-----------------------------------------------" << std::endl;
1155  } // End of for summary on reconstructed primary vertices.
1156 
1157  // In case of no reco vertices, break here
1158  if(recopv.empty())
1159  return recopv;
1160 
1161  // Now compute the closest distance in z between all reconstructed vertex
1162  // first initialize
1163  auto prev_z = recopv.back().z;
1164  for(recoPrimaryVertex& vreco: recopv) {
1165  vreco.closest_vertex_distance_z = std::abs(vreco.z - prev_z);
1166  prev_z = vreco.z;
1167  }
1168  for (std::vector<recoPrimaryVertex>::iterator vreco = recopv.begin();
1169  vreco != recopv.end(); vreco++) {
1170  std::vector<recoPrimaryVertex>::iterator vreco2 = vreco;
1171  vreco2++;
1172  for (; vreco2 != recopv.end(); vreco2++) {
1173  double distance = std::abs(vreco->z - vreco2->z);
1174  // need both to be complete
1175  vreco->closest_vertex_distance_z = std::min(vreco->closest_vertex_distance_z, distance);
1176  vreco2->closest_vertex_distance_z = std::min(vreco2->closest_vertex_distance_z, distance);
1177  }
1178  }
1179  return recopv;
1180 }
1181 
1183  std::vector<simPrimaryVertex> & simpv) {
1184  for (auto & v : simpv) {
1185  v.rec_vertices.clear();
1186  }
1187 }
1188 
1189 // ------------ method called to produce the data ------------
1191  std::vector<simPrimaryVertex>& simpv,
1192  const reco::VertexSimToRecoCollection& vertex_s2r) {
1193  if (verbose_) {
1194  std::cout << "PrimaryVertexAnalyzer4PUSlimmed::matchSim2RecoVertices " << std::endl;
1195  }
1196  for (std::vector<simPrimaryVertex>::iterator vsim = simpv.begin();
1197  vsim != simpv.end(); vsim++) {
1198 
1199  auto matched = vertex_s2r.find(vsim->sim_vertex);
1200  if(matched != vertex_s2r.end()) {
1201  for(const auto vertexRefQuality: matched->val) {
1202  vsim->rec_vertices.push_back(&(*(vertexRefQuality.first)));
1203  }
1204  }
1205 
1206  if (verbose_) {
1207  if (vsim->rec_vertices.size()) {
1208  for (auto const& v : vsim->rec_vertices) {
1209  std::cout << "Found a matching vertex for genVtx "
1210  << vsim->z << " at " << v->z()
1211  << " with sign: " << fabs(v->z() - vsim->z) / v->zError()
1212  << std::endl;
1213  }
1214  } else {
1215  std::cout << "No matching vertex for " << vsim->z << std::endl;
1216  }
1217  }
1218  } // end for loop on simulated vertices
1219  if (verbose_) {
1220  std::cout << "Done with matching sim vertices" << std::endl;
1221  }
1222 }
1223 
1225  std::vector<recoPrimaryVertex>& recopv,
1226  const reco::VertexRecoToSimCollection& vertex_r2s,
1227  const std::vector<simPrimaryVertex>& simpv) {
1228  for (std::vector<recoPrimaryVertex>::iterator vrec = recopv.begin();
1229  vrec != recopv.end(); vrec++) {
1230 
1231  auto matched = vertex_r2s.find(vrec->recVtxRef);
1232  if(matched != vertex_r2s.end()) {
1233  for(const auto vertexRefQuality: matched->val) {
1234  const auto tvPtr = &(*(vertexRefQuality.first));
1235  vrec->sim_vertices.push_back(tvPtr);
1236  }
1237 
1238  for(const TrackingVertex *tv: vrec->sim_vertices) {
1239  // Set pointers to internal simVertex objects
1240  for(const auto& vv: simpv) {
1241  if (&(*(vv.sim_vertex)) == tv) {
1242  vrec->sim_vertices_internal.push_back(&vv);
1243  continue;
1244  }
1245  }
1246 
1247  // Calculate number of shared tracks
1248  vrec->sim_vertices_num_shared_tracks.push_back(calculateVertexSharedTracks(*(vrec->recVtx), *tv, *r2s_));
1249  }
1250  }
1251 
1252  if (verbose_) {
1253  for (auto v : vrec->sim_vertices) {
1254  std::cout << "Found a matching vertex for reco: " << vrec->z
1255  << " at gen:" << v->position().z() << " with sign: "
1256  << fabs(vrec->z - v->position().z()) / vrec->recVtx->zError()
1257  << std::endl;
1258  }
1259  }
1260  } // end for loop on reconstructed vertices
1261 }
1262 
1264  const edm::EventSetup& iSetup) {
1265  using std::vector;
1266  using std::cout;
1267  using std::endl;
1268  using edm::Handle;
1269  using edm::View;
1270  using namespace reco;
1271 
1272  std::vector<float> pileUpInfo_z;
1273 
1274  // get the pileup information
1276  if (iEvent.getByToken(vecPileupSummaryInfoToken_, puinfoH)) {
1277  for (auto const& pu_info : *puinfoH.product()) {
1278  if(do_generic_sim_plots_) {
1279  mes_["root_folder"]["GenVtx_vs_BX"]
1280  ->Fill(pu_info.getBunchCrossing(), pu_info.getPU_NumInteractions());
1281  }
1282  if (pu_info.getBunchCrossing() == 0) {
1283  pileUpInfo_z = pu_info.getPU_zpositions();
1284  if (verbose_) {
1285  for (auto const& p : pileUpInfo_z) {
1286  std::cout << "PileUpInfo on Z vertex: " << p << std::endl;
1287  }
1288  }
1289  break;
1290  }
1291  }
1292  }
1293 
1295  iEvent.getByToken(trackingParticleCollectionToken_, TPCollectionH);
1296  if (!TPCollectionH.isValid())
1297  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1298  << "TPCollectionH is not valid";
1299 
1301  iEvent.getByToken(trackingVertexCollectionToken_, TVCollectionH);
1302  if (!TVCollectionH.isValid())
1303  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1304  << "TVCollectionH is not valid";
1305 
1306  // TODO(rovere) the idea is to put in case a track-selector in front
1307  // of this module and then use its label to get the selected tracks
1308  // out of the event instead of making an hard-coded selection in the
1309  // code.
1310 
1312  iEvent.getByToken(simToRecoAssociationToken_, simToRecoH);
1313  if ( simToRecoH.isValid() )
1314  s2r_ = simToRecoH.product();
1315  else
1316  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1317  << "simToRecoH is not valid";
1318 
1320  iEvent.getByToken(recoToSimAssociationToken_, recoToSimH);
1321  if ( recoToSimH.isValid() )
1322  r2s_ = recoToSimH.product();
1323  else
1324  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1325  << "recoToSimH is not valid";
1326 
1327  // Vertex associator
1329  iEvent.getByToken(vertexAssociatorToken_, vertexAssociatorH);
1330  if (!vertexAssociatorH.isValid()) {
1331  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1332  << "vertexAssociatorH is not valid";
1333  return;
1334  }
1335  const reco::VertexToTrackingVertexAssociator& vertexAssociator = *(vertexAssociatorH.product());
1336 
1337  std::vector<simPrimaryVertex> simpv; // a list of simulated primary
1338  // MC vertices
1339  // TODO(rovere) use move semantic?
1340  simpv = getSimPVs(TVCollectionH);
1341  // TODO(rovere) 1 vertex is not, by definition, pileup, and should
1342  // probably be subtracted?
1343  int kind_of_signal_vertex = 0;
1344  int num_pileup_vertices = simpv.size();
1345  if(do_generic_sim_plots_) mes_["root_folder"]["GenAllV_NumVertices"]->Fill(simpv.size());
1346  bool signal_is_highest_pt = std::max_element(simpv.begin(), simpv.end(),
1347  [](const simPrimaryVertex& lhs,
1348  const simPrimaryVertex& rhs) {
1349  return lhs.ptsq < rhs.ptsq;
1350  }) == simpv.begin();
1351  kind_of_signal_vertex |= (signal_is_highest_pt << HIGHEST_PT);
1352  if(do_generic_sim_plots_) {
1353  mes_["root_folder"]["SignalIsHighestPt2"]->Fill(signal_is_highest_pt ? 1. : 0.);
1354  computePairDistance(simpv, mes_["root_folder"]["GenAllV_PairDistanceZ"]);
1355  }
1356 
1357  int label_index = -1;
1358  for(size_t iToken=0, endToken=reco_vertex_collection_tokens_.size(); iToken<endToken; ++iToken) {
1359  auto const& vertex_token = reco_vertex_collection_tokens_[iToken];
1360  std::vector<recoPrimaryVertex> recopv; // a list of reconstructed
1361  // primary MC vertices
1362  std::string label = reco_vertex_collections_[++label_index].label();
1364  if (!iEvent.getByToken(vertex_token, recVtxs)) {
1365  if(!errorPrintedForColl_[iToken]) {
1366  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1367  << "Skipping vertex collection: " << label << " since it is missing.";
1368  errorPrintedForColl_[iToken] = true;
1369  }
1370  continue;
1371  }
1372 
1373  {
1374  // check upfront that refs to track are (likely) to be valid
1375  bool ok = true;
1376  for(const auto& v: *recVtxs) {
1377  if(v.tracksSize() > 0) {
1378  const auto& ref = v.trackRefAt(0);
1379  if(ref.isNull() || !ref.isAvailable()) {
1380  if(!errorPrintedForColl_[iToken]) {
1381  edm::LogWarning("PrimaryVertexAnalyzer4PUSlimmed")
1382  << "Skipping vertex collection: " << label << " since likely the track collection the vertex has refs pointing to is missing (at least the first TrackBaseRef is null or not available)";
1383  errorPrintedForColl_[iToken] = true;
1384  }
1385  ok = false;
1386  }
1387  }
1388  }
1389  if(!ok)
1390  continue;
1391  }
1392 
1393  reco::VertexRecoToSimCollection vertex_r2s = vertexAssociator.associateRecoToSim(recVtxs, TVCollectionH);
1394  reco::VertexSimToRecoCollection vertex_s2r = vertexAssociator.associateSimToReco(recVtxs, TVCollectionH);
1395 
1396  resetSimPVAssociation(simpv);
1397  matchSim2RecoVertices(simpv, vertex_s2r);
1398  recopv = getRecoPVs(recVtxs);
1399  computePairDistance(recopv,
1400  mes_[label]["RecoAllAssoc2Gen_PairDistanceZ"]);
1401  matchReco2SimVertices(recopv, vertex_r2s, simpv);
1402 
1403  int num_total_gen_vertices_assoc2reco = 0;
1404  int num_total_reco_vertices_assoc2gen = 0;
1405  int num_total_gen_vertices_multiassoc2reco = 0;
1406  int num_total_reco_vertices_multiassoc2gen = 0;
1407  int num_total_reco_vertices_duplicate = 0;
1408  int genpv_position_in_reco_collection = -1;
1409  for (auto const& v : simpv) {
1410  float mistag = 1.;
1411  // TODO(rovere) put selectors here in front of fill* methods.
1412  if (v.eventId.event() == 0) {
1413  if (!recVtxs->empty() &&
1414  std::find(v.rec_vertices.begin(), v.rec_vertices.end(),
1415  &((*recVtxs.product())[0])) != v.rec_vertices.end()) {
1416  mistag = 0.;
1417  kind_of_signal_vertex |= (1 << IS_ASSOC2FIRST_RECO);
1418  } else {
1419  if (v.rec_vertices.size()) {
1420  kind_of_signal_vertex |= (1 << IS_ASSOC2ANY_RECO);
1421  }
1422  }
1423  mes_[label]["KindOfSignalPV"]->Fill(kind_of_signal_vertex);
1424  mes_[label]["MisTagRate"]->Fill(mistag);
1425  mes_[label]["MisTagRate_vs_PU"]->Fill(simpv.size(), mistag);
1426  mes_[label]["MisTagRate_vs_sum-pt2"]->Fill(v.ptsq, mistag);
1427  mes_[label]["MisTagRate_vs_Z"]->Fill(v.z, mistag);
1428  mes_[label]["MisTagRate_vs_R"]->Fill(v.r, mistag);
1429  mes_[label]["MisTagRate_vs_NumTracks"]->Fill(v.nGenTrk, mistag);
1430  if (signal_is_highest_pt) {
1431  mes_[label]["MisTagRateSignalIsHighest"]->Fill(mistag);
1432  mes_[label]["MisTagRateSignalIsHighest_vs_PU"]->Fill(simpv.size(),
1433  mistag);
1434  mes_[label]["MisTagRateSignalIsHighest_vs_sum-pt2"]->Fill(v.ptsq,
1435  mistag);
1436  mes_[label]["MisTagRateSignalIsHighest_vs_Z"]->Fill(v.z, mistag);
1437  mes_[label]["MisTagRateSignalIsHighest_vs_R"]->Fill(v.r, mistag);
1438  mes_[label]["MisTagRateSignalIsHighest_vs_NumTracks"]->Fill(v.nGenTrk,
1439  mistag);
1440  } else {
1441  mes_[label]["MisTagRateSignalIsNotHighest"]->Fill(mistag);
1442  mes_[label]["MisTagRateSignalIsNotHighest_vs_PU"]->Fill(simpv.size(),
1443  mistag);
1444  mes_[label]["MisTagRateSignalIsNotHighest_vs_sum-pt2"]->Fill(v.ptsq,
1445  mistag);
1446  mes_[label]["MisTagRateSignalIsNotHighest_vs_Z"]->Fill(v.z, mistag);
1447  mes_[label]["MisTagRateSignalIsNotHighest_vs_R"]->Fill(v.r, mistag);
1448  mes_[label]["MisTagRateSignalIsNotHighest_vs_NumTracks"]->
1449  Fill(v.nGenTrk, mistag);
1450  }
1451  // Now check at which location the Simulated PV has been
1452  // reconstructed in the primary vertex collection
1453  // at-hand. Mark it with fake index -1 if it was not
1454  // reconstructed at all.
1455 
1456  auto iv = (*recVtxs.product()).begin();
1457  for (int pv_position_in_reco_collection = 0;
1458  iv != (*recVtxs.product()).end();
1459  ++pv_position_in_reco_collection, ++iv) {
1460  if (std::find(v.rec_vertices.begin(), v.rec_vertices.end(),
1461  &(*iv)) != v.rec_vertices.end()) {
1462  mes_[label]["TruePVLocationIndex"]
1463  ->Fill(pv_position_in_reco_collection);
1464  const bool genPVMatchedToRecoPV = (pv_position_in_reco_collection == 0);
1465  mes_[label]["TruePVLocationIndexCumulative"]
1466  ->Fill(genPVMatchedToRecoPV ? 0 : 1);
1467 
1468  if (signal_is_highest_pt) {
1469  mes_[label]["TruePVLocationIndexSignalIsHighest"]
1470  ->Fill(pv_position_in_reco_collection);
1471  } else {
1472  mes_[label]["TruePVLocationIndexSignalIsNotHighest"]
1473  ->Fill(pv_position_in_reco_collection);
1474  }
1475 
1476  fillRecoAssociatedGenPVHistograms(label, v, genPVMatchedToRecoPV);
1477  if(genPVMatchedToRecoPV) {
1478  auto pv = recopv[0];
1479  assert(pv.recVtx == &(*iv));
1480  fillResolutionAndPullHistograms(label, num_pileup_vertices, pv, true);
1481  }
1482  genpv_position_in_reco_collection = pv_position_in_reco_collection;
1483  break;
1484  }
1485  }
1486 
1487  // If we reached the end, it means that the Simulated PV has not
1488  // been associated to any reconstructed vertex: mark it as
1489  // missing in the reconstructed vertex collection using the fake
1490  // index -1.
1491  if (iv == (*recVtxs.product()).end()) {
1492  mes_[label]["TruePVLocationIndex"]->Fill(-1.);
1493  mes_[label]["TruePVLocationIndexCumulative"]->Fill(-1.);
1494  if (signal_is_highest_pt)
1495  mes_[label]["TruePVLocationIndexSignalIsHighest"]->Fill(-1.);
1496  else
1497  mes_[label]["TruePVLocationIndexSignalIsNotHighest"]->Fill(-1.);
1498  }
1499  }
1500 
1501  if (v.rec_vertices.size()) num_total_gen_vertices_assoc2reco++;
1502  if (v.rec_vertices.size() > 1) num_total_gen_vertices_multiassoc2reco++;
1503  // No need to N-tplicate the Gen-related cumulative histograms:
1504  // fill them only at the first iteration
1505  if (do_generic_sim_plots_ && label_index == 0) fillGenericGenVertexHistograms(v);
1507  }
1508  calculatePurityAndFillHistograms(label, recopv, genpv_position_in_reco_collection, signal_is_highest_pt);
1509 
1510  mes_[label]["GenAllAssoc2Reco_NumVertices"]
1511  ->Fill(simpv.size(), simpv.size());
1512  mes_[label]["GenAllAssoc2RecoMatched_NumVertices"]
1513  ->Fill(simpv.size(), num_total_gen_vertices_assoc2reco);
1514  mes_[label]["GenAllAssoc2RecoMultiMatched_NumVertices"]
1515  ->Fill(simpv.size(), num_total_gen_vertices_multiassoc2reco);
1516  for (auto & v : recopv) {
1517  fillGenAssociatedRecoVertexHistograms(label, num_pileup_vertices, v);
1518  if (v.sim_vertices.size()) {
1519  num_total_reco_vertices_assoc2gen++;
1520  if (v.sim_vertices_internal[0]->rec_vertices.size() > 1) {
1521  num_total_reco_vertices_duplicate++;
1522  }
1523  }
1524  if (v.sim_vertices.size() > 1) num_total_reco_vertices_multiassoc2gen++;
1525  }
1526  mes_[label]["RecoAllAssoc2Gen_NumVertices"]
1527  ->Fill(recopv.size(), recopv.size());
1528  mes_[label]["RecoAllAssoc2GenMatched_NumVertices"]
1529  ->Fill(recopv.size(), num_total_reco_vertices_assoc2gen);
1530  mes_[label]["RecoAllAssoc2GenMultiMatched_NumVertices"]
1531  ->Fill(recopv.size(), num_total_reco_vertices_multiassoc2gen);
1532  mes_[label]["RecoAllAssoc2MultiMatchedGen_NumVertices"]
1533  ->Fill(recopv.size(), num_total_reco_vertices_duplicate);
1534  mes_[label]["RecoVtx_vs_GenVtx"]->Fill(simpv.size(), recopv.size());
1535  mes_[label]["MatchedRecoVtx_vs_GenVtx"]
1536  ->Fill(simpv.size(), num_total_reco_vertices_assoc2gen);
1537 
1538  }
1539 } // end of analyze
1540 
1541 template<class T>
1543  MonitorElement *me) {
1544  for (unsigned int i = 0; i < collection.size(); ++i) {
1545  for (unsigned int j = i+1; j < collection.size(); ++j) {
1546  me->Fill(
1547  std::abs(collection[i].z-collection[j].z));
1548  }
1549  }
1550 }
T getParameter(std::string const &) const
void matchSim2RecoVertices(std::vector< simPrimaryVertex > &, const reco::VertexSimToRecoCollection &)
void fillGenAssociatedRecoVertexHistograms(const std::string &, int, recoPrimaryVertex &v)
std::vector< PrimaryVertexAnalyzer4PUSlimmed::recoPrimaryVertex > getRecoPVs(const edm::Handle< edm::View< reco::Vertex >> &)
int event() const
get the contents of the subdetector field (should be protected?)
bool matchRecoTrack2SimSignal(const reco::TrackBaseRef &)
void resetSimPVAssociation(std::vector< simPrimaryVertex > &)
edm::EDGetTokenT< reco::SimToRecoCollection > simToRecoAssociationToken_
edm::EDGetTokenT< std::vector< PileupSummaryInfo > > vecPileupSummaryInfoToken_
const double xbins[]
std::vector< TrackingParticle > TrackingParticleCollection
void fillRecoAssociatedGenPVHistograms(const std::string &label, const PrimaryVertexAnalyzer4PUSlimmed::simPrimaryVertex &v, bool genPVMatchedToRecoPV)
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.cc:81
void computePairDistance(const T &collection, MonitorElement *me)
const_iterator end() const
last iterator over the map (read only)
MonitorElement * bookProfile(Args &&...args)
Definition: DQMStore.h:157
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:508
double zError() const
error on z
Definition: Vertex.h:123
std::vector< SimVertex >::const_iterator g4v_iterator
edm::RefToBase< reco::Vertex > VertexBaseRef
persistent reference to a Vertex, using views
Definition: VertexFwd.h:21
const_iterator find(const key_type &k) const
find element with specified reference key
virtual void bookHistograms(DQMStore::IBooker &i, edm::Run const &, edm::EventSetup const &) override
PrimaryVertexAnalyzer4PUSlimmed(const edm::ParameterSet &)
#define NULL
Definition: scimark2.h:8
edm::EDGetTokenT< TrackingVertexCollection > trackingVertexCollectionToken_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void Fill(long long x)
virtual void analyze(const edm::Event &, const edm::EventSetup &) override
int iEvent
Definition: GenABIO.cc:230
std::vector< PrimaryVertexAnalyzer4PUSlimmed::simPrimaryVertex > getSimPVs(const edm::Handle< TrackingVertexCollection > &)
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
T sqrt(T t)
Definition: SSEVec.h:18
void fillResolutionAndPullHistograms(const std::string &, int, recoPrimaryVertex &v, bool)
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
def pv(vc)
Definition: MetAnalyzer.py:6
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
void calculatePurityAndFillHistograms(const std::string &, std::vector< recoPrimaryVertex > &, int, bool)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:74
const reco::SimToRecoCollection * s2r_
double ndof() const
Definition: Vertex.h:105
std::vector< edm::EDGetTokenT< edm::View< reco::Vertex > > > reco_vertex_collection_tokens_
void fillGenericGenVertexHistograms(const simPrimaryVertex &v)
edm::Ref< TrackingVertexCollection > TrackingVertexRef
double xError() const
error on x
Definition: Vertex.h:119
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
#define N
Definition: blowfish.cc:9
T const * product() const
Definition: Handle.h:81
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:133
def bestMatch(object, matchCollection)
Definition: deltar.py:139
std::vector< TrackingVertex > TrackingVertexCollection
edm::AssociationMap< edm::OneToManyWithQualityGeneric< edm::View< reco::Track >, TrackingParticleCollection, double > > RecoToSimCollection
void fillRecoAssociatedGenVertexHistograms(const std::string &, const simPrimaryVertex &v)
void matchReco2SimVertices(std::vector< recoPrimaryVertex > &, const reco::VertexRecoToSimCollection &, const std::vector< simPrimaryVertex > &)
edm::EDGetTokenT< reco::VertexToTrackingVertexAssociator > vertexAssociatorToken_
edm::EDGetTokenT< reco::RecoToSimCollection > recoToSimAssociationToken_
std::vector< edm::InputTag > reco_vertex_collections_
fixed size matrix
#define begin
Definition: vmac.h:30
HLT enums.
std::map< std::string, std::map< std::string, MonitorElement * > > mes_
edm::AssociationMap< edm::OneToManyWithQualityGeneric< TrackingParticleCollection, edm::View< reco::Track >, double > > SimToRecoCollection
unsigned int calculateVertexSharedTracks(const reco::Vertex &recoV, const TrackingVertex &simV, const reco::RecoToSimCollection &trackRecoToSimAssociation)
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.cc:76
TH2F * getTH2F(void) const
reco::VertexRecoToSimCollection associateRecoToSim(const edm::Handle< edm::View< reco::Vertex > > &vCH, const edm::Handle< TrackingVertexCollection > &tVCH) const
compare reco to sim the handle of reco::Vertex and TrackingVertex collections
long double T
reco::VertexSimToRecoCollection associateSimToReco(const edm::Handle< edm::View< reco::Vertex > > &vCH, const edm::Handle< TrackingVertexCollection > &tVCH) const
compare reco to sim the handle of reco::Vertex and TrackingVertex collections
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
double yError() const
error on y
Definition: Vertex.h:121
const reco::RecoToSimCollection * r2s_
Definition: Run.h:43
edm::EDGetTokenT< TrackingParticleCollection > trackingParticleCollectionToken_