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