CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
FFTJetProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FFTJetProducers
4 // Class: FFTJetProducer
5 //
13 //
14 // Original Author: Igor Volobouev
15 // Created: Sun Jun 20 14:32:36 CDT 2010
16 //
17 //
18 
19 #include <algorithm>
20 #include <fstream>
21 #include <functional>
22 #include <iostream>
23 #include <memory>
24 
25 #include "fftjet/peakEtLifetime.hh"
26 
27 // Header for this class
29 
30 // Framework include files
33 
34 // Data formats
39 
43 
44 // Loader for the lookup tables
46 
47 #define make_param(type, varname) const type& varname(ps.getParameter<type>(#varname))
48 
49 #define init_param(type, varname) varname(ps.getParameter<type>(#varname))
50 
51 // A generic switch statement based on jet type.
52 // Defining it in a single place avoids potential errors
53 // in case another jet type is introduced in the future.
54 //
55 // JPTJet is omitted for now: there is no reco::writeSpecific method
56 // for it (see header JetSpecific.h in the JetProducers package)
57 //
58 #define jet_type_switch(method, arg1, arg2) \
59  do { \
60  switch (jetType) { \
61  case CALOJET: \
62  method<reco::CaloJet>(arg1, arg2); \
63  break; \
64  case PFJET: \
65  method<reco::PFJet>(arg1, arg2); \
66  break; \
67  case GENJET: \
68  method<reco::GenJet>(arg1, arg2); \
69  break; \
70  case TRACKJET: \
71  method<reco::TrackJet>(arg1, arg2); \
72  break; \
73  case BASICJET: \
74  method<reco::BasicJet>(arg1, arg2); \
75  break; \
76  default: \
77  assert(!"ERROR in FFTJetProducer : invalid jet type."\
78  " This is a bug. Please report."); \
79  } \
80  } while (0);
81 
82 namespace {
83  struct LocalSortByPt {
84  template <class Jet>
85  inline bool operator()(const Jet& l, const Jet& r) const {
86  return l.pt() > r.pt();
87  }
88  };
89 } // namespace
90 
91 using namespace fftjetcms;
92 
94  if (!name.compare("fixed"))
95  return 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"))
103  return FROM_GENJETS;
104  else
105  throw cms::Exception("FFTJetBadConfig") << "Invalid resolution specification \"" << name << "\"" << std::endl;
106 }
107 
108 template <typename T>
110  produces<std::vector<reco::FFTAnyJet<T> > >(tag).setBranchAlias(alias);
111 }
112 
113 //
114 // constructors and destructor
115 //
117  : FFTJetInterface(ps),
118  myConfiguration(ps),
119  init_param(edm::InputTag, treeLabel),
120  init_param(bool, useGriddedAlgorithm),
121  init_param(bool, reuseExistingGrid),
122  init_param(unsigned, maxIterations),
123  init_param(unsigned, nJetsRequiredToConverge),
124  init_param(double, convergenceDistance),
125  init_param(bool, assignConstituents),
126  init_param(bool, resumConstituents),
127  init_param(bool, calculatePileup),
128  init_param(bool, subtractPileup),
129  init_param(bool, subtractPileupAs4Vec),
130  init_param(edm::InputTag, pileupLabel),
131  init_param(double, fixedScale),
132  init_param(double, minStableScale),
133  init_param(double, maxStableScale),
134  init_param(double, stabilityAlpha),
135  init_param(double, noiseLevel),
136  init_param(unsigned, nClustersRequested),
137  init_param(double, gridScanMaxEta),
138  init_param(std::string, recombinationAlgorithm),
139  init_param(bool, isCrisp),
140  init_param(double, unlikelyBgWeight),
141  init_param(double, recombinationDataCutoff),
142  init_param(edm::InputTag, genJetsLabel),
143  init_param(unsigned, maxInitialPreclusters),
144  resolution(parse_resolution(ps.getParameter<std::string>("resolution"))),
145  init_param(std::string, pileupTableRecord),
146  init_param(std::string, pileupTableName),
147  init_param(std::string, pileupTableCategory),
148  init_param(bool, loadPileupFromDB),
149 
150  minLevel(0),
151  maxLevel(0),
152  usedLevel(0),
153  unused(0.0),
154  iterationsPerformed(1U),
155  constituents(200) {
156  // Check that the settings make sense
158  throw cms::Exception("FFTJetBadConfig") << "Can't resum constituents if they are not assigned" << std::endl;
159 
160  produces<reco::FFTJetProducerSummary>(outputLabel);
163 
164  if (jetType == CALOJET) {
167  }
168 
169  // Build the set of pattern recognition scales.
170  // This is needed in order to read the clustering tree
171  // from the event record.
173  checkConfig(iniScales, "invalid set of scales");
174  std::sort(iniScales->begin(), iniScales->end(), std::greater<double>());
175 
177  consumes<reco::PattRecoTree<fftjetcms::Real, reco::PattRecoPeak<fftjetcms::Real> > >(treeLabel);
178  input_genjet_token_ = consumes<std::vector<reco::FFTAnyJet<reco::GenJet> > >(genJetsLabel);
179  input_energyflow_token_ = consumes<reco::DiscretizedEnergyFlow>(treeLabel);
180  input_pusummary_token_ = consumes<reco::FFTJetPileupSummary>(pileupLabel);
181 
182  // Most of the configuration has to be performed inside
183  // the "beginJob" method. This is because chaining of the
184  // parsers between this base class and the derived classes
185  // can not work from the constructor of the base class.
186 }
187 
189 
190 //
191 // member functions
192 //
193 template <class Real>
196 
197  // Get the input
199  iEvent.getByToken(input_recotree_token_, input);
200 
201  if (!input->isSparse())
202  throw cms::Exception("FFTJetBadConfig") << "The stored clustering tree is not sparse" << std::endl;
203 
205  sparseTree.sortNodes();
206  fftjet::updateSplitMergeTimes(sparseTree, sparseTree.minScale(), sparseTree.maxScale());
207 }
208 
211  const edm::EventSetup& /* iSetup */,
212  const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
213  std::vector<fftjet::Peak>* preclusters) {
214  typedef reco::FFTAnyJet<reco::GenJet> InputJet;
215  typedef std::vector<InputJet> InputCollection;
216 
218  iEvent.getByToken(input_genjet_token_, input);
219 
220  const unsigned sz = input->size();
221  preclusters->reserve(sz);
222  for (unsigned i = 0; i < sz; ++i) {
223  const RecoFFTJet& jet(jetFromStorable((*input)[i].getFFTSpecific()));
224  fftjet::Peak p(jet.precluster());
225  const double scale(p.scale());
226  p.setEtaPhi(jet.vec().Eta(), jet.vec().Phi());
227  p.setMagnitude(jet.vec().Pt() / scale / scale);
228  p.setStatus(resolution);
229  if (peakSelect(p))
230  preclusters->push_back(p);
231  }
232 }
233 
235  const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
236  std::vector<fftjet::Peak>* preclusters) {
237  nodes.clear();
238  selectTreeNodes(tree, peakSelect, &nodes);
239 
240  // Fill out the vector of preclusters using the tree node ids
241  const unsigned nNodes = nodes.size();
242  const SparseTree::NodeId* pnodes = nNodes ? &nodes[0] : nullptr;
243  preclusters->reserve(nNodes);
244  for (unsigned i = 0; i < nNodes; ++i)
245  preclusters->push_back(sparseTree.uncheckedNode(pnodes[i]).getCluster());
246 
247  // Remember the node id in the precluster and set
248  // the status word to indicate the resolution scheme used
249  fftjet::Peak* clusters = nNodes ? &(*preclusters)[0] : nullptr;
250  for (unsigned i = 0; i < nNodes; ++i) {
251  clusters[i].setCode(pnodes[i]);
252  clusters[i].setStatus(resolution);
253  }
254 }
255 
257  const fftjet::Functor1<bool, fftjet::Peak>& peakSelect,
258  std::vector<SparseTree::NodeId>* mynodes) {
259  minLevel = maxLevel = usedLevel = 0;
260 
261  // Get the tree nodes which pass the cuts
262  // (according to the selected resolution strategy)
263  switch (resolution) {
264  case FIXED: {
265  usedLevel = tree.getLevel(fixedScale);
266  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
267  } break;
268 
269  case MAXIMALLY_STABLE: {
270  const unsigned minStartingLevel = maxStableScale > 0.0 ? tree.getLevel(maxStableScale) : 0;
271  const unsigned maxStartingLevel = minStableScale > 0.0 ? tree.getLevel(minStableScale) : UINT_MAX;
272 
273  if (tree.stableClusterCount(
274  peakSelect, &minLevel, &maxLevel, stabilityAlpha, minStartingLevel, maxStartingLevel)) {
275  usedLevel = (minLevel + maxLevel) / 2;
276  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
277  }
278  } break;
279 
280  case GLOBALLY_ADAPTIVE: {
281  const bool stable = tree.clusterCountLevels(nClustersRequested, peakSelect, &minLevel, &maxLevel);
282  if (minLevel || maxLevel) {
283  usedLevel = (minLevel + maxLevel) / 2;
284  if (!stable) {
285  const int maxlev = tree.maxStoredLevel();
286  bool levelFound = false;
287  for (int delta = 0; delta <= maxlev && !levelFound; ++delta)
288  for (int ifac = 1; ifac > -2 && !levelFound; ifac -= 2) {
289  const int level = usedLevel + ifac * delta;
290  if (level > 0 && level <= maxlev)
291  if (occupancy[level] == nClustersRequested) {
292  usedLevel = level;
293  levelFound = true;
294  }
295  }
296  assert(levelFound);
297  }
298  } else {
299  // Can't find that exact number of preclusters.
300  // Try to get the next best thing.
301  usedLevel = 1;
302  const unsigned occ1 = occupancy[1];
303  if (nClustersRequested >= occ1) {
304  const unsigned maxlev = tree.maxStoredLevel();
305  if (nClustersRequested > occupancy[maxlev])
306  usedLevel = maxlev;
307  else {
308  // It would be nice to use "lower_bound" here,
309  // but the occupancy is not necessarily monotonous.
310  unsigned bestDelta = nClustersRequested > occ1 ? nClustersRequested - occ1 : occ1 - nClustersRequested;
311  for (unsigned level = 2; level <= maxlev; ++level) {
312  const unsigned n = occupancy[level];
313  const unsigned d = nClustersRequested > n ? nClustersRequested - n : n - nClustersRequested;
314  if (d < bestDelta) {
315  bestDelta = d;
316  usedLevel = level;
317  }
318  }
319  }
320  }
321  }
322  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
323  } break;
324 
325  case LOCALLY_ADAPTIVE: {
326  usedLevel = tree.getLevel(fixedScale);
327  tree.getMagS2OptimalNodes(peakSelect, nClustersRequested, usedLevel, mynodes, &thresholds);
328  } break;
329 
330  default:
331  assert(!"ERROR in FFTJetProducer::selectTreeNodes : "
332  "should never get here! This is a bug. Please report.");
333  }
334 }
335 
337  const unsigned nClus = preclusters.size();
338  if (nClus) {
339  fftjet::Peak* clus = &preclusters[0];
340  fftjet::Functor1<double, fftjet::Peak>& scaleCalc(*recoScaleCalcPeak);
341  fftjet::Functor1<double, fftjet::Peak>& ratioCalc(*recoScaleRatioCalcPeak);
342  fftjet::Functor1<double, fftjet::Peak>& factorCalc(*memberFactorCalcPeak);
343 
344  for (unsigned i = 0; i < nClus; ++i) {
345  clus[i].setRecoScale(scaleCalc(clus[i]));
346  clus[i].setRecoScaleRatio(ratioCalc(clus[i]));
347  clus[i].setMembershipFactor(factorCalc(clus[i]));
348  }
349  }
350 }
351 
353  int minBin = energyFlow->getEtaBin(-gridScanMaxEta);
354  if (minBin < 0)
355  minBin = 0;
356  int maxBin = energyFlow->getEtaBin(gridScanMaxEta) + 1;
357  if (maxBin < 0)
358  maxBin = 0;
359 
360  fftjet::DefaultRecombinationAlgFactory<Real, VectorLike, BgData, VBuilder> factory;
361  if (factory[recombinationAlgorithm] == nullptr)
362  throw cms::Exception("FFTJetBadConfig")
363  << "Invalid grid recombination algorithm \"" << recombinationAlgorithm << "\"" << std::endl;
364  gridAlg = std::unique_ptr<GridAlg>(factory[recombinationAlgorithm]->create(jetMembershipFunction.get(),
365  bgMembershipFunction.get(),
368  isCrisp,
369  false,
371  minBin,
372  maxBin));
373 }
374 
375 bool FFTJetProducer::loadEnergyFlow(const edm::Event& iEvent, std::unique_ptr<fftjet::Grid2d<fftjetcms::Real> >& flow) {
377  iEvent.getByToken(input_energyflow_token_, input);
378 
379  // Make sure that the grid is compatible with the stored one
380  bool rebuildGrid = flow.get() == nullptr;
381  if (!rebuildGrid)
382  rebuildGrid =
383  !(flow->nEta() == input->nEtaBins() && flow->nPhi() == input->nPhiBins() && flow->etaMin() == input->etaMin() &&
384  flow->etaMax() == input->etaMax() && flow->phiBin0Edge() == input->phiBin0Edge());
385  if (rebuildGrid) {
386  // We should not get here very often...
387  flow = std::make_unique<fftjet::Grid2d<Real> >(
388  input->nEtaBins(), input->etaMin(), input->etaMax(), input->nPhiBins(), input->phiBin0Edge(), input->title());
389  }
390  flow->blockSet(input->data(), input->nEtaBins(), input->nPhiBins());
391  return rebuildGrid;
392 }
393 
394 bool FFTJetProducer::checkConvergence(const std::vector<RecoFFTJet>& previous, std::vector<RecoFFTJet>& nextSet) {
395  fftjet::Functor2<double, RecoFFTJet, RecoFFTJet>& distanceCalc(*jetDistanceCalc);
396 
397  const unsigned nJets = previous.size();
398  if (nJets != nextSet.size())
399  return false;
400 
401  const RecoFFTJet* prev = &previous[0];
402  RecoFFTJet* next = &nextSet[0];
403 
404  // Calculate convergence distances for all jets
405  bool converged = true;
406  for (unsigned i = 0; i < nJets; ++i) {
407  const double d = distanceCalc(prev[i], next[i]);
408  next[i].setConvergenceDistance(d);
409  if (i < nJetsRequiredToConverge && d > convergenceDistance)
410  converged = false;
411  }
412 
413  return converged;
414 }
415 
417  fftjet::Functor1<double, RecoFFTJet>& scaleCalc(*recoScaleCalcJet);
418  fftjet::Functor1<double, RecoFFTJet>& ratioCalc(*recoScaleRatioCalcJet);
419  fftjet::Functor1<double, RecoFFTJet>& factorCalc(*memberFactorCalcJet);
420 
421  unsigned nJets = recoJets.size();
422  unsigned iterNum = 1U;
423  bool converged = false;
424  for (; iterNum < maxIterations && !converged; ++iterNum) {
425  // Recreate the vector of preclusters using the jets
426  const RecoFFTJet* jets = &recoJets[0];
427  iterPreclusters.clear();
428  iterPreclusters.reserve(nJets);
429  for (unsigned i = 0; i < nJets; ++i) {
430  const RecoFFTJet& jet(jets[i]);
431  fftjet::Peak p(jet.precluster());
432  p.setEtaPhi(jet.vec().Eta(), jet.vec().Phi());
433  p.setRecoScale(scaleCalc(jet));
434  p.setRecoScaleRatio(ratioCalc(jet));
435  p.setMembershipFactor(factorCalc(jet));
436  iterPreclusters.push_back(p);
437  }
438 
439  // Run the algorithm
440  int status = 0;
442  status = gridAlg->run(iterPreclusters, *energyFlow, &noiseLevel, 1U, 1U, &iterJets, &unclustered, &unused);
443  else
445  if (status)
446  throw cms::Exception("FFTJetInterface") << "FFTJet algorithm failed" << std::endl;
447 
448  // As it turns out, it is possible, in very rare cases,
449  // to have iterJets.size() != nJets at this point
450 
451  // Figure out if the iterations have converged
452  converged = checkConvergence(recoJets, iterJets);
453 
454  // Prepare for the next cycle
455  iterJets.swap(recoJets);
456  nJets = recoJets.size();
457  }
458 
459  // Check that we have the correct number of preclusters
460  if (preclusters.size() != nJets) {
461  assert(nJets < preclusters.size());
463  assert(preclusters.size() == nJets);
464  }
465 
466  // Plug in the original precluster coordinates into the result
467  RecoFFTJet* jets = &recoJets[0];
468  for (unsigned i = 0; i < nJets; ++i) {
469  const fftjet::Peak& oldp(preclusters[i]);
470  jets[i].setPeakEtaPhi(oldp.eta(), oldp.phi());
471  }
472 
473  // If we have converged on the last cycle, the result
474  // would be indistinguishable from no convergence.
475  // Because of this, raise the counter by one to indicate
476  // the case when the convergence is not achieved.
477  if (!converged)
478  ++iterNum;
479 
480  return iterNum;
481 }
482 
484  const unsigned nJets = recoJets.size();
485  const unsigned* clusterMask = gridAlg->getClusterMask();
486  const int nEta = gridAlg->getLastNEta();
487  const int nPhi = gridAlg->getLastNPhi();
488  const fftjet::Grid2d<Real>& g(*energyFlow);
489 
490  const unsigned nInputs = eventData.size();
491  const VectorLike* inp = nInputs ? &eventData[0] : nullptr;
492  const unsigned* candIdx = nInputs ? &candidateIndex[0] : nullptr;
493  for (unsigned i = 0; i < nInputs; ++i) {
494  const VectorLike& item(inp[i]);
495  const int iPhi = g.getPhiBin(item.Phi());
496  const int iEta = g.getEtaBin(item.Eta());
497  const unsigned mask = iEta >= 0 && iEta < nEta ? clusterMask[iEta * nPhi + iPhi] : 0;
498  assert(mask <= nJets);
499  constituents[mask].push_back(inputCollection->ptrAt(candIdx[i]));
500  }
501 }
502 
504  const unsigned nJets = recoJets.size();
505  const unsigned* clusterMask = recoAlg->getClusterMask();
506  const unsigned maskLength = recoAlg->getLastNData();
507  assert(maskLength == eventData.size());
508 
509  const unsigned* candIdx = maskLength ? &candidateIndex[0] : nullptr;
510  for (unsigned i = 0; i < maskLength; ++i) {
511  // In FFTJet, the mask value of 0 corresponds to unclustered
512  // energy. We will do the same here. Jet numbers are therefore
513  // shifted by 1 wrt constituents vector, and constituents[1]
514  // corresponds to jet number 0.
515  const unsigned mask = clusterMask[i];
516  assert(mask <= nJets);
517  constituents[mask].push_back(inputCollection->ptrAt(candIdx[i]));
518  }
519 }
520 
521 // The following code more or less coincides with the similar method
522 // implemented in VirtualJetProducer
523 template <typename T>
525  using namespace reco;
526 
527  typedef FFTAnyJet<T> OutputJet;
528  typedef std::vector<OutputJet> OutputCollection;
529 
530  // Area of a single eta-phi cell for jet area calculations.
531  // Set it to 0 in case the module configuration does not allow
532  // us to calculate jet areas reliably.
533  double cellArea = useGriddedAlgorithm && recombinationDataCutoff < 0.0
534  ? energyFlow->etaBinWidth() * energyFlow->phiBinWidth()
535  : 0.0;
536 
537  if (calculatePileup)
538  cellArea = pileupEnergyFlow->etaBinWidth() * pileupEnergyFlow->phiBinWidth();
539 
540  // allocate output jet collection
541  auto jets = std::make_unique<OutputCollection>();
542  const unsigned nJets = recoJets.size();
543  jets->reserve(nJets);
544 
545  bool sorted = true;
546  double previousPt = DBL_MAX;
547  for (unsigned ijet = 0; ijet < nJets; ++ijet) {
548  RecoFFTJet& myjet(recoJets[ijet]);
549 
550  // Check if we should resum jet constituents
551  VectorLike jet4vec(myjet.vec());
552  if (resumConstituents) {
553  VectorLike sum(0.0, 0.0, 0.0, 0.0);
554  const unsigned nCon = constituents[ijet + 1].size();
555  const reco::CandidatePtr* cn = nCon ? &constituents[ijet + 1][0] : nullptr;
556  for (unsigned i = 0; i < nCon; ++i)
557  sum += cn[i]->p4();
558  jet4vec = sum;
559  setJetStatusBit(&myjet, CONSTITUENTS_RESUMMED, true);
560  }
561 
562  // Subtract the pile-up
564  jet4vec = adjustForPileup(jet4vec, pileup[ijet], subtractPileupAs4Vec);
567  else
568  setJetStatusBit(&myjet, PILEUP_SUBTRACTED_PT, true);
569  }
570 
571  // Write the specifics to the jet (simultaneously sets 4-vector,
572  // vertex, constituents). These are overridden functions that will
573  // call the appropriate specific code.
574  T jet;
575  if constexpr (std::is_same_v<T, reco::CaloJet>) {
576  const CaloGeometry& geometry = iSetup.getData(geometry_token_);
577  const HcalTopology& topology = iSetup.getData(topology_token_);
578  writeSpecific(jet, jet4vec, vertexUsed(), constituents[ijet + 1], geometry, topology);
579  } else {
580  writeSpecific(jet, jet4vec, vertexUsed(), constituents[ijet + 1]);
581  }
582 
583  // calcuate the jet area
584  double ncells = myjet.ncells();
585  if (calculatePileup) {
586  ncells = cellCountsVec[ijet];
587  setJetStatusBit(&myjet, PILEUP_CALCULATED, true);
588  }
589  jet.setJetArea(cellArea * ncells);
590 
591  // add jet to the list
592  FFTJet<float> fj(jetToStorable<float>(myjet));
593  fj.setFourVec(jet4vec);
594  if (calculatePileup) {
595  fj.setPileup(pileup[ijet]);
596  fj.setNCells(ncells);
597  }
598  jets->push_back(OutputJet(jet, fj));
599 
600  // Check whether the sequence remains sorted by pt
601  const double pt = jet.pt();
602  if (pt > previousPt)
603  sorted = false;
604  previousPt = pt;
605  }
606 
607  // Sort the collection
608  if (!sorted)
609  std::sort(jets->begin(), jets->end(), LocalSortByPt());
610 
611  // put the collection into the event
612  iEvent.put(std::move(jets), outputLabel);
613 }
614 
615 void FFTJetProducer::saveResults(edm::Event& ev, const edm::EventSetup& iSetup, const unsigned nPreclustersFound) {
616  // Write recombined jets
617  jet_type_switch(writeJets, ev, iSetup);
618 
619  // Check if we should resum unclustered energy constituents
620  VectorLike unclusE(unclustered);
621  if (resumConstituents) {
622  VectorLike sum(0.0, 0.0, 0.0, 0.0);
623  const unsigned nCon = constituents[0].size();
624  const reco::CandidatePtr* cn = nCon ? &constituents[0][0] : nullptr;
625  for (unsigned i = 0; i < nCon; ++i)
626  sum += cn[i]->p4();
627  unclusE = sum;
628  }
629 
630  // Write the jet reconstruction summary
631  const double minScale = minLevel ? sparseTree.getScale(minLevel) : 0.0;
632  const double maxScale = maxLevel ? sparseTree.getScale(maxLevel) : 0.0;
633  const double scaleUsed = usedLevel ? sparseTree.getScale(usedLevel) : 0.0;
634 
635  ev.put(
636  std::make_unique<reco::FFTJetProducerSummary>(thresholds,
637  occupancy,
638  unclusE,
639  constituents[0],
640  unused,
641  minScale,
642  maxScale,
643  scaleUsed,
644  nPreclustersFound,
647  outputLabel);
648 }
649 
650 // ------------ method called to for each event ------------
652  // Load the clustering tree made by FFTJetPatRecoProducer
654  loadSparseTreeData<float>(iEvent);
655  else
656  loadSparseTreeData<double>(iEvent);
657 
658  // Do we need to load the candidate collection?
660  loadInputCollection(iEvent);
661 
662  // Do we need to have discretized energy flow?
663  if (useGriddedAlgorithm) {
664  if (reuseExistingGrid) {
665  if (loadEnergyFlow(iEvent, energyFlow))
666  buildGridAlg();
667  } else
669  }
670 
671  // Calculate cluster occupancy as a function of level number
672  sparseTree.occupancyInScaleSpace(*peakSelector, &occupancy);
673 
674  // Select the preclusters using the requested resolution scheme
675  preclusters.clear();
676  if (resolution == FROM_GENJETS)
678  else
680  if (preclusters.size() > maxInitialPreclusters) {
681  std::sort(preclusters.begin(), preclusters.end(), std::greater<fftjet::Peak>());
683  }
684 
685  // Prepare to run the jet recombination procedure
687 
688  // Assign membership functions to preclusters. If this function
689  // is not overriden in a derived class, default algorithm membership
690  // function will be used for every cluster.
692 
693  // Count the preclusters going in
694  unsigned nPreclustersFound = 0U;
695  const unsigned npre = preclusters.size();
696  for (unsigned i = 0; i < npre; ++i)
697  if (preclusters[i].membershipFactor() > 0.0)
698  ++nPreclustersFound;
699 
700  // Run the recombination algorithm once
701  int status = 0;
703  status = gridAlg->run(preclusters, *energyFlow, &noiseLevel, 1U, 1U, &recoJets, &unclustered, &unused);
704  else
705  status = recoAlg->run(preclusters, eventData, &noiseLevel, 1U, &recoJets, &unclustered, &unused);
706  if (status)
707  throw cms::Exception("FFTJetInterface") << "FFTJet algorithm failed (first iteration)" << std::endl;
708 
709  // If requested, iterate the jet recombination procedure
710  if (maxIterations > 1U && !recoJets.empty()) {
711  // It is possible to have a smaller number of jets than we had
712  // preclusters. Fake preclusters are possible, but for a good
713  // choice of pattern recognition kernel their presence should
714  // be infrequent. However, any fake preclusters will throw the
715  // iterative reconstruction off balance. Deal with the problem now.
716  const unsigned nJets = recoJets.size();
717  if (preclusters.size() != nJets) {
718  assert(nJets < preclusters.size());
720  }
722  } else
723  iterationsPerformed = 1U;
724 
725  // Determine jet constituents. FFTJet returns a map
726  // of constituents which is inverse to what we need here.
727  const unsigned nJets = recoJets.size();
728  if (constituents.size() <= nJets)
729  constituents.resize(nJets + 1U);
730  if (assignConstituents) {
731  for (unsigned i = 0; i <= nJets; ++i)
732  constituents[i].clear();
735  else
737  }
738 
739  // Figure out the pile-up
740  if (calculatePileup) {
741  if (loadPileupFromDB)
743  else
745  determinePileup();
746  assert(pileup.size() == recoJets.size());
747  }
748 
749  // Write out the results
750  saveResults(iEvent, iSetup, nPreclustersFound);
751 }
752 
753 std::unique_ptr<fftjet::Functor1<bool, fftjet::Peak> > FFTJetProducer::parse_peakSelector(const edm::ParameterSet& ps) {
754  return fftjet_PeakSelector_parser(ps.getParameter<edm::ParameterSet>("PeakSelectorConfiguration"));
755 }
756 
757 // Parser for the jet membership function
758 std::unique_ptr<fftjet::ScaleSpaceKernel> FFTJetProducer::parse_jetMembershipFunction(const edm::ParameterSet& ps) {
759  return fftjet_MembershipFunction_parser(ps.getParameter<edm::ParameterSet>("jetMembershipFunction"));
760 }
761 
762 // Parser for the background membership function
763 std::unique_ptr<AbsBgFunctor> FFTJetProducer::parse_bgMembershipFunction(const edm::ParameterSet& ps) {
764  return fftjet_BgFunctor_parser(ps.getParameter<edm::ParameterSet>("bgMembershipFunction"));
765 }
766 
767 // Calculator for the recombination scale
768 std::unique_ptr<fftjet::Functor1<double, fftjet::Peak> > FFTJetProducer::parse_recoScaleCalcPeak(
769  const edm::ParameterSet& ps) {
770  return fftjet_PeakFunctor_parser(ps.getParameter<edm::ParameterSet>("recoScaleCalcPeak"));
771 }
772 
773 // Pile-up density calculator
774 std::unique_ptr<fftjetcms::AbsPileupCalculator> FFTJetProducer::parse_pileupDensityCalc(const edm::ParameterSet& ps) {
775  return fftjet_PileupCalculator_parser(ps.getParameter<edm::ParameterSet>("pileupDensityCalc"));
776 }
777 
778 // Calculator for the recombination scale ratio
779 std::unique_ptr<fftjet::Functor1<double, fftjet::Peak> > FFTJetProducer::parse_recoScaleRatioCalcPeak(
780  const edm::ParameterSet& ps) {
781  return fftjet_PeakFunctor_parser(ps.getParameter<edm::ParameterSet>("recoScaleRatioCalcPeak"));
782 }
783 
784 // Calculator for the membership function factor
785 std::unique_ptr<fftjet::Functor1<double, fftjet::Peak> > FFTJetProducer::parse_memberFactorCalcPeak(
786  const edm::ParameterSet& ps) {
787  return fftjet_PeakFunctor_parser(ps.getParameter<edm::ParameterSet>("memberFactorCalcPeak"));
788 }
789 
790 std::unique_ptr<fftjet::Functor1<double, FFTJetProducer::RecoFFTJet> > FFTJetProducer::parse_recoScaleCalcJet(
791  const edm::ParameterSet& ps) {
792  return fftjet_JetFunctor_parser(ps.getParameter<edm::ParameterSet>("recoScaleCalcJet"));
793 }
794 
795 std::unique_ptr<fftjet::Functor1<double, FFTJetProducer::RecoFFTJet> > FFTJetProducer::parse_recoScaleRatioCalcJet(
796  const edm::ParameterSet& ps) {
797  return fftjet_JetFunctor_parser(ps.getParameter<edm::ParameterSet>("recoScaleRatioCalcJet"));
798 }
799 
800 std::unique_ptr<fftjet::Functor1<double, FFTJetProducer::RecoFFTJet> > FFTJetProducer::parse_memberFactorCalcJet(
801  const edm::ParameterSet& ps) {
802  return fftjet_JetFunctor_parser(ps.getParameter<edm::ParameterSet>("memberFactorCalcJet"));
803 }
804 
805 std::unique_ptr<fftjet::Functor2<double, FFTJetProducer::RecoFFTJet, FFTJetProducer::RecoFFTJet> >
807  return fftjet_JetDistance_parser(ps.getParameter<edm::ParameterSet>("jetDistanceCalc"));
808 }
809 
810 void FFTJetProducer::assignMembershipFunctions(std::vector<fftjet::Peak>*) {}
811 
812 // ------------ method called once each job just before starting event loop
815 
816  // Parse the peak selector definition
818  checkConfig(peakSelector, "invalid peak selector");
819 
821  checkConfig(jetMembershipFunction, "invalid jet membership function");
822 
824  checkConfig(bgMembershipFunction, "invalid noise membership function");
825 
826  // Build the energy recombination algorithm
827  if (!useGriddedAlgorithm) {
828  fftjet::DefaultVectorRecombinationAlgFactory<VectorLike, BgData, VBuilder> factory;
829  if (factory[recombinationAlgorithm] == nullptr)
830  throw cms::Exception("FFTJetBadConfig")
831  << "Invalid vector recombination algorithm \"" << recombinationAlgorithm << "\"" << std::endl;
832  recoAlg = std::unique_ptr<RecoAlg>(factory[recombinationAlgorithm]->create(jetMembershipFunction.get(),
833  &VectorLike::Et,
834  &VectorLike::Eta,
836  bgMembershipFunction.get(),
838  isCrisp,
839  false,
841  } else if (!reuseExistingGrid) {
843  checkConfig(energyFlow, "invalid discretization grid");
844  buildGridAlg();
845  }
846 
847  // Create the grid subsequently used for pile-up subtraction
848  if (calculatePileup) {
849  pileupEnergyFlow = fftjet_Grid2d_parser(ps.getParameter<edm::ParameterSet>("PileupGridConfiguration"));
850  checkConfig(pileupEnergyFlow, "invalid pileup density grid");
851 
852  if (!loadPileupFromDB) {
854  checkConfig(pileupDensityCalc, "invalid pile-up density calculator");
855  }
856  }
857 
858  // Parse the calculator of the recombination scale
861  "invalid spec for the "
862  "reconstruction scale calculator from peaks");
863 
864  // Parse the calculator of the recombination scale ratio
867  "invalid spec for the "
868  "reconstruction scale ratio calculator from peaks");
869 
870  // Calculator for the membership function factor
873  "invalid spec for the "
874  "membership function factor calculator from peaks");
875 
876  if (maxIterations > 1) {
877  // We are going to run iteratively. Make required objects.
880  "invalid spec for the "
881  "reconstruction scale calculator from jets");
882 
885  "invalid spec for the "
886  "reconstruction scale ratio calculator from jets");
887 
890  "invalid spec for the "
891  "membership function factor calculator from jets");
892 
895  "invalid spec for the "
896  "jet distance calculator");
897  }
898 }
899 
901  // There are two possible reasons for fake preclusters:
902  // 1. Membership factor was set to 0
903  // 2. Genuine problem with pattern recognition
904  //
905  // Anyway, we need to match jets to preclusters and keep
906  // only those preclusters that have been matched
907  //
908  std::vector<int> matchTable;
909  const unsigned nmatched = matchOneToOne(recoJets, preclusters, JetToPeakDistance(), &matchTable);
910 
911  // Ensure that all jets have been matched.
912  // If not, we must have a bug somewhere.
913  assert(nmatched == recoJets.size());
914 
915  // Collect all matched preclusters
916  iterPreclusters.clear();
917  iterPreclusters.reserve(nmatched);
918  for (unsigned i = 0; i < nmatched; ++i)
919  iterPreclusters.push_back(preclusters[matchTable[i]]);
921 }
922 
923 void FFTJetProducer::setJetStatusBit(RecoFFTJet* jet, const int mask, const bool value) {
924  int status = jet->status();
925  if (value)
926  status |= mask;
927  else
928  status &= ~mask;
929  jet->setStatus(status);
930 }
931 
933  std::unique_ptr<fftjet::Grid2d<fftjetcms::Real> >& density) {
935  iEvent.getByToken(input_pusummary_token_, summary);
936 
937  const reco::FFTJetPileupSummary& s(*summary);
939  const bool phiDependent = calc.isPhiDependent();
940 
941  fftjet::Grid2d<Real>& g(*density);
942  const unsigned nEta = g.nEta();
943  const unsigned nPhi = g.nPhi();
944 
945  for (unsigned ieta = 0; ieta < nEta; ++ieta) {
946  const double eta(g.etaBinCenter(ieta));
947 
948  if (phiDependent) {
949  for (unsigned iphi = 0; iphi < nPhi; ++iphi) {
950  const double phi(g.phiBinCenter(iphi));
951  g.uncheckedSetBin(ieta, iphi, calc(eta, phi, s));
952  }
953  } else {
954  const double pil = calc(eta, 0.0, s);
955  for (unsigned iphi = 0; iphi < nPhi; ++iphi)
956  g.uncheckedSetBin(ieta, iphi, pil);
957  }
958  }
959 }
960 
962  const edm::EventSetup& iSetup,
963  std::unique_ptr<fftjet::Grid2d<fftjetcms::Real> >& density) {
966  std::shared_ptr<npstat::StorableMultivariateFunctor> f = (*h)[pileupTableCategory][pileupTableName];
967 
969  iEvent.getByToken(input_pusummary_token_, summary);
970 
971  const float rho = summary->pileupRho();
972  const bool phiDependent = f->minDim() == 3U;
973 
974  fftjet::Grid2d<Real>& g(*density);
975  const unsigned nEta = g.nEta();
976  const unsigned nPhi = g.nPhi();
977 
978  double functorArg[3] = {0.0, 0.0, 0.0};
979  if (phiDependent)
980  functorArg[2] = rho;
981  else
982  functorArg[1] = rho;
983 
984  for (unsigned ieta = 0; ieta < nEta; ++ieta) {
985  const double eta(g.etaBinCenter(ieta));
986  functorArg[0] = eta;
987 
988  if (phiDependent) {
989  for (unsigned iphi = 0; iphi < nPhi; ++iphi) {
990  functorArg[1] = g.phiBinCenter(iphi);
991  g.uncheckedSetBin(ieta, iphi, (*f)(functorArg, 3U));
992  }
993  } else {
994  const double pil = (*f)(functorArg, 2U);
995  for (unsigned iphi = 0; iphi < nPhi; ++iphi)
996  g.uncheckedSetBin(ieta, iphi, pil);
997  }
998  }
999 }
1000 
1002  // This function works with crisp clustering only
1003  if (!isCrisp)
1004  assert(!"Pile-up subtraction for fuzzy clustering "
1005  "is not implemented yet");
1006 
1007  // Clear the pileup vector
1008  const unsigned nJets = recoJets.size();
1009  pileup.resize(nJets);
1010  if (nJets == 0)
1011  return;
1012  const VectorLike zero;
1013  for (unsigned i = 0; i < nJets; ++i)
1014  pileup[i] = zero;
1015 
1016  // Pileup energy flow grid
1017  const fftjet::Grid2d<Real>& g(*pileupEnergyFlow);
1018  const unsigned nEta = g.nEta();
1019  const unsigned nPhi = g.nPhi();
1020  const double cellArea = g.etaBinWidth() * g.phiBinWidth();
1021 
1022  // Various calculators
1023  fftjet::Functor1<double, RecoFFTJet>& scaleCalc(*recoScaleCalcJet);
1024  fftjet::Functor1<double, RecoFFTJet>& ratioCalc(*recoScaleRatioCalcJet);
1025  fftjet::Functor1<double, RecoFFTJet>& factorCalc(*memberFactorCalcJet);
1026 
1027  // Make sure we have enough memory
1028  memFcns2dVec.resize(nJets);
1029  fftjet::AbsKernel2d** memFcns2d = &memFcns2dVec[0];
1030 
1031  doubleBuf.resize(nJets * 4U + nJets * nPhi);
1032  double* recoScales = &doubleBuf[0];
1033  double* recoScaleRatios = recoScales + nJets;
1034  double* memFactors = recoScaleRatios + nJets;
1035  double* dEta = memFactors + nJets;
1036  double* dPhiBuf = dEta + nJets;
1037 
1038  cellCountsVec.resize(nJets);
1039  unsigned* cellCounts = &cellCountsVec[0];
1040 
1041  // Go over jets and collect the necessary info
1042  for (unsigned ijet = 0; ijet < nJets; ++ijet) {
1043  const RecoFFTJet& jet(recoJets[ijet]);
1044  const fftjet::Peak& peak(jet.precluster());
1045 
1046  // Make sure we are using 2-d membership functions.
1047  // Pile-up subtraction scheme for 3-d functions should be different.
1048  fftjet::AbsMembershipFunction* m3d = dynamic_cast<fftjet::AbsMembershipFunction*>(peak.membershipFunction());
1049  if (m3d == nullptr)
1050  m3d = dynamic_cast<fftjet::AbsMembershipFunction*>(jetMembershipFunction.get());
1051  if (m3d) {
1052  assert(!"Pile-up subtraction for 3-d membership functions "
1053  "is not implemented yet");
1054  } else {
1055  fftjet::AbsKernel2d* m2d = dynamic_cast<fftjet::AbsKernel2d*>(peak.membershipFunction());
1056  if (m2d == nullptr)
1057  m2d = dynamic_cast<fftjet::AbsKernel2d*>(jetMembershipFunction.get());
1058  assert(m2d);
1059  memFcns2d[ijet] = m2d;
1060  }
1061  recoScales[ijet] = scaleCalc(jet);
1062  recoScaleRatios[ijet] = ratioCalc(jet);
1063  memFactors[ijet] = factorCalc(jet);
1064  cellCounts[ijet] = 0U;
1065 
1066  const double jetPhi = jet.vec().Phi();
1067  for (unsigned iphi = 0; iphi < nPhi; ++iphi) {
1068  double dphi = g.phiBinCenter(iphi) - jetPhi;
1069  while (dphi > M_PI)
1070  dphi -= (2.0 * M_PI);
1071  while (dphi < -M_PI)
1072  dphi += (2.0 * M_PI);
1073  dPhiBuf[iphi * nJets + ijet] = dphi;
1074  }
1075  }
1076 
1077  // Go over all grid points and integrate
1078  // the pile-up energy density
1079  VBuilder vMaker;
1080  for (unsigned ieta = 0; ieta < nEta; ++ieta) {
1081  const double eta(g.etaBinCenter(ieta));
1082  const Real* databuf = g.data() + ieta * nPhi;
1083 
1084  // Figure out dEta for each jet
1085  for (unsigned ijet = 0; ijet < nJets; ++ijet)
1086  dEta[ijet] = eta - recoJets[ijet].vec().Eta();
1087 
1088  for (unsigned iphi = 0; iphi < nPhi; ++iphi) {
1089  double maxW(0.0);
1090  unsigned maxWJet(nJets);
1091  const double* dPhi = dPhiBuf + iphi * nJets;
1092 
1093  for (unsigned ijet = 0; ijet < nJets; ++ijet) {
1094  if (recoScaleRatios[ijet] > 0.0)
1095  memFcns2d[ijet]->setScaleRatio(recoScaleRatios[ijet]);
1096  const double f = memFactors[ijet] * (*memFcns2d[ijet])(dEta[ijet], dPhi[ijet], recoScales[ijet]);
1097  if (f > maxW) {
1098  maxW = f;
1099  maxWJet = ijet;
1100  }
1101  }
1102 
1103  if (maxWJet < nJets) {
1104  pileup[maxWJet] += vMaker(cellArea * databuf[iphi], eta, g.phiBinCenter(iphi));
1105  cellCounts[maxWJet]++;
1106  }
1107  }
1108  }
1109 }
1110 
1111 // ------------ method called once each job just after ending the event loop
1113 
1114 //define this as a plug-in
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)
Definition: matchOneToOne.h:38
T getUntrackedParameter(std::string const &, T const &) const
virtual std::unique_ptr< fftjet::ScaleSpaceKernel > parse_jetMembershipFunction(const edm::ParameterSet &)
std::unique_ptr< fftjet::Functor2< double, RecoFFTJet, RecoFFTJet > > jetDistanceCalc
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
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.
Definition: PattRecoTree.h:20
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
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
constexpr unsigned int maxBin
const reco::Particle::Point & vertexUsed() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void loadInputCollection(const edm::Event &)
std::unique_ptr< fftjet::Functor1< double, RecoFFTJet > > recoScaleCalcJet
activeDets clear()
const std::string recombinationAlgorithm
static const int stable
Definition: TopGenEvent.h:10
const double fixedScale
list status
Definition: mps_update.py:107
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)
Definition: jetConverters.h:65
void checkConfig(const Ptr &ptr, const char *message)
const double unlikelyBgWeight
bool ev
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)
Definition: JetSpecific.cc:32
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)
Resolution resolution
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 bool isCrisp
const double recombinationDataCutoff
Summary info for pile-up determined by Gaussian filtering.
std::vector< unsigned > occupancy
std::unique_ptr< T, impl::DeviceDeleter > unique_ptr
assert(be >=bs)
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
Definition: Activities.doc:4
tuple previous
Definition: callgraph.py:103
void determineVectorConstituents()
FFTJetProducer()=delete
static std::string const input
Definition: EdmProvDump.cc:47
std::unique_ptr< fftjet::Functor2< double, fftjet::RecombinedJet< VectorLike >, fftjet::RecombinedJet< VectorLike > > > fftjet_JetDistance_parser(const edm::ParameterSet &ps)
edm::EDGetTokenT< reco::PattRecoTree< fftjetcms::Real, reco::PattRecoPeak< fftjetcms::Real > > > input_recotree_token_
bool getData(T &iHolder) const
Definition: EventSetup.h:128
void loadSparseTreeData(const edm::Event &)
tuple d
Definition: ztail.py:151
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
int iEvent
Definition: GenABIO.cc:224
std::vector< unsigned > candidateIndex
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
unsigned usedLevel
fftjet::SparseClusteringTree< fftjet::Peak, long > SparseTree
std::unique_ptr< fftjet::Functor1< double, fftjet::RecombinedJet< VectorLike > > > fftjet_JetFunctor_parser(const edm::ParameterSet &ps)
vector< PseudoJet > jets
virtual std::unique_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_recoScaleRatioCalcPeak(const edm::ParameterSet &)
void endJob() override
def move
Definition: eostools.py:511
Implements inheritance relationships for FFTJet jets.
Definition: FFTAnyJet.h:16
const double noiseLevel
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)
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)
Definition: FFTJet.h:96
const bool calculatePileup
const bool assignConstituents
bool storeInSinglePrecision() const
void setPileup(const math::XYZTLorentzVector &p)
Definition: FFTJet.h:92
#define M_PI
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)
double Real
void sparsePeakTreeFromStorable(const reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > &in, const std::vector< double > *scaleSetIfNotAdaptive, double completeEventScale, fftjet::SparseClusteringTree< fftjet::Peak, long > *out)
const edm::InputTag genJetsLabel
const edm::ParameterSet myConfiguration
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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_
constexpr char Jet[]
Definition: modules.cc:9
const double stabilityAlpha
const unsigned maxInitialPreclusters
std::string pileupTableCategory
SparseTree sparseTree
std::unique_ptr< fftjetcms::AbsPileupCalculator > pileupDensityCalc
void setFourVec(const math::XYZTLorentzVector &p)
Definition: FFTJet.h:93
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
void beginJob() override
tuple level
Definition: testEve_cfg.py:47
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.
Definition: Activities.doc:4
long double T
static const Mapper & instance()
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)
constexpr unsigned int minBin
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 &)