File indexing completed on 2024-04-06 12:09:07
0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0003 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0004 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006
0007 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0008 #include "DQMServices/Core/interface/DQMStore.h"
0009
0010 #include "DataFormats/Common/interface/Handle.h"
0011 #include "DataFormats/VertexReco/interface/Vertex.h"
0012 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0013 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0014 #include "DataFormats/Scalers/interface/LumiScalers.h"
0015 #include "DataFormats/OnlineMetaData/interface/OnlineLuminosityRecord.h"
0016
0017 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0018 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
0019 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0020 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0021
0022 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
0023
0024 #include <random>
0025
0026 namespace {
0027 template <typename T, size_t N>
0028 std::array<T, N + 1> makeLogBins(const double min, const double max) {
0029 const double minLog10 = std::log10(min);
0030 const double maxLog10 = std::log10(max);
0031 const double width = (maxLog10 - minLog10) / N;
0032 std::array<T, N + 1> ret;
0033 ret[0] = std::pow(10, minLog10);
0034 const double mult = std::pow(10, width);
0035 for (size_t i = 1; i <= N; ++i) {
0036 ret[i] = ret[i - 1] * mult;
0037 }
0038 return ret;
0039 }
0040
0041 template <typename T>
0042 T sqr(T val) {
0043 return val * val;
0044 }
0045 }
0046
0047 class PrimaryVertexResolution : public DQMEDAnalyzer {
0048 public:
0049 PrimaryVertexResolution(const edm::ParameterSet& iConfig);
0050 ~PrimaryVertexResolution() override;
0051
0052 void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0053 void analyze(const edm::Event&, const edm::EventSetup&) override;
0054
0055 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0056
0057 private:
0058 std::vector<reco::TransientTrack> sortTracksByPt(const reco::Vertex& thePV,
0059 const TransientTrackBuilder& ttBuilder,
0060 const reco::BeamSpot& beamspot);
0061
0062 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> ttbToken_;
0063 edm::EDGetTokenT<reco::VertexCollection> vertexSrc_;
0064 edm::EDGetTokenT<reco::BeamSpot> beamspotSrc_;
0065 edm::EDGetTokenT<LumiScalersCollection> lumiScalersSrc_;
0066 edm::EDGetTokenT<OnlineLuminosityRecord> metaDataSrc_;
0067 const bool forceSCAL_;
0068 std::string rootFolder_;
0069
0070 AdaptiveVertexFitter fitter_;
0071
0072 struct BinningY {
0073 explicit BinningY(const edm::ParameterSet& iConfig)
0074 : maxResol_(iConfig.getUntrackedParameter<double>("maxResol")),
0075 binsResol_(iConfig.getUntrackedParameter<int>("binsResol")),
0076 maxPull_(iConfig.getUntrackedParameter<double>("maxPull")),
0077 binsPull_(iConfig.getUntrackedParameter<int>("binsPull")) {}
0078
0079 const double maxResol_;
0080 const int binsResol_;
0081 const double maxPull_;
0082 const int binsPull_;
0083 };
0084
0085 struct BinningX {
0086 explicit BinningX(const edm::ParameterSet& iConfig)
0087 : minNtracks_(iConfig.getUntrackedParameter<double>("minNtracks")),
0088 maxNtracks_(iConfig.getUntrackedParameter<double>("maxNtracks")),
0089 binsNtracks_(iConfig.getUntrackedParameter<int>("binsNtracks")),
0090 minNvertices_(iConfig.getUntrackedParameter<double>("minNvertices")),
0091 maxNvertices_(iConfig.getUntrackedParameter<double>("maxNvertices")),
0092 binsNvertices_(iConfig.getUntrackedParameter<int>("binsNvertices")),
0093 maxXY_(iConfig.getUntrackedParameter<double>("maxXY")),
0094 binsXY_(iConfig.getUntrackedParameter<int>("binsXY")),
0095 maxZ_(iConfig.getUntrackedParameter<double>("maxZ")),
0096 binsZ_(iConfig.getUntrackedParameter<int>("binsZ")),
0097 minPt_(iConfig.getUntrackedParameter<double>("minPt")),
0098 maxPt_(iConfig.getUntrackedParameter<double>("maxPt")),
0099 minLumi_(iConfig.getUntrackedParameter<double>("minLumi")),
0100 maxLumi_(iConfig.getUntrackedParameter<double>("maxLumi")) {}
0101
0102 const int minNtracks_;
0103 const int maxNtracks_;
0104 const int binsNtracks_;
0105 const int minNvertices_;
0106 const int maxNvertices_;
0107 const int binsNvertices_;
0108 const double maxXY_;
0109 const int binsXY_;
0110 const double maxZ_;
0111 const int binsZ_;
0112 const double minPt_;
0113 const double maxPt_;
0114 const double minLumi_;
0115 const double maxLumi_;
0116 };
0117
0118 class Resolution {
0119 public:
0120 Resolution(const reco::Vertex& vertex1, const reco::Vertex& vertex2) {
0121 const double diffx = vertex1.x() - vertex2.x();
0122 const double diffy = vertex1.y() - vertex2.y();
0123 const double diffz = vertex1.z() - vertex2.z();
0124
0125
0126
0127
0128 const double invSqrt2 = 1. / std::sqrt(2.);
0129 resx_ = diffx * invSqrt2;
0130 resy_ = diffy * invSqrt2;
0131 resz_ = diffz * invSqrt2;
0132
0133 pullx_ = diffx / std::sqrt(sqr(vertex1.xError()) + sqr(vertex2.xError()));
0134 pully_ = diffy / std::sqrt(sqr(vertex1.yError()) + sqr(vertex2.yError()));
0135 pullz_ = diffz / std::sqrt(sqr(vertex1.zError()) + sqr(vertex2.zError()));
0136
0137 avgx_ = (vertex1.x() + vertex2.x()) / 2.;
0138 avgy_ = (vertex1.y() + vertex2.y()) / 2.;
0139 avgz_ = (vertex1.z() + vertex2.z()) / 2.;
0140 }
0141
0142 double resx() const { return resx_; }
0143 double resy() const { return resy_; }
0144 double resz() const { return resz_; }
0145
0146 double pullx() const { return pullx_; }
0147 double pully() const { return pully_; }
0148 double pullz() const { return pullz_; }
0149
0150 double avgx() const { return avgx_; }
0151 double avgy() const { return avgy_; }
0152 double avgz() const { return avgz_; }
0153
0154 private:
0155 double resx_;
0156 double resy_;
0157 double resz_;
0158 double pullx_;
0159 double pully_;
0160 double pullz_;
0161 double avgx_;
0162 double avgy_;
0163 double avgz_;
0164 };
0165
0166 class DiffPlots {
0167 public:
0168 explicit DiffPlots(const std::string& postfix, const BinningY& binY) : postfix_(postfix), binningY_(binY) {}
0169
0170 template <typename T>
0171 void bookLogX(DQMStore::IBooker& iBooker, const T& binArray) {
0172 book(iBooker, binArray.size() - 1, binArray.front(), binArray.back());
0173 setLogX(binArray.size() - 1, binArray.data());
0174 }
0175
0176 template <typename... Args>
0177 void book(DQMStore::IBooker& iBooker, Args&&... args) {
0178 const auto binsResol = binningY_.binsResol_;
0179 const auto maxResol = binningY_.maxResol_;
0180 hDiffX_ = iBooker.book2D("res_x_vs_" + postfix_,
0181 "Resolution of X vs. " + postfix_,
0182 std::forward<Args>(args)...,
0183 binsResol,
0184 -maxResol,
0185 maxResol);
0186 hDiffY_ = iBooker.book2D("res_y_vs_" + postfix_,
0187 "Resolution of Y vs. " + postfix_,
0188 std::forward<Args>(args)...,
0189 binsResol,
0190 -maxResol,
0191 maxResol);
0192 hDiffZ_ = iBooker.book2D("res_z_vs_" + postfix_,
0193 "Resolution of Z vs. " + postfix_,
0194 std::forward<Args>(args)...,
0195 binsResol,
0196 -maxResol,
0197 maxResol);
0198
0199 const auto binsPull = binningY_.binsPull_;
0200 const auto maxPull = binningY_.maxPull_;
0201 hPullX_ = iBooker.book2D("pull_x_vs_" + postfix_,
0202 "Pull of X vs. " + postfix_,
0203 std::forward<Args>(args)...,
0204 binsPull,
0205 -maxPull,
0206 maxPull);
0207 hPullY_ = iBooker.book2D("pull_y_vs_" + postfix_,
0208 "Pull of Y vs. " + postfix_,
0209 std::forward<Args>(args)...,
0210 binsPull,
0211 -maxPull,
0212 maxPull);
0213 hPullZ_ = iBooker.book2D("pull_z_vs_" + postfix_,
0214 "Pull of Z vs. " + postfix_,
0215 std::forward<Args>(args)...,
0216 binsPull,
0217 -maxPull,
0218 maxPull);
0219 }
0220 template <typename... Args>
0221 void setLogX(Args&&... args) {
0222 hDiffX_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0223 hDiffY_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0224 hDiffZ_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0225
0226 hPullX_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0227 hPullY_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0228 hPullZ_->getTH2F()->GetXaxis()->Set(std::forward<Args>(args)...);
0229 }
0230
0231 template <typename T>
0232 void fill(const Resolution& res, const T ref) {
0233 hDiffX_->Fill(ref, res.resx());
0234 hDiffY_->Fill(ref, res.resy());
0235 hDiffZ_->Fill(ref, res.resz());
0236 hPullX_->Fill(ref, res.pullx());
0237 hPullY_->Fill(ref, res.pully());
0238 hPullZ_->Fill(ref, res.pullz());
0239 }
0240
0241 private:
0242 std::string postfix_;
0243 const BinningY& binningY_;
0244 MonitorElement* hDiffX_ = nullptr;
0245 MonitorElement* hDiffY_ = nullptr;
0246 MonitorElement* hDiffZ_ = nullptr;
0247 MonitorElement* hPullX_ = nullptr;
0248 MonitorElement* hPullY_ = nullptr;
0249 MonitorElement* hPullZ_ = nullptr;
0250 };
0251
0252 class Plots {
0253 public:
0254 Plots(const BinningX& binX, const BinningY& binY)
0255 : binningX_(binX),
0256 binningY_(binY),
0257 hDiff_Ntracks_("ntracks", binY),
0258 hDiff_sumPt_("sumpt", binY),
0259 hDiff_Nvertices_("nvertices", binY),
0260 hDiff_X_("X", binY),
0261 hDiff_Y_("Y", binY),
0262 hDiff_Z_("Z", binY),
0263 hDiff_instLumiScal_("instLumiScal", binY) {}
0264
0265 void book(DQMStore::IBooker& iBooker) {
0266 const auto binsResol = binningY_.binsResol_;
0267 const auto maxResol = binningY_.maxResol_;
0268 hDiffX_ = iBooker.book1D("res_x", "Resolution of X", binsResol, -maxResol, maxResol);
0269 hDiffY_ = iBooker.book1D("res_y", "Resolution of Y", binsResol, -maxResol, maxResol);
0270 hDiffZ_ = iBooker.book1D("res_z", "Resolution of Z", binsResol, -maxResol, maxResol);
0271
0272 const auto binsPull = binningY_.binsPull_;
0273 const auto maxPull = binningY_.maxPull_;
0274 hPullX_ = iBooker.book1D(+"pull_x", "Pull of X", binsPull, -maxPull, maxPull);
0275 hPullY_ = iBooker.book1D(+"pull_y", "Pull of Y", binsPull, -maxPull, maxPull);
0276 hPullZ_ = iBooker.book1D(+"pull_z", "Pull of Z", binsPull, -maxPull, maxPull);
0277
0278 hDiff_Ntracks_.book(iBooker, binningX_.binsNtracks_, binningX_.minNtracks_, binningX_.maxNtracks_);
0279 hDiff_Nvertices_.book(iBooker, binningX_.binsNvertices_, binningX_.minNvertices_, binningX_.maxNvertices_);
0280 hDiff_X_.book(iBooker, binningX_.binsXY_, -binningX_.maxXY_, binningX_.maxXY_);
0281 hDiff_Y_.book(iBooker, binningX_.binsXY_, -binningX_.maxXY_, binningX_.maxXY_);
0282 hDiff_Z_.book(iBooker, binningX_.binsZ_, -binningX_.maxZ_, binningX_.maxZ_);
0283
0284 constexpr int binsPt = 30;
0285 hDiff_sumPt_.bookLogX(iBooker, makeLogBins<float, binsPt>(binningX_.minPt_, binningX_.maxPt_));
0286
0287 constexpr int binsLumi = 100;
0288 hDiff_instLumiScal_.bookLogX(iBooker, makeLogBins<float, binsLumi>(binningX_.minLumi_, binningX_.maxLumi_));
0289 }
0290
0291 void calculateAndFillResolution(const std::vector<reco::TransientTrack>& tracks,
0292 size_t nvertices,
0293 float lumi,
0294 std::mt19937& engine,
0295 AdaptiveVertexFitter& fitter);
0296
0297 private:
0298 const BinningX& binningX_;
0299 const BinningY& binningY_;
0300
0301 MonitorElement* hDiffX_ = nullptr;
0302 MonitorElement* hDiffY_ = nullptr;
0303 MonitorElement* hDiffZ_ = nullptr;
0304 MonitorElement* hPullX_ = nullptr;
0305 MonitorElement* hPullY_ = nullptr;
0306 MonitorElement* hPullZ_ = nullptr;
0307
0308 DiffPlots hDiff_Ntracks_;
0309 DiffPlots hDiff_sumPt_;
0310 DiffPlots hDiff_Nvertices_;
0311 DiffPlots hDiff_X_;
0312 DiffPlots hDiff_Y_;
0313 DiffPlots hDiff_Z_;
0314 DiffPlots hDiff_instLumiScal_;
0315 };
0316
0317
0318 BinningX binningX_;
0319 BinningY binningY_;
0320
0321
0322 Plots hPV_;
0323 Plots hOtherV_;
0324
0325 std::mt19937 engine_;
0326 };
0327
0328 PrimaryVertexResolution::PrimaryVertexResolution(const edm::ParameterSet& iConfig)
0329 : ttbToken_(esConsumes(edm::ESInputTag("", iConfig.getUntrackedParameter<std::string>("transientTrackBuilder")))),
0330 vertexSrc_(consumes<reco::VertexCollection>(iConfig.getUntrackedParameter<edm::InputTag>("vertexSrc"))),
0331 beamspotSrc_(consumes<reco::BeamSpot>(iConfig.getUntrackedParameter<edm::InputTag>("beamspotSrc"))),
0332 lumiScalersSrc_(consumes<LumiScalersCollection>(iConfig.getUntrackedParameter<edm::InputTag>("lumiScalersSrc"))),
0333 metaDataSrc_(consumes<OnlineLuminosityRecord>(iConfig.getUntrackedParameter<edm::InputTag>("metaDataSrc"))),
0334 forceSCAL_(iConfig.getUntrackedParameter<bool>("forceSCAL")),
0335 rootFolder_(iConfig.getUntrackedParameter<std::string>("rootFolder")),
0336 binningX_(iConfig),
0337 binningY_(iConfig),
0338 hPV_(binningX_, binningY_),
0339 hOtherV_(binningX_, binningY_) {}
0340
0341 PrimaryVertexResolution::~PrimaryVertexResolution() {}
0342
0343 void PrimaryVertexResolution::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0344 edm::ParameterSetDescription desc;
0345 desc.addUntracked<edm::InputTag>("vertexSrc", edm::InputTag("trackingDQMgoodOfflinePrimaryVertices"));
0346 desc.addUntracked<edm::InputTag>("beamspotSrc", edm::InputTag("offlineBeamSpot"));
0347 desc.addUntracked<edm::InputTag>("lumiScalersSrc", edm::InputTag("scalersRawToDigi"));
0348 desc.addUntracked<edm::InputTag>("metaDataSrc", edm::InputTag("onlineMetaDataDigis"));
0349 desc.addUntracked<bool>("forceSCAL", true);
0350 desc.addUntracked<std::string>("rootFolder", "OfflinePV/Resolution");
0351 desc.addUntracked<std::string>("transientTrackBuilder", "TransientTrackBuilder");
0352
0353
0354 desc.addUntracked<double>("maxResol", 0.02);
0355 desc.addUntracked<int>("binsResol", 100);
0356
0357 desc.addUntracked<double>("maxPull", 5);
0358 desc.addUntracked<int>("binsPull", 100);
0359
0360
0361 desc.addUntracked<double>("minNtracks", -0.5);
0362 desc.addUntracked<double>("maxNtracks", 119.5);
0363 desc.addUntracked<int>("binsNtracks", 60);
0364
0365 desc.addUntracked<double>("minNvertices", -0.5);
0366 desc.addUntracked<double>("maxNvertices", 199.5);
0367 desc.addUntracked<int>("binsNvertices", 100);
0368
0369 desc.addUntracked<double>("maxXY", 0.15);
0370 desc.addUntracked<int>("binsXY", 100);
0371
0372 desc.addUntracked<double>("maxZ", 30.);
0373 desc.addUntracked<int>("binsZ", 100);
0374
0375 desc.addUntracked<double>("minPt", 1);
0376 desc.addUntracked<double>("maxPt", 1e3);
0377
0378 desc.addUntracked<double>("minLumi", 200.);
0379 desc.addUntracked<double>("maxLumi", 20000.);
0380
0381 descriptions.add("primaryVertexResolution", desc);
0382 }
0383
0384 void PrimaryVertexResolution::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const&, edm::EventSetup const&) {
0385 iBooker.setCurrentFolder(rootFolder_ + "/PV");
0386 hPV_.book(iBooker);
0387
0388 iBooker.setCurrentFolder(rootFolder_ + "/OtherV");
0389 hOtherV_.book(iBooker);
0390 }
0391
0392 void PrimaryVertexResolution::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0393 edm::Handle<reco::VertexCollection> hvertices = iEvent.getHandle(vertexSrc_);
0394 const reco::VertexCollection& vertices = *hvertices;
0395 if (vertices.empty())
0396 return;
0397
0398 edm::Handle<reco::BeamSpot> hbeamspot = iEvent.getHandle(beamspotSrc_);
0399 const reco::BeamSpot& beamspot = *hbeamspot;
0400
0401 float lumi = -1.;
0402 if (forceSCAL_) {
0403 edm::Handle<LumiScalersCollection> lumiScalers = iEvent.getHandle(lumiScalersSrc_);
0404 if (lumiScalers.isValid() && !lumiScalers->empty()) {
0405 LumiScalersCollection::const_iterator scalit = lumiScalers->begin();
0406 lumi = scalit->instantLumi();
0407 }
0408 } else {
0409 edm::Handle<OnlineLuminosityRecord> metaData = iEvent.getHandle(metaDataSrc_);
0410 if (metaData.isValid())
0411 lumi = metaData->instLumi();
0412 }
0413
0414 const TransientTrackBuilder& ttBuilder = iSetup.getData(ttbToken_);
0415
0416
0417
0418
0419 engine_.seed(iEvent.id().event() + (iEvent.id().luminosityBlock() << 10) + (iEvent.id().run() << 20));
0420
0421
0422 auto iPV = cbegin(vertices);
0423 const reco::Vertex& thePV = *iPV;
0424 const auto nvertices = vertices.size();
0425 if (thePV.tracksSize() >= 4) {
0426 auto sortedTracks = sortTracksByPt(thePV, ttBuilder, beamspot);
0427 hPV_.calculateAndFillResolution(sortedTracks, nvertices, lumi, engine_, fitter_);
0428 }
0429 ++iPV;
0430
0431
0432 for (auto endPV = cend(vertices); iPV != endPV; ++iPV) {
0433 if (iPV->tracksSize() >= 4) {
0434 auto sortedTracks = sortTracksByPt(*iPV, ttBuilder, beamspot);
0435 hOtherV_.calculateAndFillResolution(sortedTracks, nvertices, lumi, engine_, fitter_);
0436 }
0437 }
0438 }
0439
0440 std::vector<reco::TransientTrack> PrimaryVertexResolution::sortTracksByPt(const reco::Vertex& thePV,
0441 const TransientTrackBuilder& ttBuilder,
0442 const reco::BeamSpot& beamspot) {
0443 std::vector<const reco::Track*> sortedTracks;
0444 sortedTracks.reserve(thePV.tracksSize());
0445 std::transform(
0446 thePV.tracks_begin(), thePV.tracks_end(), std::back_inserter(sortedTracks), [](const reco::TrackBaseRef& ref) {
0447 return &(*ref);
0448 });
0449 std::sort(sortedTracks.begin(), sortedTracks.end(), [](const reco::Track* a, const reco::Track* b) {
0450 return a->pt() > b->pt();
0451 });
0452
0453 std::vector<reco::TransientTrack> ttracks;
0454 ttracks.reserve(sortedTracks.size());
0455 std::transform(sortedTracks.begin(), sortedTracks.end(), std::back_inserter(ttracks), [&](const reco::Track* track) {
0456 auto tt = ttBuilder.build(track);
0457 tt.setBeamSpot(beamspot);
0458 return tt;
0459 });
0460 return ttracks;
0461 }
0462
0463 void PrimaryVertexResolution::Plots::calculateAndFillResolution(const std::vector<reco::TransientTrack>& tracks,
0464 size_t nvertices,
0465 float lumi,
0466 std::mt19937& engine,
0467 AdaptiveVertexFitter& fitter) {
0468 const size_t end = tracks.size() % 2 == 0 ? tracks.size() : tracks.size() - 1;
0469
0470 std::vector<reco::TransientTrack> set1, set2;
0471 set1.reserve(end / 2);
0472 set2.reserve(end / 2);
0473
0474 auto dis = std::uniform_int_distribution<>(0, 1);
0475
0476 double sumpt1 = 0, sumpt2 = 0;
0477 for (size_t i = 0; i < end; i += 2) {
0478 const size_t set1_i = dis(engine);
0479 const size_t set2_i = 1 - set1_i;
0480
0481 set1.push_back(tracks[i + set1_i]);
0482 set2.push_back(tracks[i + set2_i]);
0483
0484 sumpt1 += set1.back().track().pt();
0485 sumpt2 += set2.back().track().pt();
0486 }
0487
0488
0489 TransientVertex vertex1 = fitter.vertex(set1);
0490 TransientVertex vertex2 = fitter.vertex(set2);
0491
0492 Resolution res(vertex1, vertex2);
0493 hDiffX_->Fill(res.resx());
0494 hDiffY_->Fill(res.resy());
0495 hDiffZ_->Fill(res.resz());
0496 hPullX_->Fill(res.pullx());
0497 hPullY_->Fill(res.pully());
0498 hPullZ_->Fill(res.pullz());
0499
0500 hDiff_Ntracks_.fill(res, set1.size());
0501 hDiff_sumPt_.fill(
0502 res,
0503 (sumpt1 + sumpt2) /
0504 2.0);
0505 hDiff_Nvertices_.fill(res, nvertices);
0506
0507 if (vertex1.isValid() && vertex2.isValid()) {
0508 hDiff_X_.fill(res, res.avgx());
0509 hDiff_Y_.fill(res, res.avgy());
0510 hDiff_Z_.fill(res, res.avgz());
0511 }
0512
0513 hDiff_instLumiScal_.fill(res, lumi);
0514 }
0515
0516 #include "FWCore/Framework/interface/MakerMacros.h"
0517 DEFINE_FWK_MODULE(PrimaryVertexResolution);