CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
VirtualJetProducer.cc
Go to the documentation of this file.
1 //
3 // VirtualJetProducer
4 // ------------------
5 //
6 // 04/21/2009 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
8 
13 
21 
36 
37 //#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
38 
39 #include "fastjet/SISConePlugin.hh"
40 #include "fastjet/CMSIterativeConePlugin.hh"
41 #include "fastjet/ATLASConePlugin.hh"
42 #include "fastjet/CDFMidPointPlugin.hh"
43 
44 #include <iostream>
45 #include <memory>
46 #include <algorithm>
47 #include <limits>
48 #include <cmath>
49 
50 
51 using namespace std;
52 
53 
54 namespace reco {
55  namespace helper {
57  bool operator()( const fastjet::PseudoJet & t1, const fastjet::PseudoJet & t2 ) const {
58  return t1.perp() > t2.perp();
59  }
60  };
61 
62  }
63 }
64 
65 //______________________________________________________________________________
66 const char *VirtualJetProducer::JetType::names[] = {
67  "BasicJet","GenJet","CaloJet","PFJet","TrackJet","PFClusterJet"
68 };
69 
70 
71 //______________________________________________________________________________
74 {
75  const char **pos = std::find(names, names + LastJetType, name);
76  if (pos == names + LastJetType) {
77  std::string errorMessage="Requested jetType not supported: "+name+"\n";
78  throw cms::Exception("Configuration",errorMessage);
79  }
80  return (Type)(pos-names);
81 }
82 
83 
85 {
86 
87 
88  if ( writeCompound_ ) {
89  produces<reco::BasicJetCollection>();
90  }
91 
92  if (makeCaloJet(jetTypeE)) {
93  produces<reco::CaloJetCollection>(tag).setBranchAlias(alias);
94  }
95  else if (makePFJet(jetTypeE)) {
96  produces<reco::PFJetCollection>(tag).setBranchAlias(alias);
97  }
98  else if (makeGenJet(jetTypeE)) {
99  produces<reco::GenJetCollection>(tag).setBranchAlias(alias);
100  }
101  else if (makeTrackJet(jetTypeE)) {
102  produces<reco::TrackJetCollection>(tag).setBranchAlias(alias);
103  }
104  else if (makePFClusterJet(jetTypeE)) {
105  produces<reco::PFClusterJetCollection>(tag).setBranchAlias(alias);
106  }
107  else if (makeBasicJet(jetTypeE)) {
108  produces<reco::BasicJetCollection>(tag).setBranchAlias(alias);
109  }
110 }
111 
113 // construction / destruction
115 
116 //______________________________________________________________________________
118  : moduleLabel_ (iConfig.getParameter<string> ("@module_label"))
119  , src_ (iConfig.getParameter<edm::InputTag>("src"))
120  , srcPVs_ (iConfig.getParameter<edm::InputTag>("srcPVs"))
121  , jetType_ (iConfig.getParameter<string> ("jetType"))
122  , jetAlgorithm_ (iConfig.getParameter<string> ("jetAlgorithm"))
123  , rParam_ (iConfig.getParameter<double> ("rParam"))
124  , inputEtMin_ (iConfig.getParameter<double> ("inputEtMin"))
125  , inputEMin_ (iConfig.getParameter<double> ("inputEMin"))
126  , jetPtMin_ (iConfig.getParameter<double> ("jetPtMin"))
127  , doPVCorrection_(iConfig.getParameter<bool> ("doPVCorrection"))
128  , restrictInputs_(false)
129  , maxInputs_(99999999)
130  , doAreaFastjet_ (iConfig.getParameter<bool> ("doAreaFastjet"))
131  , useExplicitGhosts_(false)
132  , doAreaDiskApprox_ (false)
133  , doRhoFastjet_ (iConfig.getParameter<bool> ("doRhoFastjet"))
134  , voronoiRfact_ (-9)
135  , doPUOffsetCorr_(iConfig.getParameter<bool> ("doPUOffsetCorr"))
136  , puWidth_(0)
137  , nExclude_(0)
138  , jetCollInstanceName_ ("")
139  , writeCompound_ ( false )
140 {
141  anomalousTowerDef_ = std::auto_ptr<AnomalousTower>(new AnomalousTower(iConfig));
142 
143  //
144  // additional parameters to think about:
145  // - overlap threshold (set to 0.75 for the time being)
146  // - p parameter for generalized kT (set to -2 for the time being)
147  // - fastjet PU subtraction parameters (not yet considered)
148  //
149  if (jetAlgorithm_=="SISCone") {
150  fjPlugin_ = PluginPtr( new fastjet::SISConePlugin(rParam_,0.75,0,0.0,false,
151  fastjet::SISConePlugin::SM_pttilde) );
152  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(&*fjPlugin_) );
153  }
154  else if (jetAlgorithm_=="IterativeCone") {
155  fjPlugin_ = PluginPtr(new fastjet::CMSIterativeConePlugin(rParam_,1.0));
156  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
157  }
158  else if (jetAlgorithm_=="CDFMidPoint") {
159  fjPlugin_ = PluginPtr(new fastjet::CDFMidPointPlugin(rParam_,0.75));
160  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
161  }
162  else if (jetAlgorithm_=="ATLASCone") {
163  fjPlugin_ = PluginPtr(new fastjet::ATLASConePlugin(rParam_));
164  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
165  }
166  else if (jetAlgorithm_=="Kt")
167  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::kt_algorithm,rParam_));
168  else if (jetAlgorithm_=="CambridgeAachen")
169  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::cambridge_algorithm,
170  rParam_) );
171  else if (jetAlgorithm_=="AntiKt")
172  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm,rParam_) );
173  else if (jetAlgorithm_=="GeneralizedKt")
174  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::genkt_algorithm,
175  rParam_,-2) );
176  else
177  throw cms::Exception("Invalid jetAlgorithm")
178  <<"Jet algorithm for VirtualJetProducer is invalid, Abort!\n";
179 
181 
182  if ( iConfig.exists("jetCollInstanceName") ) {
183  jetCollInstanceName_ = iConfig.getParameter<string>("jetCollInstanceName");
184  }
185 
186  if ( doPUOffsetCorr_ ) {
188  throw cms::Exception("InvalidInput") << "Can only offset correct jets of type CaloJet or BasicJet";
189  }
190 
191  if(iConfig.exists("subtractorName")) puSubtractorName_ = iConfig.getParameter<string> ("subtractorName");
193 
194  if(puSubtractorName_.empty()){
195  edm::LogWarning("VirtualJetProducer") << "Pile Up correction on; however, pile up type is not specified. Using default... \n";
196  subtractor_ = boost::shared_ptr<PileUpSubtractor>(new PileUpSubtractor(iConfig));
197  }else{
198  subtractor_ = boost::shared_ptr<PileUpSubtractor>(PileUpSubtractorFactory::get()->create( puSubtractorName_, iConfig));
199  }
200  }
201 
202  // use explicit ghosts in the fastjet clustering sequence?
203  if ( iConfig.exists("useExplicitGhosts") ) {
204  useExplicitGhosts_ = iConfig.getParameter<bool>("useExplicitGhosts");
205  }
206 
207  // do approximate disk-based area calculation => warn if conflicting request
208  if (iConfig.exists("doAreaDiskApprox")) {
209  doAreaDiskApprox_ = iConfig.getParameter<bool>("doAreaDiskApprox");
211  throw cms::Exception("Conflicting area calculations") << "Both the calculation of jet area via fastjet and via an analytical disk approximation have been requested. Please decide on one.\n";
212 
213  }
214  // turn off jet collection output for speed
215  // Voronoi-based area calculation allows for an empirical scale factor
216  if (iConfig.exists("voronoiRfact"))
217  voronoiRfact_ = iConfig.getParameter<double>("voronoiRfact");
218 
219 
220  // do fasjet area / rho calcluation? => accept corresponding parameters
221  if ( doAreaFastjet_ || doRhoFastjet_ ) {
222  // Eta range of jets to be considered for Rho calculation
223  // Should be at most (jet acceptance - jet radius)
224  double rhoEtaMax=iConfig.getParameter<double>("Rho_EtaMax");
225  // default Ghost_EtaMax should be 5
226  double ghostEtaMax = iConfig.getParameter<double>("Ghost_EtaMax");
227  // default Active_Area_Repeats 1
228  int activeAreaRepeats = iConfig.getParameter<int> ("Active_Area_Repeats");
229  // default GhostArea 0.01
230  double ghostArea = iConfig.getParameter<double> ("GhostArea");
231  if (voronoiRfact_ <= 0) {
232  fjActiveArea_ = ActiveAreaSpecPtr(new fastjet::GhostedAreaSpec(ghostEtaMax,activeAreaRepeats,ghostArea));
233  fjActiveArea_->set_fj2_placement(true);
234  if ( ! useExplicitGhosts_ ) {
235  fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area, *fjActiveArea_ ) );
236  } else {
237  fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area_explicit_ghosts, *fjActiveArea_ ) );
238  }
239  }
240  fjRangeDef_ = RangeDefPtr( new fastjet::RangeDefinition(rhoEtaMax) );
241  }
242 
243  // restrict inputs to first "maxInputs" towers?
244  if ( iConfig.exists("restrictInputs") ) {
245  restrictInputs_ = iConfig.getParameter<bool>("restrictInputs");
246  maxInputs_ = iConfig.getParameter<unsigned int>("maxInputs");
247  }
248 
249 
250  string alias=iConfig.getUntrackedParameter<string>("alias",moduleLabel_);
251 
252 
253  // Check to see if we are writing compound jets for substructure
254  // and jet grooming
255  if ( iConfig.exists("writeCompound") ) {
256  writeCompound_ = iConfig.getParameter<bool>("writeCompound");
257  }
258 
259  // make the "produces" statements
261 
262  doFastJetNonUniform_ = false;
263  if(iConfig.exists("doFastJetNonUniform")) doFastJetNonUniform_ = iConfig.getParameter<bool> ("doFastJetNonUniform");
265  puCenters_ = iConfig.getParameter<std::vector<double> >("puCenters");
266  puWidth_ = iConfig.getParameter<double>("puWidth");
267  nExclude_ = iConfig.getParameter<unsigned int>("nExclude");
268  }
269 
270  useDeterministicSeed_ = false;
271  minSeed_ = 0;
272  if ( iConfig.exists("useDeterministicSeed") ) {
273  useDeterministicSeed_ = iConfig.getParameter<bool>("useDeterministicSeed");
274  minSeed_ = iConfig.getParameter<unsigned int>("minSeed");
275  }
276 
277 
278  produces<std::vector<double> >("rhos");
279  produces<std::vector<double> >("sigmas");
280  produces<double>("rho");
281  produces<double>("sigma");
282 
283 
284 }
285 
286 //______________________________________________________________________________
288 {
289 }
290 
291 
293 // implementation of member functions
295 
296 //______________________________________________________________________________
298 {
299 
300  // If requested, set the fastjet random seed to a deterministic function
301  // of the run/lumi/event.
302  // NOTE!!! The fastjet random number sequence is a global singleton.
303  // Thus, we have to create an object and get access to the global singleton
304  // in order to change it.
305  if ( useDeterministicSeed_ ) {
306  fastjet::GhostedAreaSpec gas;
307  std::vector<int> seeds(2);
308  seeds[0] = std::max(iEvent.id().run(),minSeed_ + 3) + 3 * iEvent.id().event();
309  seeds[1] = std::max(iEvent.id().run(),minSeed_ + 5) + 5 * iEvent.id().event();
310  gas.set_random_status(seeds);
311  }
312 
313  LogDebug("VirtualJetProducer") << "Entered produce\n";
314  //determine signal vertex2
315  vertex_=reco::Jet::Point(0,0,0);
317  LogDebug("VirtualJetProducer") << "Adding PV info\n";
319  iEvent.getByLabel(srcPVs_,pvCollection);
320  if (pvCollection->size()>0) vertex_=pvCollection->begin()->position();
321  }
322 
323  // For Pileup subtraction using offset correction:
324  // set up geometry map
325  if ( doPUOffsetCorr_ ) {
326  subtractor_->setupGeometryMap(iEvent, iSetup);
327  }
328 
329  // clear data
330  LogDebug("VirtualJetProducer") << "Clear data\n";
331  fjInputs_.clear();
332  fjJets_.clear();
333  inputs_.clear();
334 
335  // get inputs and convert them to the fastjet format (fastjet::PeudoJet)
338 
339  bool isView = iEvent.getByLabel(src_,inputsHandle);
340  if ( isView ) {
341  for (size_t i = 0; i < inputsHandle->size(); ++i) {
342  inputs_.push_back(inputsHandle->ptrAt(i));
343  }
344  } else {
345  iEvent.getByLabel(src_,pfinputsHandleAsFwdPtr);
346  for (size_t i = 0; i < pfinputsHandleAsFwdPtr->size(); ++i) {
347  if ( (*pfinputsHandleAsFwdPtr)[i].ptr().isAvailable() ) {
348  inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].ptr() );
349  }
350  else if ( (*pfinputsHandleAsFwdPtr)[i].backPtr().isAvailable() ) {
351  inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].backPtr() );
352  }
353  }
354  }
355  LogDebug("VirtualJetProducer") << "Got inputs\n";
356 
357  // Convert candidates to fastjet::PseudoJets.
358  // Also correct to Primary Vertex. Will modify fjInputs_
359  // and use inputs_
360  fjInputs_.reserve(inputs_.size());
361  inputTowers();
362  LogDebug("VirtualJetProducer") << "Inputted towers\n";
363 
364  // For Pileup subtraction using offset correction:
365  // Subtract pedestal.
366  if ( doPUOffsetCorr_ ) {
367  subtractor_->setDefinition(fjJetDefinition_);
369  subtractor_->calculatePedestal(fjInputs_);
370  subtractor_->subtractPedestal(fjInputs_);
371  LogDebug("VirtualJetProducer") << "Subtracted pedestal\n";
372  }
373  // Run algorithm. Will modify fjJets_ and allocate fjClusterSeq_.
374  // This will use fjInputs_
375  runAlgorithm( iEvent, iSetup );
376 
377  // if ( doPUOffsetCorr_ ) {
378  // subtractor_->setAlgorithm(fjClusterSeq_);
379  // }
380 
381  LogDebug("VirtualJetProducer") << "Ran algorithm\n";
382  // For Pileup subtraction using offset correction:
383  // Now we find jets and need to recalculate their energy,
384  // mark towers participated in jet,
385  // remove occupied towers from the list and recalculate mean and sigma
386  // put the initial towers collection to the jet,
387  // and subtract from initial towers in jet recalculated mean and sigma of towers
388  if ( doPUOffsetCorr_ ) {
389  LogDebug("VirtualJetProducer") << "Do PUOffsetCorr\n";
390  vector<fastjet::PseudoJet> orphanInput;
391  subtractor_->calculateOrphanInput(orphanInput);
392  subtractor_->calculatePedestal(orphanInput);
393  subtractor_->offsetCorrectJets();
394  }
395  // Write the output jets.
396  // This will (by default) call the member function template
397  // "writeJets", but can be overridden.
398  // this will use inputs_
399  output( iEvent, iSetup );
400  LogDebug("VirtualJetProducer") << "Wrote jets\n";
401 
402  return;
403 }
404 
405 //______________________________________________________________________________
406 
408 {
409  std::vector<edm::Ptr<reco::Candidate> >::const_iterator inBegin = inputs_.begin(),
410  inEnd = inputs_.end(), i = inBegin;
411  for (; i != inEnd; ++i ) {
413  if (edm::isNotFinite(input->pt())) continue;
414  if (input->et() <inputEtMin_) continue;
415  if (input->energy()<inputEMin_) continue;
416  if (isAnomalousTower(input)) continue;
417  if (input->pt() == 0) {
418  edm::LogError("NullTransverseMomentum") << "dropping input candidate with pt=0";
419  continue;
420  }
422  const CaloTower* tower=dynamic_cast<const CaloTower*>(input.get());
424  fjInputs_.push_back(fastjet::PseudoJet(ct.px(),ct.py(),ct.pz(),ct.energy()));
425  //std::cout << "tower:" << *tower << '\n';
426  }
427  else {
428  /*
429  if(makePFJet(jetTypeE)) {
430  reco::PFCandidate* pfc = (reco::PFCandidate*)input.get();
431  std::cout << "PF cand:" << *pfc << '\n';
432  }
433  */
434  fjInputs_.push_back(fastjet::PseudoJet(input->px(),input->py(),input->pz(),
435  input->energy()));
436  }
437  fjInputs_.back().set_user_index(i - inBegin);
438  }
439 
440  if ( restrictInputs_ && fjInputs_.size() > maxInputs_ ) {
442  std::sort(fjInputs_.begin(), fjInputs_.end(), pTComparator);
443  fjInputs_.resize(maxInputs_);
444  edm::LogWarning("JetRecoTooManyEntries") << "Too many inputs in the event, limiting to first " << maxInputs_ << ". Output is suspect.";
445  }
446 }
447 
448 //______________________________________________________________________________
450 {
451  if (!makeCaloJet(jetTypeE))
452  return false;
453  else
454  return (*anomalousTowerDef_)(*input);
455 }
456 
457 //------------------------------------------------------------------------------
458 // This is pure virtual.
459 //______________________________________________________________________________
460 // void VirtualJetProducer::runAlgorithm( edm::Event & iEvent, edm::EventSetup const& iSetup,
461 // std::vector<edm::Ptr<reco::Candidate> > const & inputs_);
462 
463 //______________________________________________________________________________
464 void VirtualJetProducer::copyConstituents(const vector<fastjet::PseudoJet>& fjConstituents,
465  reco::Jet* jet)
466 {
467  for (unsigned int i=0;i<fjConstituents.size();++i) {
468  int index = fjConstituents[i].user_index();
469  if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() )
470  jet->addDaughter(inputs_[index]);
471  }
472 }
473 
474 
475 //______________________________________________________________________________
476 vector<reco::CandidatePtr>
477 VirtualJetProducer::getConstituents(const vector<fastjet::PseudoJet>&fjConstituents)
478 {
479  vector<reco::CandidatePtr> result;
480  for (unsigned int i=0;i<fjConstituents.size();i++) {
481  int index = fjConstituents[i].user_index();
482  if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() ) {
483  reco::CandidatePtr candidate = inputs_[index];
484  result.push_back(candidate);
485  }
486  }
487  return result;
488 }
489 
490 
491 //_____________________________________________________________________________
492 
494 {
495  // Write jets and constitutents. Will use fjJets_, inputs_
496  // and fjClusterSeq_
497 
498  if ( !writeCompound_ ) {
499  switch( jetTypeE ) {
500  case JetType::CaloJet :
501  writeJets<reco::CaloJet>( iEvent, iSetup);
502  break;
503  case JetType::PFJet :
504  writeJets<reco::PFJet>( iEvent, iSetup);
505  break;
506  case JetType::GenJet :
507  writeJets<reco::GenJet>( iEvent, iSetup);
508  break;
509  case JetType::TrackJet :
510  writeJets<reco::TrackJet>( iEvent, iSetup);
511  break;
512  case JetType::PFClusterJet :
513  writeJets<reco::PFClusterJet>( iEvent, iSetup);
514  break;
515  case JetType::BasicJet :
516  writeJets<reco::BasicJet>( iEvent, iSetup);
517  break;
518  default:
519  throw cms::Exception("InvalidInput") << "invalid jet type in VirtualJetProducer\n";
520  break;
521  };
522  } else {
523  // Write jets and constitutents.
524  switch( jetTypeE ) {
525  case JetType::CaloJet :
526  writeCompoundJets<reco::CaloJet>( iEvent, iSetup );
527  break;
528  case JetType::PFJet :
529  writeCompoundJets<reco::PFJet>( iEvent, iSetup );
530  break;
531  case JetType::GenJet :
532  writeCompoundJets<reco::GenJet>( iEvent, iSetup );
533  break;
534  case JetType::BasicJet :
535  writeCompoundJets<reco::BasicJet>( iEvent, iSetup );
536  break;
537  default:
538  throw cms::Exception("InvalidInput") << "invalid jet type in CompoundJetProducer\n";
539  break;
540  };
541  }
542 
543 }
544 
545 template< typename T >
547 {
548  if (doRhoFastjet_) {
549  // declare jet collection without the two jets,
550  // for unbiased background estimation.
551  std::vector<fastjet::PseudoJet> fjexcluded_jets;
552  fjexcluded_jets=fjJets_;
553 
554  if(fjexcluded_jets.size()>2) fjexcluded_jets.resize(nExclude_);
555 
557  std::auto_ptr<std::vector<double> > rhos(new std::vector<double>);
558  std::auto_ptr<std::vector<double> > sigmas(new std::vector<double>);
559  int nEta = puCenters_.size();
560  rhos->reserve(nEta);
561  sigmas->reserve(nEta);
562  fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
563  dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
564 
565 
566  for(int ie = 0; ie < nEta; ++ie){
567  double eta = puCenters_[ie];
568  double etamin=eta-puWidth_;
569  double etamax=eta+puWidth_;
570  fastjet::RangeDefinition range_rho(etamin,etamax);
571  fastjet::BackgroundEstimator bkgestim(*clusterSequenceWithArea,range_rho);
572  bkgestim.set_excluded_jets(fjexcluded_jets);
573  rhos->push_back(bkgestim.rho());
574  sigmas->push_back(bkgestim.sigma());
575  }
576  iEvent.put(rhos,"rhos");
577  iEvent.put(sigmas,"sigmas");
578  }else{
579  std::auto_ptr<double> rho(new double(0.0));
580  std::auto_ptr<double> sigma(new double(0.0));
581  double mean_area = 0;
582 
583  fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
584  dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
585  /*
586  const double nemptyjets = clusterSequenceWithArea->n_empty_jets(*fjRangeDef_);
587  if(( nemptyjets < -15 ) || ( nemptyjets > fjRangeDef_->area()+ 15)) {
588  edm::LogWarning("StrangeNEmtpyJets") << "n_empty_jets is : " << clusterSequenceWithArea->n_empty_jets(*fjRangeDef_) << " with range " << fjRangeDef_->description() << ".";
589  }
590  */
591  clusterSequenceWithArea->get_median_rho_and_sigma(*fjRangeDef_,false,*rho,*sigma,mean_area);
592  if((*rho < 0)|| (edm::isNotFinite(*rho))) {
593  edm::LogError("BadRho") << "rho value is " << *rho << " area:" << mean_area << " and n_empty_jets: " << clusterSequenceWithArea->n_empty_jets(*fjRangeDef_) << " with range " << fjRangeDef_->description()
594  <<". Setting rho to rezo.";
595  *rho = 0;
596  }
597  iEvent.put(rho,"rho");
598  iEvent.put(sigma,"sigma");
599  }
600  } // doRhoFastjet_
601 
602  // produce output jet collection
603 
604  using namespace reco;
605 
606  std::auto_ptr<std::vector<T> > jets(new std::vector<T>() );
607  jets->reserve(fjJets_.size());
608 
609  // Distance between jet centers -- for disk-based area calculation
610  std::vector<std::vector<double> > rij(fjJets_.size());
611 
612  for (unsigned int ijet=0;ijet<fjJets_.size();++ijet) {
613  // allocate this jet
614  T jet;
615  // get the fastjet jet
616  const fastjet::PseudoJet& fjJet = fjJets_[ijet];
617  // get the constituents from fastjet
618  std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
619  // convert them to CandidatePtr vector
620  std::vector<CandidatePtr> constituents =
621  getConstituents(fjConstituents);
622 
623 
624  // calcuate the jet area
625  double jetArea=0.0;
626  if ( doAreaFastjet_ && fjJet.has_area() ) {
627  jetArea = fjJet.area();
628  }
629  else if ( doAreaDiskApprox_ ) {
630  // Here it is assumed that fjJets_ is in decreasing order of pT,
631  // which should happen in FastjetJetProducer::runAlgorithm()
632  jetArea = M_PI;
633  if (ijet) {
634  std::vector<double>& distance = rij[ijet];
635  distance.resize(ijet);
636  for (unsigned jJet = 0; jJet < ijet; ++jJet) {
637  distance[jJet] = reco::deltaR(fjJets_[ijet],fjJets_[jJet]) / rParam_;
638  jetArea -= reco::helper::VirtualJetProducerHelper::intersection(distance[jJet]);
639  for (unsigned kJet = 0; kJet < jJet; ++kJet) {
640  jetArea += reco::helper::VirtualJetProducerHelper::intersection(distance[jJet], distance[kJet], rij[jJet][kJet]);
641  } // end loop over harder jets
642  } // end loop over harder jets
643  }
644  jetArea *= rParam_;
645  jetArea *= rParam_;
646  }
647  // write the specifics to the jet (simultaneously sets 4-vector, vertex).
648  // These are overridden functions that will call the appropriate
649  // specific allocator.
650  writeSpecific(jet,
651  Particle::LorentzVector(fjJet.px(),
652  fjJet.py(),
653  fjJet.pz(),
654  fjJet.E()),
655  vertex_,
656  constituents, iSetup);
657 
658  jet.setJetArea (jetArea);
659 
660  if(doPUOffsetCorr_){
661  jet.setPileup(subtractor_->getPileUpEnergy(ijet));
662  }else{
663  jet.setPileup (0.0);
664  }
665 
666  // add to the list
667  jets->push_back(jet);
668  }
669  // put the jets in the collection
670  iEvent.put(jets,jetCollInstanceName_);
671 
672 
673 }
674 
675 
676 
678 template< class T>
680 {
681 
682  // get a list of output jets
683  std::auto_ptr<reco::BasicJetCollection> jetCollection( new reco::BasicJetCollection() );
684  // get a list of output subjets
685  std::auto_ptr<std::vector<T> > subjetCollection( new std::vector<T>() );
686 
687  // This will store the handle for the subjets after we write them
688  edm::OrphanHandle< std::vector<T> > subjetHandleAfterPut;
689  // this is the mapping of subjet to hard jet
690  std::vector< std::vector<int> > indices;
691  // this is the list of hardjet 4-momenta
692  std::vector<math::XYZTLorentzVector> p4_hardJets;
693  // this is the hardjet areas
694  std::vector<double> area_hardJets;
695 
696 
697  // Loop over the hard jets
698  std::vector<fastjet::PseudoJet>::const_iterator it = fjJets_.begin(),
699  iEnd = fjJets_.end(),
700  iBegin = fjJets_.begin();
701  indices.resize( fjJets_.size() );
702  for ( ; it != iEnd; ++it ) {
703  fastjet::PseudoJet const & localJet = *it;
704  unsigned int jetIndex = it - iBegin;
705  // Get the 4-vector for the hard jet
706  p4_hardJets.push_back( math::XYZTLorentzVector(localJet.px(), localJet.py(), localJet.pz(), localJet.e() ));
707  double localJetArea = 0.0;
708  if ( doAreaFastjet_ && localJet.has_area() ) {
709  localJetArea = localJet.area();
710  }
711  area_hardJets.push_back( localJetArea );
712 
713  // create the subjet list
714  std::vector<fastjet::PseudoJet> constituents;
715  if ( it->has_pieces() ) {
716  constituents = it->pieces();
717  } else {
718  constituents=it->constituents();
719  }
720 
721 
722  std::vector<fastjet::PseudoJet>::const_iterator itSubJetBegin = constituents.begin(),
723  itSubJet = itSubJetBegin, itSubJetEnd = constituents.end();
724  for (; itSubJet != itSubJetEnd; ++itSubJet ){
725 
726  fastjet::PseudoJet const & subjet = *itSubJet;
727 
728  math::XYZTLorentzVector p4Subjet(subjet.px(), subjet.py(), subjet.pz(), subjet.e() );
730 
731  // This will hold ptr's to the subjets
732  std::vector<reco::CandidatePtr> subjetConstituents;
733 
734  // Get the transient subjet constituents from fastjet
735  std::vector<fastjet::PseudoJet> subjetFastjetConstituents = subjet.constituents();
736  std::vector<reco::CandidatePtr> constituents =
737  getConstituents(subjetFastjetConstituents );
738 
739  indices[jetIndex].push_back( subjetCollection->size() );
740 
741  // Add the concrete subjet type to the subjet list to write to event record
742  T jet;
743  reco::writeSpecific( jet, p4Subjet, point, constituents, iSetup);
744  double subjetArea = 0.0;
745  if ( doAreaFastjet_ && itSubJet->has_area() ){
746  subjetArea = itSubJet->area();
747  }
748  jet.setJetArea( subjetArea );
749  subjetCollection->push_back( jet );
750 
751  }
752  }
753  // put subjets into event record
754  subjetHandleAfterPut = iEvent.put( subjetCollection, jetCollInstanceName_ );
755 
756 
757  // Now create the hard jets with ptr's to the subjets as constituents
758  std::vector<math::XYZTLorentzVector>::const_iterator ip4 = p4_hardJets.begin(),
759  ip4Begin = p4_hardJets.begin(),
760  ip4End = p4_hardJets.end();
761 
762  for ( ; ip4 != ip4End; ++ip4 ) {
763  int p4_index = ip4 - ip4Begin;
764  std::vector<int> & ind = indices[p4_index];
765  std::vector<reco::CandidatePtr> i_hardJetConstituents;
766  // Add the subjets to the hard jet
767  for( std::vector<int>::const_iterator isub = ind.begin();
768  isub != ind.end(); ++isub ) {
769  reco::CandidatePtr candPtr( subjetHandleAfterPut, *isub, false );
770  i_hardJetConstituents.push_back( candPtr );
771  }
773  reco::BasicJet toput( *ip4, point, i_hardJetConstituents);
774  toput.setJetArea( area_hardJets[ip4 - ip4Begin] );
775  jetCollection->push_back( toput );
776  }
777 
778  // put hard jets into event record
779  iEvent.put( jetCollection);
780 
781 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:42
boost::shared_ptr< fastjet::AreaDefinition > AreaDefinitionPtr
void writeJets(edm::Event &iEvent, edm::EventSetup const &iSetup)
JetType::Type jetTypeE
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:44
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
reco::Particle::Point vertex_
static const HistoName names[]
math::PtEtaPhiMLorentzVector p4(double vtxZ) const
Definition: CaloTower.cc:105
virtual std::vector< reco::CandidatePtr > getConstituents(const std::vector< fastjet::PseudoJet > &fjConstituents)
std::vector< fastjet::PseudoJet > fjJets_
virtual void inputTowers()
Base class for all types of Jets.
Definition: Jet.h:21
boost::shared_ptr< fastjet::JetDefinition::Plugin > PluginPtr
Definition: DDAxes.h:10
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::string puSubtractorName_
std::vector< double > puCenters_
T eta() const
virtual void copyConstituents(const std::vector< fastjet::PseudoJet > &fjConstituents, reco::Jet *jet)
Jets made from CaloTowers.
Definition: BasicJet.h:21
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
virtual void runAlgorithm(edm::Event &iEvent, const edm::EventSetup &iSetup)=0
void writeCompoundJets(edm::Event &iEvent, edm::EventSetup const &iSetup)
function template to write out the outputs
bool operator()(const fastjet::PseudoJet &t1, const fastjet::PseudoJet &t2) const
boost::shared_ptr< fastjet::RangeDefinition > RangeDefPtr
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:26
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
virtual bool isAnomalousTower(reco::CandidatePtr input)
virtual void setJetArea(float fArea)
set jet area
Definition: Jet.h:104
static const char * names[]
std::vector< fastjet::PseudoJet > fjInputs_
int iEvent
Definition: GenABIO.cc:243
std::string jetCollInstanceName_
boost::shared_ptr< PileUpSubtractor > subtractor_
bool isNotFinite(T x)
Definition: isFinite.h:10
std::vector< edm::Ptr< reco::Candidate > > inputs_
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:143
const T & max(const T &a, const T &b)
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:18
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:94
ClusterSequencePtr fjClusterSeq_
virtual void makeProduces(std::string s, std::string tag="")
vector< PseudoJet > jets
tuple result
Definition: query.py:137
math::XYZPoint Point
point in the space
Definition: Particle.h:29
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
void set_excluded_jets(const std::vector< PseudoJet > &excluded_jets)
boost::shared_ptr< fastjet::JetDefinition > JetDefPtr
std::auto_ptr< AnomalousTower > anomalousTowerDef_
ActiveAreaSpecPtr fjActiveArea_
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:361
#define M_PI
Definition: BFit3D.cc:3
virtual void produce(edm::Event &iEvent, const edm::EventSetup &iSetup)
double rho()
synonym for median rho [[do we have this? Both?]]
double sigma()
get the sigma
edm::EventID id() const
Definition: EventBase.h:56
VirtualJetProducer(const edm::ParameterSet &iConfig)
boost::shared_ptr< fastjet::GhostedAreaSpec > ActiveAreaSpecPtr
void addDaughter(const CandidatePtr &)
add a daughter via a reference
AreaDefinitionPtr fjAreaDefinition_
virtual void output(edm::Event &iEvent, edm::EventSetup const &iSetup)
long double T
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:25
bool makeCaloJet(const JetType::Type &fTag)
static Type byName(const std::string &name)
T get(const Candidate &c)
Definition: component.h:56
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
math::XYZPoint Point
point in the space
Definition: LeafCandidate.h:30
void writeSpecific(reco::CaloJet &jet, reco::Particle::LorentzVector const &p4, reco::Particle::Point const &point, std::vector< reco::CandidatePtr > const &constituents, edm::EventSetup const &c)
Definition: JetSpecific.cc:41
std::vector< BasicJet > BasicJetCollection
collection of BasicJet objects