Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to jet pileup subtraction #29948

Merged
merged 25 commits into from Jun 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
59a7068
move ParticleTowerProducer to plugins
stepobr May 21, 2020
f4d176c
fix pileup subtraction bug
stepobr May 21, 2020
a4a984d
calculateOrphanInput overwritten in plugin
stepobr May 21, 2020
d632591
add minimumTowersFraction to fillDescriptions
stepobr May 21, 2020
2083ce9
quick update to move ParticleTowerProducer to plugins
stepobr May 21, 2020
299c48a
small fixes
stepobr May 21, 2020
501a13d
fix code and style checks issues
stepobr May 21, 2020
4e180bd
Update RecoHI/HiJetAlgos/interface/MultipleAlgoIterator.h
stepobr May 28, 2020
52ceb17
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.h
stepobr May 28, 2020
198576b
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
e6aa240
Update RecoHI/HiJetAlgos/src/MultipleAlgoIterator.cc
stepobr May 28, 2020
b3f6205
Update RecoHI/HiJetAlgos/src/MultipleAlgoIterator.cc
stepobr May 28, 2020
eeeef32
Update RecoHI/HiJetAlgos/src/ParametrizedSubtractor.cc
stepobr May 28, 2020
317bda7
Update RecoJets/JetProducers/src/PileUpSubtractor.cc
stepobr May 28, 2020
a7c45c7
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
7b74388
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
0fce04c
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
d50f116
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
d10d04c
Update RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
stepobr May 28, 2020
19624dc
Apply suggestions from code review
stepobr May 28, 2020
f6af73b
Merged pusubtraction_05_2020 from repository stepobr with cms-merge-t…
stepobr May 28, 2020
aa74a4f
apply suggestions
stepobr Jun 2, 2020
e7afc11
import PFTowers from cfi
stepobr Jun 10, 2020
add8df3
minor fixes and cleaning
stepobr Jun 10, 2020
e06ba5b
fix code check warnings
stepobr Jun 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 4 additions & 7 deletions RecoHI/HiJetAlgos/interface/MultipleAlgoIterator.h
Expand Up @@ -5,22 +5,19 @@

class MultipleAlgoIterator : public PileUpSubtractor {
public:
MultipleAlgoIterator(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC)
: PileUpSubtractor(iConfig, std::move(iC)),
sumRecHits_(iConfig.getParameter<bool>("sumRecHits")),
dropZeroTowers_(iConfig.getUntrackedParameter<bool>("dropZeroTowers", true)) {
;
}
MultipleAlgoIterator(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC);
void offsetCorrectJets() override;
void rescaleRMS(double s);
double getEt(const reco::CandidatePtr& in) const;
double getEta(const reco::CandidatePtr& in) const;
void calculatePedestal(std::vector<fastjet::PseudoJet> const& coll) override;
void subtractPedestal(std::vector<fastjet::PseudoJet>& coll) override;
void calculateOrphanInput(std::vector<fastjet::PseudoJet>& orphanInput) override;

private:
double minimumTowersFraction_;
bool sumRecHits_;
bool dropZeroTowers_;
~MultipleAlgoIterator() override { ; }
};

#endif
57 changes: 0 additions & 57 deletions RecoHI/HiJetAlgos/interface/ParticleTowerProducer.h

This file was deleted.

197 changes: 197 additions & 0 deletions RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
@@ -0,0 +1,197 @@
// -*- C++ -*-
//
// Package: RecoHI/HiJetAlgos
// Class: ParticleTowerProducer
//
/**\class ParticleTowerProducer RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.cc
Description: [one line class summary]
Implementation:
[Notes on implementation]
*/
//
// Original Author: Yetkin Yilmaz,32 4-A08,+41227673039,
// Created: Thu Jan 20 19:53:58 CET 2011
//
//

#include "DataFormats/CaloTowers/interface/CaloTowerDefs.h"
#include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
#include "DataFormats/Candidate/interface/Particle.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/Common/interface/SortedCollection.h"
#include "DataFormats/GeometryVector/interface/GlobalPoint.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/Framework/src/WorkerMaker.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescriptionFiller.h"
#include "DataFormats/Math/interface/deltaPhi.h"
#include "DataFormats/DetId/interface/DetId.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"

