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 
12 
21 
36 
37 #include "fastjet/SISConePlugin.hh"
38 #include "fastjet/CMSIterativeConePlugin.hh"
39 #include "fastjet/ATLASConePlugin.hh"
40 #include "fastjet/CDFMidPointPlugin.hh"
41 
42 #include <iostream>
43 #include <memory>
44 #include <algorithm>
45 #include <limits>
46 #include <cmath>
47 #include <vdt/vdtMath.h>
48 
49 using namespace std;
50 
51 
52 namespace reco {
53  namespace helper {
55  bool operator()( const fastjet::PseudoJet & t1, const fastjet::PseudoJet & t2 ) const {
56  return t1.perp() > t2.perp();
57  }
58  };
59 
60  }
61 }
62 
63 //______________________________________________________________________________
64 const char *const VirtualJetProducer::JetType::names[] = {
65  "BasicJet","GenJet","CaloJet","PFJet","TrackJet","PFClusterJet"
66 };
67 
68 
69 //______________________________________________________________________________
72 {
73  const char *const *pos = std::find(names, names + LastJetType, name);
74  if (pos == names + LastJetType) {
75  std::string errorMessage="Requested jetType not supported: "+name+"\n";
76  throw cms::Exception("Configuration",errorMessage);
77  }
78  return (Type)(pos-names);
79 }
80 
81 
83 {
84 
85 
86  if ( writeCompound_ ) {
87  produces<reco::BasicJetCollection>();
88  }
89 
90  if (makeCaloJet(jetTypeE)) {
91  produces<reco::CaloJetCollection>(tag).setBranchAlias(alias);
92  }
93  else if (makePFJet(jetTypeE)) {
94  produces<reco::PFJetCollection>(tag).setBranchAlias(alias);
95  }
96  else if (makeGenJet(jetTypeE)) {
97  produces<reco::GenJetCollection>(tag).setBranchAlias(alias);
98  }
99  else if (makeTrackJet(jetTypeE)) {
100  produces<reco::TrackJetCollection>(tag).setBranchAlias(alias);
101  }
102  else if (makePFClusterJet(jetTypeE)) {
103  produces<reco::PFClusterJetCollection>(tag).setBranchAlias(alias);
104  }
105  else if (makeBasicJet(jetTypeE)) {
106  produces<reco::BasicJetCollection>(tag).setBranchAlias(alias);
107  }
108 }
109 
111 // construction / destruction
113 
114 //______________________________________________________________________________
116  : moduleLabel_ (iConfig.getParameter<string> ("@module_label"))
117  , src_ (iConfig.getParameter<edm::InputTag>("src"))
118  , srcPVs_ (iConfig.getParameter<edm::InputTag>("srcPVs"))
119  , jetType_ (iConfig.getParameter<string> ("jetType"))
120  , jetAlgorithm_ (iConfig.getParameter<string> ("jetAlgorithm"))
121  , rParam_ (iConfig.getParameter<double> ("rParam"))
122  , inputEtMin_ (iConfig.getParameter<double> ("inputEtMin"))
123  , inputEMin_ (iConfig.getParameter<double> ("inputEMin"))
124  , jetPtMin_ (iConfig.getParameter<double> ("jetPtMin"))
125  , doPVCorrection_(iConfig.getParameter<bool> ("doPVCorrection"))
126  , restrictInputs_(false)
127  , maxInputs_(99999999)
128  , doAreaFastjet_ (iConfig.getParameter<bool> ("doAreaFastjet"))
129  , useExplicitGhosts_(false)
130  , doAreaDiskApprox_ (false)
131  , doRhoFastjet_ (iConfig.getParameter<bool> ("doRhoFastjet"))
132  , voronoiRfact_ (-9)
133  , doPUOffsetCorr_(iConfig.getParameter<bool> ("doPUOffsetCorr"))
134  , puWidth_(0)
135  , nExclude_(0)
136  , jetCollInstanceName_ ("")
137  , writeCompound_ ( false )
138  , verbosity_(0)
139 {
140  anomalousTowerDef_ = std::auto_ptr<AnomalousTower>(new AnomalousTower(iConfig));
141 
142  //
143  // additional parameters to think about:
144  // - overlap threshold (set to 0.75 for the time being)
145  // - p parameter for generalized kT (set to -2 for the time being)
146  // - fastjet PU subtraction parameters (not yet considered)
147  //
148  if (jetAlgorithm_=="SISCone") {
149  fjPlugin_ = PluginPtr( new fastjet::SISConePlugin(rParam_,0.75,0,0.0,false,
150  fastjet::SISConePlugin::SM_pttilde) );
151  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(&*fjPlugin_) );
152  }
153  else if (jetAlgorithm_=="IterativeCone") {
154  fjPlugin_ = PluginPtr(new fastjet::CMSIterativeConePlugin(rParam_,1.0));
155  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
156  }
157  else if (jetAlgorithm_=="CDFMidPoint") {
158  fjPlugin_ = PluginPtr(new fastjet::CDFMidPointPlugin(rParam_,0.75));
159  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
160  }
161  else if (jetAlgorithm_=="ATLASCone") {
162  fjPlugin_ = PluginPtr(new fastjet::ATLASConePlugin(rParam_));
163  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
164  }
165  else if (jetAlgorithm_=="Kt")
166  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::kt_algorithm,rParam_));
167  else if (jetAlgorithm_=="CambridgeAachen")
168  fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::cambridge_algorithm,
169  rParam_) );
170  else if (jetAlgorithm_=="AntiKt")
171  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm,rParam_) );
172  else if (jetAlgorithm_=="GeneralizedKt")
173  fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::genkt_algorithm,
174  rParam_,-2) );
175  else
176  throw cms::Exception("Invalid jetAlgorithm")
177  <<"Jet algorithm for VirtualJetProducer is invalid, Abort!\n";
178 
180 
181  if ( iConfig.exists("jetCollInstanceName") ) {
182  jetCollInstanceName_ = iConfig.getParameter<string>("jetCollInstanceName");
183  }
184 
185  if ( doPUOffsetCorr_ ) {
186 
187  if(iConfig.exists("subtractorName")) puSubtractorName_ = iConfig.getParameter<string> ("subtractorName");
189 
190  if(puSubtractorName_.empty()){
191  edm::LogWarning("VirtualJetProducer") << "Pile Up correction on; however, pile up type is not specified. Using default... \n";
192  subtractor_ = boost::shared_ptr<PileUpSubtractor>(new PileUpSubtractor(iConfig, consumesCollector()));
193  }else{
194  subtractor_ = boost::shared_ptr<PileUpSubtractor>(PileUpSubtractorFactory::get()->create( puSubtractorName_, iConfig, consumesCollector()));
195  }
196  }
197 
198  // use explicit ghosts in the fastjet clustering sequence?
199  if ( iConfig.exists("useExplicitGhosts") ) {
200  useExplicitGhosts_ = iConfig.getParameter<bool>("useExplicitGhosts");
201  }
202 
203  // do approximate disk-based area calculation => warn if conflicting request
204  if (iConfig.exists("doAreaDiskApprox")) {
205  doAreaDiskApprox_ = iConfig.getParameter<bool>("doAreaDiskApprox");
207  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";
208 
209  }
210  // turn off jet collection output for speed
211  // Voronoi-based area calculation allows for an empirical scale factor
212  if (iConfig.exists("voronoiRfact"))
213  voronoiRfact_ = iConfig.getParameter<double>("voronoiRfact");
214 
215 
216  // do fasjet area / rho calcluation? => accept corresponding parameters
217  if ( doAreaFastjet_ || doRhoFastjet_ ) {
218  // Eta range of jets to be considered for Rho calculation
219  // Should be at most (jet acceptance - jet radius)
220  double rhoEtaMax=iConfig.getParameter<double>("Rho_EtaMax");
221  // default Ghost_EtaMax should be 5
222  double ghostEtaMax = iConfig.getParameter<double>("Ghost_EtaMax");
223  // default Active_Area_Repeats 1
224  int activeAreaRepeats = iConfig.getParameter<int> ("Active_Area_Repeats");
225  // default GhostArea 0.01
226  double ghostArea = iConfig.getParameter<double> ("GhostArea");
227  if (voronoiRfact_ <= 0) {
228  fjActiveArea_ = ActiveAreaSpecPtr(new fastjet::GhostedAreaSpec(ghostEtaMax,activeAreaRepeats,ghostArea));
229  fjActiveArea_->set_fj2_placement(true);
230  if ( ! useExplicitGhosts_ ) {
231  fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area, *fjActiveArea_ ) );
232  } else {
233  fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area_explicit_ghosts, *fjActiveArea_ ) );
234  }
235  }
236  fjRangeDef_ = RangeDefPtr( new fastjet::RangeDefinition(rhoEtaMax) );
237  }
238 
239  // restrict inputs to first "maxInputs" towers?
240  if ( iConfig.exists("restrictInputs") ) {
241  restrictInputs_ = iConfig.getParameter<bool>("restrictInputs");
242  maxInputs_ = iConfig.getParameter<unsigned int>("maxInputs");
243  }
244 
245 
246  string alias=iConfig.getUntrackedParameter<string>("alias",moduleLabel_);
247 
248 
249  // Check to see if we are writing compound jets for substructure
250  // and jet grooming
251  if ( iConfig.exists("writeCompound") ) {
252  writeCompound_ = iConfig.getParameter<bool>("writeCompound");
253  }
254 
255  // make the "produces" statements
257 
258  doFastJetNonUniform_ = false;
259  if(iConfig.exists("doFastJetNonUniform")) doFastJetNonUniform_ = iConfig.getParameter<bool> ("doFastJetNonUniform");
261  puCenters_ = iConfig.getParameter<std::vector<double> >("puCenters");
262  puWidth_ = iConfig.getParameter<double>("puWidth");
263  nExclude_ = iConfig.getParameter<unsigned int>("nExclude");
264  }
265 
266  useDeterministicSeed_ = false;
267  minSeed_ = 0;
268  if ( iConfig.exists("useDeterministicSeed") ) {
269  useDeterministicSeed_ = iConfig.getParameter<bool>("useDeterministicSeed");
270  minSeed_ = iConfig.getParameter<unsigned int>("minSeed");
271  }
272 
273  if ( iConfig.exists("verbosity" ) ) {
274  verbosity_ = iConfig.getParameter<int>("verbosity");
275  }
276 
277  produces<std::vector<double> >("rhos");
278  produces<std::vector<double> >("sigmas");
279  produces<double>("rho");
280  produces<double>("sigma");
281 
282  if (!srcPVs_.label().empty()) input_vertex_token_ = consumes<reco::VertexCollection>(srcPVs_);
283  input_candidateview_token_ = consumes<reco::CandidateView>(src_);
284  input_candidatefwdptr_token_ = consumes<std::vector<edm::FwdPtr<reco::PFCandidate> > >(src_);
285  input_packedcandidatefwdptr_token_ = consumes<std::vector<edm::FwdPtr<pat::PackedCandidate> > >(src_);
286 
287 }
288 
289 //______________________________________________________________________________
291 {
292 }
293 
294 
296 // implementation of member functions
298 
299 //______________________________________________________________________________
301 {
302 
303  // If requested, set the fastjet random seed to a deterministic function
304  // of the run/lumi/event.
305  // NOTE!!! The fastjet random number sequence is a global singleton.
306  // Thus, we have to create an object and get access to the global singleton
307  // in order to change it.
308  if ( useDeterministicSeed_ ) {
309  fastjet::GhostedAreaSpec gas;
310  std::vector<int> seeds(2);
311  unsigned int runNum_uint = static_cast <unsigned int> (iEvent.id().run());
312  unsigned int evNum_uint = static_cast <unsigned int> (iEvent.id().event());
313  seeds[0] = std::max(runNum_uint,minSeed_ + 3) + 3 * evNum_uint;
314  seeds[1] = std::max(runNum_uint,minSeed_ + 5) + 5 * evNum_uint;
315  gas.set_random_status(seeds);
316  }
317 
318  LogDebug("VirtualJetProducer") << "Entered produce\n";
319  //determine signal vertex2
320  vertex_=reco::Jet::Point(0,0,0);
322  LogDebug("VirtualJetProducer") << "Adding PV info\n";
324  iEvent.getByToken(input_vertex_token_ , pvCollection);
325  if (pvCollection->size()>0) vertex_=pvCollection->begin()->position();
326  }
327 
328  // For Pileup subtraction using offset correction:
329  // set up geometry map
330  if ( doPUOffsetCorr_ ) {
331  subtractor_->setupGeometryMap(iEvent, iSetup);
332  }
333 
334  // clear data
335  LogDebug("VirtualJetProducer") << "Clear data\n";
336  fjInputs_.clear();
337  fjJets_.clear();
338  inputs_.clear();
339 
340  // get inputs and convert them to the fastjet format (fastjet::PeudoJet)
342 
344  edm::Handle< std::vector<edm::FwdPtr<pat::PackedCandidate> > > packedinputsHandleAsFwdPtr;
345 
346  bool isView = iEvent.getByToken(input_candidateview_token_, inputsHandle);
347  if ( isView ) {
348  if ( inputsHandle->size() == 0) {
349  output( iEvent, iSetup );
350  return;
351  }
352  for (size_t i = 0; i < inputsHandle->size(); ++i) {
353  inputs_.push_back(inputsHandle->ptrAt(i));
354  }
355  } else {
356  bool isPF = iEvent.getByToken(input_candidatefwdptr_token_, pfinputsHandleAsFwdPtr);
357  if ( isPF ) {
358  if ( pfinputsHandleAsFwdPtr->size() == 0) {
359  output( iEvent, iSetup );
360  return;
361  }
362  for (size_t i = 0; i < pfinputsHandleAsFwdPtr->size(); ++i) {
363  if ( (*pfinputsHandleAsFwdPtr)[i].ptr().isAvailable() ) {
364  inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].ptr() );
365  }
366  else if ( (*pfinputsHandleAsFwdPtr)[i].backPtr().isAvailable() ) {
367  inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].backPtr() );
368  }
369  }
370  } else {
371  iEvent.getByToken(input_packedcandidatefwdptr_token_, packedinputsHandleAsFwdPtr);
372  if ( packedinputsHandleAsFwdPtr->size() == 0) {
373  output( iEvent, iSetup );
374  return;
375  }
376  for (size_t i = 0; i < packedinputsHandleAsFwdPtr->size(); ++i) {
377  if ( (*packedinputsHandleAsFwdPtr)[i].ptr().isAvailable() ) {
378  inputs_.push_back( (*packedinputsHandleAsFwdPtr)[i].ptr() );
379  }
380  else if ( (*packedinputsHandleAsFwdPtr)[i].backPtr().isAvailable() ) {
381  inputs_.push_back( (*packedinputsHandleAsFwdPtr)[i].backPtr() );
382  }
383  }
384  }
385  }
386  LogDebug("VirtualJetProducer") << "Got inputs\n";
387 
388  // Convert candidates to fastjet::PseudoJets.
389  // Also correct to Primary Vertex. Will modify fjInputs_
390  // and use inputs_
391  fjInputs_.reserve(inputs_.size());
392  inputTowers();
393  LogDebug("VirtualJetProducer") << "Inputted towers\n";
394 
395  // For Pileup subtraction using offset correction:
396  // Subtract pedestal.
397  if ( doPUOffsetCorr_ ) {
398  subtractor_->setDefinition(fjJetDefinition_);
400  subtractor_->calculatePedestal(fjInputs_);
401  subtractor_->subtractPedestal(fjInputs_);
402  LogDebug("VirtualJetProducer") << "Subtracted pedestal\n";
403  }
404  // Run algorithm. Will modify fjJets_ and allocate fjClusterSeq_.
405  // This will use fjInputs_
406  runAlgorithm( iEvent, iSetup );
407 
408  // if ( doPUOffsetCorr_ ) {
409  // subtractor_->setAlgorithm(fjClusterSeq_);
410  // }
411 
412  LogDebug("VirtualJetProducer") << "Ran algorithm\n";
413  // For Pileup subtraction using offset correction:
414  // Now we find jets and need to recalculate their energy,
415  // mark towers participated in jet,
416  // remove occupied towers from the list and recalculate mean and sigma
417  // put the initial towers collection to the jet,
418  // and subtract from initial towers in jet recalculated mean and sigma of towers
419  if ( doPUOffsetCorr_ ) {
420  LogDebug("VirtualJetProducer") << "Do PUOffsetCorr\n";
421  vector<fastjet::PseudoJet> orphanInput;
422  subtractor_->calculateOrphanInput(orphanInput);
423  subtractor_->calculatePedestal(orphanInput);
424  subtractor_->offsetCorrectJets();
425  }
426  // Write the output jets.
427  // This will (by default) call the member function template
428  // "writeJets", but can be overridden.
429  // this will use inputs_
430  output( iEvent, iSetup );
431  LogDebug("VirtualJetProducer") << "Wrote jets\n";
432 
433  // Clear the work vectors so that memory is free for other modules.
434  // Use the trick of swapping with an empty vector so that the memory
435  // is actually given back rather than silently kept.
436  decltype(fjInputs_)().swap(fjInputs_);
437  decltype(fjJets_)().swap(fjJets_);
438  decltype(inputs_)().swap(inputs_);
439 
440  return;
441 }
442 
443 //______________________________________________________________________________
444 
446 {
447  std::vector<edm::Ptr<reco::Candidate> >::const_iterator inBegin = inputs_.begin(),
448  inEnd = inputs_.end(), i = inBegin;
449  for (; i != inEnd; ++i ) {
451  // std::cout << "CaloTowerVI jets " << input->pt() << " " << input->et() << ' '<< input->energy() << ' ' << (isAnomalousTower(input) ? " bad" : " ok") << std::endl;
452  if (edm::isNotFinite(input->pt())) continue;
453  if (input->et() <inputEtMin_) continue;
454  if (input->energy()<inputEMin_) continue;
455  if (isAnomalousTower(input)) continue;
456  // Change by SRR : this is no longer an error nor warning, this can happen with PU mitigation algos.
457  // Also switch to something more numerically safe.
458  if (input->pt() < 100 * std::numeric_limits<double>::epsilon() ) {
459  continue;
460  }
462  const CaloTower* tower=dynamic_cast<const CaloTower*>(input.get());
464  fjInputs_.push_back(fastjet::PseudoJet(ct.px(),ct.py(),ct.pz(),ct.energy()));
465  //std::cout << "tower:" << *tower << '\n';
466  }
467  else {
468  /*
469  if(makePFJet(jetTypeE)) {
470  reco::PFCandidate* pfc = (reco::PFCandidate*)input.get();
471  std::cout << "PF cand:" << *pfc << '\n';
472  }
473  */
474  fjInputs_.push_back(fastjet::PseudoJet(input->px(),input->py(),input->pz(),
475  input->energy()));
476  }
477  fjInputs_.back().set_user_index(i - inBegin);
478  }
479 
480  if ( restrictInputs_ && fjInputs_.size() > maxInputs_ ) {
482  std::sort(fjInputs_.begin(), fjInputs_.end(), pTComparator);
483  fjInputs_.resize(maxInputs_);
484  edm::LogWarning("JetRecoTooManyEntries") << "Too many inputs in the event, limiting to first " << maxInputs_ << ". Output is suspect.";
485  }
486 }
487 
488 //______________________________________________________________________________
490 {
491  if (!makeCaloJet(jetTypeE))
492  return false;
493  else
494  return (*anomalousTowerDef_)(*input);
495 }
496 
497 //------------------------------------------------------------------------------
498 // This is pure virtual.
499 //______________________________________________________________________________
500 // void VirtualJetProducer::runAlgorithm( edm::Event & iEvent, edm::EventSetup const& iSetup,
501 // std::vector<edm::Ptr<reco::Candidate> > const & inputs_);
502 
503 //______________________________________________________________________________
504 void VirtualJetProducer::copyConstituents(const vector<fastjet::PseudoJet>& fjConstituents,
505  reco::Jet* jet)
506 {
507  for (unsigned int i=0;i<fjConstituents.size();++i) {
508  int index = fjConstituents[i].user_index();
509  if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() )
510  jet->addDaughter(inputs_[index]);
511  }
512 }
513 
514 
515 //______________________________________________________________________________
516 vector<reco::CandidatePtr>
517 VirtualJetProducer::getConstituents(const vector<fastjet::PseudoJet>&fjConstituents)
518 {
519  vector<reco::CandidatePtr> result;
520  for (unsigned int i=0;i<fjConstituents.size();i++) {
521  int index = fjConstituents[i].user_index();
522  if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() ) {
523  reco::CandidatePtr candidate = inputs_[index];
524  result.push_back(candidate);
525  }
526  }
527  return result;
528 }
529 
530 
531 //_____________________________________________________________________________
532 
534 {
535  // Write jets and constitutents. Will use fjJets_, inputs_
536  // and fjClusterSeq_
537 
538  if ( !writeCompound_ ) {
539  switch( jetTypeE ) {
540  case JetType::CaloJet :
541  writeJets<reco::CaloJet>( iEvent, iSetup);
542  break;
543  case JetType::PFJet :
544  writeJets<reco::PFJet>( iEvent, iSetup);
545  break;
546  case JetType::GenJet :
547  writeJets<reco::GenJet>( iEvent, iSetup);
548  break;
549  case JetType::TrackJet :
550  writeJets<reco::TrackJet>( iEvent, iSetup);
551  break;
552  case JetType::PFClusterJet :
553  writeJets<reco::PFClusterJet>( iEvent, iSetup);
554  break;
555  case JetType::BasicJet :
556  writeJets<reco::BasicJet>( iEvent, iSetup);
557  break;
558  default:
559  throw cms::Exception("InvalidInput") << "invalid jet type in VirtualJetProducer\n";
560  break;
561  };
562  } else {
563  // Write jets and constitutents.
564  switch( jetTypeE ) {
565  case JetType::CaloJet :
566  writeCompoundJets<reco::CaloJet>( iEvent, iSetup );
567  break;
568  case JetType::PFJet :
569  writeCompoundJets<reco::PFJet>( iEvent, iSetup );
570  break;
571  case JetType::GenJet :
572  writeCompoundJets<reco::GenJet>( iEvent, iSetup );
573  break;
574  case JetType::BasicJet :
575  writeCompoundJets<reco::BasicJet>( iEvent, iSetup );
576  break;
577  default:
578  throw cms::Exception("InvalidInput") << "invalid jet type in CompoundJetProducer\n";
579  break;
580  };
581  }
582 }
583 
584 namespace {
585 template< typename T >
586 struct Area { static float get(T const &) {return 0;}};
587 
588 template<>
589 struct Area<reco::CaloJet>{ static float get(reco::CaloJet const & jet) {
590  return jet.getSpecific().mTowersArea;
591 }
592 };
593 }
594 
595 template< typename T >
597 {
598  // std::cout << "writeJets " << typeid(T).name()
599  // << (doRhoFastjet_ ? " doRhoFastjet " : "")
600  // << (doAreaFastjet_ ? " doAreaFastjet " : "")
601  // << (doAreaDiskApprox_ ? " doAreaDiskApprox " : "")
602  // << std::endl;
603 
604  if (doRhoFastjet_) {
605  // declare jet collection without the two jets,
606  // for unbiased background estimation.
607  std::vector<fastjet::PseudoJet> fjexcluded_jets;
608  fjexcluded_jets=fjJets_;
609 
610  if(fjexcluded_jets.size()>2) fjexcluded_jets.resize(nExclude_);
611 
613  std::auto_ptr<std::vector<double> > rhos(new std::vector<double>);
614  std::auto_ptr<std::vector<double> > sigmas(new std::vector<double>);
615  int nEta = puCenters_.size();
616  rhos->reserve(nEta);
617  sigmas->reserve(nEta);
618  fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
619  dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
620 
621  if (clusterSequenceWithArea ==nullptr ){
622  if (fjJets_.size() > 0) {
623  throw cms::Exception("LogicError")<<"fjClusterSeq is not initialized while inputs are present\n ";
624  }
625  } else {
626  for(int ie = 0; ie < nEta; ++ie){
627  double eta = puCenters_[ie];
628  double etamin=eta-puWidth_;
629  double etamax=eta+puWidth_;
630  fastjet::RangeDefinition range_rho(etamin,etamax);
631  fastjet::BackgroundEstimator bkgestim(*clusterSequenceWithArea,range_rho);
632  bkgestim.set_excluded_jets(fjexcluded_jets);
633  rhos->push_back(bkgestim.rho());
634  sigmas->push_back(bkgestim.sigma());
635  }
636  }
637  iEvent.put(rhos,"rhos");
638  iEvent.put(sigmas,"sigmas");
639  }else{
640  std::auto_ptr<double> rho(new double(0.0));
641  std::auto_ptr<double> sigma(new double(0.0));
642  double mean_area = 0;
643 
644  fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
645  dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
646  /*
647  const double nemptyjets = clusterSequenceWithArea->n_empty_jets(*fjRangeDef_);
648  if(( nemptyjets < -15 ) || ( nemptyjets > fjRangeDef_->area()+ 15)) {
649  edm::LogWarning("StrangeNEmtpyJets") << "n_empty_jets is : " << clusterSequenceWithArea->n_empty_jets(*fjRangeDef_) << " with range " << fjRangeDef_->description() << ".";
650  }
651  */
652  if (clusterSequenceWithArea ==nullptr ){
653  if (fjJets_.size() > 0) {
654  throw cms::Exception("LogicError")<<"fjClusterSeq is not initialized while inputs are present\n ";
655  }
656  } else {
657  clusterSequenceWithArea->get_median_rho_and_sigma(*fjRangeDef_,false,*rho,*sigma,mean_area);
658  if((*rho < 0)|| (edm::isNotFinite(*rho))) {
659  edm::LogError("BadRho") << "rho value is " << *rho << " area:" << mean_area << " and n_empty_jets: " << clusterSequenceWithArea->n_empty_jets(*fjRangeDef_) << " with range " << fjRangeDef_->description()
660  <<". Setting rho to rezo.";
661  *rho = 0;
662  }
663  }
664  iEvent.put(rho,"rho");
665  iEvent.put(sigma,"sigma");
666  }
667  } // doRhoFastjet_
668 
669  // produce output jet collection
670 
671  using namespace reco;
672 
673  std::auto_ptr<std::vector<T> > jets(new std::vector<T>() );
674  jets->reserve(fjJets_.size());
675 
676  // Distance between jet centers and overlap area -- for disk-based area calculation
677  using RIJ = std::pair<double,double>;
678  std::vector<std::vector<RIJ> > rij(fjJets_.size());
679 
680  float etaJ[fjJets_.size()], phiJ[fjJets_.size()];
681  auto etaFromXYZ = [](float x, float y, float z)->float { float t(z/std::sqrt(x*x+y*y)); return vdt::fast_logf(t + std::sqrt(t*t+1.f));};
682  for (auto ijet=0U;ijet<fjJets_.size();++ijet) {
683  float x = fjJets_[ijet].px();
684  float y = fjJets_[ijet].py();
685  float z = fjJets_[ijet].pz();
686  phiJ[ijet] = vdt::fast_atan2(y,x);
687  etaJ[ijet] =etaFromXYZ(x,y,z);
688  }
689  for (unsigned int ijet=0;ijet<fjJets_.size();++ijet) {
690  // allocate this jet
691  T jet;
692  // get the fastjet jet
693  const fastjet::PseudoJet& fjJet = fjJets_[ijet];
694  // get the constituents from fastjet
695  std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
696  // convert them to CandidatePtr vector
697  std::vector<CandidatePtr> constituents =
698  getConstituents(fjConstituents);
699 
700  // calcuate the jet area
701  double jetArea=0.0;
702  if ( doAreaFastjet_ && fjJet.has_area() ) {
703  jetArea = fjJet.area();
704  }
705  else if ( doAreaDiskApprox_ ) {
706  // Here it is assumed that fjJets_ is in decreasing order of pT,
707  // which should happen in FastjetJetProducer::runAlgorithm()
708  jetArea = M_PI;
709  if (0!=ijet) {
710  std::vector<RIJ>& distance = rij[ijet];
711  distance.resize(ijet);
712  for (unsigned jJet = 0; jJet < ijet; ++jJet) {
713  distance[jJet].first = std::sqrt(reco::deltaR2(etaJ[ijet],phiJ[ijet], etaJ[jJet],phiJ[jJet])) / rParam_;
714  distance[jJet].second = reco::helper::VirtualJetProducerHelper::intersection(distance[jJet].first);
715  jetArea -=distance[jJet].second;
716  for (unsigned kJet = 0; kJet < jJet; ++kJet) {
717  jetArea += reco::helper::VirtualJetProducerHelper::intersection(distance[jJet].first, distance[kJet].first, rij[jJet][kJet].first,
718  distance[jJet].second, distance[kJet].second, rij[jJet][kJet].second);
719  } // end loop over harder jets
720  } // end loop over harder jets
721  }
722  jetArea *= rParam_;
723  jetArea *= rParam_;
724  }
725  // write the specifics to the jet (simultaneously sets 4-vector, vertex).
726  // These are overridden functions that will call the appropriate
727  // specific allocator.
728  writeSpecific(jet,
729  Particle::LorentzVector(fjJet.px(),
730  fjJet.py(),
731  fjJet.pz(),
732  fjJet.E()),
733  vertex_,
734  constituents, iSetup);
735 
736  jet.setJetArea (jetArea);
737 
738  if(doPUOffsetCorr_){
739  jet.setPileup(subtractor_->getPileUpEnergy(ijet));
740  }else{
741  jet.setPileup (0.0);
742  }
743 
744 
745  // std::cout << "area " << ijet << " " << jetArea << " " << Area<T>::get(jet) << std::endl;
746  // std::cout << "JetVI " << ijet << jet.pt() << " " << jet.et() << ' '<< jet.energy() << ' '<< jet.mass() << std::endl;
747 
748  // add to the list
749  jets->push_back(jet);
750  }
751  // put the jets in the collection
752  iEvent.put(jets,jetCollInstanceName_);
753 }
754 
756 template< class T>
758 {
759  if ( verbosity_ >= 1 ) {
760  std::cout << "<VirtualJetProducer::writeCompoundJets (moduleLabel = " << moduleLabel_ << ")>:" << std::endl;
761  }
762 
763  // get a list of output jets
764  std::auto_ptr<reco::BasicJetCollection> jetCollection( new reco::BasicJetCollection() );
765  // get a list of output subjets
766  std::auto_ptr<std::vector<T> > subjetCollection( new std::vector<T>() );
767 
768  // This will store the handle for the subjets after we write them
769  edm::OrphanHandle< std::vector<T> > subjetHandleAfterPut;
770  // this is the mapping of subjet to hard jet
771  std::vector< std::vector<int> > indices;
772  // this is the list of hardjet 4-momenta
773  std::vector<math::XYZTLorentzVector> p4_hardJets;
774  // this is the hardjet areas
775  std::vector<double> area_hardJets;
776 
777  // Loop over the hard jets
778  std::vector<fastjet::PseudoJet>::const_iterator it = fjJets_.begin(),
779  iEnd = fjJets_.end(),
780  iBegin = fjJets_.begin();
781  indices.resize( fjJets_.size() );
782  for ( ; it != iEnd; ++it ) {
783  fastjet::PseudoJet const & localJet = *it;
784  unsigned int jetIndex = it - iBegin;
785  // Get the 4-vector for the hard jet
786  p4_hardJets.push_back( math::XYZTLorentzVector(localJet.px(), localJet.py(), localJet.pz(), localJet.e() ));
787  double localJetArea = 0.0;
788  if ( doAreaFastjet_ && localJet.has_area() ) {
789  localJetArea = localJet.area();
790  }
791  area_hardJets.push_back( localJetArea );
792 
793  // create the subjet list
794  std::vector<fastjet::PseudoJet> constituents;
795  if ( it->has_pieces() ) {
796  constituents = it->pieces();
797  } else if ( it->has_constituents() ) {
798  constituents = it->constituents();
799  }
800 
801  std::vector<fastjet::PseudoJet>::const_iterator itSubJetBegin = constituents.begin(),
802  itSubJet = itSubJetBegin, itSubJetEnd = constituents.end();
803  for (; itSubJet != itSubJetEnd; ++itSubJet ){
804 
805  fastjet::PseudoJet const & subjet = *itSubJet;
806  if ( verbosity_ >= 1 ) {
807  std::cout << "subjet #" << (itSubJet - itSubJetBegin) << ": Pt = " << subjet.pt() << ", eta = " << subjet.eta() << ", phi = " << subjet.phi() << ", mass = " << subjet.m()
808  << " (#constituents = " << subjet.constituents().size() << ")" << std::endl;
809  std::vector<fastjet::PseudoJet> subjet_constituents = subjet.constituents();
810  int idx_constituent = 0;
811  for ( std::vector<fastjet::PseudoJet>::const_iterator constituent = subjet_constituents.begin();
812  constituent != subjet_constituents.end(); ++constituent ) {
813  if ( constituent->pt() < 1.e-3 ) continue; // CV: skip ghosts
814  std::cout << " constituent #" << idx_constituent << ": Pt = " << constituent->pt() << ", eta = " << constituent->eta() << ", phi = " << constituent->phi() << ","
815  << " mass = " << constituent->m() << std::endl;
816  ++idx_constituent;
817  }
818  }
819 
820  if ( verbosity_ >= 1 ) {
821  std::cout << "subjet #" << (itSubJet - itSubJetBegin) << ": Pt = " << subjet.pt() << ", eta = " << subjet.eta() << ", phi = " << subjet.phi() << ", mass = " << subjet.m()
822  << " (#constituents = " << subjet.constituents().size() << ")" << std::endl;
823  std::vector<fastjet::PseudoJet> subjet_constituents = subjet.constituents();
824  int idx_constituent = 0;
825  for ( std::vector<fastjet::PseudoJet>::const_iterator constituent = subjet_constituents.begin();
826  constituent != subjet_constituents.end(); ++constituent ) {
827  if ( constituent->pt() < 1.e-3 ) continue; // CV: skip ghosts
828  std::cout << " constituent #" << idx_constituent << ": Pt = " << constituent->pt() << ", eta = " << constituent->eta() << ", phi = " << constituent->phi() << ","
829  << " mass = " << constituent->m() << std::endl;
830  ++idx_constituent;
831  }
832  }
833 
834  math::XYZTLorentzVector p4Subjet(subjet.px(), subjet.py(), subjet.pz(), subjet.e() );
836 
837  // This will hold ptr's to the subjets
838  std::vector<reco::CandidatePtr> subjetConstituents;
839 
840  // Get the transient subjet constituents from fastjet
841  std::vector<fastjet::PseudoJet> subjetFastjetConstituents = subjet.constituents();
842  std::vector<reco::CandidatePtr> constituents =
843  getConstituents(subjetFastjetConstituents );
844 
845  indices[jetIndex].push_back( subjetCollection->size() );
846 
847  // Add the concrete subjet type to the subjet list to write to event record
848  T jet;
849  reco::writeSpecific( jet, p4Subjet, point, constituents, iSetup);
850  double subjetArea = 0.0;
851  if ( doAreaFastjet_ && itSubJet->has_area() ){
852  subjetArea = itSubJet->area();
853  }
854  jet.setJetArea( subjetArea );
855  subjetCollection->push_back( jet );
856  }
857  }
858 
859  // put subjets into event record
860  subjetHandleAfterPut = iEvent.put( subjetCollection, jetCollInstanceName_ );
861 
862  // Now create the hard jets with ptr's to the subjets as constituents
863  std::vector<math::XYZTLorentzVector>::const_iterator ip4 = p4_hardJets.begin(),
864  ip4Begin = p4_hardJets.begin(),
865  ip4End = p4_hardJets.end();
866 
867  for ( ; ip4 != ip4End; ++ip4 ) {
868  int p4_index = ip4 - ip4Begin;
869  std::vector<int> & ind = indices[p4_index];
870  std::vector<reco::CandidatePtr> i_hardJetConstituents;
871  // Add the subjets to the hard jet
872  for( std::vector<int>::const_iterator isub = ind.begin();
873  isub != ind.end(); ++isub ) {
874  reco::CandidatePtr candPtr( subjetHandleAfterPut, *isub, false );
875  i_hardJetConstituents.push_back( candPtr );
876  }
878  reco::BasicJet toput( *ip4, point, i_hardJetConstituents);
879  toput.setJetArea( area_hardJets[ip4 - ip4Begin] );
880  jetCollection->push_back( toput );
881  }
882 
883  // put hard jets into event record
884  iEvent.put( jetCollection);
885 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:39
boost::shared_ptr< fastjet::AreaDefinition > AreaDefinitionPtr
void writeJets(edm::Event &iEvent, edm::EventSetup const &iSetup)
JetType::Type jetTypeE
void swap(ora::Record &rh, ora::Record &lh)
Definition: Record.h:70
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
reco::Particle::Point vertex_
Jets made from CaloTowers.
Definition: CaloJet.h:29
static const HistoName names[]
math::PtEtaPhiMLorentzVector p4(double vtxZ) const
Definition: CaloTower.cc:129
edm::EDGetTokenT< reco::CandidateView > input_candidateview_token_
virtual std::vector< reco::CandidatePtr > getConstituents(const std::vector< fastjet::PseudoJet > &fjConstituents)
std::vector< fastjet::PseudoJet > fjJets_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
virtual void inputTowers()
edm::EDGetTokenT< std::vector< edm::FwdPtr< pat::PackedCandidate > > > input_packedcandidatefwdptr_token_
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:160
Base class for all types of Jets.
Definition: Jet.h:20
boost::shared_ptr< fastjet::JetDefinition::Plugin > PluginPtr
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::string puSubtractorName_
std::vector< double > puCenters_
virtual void copyConstituents(const std::vector< fastjet::PseudoJet > &fjConstituents, reco::Jet *jet)
Jets made from CaloTowers.
Definition: BasicJet.h:20
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
static std::string const input
Definition: EdmProvDump.cc:44
tuple result
Definition: mps_fire.py:95
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
U second(std::pair< T, U > const &p)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
bool makePFJet(const JetType::Type &fTag)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
virtual bool isAnomalousTower(reco::CandidatePtr input)
virtual void setJetArea(float fArea)
set jet area
Definition: Jet.h:103
std::vector< fastjet::PseudoJet > fjInputs_
int iEvent
Definition: GenABIO.cc:230
std::string jetCollInstanceName_
boost::shared_ptr< PileUpSubtractor > subtractor_
bool isNotFinite(T x)
Definition: isFinite.h:10
std::vector< edm::Ptr< reco::Candidate > > inputs_
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:16
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
ClusterSequencePtr fjClusterSeq_
virtual void makeProduces(std::string s, std::string tag="")
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
T sqrt(T t)
Definition: SSEVec.h:18
vector< PseudoJet > jets
math::XYZPoint Point
point in the space
Definition: Particle.h:25
void set_excluded_jets(const std::vector< PseudoJet > &excluded_jets)
double f[11][100]
boost::shared_ptr< fastjet::JetDefinition > JetDefPtr
std::auto_ptr< AnomalousTower > anomalousTowerDef_
ActiveAreaSpecPtr fjActiveArea_
#define M_PI
edm::EDGetTokenT< reco::VertexCollection > input_vertex_token_
double rho()
synonym for median rho [[do we have this? Both?]]
edm::EDGetTokenT< std::vector< edm::FwdPtr< reco::PFCandidate > > > input_candidatefwdptr_token_
static const char *const names[]
T1 deltaR2(T1 eta1, T2 phi1, T3 eta2, T4 phi2)
Definition: deltaR.h:36
double sigma()
get the sigma
std::string const & label() const
Definition: InputTag.h:36
edm::EventID id() const
Definition: EventBase.h:59
virtual void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
VirtualJetProducer(const edm::ParameterSet &iConfig)
boost::shared_ptr< fastjet::GhostedAreaSpec > ActiveAreaSpecPtr
void addDaughter(const CandidatePtr &)
add a daughter via a reference
tuple cout
Definition: gather_cfg.py:145
AreaDefinitionPtr fjAreaDefinition_
virtual void output(edm::Event &iEvent, edm::EventSetup const &iSetup)
volatile std::atomic< bool > shutdown_flag false
moduleLabel_(iConfig.getParameter< string >("@module_label"))
long double T
bool makeCaloJet(const JetType::Type &fTag)
static Type byName(const std::string &name)
float fast_logf(float x)
T get(const Candidate &c)
Definition: component.h:55
*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::PtEtaPhiELorentzVectorF LorentzVector
math::XYZPoint Point
point in the space
Definition: LeafCandidate.h:27
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