CMS 3D CMS Logo

RecoTauPiZeroProducer.cc
Go to the documentation of this file.
1 /*
2  * RecoTauPiZeroProducer
3  *
4  * Author: Evan K. Friis, UC Davis
5  *
6  * Associates reconstructed PiZeros to PFJets. The PiZeros are built using one
7  * or more RecoTauBuilder plugins. Any overlaps (PiZeros sharing constituents)
8  * are removed, with the best PiZero candidates taken. The 'best' are defined
9  * via the input list of RecoTauPiZeroQualityPlugins, which form a
10  * lexicograpical ranking.
11  *
12  */
13 
14 #include <algorithm>
15 #include <functional>
16 #include <memory>
17 
26 
31 
36 
39 
41 public:
44 
46  ~RecoTauPiZeroProducer() override {}
47  void produce(edm::Event& evt, const edm::EventSetup& es) override;
48  void print(const std::vector<reco::RecoTauPiZero>& piZeros, std::ostream& out);
49 
50  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
51 
52 private:
53  typedef std::vector<std::unique_ptr<Ranker>> RankerList;
55  typedef std::list<std::unique_ptr<reco::RecoTauPiZero>> PiZeroList;
56 
58 
59  std::vector<std::unique_ptr<Builder>> builders_;
61  std::unique_ptr<PiZeroPredicate> predicate_;
62  double piZeroMass_;
63 
64  // Output selector
65  std::unique_ptr<StringCutObjectSelector<reco::RecoTauPiZero>> outputSelector_;
66 
67  //consumes interface
69 
70  double minJetPt_;
71  double maxJetAbsEta_;
72 
74 };
75 
77  cand_token = consumes<reco::JetView>(pset.getParameter<edm::InputTag>("jetSrc"));
78  minJetPt_ = pset.getParameter<double>("minJetPt");
79  maxJetAbsEta_ = pset.getParameter<double>("maxJetAbsEta");
80 
81  typedef std::vector<edm::ParameterSet> VPSet;
82  // Get the mass hypothesis for the pizeros
83  piZeroMass_ = pset.getParameter<double>("massHypothesis");
84 
85  // Get each of our PiZero builders
86  const VPSet& builders = pset.getParameter<VPSet>("builders");
87 
88  for (VPSet::const_iterator builderPSet = builders.begin(); builderPSet != builders.end(); ++builderPSet) {
89  // Get plugin name
90  const std::string& pluginType = builderPSet->getParameter<std::string>("plugin");
91  // Build the plugin
92  builders_.emplace_back(
93  RecoTauPiZeroBuilderPluginFactory::get()->create(pluginType, *builderPSet, consumesCollector()));
94  }
95 
96  // Get each of our quality rankers
97  const VPSet& rankers = pset.getParameter<VPSet>("ranking");
98  for (VPSet::const_iterator rankerPSet = rankers.begin(); rankerPSet != rankers.end(); ++rankerPSet) {
99  const std::string& pluginType = rankerPSet->getParameter<std::string>("plugin");
100  rankers_.emplace_back(RecoTauPiZeroQualityPluginFactory::get()->create(pluginType, *rankerPSet));
101  }
102 
103  // Build the sorting predicate
104  predicate_ = std::make_unique<PiZeroPredicate>(rankers_);
105 
106  // now all producers apply a final output selection
107  std::string selection = pset.getParameter<std::string>("outputSelection");
108  if (!selection.empty()) {
109  outputSelector_ = std::make_unique<StringCutObjectSelector<reco::RecoTauPiZero>>(selection);
110  }
111 
112  verbosity_ = pset.getParameter<int>("verbosity");
113 
114  produces<reco::JetPiZeroAssociation>();
115 }
116 
118  // Get a view of our jets via the base candidates
120  evt.getByToken(cand_token, jetView);
121 
122  // Give each of our plugins a chance at doing something with the edm::Event
123  for (auto& builder : builders_) {
124  builder->setup(evt, es);
125  }
126 
127  // Make our association
128  auto association = std::make_unique<reco::JetPiZeroAssociation>(reco::JetRefBaseProd(jetView));
129 
130  // Loop over our jets
131  size_t nJets = jetView->size();
132  for (size_t i = 0; i < nJets; ++i) {
133  const reco::JetBaseRef jet(jetView->refAt(i));
134 
135  if (jet->pt() - minJetPt_ < 1e-5)
136  continue;
137  if (std::abs(jet->eta()) - maxJetAbsEta_ > -1e-5)
138  continue;
139  // Build our global list of RecoTauPiZero
140  PiZeroList dirtyPiZeros;
141 
142  // Compute the pi zeros from this jet for all the desired algorithms
143  for (auto const& builder : builders_) {
144  try {
145  PiZeroVector result((*builder)(*jet));
146  std::move(result.begin(), result.end(), std::back_inserter(dirtyPiZeros));
147  } catch (cms::Exception& exception) {
148  edm::LogError("BuilderPluginException")
149  << "Exception caught in builder plugin " << builder->name() << ", rethrowing" << std::endl;
150  throw exception;
151  }
152  }
153  // Rank the candidates according to our quality plugins
154  dirtyPiZeros.sort([this](const auto& a, const auto& b) { return (*predicate_)(*a, *b); });
155 
156  // Keep track of the photons in the clean collection
157  std::vector<reco::RecoTauPiZero> cleanPiZeros;
158  std::set<reco::CandidatePtr> photonsInCleanCollection;
159  while (!dirtyPiZeros.empty()) {
160  // Pull our candidate pi zero from the front of the list
161  std::unique_ptr<reco::RecoTauPiZero> toAdd(dirtyPiZeros.front().release());
162  dirtyPiZeros.pop_front();
163  // If this doesn't pass our basic selection, discard it.
164  if (!(*outputSelector_)(*toAdd)) {
165  continue;
166  }
167  // Find the sub-gammas that are not already in the cleaned collection
168  std::vector<reco::CandidatePtr> uniqueGammas;
169  std::set_difference(toAdd->daughterPtrVector().begin(),
170  toAdd->daughterPtrVector().end(),
171  photonsInCleanCollection.begin(),
172  photonsInCleanCollection.end(),
173  std::back_inserter(uniqueGammas));
174  // If the pi zero has no unique gammas, discard it. Note toAdd is deleted
175  // when it goes out of scope.
176  if (uniqueGammas.empty()) {
177  continue;
178  } else if (uniqueGammas.size() == toAdd->daughterPtrVector().size()) {
179  // Check if it is composed entirely of unique gammas. In this case
180  // immediately add it to the clean collection.
181  photonsInCleanCollection.insert(toAdd->daughterPtrVector().begin(), toAdd->daughterPtrVector().end());
182  cleanPiZeros.push_back(*toAdd);
183  } else {
184  // Otherwise update the pizero that contains only the unique gammas and
185  // add it back into the sorted list of dirty PiZeros
186  toAdd->clearDaughters();
187  // Add each of the unique daughters back to the pizero
188  for (auto const& gamma : uniqueGammas) {
189  toAdd->addDaughter(gamma);
190  }
191  // Update the four vector
192  AddFourMomenta p4Builder_;
193  p4Builder_.set(*toAdd);
194  // Put this pi zero back into the collection of sorted dirty pizeros
195  auto insertionPoint =
196  std::lower_bound(dirtyPiZeros.begin(), dirtyPiZeros.end(), *toAdd, [this](const auto& a, const auto& b) {
197  return (*predicate_)(*a, b);
198  });
199  dirtyPiZeros.insert(insertionPoint, std::move(toAdd));
200  }
201  }
202  // Apply the mass hypothesis if desired
203  if (piZeroMass_ >= 0) {
204  for (auto& cleanPiZero : cleanPiZeros) {
205  cleanPiZero.setMass(this->piZeroMass_);
206  };
207  }
208  // Add to association
209  if (verbosity_ >= 2) {
210  print(cleanPiZeros, std::cout);
211  }
212  association->setValue(jet.key(), cleanPiZeros);
213  }
214  evt.put(std::move(association));
215 }
216 
217 // Print some helpful information
218 void RecoTauPiZeroProducer::print(const std::vector<reco::RecoTauPiZero>& piZeros, std::ostream& out) {
219  const unsigned int width = 25;
220  for (auto const& piZero : piZeros) {
221  out << piZero;
222  out << "* Rankers:" << std::endl;
223  for (auto const& ranker : rankers_) {
224  out << "* " << std::setiosflags(std::ios::left) << std::setw(width) << ranker->name() << " "
225  << std::resetiosflags(std::ios::left) << std::setprecision(3) << (*ranker)(piZero);
226  out << std::endl;
227  }
228  }
229 }
230 
232  // common parameter descriptions
233  edm::ParameterSetDescription desc_ranking;
234  desc_ranking.add<std::string>("selectionPassFunction", "Func");
235  desc_ranking.add<double>("selectionFailValue", 1000);
236  desc_ranking.add<std::string>("selection", "Sel");
237  desc_ranking.add<std::string>("name", "name");
238  desc_ranking.add<std::string>("plugin", "plugin");
239  edm::ParameterSet pset_ranking;
240  pset_ranking.addParameter<std::string>("selectionPassFunction", "");
241  pset_ranking.addParameter<double>("selectionFailValue", 1000);
242  pset_ranking.addParameter<std::string>("selection", "");
243  pset_ranking.addParameter<std::string>("name", "");
244  pset_ranking.addParameter<std::string>("plugin", "");
245  std::vector<edm::ParameterSet> vpsd_ranking;
246  vpsd_ranking.push_back(pset_ranking);
247 
248  edm::ParameterSetDescription desc_qualityCuts;
250 
251  edm::ParameterSet pset_builders;
252  pset_builders.addParameter<std::string>("name", "");
253  pset_builders.addParameter<std::string>("plugin", "");
255  pset_builders.addParameter<edm::ParameterSet>("qualityCuts", qualityCuts);
256  pset_builders.addParameter<int>("verbosity", 0);
257 
258  {
259  // Tailored on ak4PFJetsLegacyHPSPiZeros
261  desc.add<double>("massHypothesis", 0.136);
262  desc.addVPSet("ranking", desc_ranking, vpsd_ranking);
263  desc.add<int>("verbosity", 0);
264  desc.add<double>("maxJetAbsEta", 2.5);
265  desc.add<std::string>("outputSelection", "pt > 0");
266  desc.add<double>("minJetPt", 14.0);
267  desc.add<edm::InputTag>("jetSrc", edm::InputTag("ak4PFJets"));
268 
269  edm::ParameterSetDescription desc_builders;
270  {
272  psd0.add<std::string>("function", "TMath::Min(0.3, TMath::Max(0.05, [0]*TMath::Power(pT, -[1])))");
273  psd0.add<double>("par1", 0.707716);
274  psd0.add<double>("par0", 0.352476);
275  desc_builders.addOptional<edm::ParameterSetDescription>("stripPhiAssociationDistanceFunc", psd0);
276  }
277  {
279  psd0.add<std::string>("function", "TMath::Min(0.15, TMath::Max(0.05, [0]*TMath::Power(pT, -[1])))");
280  psd0.add<double>("par1", 0.658701);
281  psd0.add<double>("par0", 0.197077);
282  desc_builders.addOptional<edm::ParameterSetDescription>("stripEtaAssociationDistanceFunc", psd0);
283  }
284  desc_builders.addOptional<double>("stripEtaAssociationDistance", 0.05);
285  desc_builders.addOptional<double>("stripPhiAssociationDistance", 0.2);
286 
287  desc_builders.add<edm::ParameterSetDescription>("qualityCuts", desc_qualityCuts);
288 
289  desc_builders.add<std::string>("name");
290  desc_builders.add<std::string>("plugin");
291  desc_builders.add<int>("verbosity", 0);
292 
293  desc_builders.addOptional<bool>("makeCombinatoricStrips");
294  desc_builders.addOptional<int>("maxStripBuildIterations");
295  desc_builders.addOptional<double>("minGammaEtStripAdd");
296  desc_builders.addOptional<double>("minGammaEtStripSeed");
297  desc_builders.addOptional<double>("minStripEt");
298  desc_builders.addOptional<std::vector<int>>("stripCandidatesParticleIds");
299  desc_builders.addOptional<bool>("updateStripAfterEachDaughter");
300  desc_builders.addOptional<bool>("applyElecTrackQcuts");
301 
302  std::vector<edm::ParameterSet> vpsd_builders;
303  vpsd_builders.push_back(pset_builders);
304  desc.addVPSet("builders", desc_builders, vpsd_builders);
305 
306  descriptions.add("recoTauPiZeroProducer", desc);
307  }
308 }
309 
void produce(edm::Event &evt, const edm::EventSetup &es) override
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
RefToBase< value_type > refAt(size_type i) const
void set(reco::Candidate &c) const
set up a candidate
static void fillDescriptions(edm::ParameterSetDescription &descriptions)
Declare all parameters read from python config file.
def create(alignables, pedeDump, additionalData, outputFile, config)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
reco::tau::RecoTauLexicographicalRanking< RankerList, reco::RecoTauPiZero > PiZeroPredicate
reco::tau::RecoTauPiZeroQualityPlugin Ranker
selection
main part
Definition: corrVsCorr.py:100
RecoTauPiZeroProducer(const edm::ParameterSet &pset)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:528
std::list< std::unique_ptr< reco::RecoTauPiZero > > PiZeroList
Log< level::Error, false > LogError
static constexpr int nJets
void print(const std::vector< reco::RecoTauPiZero > &piZeros, std::ostream &out)
size_type size() const
edm::RefToBaseProd< reco::Jet > JetRefBaseProd
Definition: JetCollection.h:13
reco::tau::RecoTauPiZeroBuilderPlugin Builder
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:136
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Builder::return_type PiZeroVector
double b
Definition: hdecay.h:120
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::unique_ptr< StringCutObjectSelector< reco::RecoTauPiZero > > outputSelector_
edm::EDGetTokenT< reco::JetView > cand_token
double a
Definition: hdecay.h:121
std::vector< std::unique_ptr< Ranker > > RankerList
#define get
std::vector< std::unique_ptr< Builder > > builders_
std::vector< std::string > set_difference(std::vector< std::string > const &v1, std::vector< std::string > const &v2)
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr< PiZeroPredicate > predicate_