CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauChargedHadronProducer.cc
Go to the documentation of this file.
1 /*
2  * PFRecoTauChargedHadronProducer
3  *
4  * Author: Christian Veelken, LLR
5  *
6  * Associates reconstructed ChargedHadrons to PFJets. The ChargedHadrons are built using one
7  * or more RecoTauBuilder plugins. Any overlaps (ChargedHadrons sharing tracks)
8  * are removed, with the best ChargedHadron candidates taken. The 'best' are defined
9  * via the input list of PFRecoTauChargedHadronQualityPlugins, which form a
10  * lexicograpical ranking.
11  *
12  */
13 
18 
21 
26 
37 
39 
40 #include <boost/ptr_container/ptr_vector.hpp>
41 #include <boost/ptr_container/ptr_list.hpp>
42 #include <boost/foreach.hpp>
43 
44 #include <string>
45 #include <vector>
46 #include <list>
47 #include <set>
48 #include <algorithm>
49 #include <functional>
50 #include <math.h>
51 
53 {
54 public:
57 
60  void produce(edm::Event& evt, const edm::EventSetup& es);
61  template <typename T>
62  void print(const T& chargedHadrons);
63 
64  private:
65  typedef boost::ptr_vector<Builder> builderList;
66  typedef boost::ptr_vector<Ranker> rankerList;
67  typedef boost::ptr_vector<reco::PFRecoTauChargedHadron> ChargedHadronVector;
68  typedef boost::ptr_list<reco::PFRecoTauChargedHadron> ChargedHadronList;
69 
71 
73 
74  // input jet collection
77 
78  // plugins for building and ranking ChargedHadron candidates
81 
82  std::auto_ptr<ChargedHadronPredicate> predicate_;
83 
84  // output selector
85  std::auto_ptr<StringCutObjectSelector<reco::PFRecoTauChargedHadron> > outputSelector_;
86 
87  // flag to enable/disable debug print-out
89 };
90 
92  : moduleLabel_(cfg.getParameter<std::string>("@module_label"))
93 {
94  srcJets_ = cfg.getParameter<edm::InputTag>("jetSrc");
95  Jets_token = consumes<reco::CandidateView>(srcJets_);
96  verbosity_ = ( cfg.exists("verbosity") ) ?
97  cfg.getParameter<int>("verbosity") : 0;
98 
99  // get set of ChargedHadron builder plugins
100  edm::VParameterSet psets_builders = cfg.getParameter<edm::VParameterSet>("builders");
101  for ( edm::VParameterSet::const_iterator pset = psets_builders.begin();
102  pset != psets_builders.end(); ++pset ) {
103  std::string pluginType = pset->getParameter<std::string>("plugin");
104  edm::ParameterSet pset_modified = (*pset);
105  pset_modified.addParameter<int>("verbosity", verbosity_);
106  builders_.push_back(PFRecoTauChargedHadronBuilderPluginFactory::get()->create(pluginType, pset_modified, consumesCollector()));
107  }
108 
109  // get set of plugins for ranking ChargedHadrons in quality
110  edm::VParameterSet psets_rankers = cfg.getParameter<edm::VParameterSet>("ranking");
111  for ( edm::VParameterSet::const_iterator pset = psets_rankers.begin();
112  pset != psets_rankers.end(); ++pset ) {
113  std::string pluginType = pset->getParameter<std::string>("plugin");
114  edm::ParameterSet pset_modified = (*pset);
115  pset_modified.addParameter<int>("verbosity", verbosity_);
116  rankers_.push_back(PFRecoTauChargedHadronQualityPluginFactory::get()->create(pluginType, pset_modified));
117  }
118 
119  // build the sorting predicate
120  predicate_ = std::auto_ptr<ChargedHadronPredicate>(new ChargedHadronPredicate(rankers_));
121 
122  // check if we want to apply a final output selection
123  if ( cfg.exists("outputSelection") ) {
124  std::string selection = cfg.getParameter<std::string>("outputSelection");
125  if ( selection != "" ) {
127  }
128  }
129 
130  produces<reco::PFJetChargedHadronAssociation>();
131 }
132 
134 {
135  if ( verbosity_ ) {
136  edm::LogPrint("PFRecoTauChHProducer")<< "<PFRecoTauChargedHadronProducer::produce>:" ;
137  edm::LogPrint("PFRecoTauChHProducer")<< " moduleLabel = " << moduleLabel_ ;
138  }
139 
140  // give each of our plugins a chance at doing something with the edm::Event
141  BOOST_FOREACH( Builder& builder, builders_ ) {
142  builder.setup(evt, es);
143  }
144 
145  // get a view of our jets via the base candidates
147  evt.getByToken(Jets_token, jets);
148 
149  // convert the view to a RefVector of actual PFJets
150  reco::PFJetRefVector pfJets = reco::tau::castView<reco::PFJetRefVector>(jets);
151 
152  // make our association
153  std::auto_ptr<reco::PFJetChargedHadronAssociation> pfJetChargedHadronAssociations;
154 
155 
156  if ( pfJets.size() ) {
157  edm::Handle<reco::PFJetCollection> pfJetCollectionHandle;
158  evt.get(pfJets.id(), pfJetCollectionHandle);
159  pfJetChargedHadronAssociations.reset(new reco::PFJetChargedHadronAssociation(reco::PFJetRefProd(pfJetCollectionHandle)));
160  } else {
161  pfJetChargedHadronAssociations.reset(new reco::PFJetChargedHadronAssociation);
162  }
163 
164  // loop over our jets
165  BOOST_FOREACH( const reco::PFJetRef& pfJet, pfJets ) {
166 
167  // build global list of ChargedHadron candidates for each jet
168  ChargedHadronList uncleanedChargedHadrons;
169 
170  // merge candidates reconstructed by all desired algorithm plugins
171  BOOST_FOREACH( const Builder& builder, builders_ ) {
172  try {
173  ChargedHadronVector result(builder(*pfJet));
174  if ( verbosity_ ) {
175  edm::LogPrint("PFRecoTauChHProducer")<< "result of builder = " << builder.name() << ":" ;
176  print(result);
177  }
178  uncleanedChargedHadrons.transfer(uncleanedChargedHadrons.end(), result);
179  } catch ( cms::Exception& exception ) {
180  edm::LogError("BuilderPluginException")
181  << "Exception caught in builder plugin " << builder.name()
182  << ", rethrowing" << std::endl;
183  throw exception;
184  }
185  }
186 
187  // rank the candidates according to our quality plugins
188  uncleanedChargedHadrons.sort(*predicate_);
189 
190  // define collection of cleaned ChargedHadrons;
191  std::vector<reco::PFRecoTauChargedHadron> cleanedChargedHadrons;
192 
193  // keep track of neutral PFCandidates, charged PFCandidates and tracks "used" by ChargedHadron candidates in the clean collection
194  typedef std::pair<double, double> etaPhiPair;
195  std::list<etaPhiPair> tracksInCleanCollection;
196  std::set<reco::PFCandidatePtr> neutralPFCandsInCleanCollection;
197 
198  while ( uncleanedChargedHadrons.size() >= 1 ) {
199 
200  // get next best ChargedHadron candidate
201  std::auto_ptr<reco::PFRecoTauChargedHadron> nextChargedHadron(uncleanedChargedHadrons.pop_front().release());
202  if ( verbosity_ ) {
203  edm::LogPrint("PFRecoTauChHProducer")<< "processing nextChargedHadron:" ;
204  edm::LogPrint("PFRecoTauChHProducer")<< (*nextChargedHadron);
205  }
206 
207  // discard candidates which fail final output selection
208  if ( !(*outputSelector_)(*nextChargedHadron) ) continue;
209 
210  const reco::Track* track = 0;
211  if ( nextChargedHadron->getChargedPFCandidate().isNonnull() ) {
212  const reco::PFCandidatePtr& chargedPFCand = nextChargedHadron->getChargedPFCandidate();
213  if ( chargedPFCand->trackRef().isNonnull() ) track = chargedPFCand->trackRef().get();
214  else if ( chargedPFCand->muonRef().isNonnull() && chargedPFCand->muonRef()->innerTrack().isNonnull() ) track = chargedPFCand->muonRef()->innerTrack().get();
215  else if ( chargedPFCand->muonRef().isNonnull() && chargedPFCand->muonRef()->globalTrack().isNonnull() ) track = chargedPFCand->muonRef()->globalTrack().get();
216  else if ( chargedPFCand->muonRef().isNonnull() && chargedPFCand->muonRef()->outerTrack().isNonnull() ) track = chargedPFCand->muonRef()->outerTrack().get();
217  else if ( chargedPFCand->gsfTrackRef().isNonnull() ) track = chargedPFCand->gsfTrackRef().get();
218  }
219  if ( nextChargedHadron->getTrack().isNonnull() && !track ) {
220  track = nextChargedHadron->getTrack().get();
221  }
222 
223  // discard candidate in case its track is "used" by any ChargedHadron in the clean collection
224  bool isTrack_overlap = false;
225  if ( track ) {
226  double track_eta = track->eta();
227  double track_phi = track->phi();
228  for ( std::list<etaPhiPair>::const_iterator trackInCleanCollection = tracksInCleanCollection.begin();
229  trackInCleanCollection != tracksInCleanCollection.end(); ++trackInCleanCollection ) {
230  double dR = deltaR(track_eta, track_phi, trackInCleanCollection->first, trackInCleanCollection->second);
231  if ( dR < 1.e-4 ) isTrack_overlap = true;
232  }
233  }
234  if ( verbosity_ ) {
235  edm::LogPrint("PFRecoTauChHProducer")<< "isTrack_overlap = " << isTrack_overlap ;
236  }
237  if ( isTrack_overlap ) continue;
238 
239  // discard ChargedHadron candidates without track in case they are close to neutral PFCandidates "used" by ChargedHadron candidates in the clean collection
240  bool isNeutralPFCand_overlap = false;
241  if ( nextChargedHadron->algoIs(reco::PFRecoTauChargedHadron::kPFNeutralHadron) ) {
242  for ( std::set<reco::PFCandidatePtr>::const_iterator neutralPFCandInCleanCollection = neutralPFCandsInCleanCollection.begin();
243  neutralPFCandInCleanCollection != neutralPFCandsInCleanCollection.end(); ++neutralPFCandInCleanCollection ) {
244  if ( (*neutralPFCandInCleanCollection) == nextChargedHadron->getChargedPFCandidate() ) isNeutralPFCand_overlap = true;
245  }
246  }
247  if ( verbosity_ ) {
248  edm::LogPrint("PFRecoTauChHProducer")<< "isNeutralPFCand_overlap = " << isNeutralPFCand_overlap ;
249  }
250  if ( isNeutralPFCand_overlap ) continue;
251 
252  // find neutral PFCandidates that are not "used" by any ChargedHadron in the clean collection
253  std::vector<reco::PFCandidatePtr> uniqueNeutralPFCands;
254  std::set_difference(nextChargedHadron->getNeutralPFCandidates().begin(),
255  nextChargedHadron->getNeutralPFCandidates().end(),
256  neutralPFCandsInCleanCollection.begin(),
257  neutralPFCandsInCleanCollection.end(),
258  std::back_inserter(uniqueNeutralPFCands));
259 
260  if ( uniqueNeutralPFCands.size() == nextChargedHadron->getNeutralPFCandidates().size() ) { // all neutral PFCandidates are unique, add ChargedHadron candidate to clean collection
261  if ( track ) tracksInCleanCollection.push_back(std::make_pair(track->eta(), track->phi()));
262  neutralPFCandsInCleanCollection.insert(nextChargedHadron->getNeutralPFCandidates().begin(), nextChargedHadron->getNeutralPFCandidates().end());
263  if ( verbosity_ ) {
264  edm::LogPrint("PFRecoTauChHProducer")<< "--> adding nextChargedHadron to output collection." ;
265  }
266  cleanedChargedHadrons.push_back(*nextChargedHadron);
267  } else { // remove overlapping neutral PFCandidates, reevaluate ranking criterion and process ChargedHadron candidate again
268  nextChargedHadron->neutralPFCandidates_.clear();
269  BOOST_FOREACH( const reco::PFCandidatePtr& neutralPFCand, uniqueNeutralPFCands ) {
270  nextChargedHadron->neutralPFCandidates_.push_back(neutralPFCand);
271  }
272  // update ChargedHadron four-momentum
273  reco::tau::setChargedHadronP4(*nextChargedHadron);
274  // reinsert ChargedHadron candidate into list of uncleaned candidates,
275  // at position according to new rank
276  ChargedHadronList::iterator insertionPoint = std::lower_bound(uncleanedChargedHadrons.begin(), uncleanedChargedHadrons.end(), *nextChargedHadron, *predicate_);
277  if ( verbosity_ ) {
278  edm::LogPrint("PFRecoTauChHProducer")<< "--> removing non-unique neutral PFCandidates and reinserting nextChargedHadron in uncleaned collection." ;
279  }
280  uncleanedChargedHadrons.insert(insertionPoint, nextChargedHadron);
281  }
282  }
283 
284  if ( verbosity_ ) {
285  print(cleanedChargedHadrons);
286  }
287 
288  // add ChargedHadron-to-jet association
289  pfJetChargedHadronAssociations->setValue(pfJet.key(), cleanedChargedHadrons);
290  }
291 
292  evt.put(pfJetChargedHadronAssociations);
293 }
294 
295 template <typename T>
296 void PFRecoTauChargedHadronProducer::print(const T& chargedHadrons)
297 {
298  for ( typename T::const_iterator chargedHadron = chargedHadrons.begin();
299  chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
300  edm::LogPrint("PFRecoTauChHProducer") << (*chargedHadron);
301  edm::LogPrint("PFRecoTauChHProducer") << "Rankers:" ;
302  for ( rankerList::const_iterator ranker = rankers_.begin();
303  ranker != rankers_.end(); ++ranker) {
304  const unsigned width = 25;
305  edm::LogPrint("PFRecoTauChHProducer") << " " << std::setiosflags(std::ios::left) << std::setw(width) << ranker->name()
306  << " " << std::resetiosflags(std::ios::left) << std::setprecision(3) << (*ranker)(*chargedHadron) << std::endl;
307  }
308  }
309 }
310 
312 
T getParameter(std::string const &) const
tuple cfg
Definition: looper.py:293
reco::tau::RecoTauLexicographicalRanking< rankerList, reco::PFRecoTauChargedHadron > ChargedHadronPredicate
void produce(edm::Event &evt, const edm::EventSetup &es)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:464
PFRecoTauChargedHadronProducer(const edm::ParameterSet &cfg)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:33
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:160
selection
main part
Definition: corrVsCorr.py:98
bool exists(std::string const &parameterName) const
checks if a parameter exists
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:632
key_type key() const
Accessor for product key.
Definition: Ref.h:264
edm::EDGetTokenT< reco::CandidateView > Jets_token
void setup(edm::Event &, const edm::EventSetup &)
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:638
reco::tau::PFRecoTauChargedHadronBuilderPlugin Builder
ProductID id() const
Accessor for product ID.
Definition: RefVector.h:114
boost::ptr_vector< reco::PFRecoTauChargedHadron > ChargedHadronVector
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:120
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
std::auto_ptr< ChargedHadronPredicate > predicate_
vector< PseudoJet > jets
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:144
tuple result
Definition: query.py:137
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:333
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:169
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
reco::tau::PFRecoTauChargedHadronQualityPlugin Ranker
std::auto_ptr< StringCutObjectSelector< reco::PFRecoTauChargedHadron > > outputSelector_
boost::ptr_list< reco::PFRecoTauChargedHadron > ChargedHadronList
size_type size() const
Size of the RefVector.
Definition: RefVector.h:99
const std::string & name() const
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
moduleLabel_(iConfig.getParameter< string >("@module_label"))
long double T
tuple pfJets
Definition: pfJets_cff.py:8
SurfaceDeformation * create(int type, const std::vector< double > &params)
T get(const Candidate &c)
Definition: component.h:55