00001
00002
00003
00004
00005
00006
00008
00009 #include "RecoJets/JetProducers/plugins/VirtualJetProducer.h"
00010 #include "RecoJets/JetProducers/interface/JetSpecific.h"
00011 #include "RecoJets/JetProducers/interface/BackgroundEstimator.h"
00012 #include "RecoJets/JetProducers/interface/VirtualJetProducerHelper.h"
00013
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/Framework/interface/EventSetup.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 #include "FWCore/Framework/interface/MakerMacros.h"
00020 #include "FWCore/Utilities/interface/isFinite.h"
00021
00022 #include "DataFormats/Common/interface/View.h"
00023 #include "DataFormats/Common/interface/Handle.h"
00024 #include "DataFormats/VertexReco/interface/Vertex.h"
00025 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00026 #include "DataFormats/JetReco/interface/CaloJetCollection.h"
00027 #include "DataFormats/JetReco/interface/GenJetCollection.h"
00028 #include "DataFormats/JetReco/interface/PFJetCollection.h"
00029 #include "DataFormats/JetReco/interface/BasicJetCollection.h"
00030 #include "DataFormats/JetReco/interface/TrackJetCollection.h"
00031 #include "DataFormats/JetReco/interface/PFClusterJetCollection.h"
00032 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00033 #include "DataFormats/Candidate/interface/LeafCandidate.h"
00034 #include "DataFormats/Math/interface/deltaR.h"
00035 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00036
00037
00038
00039 #include "fastjet/SISConePlugin.hh"
00040 #include "fastjet/CMSIterativeConePlugin.hh"
00041 #include "fastjet/ATLASConePlugin.hh"
00042 #include "fastjet/CDFMidPointPlugin.hh"
00043
00044 #include <iostream>
00045 #include <memory>
00046 #include <algorithm>
00047 #include <limits>
00048 #include <cmath>
00049
00050
00051 using namespace std;
00052
00053
00054 namespace reco {
00055 namespace helper {
00056 struct GreaterByPtPseudoJet {
00057 bool operator()( const fastjet::PseudoJet & t1, const fastjet::PseudoJet & t2 ) const {
00058 return t1.perp() > t2.perp();
00059 }
00060 };
00061
00062 }
00063 }
00064
00065
00066 const char *VirtualJetProducer::JetType::names[] = {
00067 "BasicJet","GenJet","CaloJet","PFJet","TrackJet","PFClusterJet"
00068 };
00069
00070
00071
00072 VirtualJetProducer::JetType::Type
00073 VirtualJetProducer::JetType::byName(const string &name)
00074 {
00075 const char **pos = std::find(names, names + LastJetType, name);
00076 if (pos == names + LastJetType) {
00077 std::string errorMessage="Requested jetType not supported: "+name+"\n";
00078 throw cms::Exception("Configuration",errorMessage);
00079 }
00080 return (Type)(pos-names);
00081 }
00082
00083
00084 void VirtualJetProducer::makeProduces( std::string alias, std::string tag )
00085 {
00086
00087
00088 if ( writeCompound_ ) {
00089 produces<reco::BasicJetCollection>();
00090 }
00091
00092 if (makeCaloJet(jetTypeE)) {
00093 produces<reco::CaloJetCollection>(tag).setBranchAlias(alias);
00094 }
00095 else if (makePFJet(jetTypeE)) {
00096 produces<reco::PFJetCollection>(tag).setBranchAlias(alias);
00097 }
00098 else if (makeGenJet(jetTypeE)) {
00099 produces<reco::GenJetCollection>(tag).setBranchAlias(alias);
00100 }
00101 else if (makeTrackJet(jetTypeE)) {
00102 produces<reco::TrackJetCollection>(tag).setBranchAlias(alias);
00103 }
00104 else if (makePFClusterJet(jetTypeE)) {
00105 produces<reco::PFClusterJetCollection>(tag).setBranchAlias(alias);
00106 }
00107 else if (makeBasicJet(jetTypeE)) {
00108 produces<reco::BasicJetCollection>(tag).setBranchAlias(alias);
00109 }
00110 }
00111
00113
00115
00116
00117 VirtualJetProducer::VirtualJetProducer(const edm::ParameterSet& iConfig)
00118 : moduleLabel_ (iConfig.getParameter<string> ("@module_label"))
00119 , src_ (iConfig.getParameter<edm::InputTag>("src"))
00120 , srcPVs_ (iConfig.getParameter<edm::InputTag>("srcPVs"))
00121 , jetType_ (iConfig.getParameter<string> ("jetType"))
00122 , jetAlgorithm_ (iConfig.getParameter<string> ("jetAlgorithm"))
00123 , rParam_ (iConfig.getParameter<double> ("rParam"))
00124 , inputEtMin_ (iConfig.getParameter<double> ("inputEtMin"))
00125 , inputEMin_ (iConfig.getParameter<double> ("inputEMin"))
00126 , jetPtMin_ (iConfig.getParameter<double> ("jetPtMin"))
00127 , doPVCorrection_(iConfig.getParameter<bool> ("doPVCorrection"))
00128 , restrictInputs_(false)
00129 , maxInputs_(99999999)
00130 , doAreaFastjet_ (iConfig.getParameter<bool> ("doAreaFastjet"))
00131 , useExplicitGhosts_(false)
00132 , doAreaDiskApprox_ (false)
00133 , doRhoFastjet_ (iConfig.getParameter<bool> ("doRhoFastjet"))
00134 , voronoiRfact_ (-9)
00135 , doPUOffsetCorr_(iConfig.getParameter<bool> ("doPUOffsetCorr"))
00136 , puWidth_(0)
00137 , nExclude_(0)
00138 , jetCollInstanceName_ ("")
00139 , writeCompound_ ( false )
00140 {
00141 anomalousTowerDef_ = std::auto_ptr<AnomalousTower>(new AnomalousTower(iConfig));
00142
00143
00144
00145
00146
00147
00148
00149 if (jetAlgorithm_=="SISCone") {
00150 fjPlugin_ = PluginPtr( new fastjet::SISConePlugin(rParam_,0.75,0,0.0,false,
00151 fastjet::SISConePlugin::SM_pttilde) );
00152 fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(&*fjPlugin_) );
00153 }
00154 else if (jetAlgorithm_=="IterativeCone") {
00155 fjPlugin_ = PluginPtr(new fastjet::CMSIterativeConePlugin(rParam_,1.0));
00156 fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
00157 }
00158 else if (jetAlgorithm_=="CDFMidPoint") {
00159 fjPlugin_ = PluginPtr(new fastjet::CDFMidPointPlugin(rParam_,0.75));
00160 fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
00161 }
00162 else if (jetAlgorithm_=="ATLASCone") {
00163 fjPlugin_ = PluginPtr(new fastjet::ATLASConePlugin(rParam_));
00164 fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(&*fjPlugin_));
00165 }
00166 else if (jetAlgorithm_=="Kt")
00167 fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::kt_algorithm,rParam_));
00168 else if (jetAlgorithm_=="CambridgeAachen")
00169 fjJetDefinition_= JetDefPtr(new fastjet::JetDefinition(fastjet::cambridge_algorithm,
00170 rParam_) );
00171 else if (jetAlgorithm_=="AntiKt")
00172 fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm,rParam_) );
00173 else if (jetAlgorithm_=="GeneralizedKt")
00174 fjJetDefinition_= JetDefPtr( new fastjet::JetDefinition(fastjet::genkt_algorithm,
00175 rParam_,-2) );
00176 else
00177 throw cms::Exception("Invalid jetAlgorithm")
00178 <<"Jet algorithm for VirtualJetProducer is invalid, Abort!\n";
00179
00180 jetTypeE=JetType::byName(jetType_);
00181
00182 if ( iConfig.exists("jetCollInstanceName") ) {
00183 jetCollInstanceName_ = iConfig.getParameter<string>("jetCollInstanceName");
00184 }
00185
00186 if ( doPUOffsetCorr_ ) {
00187 if ( jetTypeE != JetType::CaloJet && jetTypeE != JetType::BasicJet) {
00188 throw cms::Exception("InvalidInput") << "Can only offset correct jets of type CaloJet or BasicJet";
00189 }
00190
00191 if(iConfig.exists("subtractorName")) puSubtractorName_ = iConfig.getParameter<string> ("subtractorName");
00192 else puSubtractorName_ = std::string();
00193
00194 if(puSubtractorName_.empty()){
00195 edm::LogWarning("VirtualJetProducer") << "Pile Up correction on; however, pile up type is not specified. Using default... \n";
00196 subtractor_ = boost::shared_ptr<PileUpSubtractor>(new PileUpSubtractor(iConfig));
00197 }else{
00198 subtractor_ = boost::shared_ptr<PileUpSubtractor>(PileUpSubtractorFactory::get()->create( puSubtractorName_, iConfig));
00199 }
00200 }
00201
00202
00203 if ( iConfig.exists("useExplicitGhosts") ) {
00204 useExplicitGhosts_ = iConfig.getParameter<bool>("useExplicitGhosts");
00205 }
00206
00207
00208 if (iConfig.exists("doAreaDiskApprox")) {
00209 doAreaDiskApprox_ = iConfig.getParameter<bool>("doAreaDiskApprox");
00210 if (doAreaDiskApprox_ && doAreaFastjet_)
00211 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";
00212
00213 }
00214
00215
00216 if (iConfig.exists("voronoiRfact"))
00217 voronoiRfact_ = iConfig.getParameter<double>("voronoiRfact");
00218
00219
00220
00221 if ( doAreaFastjet_ || doRhoFastjet_ ) {
00222
00223
00224 double rhoEtaMax=iConfig.getParameter<double>("Rho_EtaMax");
00225
00226 double ghostEtaMax = iConfig.getParameter<double>("Ghost_EtaMax");
00227
00228 int activeAreaRepeats = iConfig.getParameter<int> ("Active_Area_Repeats");
00229
00230 double ghostArea = iConfig.getParameter<double> ("GhostArea");
00231 if (voronoiRfact_ <= 0) {
00232 fjActiveArea_ = ActiveAreaSpecPtr(new fastjet::GhostedAreaSpec(ghostEtaMax,activeAreaRepeats,ghostArea));
00233 fjActiveArea_->set_fj2_placement(true);
00234 if ( ! useExplicitGhosts_ ) {
00235 fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area, *fjActiveArea_ ) );
00236 } else {
00237 fjAreaDefinition_ = AreaDefinitionPtr( new fastjet::AreaDefinition(fastjet::active_area_explicit_ghosts, *fjActiveArea_ ) );
00238 }
00239 }
00240 fjRangeDef_ = RangeDefPtr( new fastjet::RangeDefinition(rhoEtaMax) );
00241 }
00242
00243
00244 if ( iConfig.exists("restrictInputs") ) {
00245 restrictInputs_ = iConfig.getParameter<bool>("restrictInputs");
00246 maxInputs_ = iConfig.getParameter<unsigned int>("maxInputs");
00247 }
00248
00249
00250 string alias=iConfig.getUntrackedParameter<string>("alias",moduleLabel_);
00251
00252
00253
00254
00255 if ( iConfig.exists("writeCompound") ) {
00256 writeCompound_ = iConfig.getParameter<bool>("writeCompound");
00257 }
00258
00259
00260 makeProduces( alias, jetCollInstanceName_ );
00261
00262 doFastJetNonUniform_ = false;
00263 if(iConfig.exists("doFastJetNonUniform")) doFastJetNonUniform_ = iConfig.getParameter<bool> ("doFastJetNonUniform");
00264 if(doFastJetNonUniform_){
00265 puCenters_ = iConfig.getParameter<std::vector<double> >("puCenters");
00266 puWidth_ = iConfig.getParameter<double>("puWidth");
00267 nExclude_ = iConfig.getParameter<unsigned int>("nExclude");
00268 }
00269
00270 useDeterministicSeed_ = false;
00271 minSeed_ = 0;
00272 if ( iConfig.exists("useDeterministicSeed") ) {
00273 useDeterministicSeed_ = iConfig.getParameter<bool>("useDeterministicSeed");
00274 minSeed_ = iConfig.getParameter<unsigned int>("minSeed");
00275 }
00276
00277
00278 produces<std::vector<double> >("rhos");
00279 produces<std::vector<double> >("sigmas");
00280 produces<double>("rho");
00281 produces<double>("sigma");
00282
00283
00284 }
00285
00286
00287 VirtualJetProducer::~VirtualJetProducer()
00288 {
00289 }
00290
00291
00293
00295
00296
00297 void VirtualJetProducer::produce(edm::Event& iEvent,const edm::EventSetup& iSetup)
00298 {
00299
00300
00301
00302
00303
00304
00305 if ( useDeterministicSeed_ ) {
00306 fastjet::GhostedAreaSpec gas;
00307 std::vector<int> seeds(2);
00308 seeds[0] = std::max(iEvent.id().run(),minSeed_ + 3) + 3 * iEvent.id().event();
00309 seeds[1] = std::max(iEvent.id().run(),minSeed_ + 5) + 5 * iEvent.id().event();
00310 gas.set_random_status(seeds);
00311 }
00312
00313 LogDebug("VirtualJetProducer") << "Entered produce\n";
00314
00315 vertex_=reco::Jet::Point(0,0,0);
00316 if (makeCaloJet(jetTypeE)&&doPVCorrection_) {
00317 LogDebug("VirtualJetProducer") << "Adding PV info\n";
00318 edm::Handle<reco::VertexCollection> pvCollection;
00319 iEvent.getByLabel(srcPVs_,pvCollection);
00320 if (pvCollection->size()>0) vertex_=pvCollection->begin()->position();
00321 }
00322
00323
00324
00325 if ( doPUOffsetCorr_ ) {
00326 subtractor_->setupGeometryMap(iEvent, iSetup);
00327 }
00328
00329
00330 LogDebug("VirtualJetProducer") << "Clear data\n";
00331 fjInputs_.clear();
00332 fjJets_.clear();
00333 inputs_.clear();
00334
00335
00336 edm::Handle<reco::CandidateView> inputsHandle;
00337 edm::Handle< std::vector<edm::FwdPtr<reco::PFCandidate> > > pfinputsHandleAsFwdPtr;
00338
00339 bool isView = iEvent.getByLabel(src_,inputsHandle);
00340 if ( isView ) {
00341 for (size_t i = 0; i < inputsHandle->size(); ++i) {
00342 inputs_.push_back(inputsHandle->ptrAt(i));
00343 }
00344 } else {
00345 iEvent.getByLabel(src_,pfinputsHandleAsFwdPtr);
00346 for (size_t i = 0; i < pfinputsHandleAsFwdPtr->size(); ++i) {
00347 if ( (*pfinputsHandleAsFwdPtr)[i].ptr().isAvailable() ) {
00348 inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].ptr() );
00349 }
00350 else if ( (*pfinputsHandleAsFwdPtr)[i].backPtr().isAvailable() ) {
00351 inputs_.push_back( (*pfinputsHandleAsFwdPtr)[i].backPtr() );
00352 }
00353 }
00354 }
00355 LogDebug("VirtualJetProducer") << "Got inputs\n";
00356
00357
00358
00359
00360 fjInputs_.reserve(inputs_.size());
00361 inputTowers();
00362 LogDebug("VirtualJetProducer") << "Inputted towers\n";
00363
00364
00365
00366 if ( doPUOffsetCorr_ ) {
00367 subtractor_->setDefinition(fjJetDefinition_);
00368 subtractor_->reset(inputs_,fjInputs_,fjJets_);
00369 subtractor_->calculatePedestal(fjInputs_);
00370 subtractor_->subtractPedestal(fjInputs_);
00371 LogDebug("VirtualJetProducer") << "Subtracted pedestal\n";
00372 }
00373
00374
00375 runAlgorithm( iEvent, iSetup );
00376
00377
00378
00379
00380
00381 LogDebug("VirtualJetProducer") << "Ran algorithm\n";
00382
00383
00384
00385
00386
00387
00388 if ( doPUOffsetCorr_ ) {
00389 LogDebug("VirtualJetProducer") << "Do PUOffsetCorr\n";
00390 vector<fastjet::PseudoJet> orphanInput;
00391 subtractor_->calculateOrphanInput(orphanInput);
00392 subtractor_->calculatePedestal(orphanInput);
00393 subtractor_->offsetCorrectJets();
00394 }
00395
00396
00397
00398
00399 output( iEvent, iSetup );
00400 LogDebug("VirtualJetProducer") << "Wrote jets\n";
00401
00402 return;
00403 }
00404
00405
00406
00407 void VirtualJetProducer::inputTowers( )
00408 {
00409 std::vector<edm::Ptr<reco::Candidate> >::const_iterator inBegin = inputs_.begin(),
00410 inEnd = inputs_.end(), i = inBegin;
00411 for (; i != inEnd; ++i ) {
00412 reco::CandidatePtr input = *i;
00413 if (edm::isNotFinite(input->pt())) continue;
00414 if (input->et() <inputEtMin_) continue;
00415 if (input->energy()<inputEMin_) continue;
00416 if (isAnomalousTower(input)) continue;
00417 if (input->pt() == 0) {
00418 edm::LogError("NullTransverseMomentum") << "dropping input candidate with pt=0";
00419 continue;
00420 }
00421 if (makeCaloJet(jetTypeE)&&doPVCorrection_) {
00422 const CaloTower* tower=dynamic_cast<const CaloTower*>(input.get());
00423 math::PtEtaPhiMLorentzVector ct(tower->p4(vertex_));
00424 fjInputs_.push_back(fastjet::PseudoJet(ct.px(),ct.py(),ct.pz(),ct.energy()));
00425
00426 }
00427 else {
00428
00429
00430
00431
00432
00433
00434 fjInputs_.push_back(fastjet::PseudoJet(input->px(),input->py(),input->pz(),
00435 input->energy()));
00436 }
00437 fjInputs_.back().set_user_index(i - inBegin);
00438 }
00439
00440 if ( restrictInputs_ && fjInputs_.size() > maxInputs_ ) {
00441 reco::helper::GreaterByPtPseudoJet pTComparator;
00442 std::sort(fjInputs_.begin(), fjInputs_.end(), pTComparator);
00443 fjInputs_.resize(maxInputs_);
00444 edm::LogWarning("JetRecoTooManyEntries") << "Too many inputs in the event, limiting to first " << maxInputs_ << ". Output is suspect.";
00445 }
00446 }
00447
00448
00449 bool VirtualJetProducer::isAnomalousTower(reco::CandidatePtr input)
00450 {
00451 if (!makeCaloJet(jetTypeE))
00452 return false;
00453 else
00454 return (*anomalousTowerDef_)(*input);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 void VirtualJetProducer::copyConstituents(const vector<fastjet::PseudoJet>& fjConstituents,
00465 reco::Jet* jet)
00466 {
00467 for (unsigned int i=0;i<fjConstituents.size();++i) {
00468 int index = fjConstituents[i].user_index();
00469 if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() )
00470 jet->addDaughter(inputs_[index]);
00471 }
00472 }
00473
00474
00475
00476 vector<reco::CandidatePtr>
00477 VirtualJetProducer::getConstituents(const vector<fastjet::PseudoJet>&fjConstituents)
00478 {
00479 vector<reco::CandidatePtr> result;
00480 for (unsigned int i=0;i<fjConstituents.size();i++) {
00481 int index = fjConstituents[i].user_index();
00482 if ( index >= 0 && static_cast<unsigned int>(index) < inputs_.size() ) {
00483 reco::CandidatePtr candidate = inputs_[index];
00484 result.push_back(candidate);
00485 }
00486 }
00487 return result;
00488 }
00489
00490
00491
00492
00493 void VirtualJetProducer::output(edm::Event & iEvent, edm::EventSetup const& iSetup)
00494 {
00495
00496
00497
00498 if ( !writeCompound_ ) {
00499 switch( jetTypeE ) {
00500 case JetType::CaloJet :
00501 writeJets<reco::CaloJet>( iEvent, iSetup);
00502 break;
00503 case JetType::PFJet :
00504 writeJets<reco::PFJet>( iEvent, iSetup);
00505 break;
00506 case JetType::GenJet :
00507 writeJets<reco::GenJet>( iEvent, iSetup);
00508 break;
00509 case JetType::TrackJet :
00510 writeJets<reco::TrackJet>( iEvent, iSetup);
00511 break;
00512 case JetType::PFClusterJet :
00513 writeJets<reco::PFClusterJet>( iEvent, iSetup);
00514 break;
00515 case JetType::BasicJet :
00516 writeJets<reco::BasicJet>( iEvent, iSetup);
00517 break;
00518 default:
00519 throw cms::Exception("InvalidInput") << "invalid jet type in VirtualJetProducer\n";
00520 break;
00521 };
00522 } else {
00523
00524 switch( jetTypeE ) {
00525 case JetType::CaloJet :
00526 writeCompoundJets<reco::CaloJet>( iEvent, iSetup );
00527 break;
00528 case JetType::PFJet :
00529 writeCompoundJets<reco::PFJet>( iEvent, iSetup );
00530 break;
00531 case JetType::GenJet :
00532 writeCompoundJets<reco::GenJet>( iEvent, iSetup );
00533 break;
00534 case JetType::BasicJet :
00535 writeCompoundJets<reco::BasicJet>( iEvent, iSetup );
00536 break;
00537 default:
00538 throw cms::Exception("InvalidInput") << "invalid jet type in CompoundJetProducer\n";
00539 break;
00540 };
00541 }
00542
00543 }
00544
00545 template< typename T >
00546 void VirtualJetProducer::writeJets( edm::Event & iEvent, edm::EventSetup const& iSetup )
00547 {
00548 if (doRhoFastjet_) {
00549
00550
00551 std::vector<fastjet::PseudoJet> fjexcluded_jets;
00552 fjexcluded_jets=fjJets_;
00553
00554 if(fjexcluded_jets.size()>2) fjexcluded_jets.resize(nExclude_);
00555
00556 if(doFastJetNonUniform_){
00557 std::auto_ptr<std::vector<double> > rhos(new std::vector<double>);
00558 std::auto_ptr<std::vector<double> > sigmas(new std::vector<double>);
00559 int nEta = puCenters_.size();
00560 rhos->reserve(nEta);
00561 sigmas->reserve(nEta);
00562 fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
00563 dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
00564
00565
00566 for(int ie = 0; ie < nEta; ++ie){
00567 double eta = puCenters_[ie];
00568 double etamin=eta-puWidth_;
00569 double etamax=eta+puWidth_;
00570 fastjet::RangeDefinition range_rho(etamin,etamax);
00571 fastjet::BackgroundEstimator bkgestim(*clusterSequenceWithArea,range_rho);
00572 bkgestim.set_excluded_jets(fjexcluded_jets);
00573 rhos->push_back(bkgestim.rho());
00574 sigmas->push_back(bkgestim.sigma());
00575 }
00576 iEvent.put(rhos,"rhos");
00577 iEvent.put(sigmas,"sigmas");
00578 }else{
00579 std::auto_ptr<double> rho(new double(0.0));
00580 std::auto_ptr<double> sigma(new double(0.0));
00581 double mean_area = 0;
00582
00583 fastjet::ClusterSequenceAreaBase const* clusterSequenceWithArea =
00584 dynamic_cast<fastjet::ClusterSequenceAreaBase const *> ( &*fjClusterSeq_ );
00585
00586
00587
00588
00589
00590
00591 clusterSequenceWithArea->get_median_rho_and_sigma(*fjRangeDef_,false,*rho,*sigma,mean_area);
00592 if((*rho < 0)|| (edm::isNotFinite(*rho))) {
00593 edm::LogError("BadRho") << "rho value is " << *rho << " area:" << mean_area << " and n_empty_jets: " << clusterSequenceWithArea->n_empty_jets(*fjRangeDef_) << " with range " << fjRangeDef_->description()
00594 <<". Setting rho to rezo.";
00595 *rho = 0;
00596 }
00597 iEvent.put(rho,"rho");
00598 iEvent.put(sigma,"sigma");
00599 }
00600 }
00601
00602
00603
00604 using namespace reco;
00605
00606 std::auto_ptr<std::vector<T> > jets(new std::vector<T>() );
00607 jets->reserve(fjJets_.size());
00608
00609
00610 std::vector<std::vector<double> > rij(fjJets_.size());
00611
00612 for (unsigned int ijet=0;ijet<fjJets_.size();++ijet) {
00613
00614 T jet;
00615
00616 const fastjet::PseudoJet& fjJet = fjJets_[ijet];
00617
00618 std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
00619
00620 std::vector<CandidatePtr> constituents =
00621 getConstituents(fjConstituents);
00622
00623
00624
00625 double jetArea=0.0;
00626 if ( doAreaFastjet_ && fjJet.has_area() ) {
00627 jetArea = fjJet.area();
00628 }
00629 else if ( doAreaDiskApprox_ ) {
00630
00631
00632 jetArea = M_PI;
00633 if (ijet) {
00634 std::vector<double>& distance = rij[ijet];
00635 distance.resize(ijet);
00636 for (unsigned jJet = 0; jJet < ijet; ++jJet) {
00637 distance[jJet] = reco::deltaR(fjJets_[ijet],fjJets_[jJet]) / rParam_;
00638 jetArea -= reco::helper::VirtualJetProducerHelper::intersection(distance[jJet]);
00639 for (unsigned kJet = 0; kJet < jJet; ++kJet) {
00640 jetArea += reco::helper::VirtualJetProducerHelper::intersection(distance[jJet], distance[kJet], rij[jJet][kJet]);
00641 }
00642 }
00643 }
00644 jetArea *= rParam_;
00645 jetArea *= rParam_;
00646 }
00647
00648
00649
00650 writeSpecific(jet,
00651 Particle::LorentzVector(fjJet.px(),
00652 fjJet.py(),
00653 fjJet.pz(),
00654 fjJet.E()),
00655 vertex_,
00656 constituents, iSetup);
00657
00658 jet.setJetArea (jetArea);
00659
00660 if(doPUOffsetCorr_){
00661 jet.setPileup(subtractor_->getPileUpEnergy(ijet));
00662 }else{
00663 jet.setPileup (0.0);
00664 }
00665
00666
00667 jets->push_back(jet);
00668 }
00669
00670 iEvent.put(jets,jetCollInstanceName_);
00671
00672
00673 }
00674
00675
00676
00678 template< class T>
00679 void VirtualJetProducer::writeCompoundJets( edm::Event & iEvent, edm::EventSetup const& iSetup)
00680 {
00681
00682
00683 std::auto_ptr<reco::BasicJetCollection> jetCollection( new reco::BasicJetCollection() );
00684
00685 std::auto_ptr<std::vector<T> > subjetCollection( new std::vector<T>() );
00686
00687
00688 edm::OrphanHandle< std::vector<T> > subjetHandleAfterPut;
00689
00690 std::vector< std::vector<int> > indices;
00691
00692 std::vector<math::XYZTLorentzVector> p4_hardJets;
00693
00694 std::vector<double> area_hardJets;
00695
00696
00697
00698 std::vector<fastjet::PseudoJet>::const_iterator it = fjJets_.begin(),
00699 iEnd = fjJets_.end(),
00700 iBegin = fjJets_.begin();
00701 indices.resize( fjJets_.size() );
00702 for ( ; it != iEnd; ++it ) {
00703 fastjet::PseudoJet const & localJet = *it;
00704 unsigned int jetIndex = it - iBegin;
00705
00706 p4_hardJets.push_back( math::XYZTLorentzVector(localJet.px(), localJet.py(), localJet.pz(), localJet.e() ));
00707 double localJetArea = 0.0;
00708 if ( doAreaFastjet_ && localJet.has_area() ) {
00709 localJetArea = localJet.area();
00710 }
00711 area_hardJets.push_back( localJetArea );
00712
00713
00714 std::vector<fastjet::PseudoJet> constituents;
00715 if ( it->has_pieces() ) {
00716 constituents = it->pieces();
00717 } else {
00718 constituents=it->constituents();
00719 }
00720
00721
00722 std::vector<fastjet::PseudoJet>::const_iterator itSubJetBegin = constituents.begin(),
00723 itSubJet = itSubJetBegin, itSubJetEnd = constituents.end();
00724 for (; itSubJet != itSubJetEnd; ++itSubJet ){
00725
00726 fastjet::PseudoJet const & subjet = *itSubJet;
00727
00728 math::XYZTLorentzVector p4Subjet(subjet.px(), subjet.py(), subjet.pz(), subjet.e() );
00729 reco::Particle::Point point(0,0,0);
00730
00731
00732 std::vector<reco::CandidatePtr> subjetConstituents;
00733
00734
00735 std::vector<fastjet::PseudoJet> subjetFastjetConstituents = subjet.constituents();
00736 std::vector<reco::CandidatePtr> constituents =
00737 getConstituents(subjetFastjetConstituents );
00738
00739 indices[jetIndex].push_back( subjetCollection->size() );
00740
00741
00742 T jet;
00743 reco::writeSpecific( jet, p4Subjet, point, constituents, iSetup);
00744 double subjetArea = 0.0;
00745 if ( doAreaFastjet_ && itSubJet->has_area() ){
00746 subjetArea = itSubJet->area();
00747 }
00748 jet.setJetArea( subjetArea );
00749 subjetCollection->push_back( jet );
00750
00751 }
00752 }
00753
00754 subjetHandleAfterPut = iEvent.put( subjetCollection, jetCollInstanceName_ );
00755
00756
00757
00758 std::vector<math::XYZTLorentzVector>::const_iterator ip4 = p4_hardJets.begin(),
00759 ip4Begin = p4_hardJets.begin(),
00760 ip4End = p4_hardJets.end();
00761
00762 for ( ; ip4 != ip4End; ++ip4 ) {
00763 int p4_index = ip4 - ip4Begin;
00764 std::vector<int> & ind = indices[p4_index];
00765 std::vector<reco::CandidatePtr> i_hardJetConstituents;
00766
00767 for( std::vector<int>::const_iterator isub = ind.begin();
00768 isub != ind.end(); ++isub ) {
00769 reco::CandidatePtr candPtr( subjetHandleAfterPut, *isub, false );
00770 i_hardJetConstituents.push_back( candPtr );
00771 }
00772 reco::Particle::Point point(0,0,0);
00773 reco::BasicJet toput( *ip4, point, i_hardJetConstituents);
00774 toput.setJetArea( area_hardJets[ip4 - ip4Begin] );
00775 jetCollection->push_back( toput );
00776 }
00777
00778
00779 iEvent.put( jetCollection);
00780
00781 }