CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros 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 // $Id: FFTJetProducer.cc,v 1.11 2011/10/26 22:57:17 igv Exp $
17 //
18 //
19 
20 #include <iostream>
21 #include <fstream>
22 #include <algorithm>
23 
24 // Header for this class
26 
27 // Additional FFTJet headers
28 #include "fftjet/VectorRecombinationAlgFactory.hh"
29 #include "fftjet/RecombinationAlgFactory.hh"
30 
31 // Framework include files
34 
35 // Data formats
47 
49 
54 
56 
58 
59 
60 #define make_param(type, varname) const \
61  type & varname (ps.getParameter< type >( #varname ))
62 
63 #define init_param(type, varname) varname (ps.getParameter< type >( #varname ))
64 
65 // A generic switch statement based on jet type.
66 // Defining it in a single place avoids potential errors
67 // in case another jet type is introduced in the future.
68 //
69 // JPTJet is omitted for now: there is no reco::writeSpecific method
70 // for it (see header JetSpecific.h in the JetProducers package)
71 //
72 #define jet_type_switch(method, arg1, arg2) do {\
73  switch (jetType)\
74  {\
75  case CALOJET:\
76  method <reco::CaloJet> ( arg1 , arg2 );\
77  break;\
78  case PFJET:\
79  method <reco::PFJet> ( arg1 , arg2 );\
80  break;\
81  case GENJET:\
82  method <reco::GenJet> ( arg1 , arg2 );\
83  break;\
84  case TRACKJET:\
85  method <reco::TrackJet> ( arg1 , arg2 );\
86  break;\
87  case BASICJET:\
88  method <reco::BasicJet> ( arg1 , arg2 );\
89  break;\
90  default:\
91  assert(!"ERROR in FFTJetProducer : invalid jet type."\
92  " This is a bug. Please report.");\
93  }\
94 } while(0);
95 
96 using namespace fftjetcms;
97 
99  const std::string& name)
100 {
101  if (!name.compare("fixed"))
102  return FIXED;
103  else if (!name.compare("maximallyStable"))
104  return MAXIMALLY_STABLE;
105  else if (!name.compare("globallyAdaptive"))
106  return GLOBALLY_ADAPTIVE;
107  else if (!name.compare("locallyAdaptive"))
108  return LOCALLY_ADAPTIVE;
109  else
110  throw cms::Exception("FFTJetBadConfig")
111  << "Invalid resolution specification \""
112  << name << "\"" << std::endl;
113 }
114 
115 
116 template <typename T>
118  const std::string& alias, const std::string& tag)
119 {
120  produces<std::vector<reco::FFTAnyJet<T> > >(tag).setBranchAlias(alias);
121 }
122 
123 //
124 // constructors and destructor
125 //
127  : FFTJetInterface(ps),
128  myConfiguration(ps),
129  init_param(edm::InputTag, treeLabel),
130  init_param(bool, useGriddedAlgorithm),
131  init_param(bool, reuseExistingGrid),
132  init_param(unsigned, maxIterations),
133  init_param(unsigned, nJetsRequiredToConverge),
134  init_param(double, convergenceDistance),
135  init_param(bool, assignConstituents),
136  init_param(bool, resumConstituents),
137  init_param(bool, calculatePileup),
138  init_param(bool, subtractPileup),
139  init_param(bool, subtractPileupAs4Vec),
140  init_param(edm::InputTag, pileupLabel),
141  init_param(double, fixedScale),
142  init_param(double, minStableScale),
143  init_param(double, maxStableScale),
144  init_param(double, stabilityAlpha),
145  init_param(double, noiseLevel),
146  init_param(unsigned, nClustersRequested),
147  init_param(double, gridScanMaxEta),
148  init_param(std::string, recombinationAlgorithm),
149  init_param(bool, isCrisp),
150  init_param(double, unlikelyBgWeight),
151  init_param(double, recombinationDataCutoff),
152  resolution(parse_resolution(ps.getParameter<std::string>("resolution"))),
153 
154  minLevel(0),
155  maxLevel(0),
156  usedLevel(0),
157  unused(0.0),
158  iterationsPerformed(1U),
159  constituents(200)
160 {
161  // Check that the settings make sense
163  throw cms::Exception("FFTJetBadConfig")
164  << "Can't resum constituents if they are not assigned"
165  << std::endl;
166 
167  produces<reco::FFTJetProducerSummary>(outputLabel);
168  const std::string alias(ps.getUntrackedParameter<std::string>(
169  "alias", outputLabel));
171 
172  // Build the set of pattern recognition scales.
173  // This is needed in order to read the clustering tree
174  // from the event record.
176  ps.getParameter<edm::ParameterSet>("InitialScales"));
177  checkConfig(iniScales, "invalid set of scales");
178  std::sort(iniScales->begin(), iniScales->end(), std::greater<double>());
179 
180  // Most of the configuration has to be performed inside
181  // the "beginJob" method. This is because chaining of the
182  // parsers between this base class and the derived classes
183  // can not work from the constructor of the base class.
184 }
185 
186 
188 {
189 }
190 
191 //
192 // member functions
193 //
194 template<class Real>
196 {
198 
199  // Get the input
201  iEvent.getByLabel(treeLabel, input);
202 
203  if (!input->isSparse())
204  throw cms::Exception("FFTJetBadConfig")
205  << "The stored clustering tree is not sparse" << std::endl;
206 
209  sparseTree.sortNodes();
210 }
211 
212 
214  const SparseTree& tree,
215  const fftjet::Functor1<bool,fftjet::Peak>& peakSelector,
216  std::vector<fftjet::Peak>* preclusters)
217 {
218  nodes.clear();
219  selectTreeNodes(tree, peakSelector, &nodes);
220 
221  // Fill out the vector of preclusters using the tree node ids
222  const unsigned nNodes = nodes.size();
223  const SparseTree::NodeId* pnodes = nNodes ? &nodes[0] : 0;
224  preclusters->reserve(nNodes);
225  for (unsigned i=0; i<nNodes; ++i)
226  preclusters->push_back(
227  sparseTree.uncheckedNode(pnodes[i]).getCluster());
228 
229  // Remember the node id in the precluster and set
230  // the status word to indicate the resolution scheme used
231  fftjet::Peak* clusters = nNodes ? &(*preclusters)[0] : 0;
232  for (unsigned i=0; i<nNodes; ++i)
233  {
234  clusters[i].setCode(pnodes[i]);
235  clusters[i].setStatus(resolution);
236  }
237 }
238 
239 
241  const SparseTree& tree,
242  const fftjet::Functor1<bool,fftjet::Peak>& peakSelect,
243  std::vector<SparseTree::NodeId>* mynodes)
244 {
245  minLevel = maxLevel = usedLevel = 0;
246 
247  // Get the tree nodes which pass the cuts
248  // (according to the selected resolution strategy)
249  switch (resolution)
250  {
251  case FIXED:
252  {
253  usedLevel = tree.getLevel(fixedScale);
254  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
255  }
256  break;
257 
258  case MAXIMALLY_STABLE:
259  {
260  const unsigned minStartingLevel = maxStableScale > 0.0 ?
261  tree.getLevel(maxStableScale) : 0;
262  const unsigned maxStartingLevel = minStableScale > 0.0 ?
263  tree.getLevel(minStableScale) : UINT_MAX;
264 
265  if (tree.stableClusterCount(
266  peakSelect, &minLevel, &maxLevel, stabilityAlpha,
267  minStartingLevel, maxStartingLevel))
268  {
269  usedLevel = (minLevel + maxLevel)/2;
270  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
271  }
272  }
273  break;
274 
275  case GLOBALLY_ADAPTIVE:
276  {
277  const bool stable = tree.clusterCountLevels(
278  nClustersRequested, peakSelect, &minLevel, &maxLevel);
279  if (minLevel || maxLevel)
280  {
281  usedLevel = (minLevel + maxLevel)/2;
282  if (!stable)
283  {
284  const int maxlev = tree.maxStoredLevel();
285  bool levelFound = false;
286  for (int delta=0; delta<=maxlev && !levelFound; ++delta)
287  for (int ifac=1; ifac>-2 && !levelFound; ifac-=2)
288  {
289  const int level = usedLevel + ifac*delta;
290  if (level > 0 && level <= maxlev)
291  if (occupancy[level] == nClustersRequested)
292  {
293  usedLevel = level;
294  levelFound = true;
295  }
296  }
297  assert(levelFound);
298  }
299  }
300  else
301  {
302  // Can't find that exact number of preclusters.
303  // Try to get the next best thing.
304  usedLevel = 1;
305  const unsigned occ1 = occupancy[1];
306  if (nClustersRequested >= occ1)
307  {
308  const unsigned maxlev = tree.maxStoredLevel();
309  if (nClustersRequested > occupancy[maxlev])
310  usedLevel = maxlev;
311  else
312  {
313  // It would be nice to use "lower_bound" here,
314  // but the occupancy is not necessarily monotonous.
315  unsigned bestDelta = nClustersRequested > occ1 ?
316  nClustersRequested - occ1 : occ1 - nClustersRequested;
317  for (unsigned level=2; level<=maxlev; ++level)
318  {
319  const unsigned n = occupancy[level];
320  const unsigned d = nClustersRequested > n ?
321  nClustersRequested - n : n - nClustersRequested;
322  if (d < bestDelta)
323  {
324  bestDelta = d;
325  usedLevel = level;
326  }
327  }
328  }
329  }
330  }
331  tree.getPassingNodes(usedLevel, peakSelect, mynodes);
332  }
333  break;
334 
335  case LOCALLY_ADAPTIVE:
336  {
337  usedLevel = tree.getLevel(fixedScale);
338  tree.getMagS2OptimalNodes(peakSelect, nClustersRequested,
339  usedLevel, mynodes, &thresholds);
340  }
341  break;
342 
343  default:
344  assert(!"ERROR in FFTJetProducer::selectTreeNodes : "
345  "should never get here! This is a bug. Please report.");
346  }
347 }
348 
349 
351 {
352  const unsigned nClus = preclusters.size();
353  if (nClus)
354  {
355  fftjet::Peak* clus = &preclusters[0];
356  fftjet::Functor1<double,fftjet::Peak>&
357  scaleCalc(*recoScaleCalcPeak);
358  fftjet::Functor1<double,fftjet::Peak>&
359  ratioCalc(*recoScaleRatioCalcPeak);
360  fftjet::Functor1<double,fftjet::Peak>&
361  factorCalc(*memberFactorCalcPeak);
362 
363  for (unsigned i=0; i<nClus; ++i)
364  {
365  clus[i].setRecoScale(scaleCalc(clus[i]));
366  clus[i].setRecoScaleRatio(ratioCalc(clus[i]));
367  clus[i].setMembershipFactor(factorCalc(clus[i]));
368  }
369  }
370 }
371 
372 
374 {
375  int minBin = energyFlow->getEtaBin(-gridScanMaxEta);
376  if (minBin < 0)
377  minBin = 0;
378  int maxBin = energyFlow->getEtaBin(gridScanMaxEta) + 1;
379  if (maxBin < 0)
380  maxBin = 0;
381 
382  fftjet::DefaultRecombinationAlgFactory<
383  Real,VectorLike,BgData,VBuilder> factory;
384  if (factory[recombinationAlgorithm] == NULL)
385  throw cms::Exception("FFTJetBadConfig")
386  << "Invalid grid recombination algorithm \""
387  << recombinationAlgorithm << "\"" << std::endl;
388  gridAlg = std::auto_ptr<GridAlg>(
389  factory[recombinationAlgorithm]->create(
390  jetMembershipFunction.get(),
391  bgMembershipFunction.get(),
393  isCrisp, false, assignConstituents, minBin, maxBin));
394 }
395 
396 
398  const edm::Event& iEvent, const edm::InputTag& label,
399  std::auto_ptr<fftjet::Grid2d<fftjetcms::Real> >& flow)
400 {
402  iEvent.getByLabel(label, input);
403 
404  // Make sure that the grid is compatible with the stored one
405  bool rebuildGrid = flow.get() == NULL;
406  if (!rebuildGrid)
407  rebuildGrid =
408  !(flow->nEta() == input->nEtaBins() &&
409  flow->nPhi() == input->nPhiBins() &&
410  flow->etaMin() == input->etaMin() &&
411  flow->etaMax() == input->etaMax() &&
412  flow->phiBin0Edge() == input->phiBin0Edge());
413  if (rebuildGrid)
414  {
415  // We should not get here very often...
416  flow = std::auto_ptr<fftjet::Grid2d<Real> >(
417  new fftjet::Grid2d<Real>(
418  input->nEtaBins(), input->etaMin(), input->etaMax(),
419  input->nPhiBins(), input->phiBin0Edge(), input->title()));
420  }
421  flow->blockSet(input->data(), input->nEtaBins(), input->nPhiBins());
422  return rebuildGrid;
423 }
424 
425 
426 bool FFTJetProducer::checkConvergence(const std::vector<RecoFFTJet>& previous,
427  std::vector<RecoFFTJet>& nextSet)
428 {
429  fftjet::Functor2<double,RecoFFTJet,RecoFFTJet>&
430  distanceCalc(*jetDistanceCalc);
431 
432  const unsigned nJets = previous.size();
433  if (nJets != nextSet.size())
434  return false;
435 
436  const RecoFFTJet* prev = &previous[0];
437  RecoFFTJet* next = &nextSet[0];
438 
439  // Calculate convergence distances for all jets
440  bool converged = true;
441  for (unsigned i=0; i<nJets; ++i)
442  {
443  const double d = distanceCalc(prev[i], next[i]);
444  next[i].setConvergenceDistance(d);
445  if (i < nJetsRequiredToConverge && d > convergenceDistance)
446  converged = false;
447  }
448 
449  return converged;
450 }
451 
452 
454 {
455  fftjet::Functor1<double,RecoFFTJet>& scaleCalc(*recoScaleCalcJet);
456  fftjet::Functor1<double,RecoFFTJet>& ratioCalc(*recoScaleRatioCalcJet);
457  fftjet::Functor1<double,RecoFFTJet>& factorCalc(*memberFactorCalcJet);
458 
459  unsigned nJets = recoJets.size();
460  unsigned iterNum = 1U;
461  bool converged = false;
462  for (; iterNum<maxIterations && !converged; ++iterNum)
463  {
464  // Recreate the vector of preclusters using the jets
465  const RecoFFTJet* jets = &recoJets[0];
466  iterPreclusters.clear();
467  iterPreclusters.reserve(nJets);
468  for (unsigned i=0; i<nJets; ++i)
469  {
470  const RecoFFTJet& jet(jets[i]);
471  fftjet::Peak p(jet.precluster());
472  p.setEtaPhi(jet.vec().Eta(), jet.vec().Phi());
473  p.setRecoScale(scaleCalc(jet));
474  p.setRecoScaleRatio(ratioCalc(jet));
475  p.setMembershipFactor(factorCalc(jet));
476  iterPreclusters.push_back(p);
477  }
478 
479  // Run the algorithm
480  int status = 0;
482  status = gridAlg->run(iterPreclusters, *energyFlow,
483  &noiseLevel, 1U, 1U,
485  else
486  status = recoAlg->run(iterPreclusters, eventData, &noiseLevel, 1U,
488  if (status)
489  throw cms::Exception("FFTJetInterface")
490  << "FFTJet algorithm failed" << std::endl;
491 
492  // As it turns out, it is possible, in very rare cases,
493  // to have iterJets.size() != nJets at this point
494 
495  // Figure out if the iterations have converged
496  converged = checkConvergence(recoJets, iterJets);
497 
498  // Prepare for the next cycle
499  iterJets.swap(recoJets);
500  nJets = recoJets.size();
501  }
502 
503  // Check that we have the correct number of preclusters
504  if (preclusters.size() != nJets)
505  {
506  assert(nJets < preclusters.size());
508  assert(preclusters.size() == nJets);
509  }
510 
511  // Plug in the original precluster coordinates into the result
512  RecoFFTJet* jets = &recoJets[0];
513  for (unsigned i=0; i<nJets; ++i)
514  {
515  const fftjet::Peak& oldp(preclusters[i]);
516  jets[i].setPeakEtaPhi(oldp.eta(), oldp.phi());
517  }
518 
519  // If we have converged on the last cycle, the result
520  // would be indistinguishable from no convergence.
521  // Because of this, raise the counter by one to indicate
522  // the case when the convergence is not achieved.
523  if (!converged)
524  ++iterNum;
525 
526  return iterNum;
527 }
528 
529 
531 {
532  const unsigned nJets = recoJets.size();
533  const unsigned* clusterMask = gridAlg->getClusterMask();
534  const int nEta = gridAlg->getLastNEta();
535  const int nPhi = gridAlg->getLastNPhi();
536  const fftjet::Grid2d<Real>& g(*energyFlow);
537 
538  const unsigned nInputs = eventData.size();
539  const VectorLike* inp = nInputs ? &eventData[0] : 0;
540  const unsigned* candIdx = nInputs ? &candidateIndex[0] : 0;
541  for (unsigned i=0; i<nInputs; ++i)
542  {
543  const VectorLike& item(inp[i]);
544  const int iPhi = g.getPhiBin(item.Phi());
545  const int iEta = g.getEtaBin(item.Eta());
546  const unsigned mask = iEta >= 0 && iEta < nEta ?
547  clusterMask[iEta*nPhi + iPhi] : 0;
548  assert(mask <= nJets);
549  constituents[mask].push_back(inputCollection->ptrAt(candIdx[i]));
550  }
551 }
552 
553 
555 {
556  const unsigned nJets = recoJets.size();
557  const unsigned* clusterMask = recoAlg->getClusterMask();
558  const unsigned maskLength = recoAlg->getLastNData();
559  assert(maskLength == eventData.size());
560 
561  const unsigned* candIdx = maskLength ? &candidateIndex[0] : 0;
562  for (unsigned i=0; i<maskLength; ++i)
563  {
564  // In FFTJet, the mask value of 0 corresponds to unclustered
565  // energy. We will do the same here. Jet numbers are therefore
566  // shifted by 1 wrt constituents vector, and constituents[1]
567  // corresponds to jet number 0.
568  const unsigned mask = clusterMask[i];
569  assert(mask <= nJets);
570  constituents[mask].push_back(inputCollection->ptrAt(candIdx[i]));
571  }
572 }
573 
574 
575 // The following code more or less coincides with the similar method
576 // implemented in VirtualJetProducer
577 template <typename T>
579  const edm::EventSetup& iSetup)
580 {
581  using namespace reco;
582 
583  typedef FFTAnyJet<T> OutputJet;
584  typedef std::vector<OutputJet> OutputCollection;
585 
586  // Area of a single eta-phi cell for jet area calculations.
587  // Set it to 0 in case the module configuration does not allow
588  // us to calculate jet areas reliably.
589  double cellArea = useGriddedAlgorithm &&
591  energyFlow->etaBinWidth() * energyFlow->phiBinWidth() : 0.0;
592 
593  if (calculatePileup)
594  cellArea = pileupEnergyFlow->etaBinWidth() *
595  pileupEnergyFlow->phiBinWidth();
596 
597  // allocate output jet collection
598  std::auto_ptr<OutputCollection> jets(new OutputCollection());
599  const unsigned nJets = recoJets.size();
600  jets->reserve(nJets);
601 
602  for (unsigned ijet=0; ijet<nJets; ++ijet)
603  {
604  RecoFFTJet& myjet(recoJets[ijet]);
605 
606  // Check if we should resum jet constituents
607  VectorLike jet4vec(myjet.vec());
608  if (resumConstituents)
609  {
610  VectorLike sum(0.0, 0.0, 0.0, 0.0);
611  const unsigned nCon = constituents[ijet+1].size();
612  const reco::CandidatePtr* cn = nCon ? &constituents[ijet+1][0] : 0;
613  for (unsigned i=0; i<nCon; ++i)
614  sum += cn[i]->p4();
615  jet4vec = sum;
616  setJetStatusBit(&myjet, CONSTITUENTS_RESUMMED, true);
617  }
618 
619  // Subtract the pile-up
621  {
623  {
624  jet4vec -= pileup[ijet];
626  }
627  else
628  {
629  const double pt = jet4vec.Pt();
630  if (pt > 0.0)
631  {
632  const double pileupPt = pileup[ijet].Pt();
633  jet4vec *= ((pt - pileupPt)/pt);
634  }
635  setJetStatusBit(&myjet, PILEUP_SUBTRACTED_PT, true);
636  }
637  }
638 
639  // Write the specifics to the jet (simultaneously sets 4-vector,
640  // vertex, constituents). These are overridden functions that will
641  // call the appropriate specific code.
642  T jet;
643  writeSpecific(jet, jet4vec, vertexUsed(),
644  constituents[ijet+1], iSetup);
645 
646  // calcuate the jet area
647  double ncells = myjet.ncells();
648  if (calculatePileup)
649  {
650  ncells = cellCountsVec[ijet];
651  setJetStatusBit(&myjet, PILEUP_CALCULATED, true);
652  }
653  jet.setJetArea(cellArea*ncells);
654 
655  // add jet to the list
656  FFTJet<float> fj(jetToStorable<float>(myjet));
657  fj.setFourVec(jet4vec);
658  if (calculatePileup)
659  {
660  fj.setPileup(pileup[ijet]);
661  fj.setNCells(ncells);
662  }
663  jets->push_back(OutputJet(jet, fj));
664  }
665 
666  // put the collection into the event
667  iEvent.put(jets, outputLabel);
668 }
669 
670 
672  const unsigned nPreclustersFound)
673 {
674  // Write recombined jets
675  jet_type_switch(writeJets, ev, iSetup);
676 
677  // Check if we should resum unclustered energy constituents
678  VectorLike unclusE(unclustered);
679  if (resumConstituents)
680  {
681  VectorLike sum(0.0, 0.0, 0.0, 0.0);
682  const unsigned nCon = constituents[0].size();
683  const reco::CandidatePtr* cn = nCon ? &constituents[0][0] : 0;
684  for (unsigned i=0; i<nCon; ++i)
685  sum += cn[i]->p4();
686  unclusE = sum;
687  }
688 
689  // Write the jet reconstruction summary
690  const double minScale = minLevel ? sparseTree.getScale(minLevel) : 0.0;
691  const double maxScale = maxLevel ? sparseTree.getScale(maxLevel) : 0.0;
692  const double scaleUsed = usedLevel ? sparseTree.getScale(usedLevel) : 0.0;
693 
694  std::auto_ptr<reco::FFTJetProducerSummary> summary(
696  thresholds, occupancy, unclusE,
697  constituents[0], unused,
698  minScale, maxScale, scaleUsed,
699  nPreclustersFound, iterationsPerformed,
700  iterationsPerformed == 1U ||
702  ev.put(summary, outputLabel);
703 }
704 
705 
706 // ------------ method called to for each event ------------
708  const edm::EventSetup& iSetup)
709 {
710  // Load the clustering tree made by FFTJetPatRecoProducer
712  loadSparseTreeData<float>(iEvent);
713  else
714  loadSparseTreeData<double>(iEvent);
715 
716  // Do we need to load the candidate collection?
718  loadInputCollection(iEvent);
719 
720  // Do we need to have discretized energy flow?
722  {
723  if (reuseExistingGrid)
724  {
725  if (loadEnergyFlow(iEvent, treeLabel, energyFlow))
726  buildGridAlg();
727  }
728  else
730  }
731 
732  // Calculate cluster occupancy as a function of level number
733  sparseTree.occupancyInScaleSpace(*peakSelector, &occupancy);
734 
735  // Select the preclusters using the requested resolution scheme
736  preclusters.clear();
738 
739  // Prepare to run the jet recombination procedure
741 
742  // Assign membership functions to preclusters. If this function
743  // is not overriden in a derived class, default algorithm membership
744  // function will be used for every cluster.
746 
747  // Count the preclusters going in
748  unsigned nPreclustersFound = 0U;
749  const unsigned npre = preclusters.size();
750  for (unsigned i=0; i<npre; ++i)
751  if (preclusters[i].membershipFactor() > 0.0)
752  ++nPreclustersFound;
753 
754  // Run the recombination algorithm once
755  int status = 0;
757  status = gridAlg->run(preclusters, *energyFlow,
758  &noiseLevel, 1U, 1U,
760  else
761  status = recoAlg->run(preclusters, eventData, &noiseLevel, 1U,
763  if (status)
764  throw cms::Exception("FFTJetInterface")
765  << "FFTJet algorithm failed (first iteration)" << std::endl;
766 
767  // If requested, iterate the jet recombination procedure
768  if (maxIterations > 1U && !recoJets.empty())
769  {
770  // It is possible to have a smaller number of jets than we had
771  // preclusters. Fake preclusters are possible, but for a good
772  // choice of pattern recognition kernel their presence should
773  // be infrequent. However, any fake preclusters will throw the
774  // iterative reconstruction off balance. Deal with the problem now.
775  const unsigned nJets = recoJets.size();
776  if (preclusters.size() != nJets)
777  {
778  assert(nJets < preclusters.size());
780  }
782  }
783  else
784  iterationsPerformed = 1U;
785 
786  // Determine jet constituents. FFTJet returns a map
787  // of constituents which is inverse to what we need here.
788  const unsigned nJets = recoJets.size();
789  if (constituents.size() <= nJets)
790  constituents.resize(nJets + 1U);
791  if (assignConstituents)
792  {
793  for (unsigned i=0; i<=nJets; ++i)
794  constituents[i].clear();
797  else
799  }
800 
801  // Figure out the pile-up
802  if (calculatePileup)
803  {
805  determinePileup();
806  assert(pileup.size() == recoJets.size());
807  }
808 
809  // Write out the results
810  saveResults(iEvent, iSetup, nPreclustersFound);
811 }
812 
813 
814 std::auto_ptr<fftjet::Functor1<bool,fftjet::Peak> >
816 {
818  ps.getParameter<edm::ParameterSet>("PeakSelectorConfiguration"));
819 }
820 
821 
822 // Parser for the jet membership function
823 std::auto_ptr<fftjet::ScaleSpaceKernel>
825 {
827  ps.getParameter<edm::ParameterSet>("jetMembershipFunction"));
828 }
829 
830 
831 // Parser for the background membership function
832 std::auto_ptr<AbsBgFunctor>
834 {
836  ps.getParameter<edm::ParameterSet>("bgMembershipFunction"));
837 }
838 
839 
840 // Calculator for the recombination scale
841 std::auto_ptr<fftjet::Functor1<double,fftjet::Peak> >
843 {
845  ps.getParameter<edm::ParameterSet>("recoScaleCalcPeak"));
846 }
847 
848 
849 // Pile-up density calculator
850 std::auto_ptr<fftjetcms::AbsPileupCalculator>
852 {
854  ps.getParameter<edm::ParameterSet>("pileupDensityCalc"));
855 }
856 
857 
858 // Calculator for the recombination scale ratio
859 std::auto_ptr<fftjet::Functor1<double,fftjet::Peak> >
861 {
863  ps.getParameter<edm::ParameterSet>("recoScaleRatioCalcPeak"));
864 }
865 
866 
867 // Calculator for the membership function factor
868 std::auto_ptr<fftjet::Functor1<double,fftjet::Peak> >
870 {
872  ps.getParameter<edm::ParameterSet>("memberFactorCalcPeak"));
873 }
874 
875 
876 std::auto_ptr<fftjet::Functor1<double,FFTJetProducer::RecoFFTJet> >
878 {
880  ps.getParameter<edm::ParameterSet>("recoScaleCalcJet"));
881 }
882 
883 
884 std::auto_ptr<fftjet::Functor1<double,FFTJetProducer::RecoFFTJet> >
886 {
888  ps.getParameter<edm::ParameterSet>("recoScaleRatioCalcJet"));
889 }
890 
891 
892 std::auto_ptr<fftjet::Functor1<double,FFTJetProducer::RecoFFTJet> >
894 {
896  ps.getParameter<edm::ParameterSet>("memberFactorCalcJet"));
897 }
898 
899 
900 std::auto_ptr<fftjet::Functor2<
903 {
905  ps.getParameter<edm::ParameterSet>("jetDistanceCalc"));
906 }
907 
908 
909 void FFTJetProducer::assignMembershipFunctions(std::vector<fftjet::Peak>*)
910 {
911 }
912 
913 
914 // ------------ method called once each job just before starting event loop
916 {
918 
919  // Parse the peak selector definition
921  checkConfig(peakSelector, "invalid peak selector");
922 
924  checkConfig(jetMembershipFunction, "invalid jet membership function");
925 
927  checkConfig(bgMembershipFunction, "invalid noise membership function");
928 
929  // Build the energy recombination algorithm
930  if (!useGriddedAlgorithm)
931  {
932  fftjet::DefaultVectorRecombinationAlgFactory<
933  VectorLike,BgData,VBuilder> factory;
934  if (factory[recombinationAlgorithm] == NULL)
935  throw cms::Exception("FFTJetBadConfig")
936  << "Invalid vector recombination algorithm \""
937  << recombinationAlgorithm << "\"" << std::endl;
938  recoAlg = std::auto_ptr<RecoAlg>(
939  factory[recombinationAlgorithm]->create(
940  jetMembershipFunction.get(),
941  &VectorLike::Et, &VectorLike::Eta, &VectorLike::Phi,
942  bgMembershipFunction.get(),
944  }
945  else if (!reuseExistingGrid)
946  {
948  ps.getParameter<edm::ParameterSet>("GridConfiguration"));
949  checkConfig(energyFlow, "invalid discretization grid");
950  buildGridAlg();
951  }
952 
953  // Create the grid subsequently used for pile-up subtraction
954  if (calculatePileup)
955  {
957  ps.getParameter<edm::ParameterSet>("PileupGridConfiguration"));
958  checkConfig(pileupEnergyFlow, "invalid pileup density grid");
959 
961  checkConfig(pileupDensityCalc, "invalid pile-up density calculator");
962  }
963 
964  // Parse the calculator of the recombination scale
966  checkConfig(recoScaleCalcPeak, "invalid spec for the "
967  "reconstruction scale calculator from peaks");
968 
969  // Parse the calculator of the recombination scale ratio
971  checkConfig(recoScaleRatioCalcPeak, "invalid spec for the "
972  "reconstruction scale ratio calculator from peaks");
973 
974  // Calculator for the membership function factor
976  checkConfig(memberFactorCalcPeak, "invalid spec for the "
977  "membership function factor calculator from peaks");
978 
979  if (maxIterations > 1)
980  {
981  // We are going to run iteratively. Make required objects.
983  checkConfig(recoScaleCalcJet, "invalid spec for the "
984  "reconstruction scale calculator from jets");
985 
987  checkConfig(recoScaleRatioCalcJet, "invalid spec for the "
988  "reconstruction scale ratio calculator from jets");
989 
991  checkConfig(memberFactorCalcJet, "invalid spec for the "
992  "membership function factor calculator from jets");
993 
995  checkConfig(memberFactorCalcJet, "invalid spec for the "
996  "jet distance calculator");
997  }
998 }
999 
1000 
1002 {
1003  // There are two possible reasons for fake preclusters:
1004  // 1. Membership factor was set to 0
1005  // 2. Genuine problem with pattern recognition
1006  //
1007  // Anyway, we need to match jets to preclusters and keep
1008  // only those preclusters that have been matched
1009  //
1010  std::vector<int> matchTable;
1011  const unsigned nmatched = matchOneToOne(
1012  recoJets, preclusters, JetToPeakDistance(), &matchTable);
1013 
1014  // Ensure that all jets have been matched.
1015  // If not, we must have a bug somewhere.
1016  assert(nmatched == recoJets.size());
1017 
1018  // Collect all matched preclusters
1019  iterPreclusters.clear();
1020  iterPreclusters.reserve(nmatched);
1021  for (unsigned i=0; i<nmatched; ++i)
1022  iterPreclusters.push_back(preclusters[matchTable[i]]);
1024 }
1025 
1026 
1028  const int mask, const bool value)
1029 {
1030  int status = jet->status();
1031  if (value)
1032  status |= mask;
1033  else
1034  status &= ~mask;
1035  jet->setStatus(status);
1036 }
1037 
1038 
1040  const edm::Event& iEvent, const edm::InputTag& label,
1041  std::auto_ptr<fftjet::Grid2d<fftjetcms::Real> >& density)
1042 {
1044  iEvent.getByLabel(label, summary);
1045 
1046  const reco::FFTJetPileupSummary& s(*summary);
1047  const AbsPileupCalculator& calc(*pileupDensityCalc);
1048  const bool phiDependent = calc.isPhiDependent();
1049 
1050  fftjet::Grid2d<Real>& g(*density);
1051  const unsigned nEta = g.nEta();
1052  const unsigned nPhi = g.nPhi();
1053 
1054  for (unsigned ieta=0; ieta<nEta; ++ieta)
1055  {
1056  const double eta(g.etaBinCenter(ieta));
1057 
1058  if (phiDependent)
1059  {
1060  for (unsigned iphi=0; iphi<nPhi; ++iphi)
1061  {
1062  const double phi(g.phiBinCenter(iphi));
1063  g.uncheckedSetBin(ieta, iphi, calc(eta, phi, s));
1064  }
1065  }
1066  else
1067  {
1068  const double pil = calc(eta, 0.0, s);
1069  for (unsigned iphi=0; iphi<nPhi; ++iphi)
1070  g.uncheckedSetBin(ieta, iphi, pil);
1071  }
1072  }
1073 }
1074 
1075 
1077 {
1078  // This function works with crisp clustering only
1079  if (!isCrisp)
1080  assert(!"Pile-up subtraction for fuzzy clustering "
1081  "is not implemented yet");
1082 
1083  // Clear the pileup vector
1084  const unsigned nJets = recoJets.size();
1085  pileup.resize(nJets);
1086  if (nJets == 0)
1087  return;
1088  const VectorLike zero;
1089  for (unsigned i=0; i<nJets; ++i)
1090  pileup[i] = zero;
1091 
1092  // Pileup energy flow grid
1093  const fftjet::Grid2d<Real>& g(*pileupEnergyFlow);
1094  const unsigned nEta = g.nEta();
1095  const unsigned nPhi = g.nPhi();
1096  const double cellArea = g.etaBinWidth() * g.phiBinWidth();
1097 
1098  // Various calculators
1099  fftjet::Functor1<double,RecoFFTJet>& scaleCalc(*recoScaleCalcJet);
1100  fftjet::Functor1<double,RecoFFTJet>& ratioCalc(*recoScaleRatioCalcJet);
1101  fftjet::Functor1<double,RecoFFTJet>& factorCalc(*memberFactorCalcJet);
1102 
1103  // Make sure we have enough memory
1104  memFcns2dVec.resize(nJets);
1105  fftjet::AbsKernel2d** memFcns2d = &memFcns2dVec[0];
1106 
1107  doubleBuf.resize(nJets*4U + nJets*nPhi);
1108  double* recoScales = &doubleBuf[0];
1109  double* recoScaleRatios = recoScales + nJets;
1110  double* memFactors = recoScaleRatios + nJets;
1111  double* dEta = memFactors + nJets;
1112  double* dPhiBuf = dEta + nJets;
1113 
1114  cellCountsVec.resize(nJets);
1115  unsigned* cellCounts = &cellCountsVec[0];
1116 
1117  // Go over jets and collect the necessary info
1118  for (unsigned ijet=0; ijet<nJets; ++ijet)
1119  {
1120  const RecoFFTJet& jet(recoJets[ijet]);
1121  const fftjet::Peak& peak(jet.precluster());
1122 
1123  // Make sure we are using 2-d membership functions.
1124  // Pile-up subtraction scheme for 3-d functions should be different.
1125  fftjet::AbsMembershipFunction* m3d =
1126  dynamic_cast<fftjet::AbsMembershipFunction*>(
1127  peak.membershipFunction());
1128  if (m3d == 0)
1129  m3d = dynamic_cast<fftjet::AbsMembershipFunction*>(
1130  jetMembershipFunction.get());
1131  if (m3d)
1132  {
1133  assert(!"Pile-up subtraction for 3-d membership functions "
1134  "is not implemented yet");
1135  }
1136  else
1137  {
1138  fftjet::AbsKernel2d* m2d =
1139  dynamic_cast<fftjet::AbsKernel2d*>(
1140  peak.membershipFunction());
1141  if (m2d == 0)
1142  m2d = dynamic_cast<fftjet::AbsKernel2d*>(
1143  jetMembershipFunction.get());
1144  assert(m2d);
1145  memFcns2d[ijet] = m2d;
1146  }
1147  recoScales[ijet] = scaleCalc(jet);
1148  recoScaleRatios[ijet] = ratioCalc(jet);
1149  memFactors[ijet] = factorCalc(jet);
1150  cellCounts[ijet] = 0U;
1151 
1152  const double jetPhi = jet.vec().Phi();
1153  for (unsigned iphi=0; iphi<nPhi; ++iphi)
1154  {
1155  double dphi = g.phiBinCenter(iphi) - jetPhi;
1156  while (dphi > M_PI)
1157  dphi -= (2.0*M_PI);
1158  while (dphi < -M_PI)
1159  dphi += (2.0*M_PI);
1160  dPhiBuf[iphi*nJets+ijet] = dphi;
1161  }
1162  }
1163 
1164  // Go over all grid points and integrate
1165  // the pile-up energy density
1166  VBuilder vMaker;
1167  for (unsigned ieta=0; ieta<nEta; ++ieta)
1168  {
1169  const double eta(g.etaBinCenter(ieta));
1170  const Real* databuf = g.data() + ieta*nPhi;
1171 
1172  // Figure out dEta for each jet
1173  for (unsigned ijet=0; ijet<nJets; ++ijet)
1174  dEta[ijet] = eta - recoJets[ijet].vec().Eta();
1175 
1176  for (unsigned iphi=0; iphi<nPhi; ++iphi)
1177  {
1178  double maxW(0.0);
1179  unsigned maxWJet(nJets);
1180  const double* dPhi = dPhiBuf + iphi*nJets;
1181 
1182  for (unsigned ijet=0; ijet<nJets; ++ijet)
1183  {
1184  if (recoScaleRatios[ijet] > 0.0)
1185  memFcns2d[ijet]->setScaleRatio(recoScaleRatios[ijet]);
1186  const double f = memFactors[ijet]*
1187  (*memFcns2d[ijet])(dEta[ijet], dPhi[ijet],
1188  recoScales[ijet]);
1189  if (f > maxW)
1190  {
1191  maxW = f;
1192  maxWJet = ijet;
1193  }
1194  }
1195 
1196  if (maxWJet < nJets)
1197  {
1198  pileup[maxWJet] += vMaker(cellArea*databuf[iphi],
1199  eta, g.phiBinCenter(iphi));
1200  cellCounts[maxWJet]++;
1201  }
1202  }
1203  }
1204 }
1205 
1206 
1207 // ------------ method called once each job just after ending the event loop
1209 {
1210 }
1211 
1212 
1213 //define this as a plug-in
std::vector< std::vector< reco::CandidatePtr > > constituents
dbl * delta
Definition: mlp_gen.cc:36
virtual ~FFTJetProducer()
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:41
T getParameter(std::string const &) const
std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > pileupEnergyFlow
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > energyFlow
std::auto_ptr< RecoAlg > recoAlg
std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > memberFactorCalcPeak
unsigned iterationsPerformed
std::vector< ProtoJet > OutputCollection
Definition: JetRecoTypes.h:63
virtual void beginJob()
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:19
const double gridScanMaxEta
void saveResults(edm::Event &iEvent, const edm::EventSetup &, unsigned nPreclustersFound)
std::auto_ptr< fftjet::Grid2d< Real > > fftjet_Grid2d_parser(const edm::ParameterSet &ps)
virtual std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_recoScaleRatioCalcPeak(const edm::ParameterSet &)
std::auto_ptr< GridAlg > gridAlg
std::auto_ptr< fftjetcms::AbsPileupCalculator > pileupDensityCalc
virtual void assignMembershipFunctions(std::vector< fftjet::Peak > *preclusters)
const reco::Particle::Point & vertexUsed() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void loadInputCollection(const edm::Event &)
virtual std::auto_ptr< fftjet::Functor1< bool, fftjet::Peak > > parse_peakSelector(const edm::ParameterSet &)
virtual std::auto_ptr< fftjetcms::AbsPileupCalculator > parse_pileupDensityCalc(const edm::ParameterSet &ps)
double BgData
const std::string recombinationAlgorithm
static const int stable
Definition: TopGenEvent.h:11
const double fixedScale
Data processing summary generated by FFTJetProducer.
virtual std::auto_ptr< fftjetcms::AbsBgFunctor > parse_bgMembershipFunction(const edm::ParameterSet &)
const bool subtractPileupAs4Vec
#define NULL
Definition: scimark2.h:8
std::auto_ptr< fftjet::ScaleSpaceKernel > fftjet_MembershipFunction_parser(const edm::ParameterSet &ps)
void checkConfig(const Ptr &ptr, const char *message)
const double unlikelyBgWeight
void makeProduces(const std::string &alias, const std::string &tag)
const bool subtractPileup
Resolution resolution
std::auto_ptr< AbsPileupCalculator > fftjet_PileupCalculator_parser(const edm::ParameterSet &ps)
std::vector< double > doubleBuf
std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > recoScaleCalcPeak
std::vector< fftjet::AbsKernel2d * > memFcns2dVec
std::vector< RecoFFTJet > recoJets
const bool isCrisp
T eta() const
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()
virtual std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_memberFactorCalcPeak(const edm::ParameterSet &)
void loadSparseTreeData(const edm::Event &)
std::auto_ptr< fftjetcms::AbsBgFunctor > bgMembershipFunction
const bool reuseExistingGrid
std::auto_ptr< fftjet::Functor1< bool, fftjet::Peak > > fftjet_PeakSelector_parser(const edm::ParameterSet &ps)
const unsigned nClustersRequested
virtual void produce(edm::Event &, const edm::EventSetup &)
int iEvent
Definition: GenABIO.cc:243
std::vector< unsigned > candidateIndex
std::auto_ptr< fftjet::Functor2< double, fftjet::RecombinedJet< VectorLike >, fftjet::RecombinedJet< VectorLike > > > fftjet_JetDistance_parser(const edm::ParameterSet &ps)
double dPhi(double phi1, double phi2)
Definition: JetUtil.h:30
std::auto_ptr< std::vector< double > > iniScales
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:85
math::XYZTLorentzVector VectorLike
unsigned usedLevel
double p4[4]
Definition: TauolaWrapper.h:92
std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > memberFactorCalcJet
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:168
virtual std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_recoScaleCalcJet(const edm::ParameterSet &)
vector< PseudoJet > jets
Implements inheritance relationships for FFTJet jets.
Definition: FFTAnyJet.h:17
const double noiseLevel
static void setJetStatusBit(RecoFFTJet *jet, int mask, bool value)
std::vector< RecoFFTJet > iterJets
double f[11][100]
fftjet::SparseClusteringTree< fftjet::Peak, long > SparseTree
std::vector< unsigned > cellCountsVec
virtual void determinePileupDensity(const edm::Event &iEvent, const edm::InputTag &label, std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > &density)
std::vector< double > thresholds
virtual std::auto_ptr< fftjet::Functor2< double, RecoFFTJet, RecoFFTJet > > parse_jetDistanceCalc(const edm::ParameterSet &)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
virtual void endJob()
unsigned iterateJetReconstruction()
void setNCells(const double nc)
Definition: FFTJet.h:85
const bool calculatePileup
const bool assignConstituents
bool storeInSinglePrecision() const
void setPileup(const math::XYZTLorentzVector &p)
Definition: FFTJet.h:81
std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > fftjet_PeakFunctor_parser(const edm::ParameterSet &ps)
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)
#define M_PI
Definition: BFit3D.cc:3
const edm::ParameterSet myConfiguration
fftjet::RecombinedJet< fftjetcms::VectorLike > RecoFFTJet
const double stabilityAlpha
std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > recoScaleRatioCalcPeak
virtual std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_memberFactorCalcJet(const edm::ParameterSet &)
SparseTree sparseTree
virtual std::auto_ptr< fftjet::Functor1< double, fftjet::Peak > > parse_recoScaleCalcPeak(const edm::ParameterSet &)
void setFourVec(const math::XYZTLorentzVector &p)
Definition: FFTJet.h:82
std::vector< SparseTree::NodeId > nodes
void determineGriddedConstituents()
const double convergenceDistance
void writeJets(edm::Event &iEvent, const edm::EventSetup &)
virtual std::auto_ptr< fftjet::ScaleSpaceKernel > parse_jetMembershipFunction(const edm::ParameterSet &)
virtual std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > parse_recoScaleRatioCalcJet(const edm::ParameterSet &)
std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > recoScaleRatioCalcJet
const edm::InputTag pileupLabel
tuple level
Definition: testEve_cfg.py:34
#define jet_type_switch(method, arg1, arg2)
static bool loadEnergyFlow(const edm::Event &iEvent, const edm::InputTag &label, std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > &flow)
tuple status
Definition: ntuplemaker.py:245
virtual bool isPhiDependent() const =0
std::auto_ptr< AbsBgFunctor > fftjet_BgFunctor_parser(const edm::ParameterSet &ps)
long double T
std::vector< fftjetcms::VectorLike > eventData
const std::string outputLabel
fftjetcms::VectorLike unclustered
std::auto_ptr< fftjet::Functor1< bool, fftjet::Peak > > peakSelector
std::vector< fftjet::Peak > iterPreclusters
std::auto_ptr< std::vector< double > > fftjet_ScaleSet_parser(const edm::ParameterSet &ps)
std::auto_ptr< fftjet::Functor2< double, RecoFFTJet, RecoFFTJet > > jetDistanceCalc
std::auto_ptr< fftjet::ScaleSpaceKernel > jetMembershipFunction
std::auto_ptr< fftjet::Functor1< double, fftjet::RecombinedJet< VectorLike > > > fftjet_JetFunctor_parser(const edm::ParameterSet &ps)
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:41
void removeFakePreclusters()
const unsigned maxIterations
std::auto_ptr< fftjet::Functor1< double, RecoFFTJet > > recoScaleCalcJet
void prepareRecombinationScales()
Definition: DDAxes.h:10