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 
14 
15 namespace reco { namespace tau {
16 
18  public:
22  const std::vector<RecoTauPiZero>& piZeros,
23  const std::vector<PFCandidatePtr>& regionalExtras) const;
24  private:
28  struct decayModeInfo {
29  uint32_t maxPiZeros_;
30  uint32_t maxPFCHs_;
31  uint32_t nCharged_;
32  uint32_t nPiZeros_;
33  };
34  std::vector<decayModeInfo> decayModesToBuild_;
35 };
36 
39  qcuts_(pset.getParameter<edm::ParameterSet>("qualityCuts")),
40  usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
41  isolationConeSize_(pset.getParameter<double>("isolationConeSize")) {
42  typedef std::vector<edm::ParameterSet> VPSet;
43  const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
44  for (VPSet::const_iterator dm = decayModes.begin();
45  dm != decayModes.end(); ++dm) {
47  info.nCharged_ = dm->getParameter<uint32_t>("nCharged");
48  info.nPiZeros_ = dm->getParameter<uint32_t>("nPiZeros");
49  info.maxPFCHs_ = dm->getParameter<uint32_t>("maxTracks");
50  info.maxPiZeros_ = dm->getParameter<uint32_t>("maxPiZeros");
51  decayModesToBuild_.push_back(info);
52  }
53 }
54 
57  const reco::PFJetRef& jet,
58  const std::vector<RecoTauPiZero>& piZeros,
59  const std::vector<PFCandidatePtr>& regionalExtras) const {
60 
61  typedef std::vector<PFCandidatePtr> PFCandPtrs;
62  typedef std::vector<RecoTauPiZero> PiZeroList;
63 
65 
66  // Update the primary vertex used by the quality cuts. The PV is supplied by
67  // the base class.
69 
70  // Get PFCHs from this jet. They are already sorted by descending Pt
71  PFCandPtrs pfchs;
74  } else {
75  // Check if we want to include electrons in muons in "charged hadron"
76  // collection. This is the preferred behavior, as the PF lepton selections
77  // are very loose.
78  pfchs = qcuts_.filterRefs(pfChargedCands(*jet));
79  }
80 
81  PFCandPtrs pfnhs = qcuts_.filterRefs(
83 
86  PFCandPtrs regionalJunk = qcuts_.filterRefs(regionalExtras);
87 
88  // Loop over the decay modes we want to build
89  for (std::vector<decayModeInfo>::const_iterator
90  decayMode = decayModesToBuild_.begin();
91  decayMode != decayModesToBuild_.end(); ++decayMode) {
92  // Find how many piZeros are in this decay mode
93  size_t piZerosToBuild = decayMode->nPiZeros_;
94  // Find how many tracks are in this decay mode
95  size_t tracksToBuild = decayMode->nCharged_;
96 
97  // Skip decay mode if jet doesn't have the multiplicity to support it
98  if (pfchs.size() < tracksToBuild)
99  continue;
100 
101  // Find the start and end of potential signal tracks
102  PFCandPtrs::iterator pfch_begin = pfchs.begin();
103  PFCandPtrs::iterator pfch_end = pfchs.end();
104  pfch_end = takeNElements(pfch_begin, pfch_end, decayMode->maxPFCHs_);
105 
106  // Build our track combo generator
108  PFCombo trackCombos(pfch_begin, pfch_end, tracksToBuild);
109 
110  /*
111  * Begin combinatoric loop for this decay mode
112  */
113 
114  // Loop over the different combinations of tracks
115  for (PFCombo::iterator trackCombo = trackCombos.begin();
116  trackCombo != trackCombos.end(); ++trackCombo) {
117 
119  xCleaner(trackCombo->combo_begin(), trackCombo->combo_end());
120 
121  PiZeroList cleanPiZeros = xCleaner(piZeros);
122 
123  // Skip decay mode if we don't have enough remaining clean pizeros to
124  // build it.
125  if (cleanPiZeros.size() < piZerosToBuild)
126  continue;
127 
128  // Find the start and end of potential signal tracks
129  PiZeroList::iterator piZero_begin = cleanPiZeros.begin();
130  PiZeroList::iterator piZero_end = cleanPiZeros.end();
131 
132  piZero_end = takeNElements(piZero_begin, piZero_end,
133  decayMode->maxPiZeros_);
134 
135  // Build our piZero combo generator
136  typedef tau::CombinatoricGenerator<PiZeroList> PiZeroCombo;
137  PiZeroCombo piZeroCombos(piZero_begin, piZero_end, piZerosToBuild);
138 
139  // Loop over the different combinations of PiZeros
140  for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin();
141  piZeroCombo != piZeroCombos.end(); ++piZeroCombo) {
142 
143  // Output tau
144  RecoTauConstructor tau(jet, getPFCands(), true);
145  // Reserve space in our collections
147  RecoTauConstructor::kChargedHadron, tracksToBuild);
148  tau.reserve(
150  RecoTauConstructor::kGamma, 2*piZerosToBuild); // k-factor = 2
151  tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
152 
153  // FIXME - are all these reserves okay? will they get propagated to the
154  // dataformat size if they are wrong?
155  tau.reserve(
157  RecoTauConstructor::kChargedHadron, pfchs.size() - tracksToBuild);
160  (cleanPiZeros.size() - piZerosToBuild)*2);
162  (cleanPiZeros.size() - piZerosToBuild));
163 
164  // Set signal and isolation components for charged hadrons, after
165  // converting them to a PFCandidateRefVector
166  tau.addPFCands(
168  trackCombo->combo_begin(), trackCombo->combo_end()
169  );
170 
171  // Get signal PiZero constituents and add them to the tau.
172  // The sub-gammas are automatically added.
173  tau.addPiZeros(
175  piZeroCombo->combo_begin(), piZeroCombo->combo_end()
176  );
177 
178  // Now build isolation collections
179  // Load our isolation tools
180  using namespace reco::tau::cone;
181  PFCandPtrDRFilter isolationConeFilter(tau.p4(), 0, isolationConeSize_);
182 
183  // Cross cleaning predicate. Remove any PFCandidatePtrs that are
184  // contained within existing PiZeros. This predicate will return false
185  // for any object that overlaps with cleanPiZeros.
186  xclean::CrossCleanPtrs pfCandXCleaner(cleanPiZeros);
187  // And this cleaning filter predicate with our Iso cone filter
189  pfCandFilter(isolationConeFilter, pfCandXCleaner);
190 
191  PiZeroDRFilter isolationConeFilterPiZero(
192  tau.p4(), 0, isolationConeSize_);
193 
194  // Additionally make predicates to select the different PF object types
195  // of the regional junk objects to add
197  PFCandPtrDRFilter> RegionalJunkConeAndIdFilter;
198 
200  pfchCandSelector(reco::PFCandidate::h);
202  pfgammaCandSelector(reco::PFCandidate::gamma);
204  pfnhCandSelector(reco::PFCandidate::h0);
205 
206  RegionalJunkConeAndIdFilter pfChargedJunk(
207  pfchCandSelector, // select charged stuff from junk
208  isolationConeFilter // only take those in iso cone
209  );
210 
211  RegionalJunkConeAndIdFilter pfGammaJunk(
212  pfgammaCandSelector, // select gammas from junk
213  isolationConeFilter // only take those in iso cone
214  );
215 
216  RegionalJunkConeAndIdFilter pfNeutralJunk(
217  pfnhCandSelector, // select neutral stuff from junk
218  isolationConeFilter // select stuff in iso cone
219  );
220 
221  // Filter the isolation candidates in a DR cone
222  tau.addPFCands(
224  boost::make_filter_iterator(
225  pfCandFilter,
226  trackCombo->remainder_begin(), trackCombo->remainder_end()),
227  boost::make_filter_iterator(
228  pfCandFilter,
229  trackCombo->remainder_end(), trackCombo->remainder_end())
230  );
231 
232  // Add all the candidates that weren't included in the combinatoric
233  // generation
234  tau.addPFCands(
236  boost::make_filter_iterator(
237  pfCandFilter,
238  pfch_end, pfchs.end()),
239  boost::make_filter_iterator(
240  pfCandFilter,
241  pfchs.end(), pfchs.end())
242  );
243  // Add all charged candidates that are in the iso cone but weren't in the
244  // original PFJet
245  tau.addPFCands(
247  boost::make_filter_iterator(
248  pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
249  boost::make_filter_iterator(
250  pfChargedJunk, regionalJunk.end(), regionalJunk.end())
251  );
252 
253  // Add all gammas that are in the iso cone but weren't in the
254  // orginal PFJet
255  tau.addPFCands(
257  boost::make_filter_iterator(
258  pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
259  boost::make_filter_iterator(
260  pfGammaJunk, regionalJunk.end(), regionalJunk.end())
261  );
262 
263  // Add all the netural hadron candidates to the isolation collection
264  tau.addPFCands(
266  boost::make_filter_iterator(
267  pfCandFilter,
268  pfnhs.begin(), pfnhs.end()),
269  boost::make_filter_iterator(
270  pfCandFilter,
271  pfnhs.end(), pfnhs.end())
272  );
273  // Add all the netural hadrons from the region collection that are in
274  // the iso cone to the tau
275  tau.addPFCands(
277  boost::make_filter_iterator(
278  pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
279  boost::make_filter_iterator(
280  pfNeutralJunk, regionalJunk.end(), regionalJunk.end())
281  );
282 
283  tau.addPiZeros(
285  boost::make_filter_iterator(
286  isolationConeFilterPiZero,
287  piZeroCombo->remainder_begin(), piZeroCombo->remainder_end()),
288  boost::make_filter_iterator(
289  isolationConeFilterPiZero,
290  piZeroCombo->remainder_end(), piZeroCombo->remainder_end())
291  );
292 
293  tau.addPiZeros(
295  boost::make_filter_iterator(
296  isolationConeFilterPiZero,
297  piZero_end, cleanPiZeros.end()),
298  boost::make_filter_iterator(
299  isolationConeFilterPiZero,
300  cleanPiZeros.end(), cleanPiZeros.end())
301  );
302 
303  output.push_back(tau.get(true));
304  }
305  }
306  }
307  return output.release();
308 }
309 }} // end namespace reco::tau
310 
314  "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.
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.
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)
void reservePiZero(Region region, size_t size)
Reserve a set amount of space for the PiZeros.
std::vector< PFCandidatePtr > pfChargedCands(const PFJet &jet, bool sort=true)
Extract all non-neutral candidates from a PFJet.
#define DEFINE_EDM_PLUGIN(factory, type, name)
const reco::VertexRef & primaryVertex() const
Get primary vertex associated to this event.
Transform a pizero to remove given candidates.