ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/JetFitAnalyzer/test/JetFinderAnalyzer.cc
Revision: 1.20
Committed: Wed Nov 11 01:46:56 2009 UTC (15 years, 5 months ago) by dnisson
Content type: text/plain
Branch: MAIN
Changes since 1.19: +4 -24 lines
Log Message:
Encapsulated functions into class model_def, as appropriate.

File Contents

# User Rev Content
1 dnisson 1.1 /* A simple jet-finding analyzer */
2    
3     #include "UserCode/JetFitAnalyzer/interface/JetFitAnalyzer.h"
4    
5     #include "fastjet/ClusterSequence.hh"
6     #include "FWCore/ServiceRegistry/interface/Service.h"
7 dnisson 1.2 #include "FWCore/MessageLogger/interface/MessageLogger.h"
8 dnisson 1.1 #include "PhysicsTools/UtilAlgos/interface/TFileService.h"
9    
10 dnisson 1.4 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
11     #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
12 dnisson 1.2 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
13     #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
14     #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
15    
16 dnisson 1.11 /* Jet reco stuff */
17     #include "DataFormats/JetReco/interface/PFJetCollection.h"
18     #include "DataFormats/JetReco/interface/GenJetCollection.h"
19     #include "DataFormats/JetReco/interface/PFJet.h"
20     #include "DataFormats/JetReco/interface/GenJet.h"
21    
22 dnisson 1.1 #include <map>
23     #include <vector>
24     #include <limits>
25     #include <cmath>
26     #include <cstdlib>
27 dnisson 1.18 #include <iostream>
28 dnisson 1.1 #include <fstream>
29     #include <sstream>
30    
31     #include "TFormula.h"
32     #include "TF2.h"
33    
34     #define PI 3.141593
35    
36     using namespace std;
37     using namespace fastjet;
38    
39     class JetFinderAnalyzer : public JetFitAnalyzer {
40     public:
41     struct jet {
42     double energy;
43     double eta;
44     double phi;
45     };
46    
47     explicit JetFinderAnalyzer( const edm::ParameterSet&);
48     ~JetFinderAnalyzer() {}
49    
50     private:
51     static map<TH2 *, vector< vector<jet> > > unique_jets;
52    
53     static double phi_cutoff_;
54    
55 dnisson 1.15 virtual void beginJob(const edm::EventSetup &es);
56     virtual TH2D * make_histo(const edm::Event &, const edm::EventSetup &);
57 dnisson 1.1 virtual jetfit::model_def& make_model_def(const edm::Event&,
58     const edm::EventSetup&,
59     TH2 *);
60     virtual void analyze_results(jetfit::results r,
61     std::vector<jetfit::trouble> t, TH2 *);
62 dnisson 1.4 vector<reco::Candidate *> get_particles(const edm::Event&);
63 dnisson 1.1
64     fstream ofs;
65 dnisson 1.2 edm::InputTag inputTagPFCandidates_;
66 dnisson 1.4 edm::InputTag inputTagGenParticles_;
67 dnisson 1.2 int info_type_;
68 dnisson 1.1 double smear_;
69     int smear_coord_;
70 dnisson 1.11 string jet_algo_;
71 dnisson 1.15 string reclustered_jet_algo_;
72 dnisson 1.1 };
73    
74     map<TH2 *, vector< vector< JetFinderAnalyzer::jet > > >
75     JetFinderAnalyzer::unique_jets;
76    
77     JetFinderAnalyzer::JetFinderAnalyzer(const edm::ParameterSet &pSet)
78     : JetFitAnalyzer(pSet) // this is important!
79     {
80 dnisson 1.2 info_type_ = pSet.getUntrackedParameter("info_type", 0);
81    
82 dnisson 1.4 if (info_type_ == 0) {
83     inputTagGenParticles_ = pSet.getParameter<edm::InputTag>("GenParticles");
84     }
85 dnisson 1.2 if (info_type_ == 1) {
86     inputTagPFCandidates_ = pSet.getParameter<edm::InputTag>("PFCandidates");
87     }
88    
89 dnisson 1.1 smear_ = pSet.getUntrackedParameter("smear", 0.02);
90     smear_coord_ = pSet.getUntrackedParameter("smear_coord", 0);
91     // 0 = eta-phi smear
92     // 1 = proper angle smear
93 dnisson 1.11 jet_algo_ = pSet.getParameter<string>("jet_algo");
94 dnisson 1.15 set_user_minuit(0); // we don't need this feature--it's deprecated
95 dnisson 1.1 }
96    
97     TH2D * JetFinderAnalyzer::make_histo(const edm::Event &evt, const edm::EventSetup&) {
98 dnisson 1.16 const reco::Jet * highest_e_jet = 0;
99 dnisson 1.1
100 dnisson 1.13 if (info_type_ == 0) {
101     edm::Handle< vector<reco::GenJet> > evtJets;
102     evt.getByLabel(jet_algo_, evtJets);
103     for (unsigned i = 0; i < evtJets->size(); i++) {
104 dnisson 1.16 if (highest_e_jet == 0
105     || (*evtJets)[i].energy() > highest_e_jet->energy()) {
106 dnisson 1.13 highest_e_jet = &((*evtJets)[i]);
107     }
108     }
109 dnisson 1.1 }
110 dnisson 1.13 else if (info_type_ == 1) {
111     edm::Handle< vector<reco::PFJet> > evtJets;
112     evt.getByLabel(jet_algo_, evtJets);
113     for (unsigned i = 0; i < evtJets->size(); i++) {
114 dnisson 1.16 if (highest_e_jet == 0
115     || (*evtJets)[i].energy() > highest_e_jet->energy()) {
116 dnisson 1.13 highest_e_jet = &((*evtJets)[i]);
117 dnisson 1.1 }
118     }
119     }
120 dnisson 1.13
121     if (highest_e_jet == 0) {
122 dnisson 1.17 cerr << "No fat jets found!" << endl;
123     return 0;
124 dnisson 1.13 }
125    
126     vector<const reco::Candidate *> particles =
127     highest_e_jet->getJetConstituentsQuick();
128 dnisson 1.17
129 dnisson 1.13 ostringstream oss;
130     oss << "eta_phi_energy"<<evt.id().event() << flush;
131 dnisson 1.15 edm::Service<TFileService> fs;
132     TH2D *histo = fs->make<TH2D>(oss.str().c_str(), oss.str().c_str(),
133 dnisson 1.14 30,
134 dnisson 1.13 highest_e_jet->eta()-0.5,
135     highest_e_jet->eta()+0.5,
136 dnisson 1.14 30,
137 dnisson 1.13 highest_e_jet->phi()-0.5,
138     highest_e_jet->phi()+0.5);
139    
140 dnisson 1.17 if (smear_ > 0.0) {
141 dnisson 1.13 // create a smeared histo
142 dnisson 1.1 // create a temporary 2D vector for smeared energies
143 dnisson 1.13 double XbinSize = (histo->GetXaxis()->GetXmax()
144 dnisson 1.1 - histo->GetXaxis()->GetXmin()) /
145     static_cast<double>(histo->GetXaxis()->GetNbins());
146 dnisson 1.13 double YbinSize = (histo->GetYaxis()->GetXmax()
147 dnisson 1.1 - histo->GetYaxis()->GetXmin()) /
148     static_cast<double>(histo->GetYaxis()->GetNbins());
149 dnisson 1.13 double Xlo = histo->GetXaxis()->GetXmin();
150 dnisson 1.15 double Xhi = histo->GetXaxis()->GetXmax();
151 dnisson 1.13 double Ylo = histo->GetYaxis()->GetXmin();
152 dnisson 1.15 double Yhi = histo->GetYaxis()->GetXmax();
153 dnisson 1.14 vector< vector<double> > smeared(30, vector<double>(30, 0.0) );
154 dnisson 1.1 switch (smear_coord_) {
155     case 1:
156     for (int i = 0; i < particles.size(); i++) {
157 dnisson 1.4 double N = particles[i]->energy();
158 dnisson 1.2 double x = particles[i]->eta();
159     double y = particles[i]->phi();
160 dnisson 1.15 if (y < Ylo) {
161     y += 2.0*PI;
162     }
163     if (y > Yhi) {
164     y -= 2.0*PI;
165     }
166 dnisson 1.1 // loop over bins and add Gaussian in proper angle to smeared
167 dnisson 1.14 for (vector< vector<double> >::size_type i2 = 0; i2 < 30; i2++) {
168     for (vector< double >::size_type j2 = 0; j2 < 30; j2++) {
169 dnisson 1.1 double eta = static_cast<double>((signed int)i2) * XbinSize +
170 dnisson 1.15 Xlo - x;
171     double phi = static_cast<double>((signed int)j2) * YbinSize +
172     Ylo - y;
173    
174 dnisson 1.1 // transform eta, phi to proper angle
175     double theta = 2.0*atan(exp(-eta));
176     double iota = asin(sin(theta)*sin(phi));
177    
178     smeared[i2][j2] += (N*XbinSize*YbinSize/(2.0*PI*smear_*smear_))
179     * exp(-0.5*(theta*theta + iota*iota)/(smear_*smear_));
180     }
181     }
182     }
183     break;
184     case 0:
185     default:
186     for (int i = 0; i < particles.size(); i++) {
187 dnisson 1.4 double N = particles[i]->energy();
188 dnisson 1.2 double x = particles[i]->eta();
189     double y = particles[i]->phi();
190 dnisson 1.15 if (y < Ylo) {
191     y += 2.0*PI;
192     }
193     if (y > Yhi) {
194     y -= 2.0*PI;
195     }
196 dnisson 1.1 // loop over bins and add Gaussian to smeared
197 dnisson 1.14 for (vector< vector<double> >::size_type i2 = 0; i2 < 30; i2++) {
198     for (vector< double >::size_type j2 = 0; j2 < 30; j2++) {
199 dnisson 1.1 double eta = static_cast<double>((signed int)i2) * XbinSize
200 dnisson 1.15 + Xlo - x;
201     double phi = static_cast<double>((signed int)j2) * YbinSize +
202     Ylo - y;
203    
204 dnisson 1.1 smeared[i2][j2] += (N*XbinSize*YbinSize/(2.0*PI*smear_*smear_))
205     * exp(-0.5*(eta*eta + phi*phi)/(smear_*smear_));
206     }
207     }
208     }
209     }
210     // set histogram to match smear vector
211 dnisson 1.14 for (int i = 1; i <= 30; i++) {
212     for (int j = 1; j <= 30; j++) {
213 dnisson 1.1 histo->SetBinContent(i, j, smeared[i-1][j-1]);
214     }
215     }
216 dnisson 1.17 }
217     else {
218     // don't smear--just fill with particles
219     for (int i = 0; i < particles.size(); i++) {
220     histo->Fill(particles[i]->eta(), particles[i]->phi(),
221     particles[i]->energy());
222     }
223     }
224 dnisson 1.1
225     return histo;
226     }
227    
228 dnisson 1.12 template <class Jet>
229     void seed_with_jetcoll(vector<Jet> jets,
230 dnisson 1.15 jetfit::model_def &_mdef, double phi_lo = -PI,
231     double phi_hi = PI) {
232 dnisson 1.11 // seed with jet collection
233 dnisson 1.1 int ijset = 0;
234     for (unsigned ij = 0; ij < jets.size(); ij++) {
235 dnisson 1.11 double N = jets[ij].energy();
236     double eta = jets[ij].eta();
237     double phi = jets[ij].phi();
238     if (N > 10.0) {
239 dnisson 1.19 _mdef.set_special_par(ijset, 0, N, _mdef.chisquare_error(N)*0.1,
240 dnisson 1.1 0.0, 1.0e6);
241 dnisson 1.11 _mdef.set_special_par(ijset, 1, eta, 0.01,
242 dnisson 1.1 0.0, 0.0);
243 dnisson 1.17 if (phi < phi_lo) {
244     phi += 2.0*PI;
245 dnisson 1.15 }
246 dnisson 1.17 if (phi > phi_hi) {
247     phi -= 2.0*PI;
248 dnisson 1.15 }
249 dnisson 1.17 _mdef.set_special_par(ijset, 2, phi, 0.01,
250 dnisson 1.1 0.0, 0.0);
251     _mdef.set_special_par(ijset, 3, 0.1, 0.001, 0.0, 0.0);
252     ijset++;
253     }
254     }
255     }
256    
257     jetfit::model_def& JetFinderAnalyzer::make_model_def(const edm::Event& evt,
258     const edm::EventSetup&,
259     TH2 *histo) {
260     class jf_model_def : public jetfit::model_def {
261     public:
262     virtual double chisquare_error(double E) {
263 dnisson 1.19 return 0.298 - 0.9557*E; // study 11-09-09
264 dnisson 1.1 }
265     };
266    
267     jf_model_def *_mdef = new jf_model_def();
268     TFormula *formula = new TFormula("gaus2d",
269     "[0]*exp(-0.5*((x-[1])**2 + (y-[2])**2)/([3]**2))/(2*pi*[3]**2)");
270     _mdef->set_formula(formula);
271     _mdef->set_indiv_max_E(0);
272     _mdef->set_indiv_max_x(1);
273     _mdef->set_indiv_max_y(2);
274     _mdef->set_indiv_par(0, string("N"), 0.0, 0.0, 0.0, 1.0e6);
275     _mdef->set_indiv_par(1, string("mu_x"), 0.0, 0.0, 0.0, 0.0);
276     _mdef->set_indiv_par(2, string("mu_y"), 0.0, 0.0, 0.0, 0.0);
277     _mdef->set_indiv_par(3, string("sig"), 0.1, 0.001, 0.0, 0.0);
278    
279 dnisson 1.13 // get jetcoll from event file and select highest e jet
280 dnisson 1.12 if (info_type_ == 0) {
281     edm::Handle< vector<reco::GenJet> > jet_collection;
282     evt.getByLabel(jet_algo_, jet_collection);
283 dnisson 1.13 reco::GenJet highest_e_jet;
284     bool found_jet = false;
285     for (unsigned i = 0; i < jet_collection->size(); i++) {
286     if (!found_jet || (*jet_collection)[i].energy() > highest_e_jet.energy())
287     {
288     highest_e_jet = (*jet_collection)[i];
289 dnisson 1.17 found_jet = true;
290 dnisson 1.13 }
291     }
292     vector<reco::GenJet> highest_e_jet_coll;
293     highest_e_jet_coll.push_back(highest_e_jet);
294 dnisson 1.15 seed_with_jetcoll(highest_e_jet_coll, *_mdef,
295     histo->GetYaxis()->GetXmin(),
296     histo->GetYaxis()->GetXmax());
297 dnisson 1.12 }
298     if (info_type_ == 1) {
299     edm::Handle< vector<reco::PFJet> > jet_collection;
300     evt.getByLabel(jet_algo_, jet_collection);
301 dnisson 1.13 reco::PFJet highest_e_jet;
302     bool found_jet = false;
303     for (unsigned i = 0; i < jet_collection->size(); i++) {
304     if (!found_jet || (*jet_collection)[i].energy() > highest_e_jet.energy())
305     {
306     highest_e_jet = (*jet_collection)[i];
307 dnisson 1.17 found_jet = true;
308 dnisson 1.13 }
309     }
310     vector<reco::PFJet> highest_e_jet_coll;
311     highest_e_jet_coll.push_back(highest_e_jet);
312 dnisson 1.15 seed_with_jetcoll(highest_e_jet_coll, *_mdef,
313     histo->GetYaxis()->GetXmin(),
314     histo->GetYaxis()->GetXmax());
315 dnisson 1.12 }
316 dnisson 1.1
317     // generate initial fit histogram
318     edm::Service<TFileService> fs;
319     TH2D *init_fit_histo = fs->make<TH2D>(("init_fit_"+string(histo->GetName()))
320     .c_str(),
321     ("Initial fit for "
322     +string(histo->GetName())).c_str(),
323     histo->GetXaxis()->GetNbins(),
324     histo->GetXaxis()->GetXmin(),
325     histo->GetXaxis()->GetXmax(),
326     histo->GetXaxis()->GetNbins(),
327     histo->GetXaxis()->GetXmin(),
328     histo->GetXaxis()->GetXmax());
329     double XbinSize = (histo->GetXaxis()->GetXmax()
330     - histo->GetXaxis()->GetXmin()) /
331     static_cast<double>(histo->GetXaxis()->GetNbins());
332     double YbinSize = (histo->GetYaxis()->GetXmax()
333     - histo->GetYaxis()->GetXmin()) /
334     static_cast<double>(histo->GetYaxis()->GetNbins());
335     double Xlo = histo->GetXaxis()->GetXmin();
336     double Xhi = histo->GetXaxis()->GetXmax();
337     double Ylo = histo->GetYaxis()->GetXmin();
338     double Yhi = histo->GetYaxis()->GetXmax();
339    
340 dnisson 1.19 for (int i = 0; i < 30; i++) {
341     for (int j = 0; j < 30; j++) {
342 dnisson 1.1 double x = (static_cast<double>(i) + 0.5)*XbinSize + Xlo;
343     double y = (static_cast<double>(j) + 0.5)*YbinSize + Ylo;
344     double pval[256];
345     if (_mdef->get_n_special_par_sets() > 64) {
346     cerr << "Parameter overload" << endl;
347     return *_mdef;
348     }
349     else {
350     for (int is = 0; is < _mdef->get_n_special_par_sets(); is++) {
351     for (int ii = 0; ii < 4; ii++) {
352     double spval, sperr, splo, sphi;
353     _mdef->get_special_par(is, ii, spval, sperr, splo, sphi);
354     pval[4*is + ii] = spval;
355     }
356     }
357     }
358 dnisson 1.20 _mdef->set_ngauss(_mdef->get_n_special_par_sets());
359 dnisson 1.1 init_fit_histo->SetBinContent(i+1, j+1,
360 dnisson 1.20 _mdef->fit_fcn(x, y, pval)
361 dnisson 1.10 * XbinSize * YbinSize);
362 dnisson 1.1 }
363     }
364    
365     return *_mdef;
366     }
367    
368     void JetFinderAnalyzer::beginJob(const edm::EventSetup &es) {
369     ofs.open("jetfindlog.txt", ios::out);
370     if (ofs.fail()) {
371     cerr << "Opening jetfindlog.txt FAILED" << endl;
372     }
373     ofs << "Jetfinder log" << endl
374     << "=============" << endl << endl;
375     }
376    
377     ostream& operator<<(ostream &out, jetfit::trouble t) {
378     string action, error_string;
379    
380     if (t.istat != 3) {
381     switch(t.occ) {
382     case jetfit::T_NULL:
383     action = "Program"; break;
384     case jetfit::T_SIMPLEX:
385     action = "SIMPLEX"; break;
386     case jetfit::T_MIGRAD:
387     action = "MIGRAD"; break;
388     case jetfit::T_MINOS:
389     action = "MINOS"; break;
390     default:
391     action = "Program"; break;
392     }
393    
394     switch (t.istat) {
395     case 0:
396     error_string = "Unable to calculate error matrix"; break;
397     case 1:
398     error_string = "Error matrix a diagonal approximation"; break;
399     case 2:
400     error_string = "Error matrix not positive definite"; break;
401     case 3:
402     error_string = "Converged successfully"; break;
403     default:
404     ostringstream oss;
405     oss<<"Unknown status code "<<t.istat << flush;
406     error_string = oss.str(); break;
407     }
408    
409     if (t.occ != jetfit::T_NULL)
410     out << action<<" trouble: "<<error_string;
411     else
412     out << "Not calculated" << endl;
413     }
414 dnisson 1.9 else {
415     out << "Error matrix accurate" << endl;
416     }
417 dnisson 1.1
418     return out;
419     }
420    
421     void JetFinderAnalyzer::analyze_results(jetfit::results r,
422     std::vector<jetfit::trouble> t,
423     TH2 *hist_orig) {
424     ofs << "Histogram "<<hist_orig->GetName() << endl;
425 dnisson 1.9 for (int i = unique_jets[hist_orig].size() - r.chisquare.size();
426     i < unique_jets[hist_orig].size(); i++) {
427     int ir = i - unique_jets[hist_orig].size() + r.chisquare.size();
428 dnisson 1.1 ofs << "For "<<i+1<<" gaussians: " << endl
429 dnisson 1.9 << t.at(i) << endl;
430     ofs << "chisquare="<<r.chisquare.at(ir)
431     << endl;
432     ofs << unique_jets[hist_orig][i].size()<<" unique jets found" << endl;
433 dnisson 1.1 for (int j = 0; j < unique_jets[hist_orig][i].size(); j++) {
434     jet _jet = unique_jets[hist_orig][i][j];
435     ofs << "Jet "<<j<<": Energy = "<<_jet.energy<<", eta = "<<_jet.eta
436     << ", phi = "<<_jet.phi << endl;
437     }
438     ofs << endl;
439     }
440     ofs << endl;
441    
442     // save fit function histograms to root file
443     edm::Service<TFileService> fs;
444     for (vector< vector<double> >::size_type i = 0;
445     i < r.pval.size(); i++) {
446 dnisson 1.20 r.moddef->set_ngauss(r.pval[i].size() / 4);
447     jetfit::set_model_def(r.moddef);
448 dnisson 1.19 TF2 *tf2 = new TF2("fit_func", jetfit::fit_fcn_TF2,
449     hist_orig->GetXaxis()->GetXmin(),
450     hist_orig->GetXaxis()->GetXmax(),
451     hist_orig->GetYaxis()->GetXmin(),
452     hist_orig->GetYaxis()->GetXmax(),
453     r.pval[i].size());
454     for (vector<double>::size_type j = 0; j < r.pval[i].size(); j++) {
455     tf2->SetParameter(j, r.pval[i][j]);
456     }
457 dnisson 1.1 ostringstream fit_histo_oss;
458     fit_histo_oss << hist_orig->GetName()<<"_fit_"<<i << flush;
459 dnisson 1.19 tf2->SetNpx(hist_orig->GetXaxis()->GetNbins());
460     tf2->SetNpy(hist_orig->GetYaxis()->GetNbins());
461 dnisson 1.1 TH2D *fit_histo = fs->make<TH2D>(fit_histo_oss.str().c_str(),
462     fit_histo_oss.str().c_str(),
463     hist_orig->GetXaxis()->GetNbins(),
464     hist_orig->GetXaxis()->GetXmin(),
465     hist_orig->GetXaxis()->GetXmax(),
466     hist_orig->GetYaxis()->GetNbins(),
467     hist_orig->GetYaxis()->GetXmin(),
468     hist_orig->GetYaxis()->GetXmax());
469 dnisson 1.17 double XbinSize = (hist_orig->GetXaxis()->GetXmax()
470     - hist_orig->GetXaxis()->GetXmin())
471 dnisson 1.19 / hist_orig->GetXaxis()->GetNbins();
472 dnisson 1.17 double YbinSize = (hist_orig->GetYaxis()->GetXmax()
473     - hist_orig->GetYaxis()->GetXmin())
474 dnisson 1.19 / hist_orig->GetYaxis()->GetNbins();
475     for (int i = 1; i <= fit_histo->GetXaxis()->GetNbins(); i++) {
476     for (int j = 1; j <= fit_histo->GetYaxis()->GetNbins(); j++) {
477     double x = static_cast<double>(i - 1)
478     * (fit_histo->GetXaxis()->GetXmax()
479     - fit_histo->GetXaxis()->GetXmin())
480     / static_cast<double>(fit_histo->GetXaxis()->GetNbins())
481     + fit_histo->GetXaxis()->GetXmin();;
482     double y = static_cast<double>(j - 1)
483     * (fit_histo->GetYaxis()->GetXmax()
484     - fit_histo->GetYaxis()->GetXmin())
485     / static_cast<double>(fit_histo->GetYaxis()->GetNbins())
486     + fit_histo->GetYaxis()->GetXmin();
487     fit_histo->SetBinContent(i, j, tf2->Eval(x, y) * XbinSize * YbinSize);
488 dnisson 1.1 }
489     }
490     }
491    
492     // save results to file
493     ostringstream res_tree_oss, rt_title_oss;
494     res_tree_oss << hist_orig->GetName()<<"_results" << flush;
495     rt_title_oss << "Fit results for "<<hist_orig->GetName() << flush;
496     }
497    
498     DEFINE_FWK_MODULE(JetFinderAnalyzer);