File indexing completed on 2023-03-17 11:28:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "FWCore/Framework/interface/LuminosityBlock.h"
0011 #include "FWCore/Framework/interface/Run.h"
0012 #include "FWCore/Framework/interface/Event.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/ServiceRegistry/interface/Service.h"
0016
0017 #include "DQMServices/Core/interface/DQMEDHarvester.h"
0018 #include "DQMServices/Core/interface/DQMStore.h"
0019
0020 #include "TCanvas.h"
0021
0022
0023
0024
0025
0026 class PFJetDQMPostProcessor : public DQMEDHarvester {
0027 public:
0028 explicit PFJetDQMPostProcessor(const edm::ParameterSet&);
0029 ~PFJetDQMPostProcessor() override;
0030
0031 private:
0032 void dqmEndJob(DQMStore::IBooker&, DQMStore::IGetter&) override;
0033 void fitResponse(TH1F* hreso,
0034 TH1F* h_genjet_pt,
0035 int ptbinlow,
0036 int ietahigh,
0037 double recoptcut,
0038 double& resp,
0039 double& resp_err,
0040 double& reso,
0041 double& reso_err);
0042 double getRespUnc(double width, double width_err, double mean, double mean_err);
0043
0044 std::vector<std::string> jetResponseDir;
0045 std::string genjetDir;
0046 std::vector<double> ptBins;
0047 std::vector<double> etaBins;
0048
0049 double recoptcut;
0050
0051 bool debug = false;
0052
0053 std::string seta(double eta) {
0054 std::string seta = std::to_string(int(eta * 10.));
0055 if (seta.length() < 2)
0056 seta = "0" + seta;
0057 return seta;
0058 }
0059
0060 std::string spt(double ptmin, double ptmax) {
0061 std::string spt = std::to_string(int(ptmin)) + "_" + std::to_string(int(ptmax));
0062 return spt;
0063 }
0064 };
0065
0066
0067
0068
0069
0070 PFJetDQMPostProcessor::PFJetDQMPostProcessor(const edm::ParameterSet& iConfig) {
0071 jetResponseDir = iConfig.getParameter<std::vector<std::string>>("jetResponseDir");
0072 genjetDir = iConfig.getParameter<std::string>("genjetDir");
0073 ptBins = iConfig.getParameter<std::vector<double>>("ptBins");
0074 etaBins = iConfig.getParameter<std::vector<double>>("etaBins");
0075 recoptcut = iConfig.getParameter<double>("recoPtCut");
0076 }
0077
0078 PFJetDQMPostProcessor::~PFJetDQMPostProcessor() {}
0079
0080
0081 void PFJetDQMPostProcessor::dqmEndJob(DQMStore::IBooker& ibook_, DQMStore::IGetter& iget_) {
0082 for (unsigned int idir = 0; idir < jetResponseDir.size(); idir++) {
0083 iget_.setCurrentFolder(genjetDir);
0084 std::vector<std::string> sME_genjets = iget_.getMEs();
0085 std::for_each(sME_genjets.begin(), sME_genjets.end(), [&](auto& s) { s.insert(0, genjetDir); });
0086
0087
0088 iget_.setCurrentFolder(jetResponseDir[idir]);
0089 std::vector<std::string> sME_response = iget_.getMEs();
0090 std::for_each(sME_response.begin(), sME_response.end(), [&](auto& s) { s.insert(0, jetResponseDir[idir]); });
0091
0092
0093 iget_.setCurrentFolder(jetResponseDir[idir]);
0094
0095 double ptBinsArray[ptBins.size()];
0096 unsigned int nPtBins = ptBins.size() - 1;
0097 std::copy(ptBins.begin(), ptBins.end(), ptBinsArray);
0098
0099
0100 std::string stitle;
0101 char ctitle[50];
0102 std::vector<MonitorElement*> vME_presponse;
0103 std::vector<MonitorElement*> vME_preso;
0104 std::vector<MonitorElement*> vME_preso_rms;
0105
0106 MonitorElement* me;
0107 TH1F* h_resp;
0108 TH1F* h_genjet_pt;
0109
0110
0111
0112
0113 for (unsigned int ieta = 1; ieta < etaBins.size(); ++ieta) {
0114 stitle = genjetDir + "genjet_pt" + "_eta" + seta(etaBins[ieta]);
0115
0116
0117 std::vector<std::string>::const_iterator it = std::find(sME_genjets.begin(), sME_genjets.end(), stitle);
0118 if (it == sME_genjets.end())
0119 continue;
0120 me = iget_.get(stitle);
0121 h_genjet_pt = (TH1F*)me->getTH1F();
0122
0123 stitle = "presponse_eta" + seta(etaBins[ieta]);
0124
0125 if (jetResponseDir[idir].find("noJEC") != std::string::npos) {
0126 sprintf(ctitle, "Raw Jet pT response, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0127 } else {
0128 sprintf(ctitle, "Jet pT response, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0129 }
0130 TH1F* h_presponse = new TH1F(stitle.c_str(), ctitle, nPtBins, ptBinsArray);
0131
0132 stitle = "preso_eta" + seta(etaBins[ieta]);
0133 if (jetResponseDir[idir].find("noJEC") != std::string::npos) {
0134 sprintf(ctitle, "Raw Jet pT resolution, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0135 } else {
0136 sprintf(ctitle, "Jet pT resolution, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0137 }
0138 TH1F* h_preso = new TH1F(stitle.c_str(), ctitle, nPtBins, ptBinsArray);
0139
0140 stitle = "preso_eta" + seta(etaBins[ieta]) + "_rms";
0141 if (jetResponseDir[idir].find("noJEC") != std::string::npos) {
0142 sprintf(ctitle, "Raw Jet pT resolution using RMS, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0143 } else {
0144 sprintf(ctitle, "Jet pT resolution using RMS, %4.1f<|#eta|<%4.1f", etaBins[ieta - 1], etaBins[ieta]);
0145 }
0146 TH1F* h_preso_rms = new TH1F(stitle.c_str(), ctitle, nPtBins, ptBinsArray);
0147
0148 for (unsigned int ipt = 0; ipt < ptBins.size() - 1; ++ipt) {
0149 stitle = jetResponseDir[idir] + "reso_dist_" + spt(ptBins[ipt], ptBins[ipt + 1]) + "_eta" + seta(etaBins[ieta]);
0150 std::vector<std::string>::const_iterator it = std::find(sME_response.begin(), sME_response.end(), stitle);
0151 if (it == sME_response.end())
0152 continue;
0153 me = iget_.get(stitle);
0154 h_resp = (TH1F*)me->getTH1F();
0155
0156
0157 double resp = 1.0, resp_err = 0.0, reso = 0.0, reso_err = 0.0;
0158 fitResponse(h_resp, h_genjet_pt, ipt, ieta, recoptcut, resp, resp_err, reso, reso_err);
0159
0160 h_presponse->SetBinContent(ipt + 1, resp);
0161 h_presponse->SetBinError(ipt + 1, resp_err);
0162 h_preso->SetBinContent(ipt + 1, reso);
0163 h_preso->SetBinError(ipt + 1, reso_err);
0164
0165
0166 double std = h_resp->GetStdDev();
0167 double std_error = h_resp->GetStdDevError();
0168
0169
0170 double mean = 1.0;
0171 double mean_error = 0.0;
0172 double err = 0.0;
0173 if (h_resp->GetMean() > 0) {
0174 mean = h_resp->GetMean();
0175 mean_error = h_resp->GetMeanError();
0176
0177
0178 std /= mean;
0179 std_error /= mean;
0180
0181 err = getRespUnc(std, std_error, mean, mean_error);
0182 }
0183
0184 h_preso_rms->SetBinContent(ipt + 1, std);
0185 h_preso_rms->SetBinError(ipt + 1, err);
0186
0187 }
0188
0189 stitle = "presponse_eta" + seta(etaBins[ieta]);
0190 me = ibook_.book1D(stitle.c_str(), h_presponse);
0191 vME_presponse.push_back(me);
0192
0193 stitle = "preso_eta" + seta(etaBins[ieta]);
0194 me = ibook_.book1D(stitle.c_str(), h_preso);
0195 vME_preso.push_back(me);
0196
0197 stitle = "preso_eta" + seta(etaBins[ieta]) + "_rms";
0198 me = ibook_.book1D(stitle.c_str(), h_preso_rms);
0199 vME_preso_rms.push_back(me);
0200
0201 }
0202
0203
0204
0205
0206 if (debug) {
0207 for (std::vector<MonitorElement*>::const_iterator i = vME_presponse.begin(); i != vME_presponse.end(); ++i)
0208 (*i)->getTH1F()->Print();
0209 for (std::vector<MonitorElement*>::const_iterator i = vME_preso.begin(); i != vME_preso.end(); ++i)
0210 (*i)->getTH1F()->Print();
0211 for (std::vector<MonitorElement*>::const_iterator i = vME_preso_rms.begin(); i != vME_preso_rms.end(); ++i)
0212 (*i)->getTH1F()->Print();
0213 }
0214 }
0215 }
0216
0217 void PFJetDQMPostProcessor::fitResponse(TH1F* hreso,
0218 TH1F* h_genjet_pt,
0219 int ptbinlow,
0220 int ietahigh,
0221 double recoptcut,
0222 double& resp,
0223 double& resp_err,
0224 double& reso,
0225 double& reso_err) {
0226
0227
0228
0229
0230
0231
0232
0233 bool doPlots = false;
0234
0235 double ptlow = ptBins[ptbinlow];
0236 double pthigh = ptBins[ptbinlow + 1];
0237
0238
0239
0240 double rmswidth = hreso->GetStdDev();
0241 double rmsmean = hreso->GetMean();
0242 double fitlow = rmsmean - 1.5 * rmswidth;
0243 fitlow = TMath::Max(recoptcut / ptlow, fitlow);
0244 double fithigh = rmsmean + 1.5 * rmswidth;
0245
0246 TF1* fg = new TF1("mygaus", "gaus", fitlow, fithigh);
0247 TF1* fg2 = new TF1("fg2", "TMath::Gaus(x,[0],[1],true)*[2]", fitlow, fithigh);
0248
0249 hreso->Fit("mygaus", "RQN");
0250
0251 fg2->SetParameter(0, fg->GetParameter(1));
0252 fg2->SetParameter(1, fg->GetParameter(2));
0253
0254
0255 float ngenjet = h_genjet_pt->GetBinContent(ptbinlow + 1);
0256
0257
0258
0259
0260 fg2->FixParameter(2, ngenjet * 3. / 100.);
0261
0262 hreso->Fit("fg2", "RQN");
0263
0264 fitlow = fg2->GetParameter(0) - 1.5 * fg2->GetParameter(1);
0265 fitlow = TMath::Max(15. / ptlow, fitlow);
0266 fithigh = fg2->GetParameter(0) + 1.5 * fg2->GetParameter(1);
0267
0268 fg2->SetRange(fitlow, fithigh);
0269
0270 hreso->Fit("fg2", "RQ");
0271
0272 fg->SetRange(0, 3);
0273 fg2->SetRange(0, 3);
0274 fg->SetLineWidth(2);
0275 fg2->SetLineColor(kGreen + 2);
0276
0277 hreso->GetXaxis()->SetRangeUser(0, 2);
0278
0279
0280 if (doPlots & (hreso->GetEntries() > 0)) {
0281 TCanvas* cfit = new TCanvas(Form("respofit_%i", int(ptlow)), "respofit", 600, 600);
0282 hreso->Draw("ehist");
0283 fg->Draw("same");
0284 fg2->Draw("same");
0285 cfit->SaveAs(
0286 Form("debug/respo_smartfit_%04d_%i_eta%s.pdf", (int)ptlow, (int)pthigh, seta(etaBins[ietahigh]).c_str()));
0287 }
0288
0289 resp = fg2->GetParameter(0);
0290 resp_err = fg2->GetParError(0);
0291
0292
0293 if (0 == resp)
0294 reso = 0;
0295 else
0296 reso = fg2->GetParameter(1) / resp;
0297 reso_err = fg2->GetParError(1) / resp;
0298
0299 reso_err = getRespUnc(reso, reso_err, resp, resp_err);
0300 }
0301
0302
0303 double PFJetDQMPostProcessor::getRespUnc(double width, double width_err, double mean, double mean_err) {
0304 if (0 == width || 0 == mean)
0305 return 0;
0306 return TMath::Sqrt(pow(width_err, 2) / pow(width, 2) + pow(mean_err, 2) / pow(mean, 2)) * width;
0307 }
0308
0309 #include "FWCore/Framework/interface/MakerMacros.h"
0310 DEFINE_FWK_MODULE(PFJetDQMPostProcessor);