#include <cmath>
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>
#include <map>
#include <utility>

class ParticleTowerProducer : public edm::stream::EDProducer<> {
public:
explicit ParticleTowerProducer(const edm::ParameterSet&);
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

private:
void produce(edm::Event&, const edm::EventSetup&) override;
int eta2ieta(double eta) const;
int phi2iphi(double phi, int ieta) const;
double ieta2eta(int ieta) const;
double iphi2phi(int iphi, int ieta) const;
// ----------member data ---------------------------

edm::EDGetTokenT<reco::PFCandidateCollection> src_;
const bool useHF_;

// tower edges from fast sim, used starting at index 30 for the HF
static constexpr int ietaMax = 42;
static constexpr double etaedge[ietaMax] = {
0.000, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131,
1.218, 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650,
2.853, 3.000, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
};
//
// constructors and destructor
//
ParticleTowerProducer::ParticleTowerProducer(const edm::ParameterSet& iConfig)
: src_(consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("src"))),
useHF_(iConfig.getParameter<bool>("useHF")) {
produces<CaloTowerCollection>();
}

//
// member functions
//

// ------------ method called to produce the data ------------
void ParticleTowerProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
using namespace edm;

typedef std::pair<int, int> EtaPhi;
typedef std::map<EtaPhi, double> EtaPhiMap;
EtaPhiMap towers_;
towers_.clear();

auto const& inputs = iEvent.get(src_);
for (auto const& particle : inputs) {
double eta = particle.eta();

int ieta = eta2ieta(eta);
int iphi = phi2iphi(particle.phi(), ieta);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why positionAtECALEntrance is not used here.
Is the goal to map to iEta,iPhi simply to bin with momentum at IP, without actual goal of projecting to the formally the same and proper CaloTower ?

Please add a comment to clarify

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the original idea was to make a 2D grid in the physical eta-phi space, i.e., using the direction of the particles from the PV. The idea of using a grid is basically to reuse the calorimetric style of background subtraction, approximating the same granularity to get the gross changes vs eta. There is some smearing due to the difference between the physical eta-phi, and the values at the calorimeter face. Perhaps there's a more precise way to do it, but the subtraction seems to work rather well with this hybrid method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying. Some comment inline in the code would help.
On technical performance side (speed) it probably means that some simpler indexing (even a flat rectangular grid in eta-phi) may work.
Remind me please where is this code expected to be running (to see if it can become CPU-limited)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the code is already running and has been for quite some time. It's used in akPu4PFJets, which we are writing to AOD.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I thought that we do not have legacy modules running in reco anymore (ParticleTowerProducer is the legacy edm::EDProducer).

Indeed, it's there, I found it in e.g. 140.55 in a test I have around from 11_1_0_pre7

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's there, I found it in e.g. 140.55 in a test I have around from 11_1_0_pre7

I'm slow to realize that this is in the HeavyIons scenario, while the later Run2 and Run3 plans are to run pp_on_AA setup.
Is there a plan to enable it there?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

akPu4PFJets was enabled for in the pp_on_AA setup for Run 2, so I believe this module was run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

akPu4PFJets was enabled for in the pp_on_AA setup for Run 2, so I believe this module was run.

I'm not sure if this is on the subject of ParticleTowerProducer.cc (a producer by itself)
akPu4PFJets is made by FastjetJetProducer with MultipleAlgoIterator

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input to Pu jets is PFTowers:

process.akPu4PFJets.src
cms.InputTag("PFTowers")

process.PFTowers
cms.EDProducer("ParticleTowerProducer",
src = cms.InputTag("particleFlow"),
useHF = cms.bool(False)
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input to Pu jets is PFTowers:

thank you.


if (!useHF_ && abs(ieta) > 29)
continue;

EtaPhi ep(ieta, iphi);
towers_[ep] += particle.et();
}

auto prod = std::make_unique<CaloTowerCollection>();
prod->reserve(towers_.size());
for (auto const& tower : towers_) {
EtaPhi ep = tower.first;
double et = tower.second;

int ieta = ep.first;
int iphi = ep.second;

CaloTowerDetId newTowerId(ieta, iphi); // totally dummy id

// currently sets et = pt, mass to zero
// pt, eta, phi, mass
reco::Particle::PolarLorentzVector p4(et, ieta2eta(ieta), iphi2phi(iphi, ieta), 0.);
GlobalPoint point(p4.x(), p4.y(), p4.z());
prod->emplace_back(newTowerId, p4.e(), 0, 0, 0, 0, p4, point, point);
}

iEvent.put(std::move(prod));
}

