1 |
dnisson |
1.18 |
//*- C++ -*-
|
2 |
dnisson |
1.1 |
//
|
3 |
|
|
// Package: JetFitAnalyzer
|
4 |
|
|
// Class: JetFitAnalyzer
|
5 |
|
|
//
|
6 |
|
|
/**\class JetFitAnalyzer JetFitAnalyzer.cc UserCode/JetFitAnalyzer/src/JetFitAnalyzer.cc
|
7 |
|
|
|
8 |
|
|
Description: Base class for using jetfit with CMSSW
|
9 |
|
|
|
10 |
|
|
Implementation:
|
11 |
|
|
o Method make_histo is used to prepare a histogram for analysis;
|
12 |
|
|
the user can read this from a file or generate from the actual event
|
13 |
|
|
o Method make_model_def is used to define a formula and initial
|
14 |
|
|
parameters for the model used
|
15 |
|
|
o Method analyze_results performs user analysis on results;
|
16 |
|
|
the user is given a trouble vector and the original histogram in
|
17 |
|
|
addition.
|
18 |
|
|
o The function pointer user_minuit defines what to do after each fit
|
19 |
|
|
is done. The pointer should be obtained in the subclass constructor.
|
20 |
|
|
*/
|
21 |
|
|
//
|
22 |
|
|
// Original Author: David Nisson
|
23 |
|
|
// Created: Wed Aug 5 16:38:38 PDT 2009
|
24 |
dnisson |
1.20 |
// $Id: JetFitAnalyzer.cc,v 1.19 2010/03/01 01:59:08 dnisson Exp $
|
25 |
dnisson |
1.1 |
//
|
26 |
|
|
//
|
27 |
|
|
|
28 |
dnisson |
1.16 |
#include <HepMC/GenEvent.h>
|
29 |
|
|
#include <HepMC/GenVertex.h>
|
30 |
|
|
#include <HepMC/GenParticle.h>
|
31 |
|
|
|
32 |
dnisson |
1.1 |
#include "UserCode/JetFitAnalyzer/interface/JetFitAnalyzer.h"
|
33 |
|
|
|
34 |
dnisson |
1.15 |
#include "DataFormats/JetReco/interface/PFJetCollection.h"
|
35 |
|
|
#include "DataFormats/JetReco/interface/GenJetCollection.h"
|
36 |
|
|
#include "DataFormats/JetReco/interface/PFJet.h"
|
37 |
|
|
#include "DataFormats/JetReco/interface/GenJet.h"
|
38 |
dnisson |
1.16 |
#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
|
39 |
dnisson |
1.15 |
|
40 |
|
|
#include "FWCore/ServiceRegistry/interface/Service.h"
|
41 |
|
|
#include "FWCore/MessageLogger/interface/MessageLogger.h"
|
42 |
|
|
#include "PhysicsTools/UtilAlgos/interface/TFileService.h"
|
43 |
|
|
|
44 |
|
|
#include "TFormula.h"
|
45 |
|
|
#define PI 3.141592
|
46 |
|
|
|
47 |
|
|
#include <iostream>
|
48 |
|
|
#include <sstream>
|
49 |
|
|
#include <string>
|
50 |
dnisson |
1.16 |
#include <fstream>
|
51 |
|
|
// to save the W decay product energy, mass, eta, phi
|
52 |
dnisson |
1.15 |
|
53 |
|
|
using namespace std;
|
54 |
|
|
|
55 |
dnisson |
1.1 |
JetFitAnalyzer::JetFitAnalyzer(const edm::ParameterSet& iConfig)
|
56 |
|
|
{
|
57 |
|
|
// get parameters from iConfig
|
58 |
|
|
P_cutoff_val_ = iConfig.getUntrackedParameter("P_cutoff_val", 0.5);
|
59 |
dnisson |
1.15 |
infoType_ = iConfig.getUntrackedParameter("infoType", 1);
|
60 |
|
|
smear_ = iConfig.getUntrackedParameter("smear", 0.05);
|
61 |
|
|
jet_algo_ = iConfig.getParameter<string>("jet_algo");
|
62 |
dnisson |
1.18 |
maxGaussians_ = iConfig.getUntrackedParameter("maxGaussians", 4);
|
63 |
|
|
gausSpread_ = iConfig.getUntrackedParameter("gausSpread", 0.1);
|
64 |
dnisson |
1.1 |
}
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
JetFitAnalyzer::~JetFitAnalyzer()
|
68 |
|
|
{
|
69 |
|
|
|
70 |
|
|
// do anything here that needs to be done at desctruction time
|
71 |
|
|
// (e.g. close files, deallocate resources etc.)
|
72 |
|
|
|
73 |
|
|
}
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
//
|
77 |
|
|
// member functions
|
78 |
|
|
//
|
79 |
|
|
|
80 |
|
|
// ------------ method called to for each event ------------
|
81 |
|
|
void
|
82 |
|
|
JetFitAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
|
83 |
|
|
{
|
84 |
|
|
using namespace edm;
|
85 |
|
|
|
86 |
dnisson |
1.13 |
HistoFitter histoFitter;
|
87 |
dnisson |
1.15 |
std::vector<HistoFitter::Trouble> t; // record troubles fitting
|
88 |
dnisson |
1.1 |
|
89 |
dnisson |
1.17 |
std::vector<TH2D *> histos = make_histo(iEvent, iSetup); // create the histogrms
|
90 |
|
|
for (unsigned i= 0; i < histos.size(); i++) {
|
91 |
|
|
TH2D *histo = histos[i]; // obtain the histogram
|
92 |
|
|
if (histo != 0) {
|
93 |
|
|
HistoFitter::ModelDefinition &_mdef = make_model_def(iEvent, iSetup, histo);
|
94 |
|
|
histoFitter.set_ModelDefinition(&_mdef);
|
95 |
|
|
HistoFitter::FitResults r(histoFitter.fit_histo(histo, t, 1, P_cutoff_val_)); // fit the histogram
|
96 |
|
|
analyze_results(r, t, histo); // perform user analysis
|
97 |
|
|
}
|
98 |
|
|
else {
|
99 |
|
|
std::cerr << "Fitting not performed" << std::endl;
|
100 |
|
|
}
|
101 |
dnisson |
1.2 |
}
|
102 |
dnisson |
1.1 |
}
|
103 |
|
|
|
104 |
dnisson |
1.17 |
/* create histograms of the particles in all jets found */
|
105 |
|
|
std::vector<TH2D *> JetFitAnalyzer::make_histo(const edm::Event &evt, const edm::EventSetup&) {
|
106 |
|
|
std::vector<TH2D*> histos;
|
107 |
dnisson |
1.15 |
|
108 |
dnisson |
1.17 |
std::vector<const reco::Jet *> jets;
|
109 |
dnisson |
1.15 |
if (infoType_ == 0) {
|
110 |
|
|
edm::Handle< vector<reco::GenJet> > evtJets;
|
111 |
|
|
evt.getByLabel(jet_algo_, evtJets);
|
112 |
dnisson |
1.17 |
jets.resize(evtJets->size());
|
113 |
dnisson |
1.15 |
for (unsigned i = 0; i < evtJets->size(); i++) {
|
114 |
dnisson |
1.17 |
jets[i] = &((*evtJets)[i]);
|
115 |
dnisson |
1.15 |
}
|
116 |
|
|
}
|
117 |
|
|
else if (infoType_ == 1) {
|
118 |
|
|
edm::Handle< vector<reco::PFJet> > evtJets;
|
119 |
|
|
evt.getByLabel(jet_algo_, evtJets);
|
120 |
dnisson |
1.17 |
jets.resize(evtJets->size());
|
121 |
dnisson |
1.15 |
for (unsigned i = 0; i < evtJets->size(); i++) {
|
122 |
dnisson |
1.17 |
jets[i] = &((*evtJets)[i]);
|
123 |
dnisson |
1.15 |
}
|
124 |
|
|
}
|
125 |
|
|
|
126 |
dnisson |
1.17 |
histos.resize(jets.size());
|
127 |
dnisson |
1.15 |
|
128 |
dnisson |
1.17 |
for (unsigned i = 0; i < jets.size(); i++) {
|
129 |
|
|
/* Get the particles in the fat jet */
|
130 |
|
|
vector<const reco::Candidate *> particles =
|
131 |
|
|
jets[i]->getJetConstituentsQuick();
|
132 |
dnisson |
1.15 |
|
133 |
dnisson |
1.17 |
/* Create the histogram name */
|
134 |
|
|
ostringstream oss;
|
135 |
|
|
oss << "eta_phi_energy"<<evt.id().event() <<"jet"<<i << flush;
|
136 |
|
|
|
137 |
|
|
edm::Service<TFileService> fs;
|
138 |
|
|
|
139 |
|
|
/* save the true W decay products */
|
140 |
|
|
/* Get the generator-level info */
|
141 |
|
|
edm::Handle<edm::HepMCProduct> genProduct;
|
142 |
|
|
evt.getByLabel("generator", genProduct);
|
143 |
|
|
const HepMC::GenEvent *genEvt = genProduct->GetEvent();
|
144 |
|
|
|
145 |
|
|
/* Save to file */
|
146 |
|
|
ofstream ofs("true_W_decay.txt", ios_base::app);
|
147 |
|
|
ofs << "Event "<<evt.id().event()<<", jet"<<i<<":" << endl;
|
148 |
|
|
ofs << "PDG ID"<<'\t'<<"Eta"<<'\t'<<"Phi"<<'\t'<<"Energy"<<endl;
|
149 |
|
|
for (HepMC::GenEvent::particle_const_iterator ppit = genEvt->particles_begin();
|
150 |
|
|
ppit != genEvt->particles_end(); ppit++) {
|
151 |
|
|
if ((*ppit)->pdg_id() == 24 || (*ppit)->pdg_id() == -24) {
|
152 |
|
|
// found W-iterate over daughters
|
153 |
|
|
HepMC::GenVertex *vtx = (*ppit)->end_vertex();
|
154 |
|
|
if (vtx != 0)
|
155 |
|
|
for (HepMC::GenVertex::particles_out_const_iterator pit = vtx->particles_out_const_begin();
|
156 |
|
|
pit != vtx->particles_out_const_end(); pit++) {
|
157 |
|
|
ofs << (*pit)->pdg_id() << '\t' << (*pit)->momentum().eta() << '\t'
|
158 |
|
|
<< (*pit)->momentum().phi() << '\t' << (*pit)->momentum().e() << endl;
|
159 |
|
|
}
|
160 |
dnisson |
1.16 |
}
|
161 |
|
|
}
|
162 |
dnisson |
1.17 |
ofs.close();
|
163 |
|
|
|
164 |
|
|
/* Initialize the histogram */
|
165 |
|
|
TH2D *histo = fs->make<TH2D>(oss.str().c_str(), oss.str().c_str(),
|
166 |
|
|
30,
|
167 |
|
|
jets[i]->eta()-0.5,
|
168 |
|
|
jets[i]->eta()+0.5,
|
169 |
|
|
30,
|
170 |
|
|
jets[i]->phi()-0.5,
|
171 |
|
|
jets[i]->phi()+0.5);
|
172 |
|
|
|
173 |
|
|
if (smear_ > 0.0) {
|
174 |
|
|
// get the limits of the histogram
|
175 |
|
|
double Xlo = histo->GetXaxis()->GetXmin();
|
176 |
|
|
double Xhi = histo->GetXaxis()->GetXmax();
|
177 |
|
|
double Ylo = histo->GetYaxis()->GetXmin();
|
178 |
|
|
double Yhi = histo->GetYaxis()->GetXmax();
|
179 |
|
|
|
180 |
|
|
// get the bin sizes
|
181 |
|
|
double XbinSize = (Xhi - Xlo) / static_cast<double>(histo->GetNbinsX());
|
182 |
|
|
double YbinSize = (Yhi - Ylo) / static_cast<double>(histo->GetNbinsY());
|
183 |
|
|
|
184 |
|
|
for (int i = 0; i < particles.size(); i++) {
|
185 |
|
|
// compute the parameters of the Gaussian to be added
|
186 |
|
|
double N = particles[i]->energy();
|
187 |
|
|
double x = particles[i]->eta();
|
188 |
|
|
double y = particles[i]->phi();
|
189 |
|
|
|
190 |
|
|
// Compute correct phi for this histogram if it is out of range
|
191 |
|
|
if (y < Ylo) {
|
192 |
|
|
y += 2.0*PI;
|
193 |
|
|
}
|
194 |
|
|
if (y > Yhi) {
|
195 |
|
|
y -= 2.0*PI;
|
196 |
|
|
}
|
197 |
|
|
|
198 |
|
|
// loop over bins and add Gaussian in eta and phi to histogram
|
199 |
|
|
for (vector< vector<double> >::size_type i2 = 0; i2 < 30; i2++) {
|
200 |
|
|
for (vector< double >::size_type j2 = 0; j2 < 30; j2++) {
|
201 |
|
|
// compute the distance of the bin from the particle eta, phi
|
202 |
|
|
double eta = static_cast<double>((signed int)i2) * XbinSize +
|
203 |
|
|
Xlo - x;
|
204 |
|
|
double phi = static_cast<double>((signed int)j2) * YbinSize +
|
205 |
|
|
Ylo - y;
|
206 |
|
|
|
207 |
|
|
/* Fill the histogram with a Gaussian centered around particle */
|
208 |
|
|
histo->SetBinContent(i2+1, j2+1, histo->GetBinContent(i2+1, j2+1)
|
209 |
|
|
+ (N*XbinSize*YbinSize/(2.0*PI*smear_*smear_))
|
210 |
|
|
* exp(-0.5*(eta*eta + phi*phi)/(smear_*smear_)));
|
211 |
|
|
}
|
212 |
dnisson |
1.15 |
}
|
213 |
|
|
}
|
214 |
|
|
}
|
215 |
dnisson |
1.17 |
else {
|
216 |
|
|
// don't smear--just fill with particles
|
217 |
|
|
for (int i = 0; i < particles.size(); i++) {
|
218 |
|
|
histo->Fill(particles[i]->eta(), particles[i]->phi(),
|
219 |
|
|
particles[i]->energy());
|
220 |
|
|
}
|
221 |
dnisson |
1.15 |
}
|
222 |
dnisson |
1.17 |
histos[i] = histo;
|
223 |
dnisson |
1.15 |
}
|
224 |
dnisson |
1.17 |
|
225 |
|
|
return histos;
|
226 |
dnisson |
1.15 |
}
|
227 |
|
|
|
228 |
|
|
/* Create a model definition based on the histogram and event information */
|
229 |
|
|
HistoFitter::ModelDefinition& JetFitAnalyzer::make_model_def(const edm::Event& evt,
|
230 |
|
|
const edm::EventSetup&,
|
231 |
|
|
TH2 *histo) {
|
232 |
|
|
class DefaultModelDef : public HistoFitter::ModelDefinition {
|
233 |
|
|
public:
|
234 |
dnisson |
1.20 |
virtual double chisquareSigma(double E, double Emax) {
|
235 |
|
|
double sigma = 0.14*Emax*(1.0 - exp(-2.3*E/Emax));
|
236 |
|
|
|
237 |
|
|
return sigma;
|
238 |
|
|
// based on Nisson Elog entry 33
|
239 |
dnisson |
1.15 |
}
|
240 |
|
|
};
|
241 |
|
|
|
242 |
|
|
DefaultModelDef *_mdef = new DefaultModelDef();
|
243 |
|
|
|
244 |
|
|
// 2D Gaussian formula
|
245 |
|
|
TFormula *formula = new TFormula("gaus2d",
|
246 |
|
|
"[0]*exp(-0.5*((x-[1])**2 + (y-[2])**2)/([3]**2))/(2*pi*[3]**2)");
|
247 |
|
|
_mdef->setFormula(formula);
|
248 |
|
|
|
249 |
|
|
_mdef->setIndivEnergy(0);
|
250 |
|
|
_mdef->setIndivMeanX(1);
|
251 |
|
|
_mdef->setIndivMeanY(2);
|
252 |
|
|
_mdef->setIndivParameter(0, string("N"), 0.0, 0.0, 0.0, 1.0e6);
|
253 |
|
|
_mdef->setIndivParameter(1, string("mu_x"), 0.0, 0.0, 0.0, 0.0);
|
254 |
|
|
_mdef->setIndivParameter(2, string("mu_y"), 0.0, 0.0, 0.0, 0.0);
|
255 |
|
|
|
256 |
dnisson |
1.18 |
// set fixed Gaussian sigma equal to gausSpread
|
257 |
|
|
_mdef->setIndivParameter(3, string("sig"), gausSpread_, 0.001, 0.0, 0.0);
|
258 |
dnisson |
1.15 |
|
259 |
dnisson |
1.18 |
_mdef->setMaxNumberOfGaussians(maxGaussians_);
|
260 |
dnisson |
1.15 |
|
261 |
|
|
return *_mdef;
|
262 |
|
|
}
|
263 |
dnisson |
1.1 |
|
264 |
|
|
// ------------ method called once each job just before starting event loop ------------
|
265 |
|
|
void
|
266 |
|
|
JetFitAnalyzer::beginJob(const edm::EventSetup&)
|
267 |
|
|
{
|
268 |
|
|
}
|
269 |
|
|
|
270 |
|
|
// ------------ method called once each job just after ending the event loop ------------
|
271 |
|
|
void
|
272 |
|
|
JetFitAnalyzer::endJob() {
|
273 |
|
|
}
|
274 |
|
|
|
275 |
|
|
//define this as a plug-in
|
276 |
|
|
// this is a base class-we can't do this DEFINE_FWK_MODULE(JetFitAnalyzer);
|