CMS 3D CMS Logo

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