ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/CmsHi/JetAnalysis/src/MyVirtualJetProducer.cc
Revision: 1.2
Committed: Wed Jun 9 12:17:13 2010 UTC (14 years, 10 months ago) by yilmaz
Content type: text/plain
Branch: MAIN
Changes since 1.1: +59 -0 lines
Log Message:
update

File Contents

# User Rev Content
1 yilmaz 1.1 ////////////////////////////////////////////////////////////////////////////////
2     //
3     // MyVirtualJetProducer
4     // ------------------
5     //
6     // 04/21/2009 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
7     ////////////////////////////////////////////////////////////////////////////////
8    
9     #include "MyVirtualJetProducer.h"
10     #include "RecoJets/JetProducers/interface/JetSpecific.h"
11    
12     #include "FWCore/Framework/interface/Event.h"
13     #include "FWCore/Framework/interface/EventSetup.h"
14     #include "FWCore/Framework/interface/ESHandle.h"
15     #include "FWCore/Utilities/interface/CodedException.h"
16     #include "FWCore/MessageLogger/interface/MessageLogger.h"
17     #include "FWCore/Framework/interface/MakerMacros.h"
18    
19     #include "DataFormats/Common/interface/View.h"
20     #include "DataFormats/Common/interface/Handle.h"
21     #include "DataFormats/VertexReco/interface/Vertex.h"
22     #include "DataFormats/VertexReco/interface/VertexFwd.h"
23     #include "DataFormats/JetReco/interface/CaloJetCollection.h"
24     #include "DataFormats/JetReco/interface/GenJetCollection.h"
25     #include "DataFormats/JetReco/interface/PFJetCollection.h"
26     #include "DataFormats/JetReco/interface/BasicJetCollection.h"
27     #include "DataFormats/JetReco/interface/TrackJetCollection.h"
28     #include "DataFormats/Candidate/interface/CandidateFwd.h"
29     #include "DataFormats/Candidate/interface/LeafCandidate.h"
30 yilmaz 1.2 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
31     #include "Geometry/Records/interface/CaloGeometryRecord.h"
32    
33     #include "DataFormats/Math/interface/Vector3D.h"
34 yilmaz 1.1
35     #include "fastjet/SISConePlugin.hh"
36     #include "fastjet/CMSIterativeConePlugin.hh"
37     #include "fastjet/ATLASConePlugin.hh"
38     #include "fastjet/CDFMidPointPlugin.hh"
39    
40     #include <iostream>
41     #include <memory>
42     #include <algorithm>
43     #include <limits>
44     #include <cmath>
45    
46     using namespace std;
47    
48    
49     namespace reco {
50     namespace helper {
51     struct GreaterByPtPseudoJet {
52     bool operator()( const fastjet::PseudoJet & t1, const fastjet::PseudoJet & t2 ) const {
53     return t1.perp() > t2.perp();
54     }
55     };
56    
57     }
58     }
59    
60     //______________________________________________________________________________
61     const char *MyVirtualJetProducer::JetType::names[] = {
62     "BasicJet","GenJet","CaloJet","PFJet","TrackJet"
63     };
64    
65    
66     //______________________________________________________________________________
67     MyVirtualJetProducer::JetType::Type
68     MyVirtualJetProducer::JetType::byName(const string &name)
69     {
70     const char **pos = std::find(names, names + LastJetType, name);
71     if (pos == names + LastJetType) {
72     std::string errorMessage="Requested jetType not supported: "+name+"\n";
73     throw cms::Exception("Configuration",errorMessage);
74     }
75     return (Type)(pos-names);
76     }
77    
78    
79     void MyVirtualJetProducer::makeProduces( std::string alias, std::string tag )
80     {
81     if (makeCaloJet(jetTypeE)) {
82     produces<reco::CaloJetCollection>(tag).setBranchAlias(alias);
83     }
84     else if (makePFJet(jetTypeE)) {
85     produces<reco::PFJetCollection>(tag).setBranchAlias(alias);
86     }
87     else if (makeGenJet(jetTypeE)) {
88     produces<reco::GenJetCollection>(tag).setBranchAlias(alias);
89     }
90     else if (makeTrackJet(jetTypeE)) {
91     produces<reco::TrackJetCollection>(tag).setBranchAlias(alias);
92     }
93     else if (makeBasicJet(jetTypeE)) {
94     produces<reco::BasicJetCollection>(tag).setBranchAlias(alias);
95     }
96     }
97    
98     ////////////////////////////////////////////////////////////////////////////////
99     // construction / destruction
100     ////////////////////////////////////////////////////////////////////////////////
101    
102     //______________________________________________________________________________
103     MyVirtualJetProducer::MyVirtualJetProducer(const edm::ParameterSet& iConfig)
104     : moduleLabel_ (iConfig.getParameter<string> ("@module_label"))
105     , src_ (iConfig.getParameter<edm::InputTag>("src"))
106     , srcPVs_ (iConfig.getParameter<edm::InputTag>("srcPVs"))
107     , jetType_ (iConfig.getParameter<string> ("jetType"))
108     , jetAlgorithm_ (iConfig.getParameter<string> ("jetAlgorithm"))
109     , rParam_ (iConfig.getParameter<double> ("rParam"))
110     , inputEtMin_ (iConfig.getParameter<double> ("inputEtMin"))
111     , inputEMin_ (iConfig.getParameter<double> ("inputEMin"))
112     , jetPtMin_ (iConfig.getParameter<double> ("jetPtMin"))
113     , doPVCorrection_(iConfig.getParameter<bool> ("doPVCorrection"))
114     , restrictInputs_(false)
115     , maxInputs_(99999999)
116     , doAreaFastjet_ (iConfig.getParameter<bool> ("doAreaFastjet"))
117     , doRhoFastjet_ (iConfig.getParameter<bool> ("doRhoFastjet"))
118     , doPUOffsetCorr_(iConfig.getParameter<bool> ("doPUOffsetCorr"))
119     , maxBadEcalCells_ (iConfig.getParameter<unsigned>("maxBadEcalCells"))
120     , maxRecoveredEcalCells_ (iConfig.getParameter<unsigned>("maxRecoveredEcalCells"))
121     , maxProblematicEcalCells_(iConfig.getParameter<unsigned>("maxProblematicEcalCells"))
122     , maxBadHcalCells_ (iConfig.getParameter<unsigned>("maxBadHcalCells"))
123     , maxRecoveredHcalCells_ (iConfig.getParameter<unsigned>("maxRecoveredHcalCells"))
124     , maxProblematicHcalCells_(iConfig.getParameter<unsigned>("maxProblematicHcalCells"))
125     , jetCollInstanceName_ ("")
126     {
127    
128 yilmaz 1.2 // ntuple = new TNtuple("nt","debug","ieta:eta:iphi:phi");
129    
130 yilmaz 1.1 //
131     // additional parameters to think about:
132     // - overlap threshold (set to 0.75 for the time being)
133     // - p parameter for generalized kT (set to -2 for the time being)
134     // - fastjet PU subtraction parameters (not yet considered)
135     //
136     if (jetAlgorithm_=="SISCone") {
137     fjPlugin_ = PluginPtr( new fastjet::SISConePlugin(rParam_,0.75,0,0.0,false,
138     fastjet::SISConePlugin::SM_pttilde) );
139     fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(&*fjPlugin_) );
140     }
141     else if (jetAlgorithm_=="IterativeCone") {
142     fjPlugin_ = PluginPtr(new fastjet::CMSIterativeConePlugin(rParam_,1.0));
143     fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
144     }
145     else if (jetAlgorithm_=="CDFMidPoint") {
146     fjPlugin_ = PluginPtr(new fastjet::CDFMidPointPlugin(rParam_,0.75));
147     fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
148     }
149     else if (jetAlgorithm_=="ATLASCone") {
150     fjPlugin_ = PluginPtr(new fastjet::ATLASConePlugin(rParam_));
151     fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
152     }
153     else if (jetAlgorithm_=="Kt")
154     fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::kt_algorithm,rParam_));
155     else if (jetAlgorithm_=="CambridgeAachen")
156     fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::cambridge_algorithm,
157     rParam_) );
158     else if (jetAlgorithm_=="AntiKt")
159     fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm,rParam_) );
160     else if (jetAlgorithm_=="GeneralizedKt")
161     fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::genkt_algorithm,
162     rParam_,-2) );
163     else
164     throw cms::Exception("Invalid jetAlgorithm")
165     <<"Jet algorithm for MyVirtualJetProducer is invalid, Abort!\n";
166    
167     jetTypeE=JetType::byName(jetType_);
168    
169     if ( iConfig.exists("jetCollInstanceName") ) {
170     jetCollInstanceName_ = iConfig.getParameter<string>("jetCollInstanceName");
171     }
172    
173     if ( doPUOffsetCorr_ ) {
174     if ( jetTypeE != JetType::CaloJet ) {
175     throw cms::Exception("InvalidInput") << "Can only offset correct jets of type CaloJet";
176     }
177     subtractor_ = boost::shared_ptr<PileUpSubtractor>(new PileUpSubtractor(iConfig,inputs_,fjInputs_,fjJets_));
178     }
179    
180     // do fasjet area / rho calcluation? => accept corresponding parameters
181     if ( doAreaFastjet_ || doRhoFastjet_ ) {
182     // default Ghost_EtaMax should be 5
183     double ghostEtaMax = iConfig.getParameter<double>("Ghost_EtaMax");
184     // default Active_Area_Repeats 1
185     int activeAreaRepeats = iConfig.getParameter<int> ("Active_Area_Repeats");
186     // default GhostArea 0.01
187     double ghostArea = iConfig.getParameter<double> ("GhostArea");
188     fjActiveArea_ = ActiveAreaSpecPtr(new fastjet::ActiveAreaSpec(ghostEtaMax,
189     activeAreaRepeats,
190     ghostArea));
191     fjRangeDef_ = RangeDefPtr( new fastjet::RangeDefinition(ghostEtaMax) );
192     }
193    
194     // restrict inputs to first "maxInputs" towers?
195     if ( iConfig.exists("restrictInputs") ) {
196     restrictInputs_ = iConfig.getParameter<bool>("restrictInputs");
197     maxInputs_ = iConfig.getParameter<unsigned int>("maxInputs");
198     }
199    
200    
201     string alias=iConfig.getUntrackedParameter<string>("alias",moduleLabel_);
202    
203     // make the "produces" statements
204     makeProduces( alias, jetCollInstanceName_ );
205    
206     if(doRhoFastjet_){
207     produces<double>("rho");
208     produces<double>("sigma");
209     }
210     }
211    
212    
213     //______________________________________________________________________________
214     MyVirtualJetProducer::~MyVirtualJetProducer()
215     {
216     }
217    
218    
219     ////////////////////////////////////////////////////////////////////////////////
220     // implementation of member functions
221     ////////////////////////////////////////////////////////////////////////////////
222    
223     //______________________________________________________________________________
224     void MyVirtualJetProducer::produce(edm::Event& iEvent,const edm::EventSetup& iSetup)
225     {
226 yilmaz 1.2
227     if(!geo){
228     edm::ESHandle<CaloGeometry> pGeo;
229     iSetup.get<CaloGeometryRecord>().get(pGeo);
230     geo = pGeo.product();
231     }
232    
233 yilmaz 1.1 LogDebug("MyVirtualJetProducer") << "Entered produce\n";
234     //determine signal vertex
235     vertex_=reco::Jet::Point(0,0,0);
236     if (makeCaloJet(jetTypeE)&&doPVCorrection_) {
237     LogDebug("MyVirtualJetProducer") << "Adding PV info\n";
238     edm::Handle<reco::VertexCollection> pvCollection;
239     iEvent.getByLabel(srcPVs_,pvCollection);
240     if (pvCollection->size()>0) vertex_=pvCollection->begin()->position();
241     }
242    
243     // For Pileup subtraction using offset correction:
244     // set up geometry map
245     if ( doPUOffsetCorr_ ) {
246     subtractor_->setupGeometryMap(iEvent, iSetup);
247     }
248    
249     // clear data
250     LogDebug("MyVirtualJetProducer") << "Clear data\n";
251     fjInputs_.clear();
252     fjJets_.clear();
253     inputs_.clear();
254    
255     // get inputs and convert them to the fastjet format (fastjet::PeudoJet)
256     edm::Handle<reco::CandidateView> inputsHandle;
257     iEvent.getByLabel(src_,inputsHandle);
258     for (size_t i = 0; i < inputsHandle->size(); ++i) {
259     inputs_.push_back(inputsHandle->ptrAt(i));
260     }
261     LogDebug("MyVirtualJetProducer") << "Got inputs\n";
262    
263     // Convert candidates to fastjet::PseudoJets.
264     // Also correct to Primary Vertex. Will modify fjInputs_
265     // and use inputs_
266     fjInputs_.reserve(inputs_.size());
267     inputTowers();
268     LogDebug("MyVirtualJetProducer") << "Inputted towers\n";
269    
270     // For Pileup subtraction using offset correction:
271     // Subtract pedestal.
272     if ( doPUOffsetCorr_ ) {
273     subtractor_->calculatePedestal(fjInputs_);
274     subtractor_->subtractPedestal(fjInputs_);
275     LogDebug("MyVirtualJetProducer") << "Subtracted pedestal\n";
276     }
277    
278     // Run algorithm. Will modify fjJets_ and allocate fjClusterSeq_.
279     // This will use fjInputs_
280     runAlgorithm( iEvent, iSetup );
281     if ( doPUOffsetCorr_ ) {
282     subtractor_->setAlgorithm(fjClusterSeq_);
283     }
284    
285     LogDebug("MyVirtualJetProducer") << "Ran algorithm\n";
286    
287     // For Pileup subtraction using offset correction:
288     // Now we find jets and need to recalculate their energy,
289     // mark towers participated in jet,
290     // remove occupied towers from the list and recalculate mean and sigma
291     // put the initial towers collection to the jet,
292     // and subtract from initial towers in jet recalculated mean and sigma of towers
293     if ( doPUOffsetCorr_ ) {
294     vector<fastjet::PseudoJet> orphanInput;
295     subtractor_->calculateOrphanInput(orphanInput);
296     subtractor_->calculatePedestal(orphanInput);
297     subtractor_->offsetCorrectJets();
298     }
299    
300     // Write the output jets.
301     // This will (by default) call the member function template
302     // "writeJets", but can be overridden.
303     // this will use inputs_
304     output( iEvent, iSetup );
305     LogDebug("MyVirtualJetProducer") << "Wrote jets\n";
306    
307     return;
308     }
309    
310     //______________________________________________________________________________
311    
312     void MyVirtualJetProducer::inputTowers( )
313     {
314     std::vector<edm::Ptr<reco::Candidate> >::const_iterator inBegin = inputs_.begin(),
315     inEnd = inputs_.end(), i = inBegin;
316     for (; i != inEnd; ++i ) {
317     reco::CandidatePtr input = *i;
318     if (isnan(input->pt())) continue;
319     if (input->et() <inputEtMin_) continue;
320     if (input->energy()<inputEMin_) continue;
321     if (isAnomalousTower(input)) continue;
322 yilmaz 1.2
323     //Check consistency of kinematics
324    
325     const CaloTower* ctc = dynamic_cast<const CaloTower*>(input.get());
326     if(ctc){
327     int ieta = ctc->id().ieta();
328     int iphi = ctc->id().iphi();
329    
330     ntuple->Fill(ieta, input->eta(), iphi, input->phi(),input->et(),ctc->emEt(),ctc->hadEt());
331    
332     if(abs(ieta) < 5){
333    
334     if(0){
335     math::RhoEtaPhiVector v(1.4,input->eta(),input->phi());
336     GlobalPoint point(v.x(),v.y(),v.z());
337     // const DetId d = geo->getClosestCell(point);
338     // HcalDetId hd(d);
339     HcalDetId hd(0);
340     if(hd.ieta() != ieta || hd.iphi() != iphi){
341     cout<<"Inconsistent kinematics!!! ET = "<<input->pt()<<endl;
342     cout<<"ieta candidate : "<<ieta<<" ieta detid : "<<hd.ieta()<<endl;
343     cout<<"iphi candidate : "<<iphi<<" iphi detid : "<<hd.iphi()<<endl;
344     }
345    
346     }
347    
348     if(0){
349     HcalDetId det(HcalBarrel,ieta,iphi,1);
350    
351     if(geo->present(det)){
352     double eta = geo->getPosition(det).eta();
353     double phi = geo->getPosition(det).phi();
354    
355     if(input->eta() != eta || input->phi() != phi){
356     cout<<"Inconsistent kinematics!!! ET = "<<input->pt()<<endl;
357     cout<<"eta candidate : "<<input->eta()<<" eta detid : "<<eta<<endl;
358     cout<<"phi candidate : "<<input->phi()<<" phi detid : "<<phi<<endl;
359     }
360     }else{
361     cout<<"DetId not present in the Calo Geometry : ieta = "<<ieta<<" iphi = "<<iphi<<endl;
362     }
363     }
364     }
365    
366     }
367    
368 yilmaz 1.1 if (makeCaloJet(jetTypeE)&&doPVCorrection_) {
369     const CaloTower* tower=dynamic_cast<const CaloTower*>(input.get());
370     math::PtEtaPhiMLorentzVector ct(tower->p4(vertex_));
371     fjInputs_.push_back(fastjet::PseudoJet(ct.px(),ct.py(),ct.pz(),ct.energy()));
372     }
373     else {
374     fjInputs_.push_back(fastjet::PseudoJet(input->px(),input->py(),input->pz(),
375     input->energy()));
376     }
377     fjInputs_.back().set_user_index(i - inBegin);
378     }
379    
380     if ( restrictInputs_ && fjInputs_.size() > maxInputs_ ) {
381     reco::helper::GreaterByPtPseudoJet pTComparator;
382     std::sort(fjInputs_.begin(), fjInputs_.end(), pTComparator);
383     fjInputs_.resize(maxInputs_);
384     edm::LogWarning("JetRecoTooManyEntries") << "Too many inputs in the event, limiting to first " << maxInputs_ << ". Output is suspect.";
385     }
386     }
387    
388     //______________________________________________________________________________
389     bool MyVirtualJetProducer::isAnomalousTower(reco::CandidatePtr input)
390     {
391     if (!makeCaloJet(jetTypeE)) return false;
392     const CaloTower* tower=dynamic_cast<const CaloTower*>(input.get());
393     if (0==tower) return false;
394     if (tower->numBadEcalCells() >maxBadEcalCells_ ||
395     tower->numRecoveredEcalCells() >maxRecoveredEcalCells_ ||
396     tower->numProblematicEcalCells()>maxProblematicEcalCells_||
397     tower->numBadHcalCells() >maxBadHcalCells_ ||
398     tower->numRecoveredHcalCells() >maxRecoveredHcalCells_ ||
399     tower->numProblematicHcalCells()>maxProblematicHcalCells_) return true;
400     return false;
401     }
402    
403    
404     //------------------------------------------------------------------------------
405     // This is pure virtual.
406     //______________________________________________________________________________
407     // void MyVirtualJetProducer::runAlgorithm( edm::Event & iEvent, edm::EventSetup const& iSetup,
408     // std::vector<edm::Ptr<reco::Candidate> > const & inputs_);
409    
410     //______________________________________________________________________________
411     void MyVirtualJetProducer::copyConstituents(const vector<fastjet::PseudoJet>& fjConstituents,
412     reco::Jet* jet)
413     {
414     for (unsigned int i=0;i<fjConstituents.size();++i)
415     jet->addDaughter(inputs_[fjConstituents[i].user_index()]);
416     }
417    
418    
419     //______________________________________________________________________________
420     vector<reco::CandidatePtr>
421     MyVirtualJetProducer::getConstituents(const vector<fastjet::PseudoJet>&fjConstituents)
422     {
423     vector<reco::CandidatePtr> result;
424     for (unsigned int i=0;i<fjConstituents.size();i++) {
425     int index = fjConstituents[i].user_index();
426     reco::CandidatePtr candidate = inputs_[index];
427     result.push_back(candidate);
428     }
429     return result;
430     }
431    
432     void MyVirtualJetProducer::output(edm::Event & iEvent, edm::EventSetup const& iSetup)
433     {
434     // Write jets and constitutents. Will use fjJets_, inputs_
435     // and fjClusterSeq_
436     switch( jetTypeE ) {
437     case JetType::CaloJet :
438     writeJets<reco::CaloJet>( iEvent, iSetup);
439     break;
440     case JetType::PFJet :
441     writeJets<reco::PFJet>( iEvent, iSetup);
442     break;
443     case JetType::GenJet :
444     writeJets<reco::GenJet>( iEvent, iSetup);
445     break;
446     case JetType::TrackJet :
447     writeJets<reco::TrackJet>( iEvent, iSetup);
448     break;
449     case JetType::BasicJet :
450     writeJets<reco::BasicJet>( iEvent, iSetup);
451     break;
452     default:
453     throw cms::Exception("InvalidInput") << "invalid jet type in MyVirtualJetProducer\n";
454     break;
455     };
456    
457     }
458    
459     template< typename T >
460     void MyVirtualJetProducer::writeJets( edm::Event & iEvent, edm::EventSetup const& iSetup )
461     {
462     // produce output jet collection
463    
464     using namespace reco;
465    
466     std::auto_ptr<std::vector<T> > jets(new std::vector<T>() );
467     jets->reserve(fjJets_.size());
468    
469     for (unsigned int ijet=0;ijet<fjJets_.size();++ijet) {
470     // allocate this jet
471     T jet;
472     // get the fastjet jet
473     const fastjet::PseudoJet& fjJet = fjJets_[ijet];
474     // get the constituents from fastjet
475     std::vector<fastjet::PseudoJet> fjConstituents =
476     sorted_by_pt(fjClusterSeq_->constituents(fjJet));
477     // convert them to CandidatePtr vector
478     std::vector<CandidatePtr> constituents =
479     getConstituents(fjConstituents);
480    
481     // calcuate the jet area
482     double jetArea=0.0;
483     if ( doAreaFastjet_ ) {
484     fastjet::ClusterSequenceArea const * clusterSequenceWithArea =
485     dynamic_cast<fastjet::ClusterSequenceArea const *>(&*fjClusterSeq_);
486     jetArea = clusterSequenceWithArea->area(fjJet);
487     }
488    
489     // write the specifics to the jet (simultaneously sets 4-vector, vertex).
490     // These are overridden functions that will call the appropriate
491     // specific allocator.
492     writeSpecific(jet,
493     Particle::LorentzVector(fjJet.px(),
494     fjJet.py(),
495     fjJet.pz(),
496     fjJet.E()),
497     vertex_,
498     constituents, iSetup);
499    
500     jet.setJetArea (jetArea);
501    
502     if(doPUOffsetCorr_){
503     jet.setPileup(subtractor_->getPileUpEnergy(ijet));
504     }else{
505     jet.setPileup (0.0);
506     }
507    
508     // add to the list
509     jets->push_back(jet);
510     }
511    
512     // put the jets in the collection
513     iEvent.put(jets);
514    
515     // calculate rho (median pT per unit area, for PU&UE subtraction down the line
516     std::auto_ptr<double> rho(new double(0.0));
517     std::auto_ptr<double> sigma(new double(0.0));
518    
519     if (doRhoFastjet_) {
520     fastjet::ClusterSequenceArea const * clusterSequenceWithArea =
521     dynamic_cast<fastjet::ClusterSequenceArea const *> ( &*fjClusterSeq_ );
522     double mean_area = 0;
523     clusterSequenceWithArea->get_median_rho_and_sigma(*fjRangeDef_,false,*rho,*sigma,mean_area);
524     iEvent.put(rho,"rho");
525     iEvent.put(sigma,"sigma");
526     }
527     }
528