File indexing completed on 2024-04-06 12:25:32
0001 #include "FWCore/Framework/interface/MakerMacros.h"
0002 #include "RecoJets/JetProducers/plugins/CSJetProducer.h"
0003
0004 #include <memory>
0005
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 #include "RecoJets/JetProducers/interface/JetSpecific.h"
0008
0009 #include "Math/ProbFuncMathCore.h"
0010
0011 #include "fastjet/contrib/ConstituentSubtractor.hh"
0012
0013 using namespace std;
0014 using namespace reco;
0015 using namespace edm;
0016 using namespace cms;
0017
0018 CSJetProducer::CSJetProducer(edm::ParameterSet const& conf)
0019 : VirtualJetProducer(conf),
0020 csRParam_(-1.0),
0021 csAlpha_(0.),
0022 useModulatedRho_(conf.getParameter<bool>("useModulatedRho")),
0023 minFlowChi2Prob_(conf.getParameter<double>("minFlowChi2Prob")),
0024 maxFlowChi2Prob_(conf.getParameter<double>("maxFlowChi2Prob")) {
0025
0026 etaToken_ = consumes<std::vector<double>>(conf.getParameter<edm::InputTag>("etaMap"));
0027 rhoToken_ = consumes<std::vector<double>>(conf.getParameter<edm::InputTag>("rho"));
0028 rhomToken_ = consumes<std::vector<double>>(conf.getParameter<edm::InputTag>("rhom"));
0029 csRParam_ = conf.getParameter<double>("csRParam");
0030 csAlpha_ = conf.getParameter<double>("csAlpha");
0031 if (useModulatedRho_)
0032 rhoFlowFitParamsToken_ = consumes<std::vector<double>>(conf.getParameter<edm::InputTag>("rhoFlowFitParams"));
0033 }
0034
0035 void CSJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0036
0037 VirtualJetProducer::produce(iEvent, iSetup);
0038
0039
0040
0041 fjClusterSeq_.reset();
0042 }
0043
0044
0045 void CSJetProducer::runAlgorithm(edm::Event& iEvent, edm::EventSetup const& iSetup) {
0046
0047 if (!doAreaFastjet_ && !doRhoFastjet_) {
0048 fjClusterSeq_ = std::make_shared<fastjet::ClusterSequence>(fjInputs_, *fjJetDefinition_);
0049 } else if (voronoiRfact_ <= 0) {
0050 fjClusterSeq_ =
0051 ClusterSequencePtr(new fastjet::ClusterSequenceArea(fjInputs_, *fjJetDefinition_, *fjAreaDefinition_));
0052 } else {
0053 fjClusterSeq_ = ClusterSequencePtr(
0054 new fastjet::ClusterSequenceVoronoiArea(fjInputs_, *fjJetDefinition_, fastjet::VoronoiAreaSpec(voronoiRfact_)));
0055 }
0056
0057 fjJets_.clear();
0058 std::vector<fastjet::PseudoJet> tempJets = fastjet::sorted_by_pt(fjClusterSeq_->inclusive_jets(jetPtMin_));
0059
0060
0061 edm::Handle<std::vector<double>> etaRanges;
0062 edm::Handle<std::vector<double>> rhoRanges;
0063 edm::Handle<std::vector<double>> rhomRanges;
0064 edm::Handle<std::vector<double>> rhoFlowFitParams;
0065 iEvent.getByToken(etaToken_, etaRanges);
0066 iEvent.getByToken(rhoToken_, rhoRanges);
0067 iEvent.getByToken(rhomToken_, rhomRanges);
0068 if (useModulatedRho_)
0069 iEvent.getByToken(rhoFlowFitParamsToken_, rhoFlowFitParams);
0070
0071
0072 unsigned int bkgVecSize = etaRanges->size();
0073 if (bkgVecSize < 1) {
0074 throw cms::Exception("WrongBkgInput") << "Producer needs vector with background estimates\n";
0075 }
0076 if (bkgVecSize != (rhoRanges->size() + 1) || bkgVecSize != (rhomRanges->size() + 1)) {
0077 throw cms::Exception("WrongBkgInput")
0078 << "Size of etaRanges (" << bkgVecSize << ") and rhoRanges (" << rhoRanges->size() << ") and/or rhomRanges ("
0079 << rhomRanges->size() << ") vectors inconsistent\n";
0080 }
0081 bool minProb = false;
0082 bool maxProb = false;
0083 if (useModulatedRho_) {
0084 if (!rhoFlowFitParams->empty()) {
0085 int chi2index = rhoFlowFitParams->size() - 3;
0086 double val = ROOT::Math::chisquared_cdf_c(rhoFlowFitParams->at(chi2index), rhoFlowFitParams->at(chi2index + 1));
0087 minProb = val > minFlowChi2Prob_;
0088 maxProb = val < maxFlowChi2Prob_;
0089 }
0090 }
0091
0092
0093
0094 for (fastjet::PseudoJet& ijet : tempJets) {
0095
0096
0097 std::vector<fastjet::PseudoJet> particles, ghosts;
0098 fastjet::SelectorIsPureGhost().sift(ijet.constituents(), ghosts, particles);
0099 unsigned long nParticles = particles.size();
0100 if (nParticles == 0)
0101 continue;
0102
0103
0104 for (fastjet::PseudoJet& ighost : ghosts) {
0105 double rhoModulationFactor = 1.;
0106 double ghostPhi = ighost.phi_std();
0107
0108 if (useModulatedRho_) {
0109 if (!rhoFlowFitParams->empty()) {
0110 if (minProb && maxProb) {
0111 rhoModulationFactor = getModulatedRhoFactor(ghostPhi, rhoFlowFitParams);
0112 }
0113 }
0114 }
0115
0116 int32_t ghostPos = -1;
0117 auto const ighostEta = ighost.eta();
0118 if (ighostEta <= etaRanges->at(0) || bkgVecSize == 1) {
0119 ghostPos = 0;
0120 } else if (ighostEta >= etaRanges->at(bkgVecSize - 1)) {
0121 ghostPos = rhoRanges->size() - 1;
0122 } else {
0123 for (unsigned int ie = 0; ie < (bkgVecSize - 1); ie++) {
0124 if (ighostEta >= etaRanges->at(ie) && ighostEta < etaRanges->at(ie + 1)) {
0125 ghostPos = ie;
0126 break;
0127 }
0128 }
0129 }
0130 double pt = rhoRanges->at(ghostPos) * ighost.area() * rhoModulationFactor;
0131 double mass_squared =
0132 std::pow(rhoModulationFactor * rhomRanges->at(ghostPos) * ighost.area() + pt, 2) - std::pow(pt, 2);
0133 double mass = (mass_squared > 0) ? sqrt(mass_squared) : 0;
0134 ighost.reset_momentum_PtYPhiM(pt, ighost.rap(), ighost.phi(), mass);
0135 }
0136
0137
0138
0139
0140 fastjet::contrib::ConstituentSubtractor subtractor;
0141 subtractor.set_distance_type(fastjet::contrib::ConstituentSubtractor::deltaR);
0142 subtractor.set_max_distance(
0143 csRParam_);
0144 subtractor.set_alpha(
0145 csAlpha_);
0146 subtractor.set_do_mass_subtraction();
0147 subtractor.set_remove_all_zero_pt_particles(true);
0148
0149 std::vector<fastjet::PseudoJet> subtracted_particles = subtractor.do_subtraction(particles, ghosts);
0150
0151
0152 fastjet::PseudoJet subtracted_jet = join(subtracted_particles);
0153 if (subtracted_jet.perp() > jetPtMin_)
0154 fjJets_.push_back(subtracted_jet);
0155 }
0156 fjJets_ = fastjet::sorted_by_pt(fjJets_);
0157 }
0158
0159 void CSJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0160 edm::ParameterSetDescription descCSJetProducer;
0161
0162 fillDescriptionsFromCSJetProducer(descCSJetProducer);
0163
0164 descCSJetProducer.add<string>("jetCollInstanceName", "");
0165 VirtualJetProducer::fillDescriptionsFromVirtualJetProducer(descCSJetProducer);
0166 descCSJetProducer.add<bool>("sumRecHits", false);
0167
0168
0169 descriptions.add("CSJetProducer", descCSJetProducer);
0170 }
0171
0172 void CSJetProducer::fillDescriptionsFromCSJetProducer(edm::ParameterSetDescription& desc) {
0173 desc.add<double>("csRParam", -1.);
0174 desc.add<double>("csAlpha", 2.);
0175 desc.add<bool>("useModulatedRho", false);
0176 desc.add<double>("minFlowChi2Prob", 0.05);
0177 desc.add<double>("maxFlowChi2Prob", 0.95);
0178 desc.add<edm::InputTag>("etaMap", {"hiFJRhoProducer", "mapEtaEdges"});
0179 desc.add<edm::InputTag>("rho", {"hiFJRhoProducer", "mapToRho"});
0180 desc.add<edm::InputTag>("rhom", {"hiFJRhoProducer", "mapToRhoM"});
0181 desc.add<edm::InputTag>("rhoFlowFitParams", {"hiFJRhoFlowModulationProducer", "rhoFlowFitParams"});
0182 }
0183
0184 double CSJetProducer::getModulatedRhoFactor(const double phi, const edm::Handle<std::vector<double>>& flowComponents) {
0185
0186
0187 int nFlow = (flowComponents->size() - 4) / 2;
0188 double modulationValue = 1;
0189 double firstFlowComponent = flowComponents->at(nFlow * 2 + 3);
0190 for (int iFlow = 0; iFlow < nFlow; iFlow++) {
0191 modulationValue += 2.0 * flowComponents->at(2 * iFlow + 1) *
0192 cos((iFlow + firstFlowComponent) * (phi - flowComponents->at(2 * iFlow + 2)));
0193 }
0194 return modulationValue;
0195 }
0196
0197
0198
0199
0200
0201 DEFINE_FWK_MODULE(CSJetProducer);