// Taken from FastSimulation/CalorimeterProperties/src/HCALProperties.cc
// Note this returns an abs(ieta)
int ParticleTowerProducer::eta2ieta(double eta) const {
// binary search in the array of towers eta edges

int ieta = 0;
while (fabs(eta) > etaedge[ieta] && ieta < ietaMax - 1) {
++ieta;
}

if (eta < 0)
ieta = -ieta;
return ieta;
}

int ParticleTowerProducer::phi2iphi(double phi, int ieta) const {
phi = angle0to2pi::make0To2pi(phi);
int nphi = 72;
int n = 1;
if (abs(ieta) > 20)
n = 2;
if (abs(ieta) >= 40)
n = 4;

int iphi = (int)std::ceil(phi / 2.0 / M_PI * nphi / n);

iphi = n * (iphi - 1) + 1;

return iphi;
}

double ParticleTowerProducer::iphi2phi(int iphi, int ieta) const {
double phi = 0;
int nphi = 72;

int n = 1;
if (abs(ieta) > 20)
n = 2;
if (abs(ieta) >= 40)
n = 4;

int myphi = (iphi - 1) / n + 1;

phi = 2. * M_PI * (myphi - 0.5) / nphi * n;
while (phi > M_PI)
phi -= 2. * M_PI;

return phi;
}

double ParticleTowerProducer::ieta2eta(int ieta) const {
int sign = 1;
if (ieta < 0) {
sign = -1;
ieta = -ieta;
}

double eta = sign * (etaedge[ieta] + etaedge[ieta - 1]) / 2.;
return eta;
}

void ParticleTowerProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
// particleTowerProducer
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("src", edm::InputTag("particleFlow"));
desc.add<bool>("useHF", true);
descriptions.add("particleTowerProducer", desc);
}

