CMS 3D CMS Logo

HiBadParticleCleaner.cc
Go to the documentation of this file.
1 // system include files
2 #include <memory>
3 
4 // user include files
7 
10 
12 
22 //
23 // class declaration
24 //
25 
27 public:
28  explicit HiBadParticleCleaner(const edm::ParameterSet&);
29  ~HiBadParticleCleaner() override = default;
30 
31 private:
32  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
33  // ----------member data ---------------------------
34 
37 
38  const double minMuonPt_;
39  const double minChargedHadronPt_;
40  const double minMuonTrackRelPtErr_;
41  const double maxSigLoose_;
42  const double maxSigTight_;
43  const double minCaloCompatibility_;
44  const unsigned minTrackNHits_;
45  const unsigned minPixelNHits_;
48 };
49 
50 //
51 // constructors and destructor
52 //
54  : tokenPFCandidates_(consumes<edm::View<reco::PFCandidate>>(iConfig.getParameter<edm::InputTag>("PFCandidates"))),
55  tokenPV_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("offlinePV"))),
56  minMuonPt_(iConfig.getParameter<double>("minMuonPt")),
57  minChargedHadronPt_(iConfig.getParameter<double>("minChargedHadronPt")),
58  minMuonTrackRelPtErr_(iConfig.getParameter<double>("minMuonTrackRelPtErr")),
59  maxSigLoose_(iConfig.getParameter<double>("maxSigLoose")),
60  maxSigTight_(iConfig.getParameter<double>("maxSigTight")),
61  minCaloCompatibility_(iConfig.getParameter<double>("minCaloCompatibility")),
62  minTrackNHits_(iConfig.getParameter<uint>("minTrackNHits")),
63  minPixelNHits_(iConfig.getParameter<uint>("minPixelNHits")),
64  minTrackerLayersForMuonLoose_(iConfig.getParameter<int>("minTrackerLayersForMuonLoose")),
65  minTrackerLayersForMuonTight_(iConfig.getParameter<int>("minTrackerLayersForMuonTight")) {
66  produces<bool>();
67  produces<reco::PFCandidateCollection>();
68  produces<reco::PFCandidateCollection>("removed");
69  produces<edm::ValueMap<reco::PFCandidateRef>>();
70 }
71 
72 //
73 // member functions
74 //
75 
76 // ------------ method called on each new Event ------------
78  using namespace std;
79  using namespace edm;
80 
84 
85  const reco::VertexCollection* recoVertices;
87  iEvent.getByToken(tokenPV_, vertexCollection);
88  recoVertices = vertexCollection.product();
89 
90  auto pOutputCandidateCollection = std::make_unique<reco::PFCandidateCollection>();
91  auto pBadCandidateCollection = std::make_unique<reco::PFCandidateCollection>();
92 
93  bool foundBadCandidate = false;
94 
95  size_t n = pfCandidates->size();
96  std::vector<int> candidateIndexMapper(n, 0); // mapping between the original PF and post-cleaning PF
97  size_t iPF;
98  for (iPF = 0; iPF < n; iPF++) {
99  const reco::PFCandidate& pfCandidate = pfCandidates->at(iPF);
100  if (pfCandidate.particleId() == reco::PFCandidate::ParticleType::mu) // muon cleaning
101  {
102  if (pfCandidate.pt() > minMuonPt_) {
103  if (!pfCandidate.muonRef()->isGlobalMuon() || !pfCandidate.muonRef()->isTrackerMuon() ||
104  !pfCandidate.trackRef().isNonnull()) {
105  foundBadCandidate = true;
106  continue;
107  }
108  reco::TrackRef track = pfCandidate.trackRef();
109 
110  if (track->ptError() / track->pt() > minMuonTrackRelPtErr_ || track->pt() < pfCandidate.pt() / 2.) {
111  foundBadCandidate = true;
112  continue;
113  }
114 
117  track->originalAlgo() == reco::TrackBase::muonSeededStepInOut ||
118  track->originalAlgo() == reco::TrackBase::muonSeededStepOutIn ||
119  track->hitPattern().trackerLayersWithMeasurement() < minTrackerLayersForMuonLoose_) {
120  const reco::Vertex& vtx = (*recoVertices)[0];
121  float bestVzError = vtx.zError();
122  const math::XYZPoint& bestVtx(vtx.position());
123  math::Error<3>::type vtx_cov = vtx.covariance();
124  float dz = std::abs(track->dz(bestVtx));
125  float dxy = std::abs(track->dxy(bestVtx));
126  float dzError2 = track->dzError() * track->dzError() + bestVzError * bestVzError;
127  float dxyError = track->dxyError(bestVtx, vtx_cov);
128 
129  float dzSig2 = dz * dz / dzError2;
130  float dxySig2 = dxy * dxy / dxyError / dxyError;
131 
132  float sig3d = sqrt(dzSig2 + dxySig2);
133 
134  if (sig3d > maxSigLoose_) {
135  pBadCandidateCollection->push_back(pfCandidate);
136  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
137  foundBadCandidate = true;
138  continue;
139  }
140 
141  if (track->pt() < pfCandidate.pt() / 1.5 || track->pt() > pfCandidate.pt() * 1.5) {
142  foundBadCandidate = true;
143  pBadCandidateCollection->push_back(pfCandidate);
144  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
145  continue;
146  }
147  if (track->originalAlgo() == reco::TrackBase::muonSeededStepOutIn &&
148  track->hitPattern().trackerLayersWithMeasurement() < minTrackerLayersForMuonTight_) {
149  foundBadCandidate = true;
150  pBadCandidateCollection->push_back(pfCandidate);
151  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
152  continue;
153  }
154  }
155  }
156  } else if (pfCandidate.particleId() == reco::PFCandidate::ParticleType::h) //charged hadron cleaning
157  {
158  if (pfCandidate.pt() > minChargedHadronPt_) {
159  reco::TrackRef track = pfCandidate.trackRef();
160 
161  unsigned nHits = track->numberOfValidHits();
162  unsigned nPixelHits = track->hitPattern().numberOfValidPixelHits();
163 
164  if ((nHits < minTrackNHits_ && nPixelHits < minPixelNHits_) || nHits == 3) {
165  foundBadCandidate = true;
166  pBadCandidateCollection->push_back(pfCandidate);
167  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
168  continue;
169  }
170 
171  const reco::Vertex& vtx = (*recoVertices)[0];
172  float bestVzError = vtx.zError();
173  const math::XYZPoint& bestVtx(vtx.position());
174  math::Error<3>::type vtx_cov = vtx.covariance();
175  float dz = std::abs(track->dz(bestVtx));
176  float dxy = std::abs(track->dxy(bestVtx));
177  float dzError2 = track->dzError() * track->dzError() + bestVzError * bestVzError;
178  float dxyError = track->dxyError(bestVtx, vtx_cov);
179 
180  float dzSig2 = dz * dz / dzError2;
181  float dxySig2 = dxy * dxy / dxyError / dxyError;
182 
183  float sig3d = sqrt(dzSig2 + dxySig2);
184 
185  if (sig3d > maxSigLoose_) {
186  foundBadCandidate = true;
187  pBadCandidateCollection->push_back(pfCandidate);
188  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
189  continue;
190  }
191 
192  if (sig3d > maxSigTight_ && nHits < minTrackNHits_) {
193  foundBadCandidate = true;
194  pBadCandidateCollection->push_back(pfCandidate);
195  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
196  continue;
197  }
198 
201  track->originalAlgo() == reco::TrackBase::muonSeededStepInOut ||
202  track->originalAlgo() == reco::TrackBase::muonSeededStepOutIn) {
203  if (sig3d > maxSigLoose_) {
204  foundBadCandidate = true;
205  pBadCandidateCollection->push_back(pfCandidate);
206  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
207  continue;
208  }
209 
210  if (nHits < minTrackNHits_) {
211  foundBadCandidate = true;
212  pBadCandidateCollection->push_back(pfCandidate);
213  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
214  continue;
215  }
216  }
217 
218  double caloEnergy = pfCandidate.ecalEnergy() + pfCandidate.hcalEnergy();
219 
220  if (caloEnergy < track->p() * minCaloCompatibility_) {
221  if (sig3d > maxSigTight_) {
222  foundBadCandidate = true;
223  pBadCandidateCollection->push_back(pfCandidate);
224  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
225  continue;
226  }
227 
228  if (nHits < minTrackNHits_) {
229  foundBadCandidate = true;
230  pBadCandidateCollection->push_back(pfCandidate);
231  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
232  continue;
233  }
234 
235  if (nPixelHits < minPixelNHits_) {
236  foundBadCandidate = true;
237  pBadCandidateCollection->push_back(pfCandidate);
238  candidateIndexMapper[iPF] = -1 * (pBadCandidateCollection->size());
239  continue;
240  }
241  }
242  }
243  }
244 
245  pOutputCandidateCollection->push_back(pfCandidate);
246  candidateIndexMapper[iPF] = (pOutputCandidateCollection->size());
247  } // end loop over pf candidates
248 
249  bool pass = !foundBadCandidate;
250 
251  edm::OrphanHandle<std::vector<reco::PFCandidate>> newpf = iEvent.put(std::move(pOutputCandidateCollection));
252  edm::OrphanHandle<std::vector<reco::PFCandidate>> badpf = iEvent.put(std::move(pBadCandidateCollection), "removed");
253 
254  iEvent.put(std::make_unique<bool>(pass));
255 
256  std::unique_ptr<edm::ValueMap<reco::PFCandidateRef>> pf2pf(new edm::ValueMap<reco::PFCandidateRef>());
258 
259  std::vector<reco::PFCandidateRef> refs;
260  refs.reserve(n);
261 
262  for (iPF = 0; iPF < n; ++iPF) {
263  if (candidateIndexMapper[iPF] > 0) {
264  refs.push_back(reco::PFCandidateRef(newpf, candidateIndexMapper[iPF] - 1));
265  } else if (candidateIndexMapper[iPF] < 0) {
266  refs.push_back(reco::PFCandidateRef(badpf, -candidateIndexMapper[iPF] - 1));
267  }
268  }
269  filler.insert(pfCandidates, refs.begin(), refs.end());
270 
271  filler.fill();
272  iEvent.put(std::move(pf2pf));
273 }
274 
275 //define this as a plug-in
double pt() const final
transverse momentum
HiBadParticleCleaner(const edm::ParameterSet &)
edm::EDGetTokenT< reco::VertexCollection > tokenPV_
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
ErrorD< N >::type type
Definition: Error.h:32
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
int iEvent
Definition: GenABIO.cc:224
double hcalEnergy() const
return corrected Hcal energy
Definition: PFCandidate.h:233
T sqrt(T t)
Definition: SSEVec.h:19
const double minMuonTrackRelPtErr_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double ecalEnergy() const
return corrected Ecal energy
Definition: PFCandidate.h:221
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:448
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
~HiBadParticleCleaner() override=default
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
fixed size matrix
HLT enums.
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:435
TupleMultiplicity< TrackerTraits > const *__restrict__ uint32_t nHits
const double minCaloCompatibility_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
edm::EDGetTokenT< edm::View< reco::PFCandidate > > tokenPFCandidates_
def move(src, dest)
Definition: eostools.py:511
edm::View< Candidate > CandidateView
view of a collection containing candidates
Definition: CandidateFwd.h:23
virtual ParticleType particleId() const
Definition: PFCandidate.h:392