00001
00002
00003
00004
00005
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "fftjet/ProximityClusteringTree.hh"
00023 #include "fftjet/ClusteringSequencer.hh"
00024 #include "fftjet/ClusteringTreeSparsifier.hh"
00025 #include "fftjet/FrequencyKernelConvolver.hh"
00026 #include "fftjet/FrequencySequentialConvolver.hh"
00027 #include "fftjet/DiscreteGauss1d.hh"
00028 #include "fftjet/DiscreteGauss2d.hh"
00029
00030
00031 #include "FWCore/Framework/interface/Frameworkfwd.h"
00032 #include "FWCore/Framework/interface/EDProducer.h"
00033 #include "FWCore/Framework/interface/MakerMacros.h"
00034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00035
00036 #include "DataFormats/Common/interface/View.h"
00037 #include "DataFormats/Common/interface/Handle.h"
00038 #include "DataFormats/VertexReco/interface/Vertex.h"
00039 #include "DataFormats/JetReco/interface/CaloJetCollection.h"
00040 #include "DataFormats/JetReco/interface/GenJetCollection.h"
00041 #include "DataFormats/JetReco/interface/PFJetCollection.h"
00042 #include "DataFormats/JetReco/interface/BasicJetCollection.h"
00043 #include "DataFormats/JetReco/interface/TrackJetCollection.h"
00044 #include "DataFormats/Candidate/interface/Candidate.h"
00045
00046
00047 #include "RecoJets/FFTJetAlgorithms/interface/DiscretizedEnergyFlow.h"
00048
00049
00050 #include "RecoJets/FFTJetProducers/interface/FFTJetParameterParser.h"
00051
00052
00053 #include "RecoJets/FFTJetAlgorithms/interface/clusteringTreeConverters.h"
00054
00055
00056 #include "RecoJets/FFTJetProducers/interface/FFTJetInterface.h"
00057
00058 using namespace fftjetcms;
00059
00060
00061
00062
00063 class FFTJetPatRecoProducer : public edm::EDProducer, public FFTJetInterface
00064 {
00065 public:
00066 explicit FFTJetPatRecoProducer(const edm::ParameterSet&);
00067 ~FFTJetPatRecoProducer();
00068
00069 protected:
00070
00071 typedef fftjet::ProximityClusteringTree<fftjet::Peak,long> ClusteringTree;
00072 typedef fftjet::SparseClusteringTree<fftjet::Peak,long> SparseTree;
00073 typedef fftjet::ClusteringSequencer<Real> Sequencer;
00074 typedef fftjet::ClusteringTreeSparsifier<fftjet::Peak,long> Sparsifier;
00075
00076
00077 void beginJob() ;
00078 void produce(edm::Event&, const edm::EventSetup&);
00079 void endJob() ;
00080
00081 void buildKernelConvolver(const edm::ParameterSet&);
00082 fftjet::PeakFinder buildPeakFinder(const edm::ParameterSet&);
00083
00084 template<class Real>
00085 void buildSparseProduct(edm::Event&) const;
00086
00087 template<class Real>
00088 void buildDenseProduct(edm::Event&) const;
00089
00090
00091 ClusteringTree* clusteringTree;
00092
00093
00094
00095
00096 std::auto_ptr<Sequencer> sequencer;
00097 std::auto_ptr<Sparsifier> sparsifier;
00098
00099
00100 std::auto_ptr<MyFFTEngine> engine;
00101 std::auto_ptr<MyFFTEngine> anotherEngine;
00102
00103
00104 std::auto_ptr<fftjet::AbsFrequencyKernel> kernel2d;
00105 std::auto_ptr<fftjet::AbsFrequencyKernel1d> etaKernel;
00106 std::auto_ptr<fftjet::AbsFrequencyKernel1d> phiKernel;
00107
00108
00109 std::auto_ptr<fftjet::AbsConvolverBase<Real> > convolver;
00110
00111
00112 std::auto_ptr<fftjet::Functor1<bool,fftjet::Peak> > peakSelector;
00113
00114
00115 std::auto_ptr<fftjet::AbsDistanceCalculator<fftjet::Peak> > distanceCalc;
00116
00117
00118 SparseTree sparseTree;
00119
00120
00121
00122
00123 const double completeEventDataCutoff;
00124
00125
00126 const bool makeClusteringTree;
00127
00128
00129
00130 const bool verifyDataConversion;
00131
00132
00133 const bool storeDiscretizationGrid;
00134
00135
00136 const bool sparsify;
00137
00138 private:
00139 FFTJetPatRecoProducer();
00140 FFTJetPatRecoProducer(const FFTJetPatRecoProducer&);
00141 FFTJetPatRecoProducer& operator=(const FFTJetPatRecoProducer&);
00142 };
00143
00144
00145
00146
00147 FFTJetPatRecoProducer::FFTJetPatRecoProducer(const edm::ParameterSet& ps)
00148 : FFTJetInterface(ps),
00149 clusteringTree(0),
00150 completeEventDataCutoff(ps.getParameter<double>("completeEventDataCutoff")),
00151 makeClusteringTree(ps.getParameter<bool>("makeClusteringTree")),
00152 verifyDataConversion(ps.getUntrackedParameter<bool>("verifyDataConversion",false)),
00153 storeDiscretizationGrid(ps.getParameter<bool>("storeDiscretizationGrid")),
00154 sparsify(ps.getParameter<bool>("sparsify"))
00155 {
00156
00157 if (makeClusteringTree)
00158 {
00159 if (storeInSinglePrecision())
00160 produces<reco::PattRecoTree<float,reco::PattRecoPeak<float> > >(outputLabel);
00161 else
00162 produces<reco::PattRecoTree<double,reco::PattRecoPeak<double> > >(outputLabel);
00163 }
00164 if (storeDiscretizationGrid)
00165 produces<DiscretizedEnergyFlow>(outputLabel);
00166
00167 if (!makeClusteringTree && !storeDiscretizationGrid)
00168 {
00169 throw cms::Exception("FFTJetBadConfig")
00170 << "FFTJetPatRecoProducer is not configured to produce anything"
00171 << std::endl;
00172 }
00173
00174
00175
00176
00177 energyFlow = fftjet_Grid2d_parser(
00178 ps.getParameter<edm::ParameterSet>("GridConfiguration"));
00179 checkConfig(energyFlow, "invalid discretization grid");
00180
00181
00182
00183 buildKernelConvolver(ps);
00184
00185
00186 peakSelector = fftjet_PeakSelector_parser(
00187 ps.getParameter<edm::ParameterSet>("PeakSelectorConfiguration"));
00188 checkConfig(peakSelector, "invalid peak selector");
00189
00190
00191 std::auto_ptr<std::vector<double> > iniScales = fftjet_ScaleSet_parser(
00192 ps.getParameter<edm::ParameterSet>("InitialScales"));
00193 checkConfig(iniScales, "invalid set of scales");
00194
00195
00196 const unsigned maxAdaptiveScales =
00197 ps.getParameter<unsigned>("maxAdaptiveScales");
00198 const double minAdaptiveRatioLog =
00199 ps.getParameter<double>("minAdaptiveRatioLog");
00200 if (minAdaptiveRatioLog <= 0.0)
00201 throw cms::Exception("FFTJetBadConfig")
00202 << "bad adaptive ratio logarithm limit" << std::endl;
00203
00204
00205
00206 if (getEventScale() > 0.0)
00207 {
00208 const double cs = getEventScale();
00209 const unsigned nscales = iniScales->size();
00210 for (unsigned i=0; i<nscales; ++i)
00211 if (cs >= (*iniScales)[i])
00212 throw cms::Exception("FFTJetBadConfig")
00213 << "incompatible scale for complete event" << std::endl;
00214 }
00215
00216
00217 sequencer = std::auto_ptr<Sequencer>(new Sequencer(
00218 convolver.get(), peakSelector.get(), buildPeakFinder(ps),
00219 *iniScales, maxAdaptiveScales, minAdaptiveRatioLog));
00220
00221
00222 const edm::ParameterSet& SparsifierConfiguration(
00223 ps.getParameter<edm::ParameterSet>("SparsifierConfiguration"));
00224 sparsifier = fftjet_ClusteringTreeSparsifier_parser(
00225 SparsifierConfiguration);
00226 checkConfig(sparsifier, "invalid sparsifier parameters");
00227
00228
00229 const edm::ParameterSet& TreeDistanceCalculator(
00230 ps.getParameter<edm::ParameterSet>("TreeDistanceCalculator"));
00231 distanceCalc = fftjet_DistanceCalculator_parser(TreeDistanceCalculator);
00232 checkConfig(distanceCalc, "invalid tree distance calculator");
00233
00234
00235 clusteringTree = new ClusteringTree(distanceCalc.get());
00236 }
00237
00238
00239 void FFTJetPatRecoProducer::buildKernelConvolver(const edm::ParameterSet& ps)
00240 {
00241
00242
00243 const std::vector<double> etaDependentScaleFactors(
00244 ps.getParameter<std::vector<double> >("etaDependentScaleFactors"));
00245
00246
00247 const bool use2dKernel = etaDependentScaleFactors.empty();
00248 if (!use2dKernel)
00249 if (etaDependentScaleFactors.size() != energyFlow->nEta())
00250 throw cms::Exception("FFTJetBadConfig")
00251 << "invalid number of eta-dependent scale factors"
00252 << std::endl;
00253
00254
00255 double kernelEtaScale = ps.getParameter<double>("kernelEtaScale");
00256 const double kernelPhiScale = ps.getParameter<double>("kernelPhiScale");
00257 if (kernelEtaScale <= 0.0 || kernelPhiScale <= 0.0)
00258 throw cms::Exception("FFTJetBadConfig")
00259 << "invalid kernel scale" << std::endl;
00260
00261
00262
00263 kernelEtaScale *= (2.0*M_PI/(energyFlow->etaMax() - energyFlow->etaMin()));
00264
00265
00266 const bool fixEfficiency = ps.getParameter<bool>("fixEfficiency");
00267
00268
00269 unsigned convolverMinBin = 0, convolverMaxBin = 0;
00270 if (fixEfficiency || !use2dKernel)
00271 {
00272 convolverMinBin = ps.getParameter<unsigned>("convolverMinBin");
00273 convolverMaxBin = ps.getParameter<unsigned>("convolverMaxBin");
00274 }
00275
00276 if (use2dKernel)
00277 {
00278
00279 engine = std::auto_ptr<MyFFTEngine>(
00280 new MyFFTEngine(energyFlow->nEta(), energyFlow->nPhi()));
00281
00282
00283 kernel2d = std::auto_ptr<fftjet::AbsFrequencyKernel>(
00284 new fftjet::DiscreteGauss2d(
00285 kernelEtaScale, kernelPhiScale,
00286 energyFlow->nEta(), energyFlow->nPhi()));
00287
00288
00289 convolver = std::auto_ptr<fftjet::AbsConvolverBase<Real> >(
00290 new fftjet::FrequencyKernelConvolver<Real,Complex>(
00291 engine.get(), kernel2d.get(),
00292 convolverMinBin, convolverMaxBin));
00293 }
00294 else
00295 {
00296
00297 engine = std::auto_ptr<MyFFTEngine>(
00298 new MyFFTEngine(1, energyFlow->nEta()));
00299 anotherEngine = std::auto_ptr<MyFFTEngine>(
00300 new MyFFTEngine(1, energyFlow->nPhi()));
00301
00302
00303 etaKernel = std::auto_ptr<fftjet::AbsFrequencyKernel1d>(
00304 new fftjet::DiscreteGauss1d(kernelEtaScale, energyFlow->nEta()));
00305
00306 phiKernel = std::auto_ptr<fftjet::AbsFrequencyKernel1d>(
00307 new fftjet::DiscreteGauss1d(kernelPhiScale, energyFlow->nPhi()));
00308
00309
00310 convolver = std::auto_ptr<fftjet::AbsConvolverBase<Real> >(
00311 new fftjet::FrequencySequentialConvolver<Real,Complex>(
00312 engine.get(), anotherEngine.get(),
00313 etaKernel.get(), phiKernel.get(),
00314 etaDependentScaleFactors, convolverMinBin,
00315 convolverMaxBin, fixEfficiency));
00316 }
00317 }
00318
00319
00320 fftjet::PeakFinder FFTJetPatRecoProducer::buildPeakFinder(const edm::ParameterSet& ps)
00321 {
00322 const double peakFinderMaxEta = ps.getParameter<double>("peakFinderMaxEta");
00323 if (peakFinderMaxEta <= 0.0)
00324 throw cms::Exception("FFTJetBadConfig")
00325 << "invalid peak finder eta cut" << std::endl;
00326 const double maxMagnitude = ps.getParameter<double>("peakFinderMaxMagnitude");
00327 int minBin = energyFlow->getEtaBin(-peakFinderMaxEta);
00328 if (minBin < 0)
00329 minBin = 0;
00330 int maxBin = energyFlow->getEtaBin(peakFinderMaxEta) + 1;
00331 if (maxBin < 0)
00332 maxBin = 0;
00333 return fftjet::PeakFinder(maxMagnitude, true, minBin, maxBin);
00334 }
00335
00336
00337 FFTJetPatRecoProducer::~FFTJetPatRecoProducer()
00338 {
00339
00340
00341 delete clusteringTree;
00342 }
00343
00344
00345
00346
00347
00348 template<class Real>
00349 void FFTJetPatRecoProducer::buildSparseProduct(edm::Event& ev) const
00350 {
00351 typedef reco::PattRecoTree<Real,reco::PattRecoPeak<Real> > StoredTree;
00352
00353 std::auto_ptr<StoredTree> tree(new StoredTree());
00354
00355 sparsePeakTreeToStorable(sparseTree,
00356 sequencer->maxAdaptiveScales(),
00357 tree.get());
00358
00359
00360 if (verifyDataConversion && !storeInSinglePrecision())
00361 {
00362 SparseTree check;
00363 const std::vector<double>& scalesUsed(sequencer->getInitialScales());
00364 sparsePeakTreeFromStorable(*tree, &scalesUsed, getEventScale(), &check);
00365 if (sparseTree != check)
00366 throw cms::Exception("FFTJetInterface")
00367 << "Data conversion failed for sparse clustering tree"
00368 << std::endl;
00369 }
00370
00371 ev.put(tree, outputLabel);
00372 }
00373
00374
00375 template<class Real>
00376 void FFTJetPatRecoProducer::buildDenseProduct(edm::Event& ev) const
00377 {
00378 typedef reco::PattRecoTree<Real,reco::PattRecoPeak<Real> > StoredTree;
00379
00380 std::auto_ptr<StoredTree> tree(new StoredTree());
00381
00382 densePeakTreeToStorable(*clusteringTree,
00383 sequencer->maxAdaptiveScales(),
00384 tree.get());
00385
00386
00387 if (verifyDataConversion && !storeInSinglePrecision())
00388 {
00389 ClusteringTree check(distanceCalc.get());
00390 const std::vector<double>& scalesUsed(sequencer->getInitialScales());
00391 densePeakTreeFromStorable(*tree, &scalesUsed, getEventScale(), &check);
00392 if (*clusteringTree != check)
00393 throw cms::Exception("FFTJetInterface")
00394 << "Data conversion failed for dense clustering tree"
00395 << std::endl;
00396 }
00397
00398 ev.put(tree, outputLabel);
00399 }
00400
00401
00402
00403 void FFTJetPatRecoProducer::produce(
00404 edm::Event& iEvent, const edm::EventSetup& iSetup)
00405 {
00406 loadInputCollection(iEvent);
00407 discretizeEnergyFlow();
00408
00409 if (makeClusteringTree)
00410 {
00411 sequencer->run(*energyFlow, clusteringTree);
00412 if (getEventScale() > 0.0)
00413 sequencer->insertCompleteEvent(getEventScale(), *energyFlow,
00414 clusteringTree, completeEventDataCutoff);
00415
00416 if (sparsify)
00417 {
00418 sparsifier->sparsify(*clusteringTree, &sparseTree);
00419
00420
00421
00422
00423
00424
00425 if (storeInSinglePrecision())
00426 buildSparseProduct<float>(iEvent);
00427 else
00428 buildSparseProduct<double>(iEvent);
00429 }
00430 else
00431 {
00432 if (storeInSinglePrecision())
00433 buildDenseProduct<float>(iEvent);
00434 else
00435 buildDenseProduct<double>(iEvent);
00436 }
00437 }
00438
00439 if (storeDiscretizationGrid)
00440 {
00441 const fftjet::Grid2d<Real>& g(*energyFlow);
00442
00443 std::auto_ptr<DiscretizedEnergyFlow> flow(
00444 new DiscretizedEnergyFlow(
00445 g.data(), g.title(), g.etaMin(), g.etaMax(),
00446 g.phiBin0Edge(), g.nEta(), g.nPhi()));
00447
00448 if (verifyDataConversion)
00449 {
00450 fftjet::Grid2d<Real> check(
00451 flow->nEtaBins(), flow->etaMin(), flow->etaMax(),
00452 flow->nPhiBins(), flow->phiBin0Edge(), flow->title());
00453 check.blockSet(flow->data(), flow->nEtaBins(), flow->nPhiBins());
00454 assert(g == check);
00455 }
00456
00457 iEvent.put(flow, outputLabel);
00458 }
00459 }
00460
00461
00462
00463 void FFTJetPatRecoProducer::beginJob()
00464 {
00465 }
00466
00467
00468
00469 void FFTJetPatRecoProducer::endJob()
00470 {
00471 }
00472
00473
00474
00475 DEFINE_FWK_MODULE(FFTJetPatRecoProducer);