Imperial Analysis
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ICTriggerObjectProducer.cc
Go to the documentation of this file.
2 #include <memory>
3 #include <string>
4 #include <vector>
5 #include <algorithm>
6 #include "boost/format.hpp"
7 #include "FWCore/Framework/interface/Event.h"
8 #include "FWCore/Framework/interface/EventSetup.h"
9 #include "FWCore/Framework/interface/MakerMacros.h"
10 #include "FWCore/ParameterSet/interface/ParameterSet.h"
11 #include "FWCore/Utilities/interface/InputTag.h"
12 #include "DataFormats/Common/interface/Handle.h"
13 #include "FWCore/Common/interface/TriggerNames.h"
14 #include "DataFormats/Common/interface/TriggerResults.h"
15 #include "DataFormats/PatCandidates/interface/TriggerEvent.h"
16 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
17 #include "PhysicsTools/PatUtils/interface/TriggerHelper.h"
18 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
25 
27  const edm::ParameterSet& config)
28  : input_(config.getParameter<edm::InputTag>("input")),
29  input_trigres_(config.getParameter<edm::InputTag>("inputTriggerResults")),
30  branch_(config.getParameter<std::string>("branch")),
31  hlt_path_(config.getParameter<std::string>("hltPath")),
32  store_only_if_fired_(config.getParameter<bool>("storeOnlyIfFired")),
33  input_is_standalone_(config.getParameter<bool>("inputIsStandAlone")) {
34  if(!input_is_standalone_){
35  consumes<pat::TriggerEvent>(input_);
36  } else {
37  consumes<pat::TriggerObjectStandAloneCollection>(input_);
38  }
39  consumes<edm::TriggerResults>(input_trigres_);
40  objects_ = new std::vector<ic::TriggerObject>();
41  PrintHeaderWithProduces(config, input_, branch_);
42  std::cout << boost::format("%-15s : %-60s\n") % "Path" % hlt_path_;
43  PrintOptional(1, store_only_if_fired_, "storeOnlyIfFired");
44  PrintOptional(1, input_is_standalone_, "inputIsStandAlone");
45 }
46 
48 
49 void ICTriggerObjectProducer::produce(edm::Event& event,
50  const edm::EventSetup& setup) {
51  objects_->clear();
52 
53  if (!input_is_standalone_) {
54  edm::Handle<pat::TriggerEvent> trig_handle;
55  event.getByLabel(input_, trig_handle);
56 
57 
58  // Get a vector of all HLT paths
59  std::vector<pat::TriggerPath> const* paths = trig_handle->paths();
60 
61  // Find the full label of the chosen HLT path (i.e. with the version number)
62  bool fired = true;
63  bool path_found = false;
64  std::string full_name;
65  for (unsigned i = 0; i < paths->size(); ++i) {
66  std::string const& name = paths->at(i).name();
67  if (name.find(hlt_path_) != name.npos) {
68  full_name = name;
69  path_found = true;
70  if (store_only_if_fired_ && !(paths->at(i).wasAccept())) fired = false;
71  break; // Stop loop after we find the first match
72  }
73  }
74  if (!fired || !path_found) return;
75 
76  // Get a vector of the objects used in the chosen path
77  pat::TriggerObjectRefVector objects =
78  trig_handle->pathObjects(full_name, false);
79  objects_->resize(objects.size(), ic::TriggerObject());
80  for (unsigned i = 0; i < objects.size(); ++i) {
81  pat::TriggerObject const& src = *(objects.at(i));
82  ic::TriggerObject & dest = objects_->at(i);
83  dest.set_pt(src.pt());
84  dest.set_eta(src.eta());
85  dest.set_phi(src.phi());
86  dest.set_energy(src.energy());
87  dest.set_charge(0);
88  std::vector<std::size_t> filter_labels;
89 
90  // Get the filters this object was used in
91  pat::TriggerFilterRefVector filters =
92  trig_handle->objectFilters((objects)[i], false);
93  for (unsigned k = 0; k < filters.size(); ++k) {
94  // Only store the filter label if the filter was used in the chosen path
95  if (!trig_handle->filterInPath(filters[k], full_name, false)) continue;
96  filter_labels.push_back(CityHash64(filters[k]->label()));
97  observed_filters_[filters[k]->label()] = CityHash64(filters[k]->label());
98  }
99  dest.set_filters(filter_labels);
100 
101  // Assuming we can represent each trigger type as a short int, see here:
102  // github.com/cms-sw/cmssw/blob/CMSSW_8_0_X/DataFormats/HLTReco/interface/TriggerTypeDefs.h
103  // we can pack four of these, each 16 bits, into the id() variable
104  // (64 bits).
105  ui64 packed_type;
106  packed_type.one = 0;
107  unsigned n_types = std::min(std::size_t(4), src.triggerObjectTypes().size());
108  for (unsigned t = 0; t < n_types; ++t) {
109  packed_type.four[t] = src.triggerObjectTypes()[t];
110  }
111  dest.set_id(packed_type.one);
112  }
113  } else { // i.e. MiniAOD
114  // We need to figure out the full HLT path name (typically hlt_path_ doesn't
115  // contain the version number at the end). We don't have access to the full
116  // pat::TriggerEvent here, but we can get the same information from the
117  // edm::TriggerResults instead.
118  // This code was inspired by the example here:
119  // https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookMiniAOD#Trigger
120  edm::Handle<edm::TriggerResults> trigres_handle;
121  event.getByLabel(input_trigres_, trigres_handle);
122  edm::TriggerNames const& names = event.triggerNames(*trigres_handle);
123 
124  bool fired = true;
125  bool path_found = false;
126  std::string full_name;
127 
128  for (unsigned int i = 0, n = trigres_handle->size(); i < n; ++i) {
129  std::string const& name = names.triggerName(i);
130  // std::cout << i << "\t" << name << "\n";
131  if (name.find(hlt_path_) != name.npos) {
132  full_name = name;
133  path_found = true;
134  if (store_only_if_fired_ && !(trigres_handle->accept(i))) fired = false;
135  break; // Stop loop after we find the first match
136  }
137  }
138  if (!fired || !path_found) return;
139 
140  // Have to use the HLTConfigProvider to get the list of object-producing
141  // filter modules that were run in this path
142  std::set<std::string> path_filters;
143  std::vector<std::string> const& filt_vec =
144  hlt_config_.saveTagsModules(full_name);
145  for (unsigned i = 0; i < filt_vec.size(); ++i)
146  path_filters.insert(filt_vec[i]);
147 
148  edm::Handle<pat::TriggerObjectStandAloneCollection> trigobj_handle;
149  event.getByLabel(input_, trigobj_handle);
150  for (unsigned i = 0; i < trigobj_handle->size(); ++i) {
151  pat::TriggerObjectStandAlone src = trigobj_handle->at(i);
152 #if CMSSW_MAJOR_VERSION >= 7
153  // In MiniAOD the path names have to be unpacked, but this method
154  // was only introduced in CMSSW_7_0_5
155  src.unpackPathNames(names);
156 #endif
157  std::vector<std::string> const& pathnames = src.pathNames(false,false);
158  bool obj_in_path = false;
159  for (unsigned j = 0; j < pathnames.size(); ++j) {
160  if (full_name == pathnames[j]) {
161  obj_in_path = true;
162  break;
163  }
164  }
165  if (!obj_in_path) continue;
166 
167  // Ok, so this object was used in the path - now we can add it to the
168  // output collection
169  objects_->push_back(ic::TriggerObject());
170  ic::TriggerObject & dest = objects_->back();
171  dest.set_pt(src.pt());
172  dest.set_eta(src.eta());
173  dest.set_phi(src.phi());
174  dest.set_energy(src.energy());
175  dest.set_charge(0);
176 
177  // Get the filters this object was used in
178  std::vector<std::string> const& filters = src.filterLabels();
179  std::vector<std::size_t> filter_labels;
180  for (unsigned k = 0; k < filters.size(); ++k) {
181  // Using the info we got from the HLTConfigProvider we can check if this
182  // filter module was actually used in the path we are interested in
183  if (!path_filters.count(filters[k])) continue;
184  filter_labels.push_back(CityHash64(filters[k]));
185  observed_filters_[filters[k]] = CityHash64(filters[k]);
186  }
187  dest.set_filters(filter_labels);
188 
189  // Assuming we can represent each trigger type as a short int, see here:
190  // github.com/cms-sw/cmssw/blob/CMSSW_8_0_X/DataFormats/HLTReco/interface/TriggerTypeDefs.h
191  // we can pack four of these, each 16 bits, into the id() variable
192  // (64 bits).
193  ui64 packed_type;
194  packed_type.one = 0;
195  unsigned n_types = std::min(std::size_t(4), src.triggerObjectTypes().size());
196  for (unsigned t = 0; t < n_types; ++t) {
197  packed_type.four[t] = src.triggerObjectTypes()[t];
198  }
199  dest.set_id(packed_type.one);
200  }
201  }
202 }
203 
204 void ICTriggerObjectProducer::beginRun(edm::Run const& run,
205  edm::EventSetup const& es) {
206  if (input_is_standalone_) {
207  std::string proc =
208  input_trigres_.process() != "" ? input_trigres_.process() : "HLT";
209  bool changed = true;
210  bool res = hlt_config_.init(run, es, proc, changed);
211  if (!res)
212  throw std::runtime_error(
213  "HLTConfigProvider did not initialise correctly");
214  }
215 }
216 
217 
218 void ICTriggerObjectProducer::beginJob() {
219  ic::StaticTree::tree_->Branch(branch_.c_str(), &objects_);
220 }
221 
222 void ICTriggerObjectProducer::endJob() {
223  std::cout << std::string(78, '-') << "\n";
224  std::cout << boost::format("Path: %-50s %20s\n")
225  % hlt_path_ % std::string("Hash Summmary");
226  std::map<std::string, std::size_t>::const_iterator iter;
227  for (iter = observed_filters_.begin(); iter != observed_filters_.end();
228  ++iter) {
229  ICHashTreeProducer::Add(iter->second, iter->first);
230  std::cout << boost::format("%-56s| %020i\n") % iter->first % iter->second;
231  }
232 }
233 
234 // define this as a plug-in
uint64 CityHash64(const char *buf, size_t len)
Definition: city.cc:200
ICTriggerObjectProducer(const edm::ParameterSet &)
void set_filters(std::vector< std::size_t > const &filters)
The list of filter label hashes this object was accepted by, typically restricted to the modules in s...
See documentation here.
void set_phi(double const &phi)
Direct access to .
Definition: Candidate.hh:75
void set_id(std::size_t const &id)
Unique identifier.
Definition: Candidate.hh:66
void set_charge(int const &charge)
Electric charge.
Definition: Candidate.hh:81
static TTree * tree_
Definition: StaticTree.hh:13
void set_energy(double const &energy)
Direct access to the energy.
Definition: Candidate.hh:78
void PrintOptional(unsigned depth, bool value, std::string text)
Definition: Consumes.h:19
Stores the four-momentum of a trigger object as well as a list of the (hashed) filter labels the obje...
void set_pt(double const &pt)
Direct access to the .
Definition: Candidate.hh:69
void set_eta(double const &eta)
Direct access to .
Definition: Candidate.hh:72
void PrintHeaderWithProduces(edm::ParameterSet const &config, edm::InputTag const &in, std::string branch)
DEFINE_FWK_MODULE(ICTriggerObjectProducer)
static void Add(std::size_t const &id, std::string const &str)