// define this as a plug-in
DEFINE_FWK_MODULE(ParticleTowerProducer);
2 changes: 0 additions & 2 deletions RecoHI/HiJetAlgos/plugins/plugins.cc
Expand Up @@ -13,8 +13,6 @@ DEFINE_EDM_PLUGIN(PileUpSubtractorFactory, MultipleAlgoIterator, "MultipleAlgoIt
DEFINE_EDM_PLUGIN(PileUpSubtractorFactory, ParametrizedSubtractor, "ParametrizedSubtractor");
DEFINE_EDM_PLUGIN(PileUpSubtractorFactory, ReflectedIterator, "ReflectedIterator");

#include "RecoHI/HiJetAlgos/interface/ParticleTowerProducer.h"
DEFINE_FWK_MODULE(ParticleTowerProducer);
#include "RecoHI/HiJetAlgos/interface/HiGenCleaner.h"
#include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
#include "DataFormats/JetReco/interface/GenJetCollection.h"
Expand Down
6 changes: 2 additions & 4 deletions RecoHI/HiJetAlgos/python/HiRecoPFJets_cff.py
Expand Up @@ -5,10 +5,8 @@
from RecoHI.HiJetAlgos.HiPFJetParameters_cff import *

#pseudo towers for noise suppression background subtraction
PFTowers = cms.EDProducer("ParticleTowerProducer",
src = cms.InputTag("particleFlow"),
useHF = cms.bool(False)
)
import RecoHI.HiJetAlgos.particleTowerProducer_cfi as _mod
PFTowers = _mod.particleTowerProducer.clone(useHF = False)

#dummy sequence to speed-up reconstruction in pp_on_AA era
pfNoPileUpJMEHI = cms.EDFilter('GenericPFCandidateSelector',
Expand Down
8 changes: 0 additions & 8 deletions RecoHI/HiJetAlgos/python/ParticleTowerProducer_cfi.py

This file was deleted.

62 changes: 62 additions & 0 deletions RecoHI/HiJetAlgos/src/MultipleAlgoIterator.cc
Expand Up @@ -3,10 +3,19 @@
#include "RecoHI/HiJetAlgos/interface/MultipleAlgoIterator.h"
#include "DataFormats/Candidate/interface/CandidateFwd.h"
#include "DataFormats/Candidate/interface/Candidate.h"
#include "DataFormats/Math/interface/deltaR.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"
using namespace std;

MultipleAlgoIterator::MultipleAlgoIterator(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC)
: PileUpSubtractor(iConfig, std::move(iC)),
minimumTowersFraction_(iConfig.getParameter<double>("minimumTowersFraction")),
sumRecHits_(iConfig.getParameter<bool>("sumRecHits")),
dropZeroTowers_(iConfig.getUntrackedParameter<bool>("dropZeroTowers", true)) {
stepobr marked this conversation as resolved.
Show resolved Hide resolved
LogDebug("PileUpSubtractor") << "LIMITING THE MINIMUM TOWERS FRACTION TO : " << minimumTowersFraction_ << endl;
}

void MultipleAlgoIterator::rescaleRMS(double s) {
for (std::map<int, double>::iterator iter = esigma_.begin(); iter != esigma_.end(); ++iter) {
iter->second = s * (iter->second);
Expand Down Expand Up @@ -160,6 +169,59 @@ void MultipleAlgoIterator::calculatePedestal(vector<fastjet::PseudoJet> const& c
}
}

void MultipleAlgoIterator::calculateOrphanInput(vector<fastjet::PseudoJet>& orphanInput) {
LogDebug("PileUpSubtractor") << "The subtractor calculating orphan input...\n";

(*fjInputs_) = fjOriginalInputs_;

vector<int> jettowers; // vector of towers indexed by "user_index"
vector<pair<int, int> > excludedTowers; // vector of excluded ieta, iphi values

for (auto const& pseudojetTMP : *fjJets_) {
if (pseudojetTMP.perp() < puPtMin_)
continue;

// find towers within radiusPU_ of this jet
for (auto const im : allgeomid_) {
double dr = reco::deltaR(geo_->getPosition(im), pseudojetTMP);
auto exclude = find(excludedTowers.begin(), excludedTowers.end(), pair<int, int>(im.ieta(), im.iphi()));
if (dr < radiusPU_ && exclude == excludedTowers.end() &&
(geomtowers_[im.ieta()] - ntowersWithJets_[im.ieta()]) > minimumTowersFraction_ * (geomtowers_[im.ieta()])) {
ntowersWithJets_[im.ieta()]++;

excludedTowers.push_back(pair<int, int>(im.ieta(), im.iphi()));
}
}

for (auto const& it : *fjInputs_) {
int index = it.user_index();
int ie = ieta((*inputs_)[index]);
int ip = iphi((*inputs_)[index]);
auto exclude = find(excludedTowers.begin(), excludedTowers.end(), pair<int, int>(ie, ip));
if (exclude != excludedTowers.end()) {
jettowers.push_back(index);
}
} // initial input collection

} // pseudojets

//
// Create a new collections from the towers not included in jets
//

for (auto const& it : *fjInputs_) {
int index = it.user_index();
vector<int>::const_iterator itjet = find(jettowers.begin(), jettowers.end(), index);
if (itjet == jettowers.end()) {
const reco::CandidatePtr& originalTower = (*inputs_)[index];
fastjet::PseudoJet orphan(originalTower->px(), originalTower->py(), originalTower->pz(), originalTower->energy());
orphan.set_user_index(index);

orphanInput.push_back(orphan);
}
}
}

double MultipleAlgoIterator::getEt(const reco::CandidatePtr& in) const {
const CaloTower* ctc = dynamic_cast<const CaloTower*>(in.get());
const GlobalPoint& pos = geo_->getPosition(ctc->id());
Expand Down