CMS 3D CMS Logo

RecoTauCleaner.cc
Go to the documentation of this file.
1 /*
2  * RecoTauCleaner
3  *
4  * Author: Evan K. Friis, UC Davis
5  *
6  * Given a input collection of PFTaus, produces an output collection of PFTaus
7  * such that no two PFTaus come from the same PFJet. If multiple taus in the
8  * collection come from the same PFJet, (dirty) they are ordered according to a
9  * list of cleaners. Each cleaner is a RecoTauCleanerPlugin, and returns a
10  * double corresponding to the 'quality' for a given tau - an example would be
11  * the level of isolation. The set of dirty taus is then ranked
12  * lexicographically by these cleaners, and the best one is placed in the
13  * output collection.
14  *
15  */
16 
17 #include <boost/ptr_container/ptr_vector.hpp>
18 #include <algorithm>
19 #include <memory>
20 
26 
30 
37 
39 
40 template<typename Prod>
42 {
45  {
46  std::shared_ptr<Cleaner> plugin_;
47  float tolerance_;
48  };
49  typedef std::vector<std::unique_ptr<CleanerEntryType> > CleanerList;
50  // Define our output type - i.e. reco::PFTau OR reco::PFTauRef
51  typedef typename Prod::value_type output_type;
52 
53  // Predicate that determines if two taus 'overlap' i.e. share a base PFJet
55  {
56  public:
57  bool operator()(const reco::PFTauRef& a, const reco::PFTauRef& b) const { return (a->jetRef() == b->jetRef()); }
58  };
59 
60  public:
61  explicit RecoTauCleanerImpl(const edm::ParameterSet& pset);
62  ~RecoTauCleanerImpl() override;
63  void produce(edm::Event& evt, const edm::EventSetup& es) override;
64 
65  private:
67  CleanerList cleaners_;
68  // Optional selection on the output of the taus
69  std::unique_ptr<const StringCutObjectSelector<reco::PFTau> > outputSelector_;
72 };
73 
74 template<typename Prod>
76 {
77  tauSrc_ = pset.getParameter<edm::InputTag>("src");
78  tau_token=consumes<reco::PFTauCollection>(tauSrc_);
79  // Build our list of quality plugins
80  typedef std::vector<edm::ParameterSet> VPSet;
81  // Get each of our tau builders
82  const VPSet& cleaners = pset.getParameter<VPSet>("cleaners");
83  for ( VPSet::const_iterator cleanerPSet = cleaners.begin();
84  cleanerPSet != cleaners.end(); ++cleanerPSet ) {
85  CleanerEntryType* cleanerEntry = new CleanerEntryType();
86  // Get plugin name
87  const std::string& pluginType = cleanerPSet->getParameter<std::string>("plugin");
88  // Build the plugin
89  cleanerEntry->plugin_.reset(RecoTauCleanerPluginFactory::get()->create(pluginType, *cleanerPSet, consumesCollector()));
90  cleanerEntry->tolerance_ = ( cleanerPSet->exists("tolerance") ) ?
91  cleanerPSet->getParameter<double>("tolerance") : 0.;
92  cleaners_.emplace_back(cleanerEntry);
93  }
94 
95  // Check if we want to apply a final output selection
96  if ( pset.exists("outputSelection") ) {
97  std::string selection = pset.getParameter<std::string>("outputSelection");
98  if ( selection != "" ) {
100  }
101  }
102 
103  // Enable/disable debug output
104  verbosity_ = ( pset.exists("verbosity") ) ?
105  pset.getParameter<int>("verbosity") : 0;
106 
107  // Build the predicate that ranks our taus.
108  produces<Prod>();
109 }
110 
111 template<typename Prod>
113 {
114 }
115 
116 namespace {
117 // Template to convert a ref to desired output type
118 template<typename T> const T convert(const reco::PFTauRef &tau);
119 
120  //template<> const edm::RefToBase<reco::PFTau>
121  //convert<edm::RefToBase<reco::PFTau> >(const reco::PFTauRef &tau) {
122  // return edm::RefToBase<reco::PFTau>(tau);
123  //}
124 
125 template<> const reco::PFTauRef
126 convert<reco::PFTauRef>(const reco::PFTauRef &tau) { return tau; }
127 
128 template<> const reco::PFTau
129 convert<reco::PFTau>(const reco::PFTauRef &tau) { return *tau; }
130 }
131 
132 namespace
133 {
134  template <typename T>
135  std::string format_vT(const std::vector<T>& vT)
136  {
137  std::ostringstream os;
138  os << "{ ";
139  unsigned numEntries = vT.size();
140  for ( unsigned iEntry = 0; iEntry < numEntries; ++iEntry ) {
141  os << vT[iEntry];
142  if ( iEntry < (numEntries - 1) ) os << ", ";
143  }
144  os << " }";
145  return os.str();
146  }
147 
148  struct PFTauRankType
149  {
150  PFTauRankType(const reco::PFTauRef& tauRef)
151  : idx_(tauRef.key()),
152  tauRef_(tauRef)
153  {}
154  ~PFTauRankType() {}
155  void print(const std::string& label) const
156  {
157  std::cout << label << " (" << tauRef_.id() << ":" << tauRef_.key() << ", idx = " << idx_ << "):";
158  assert(tauRef_.key() == idx_);
159  std::cout << " Pt = " << tauRef_->pt() << ", eta = " << tauRef_->eta() << ", phi = " << tauRef_->phi() << ", mass = " << tauRef_->mass() << " (decayMode = " << tauRef_->decayMode() << ")";
160  std::cout << std::endl;
161  std::cout << "associated jet:";
162  if ( tauRef_->jetRef().isNonnull() ) {
163  std::cout << " Pt = " << tauRef_->jetRef()->pt() << ", eta = " << tauRef_->jetRef()->eta() << ", phi = " << tauRef_->jetRef()->phi()
164  << ", mass = " << tauRef_->jetRef()->mass() << ", area = " << tauRef_->jetRef()->jetArea();
165  }
166  else std::cout << " N/A";
167  std::cout << std::endl;
168  const std::vector<reco::PFRecoTauChargedHadron>& signalTauChargedHadronCandidates = tauRef_->signalTauChargedHadronCandidates();
169  size_t numChargedHadrons = signalTauChargedHadronCandidates.size();
170  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
171  const reco::PFRecoTauChargedHadron& chargedHadron = signalTauChargedHadronCandidates.at(iChargedHadron);
172  std::cout << " chargedHadron #" << iChargedHadron << ":" << std::endl;
173  chargedHadron.print(std::cout);
174  }
175  const std::vector<reco::RecoTauPiZero>& signalPiZeroCandidates = tauRef_->signalPiZeroCandidates();
176  size_t numPiZeros = signalPiZeroCandidates.size();
177  std::cout << "signalPiZeroCandidates = " << numPiZeros << std::endl;
178  for ( size_t iPiZero = 0; iPiZero < numPiZeros; ++iPiZero ) {
179  const reco::RecoTauPiZero& piZero = signalPiZeroCandidates.at(iPiZero);
180  std::cout << " piZero #" << iPiZero << ": Pt = " << piZero.pt() << ", eta = " << piZero.eta() << ", phi = " << piZero.phi() << ", mass = " << piZero.mass() << std::endl;
181  }
182  const std::vector<reco::PFCandidatePtr>& isolationPFCands = tauRef_->isolationPFCands();
183  size_t numPFCands = isolationPFCands.size();
184  std::cout << "isolationPFCands = " << numPFCands << std::endl;
185  for ( size_t iPFCand = 0; iPFCand < numPFCands; ++iPFCand ) {
186  const reco::PFCandidatePtr& pfCand = isolationPFCands.at(iPFCand);
187  std::cout << " pfCand #" << iPFCand << " (" << pfCand.id() << ":" << pfCand.key() << "):"
188  << " Pt = " << pfCand->pt() << ", eta = " << pfCand->eta() << ", phi = " << pfCand->phi() << std::endl;
189  }
190  std::cout << " ranks = " << format_vT(ranks_) << std::endl;
191  std::cout << " tolerances = " << format_vT(tolerances_) << std::endl;
192  }
193  size_t idx_;
194  reco::PFTauRef tauRef_;
195  size_t N_;
196  std::vector<float> ranks_;
197  std::vector<float> tolerances_;
198  };
199 
200  bool isHigherRank(const PFTauRankType* tau1, const PFTauRankType* tau2)
201  {
202  //std::cout << "<isHigherRank>:" << std::endl;
203  //std::cout << "tau1 @ " << tau1;
204  //tau1->print("");
205  //std::cout << "tau2 @ " << tau2;
206  //tau2->print("");
207  assert(tau1->N_ == tau1->ranks_.size());
208  assert(tau1->N_ == tau2->ranks_.size());
209  assert(tau1->N_ == tau1->tolerances_.size());
210  for ( size_t i = 0; i < tau1->N_; ++i ) {
211  const float& val1 = tau1->ranks_[i];
212  const float& val2 = tau2->ranks_[i];
213  double av = 0.5*(val1 + val2);
214  double thresh = av*tau1->tolerances_[i];
215  if ( val1 < (val2 - thresh) ) return true;
216  else if ( val2 < (val1 - thresh) ) return false;
217  }
218  return true;
219  }
220 }
221 
222 template<typename Prod>
224 {
225  if ( verbosity_ ) {
226  std::cout << "<RecoTauCleanerImpl::produce>:" << std::endl;
227  }
228 
229  // Update all our cleaners with the event info if they need it
230  for ( typename CleanerList::iterator cleaner = cleaners_.begin();
231  cleaner != cleaners_.end(); ++cleaner ) {
232  (*cleaner)->plugin_->setup(evt, es);
233  }
234 
235  // Get the input collection of all taus. Some are from the same PFJet. We must clean them.
237  evt.getByToken(tau_token, inputTaus);
238 
239  // Sort the input tau refs according to our predicate
240  std::list<PFTauRankType*> rankedTaus;
241  size_t N = inputTaus->size();
242  for ( size_t idx = 0; idx < N; ++idx ) {
243  reco::PFTauRef inputRef(inputTaus, idx);
244  PFTauRankType* rankedTau = new PFTauRankType(inputRef);
245  rankedTau->N_ = cleaners_.size();
246  rankedTau->ranks_.reserve(rankedTau->N_);
247  rankedTau->tolerances_.reserve(rankedTau->N_);
248  for ( typename CleanerList::const_iterator cleaner = cleaners_.begin();
249  cleaner != cleaners_.end(); ++cleaner ) {
250  rankedTau->ranks_.push_back((*(*cleaner)->plugin_)(inputRef));
251  rankedTau->tolerances_.push_back((*cleaner)->tolerance_);
252  }
253  if ( verbosity_ ) {
254  std::ostringstream os;
255  os << "rankedTau #" << idx;
256  rankedTau->print(os.str());
257  }
258  rankedTaus.push_back(rankedTau);
259  }
260  rankedTaus.sort(isHigherRank);
261 
262  // Make an STL algorithm friendly vector of refs
263  typedef std::vector<reco::PFTauRef> PFTauRefs;
264  PFTauRefs dirty(inputTaus->size());
265  size_t idx_sorted = 0;
266  for ( std::list<PFTauRankType*>::const_iterator rankedTau = rankedTaus.begin();
267  rankedTau != rankedTaus.end(); ++rankedTau ) {
268  dirty[idx_sorted] = (*rankedTau)->tauRef_;
269  if ( verbosity_ ) {
270  std::cout << "dirty[" << idx_sorted << "] = " << dirty[idx_sorted].id() << ":" << dirty[idx_sorted].key() << std::endl;
271  }
272  delete (*rankedTau);
273  ++idx_sorted;
274  }
275 
276  // Clean the taus, ensuring that only one tau per jet is produced
277  PFTauRefs cleanTaus = reco::tau::cleanOverlaps<PFTauRefs, RemoveDuplicateJets>(dirty);
278 
279  // create output collection
280  auto output = std::make_unique<Prod>();
281  //output->reserve(cleanTaus.size());
282 
283  // Copy clean refs into output
284  for ( PFTauRefs::const_iterator tau = cleanTaus.begin();
285  tau != cleanTaus.end(); ++tau ) {
286  // If we are applying an output selection, check if it passes
287  bool selected = true;
288  if ( outputSelector_.get() && !(*outputSelector_)(**tau) ) {
289  selected = false;
290  }
291  if ( selected ) {
292  output->push_back(convert<output_type>(*tau));
293  }
294  }
295  evt.put(std::move(output));
296 }
297 
300 
302 
305 
T getParameter(std::string const &) const
RecoTauCleanerImpl< reco::PFTauRefVector > RecoTauRefCleaner
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
double eta() const final
momentum pseudorapidity
def create(alignables, pedeDump, additionalData, outputFile, config)
key_type key() const
Definition: Ptr.h:185
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
bool operator()(const reco::PFTauRef &a, const reco::PFTauRef &b) const
edm::InputTag tauSrc_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::vector< std::unique_ptr< CleanerEntryType > > CleanerList
selection
main part
Definition: corrVsCorr.py:98
bool exists(std::string const &parameterName) const
checks if a parameter exists
double pt() const final
transverse momentum
key_type key() const
Accessor for product key.
Definition: Ref.h:265
RecoTauCleanerImpl< reco::PFTauCollection > RecoTauCleaner
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
edm::EDGetTokenT< reco::PFTauCollection > tau_token
void print(std::ostream &stream=std::cout) const
CleanerList cleaners_
Long64_t numEntries(TFile *hdl, std::string const &trname)
Definition: CollUtil.cc:50
def convert(infile, ofile)
#define N
Definition: blowfish.cc:9
double b
Definition: hdecay.h:120
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:180
reco::tau::RecoTauCleanerPlugin Cleaner
double a
Definition: hdecay.h:121
std::unique_ptr< const StringCutObjectSelector< reco::PFTau > > outputSelector_
void produce(edm::Event &evt, const edm::EventSetup &es) override
long double T
double phi() const final
momentum azimuthal angle
Prod::value_type output_type
~RecoTauCleanerImpl() override
def move(src, dest)
Definition: eostools.py:510
T get(const Candidate &c)
Definition: component.h:55
RecoTauCleanerImpl(const edm::ParameterSet &pset)
double mass() const final
mass
std::shared_ptr< Cleaner > plugin_