25 #include "fftjet/peakEtLifetime.hh" 47 #define make_param(type, varname) const type& varname(ps.getParameter<type>(#varname)) 49 #define init_param(type, varname) varname(ps.getParameter<type>(#varname)) 58 #define jet_type_switch(method, arg1, arg2) \ 62 method<reco::CaloJet>(arg1, arg2); \ 65 method<reco::PFJet>(arg1, arg2); \ 68 method<reco::GenJet>(arg1, arg2); \ 71 method<reco::TrackJet>(arg1, arg2); \ 74 method<reco::BasicJet>(arg1, arg2); \ 77 assert(!"ERROR in FFTJetProducer : invalid jet type." \ 78 " This is a bug. Please report."); \ 83 struct LocalSortByPt {
85 inline bool operator()(
const Jet&
l,
const Jet&
r)
const {
86 return l.pt() >
r.pt();
94 if (!
name.compare(
"fixed"))
96 else if (!
name.compare(
"maximallyStable"))
97 return MAXIMALLY_STABLE;
98 else if (!
name.compare(
"globallyAdaptive"))
99 return GLOBALLY_ADAPTIVE;
100 else if (!
name.compare(
"locallyAdaptive"))
101 return LOCALLY_ADAPTIVE;
102 else if (!
name.compare(
"fromGenJets"))
105 throw cms::Exception(
"FFTJetBadConfig") <<
"Invalid resolution specification \"" <<
name <<
"\"" << std::endl;
108 template <
typename T>
110 produces<std::vector<reco::FFTAnyJet<T> > >(
tag).setBranchAlias(
alias);
154 iterationsPerformed(1
U),
158 throw cms::Exception(
"FFTJetBadConfig") <<
"Can't resum constituents if they are not assigned" << std::endl;
160 produces<reco::FFTJetProducerSummary>(
outputLabel);
197 template <
class Real>
206 if (!
input->isSparse())
207 throw cms::Exception(
"FFTJetBadConfig") <<
"The stored clustering tree is not sparse" << std::endl;
217 const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
218 std::vector<fftjet::Peak>* preclusters) {
225 const unsigned sz =
input->size();
227 for (
unsigned i = 0;
i < sz; ++
i) {
229 fftjet::Peak
p(
jet.precluster());
230 const double scale(
p.scale());
231 p.setEtaPhi(
jet.vec().Eta(),
jet.vec().Phi());
240 const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
241 std::vector<fftjet::Peak>* preclusters) {
246 const unsigned nNodes =
nodes.size();
247 const SparseTree::NodeId* pnodes = nNodes ? &
nodes[0] :
nullptr;
249 for (
unsigned i = 0;
i < nNodes; ++
i)
254 fftjet::Peak*
clusters = nNodes ? &(*preclusters)[0] :
nullptr;
255 for (
unsigned i = 0;
i < nNodes; ++
i) {
262 const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
263 std::vector<SparseTree::NodeId>* mynodes) {
278 if (
tree.stableClusterCount(
290 const int maxlev =
tree.maxStoredLevel();
291 bool levelFound =
false;
293 for (
int ifac = 1; ifac > -2 && !levelFound; ifac -= 2) {
309 const unsigned maxlev =
tree.maxStoredLevel();
336 assert(!
"ERROR in FFTJetProducer::selectTreeNodes : " 337 "should never get here! This is a bug. Please report.");
349 for (
unsigned i = 0;
i < nClus; ++
i) {
350 clus[
i].setRecoScale(scaleCalc(clus[
i]));
351 clus[
i].setRecoScaleRatio(ratioCalc(clus[
i]));
352 clus[
i].setMembershipFactor(factorCalc(clus[
i]));
365 fftjet::DefaultRecombinationAlgFactory<Real, VectorLike, BgData, VBuilder> factory;
385 bool rebuildGrid =
flow.get() ==
nullptr;
392 flow = std::make_unique<fftjet::Grid2d<Real> >(
400 fftjet::Functor2<double, RecoFFTJet, RecoFFTJet>& distanceCalc(*
jetDistanceCalc);
403 if (
nJets != nextSet.size())
410 bool converged =
true;
411 for (
unsigned i = 0;
i <
nJets; ++
i) {
412 const double d = distanceCalc(prev[
i],
next[
i]);
413 next[
i].setConvergenceDistance(
d);
427 unsigned iterNum = 1
U;
428 bool converged =
false;
434 for (
unsigned i = 0;
i <
nJets; ++
i) {
436 fftjet::Peak
p(
jet.precluster());
437 p.setEtaPhi(
jet.vec().Eta(),
jet.vec().Phi());
438 p.setRecoScale(scaleCalc(
jet));
439 p.setRecoScaleRatio(ratioCalc(
jet));
440 p.setMembershipFactor(factorCalc(
jet));
451 throw cms::Exception(
"FFTJetInterface") <<
"FFTJet algorithm failed" << std::endl;
473 for (
unsigned i = 0;
i <
nJets; ++
i) {
475 jets[
i].setPeakEtaPhi(oldp.eta(), oldp.phi());
490 const unsigned* clusterMask =
gridAlg->getClusterMask();
495 const unsigned nInputs =
eventData.size();
498 for (
unsigned i = 0;
i < nInputs; ++
i) {
500 const int iPhi =
g.getPhiBin(
item.Phi());
501 const int iEta =
g.getEtaBin(
item.Eta());
510 const unsigned* clusterMask =
recoAlg->getClusterMask();
511 const unsigned maskLength =
recoAlg->getLastNData();
514 const unsigned* candIdx = maskLength ? &
candidateIndex[0] :
nullptr;
515 for (
unsigned i = 0;
i < maskLength; ++
i) {
520 const unsigned mask = clusterMask[
i];
528 template <
typename T>
530 using namespace reco;
546 auto jets = std::make_unique<OutputCollection>();
551 double previousPt = DBL_MAX;
552 for (
unsigned ijet = 0; ijet <
nJets; ++ijet) {
561 for (
unsigned i = 0;
i < nCon; ++
i)
580 if constexpr (std::is_same_v<T, reco::CaloJet>) {
589 double ncells = myjet.ncells();
594 jet.setJetArea(cellArea * ncells);
603 jets->push_back(OutputJet(
jet, fj));
606 const double pt =
jet.pt();
630 for (
unsigned i = 0;
i < nCon; ++
i)
641 std::make_unique<reco::FFTJetProducerSummary>(
thresholds,
699 unsigned nPreclustersFound = 0
U;
701 for (
unsigned i = 0;
i < npre; ++
i)
712 throw cms::Exception(
"FFTJetInterface") <<
"FFTJet algorithm failed (first iteration)" << std::endl;
736 for (
unsigned i = 0;
i <=
nJets; ++
i)
810 std::unique_ptr<fftjet::Functor2<double, FFTJetProducer::RecoFFTJet, FFTJetProducer::RecoFFTJet> >
833 fftjet::DefaultVectorRecombinationAlgFactory<VectorLike, BgData, VBuilder> factory;
866 "invalid spec for the " 867 "reconstruction scale calculator from peaks");
872 "invalid spec for the " 873 "reconstruction scale ratio calculator from peaks");
878 "invalid spec for the " 879 "membership function factor calculator from peaks");
885 "invalid spec for the " 886 "reconstruction scale calculator from jets");
890 "invalid spec for the " 891 "reconstruction scale ratio calculator from jets");
895 "invalid spec for the " 896 "membership function factor calculator from jets");
900 "invalid spec for the " 901 "jet distance calculator");
913 std::vector<int> matchTable;
923 for (
unsigned i = 0;
i < nmatched; ++
i)
947 const unsigned nEta =
g.nEta();
948 const unsigned nPhi =
g.nPhi();
951 const double eta(
g.etaBinCenter(
ieta));
955 const double phi(
g.phiBinCenter(
iphi));
959 const double pil = calc(
eta, 0.0,
s);
976 const bool phiDependent =
f->minDim() == 3
U;
979 const unsigned nEta =
g.nEta();
980 const unsigned nPhi =
g.nPhi();
982 double functorArg[3] = {0.0, 0.0, 0.0};
989 const double eta(
g.etaBinCenter(
ieta));
994 functorArg[1] =
g.phiBinCenter(
iphi);
995 g.uncheckedSetBin(
ieta,
iphi, (*
f)(functorArg, 3
U));
998 const double pil = (*f)(functorArg, 2
U);
1008 assert(!
"Pile-up subtraction for fuzzy clustering " 1009 "is not implemented yet");
1017 for (
unsigned i = 0;
i <
nJets; ++
i)
1022 const unsigned nEta =
g.nEta();
1023 const unsigned nPhi =
g.nPhi();
1024 const double cellArea =
g.etaBinWidth() *
g.phiBinWidth();
1037 double* recoScaleRatios = recoScales +
nJets;
1038 double* memFactors = recoScaleRatios +
nJets;
1046 for (
unsigned ijet = 0; ijet <
nJets; ++ijet) {
1048 const fftjet::Peak& peak(
jet.precluster());
1052 fftjet::AbsMembershipFunction* m3d =
dynamic_cast<fftjet::AbsMembershipFunction*
>(peak.membershipFunction());
1056 assert(!
"Pile-up subtraction for 3-d membership functions " 1057 "is not implemented yet");
1059 fftjet::AbsKernel2d* m2d =
dynamic_cast<fftjet::AbsKernel2d*
>(peak.membershipFunction());
1063 memFcns2d[ijet] = m2d;
1065 recoScales[ijet] = scaleCalc(
jet);
1066 recoScaleRatios[ijet] = ratioCalc(
jet);
1067 memFactors[ijet] = factorCalc(
jet);
1068 cellCounts[ijet] = 0
U;
1074 dphi -= (2.0 *
M_PI);
1075 while (dphi < -
M_PI)
1076 dphi += (2.0 *
M_PI);
1085 const double eta(
g.etaBinCenter(
ieta));
1089 for (
unsigned ijet = 0; ijet <
nJets; ++ijet)
1094 unsigned maxWJet(
nJets);
1097 for (
unsigned ijet = 0; ijet <
nJets; ++ijet) {
1098 if (recoScaleRatios[ijet] > 0.0)
1099 memFcns2d[ijet]->setScaleRatio(recoScaleRatios[ijet]);
1100 const double f = memFactors[ijet] * (*memFcns2d[ijet])(
dEta[ijet],
dPhi[ijet], recoScales[ijet]);
1107 if (maxWJet <
nJets) {
1109 cellCounts[maxWJet]++;
void loadSparseTreeData(const edm::Event &, const edm::EDGetTokenT< reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > > &tok)
std::vector< std::vector< reco::CandidatePtr > > constituents
void produce(edm::Event &, const edm::EventSetup &) override
unsigned matchOneToOne(const std::vector< T1 > &v1, const std::vector< T2 > &v2, const DistanceCalculator &calc, std::vector< int > *matchFrom1To2, const double maxMatchingDistance=1.0e300)
edm::ESHandle< DataType > load(const std::string &record, const edm::EventSetup &iSetup) const
virtual std::unique_ptr< fftjet::ScaleSpaceKernel > parse_jetMembershipFunction(const edm::ParameterSet &)
std::unique_ptr< fftjet::Functor2< double, RecoFFTJet, RecoFFTJet > > jetDistanceCalc
T getParameter(std::string const &) const
unsigned iterationsPerformed
const bool useGriddedAlgorithm
std::vector< fftjetcms::VectorLike > pileup
edm::Handle< reco::CandidateView > inputCollection
static Resolution parse_resolution(const std::string &name)
const bool resumConstituents
void selectTreeNodes(const SparseTree &tree, const fftjet::Functor1< bool, fftjet::Peak > &peakSelect, std::vector< SparseTree::NodeId > *nodes)
Class for storing FFTJet sparse clustering trees.
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Preclusters from FFTJet pattern recognition stage.
const double gridScanMaxEta
void saveResults(edm::Event &iEvent, const edm::EventSetup &, unsigned nPreclustersFound)
virtual void assignMembershipFunctions(std::vector< fftjet::Peak > *preclusters)
std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > memberFactorCalcPeak
double getEventScale() const
void loadInputCollection(const edm::Event &)
std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > recoScaleCalcJet
const std::string recombinationAlgorithm
const bool subtractPileupAs4Vec
std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > fftjet_PeakFunctor_parser(const edm::ParameterSet &ps)
virtual std::unique_ptr< fftjetcms::AbsBgFunctor > parse_bgMembershipFunction(const edm::ParameterSet &)
fftjet::RecombinedJet< VectorLike > jetFromStorable(const reco::FFTJet< Real > &jet)
const reco::Particle::Point & vertexUsed() const
void checkConfig(const Ptr &ptr, const char *message)
const double unlikelyBgWeight
void writeSpecific(reco::CaloJet &jet, reco::Particle::LorentzVector const &p4, reco::Particle::Point const &point, std::vector< reco::CandidatePtr > const &constituents, CaloGeometry const &geometry, HcalTopology const &topology)
void makeProduces(const std::string &alias, const std::string &tag)
std::unique_ptr< AbsBgFunctor > fftjet_BgFunctor_parser(const edm::ParameterSet &ps)
const bool subtractPileup
std::unique_ptr< fftjet::Grid2d< Real > > fftjet_Grid2d_parser(const edm::ParameterSet &ps)
std::vector< double > doubleBuf
std::vector< fftjet::AbsKernel2d * > memFcns2dVec
std::vector< RecoFFTJet > recoJets
std::unique_ptr< GridAlg > gridAlg
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geometry_token_
const double recombinationDataCutoff
Summary info for pile-up determined by Gaussian filtering.
static constexpr int nJets
void acquireToken(const std::string &record, edm::ConsumesCollector iC)
std::vector< unsigned > occupancy
std::unique_ptr< T, impl::DeviceDeleter > unique_ptr
const double minStableScale
const double maxStableScale
#define init_param(type, varname)
std::vector< fftjet::Peak > preclusters
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
void determineVectorConstituents()
static std::string const input
std::unique_ptr< fftjet::Functor2< double, fftjet::RecombinedJet< VectorLike >, fftjet::RecombinedJet< VectorLike > > > fftjet_JetDistance_parser(const edm::ParameterSet &ps)
T getUntrackedParameter(std::string const &, T const &) const
const bool reuseExistingGrid
const unsigned nClustersRequested
virtual std::unique_ptr< fftjetcms::AbsPileupCalculator > parse_pileupDensityCalc(const edm::ParameterSet &ps)
std::unique_ptr< std::vector< double > > iniScales
std::vector< unsigned > candidateIndex
edm::EDGetTokenT< reco::PattRecoTree< double, reco::PattRecoPeak< double > > > input_recotree_token_d_
std::unique_ptr< fftjetcms::AbsBgFunctor > bgMembershipFunction
std::unique_ptr< fftjet::Grid2d< fftjetcms::Real > > energyFlow
virtual std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_recoScaleCalcJet(const edm::ParameterSet &)
std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > memberFactorCalcJet
math::XYZTLorentzVector VectorLike
fftjet::SparseClusteringTree< fftjet::Peak, long > SparseTree
edm::EDGetTokenT< reco::PattRecoTree< float, reco::PattRecoPeak< float > > > input_recotree_token_f_
std::unique_ptr< fftjet::Functor1< double, fftjet::RecombinedJet< VectorLike > > > fftjet_JetFunctor_parser(const edm::ParameterSet &ps)
virtual std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_recoScaleRatioCalcPeak(const edm::ParameterSet &)
Implements inheritance relationships for FFTJet jets.
static void setJetStatusBit(RecoFFTJet *jet, int mask, bool value)
std::vector< RecoFFTJet > iterJets
virtual void determinePileupDensityFromDB(const edm::Event &iEvent, const edm::EventSetup &iSetup, std::unique_ptr< fftjet::Grid2d< fftjetcms::Real > > &density)
#define DEFINE_FWK_MODULE(type)
std::vector< unsigned > cellCountsVec
std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > recoScaleRatioCalcJet
std::unique_ptr< fftjet::ScaleSpaceKernel > jetMembershipFunction
std::string pileupTableRecord
std::string pileupTableName
std::vector< double > thresholds
unsigned iterateJetReconstruction()
std::unique_ptr< AbsPileupCalculator > fftjet_PileupCalculator_parser(const edm::ParameterSet &ps)
void setNCells(const double nc)
const bool calculatePileup
const bool assignConstituents
void setPileup(const math::XYZTLorentzVector &p)
bool checkConvergence(const std::vector< RecoFFTJet > &previousIterResult, std::vector< RecoFFTJet > &thisIterResult)
const edm::InputTag treeLabel
virtual void selectPreclusters(const SparseTree &tree, const fftjet::Functor1< bool, fftjet::Peak > &peakSelector, std::vector< fftjet::Peak > *preclusters)
void sparsePeakTreeFromStorable(const reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > &in, const std::vector< double > *scaleSetIfNotAdaptive, double completeEventScale, fftjet::SparseClusteringTree< fftjet::Peak, long > *out)
bool storeInSinglePrecision() const
const edm::InputTag genJetsLabel
const edm::ParameterSet myConfiguration
edm::EDGetTokenT< reco::DiscretizedEnergyFlow > input_energyflow_token_
fftjet::RecombinedJet< fftjetcms::VectorLike > RecoFFTJet
virtual std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_recoScaleRatioCalcJet(const edm::ParameterSet &)
edm::ESGetToken< HcalTopology, HcalRecNumberingRecord > topology_token_
edm::EDGetTokenT< reco::FFTJetPileupSummary > input_pusummary_token_
const double stabilityAlpha
void beginStream(edm::StreamID) override
void discretizeEnergyFlow()
const unsigned maxInitialPreclusters
std::string pileupTableCategory
std::unique_ptr< fftjetcms::AbsPileupCalculator > pileupDensityCalc
void setFourVec(const math::XYZTLorentzVector &p)
std::vector< SparseTree::NodeId > nodes
std::unique_ptr< fftjet::Functor1< bool, fftjet::Peak > > fftjet_PeakSelector_parser(const edm::ParameterSet &ps)
void determineGriddedConstituents()
std::unique_ptr< fftjet::Functor1< bool, fftjet::Peak > > peakSelector
const double convergenceDistance
edm::EDGetTokenT< std::vector< reco::FFTAnyJet< reco::GenJet > > > input_genjet_token_
void writeJets(edm::Event &iEvent, const edm::EventSetup &)
~FFTJetProducer() override
std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > recoScaleRatioCalcPeak
const edm::InputTag pileupLabel
virtual std::unique_ptr< fftjet::Functor1< bool, fftjet::Peak > > parse_peakSelector(const edm::ParameterSet &)
#define jet_type_switch(method, arg1, arg2)
std::unique_ptr< fftjet::Grid2d< fftjetcms::Real > > pileupEnergyFlow
virtual void genJetPreclusters(const SparseTree &tree, edm::Event &, const edm::EventSetup &, const fftjet::Functor1< bool, fftjet::Peak > &peakSelector, std::vector< fftjet::Peak > *preclusters)
bool loadEnergyFlow(const edm::Event &iEvent, std::unique_ptr< fftjet::Grid2d< fftjetcms::Real > > &flow)
virtual bool isPhiDependent() const =0
std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > recoScaleCalcPeak
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
FFTJetLookupTableSequenceLoader esLoader_
std::unique_ptr< std::vector< double > > fftjet_ScaleSet_parser(const edm::ParameterSet &ps)
std::unique_ptr< RecoAlg > recoAlg
std::vector< fftjetcms::VectorLike > eventData
virtual std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_memberFactorCalcPeak(const edm::ParameterSet &)
const std::string outputLabel
math::XYZTLorentzVector adjustForPileup(const math::XYZTLorentzVector &jet, const math::XYZTLorentzVector &pileup, bool subtractPileupAs4Vec)
fftjetcms::VectorLike unclustered
virtual std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_recoScaleCalcPeak(const edm::ParameterSet &)
std::vector< fftjet::Peak > iterPreclusters
virtual void determinePileupDensityFromConfig(const edm::Event &iEvent, std::unique_ptr< fftjet::Grid2d< fftjetcms::Real > > &density)
void removeFakePreclusters()
std::unique_ptr< fftjet::ScaleSpaceKernel > fftjet_MembershipFunction_parser(const edm::ParameterSet &ps)
const unsigned maxIterations
void prepareRecombinationScales()
virtual std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_memberFactorCalcJet(const edm::ParameterSet &)
virtual std::unique_ptr< fftjet::Functor2< double, RecoFFTJet, RecoFFTJet > > parse_jetDistanceCalc(const edm::ParameterSet &)