File indexing completed on 2024-10-08 05:11:59
0001
0002
0003
0004
0005
0006
0007
0008 #include "RecoEgamma/PhotonIdentification/interface/PhotonMIPHaloTagger.h"
0009 #include "DataFormats/DetId/interface/DetId.h"
0010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0011 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
0014
0015 PhotonMIPHaloTagger::PhotonMIPHaloTagger(const edm::ParameterSet& conf, edm::ConsumesCollector&& iC)
0016 : EBecalCollection_{iC.consumes<EcalRecHitCollection>(
0017 conf.getParameter<edm::InputTag>("barrelEcalRecHitCollection"))},
0018 yRangeFit_{conf.getParameter<double>("YRangeFit")},
0019 xRangeFit_{conf.getParameter<double>("XRangeFit")},
0020 residualWidthEnergy_{conf.getParameter<double>("ResidualWidth")},
0021 haloDiscThreshold_{conf.getParameter<double>("HaloDiscThreshold")} {}
0022
0023 reco::Photon::MIPVariables PhotonMIPHaloTagger::mipCalculate(const reco::Photon& pho,
0024 const edm::Event& e,
0025 const edm::EventSetup& es) const {
0026
0027 edm::Handle<EcalRecHitCollection> barrelHitHandle;
0028 e.getByToken(EBecalCollection_, barrelHitHandle);
0029
0030 bool validEcalRecHits = barrelHitHandle.isValid();
0031
0032 reco::Photon::MIPVariables mipId;
0033 if (validEcalRecHits) {
0034 mipId =
0035 getMipTrailFit(pho, e, es, barrelHitHandle, yRangeFit_, xRangeFit_, residualWidthEnergy_, haloDiscThreshold_);
0036 } else {
0037 edm::LogError("MIPcalculate") << "Error! Can't get the barrel hits product, hence set some default values";
0038 mipId.mipChi2 = -999.;
0039 mipId.mipTotEnergy = -999.;
0040 mipId.mipSlope = -999.;
0041 mipId.mipIntercept = -999.;
0042 mipId.mipNhitCone = 0;
0043 mipId.mipIsHalo = false;
0044 }
0045
0046
0047
0048 return mipId;
0049 }
0050
0051
0052 reco::Photon::MIPVariables PhotonMIPHaloTagger::getMipTrailFit(const reco::Photon& photon,
0053 const edm::Event& iEvent,
0054 const edm::EventSetup& iSetup,
0055 edm::Handle<EcalRecHitCollection> ecalhitsCollEB,
0056 double inputRangeY,
0057 double inputRangeX,
0058 double inputResWidth,
0059 double inputHaloDiscCut) const {
0060 constexpr bool printDebug = false;
0061
0062 if constexpr (printDebug)
0063 std::cout << " inside MipFitTrail " << std::endl;
0064
0065 const double yrange = inputRangeY;
0066 const double xrange = inputRangeX;
0067 const double res_width = inputResWidth;
0068 const double halo_disc_cut = inputHaloDiscCut;
0069
0070
0071 const double m = yrange / xrange;
0072
0073
0074 int seedIEta = -999;
0075 int seedIPhi = -999;
0076 double seedE = -999.;
0077
0078
0079 getSeedHighestE(photon, iEvent, iSetup, ecalhitsCollEB, seedIEta, seedIPhi, seedE);
0080
0081 if constexpr (printDebug)
0082 std::cout << "Seed E =" << seedE << " Seed ieta = " << seedIEta << " Seed iphi =" << seedIPhi << std::endl;
0083
0084
0085 std::vector<int> ieta_cell;
0086 std::vector<int> iphi_cell;
0087 std::vector<double> energy_cell;
0088
0089 for (auto const& hit : *ecalhitsCollEB) {
0090 const EBDetId dit = hit.detid();
0091
0092 const int iphicell = dit.iphi();
0093 int ietacell = dit.ieta();
0094
0095 if (ietacell < 0)
0096 ietacell++;
0097
0098
0099 if (std::abs(ietacell - seedIEta) >= 5 && hit.energy() > 0.) {
0100 int delt_ieta = ietacell - seedIEta;
0101 int delt_iphi = iphicell - seedIPhi;
0102
0103
0104 if (delt_iphi > 180) {
0105 delt_iphi = delt_iphi - 360;
0106 }
0107 if (delt_iphi < -180) {
0108 delt_iphi = delt_iphi + 360;
0109 }
0110
0111
0112 if (((delt_iphi >= (m * delt_ieta)) && (delt_iphi <= (-m * delt_ieta))) ||
0113 ((delt_iphi <= (m * delt_ieta)) && (delt_iphi >= (-m * delt_ieta)))) {
0114 ieta_cell.push_back(delt_ieta);
0115 iphi_cell.push_back(delt_iphi);
0116 energy_cell.push_back(hit.energy());
0117 }
0118
0119 }
0120
0121 }
0122
0123
0124
0125 int Npoints = ieta_cell.size();
0126 int throwaway_index = -1;
0127 double chi2 = 0.0;
0128 double eT = 0.;
0129 double a1 = 0.;
0130 double b1 = 0.;
0131 double hres = 99999.;
0132
0133 if constexpr (printDebug)
0134 std::cout << " starting npoints = " << Npoints << std::endl;
0135
0136
0137 for (int it = 0; it < 200 && hres > (5.0 * res_width); it++) {
0138
0139
0140 if (throwaway_index != -1) {
0141 ieta_cell.erase(ieta_cell.begin() + throwaway_index);
0142 iphi_cell.erase(iphi_cell.begin() + throwaway_index);
0143 energy_cell.erase(energy_cell.begin() + throwaway_index);
0144 Npoints--;
0145 }
0146
0147
0148 double sx = 0.0;
0149 double sy = 0.0;
0150 double ss = 0.0;
0151 double sxx = 0.0;
0152 double sxy = 0.0;
0153 double m_chi2 = 0.0;
0154 double etot_cell = 0.0;
0155
0156
0157 for (int j = 0; j < Npoints; j++) {
0158 constexpr double wt = 1.0;
0159 ss += wt;
0160 sx += ieta_cell[j] * wt;
0161 sy += iphi_cell[j];
0162 sxx += ieta_cell[j] * ieta_cell[j] * wt;
0163 sxy += ieta_cell[j] * iphi_cell[j] * wt;
0164 }
0165
0166 const double delt = ss * sxx - (sx * sx);
0167 a1 = ((sxx * sy) - (sx * sxy)) / delt;
0168 b1 = ((ss * sxy) - (sx * sy)) / delt;
0169
0170 double highest_res = 0.;
0171 int highres_index = 0;
0172
0173 for (int j = 0; j < Npoints; j++) {
0174 const double res = 1.0 * iphi_cell[j] - a1 - b1 * ieta_cell[j];
0175 const double res_sq = res * res;
0176
0177 if (std::abs(res) > highest_res) {
0178 highest_res = std::abs(res);
0179 highres_index = j;
0180 }
0181
0182 m_chi2 += res_sq;
0183 etot_cell += energy_cell[j];
0184 }
0185
0186 throwaway_index = highres_index;
0187 hres = highest_res;
0188
0189 chi2 = m_chi2 / ((Npoints - 2));
0190 chi2 = chi2 / (res_width * res_width);
0191 eT = etot_cell;
0192
0193 }
0194
0195 if constexpr (printDebug)
0196 std::cout << "hres = " << hres << std::endl;
0197
0198
0199 const std::vector<float> showershapes_barrel =
0200 EcalClusterTools::roundnessBarrelSuperClusters(*(photon.superCluster()), (*ecalhitsCollEB.product()));
0201
0202 const double roundness = showershapes_barrel[0];
0203 const double angle = showershapes_barrel[1];
0204
0205 if constexpr (printDebug)
0206 std::cout << " eTot =" << eT << " Rounness = " << roundness << " angle " << angle << std::endl;
0207
0208
0209 const double halo_disc = eT / (roundness * angle);
0210
0211
0212 reco::Photon::MIPVariables results;
0213 results.mipChi2 = chi2;
0214 results.mipTotEnergy = eT;
0215 results.mipSlope = b1;
0216 results.mipIntercept = a1;
0217 results.mipNhitCone = Npoints;
0218 results.mipIsHalo = halo_disc > halo_disc_cut;
0219
0220
0221
0222 if constexpr (printDebug)
0223 std::cout << "Endof MIP Trail: halo_dic= " << halo_disc << " nhitcone =" << results.mipNhitCone
0224 << " isHalo= " << results.mipIsHalo << std::endl;
0225 if constexpr (printDebug)
0226 std::cout << "Endof MIP Trail: Chi2 = " << chi2 << " eT= " << eT << " slope = " << b1 << " Intercept =" << a1
0227 << std::endl;
0228
0229 return results;
0230 }
0231
0232
0233 void PhotonMIPHaloTagger::getSeedHighestE(const reco::Photon& photon,
0234 const edm::Event& iEvent,
0235 const edm::EventSetup& iSetup,
0236 edm::Handle<EcalRecHitCollection> Brechit,
0237 int& seedIeta,
0238 int& seedIphi,
0239 double& seedEnergy) const {
0240 constexpr bool printDebug = false;
0241
0242 if constexpr (printDebug)
0243 std::cout << "Inside GetSeed" << std::endl;
0244
0245 double SeedE = -999.;
0246
0247
0248 seedIeta = -999;
0249 seedIphi = -999;
0250 seedEnergy = -999.;
0251
0252 std::vector<std::pair<DetId, float> > const& PhotonHit_DetIds = photon.superCluster()->hitsAndFractions();
0253 for (auto pr : PhotonHit_DetIds) {
0254 if ((pr.first).det() == DetId::Ecal && (pr.first).subdetId() == EcalBarrel) {
0255 EcalRecHitCollection::const_iterator thishit = Brechit->find((pr.first));
0256
0257 if (thishit == Brechit->end()) {
0258 continue;
0259 }
0260
0261 const EBDetId detId{pr.first};
0262
0263 const double crysE = thishit->energy();
0264
0265 if (crysE > SeedE) {
0266 SeedE = crysE;
0267 seedIeta = detId.ieta();
0268 seedIphi = (detId.iphi());
0269 seedEnergy = SeedE;
0270
0271 if constexpr (printDebug)
0272 std::cout << "Current max Seed = " << SeedE << " seedIphi = " << seedIphi << " ieta= " << seedIeta
0273 << std::endl;
0274 }
0275
0276 }
0277
0278 }
0279
0280 if constexpr (printDebug)
0281 std::cout << "End of GetSeed" << std::endl;
0282 }