CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RecoTauBuilderCombinatoricPlugin.cc
Go to the documentation of this file.
1 #include <vector>
2 
5 
9 
15 
16 namespace reco { namespace tau {
17 
19  public:
23  const std::vector<RecoTauPiZero>& piZeros,
24  const std::vector<PFCandidatePtr>& regionalExtras) const;
25  private:
29  struct decayModeInfo {
30  uint32_t maxPiZeros_;
31  uint32_t maxPFCHs_;
32  uint32_t nCharged_;
33  uint32_t nPiZeros_;
34  };
35  std::vector<decayModeInfo> decayModesToBuild_;
36 };
37 
39  const edm::ParameterSet& pset): RecoTauBuilderPlugin(pset),
40  qcuts_(pset.getParameterSet(
41  "qualityCuts").getParameterSet("signalQualityCuts")),
42  usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
43  isolationConeSize_(pset.getParameter<double>("isolationConeSize")) {
44  typedef std::vector<edm::ParameterSet> VPSet;
45  const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
46  for (VPSet::const_iterator dm = decayModes.begin();
47  dm != decayModes.end(); ++dm) {
49  info.nCharged_ = dm->getParameter<uint32_t>("nCharged");
50  info.nPiZeros_ = dm->getParameter<uint32_t>("nPiZeros");
51  info.maxPFCHs_ = dm->getParameter<uint32_t>("maxTracks");
52  info.maxPiZeros_ = dm->getParameter<uint32_t>("maxPiZeros");
53  decayModesToBuild_.push_back(info);
54  }
55 }
56 
57 namespace
58 {
59  class SortPi0sDescendingPt {
60  public:
61  bool operator()(const RecoTauPiZero& a, const RecoTauPiZero& b) const {
62  return a.pt() > b.pt();
63  }
64  };
65 }
66 
69  const reco::PFJetRef& jet,
70  const std::vector<RecoTauPiZero>& piZeros,
71  const std::vector<PFCandidatePtr>& regionalExtras) const
72 {
73  //std::cout << "<RecoTauBuilderCombinatoricPlugin::operator()>:" << std::endl;
74 
75  typedef std::vector<PFCandidatePtr> PFCandPtrs;
76  typedef std::vector<RecoTauPiZero> PiZeroList;
77 
79  reco::VertexRef primaryVertexRef = primaryVertex(jet);
80 
81  // Update the primary vertex used by the quality cuts. The PV is supplied by
82  // the base class.
83  qcuts_.setPV(primaryVertexRef);
84 
85  // Get PFCHs from this jet. They are already sorted by descending Pt
86  PFCandPtrs pfchs;
89  } else {
90  // Check if we want to include electrons in muons in "charged hadron"
91  // collection. This is the preferred behavior, as the PF lepton selections
92  // are very loose.
93  pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
94  }
95  //std::cout << "#pfchs = " << pfchs.size() << std::endl;
96  //int idx = 0;
97  //for ( PFCandPtrs::const_iterator pfch = pfchs.begin();
98  // pfch != pfchs.end(); ++pfch ) {
99  // std::cout << "pfch #" << idx << ": Pt = " << (*pfch)->pt() << ", eta = " << (*pfch)->eta() << ", phi = " << (*pfch)->phi() << std::endl;
100  // ++idx;
101  //}
102  //std::cout << "#piZeros = " << piZeros.size() << std::endl;
103  //idx = 0;
104  //for ( std::vector<RecoTauPiZero>::const_iterator piZero = piZeros.begin();
105  // piZero != piZeros.end(); ++piZero ) {
106  // std::cout << "piZero #" << idx << ": Pt = " << piZero->pt() << ", eta = " << piZero->eta() << ", phi = " << piZero->phi() << std::endl;
107  // ++idx;
108  //}
109 
110  PFCandPtrs pfnhs = qcuts_.filterRefs(
112 
115  PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
116 
117  // Loop over the decay modes we want to build
118  for (std::vector<decayModeInfo>::const_iterator
119  decayMode = decayModesToBuild_.begin();
120  decayMode != decayModesToBuild_.end(); ++decayMode) {
121  // Find how many piZeros are in this decay mode
122  size_t piZerosToBuild = decayMode->nPiZeros_;
123  //std::cout << "piZerosToBuild = " << piZerosToBuild << std::endl;
124  // Find how many tracks are in this decay mode
125  size_t tracksToBuild = decayMode->nCharged_;
126  //std::cout << "tracksToBuild = " << tracksToBuild << std::endl;
127 
128  // Skip decay mode if jet doesn't have the multiplicity to support it
129  if (pfchs.size() < tracksToBuild)
130  continue;
131 
132  // Find the start and end of potential signal tracks
133  PFCandPtrs::iterator pfch_begin = pfchs.begin();
134  PFCandPtrs::iterator pfch_end = pfchs.end();
135  pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
136 
137  // Build our track combo generator
139  PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
140 
141  /*
142  * Begin combinatoric loop for this decay mode
143  */
144  // Loop over the different combinations of tracks
145  for (PFCombo::iterator trackCombo = trackCombos.begin();
146  trackCombo != trackCombos.end(); ++trackCombo) {
148  xCleaner(trackCombo->combo_begin(), trackCombo->combo_end());
149 
150  PiZeroList cleanPiZeros = xCleaner(piZeros);
151 
152  // CV: sort collection of cross-cleaned pi0s by descending Pt
153  std::sort(cleanPiZeros.begin(), cleanPiZeros.end(), SortPi0sDescendingPt());
154 
155  // Skip decay mode if we don't have enough remaining clean pizeros to
156  // build it.
157  if (cleanPiZeros.size() < piZerosToBuild)
158  continue;
159 
160  // Find the start and end of potential signal tracks
161  PiZeroList::iterator piZero_begin = cleanPiZeros.begin();
162  PiZeroList::iterator piZero_end = cleanPiZeros.end();
163 
164  piZero_end = takeNElements(piZero_begin, piZero_end,
165  decayMode->maxPiZeros_);
166 
167  // Build our piZero combo generator
168  typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
169  PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
170  // Loop over the different combinations of PiZeros
171  for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
172  piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
173  // Output tau
174  RecoTauConstructor tau(jet, getPFCands(), true);
175  // Reserve space in our collections
177  RecoTauConstructor::kChargedHadron, tracksToBuild);
178  tau.reserve(
180  RecoTauConstructor::kGamma, 2*piZerosToBuild); // k-factor = 2
181  tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
182 
183  // FIXME - are all these reserves okay? will they get propagated to the
184  // dataformat size if they are wrong?
185  tau.reserve(
187  RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
190  (cleanPiZeros.size() - piZerosToBuild)*2);
192  (cleanPiZeros.size() - piZerosToBuild));
193 
194  // Set signal and isolation components for charged hadrons, after
195  // converting them to a PFCandidateRefVector
196  tau.addPFCands(
198  trackCombo->combo_begin(), trackCombo->combo_end()
199  );
200 
201  // Get signal PiZero constituents and add them to the tau.
202  // The sub-gammas are automatically added.
203  tau.addPiZeros(
205  piZeroCombo->combo_begin(), piZeroCombo->combo_end()
206  );
207 
208  // Now build isolation collections
209  // Load our isolation tools
210  using namespace reco::tau::cone;
211  PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
212 
213  // Cross cleaning predicate. Remove any PFCandidatePtrs that are
214  // contained within existing PiZeros. This predicate will return false
215  // for any object that overlaps with cleanPiZeros.
216  xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
217  // And this cleaning filter predicate with our Iso cone filter
219  pfCandFilter(isolationConeFilter, pfCandXCleaner);
220 
221  PiZeroDRFilter isolationConeFilterPiZero(
222  tau.p4(), 0, isolationConeSize_);
223 
224  // Additionally make predicates to select the different PF object types
225  // of the regional junk objects to add
227  PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
228 
230  pfchCandSelector(reco::PFCandidate::h);
232  pfgammaCandSelector(reco::PFCandidate::gamma);
234  pfnhCandSelector(reco::PFCandidate::h0);
235 
236  RegionalJunkConeAndIdFilter pfChargedJunk(
237  pfchCandSelector, // select charged stuff from junk
238  isolationConeFilter // only take those in iso cone
239  );
240 
241  RegionalJunkConeAndIdFilter pfGammaJunk(
242  pfgammaCandSelector, // select gammas from junk
243  isolationConeFilter // only take those in iso cone
244  );
245 
246  RegionalJunkConeAndIdFilter pfNeutralJunk(
247  pfnhCandSelector, // select neutral stuff from junk
248  isolationConeFilter // select stuff in iso cone
249  );
250 
251  // Filter the isolation candidates in a DR cone
252  tau.addPFCands(
254  boost::make_filter_iterator(
255  pfCandFilter,
256  trackCombo->remainder_begin(), trackCombo->remainder_end()),
257  boost::make_filter_iterator(
258  pfCandFilter,
259  trackCombo->remainder_end(), trackCombo->remainder_end())
260  );
261 
262  // Add all the candidates that weren't included in the combinatoric
263  // generation
264  tau.addPFCands(
266  boost::make_filter_iterator(
267  pfCandFilter,
268  pfch_end, pfchs.end()),
269  boost::make_filter_iterator(
270  pfCandFilter,
271  pfchs.end(), pfchs.end())
272  );
273  // Add all charged candidates that are in the iso cone but weren't in the
274  // original PFJet
275  tau.addPFCands(
277  boost::make_filter_iterator(
278  pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
279  boost::make_filter_iterator(
280  pfChargedJunk, regionalJunk.end(), regionalJunk.end())
281  );
282 
283  // Add all gammas that are in the iso cone but weren't in the
284  // orginal PFJet
285  tau.addPFCands(
287  boost::make_filter_iterator(
288  pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
289  boost::make_filter_iterator(
290  pfGammaJunk, regionalJunk.end(), regionalJunk.end())
291  );
292 
293  // Add all the netural hadron candidates to the isolation collection
294  tau.addPFCands(
296  boost::make_filter_iterator(
297  pfCandFilter,
298  pfnhs.begin(), pfnhs.end()),
299  boost::make_filter_iterator(
300  pfCandFilter,
301  pfnhs.end(), pfnhs.end())
302  );
303  // Add all the netural hadrons from the region collection that are in
304  // the iso cone to the tau
305  tau.addPFCands(
307  boost::make_filter_iterator(
308  pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
309  boost::make_filter_iterator(
310  pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
311  );
312 
313  tau.addPiZeros(
315  boost::make_filter_iterator(
316  isolationConeFilterPiZero,
317  piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
318  boost::make_filter_iterator(
319  isolationConeFilterPiZero,
320  piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
321  );
322 
323  tau.addPiZeros(
325  boost::make_filter_iterator(
326  isolationConeFilterPiZero,
327  piZero_end, cleanPiZeros.end()),
328  boost::make_filter_iterator(
329  isolationConeFilterPiZero,
330  cleanPiZeros.end(), cleanPiZeros.end())
331  );
332 
333  std::auto_ptr<reco::PFTau> tauPtr = tau.get(true);
334 
335  if ( primaryVertexRef.isNonnull() )
336  tauPtr->setVertex(primaryVertexRef->position());
337 
338  output.push_back(tauPtr);
339  }
340  }
341  }
342  return output.release();
343 }
344 }} // end namespace reco::tau
345 
349  "RecoTauBuilderCombinatoricPlugin");
T getParameter(std::string const &) const
const edm::Handle< PFCandidateCollection > & getPFCands() const
Hack to be able to convert Ptrs to Refs.
InputIterator takeNElements(const InputIterator &begin, const InputIterator &end, size_t N)
std::auto_ptr< reco::PFTau > get(bool setupLeadingCandidates=true)
void reserve(Region region, ParticleType type, size_t size)
Reserve a set amount of space for a given RefVector.
Coll filterRefs(const Coll &refcoll, bool invert=false) const
Filter a ref vector of PFCandidates.
ParameterSet const & getParameterSet(ParameterSetID const &id)
std::vector< reco::PFCandidatePtr > PFCandPtrs
boost::ptr_vector< reco::PFTau > output_type
std::auto_ptr< output_type > return_type
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
void addPiZeros(Region region, const InputIterator &begin, const InputIterator &end)
Add a list of pi zeros to the input collection.
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
reco::VertexRef primaryVertex(const reco::PFJetRef &jet) const
Get primary vertex associated to this jet.
void setPV(const reco::VertexRef &vtx) const
Update the primary vertex.
const reco::Candidate::LorentzVector & p4() const
virtual return_type operator()(const reco::PFJetRef &jet, const std::vector< RecoTauPiZero > &piZeros, const std::vector< PFCandidatePtr > &regionalExtras) const
void addPFCands(Region region, ParticleType type, const InputIterator &begin, const InputIterator &end)
virtual double pt() const
transverse momentum
void reservePiZero(Region region, size_t size)
Reserve a set amount of space for the PiZeros.
double b
Definition: hdecay.h:120
std::vector< PFCandidatePtr > pfChargedCands(const PFJet &jet, bool sort=true)
Extract all non-neutral candidates from a PFJet.
double a
Definition: hdecay.h:121
#define DEFINE_EDM_PLUGIN(factory, type, name)
Transform a pizero to remove given candidates.