CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FFTJetEFlowSmoother.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FFTJetProducers
4 // Class: FFTJetEFlowSmoother
5 //
13 //
14 // Original Author: Igor Volobouev
15 // Created: Thu Jun 2 18:49:49 CDT 2011
16 // $Id: FFTJetEFlowSmoother.cc,v 1.1 2011/06/03 05:05:44 igv Exp $
17 //
18 //
19 
20 #include <cmath>
21 
22 // FFTJet headers
23 #include "fftjet/FrequencyKernelConvolver.hh"
24 #include "fftjet/DiscreteGauss2d.hh"
25 #include "fftjet/EquidistantSequence.hh"
26 #include "fftjet/interpolate.hh"
27 #include "fftjet/FrequencyKernelConvolver.hh"
28 #include "fftjet/FrequencySequentialConvolver.hh"
29 #include "fftjet/DiscreteGauss1d.hh"
30 #include "fftjet/DiscreteGauss2d.hh"
31 
32 // framework include files
37 
41 
42 // parameter parser header
44 
45 // useful utilities collected in the second base
47 
48 using namespace fftjetcms;
49 
50 //
51 // class declaration
52 //
54 {
55 public:
56  explicit FFTJetEFlowSmoother(const edm::ParameterSet&);
58 
59 protected:
60  // methods
61  void beginJob() ;
62  void produce(edm::Event&, const edm::EventSetup&);
63  void endJob() ;
64 
65 private:
68  FFTJetEFlowSmoother& operator=(const FFTJetEFlowSmoother&);
69 
70  void buildKernelConvolver(const edm::ParameterSet&);
71 
72  // Storage for convolved energy flow
73  std::auto_ptr<fftjet::Grid2d<fftjetcms::Real> > convolvedFlow;
74 
75  // Filtering scales
76  std::auto_ptr<std::vector<double> > iniScales;
77 
78  // The FFT engine(s)
79  std::auto_ptr<MyFFTEngine> engine;
80  std::auto_ptr<MyFFTEngine> anotherEngine;
81 
82  // The pattern recognition kernel(s)
83  std::auto_ptr<fftjet::AbsFrequencyKernel> kernel2d;
84  std::auto_ptr<fftjet::AbsFrequencyKernel1d> etaKernel;
85  std::auto_ptr<fftjet::AbsFrequencyKernel1d> phiKernel;
86 
87  // The kernel convolver
88  std::auto_ptr<fftjet::AbsConvolverBase<Real> > convolver;
89 
90  // The scale power to use for scaling Et
91  double scalePower;
92 
93  // Overall factor to multiply Et with
95 };
96 
97 //
98 // constructors and destructor
99 //
101  : FFTJetInterface(ps),
102  scalePower(ps.getParameter<double>("scalePower")),
103  etConversionFactor(ps.getParameter<double>("etConversionFactor"))
104 {
105  // Build the discretization grid
107  ps.getParameter<edm::ParameterSet>("GridConfiguration"));
108  checkConfig(energyFlow, "invalid discretization grid");
109 
110  // Copy of the grid which will be used for convolutions
111  convolvedFlow = std::auto_ptr<fftjet::Grid2d<fftjetcms::Real> >(
112  new fftjet::Grid2d<fftjetcms::Real>(*energyFlow));
113 
114  // Build the initial set of pattern recognition scales
116  ps.getParameter<edm::ParameterSet>("InitialScales"));
117  checkConfig(iniScales, "invalid set of scales");
118 
119  // Build the FFT engine(s), pattern recognition kernel(s),
120  // and the kernel convolver
122 
123  // Build the set of pattern recognition scales
124  produces<TH3F>(outputLabel);
125 }
126 
127 
129 {
130  // Check the parameter named "etaDependentScaleFactors". If the vector
131  // of scales is empty we will use 2d kernel, otherwise use 1d kernels
132  const std::vector<double> etaDependentScaleFactors(
133  ps.getParameter<std::vector<double> >("etaDependentScaleFactors"));
134 
135  // Make sure that the number of scale factors provided is correct
136  const bool use2dKernel = etaDependentScaleFactors.empty();
137  if (!use2dKernel)
138  if (etaDependentScaleFactors.size() != energyFlow->nEta())
139  throw cms::Exception("FFTJetBadConfig")
140  << "invalid number of eta-dependent scale factors"
141  << std::endl;
142 
143  // Get the eta and phi scales for the kernel(s)
144  double kernelEtaScale = ps.getParameter<double>("kernelEtaScale");
145  const double kernelPhiScale = ps.getParameter<double>("kernelPhiScale");
146  if (kernelEtaScale <= 0.0 || kernelPhiScale <= 0.0)
147  throw cms::Exception("FFTJetBadConfig")
148  << "invalid kernel scale" << std::endl;
149 
150  // FFT assumes that the grid extent in eta is 2*Pi. Adjust the
151  // kernel scale in eta to compensate.
152  kernelEtaScale *= (2.0*M_PI/(energyFlow->etaMax() - energyFlow->etaMin()));
153 
154  // Are we going to try to fix the efficiency near detector edges?
155  const bool fixEfficiency = ps.getParameter<bool>("fixEfficiency");
156 
157  // Minimum and maximum eta bin for the convolver
158  unsigned convolverMinBin = 0, convolverMaxBin = 0;
159  if (fixEfficiency || !use2dKernel)
160  {
161  convolverMinBin = ps.getParameter<unsigned>("convolverMinBin");
162  convolverMaxBin = ps.getParameter<unsigned>("convolverMaxBin");
163  }
164 
165  if (use2dKernel)
166  {
167  // Build the FFT engine
168  engine = std::auto_ptr<MyFFTEngine>(
169  new MyFFTEngine(energyFlow->nEta(), energyFlow->nPhi()));
170 
171  // 2d kernel
172  kernel2d = std::auto_ptr<fftjet::AbsFrequencyKernel>(
173  new fftjet::DiscreteGauss2d(
174  kernelEtaScale, kernelPhiScale,
175  energyFlow->nEta(), energyFlow->nPhi()));
176 
177  // 2d convolver
178  convolver = std::auto_ptr<fftjet::AbsConvolverBase<Real> >(
179  new fftjet::FrequencyKernelConvolver<Real,Complex>(
180  engine.get(), kernel2d.get(),
181  convolverMinBin, convolverMaxBin));
182  }
183  else
184  {
185  // Need separate FFT engines for eta and phi
186  engine = std::auto_ptr<MyFFTEngine>(
187  new MyFFTEngine(1, energyFlow->nEta()));
188  anotherEngine = std::auto_ptr<MyFFTEngine>(
189  new MyFFTEngine(1, energyFlow->nPhi()));
190 
191  // 1d kernels
192  etaKernel = std::auto_ptr<fftjet::AbsFrequencyKernel1d>(
193  new fftjet::DiscreteGauss1d(kernelEtaScale, energyFlow->nEta()));
194 
195  phiKernel = std::auto_ptr<fftjet::AbsFrequencyKernel1d>(
196  new fftjet::DiscreteGauss1d(kernelPhiScale, energyFlow->nPhi()));
197 
198  // Sequential convolver
199  convolver = std::auto_ptr<fftjet::AbsConvolverBase<Real> >(
200  new fftjet::FrequencySequentialConvolver<Real,Complex>(
201  engine.get(), anotherEngine.get(),
202  etaKernel.get(), phiKernel.get(),
203  etaDependentScaleFactors, convolverMinBin,
204  convolverMaxBin, fixEfficiency));
205  }
206 }
207 
208 
210 {
211 }
212 
213 
214 // ------------ method called to produce the data ------------
216  edm::Event& iEvent, const edm::EventSetup& iSetup)
217 {
218  loadInputCollection(iEvent);
220 
221  // Various useful variables
222  const fftjet::Grid2d<Real>& g(*energyFlow);
223  const unsigned nScales = iniScales->size();
224  const double* scales = &(*iniScales)[0];
225  Real* convData = const_cast<Real*>(convolvedFlow->data());
226  const unsigned nEta = g.nEta();
227  const unsigned nPhi = g.nPhi();
228  const double bin0edge = g.phiBin0Edge();
229 
230  // We will fill the following histo
231  std::auto_ptr<TH3F> pTable(
232  new TH3F("FFTJetEFlowSmoother", "FFTJetEFlowSmoother",
233  nScales+1U, -1.5, nScales-0.5,
234  nEta, g.etaMin(), g.etaMax(),
235  nPhi, bin0edge, bin0edge+2.0*M_PI));
236  TH3F* h = pTable.get();
237  h->SetDirectory(0);
238  h->GetXaxis()->SetTitle("Scale");
239  h->GetYaxis()->SetTitle("Eta");
240  h->GetZaxis()->SetTitle("Phi");
241 
242  // Fill the original thing
243  double factor = etConversionFactor*pow(getEventScale(), scalePower);
244  for (unsigned ieta=0; ieta<nEta; ++ieta)
245  for (unsigned iphi=0; iphi<nPhi; ++iphi)
246  h->SetBinContent(1U, ieta+1U, iphi+1U,
247  factor*g.binValue(ieta, iphi));
248 
249  // Go over all scales and perform the convolutions
250  convolver->setEventData(g.data(), nEta, nPhi);
251  for (unsigned iscale=0; iscale<nScales; ++iscale)
252  {
253  factor = etConversionFactor*pow(scales[iscale], scalePower);
254 
255  // Perform the convolution
256  convolver->convolveWithKernel(
257  scales[iscale], convData,
258  convolvedFlow->nEta(), convolvedFlow->nPhi());
259 
260  // Fill the output histo
261  for (unsigned ieta=0; ieta<nEta; ++ieta)
262  {
263  const Real* etaData = convData + ieta*nPhi;
264  for (unsigned iphi=0; iphi<nPhi; ++iphi)
265  h->SetBinContent(iscale+2U, ieta+1U, iphi+1U,
266  factor*etaData[iphi]);
267  }
268  }
269 
270  iEvent.put(pTable, outputLabel);
271 }
272 
273 
274 // ------------ method called once each job just before starting event loop
276 {
277 }
278 
279 
280 // ------------ method called once each job just after ending the event loop
282 {
283 }
284 
285 
286 //define this as a plug-in
T getParameter(std::string const &) const
std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > energyFlow
std::auto_ptr< MyFFTEngine > anotherEngine
std::auto_ptr< fftjet::AbsFrequencyKernel1d > etaKernel
std::auto_ptr< fftjet::Grid2d< Real > > fftjet_Grid2d_parser(const edm::ParameterSet &ps)
std::auto_ptr< fftjet::AbsFrequencyKernel1d > phiKernel
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void loadInputCollection(const edm::Event &)
std::auto_ptr< MyFFTEngine > engine
void checkConfig(const Ptr &ptr, const char *message)
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 beginJob()
Definition: Breakpoints.cc:15
std::auto_ptr< fftjet::AbsFrequencyKernel > kernel2d
int iEvent
Definition: GenABIO.cc:243
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:94
std::auto_ptr< fftjet::Grid2d< fftjetcms::Real > > convolvedFlow
std::auto_ptr< std::vector< double > > iniScales
double Real
#define M_PI
Definition: BFit3D.cc:3
void produce(edm::Event &, const edm::EventSetup &)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
fftjet::FFTWDoubleEngine MyFFTEngine
void buildKernelConvolver(const edm::ParameterSet &)
std::auto_ptr< fftjet::AbsConvolverBase< Real > > convolver
const std::string outputLabel
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
std::auto_ptr< std::vector< double > > fftjet_ScaleSet_parser(const edm::ParameterSet &ps)