File indexing completed on 2024-04-06 12:25:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "RecoHI/HiJetAlgos/plugins/HiFJGridEmptyAreaCalculator.h"
0013 using namespace std;
0014 using namespace edm;
0015
0016 HiFJGridEmptyAreaCalculator::HiFJGridEmptyAreaCalculator(const edm::ParameterSet& iConfig)
0017 : gridWidth_(iConfig.getParameter<double>("gridWidth")),
0018 band_(iConfig.getParameter<double>("bandWidth")),
0019 hiBinCut_(iConfig.getParameter<int>("hiBinCut")),
0020 doCentrality_(iConfig.getParameter<bool>("doCentrality")),
0021 keepGridInfo_(iConfig.getParameter<bool>("keepGridInfo")) {
0022 ymin_ = -99;
0023 ymax_ = -99;
0024 dy_ = -99;
0025 dphi_ = -99;
0026 tileArea_ = -99;
0027
0028 dyJet_ = 99;
0029 yminJet_ = -99;
0030 ymaxJet_ = -99;
0031 totalInboundArea_ = -99;
0032 etaminJet_ = -99;
0033 etamaxJet_ = -99;
0034
0035 ny_ = 0;
0036 nphi_ = 0;
0037 ntotal_ = 0;
0038
0039 ntotalJet_ = 0;
0040 nyJet_ = 0;
0041
0042 pfCandsToken_ = consumes<reco::CandidateView>(iConfig.getParameter<edm::InputTag>("pfCandSource"));
0043 mapEtaToken_ = consumes<std::vector<double>>(iConfig.getParameter<edm::InputTag>("mapEtaEdges"));
0044 mapRhoToken_ = consumes<std::vector<double>>(iConfig.getParameter<edm::InputTag>("mapToRho"));
0045 mapRhoMToken_ = consumes<std::vector<double>>(iConfig.getParameter<edm::InputTag>("mapToRhoM"));
0046 jetsToken_ = consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jetSource"));
0047 centralityBinToken_ = consumes<int>(iConfig.getParameter<edm::InputTag>("CentralityBinSrc"));
0048
0049
0050 produces<std::vector<double>>("mapEmptyCorrFac");
0051 produces<std::vector<double>>("mapToRhoCorr");
0052 produces<std::vector<double>>("mapToRhoMCorr");
0053 produces<std::vector<double>>("mapToRhoCorr1Bin");
0054 produces<std::vector<double>>("mapToRhoMCorr1Bin");
0055
0056 if (keepGridInfo_) {
0057 produces<std::vector<double>>("mapRhoVsEtaGrid");
0058 produces<std::vector<double>>("mapMeanRhoVsEtaGrid");
0059 produces<std::vector<double>>("mapEtaMaxGrid");
0060 produces<std::vector<double>>("mapEtaMinGrid");
0061 }
0062 }
0063
0064 HiFJGridEmptyAreaCalculator::~HiFJGridEmptyAreaCalculator() {
0065
0066
0067 }
0068
0069 void HiFJGridEmptyAreaCalculator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0070 using namespace edm;
0071
0072 edm::Handle<std::vector<double>> mapEtaRanges;
0073 iEvent.getByToken(mapEtaToken_, mapEtaRanges);
0074
0075 edm::Handle<std::vector<double>> mapRho;
0076 iEvent.getByToken(mapRhoToken_, mapRho);
0077
0078 edm::Handle<std::vector<double>> mapRhoM;
0079 iEvent.getByToken(mapRhoMToken_, mapRhoM);
0080
0081
0082
0083 int hiBin = -1;
0084 bool doEmptyArea = true;
0085 if (doCentrality_) {
0086 edm::Handle<int> cbin;
0087 iEvent.getByToken(centralityBinToken_, cbin);
0088 hiBin = *cbin;
0089
0090 if (hiBin < hiBinCut_)
0091 doEmptyArea = false;
0092 }
0093
0094
0095 int neta = (int)mapEtaRanges->size();
0096
0097 auto mapToRhoCorrOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0098 auto mapToRhoMCorrOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0099 auto mapToRhoCorr1BinOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0100 auto mapToRhoMCorr1BinOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0101
0102 setupGrid(mapEtaRanges->at(0), mapEtaRanges->at(neta - 1));
0103
0104
0105 double allAcceptanceCorr = 1;
0106 if (doEmptyArea) {
0107 etaminJet_ = mapEtaRanges->at(0) - band_;
0108 etamaxJet_ = mapEtaRanges->at(neta - 1) + band_;
0109
0110 calculateAreaFractionOfJets(iEvent, iSetup);
0111
0112 allAcceptanceCorr = totalInboundArea_;
0113 }
0114
0115
0116 for (int ieta = 0; ieta < (neta - 1); ieta++) {
0117 double correctionKt = 1;
0118 double rho = mapRho->at(ieta);
0119 double rhoM = mapRhoM->at(ieta);
0120
0121 if (doEmptyArea) {
0122 double etamin = mapEtaRanges->at(ieta);
0123 double etamax = mapEtaRanges->at(ieta + 1);
0124
0125 etaminJet_ = etamin + band_;
0126 etamaxJet_ = etamax - band_;
0127
0128 calculateAreaFractionOfJets(iEvent, iSetup);
0129 correctionKt = totalInboundArea_;
0130 }
0131
0132 mapToRhoCorrOut->at(ieta) = correctionKt * rho;
0133 mapToRhoMCorrOut->at(ieta) = correctionKt * rhoM;
0134
0135 mapToRhoCorr1BinOut->at(ieta) = allAcceptanceCorr * rho;
0136 mapToRhoMCorr1BinOut->at(ieta) = allAcceptanceCorr * rhoM;
0137 }
0138
0139 iEvent.put(std::move(mapToRhoCorrOut), "mapToRhoCorr");
0140 iEvent.put(std::move(mapToRhoMCorrOut), "mapToRhoMCorr");
0141 iEvent.put(std::move(mapToRhoCorr1BinOut), "mapToRhoCorr1Bin");
0142 iEvent.put(std::move(mapToRhoMCorr1BinOut), "mapToRhoMCorr1Bin");
0143
0144
0145
0146 auto mapRhoVsEtaGridOut = std::make_unique<std::vector<double>>(ny_, 0.);
0147 auto mapMeanRhoVsEtaGridOut = std::make_unique<std::vector<double>>(ny_, 0.);
0148 auto mapEtaMaxGridOut = std::make_unique<std::vector<double>>(ny_, 0.);
0149 auto mapEtaMinGridOut = std::make_unique<std::vector<double>>(ny_, 0.);
0150 calculateGridRho(iEvent, iSetup);
0151 if (keepGridInfo_) {
0152 for (int ieta = 0; ieta < ny_; ieta++) {
0153 mapRhoVsEtaGridOut->at(ieta) = rhoVsEta_[ieta];
0154 mapMeanRhoVsEtaGridOut->at(ieta) = meanRhoVsEta_[ieta];
0155 mapEtaMaxGridOut->at(ieta) = etaMaxGrid_[ieta];
0156 mapEtaMinGridOut->at(ieta) = etaMinGrid_[ieta];
0157 }
0158
0159 iEvent.put(std::move(mapRhoVsEtaGridOut), "mapRhoVsEtaGrid");
0160 iEvent.put(std::move(mapMeanRhoVsEtaGridOut), "mapMeanRhoVsEtaGrid");
0161 iEvent.put(std::move(mapEtaMaxGridOut), "mapEtaMaxGrid");
0162 iEvent.put(std::move(mapEtaMinGridOut), "mapEtaMinGrid");
0163 }
0164 }
0165
0166
0167
0168
0169
0170
0171 void HiFJGridEmptyAreaCalculator::calculateGridRho(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0172 vector<vector<double>> scalarPt(ny_, vector<double>(nphi_, 0.0));
0173
0174 edm::Handle<reco::CandidateView> pfCands;
0175 iEvent.getByToken(pfCandsToken_, pfCands);
0176 const auto& pfCandidateColl = pfCands.product();
0177 for (const auto& pfCandidate : *pfCandidateColl) {
0178
0179 if (pfCandidate.eta() < ymin_ || pfCandidate.eta() > ymax_)
0180 continue;
0181 int jeta = tileIndexEta(&pfCandidate);
0182 int jphi = tileIndexPhi(&pfCandidate);
0183 scalarPt[jeta][jphi] += pfCandidate.pt();
0184 }
0185
0186 rhoVsEta_.resize(ny_);
0187 meanRhoVsEta_.resize(ny_);
0188 for (int jeta = 0; jeta < ny_; jeta++) {
0189 rhoVsEta_[jeta] = 0;
0190 meanRhoVsEta_[jeta] = 0;
0191 vector<double> rhoVsPhi;
0192 int nEmpty = 0;
0193
0194 for (int jphi = 0; jphi < nphi_; jphi++) {
0195 double binpt = scalarPt[jeta][jphi];
0196 meanRhoVsEta_[jeta] += binpt;
0197
0198 if (binpt > 0)
0199 rhoVsPhi.push_back(binpt);
0200 else
0201 nEmpty++;
0202 }
0203 meanRhoVsEta_[jeta] /= ((double)nphi_);
0204 meanRhoVsEta_[jeta] /= tileArea_;
0205
0206
0207 sort(rhoVsPhi.begin(), rhoVsPhi.end());
0208
0209 int nFull = nphi_ - nEmpty;
0210 if (nFull == 0) {
0211 rhoVsEta_[jeta] = 0;
0212 continue;
0213 }
0214 if (nFull % 2 == 0) {
0215 rhoVsEta_[jeta] = (rhoVsPhi[(int)(nFull / 2 - 1)] + rhoVsPhi[(int)(nFull / 2)]) / 2;
0216 } else {
0217 rhoVsEta_[jeta] = rhoVsPhi[(int)(nFull / 2)];
0218 }
0219
0220 rhoVsEta_[jeta] *= (((double)nFull) / ((double)nphi_));
0221
0222 rhoVsEta_[jeta] /= tileArea_;
0223 }
0224 }
0225
0226 void HiFJGridEmptyAreaCalculator::calculateAreaFractionOfJets(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0227 edm::Handle<edm::View<reco::Jet>> jets;
0228 iEvent.getByToken(jetsToken_, jets);
0229
0230
0231 totalInboundArea_ = 0;
0232
0233 for (const auto& jet : *jets) {
0234 if (jet.eta() < etaminJet_ || jet.eta() > etamaxJet_)
0235 continue;
0236
0237 double areaKt = jet.jetArea();
0238 setupGridJet(&jet);
0239 std::vector<std::pair<int, int>> pfIndicesJet;
0240 std::vector<std::pair<int, int>> pfIndicesJetInbound;
0241 int nConstitJet = 0;
0242 int nConstitJetInbound = 0;
0243 for (const auto& daughter : jet.getJetConstituentsQuick()) {
0244 auto pfCandidate = static_cast<const reco::PFCandidate*>(daughter);
0245
0246 int jeta = tileIndexEtaJet(&*pfCandidate);
0247 int jphi = tileIndexPhi(&*pfCandidate);
0248 pfIndicesJet.push_back(std::make_pair(jphi, jeta));
0249 nConstitJet++;
0250 if (pfCandidate->eta() < etaminJet_ && pfCandidate->eta() > etamaxJet_)
0251 continue;
0252 pfIndicesJetInbound.push_back(std::make_pair(jphi, jeta));
0253 nConstitJetInbound++;
0254 }
0255
0256
0257 if (nConstitJet == nConstitJetInbound) {
0258 totalInboundArea_ += areaKt;
0259 continue;
0260 }
0261
0262
0263
0264 int nthis = 0;
0265 if (nConstitJet > 0)
0266 nthis = numJetGridCells(pfIndicesJet);
0267
0268 int nthisInbound = 0;
0269 if (nConstitJetInbound > 0)
0270 nthisInbound = numJetGridCells(pfIndicesJetInbound);
0271
0272 double fractionArea = ((double)nthisInbound) / ((double)nthis);
0273 totalInboundArea_ += areaKt * fractionArea;
0274 }
0275
0276
0277 totalInboundArea_ /= ((etamaxJet_ - etaminJet_) * twopi_);
0278
0279
0280
0281 if (totalInboundArea_ > 1)
0282 totalInboundArea_ = 1;
0283 }
0284
0285
0286
0287
0288
0289
0290 void HiFJGridEmptyAreaCalculator::setupGrid(double etamin, double etamax) {
0291
0292
0293
0294 ymin_ = etamin;
0295 ymax_ = etamax;
0296
0297 assert(ymax_ - ymin_ >= gridWidth_);
0298
0299
0300
0301 double nyDouble = (ymax_ - ymin_) / gridWidth_;
0302 ny_ = int(nyDouble + 0.5);
0303 dy_ = (ymax_ - ymin_) / ny_;
0304
0305 nphi_ = int(twopi_ / gridWidth_ + 0.5);
0306 dphi_ = twopi_ / nphi_;
0307
0308
0309 assert(ny_ >= 1 && nphi_ >= 1);
0310
0311 ntotal_ = nphi_ * ny_;
0312
0313 tileArea_ = dy_ * dphi_;
0314
0315 etaMaxGrid_.resize(ny_);
0316 etaMinGrid_.resize(ny_);
0317 for (int jeta = 0; jeta < ny_; jeta++) {
0318 etaMinGrid_[jeta] = etamin + dy_ * ((double)jeta);
0319 etaMaxGrid_[jeta] = etamin + dy_ * ((double)jeta + 1.);
0320 }
0321 }
0322
0323
0324
0325 int HiFJGridEmptyAreaCalculator::tileIndexPhi(const reco::Candidate* pfCand) {
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 int iphi = int((pfCand->phi() + (twopi_ / 2.)) / dphi_);
0338 assert(iphi >= 0 && iphi <= nphi_);
0339 if (iphi == nphi_)
0340 iphi = 0;
0341
0342 return iphi;
0343 }
0344
0345
0346
0347 int HiFJGridEmptyAreaCalculator::tileIndexEta(const reco::Candidate* pfCand) {
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 int iy = int(floor((pfCand->eta() - ymin_) / dy_));
0359 if (iy < 0 || iy >= ny_)
0360 return -1;
0361
0362 assert(iy < ny_ && iy >= 0);
0363
0364 return iy;
0365 }
0366
0367
0368
0369
0370
0371
0372 void HiFJGridEmptyAreaCalculator::setupGridJet(const reco::Jet* jet) {
0373
0374
0375
0376 yminJet_ = jet->eta() - 0.6;
0377 ymaxJet_ = jet->eta() + 0.6;
0378
0379 assert(ymaxJet_ - yminJet_ >= gridWidth_);
0380
0381
0382
0383 double nyDouble = (ymaxJet_ - yminJet_) / gridWidth_;
0384 nyJet_ = int(nyDouble + 0.5);
0385 dyJet_ = (ymaxJet_ - yminJet_) / nyJet_;
0386
0387 assert(nyJet_ >= 1);
0388
0389 ntotalJet_ = nphi_ * nyJet_;
0390
0391 }
0392
0393
0394
0395 int HiFJGridEmptyAreaCalculator::tileIndexEtaJet(const reco::Candidate* pfCand) {
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 int iyjet = int(floor((pfCand->eta() - yminJet_) / dy_));
0407 if (iyjet < 0 || iyjet >= nyJet_)
0408 return -1;
0409
0410 assert(iyjet < nyJet_ && iyjet >= 0);
0411
0412 return iyjet;
0413 }
0414
0415 int HiFJGridEmptyAreaCalculator::numJetGridCells(std::vector<std::pair<int, int>>& indices) {
0416 int ngrid = 0;
0417
0418 std::sort(indices.begin(), indices.end());
0419 int lowestJPhi = indices[0].first;
0420 int lowestJEta = indices[0].second;
0421 int highestJEta = lowestJEta;
0422
0423
0424 for (const auto& index : indices) {
0425 int jphi = index.first;
0426 int jeta = index.second;
0427 if (jphi == lowestJPhi) {
0428 if (jeta < lowestJEta)
0429 lowestJEta = jeta;
0430 if (jeta > highestJEta)
0431 highestJEta = jeta;
0432 } else {
0433 lowestJPhi = jphi;
0434 ngrid += highestJEta - lowestJEta + 1;
0435 lowestJEta = jeta;
0436 highestJEta = jeta;
0437 }
0438 }
0439 ngrid += highestJEta - lowestJEta + 1;
0440 return ngrid;
0441 }
0442
0443 void HiFJGridEmptyAreaCalculator::beginStream(edm::StreamID) {}
0444
0445 void HiFJGridEmptyAreaCalculator::endStream() {}
0446
0447 void HiFJGridEmptyAreaCalculator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0448 edm::ParameterSetDescription desc;
0449 desc.add<edm::InputTag>("jetSource", edm::InputTag("kt4PFJets"));
0450 desc.add<edm::InputTag>("CentralityBinSrc", edm::InputTag("centralityBin"));
0451 desc.add<edm::InputTag>("mapEtaEdges", edm::InputTag("mapEtaEdges"));
0452 desc.add<edm::InputTag>("mapToRho", edm::InputTag("mapToRho"));
0453 desc.add<edm::InputTag>("mapToRhoM", edm::InputTag("mapToRhoM"));
0454 desc.add<edm::InputTag>("pfCandSource", edm::InputTag("particleFlow"));
0455 desc.add<double>("gridWidth", 0.05);
0456 desc.add<double>("bandWidth", 0.2);
0457 desc.add<bool>("doCentrality", true);
0458 desc.add<int>("hiBinCut", 100);
0459 desc.add<bool>("keepGridInfo", false);
0460 descriptions.add("hiFJGridEmptyAreaCalculator", desc);
0461 }
0462
0463 DEFINE_FWK_MODULE(HiFJGridEmptyAreaCalculator);