CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  boost::shared_ptr<Cleaner> plugin_;
47  float tolerance_;
48  };
49  typedef std::vector<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) { return (a->jetRef() == b->jetRef()); }
58  };
59 
60  public:
61  explicit RecoTauCleanerImpl(const edm::ParameterSet& pset);
63  void produce(edm::Event& evt, const edm::EventSetup& es) override;
64 
65  private:
68  // Optional selection on the output of the taus
69  std::auto_ptr<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_.push_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 != "" ) {
99  outputSelector_.reset(new StringCutObjectSelector<reco::PFTau>(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  for ( typename CleanerList::const_iterator it = cleaners_.begin();
115  it != cleaners_.end(); ++it ) {
116  delete (*it);
117  }
118 }
119 
120 namespace {
121 // Template to convert a ref to desired output type
122 template<typename T> const T convert(const reco::PFTauRef &tau);
123 
124 template<> const edm::RefToBase<reco::PFTau>
125 convert<edm::RefToBase<reco::PFTau> >(const reco::PFTauRef &tau) {
127 }
128 
129 template<> const reco::PFTauRef
130 convert<reco::PFTauRef>(const reco::PFTauRef &tau) { return tau; }
131 
132 template<> const reco::PFTau
133 convert<reco::PFTau>(const reco::PFTauRef &tau) { return *tau; }
134 }
135 
136 namespace
137 {
138  template <typename T>
139  std::string format_vT(const std::vector<T>& vT)
140  {
141  std::ostringstream os;
142  os << "{ ";
143  unsigned numEntries = vT.size();
144  for ( unsigned iEntry = 0; iEntry < numEntries; ++iEntry ) {
145  os << vT[iEntry];
146  if ( iEntry < (numEntries - 1) ) os << ", ";
147  }
148  os << " }";
149  return os.str();
150  }
151 
152  struct PFTauRankType
153  {
154  PFTauRankType(const reco::PFTauRef& tauRef)
155  : idx_(tauRef.key()),
156  tauRef_(tauRef)
157  {}
158  ~PFTauRankType() {}
159  void print(const std::string& label) const
160  {
161  std::cout << label << " (" << tauRef_.id() << ":" << tauRef_.key() << ", idx = " << idx_ << "):";
162  assert(tauRef_.key() == idx_);
163  std::cout << " Pt = " << tauRef_->pt() << ", eta = " << tauRef_->eta() << ", phi = " << tauRef_->phi() << ", mass = " << tauRef_->mass() << " (decayMode = " << tauRef_->decayMode() << ")";
164  std::cout << std::endl;
165  std::cout << "associated jet:";
166  if ( tauRef_->jetRef().isNonnull() ) {
167  std::cout << " Pt = " << tauRef_->jetRef()->pt() << ", eta = " << tauRef_->jetRef()->eta() << ", phi = " << tauRef_->jetRef()->phi()
168  << ", mass = " << tauRef_->jetRef()->mass() << ", area = " << tauRef_->jetRef()->jetArea();
169  }
170  else std::cout << " N/A";
171  std::cout << std::endl;
172  const std::vector<reco::PFRecoTauChargedHadron>& signalTauChargedHadronCandidates = tauRef_->signalTauChargedHadronCandidates();
173  size_t numChargedHadrons = signalTauChargedHadronCandidates.size();
174  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
175  const reco::PFRecoTauChargedHadron& chargedHadron = signalTauChargedHadronCandidates.at(iChargedHadron);
176  std::cout << " chargedHadron #" << iChargedHadron << ":" << std::endl;
177  chargedHadron.print(std::cout);
178  }
179  const std::vector<reco::RecoTauPiZero>& signalPiZeroCandidates = tauRef_->signalPiZeroCandidates();
180  size_t numPiZeros = signalPiZeroCandidates.size();
181  std::cout << "signalPiZeroCandidates = " << numPiZeros << std::endl;
182  for ( size_t iPiZero = 0; iPiZero < numPiZeros; ++iPiZero ) {
183  const reco::RecoTauPiZero& piZero = signalPiZeroCandidates.at(iPiZero);
184  std::cout << " piZero #" << iPiZero << ": Pt = " << piZero.pt() << ", eta = " << piZero.eta() << ", phi = " << piZero.phi() << ", mass = " << piZero.mass() << std::endl;
185  }
186  const std::vector<reco::PFCandidatePtr>& isolationPFCands = tauRef_->isolationPFCands();
187  size_t numPFCands = isolationPFCands.size();
188  std::cout << "isolationPFCands = " << numPFCands << std::endl;
189  for ( size_t iPFCand = 0; iPFCand < numPFCands; ++iPFCand ) {
190  const reco::PFCandidatePtr& pfCand = isolationPFCands.at(iPFCand);
191  std::cout << " pfCand #" << iPFCand << " (" << pfCand.id() << ":" << pfCand.key() << "):"
192  << " Pt = " << pfCand->pt() << ", eta = " << pfCand->eta() << ", phi = " << pfCand->phi() << std::endl;
193  }
194  std::cout << " ranks = " << format_vT(ranks_) << std::endl;
195  std::cout << " tolerances = " << format_vT(tolerances_) << std::endl;
196  }
197  size_t idx_;
198  reco::PFTauRef tauRef_;
199  size_t N_;
200  std::vector<float> ranks_;
201  std::vector<float> tolerances_;
202  };
203 
204  bool isHigherRank(const PFTauRankType* tau1, const PFTauRankType* tau2)
205  {
206  //std::cout << "<isHigherRank>:" << std::endl;
207  //std::cout << "tau1 @ " << tau1;
208  //tau1->print("");
209  //std::cout << "tau2 @ " << tau2;
210  //tau2->print("");
211  assert(tau1->N_ == tau1->ranks_.size());
212  assert(tau1->N_ == tau2->ranks_.size());
213  assert(tau1->N_ == tau1->tolerances_.size());
214  for ( size_t i = 0; i < tau1->N_; ++i ) {
215  const float& val1 = tau1->ranks_[i];
216  const float& val2 = tau2->ranks_[i];
217  double av = 0.5*(val1 + val2);
218  double thresh = av*tau1->tolerances_[i];
219  if ( val1 < (val2 - thresh) ) return true;
220  else if ( val2 < (val1 - thresh) ) return false;
221  }
222  return true;
223  }
224 }
225 
226 template<typename Prod>
228 {
229  if ( verbosity_ ) {
230  std::cout << "<RecoTauCleanerImpl::produce>:" << std::endl;
231  }
232 
233  // Update all our cleaners with the event info if they need it
234  for ( typename CleanerList::iterator cleaner = cleaners_.begin();
235  cleaner != cleaners_.end(); ++cleaner ) {
236  (*cleaner)->plugin_->setup(evt, es);
237  }
238 
239  // Get the input collection of all taus. Some are from the same PFJet. We must clean them.
241  evt.getByToken(tau_token, inputTaus);
242 
243  // Sort the input tau refs according to our predicate
244  std::list<PFTauRankType*> rankedTaus;
245  size_t N = inputTaus->size();
246  for ( size_t idx = 0; idx < N; ++idx ) {
247  reco::PFTauRef inputRef(inputTaus, idx);
248  PFTauRankType* rankedTau = new PFTauRankType(inputRef);
249  rankedTau->N_ = cleaners_.size();
250  rankedTau->ranks_.reserve(rankedTau->N_);
251  rankedTau->tolerances_.reserve(rankedTau->N_);
252  for ( typename CleanerList::const_iterator cleaner = cleaners_.begin();
253  cleaner != cleaners_.end(); ++cleaner ) {
254  rankedTau->ranks_.push_back((*(*cleaner)->plugin_)(inputRef));
255  rankedTau->tolerances_.push_back((*cleaner)->tolerance_);
256  }
257  if ( verbosity_ ) {
258  std::ostringstream os;
259  os << "rankedTau #" << idx;
260  rankedTau->print(os.str());
261  }
262  rankedTaus.push_back(rankedTau);
263  }
264  rankedTaus.sort(isHigherRank);
265 
266  // Make an STL algorithm friendly vector of refs
267  typedef std::vector<reco::PFTauRef> PFTauRefs;
268  PFTauRefs dirty(inputTaus->size());
269  size_t idx_sorted = 0;
270  for ( std::list<PFTauRankType*>::const_iterator rankedTau = rankedTaus.begin();
271  rankedTau != rankedTaus.end(); ++rankedTau ) {
272  dirty[idx_sorted] = (*rankedTau)->tauRef_;
273  if ( verbosity_ ) {
274  std::cout << "dirty[" << idx_sorted << "] = " << dirty[idx_sorted].id() << ":" << dirty[idx_sorted].key() << std::endl;
275  }
276  delete (*rankedTau);
277  ++idx_sorted;
278  }
279 
280  // Clean the taus, ensuring that only one tau per jet is produced
281  PFTauRefs cleanTaus = reco::tau::cleanOverlaps<PFTauRefs, RemoveDuplicateJets>(dirty);
282 
283  // create output collection
284  std::auto_ptr<Prod> output(new Prod());
285  //output->reserve(cleanTaus.size());
286 
287  // Copy clean refs into output
288  for ( PFTauRefs::const_iterator tau = cleanTaus.begin();
289  tau != cleanTaus.end(); ++tau ) {
290  // If we are applying an output selection, check if it passes
291  bool selected = true;
292  if ( outputSelector_.get() && !(*outputSelector_)(**tau) ) {
293  selected = false;
294  }
295  if ( selected ) {
296  output->push_back(convert<output_type>(*tau));
297  }
298  }
299  evt.put(output);
300 }
301 
304 
306 
307 DEFINE_FWK_MODULE(RecoTauCleaner);
308 DEFINE_FWK_MODULE(RecoTauRefCleaner);
309 
T getParameter(std::string const &) const
RecoTauCleanerImpl< reco::PFTauRefVector > RecoTauRefCleaner
int i
Definition: DBlmapReader.cc:9
virtual float pt() const
transverse momentum
key_type key() const
Definition: Ptr.h:169
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:446
edm::InputTag tauSrc_
std::auto_ptr< StringCutObjectSelector< reco::PFTau > > outputSelector_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
virtual float phi() const
momentum azimuthal angle
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
Definition: print.cc:10
bool operator()(const reco::PFTauRef &a, const reco::PFTauRef &b)
selection
main part
Definition: corrVsCorr.py:98
bool exists(std::string const &parameterName) const
checks if a parameter exists
RecoTauCleanerImpl< reco::PFTauCollection > RecoTauCleaner
edm::EDGetTokenT< reco::PFTauCollection > tau_token
void print(std::ostream &stream=std::cout) const
CleanerList cleaners_
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
virtual float eta() const
momentum pseudorapidity
Long64_t numEntries(TFile *hdl, std::string const &trname)
Definition: CollUtil.cc:50
Container::value_type value_type
#define N
Definition: blowfish.cc:9
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
double b
Definition: hdecay.h:120
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:164
list key
Definition: combine.py:13
reco::tau::RecoTauCleanerPlugin Cleaner
double a
Definition: hdecay.h:121
virtual float mass() const
mass
tuple cout
Definition: gather_cfg.py:121
void produce(edm::Event &evt, const edm::EventSetup &es) override
boost::shared_ptr< Cleaner > plugin_
long double T
Prod::value_type output_type
SurfaceDeformation * create(int type, const std::vector< double > &params)
std::vector< CleanerEntryType * > CleanerList
T get(const Candidate &c)
Definition: component.h:55
RecoTauCleanerImpl(const edm::ParameterSet &pset)