CMS 3D CMS Logo

L1TPFProducer.cc
Go to the documentation of this file.
1 // system include files
2 #include <memory>
3 #include <algorithm>
4 #include <fstream>
5 #include <cstdio>
6 
7 // user include files
15 
19 
21 
31 
34 
35 //--------------------------------------------------------------------------------------------------
37 public:
38  explicit L1TPFProducer(const edm::ParameterSet&);
39  ~L1TPFProducer() override;
40 
41 private:
43  int debug_;
44 
47 
48  bool hasTracks_;
51  unsigned trkMinStubs_;
54 
57 
58  std::vector<edm::EDGetTokenT<l1t::PFClusterCollection>> emCands_;
59  std::vector<edm::EDGetTokenT<l1t::PFClusterCollection>> hadCands_;
60 
62 
64  std::unique_ptr<l1tpf_impl::PFAlgoBase> l1pfalgo_;
65  std::unique_ptr<l1tpf_impl::PUAlgoBase> l1pualgo_;
66 
68 
69  // Region dump/coe
71  FILE* fRegionDump_;
72  std::unique_ptr<l1tpf_impl::COEFile> fRegionCOE_;
74 
75  // region of interest debugging
77 
78  void beginStream(edm::StreamID) override;
79  void produce(edm::Event&, const edm::EventSetup&) override;
80  void addUInt(unsigned int value, std::string iLabel, edm::Event& iEvent);
81 };
82 
83 //
84 // constructors and destructor
85 //
87  : config_(iConfig),
88  debug_(iConfig.getUntrackedParameter<int>("debug", 0)),
89  useStandaloneMuons_(iConfig.getParameter<bool>("useStandaloneMuons")),
90  useTrackerMuons_(iConfig.getParameter<bool>("useTrackerMuons")),
91  hasTracks_(!iConfig.getParameter<edm::InputTag>("tracks").label().empty()),
92  tkCands_(hasTracks_ ? consumes<l1t::PFTrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"))
93  : edm::EDGetTokenT<l1t::PFTrackCollection>()),
94  trkPt_(iConfig.getParameter<double>("trkPtCut")),
95  trkMaxChi2_(iConfig.getParameter<double>("trkMaxChi2")),
96  trkMinStubs_(iConfig.getParameter<unsigned>("trkMinStubs")),
97  muCands_(consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("muons"))),
98  tkMuCands_(consumes<l1t::TkMuonCollection>(iConfig.getParameter<edm::InputTag>("tkMuons"))),
99  emPtCut_(iConfig.getParameter<double>("emPtCut")),
100  hadPtCut_(iConfig.getParameter<double>("hadPtCut")),
101  l1regions_(iConfig),
102  l1pfalgo_(nullptr),
103  l1pualgo_(nullptr),
104  regionDumpName_(iConfig.getUntrackedParameter<std::string>("dumpFileName", "")),
105  regionCOEName_(iConfig.getUntrackedParameter<std::string>("coeFileName", "")),
106  fRegionDump_(nullptr),
107  fRegionCOE_(nullptr),
108  neventscoemax_(iConfig.getUntrackedParameter<unsigned int>("neventscoemax_", 0)),
109  neventsproduced_(0),
110  debugEta_(iConfig.getUntrackedParameter<double>("debugEta", 0)),
111  debugPhi_(iConfig.getUntrackedParameter<double>("debugPhi", 0)),
112  debugR_(iConfig.getUntrackedParameter<double>("debugR", -1)) {
113  produces<l1t::PFCandidateCollection>("PF");
114  produces<l1t::PFCandidateCollection>("Puppi");
115 
116  produces<l1t::PFCandidateCollection>("EmCalo");
117  produces<l1t::PFCandidateCollection>("Calo");
118  produces<l1t::PFCandidateCollection>("TK");
119  produces<l1t::PFCandidateCollection>("TKVtx");
120 
121  produces<float>("z0");
122 
123  for (const auto& tag : iConfig.getParameter<std::vector<edm::InputTag>>("emClusters")) {
124  emCands_.push_back(consumes<l1t::PFClusterCollection>(tag));
125  }
126  for (const auto& tag : iConfig.getParameter<std::vector<edm::InputTag>>("hadClusters")) {
127  hadCands_.push_back(consumes<l1t::PFClusterCollection>(tag));
128  }
129 
130  const std::string& algo = iConfig.getParameter<std::string>("pfAlgo");
131  if (algo == "PFAlgo3") {
132  l1pfalgo_ = std::make_unique<l1tpf_impl::PFAlgo3>(iConfig);
133  } else if (algo == "PFAlgo2HGC") {
134  l1pfalgo_ = std::make_unique<l1tpf_impl::PFAlgo2HGC>(iConfig);
135  } else if (algo == "BitwisePFAlgo") {
136  l1pfalgo_ = std::make_unique<l1tpf_impl::BitwisePFAlgo>(iConfig);
137  } else
138  throw cms::Exception("Configuration", "Unsupported PFAlgo");
139 
140  const std::string& pualgo = iConfig.getParameter<std::string>("puAlgo");
141  if (pualgo == "Puppi") {
142  l1pualgo_ = std::make_unique<l1tpf_impl::PuppiAlgo>(iConfig);
143  } else if (pualgo == "LinearizedPuppi") {
144  l1pualgo_ = std::make_unique<l1tpf_impl::LinearizedPuppiAlgo>(iConfig);
145  } else
146  throw cms::Exception("Configuration", "Unsupported PUAlgo");
147 
148  std::string vtxAlgo = iConfig.getParameter<std::string>("vtxAlgo");
149  if (vtxAlgo == "TP")
151  else if (vtxAlgo == "old")
153  else if (vtxAlgo == "external") {
155  const std::string& vtxFormat = iConfig.getParameter<std::string>("vtxFormat");
156  if (vtxFormat == "TkPrimaryVertex") {
157  extTkVtx_ = consumes<std::vector<l1t::TkPrimaryVertex>>(iConfig.getParameter<edm::InputTag>("vtxCollection"));
158  } else
159  throw cms::Exception("Configuration") << "Unsupported vtxFormat " << vtxFormat << "\n";
160  } else
161  throw cms::Exception("Configuration") << "Unsupported vtxAlgo " << vtxAlgo << "\n";
162 
163  for (const std::string& label : l1pualgo_->puGlobalNames()) {
164  produces<float>(label);
165  }
166 
167  if (!regionDumpName_.empty()) {
168  TokGenOrigin_ = consumes<math::XYZPointF>(iConfig.getParameter<edm::InputTag>("genOrigin"));
169  }
170  for (int tot = 0; tot <= 1; ++tot) {
171  for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) {
172  produces<unsigned int>(std::string(tot ? "totNL1" : "maxNL1") + l1tpf_impl::Region::inputTypeName(i));
173  }
174  for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) {
175  produces<unsigned int>(std::string(tot ? "totNL1PF" : "maxNL1PF") + l1tpf_impl::Region::outputTypeName(i));
176  produces<unsigned int>(std::string(tot ? "totNL1Puppi" : "maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i));
177  }
178  }
179  for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) {
180  produces<std::vector<unsigned>>(std::string("vecNL1") + l1tpf_impl::Region::inputTypeName(i));
181  }
182  for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) {
183  produces<std::vector<unsigned>>(std::string("vecNL1PF") + l1tpf_impl::Region::outputTypeName(i));
184  produces<std::vector<unsigned>>(std::string("vecNL1Puppi") + l1tpf_impl::Region::outputTypeName(i));
185  }
186 }
187 
189  // do anything here that needs to be done at desctruction time
190  // (e.g. close files, deallocate resources etc.)
191  if (fRegionDump_)
192  fclose(fRegionDump_);
193  if (fRegionCOE_)
194  fRegionCOE_->close();
195 }
196 
198  if (!regionDumpName_.empty()) {
199  if (id == 0) {
200  fRegionDump_ = fopen(regionDumpName_.c_str(), "wb");
201  } else {
202  edm::LogWarning("L1TPFProducer")
203  << "Job running with multiple streams, but dump file will have only events on stream zero.";
204  }
205  }
206  if (!regionCOEName_.empty()) {
207  if (id == 0) {
208  fRegionCOE_ = std::make_unique<l1tpf_impl::COEFile>(config_);
209  } else {
210  edm::LogWarning("L1TPFProducer")
211  << "Job running with multiple streams, but COE file will dump only events on stream zero.";
212  }
213  }
214 }
215 
216 // ------------ method called to produce the data ------------
218  // clear the regions also at the beginning, in case one event didn't complete but the job continues on
219  l1regions_.clear();
220 
222  if (hasTracks_) {
224  iEvent.getByToken(tkCands_, htracks);
225  const auto& tracks = *htracks;
226  for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) {
227  const auto& tk = tracks[itk];
228  // adding objects to PF
229  if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_)
230  continue;
231  if (tk.pt() > trkPt_ && tk.nStubs() >= trkMinStubs_ && tk.normalizedChi2() < trkMaxChi2_) {
232  l1regions_.addTrack(tk, l1t::PFTrackRef(htracks, itk));
233  }
234  }
235  }
236 
240  throw cms::Exception(
241  "Configuration",
242  "setting useStandaloneMuons=True && useTrackerMuons=True is not to be done, as it would duplicate all muons\n");
243  }
244 
245  if (useStandaloneMuons_) {
247  iEvent.getByToken(muCands_, muons);
248  for (auto it = muons->begin(0), ed = muons->end(0); it != ed; ++it) {
249  const l1t::Muon& mu = *it;
250  if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_)
251  continue;
253  }
254  }
255 
256  if (useTrackerMuons_) {
258  iEvent.getByToken(tkMuCands_, muons);
259  for (auto it = muons->begin(), ed = muons->end(); it != ed; ++it) {
260  const l1t::TkMuon& mu = *it;
261  if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_)
262  continue;
263  l1regions_.addMuon(mu); // FIXME add a l1t::PFCandidate::MuonRef
264  }
265  }
266 
267  // ------ READ CALOS -----
269  for (const auto& tag : emCands_) {
270  iEvent.getByToken(tag, caloHandle);
271  const auto& calos = *caloHandle;
272  for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
273  const auto& calo = calos[ic];
274  if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_)
275  continue;
276  if (calo.pt() > emPtCut_)
277  l1regions_.addEmCalo(calo, l1t::PFClusterRef(caloHandle, ic));
278  }
279  }
280  for (const auto& tag : hadCands_) {
281  iEvent.getByToken(tag, caloHandle);
282  const auto& calos = *caloHandle;
283  for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
284  const auto& calo = calos[ic];
285  if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_)
286  continue;
287  if (calo.pt() > hadPtCut_)
288  l1regions_.addCalo(calo, l1t::PFClusterRef(caloHandle, ic));
289  }
290  }
291 
292  // First, get a copy of the discretized and corrected inputs, and write them out
293  iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/true), "EmCalo");
294  iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/false), "Calo");
295  iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/false), "TK");
296  if (fRegionDump_) {
297  uint32_t run = iEvent.id().run(), lumi = iEvent.id().luminosityBlock();
298  uint64_t event = iEvent.id().event();
299  fwrite(&run, sizeof(uint32_t), 1, fRegionDump_);
300  fwrite(&lumi, sizeof(uint32_t), 1, fRegionDump_);
301  fwrite(&event, sizeof(uint64_t), 1, fRegionDump_);
303  }
304 
305  // Then save the regions to the COE file
306  // Do it here because there is some sorting going on in a later function
307  if (fRegionCOE_ && fRegionCOE_->is_open() && neventsproduced_ < neventscoemax_) {
308  std::vector<l1tpf_impl::Region> regions = l1regions_.regions();
309  fRegionCOE_->writeTracksToFile(regions, neventsproduced_ == 0);
310  }
312 
313  // Then do the vertexing, and save it out
314  float z0;
316  z0 = 0;
317  double ptsum = 0;
318  if (!extTkVtx_.isUninitialized()) {
320  iEvent.getByToken(extTkVtx_, vtxHandle);
321  for (const l1t::TkPrimaryVertex& vtx : *vtxHandle) {
322  if (ptsum == 0 || vtx.sum() > ptsum) {
323  z0 = vtx.zvertex();
324  ptsum = vtx.sum();
325  }
326  }
327  } else
328  throw cms::Exception("LogicError", "Inconsistent vertex configuration");
329  }
330  l1pualgo_->doVertexing(l1regions_.regions(), vtxAlgo_, z0);
331  iEvent.put(std::make_unique<float>(z0), "z0");
332  if (fRegionDump_) {
333  fwrite(&z0, sizeof(float), 1, fRegionDump_);
334  edm::Handle<math::XYZPointF> hGenOrigin;
335  iEvent.getByToken(TokGenOrigin_, hGenOrigin);
336  const math::XYZPointF& genOrigin = *hGenOrigin;
337  float genZ = genOrigin.Z();
338  fwrite(&genZ, sizeof(float), 1, fRegionDump_);
339  }
340 
341  // Then also save the tracks with a vertex cut
342  iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/true), "TKVtx");
343 
344  // Then run PF in each region
345  for (auto& l1region : l1regions_.regions()) {
346  l1pfalgo_->runPF(l1region);
347  l1pualgo_->runChargedPV(l1region, z0);
348  }
349  // save PF into the event
350  iEvent.put(l1regions_.fetch(false), "PF");
351 
352  // Then get our alphas (globally)
353  std::vector<float> puGlobals;
354  l1pualgo_->doPUGlobals(l1regions_.regions(), -1., puGlobals); // FIXME we don't have yet an external PU estimate
355  const std::vector<std::string>& puGlobalNames = l1pualgo_->puGlobalNames();
356  if (puGlobals.size() != puGlobalNames.size())
357  throw cms::Exception("LogicError", "Mismatch in the number of global pileup inputs");
358  for (unsigned int i = 0, n = puGlobalNames.size(); i < n; ++i) {
359  iEvent.put(std::make_unique<float>(puGlobals[i]), puGlobalNames[i]);
360  }
361  if (fRegionDump_) {
363  }
364 
365  // Then run puppi (regionally)
366  for (auto& l1region : l1regions_.regions()) {
367  l1pualgo_->runNeutralsPU(l1region, -1., puGlobals);
368  }
369  // and save puppi
370  iEvent.put(l1regions_.fetch(true), "Puppi");
371 
372  // Then go do the multiplicities
373 
374  for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) {
375  auto totAndMax = l1regions_.totAndMaxInput(i);
376  addUInt(totAndMax.first, std::string("totNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent);
377  addUInt(totAndMax.second, std::string("maxNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent);
379  }
380  for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) {
381  auto totAndMaxPF = l1regions_.totAndMaxOutput(i, false);
382  auto totAndMaxPuppi = l1regions_.totAndMaxOutput(i, true);
383  addUInt(totAndMaxPF.first, std::string("totNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent);
384  addUInt(totAndMaxPF.second, std::string("maxNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent);
385  addUInt(totAndMaxPuppi.first, std::string("totNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent);
386  addUInt(totAndMaxPuppi.second, std::string("maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent);
389  }
390 
391  // finally clear the regions
392  l1regions_.clear();
393 }
394 
396  iEvent.put(std::make_unique<unsigned>(value), iLabel);
397 }
398 
399 //define this as a plug-in
std::unique_ptr< l1t::PFCandidateCollection > fetchCalo(float ptMin=0.01, bool emcalo=false) const
FILE * fRegionDump_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
unsigned int neventsproduced_
void addMuon(const l1t::Muon &t)
std::unique_ptr< l1tpf_impl::PFAlgoBase > l1pfalgo_
void writeManyToFile(const std::vector< T > &objs, FILE *file)
std::unique_ptr< std::vector< unsigned > > vecOutput(int type, bool puppi) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const std::string regionDumpName_
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:99
std::unique_ptr< l1t::PFCandidateCollection > fetchTracks(float ptMin=0.01, bool fromPV=false) const
std::pair< unsigned, unsigned > totAndMaxOutput(int type, bool puppi) const
bool useStandaloneMuons_
~L1TPFProducer() override
edm::EDGetTokenT< l1t::MuonBxCollection > muCands_
edm::EDGetTokenT< math::XYZPointF > TokGenOrigin_
delete x;
Definition: CaloConfig.h:22
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
static const char * outputTypeName(int outputType)
Definition: Region.cc:22
unsigned int neventscoemax_
const std::string regionCOEName_
l1tpf_impl::PUAlgoBase::VertexAlgo vtxAlgo_
static const char * inputTypeName(int inputType)
Definition: Region.cc:6
edm::EDGetTokenT< l1t::TkMuonCollection > tkMuCands_
char const * label
edm::EDGetTokenT< l1t::PFTrackCollection > tkCands_
int iEvent
Definition: GenABIO.cc:224
std::unique_ptr< l1tpf_impl::COEFile > fRegionCOE_
std::unique_ptr< l1tpf_impl::PUAlgoBase > l1pualgo_
void addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent)
void beginStream(edm::StreamID) override
unsigned trkMinStubs_
void addTrack(const l1t::PFTrack &t)
Definition: RegionMapper.cc:86
void addCalo(const l1t::PFCluster &t)
Definition: value.py:1
std::vector< TkMuon > TkMuonCollection
Definition: TkMuonFwd.h:16
std::pair< unsigned, unsigned > totAndMaxInput(int type) const
edm::ParameterSet config_
Definition: Muon.h:21
BXVector< Muon > MuonBxCollection
Definition: Muon.h:11
std::unique_ptr< std::vector< unsigned > > vecInput(int type) const
auto const & tracks
cannot be loose
unsigned long long uint64_t
Definition: Time.h:13
edm::EDGetTokenT< std::vector< l1t::TkPrimaryVertex > > extTkVtx_
std::vector< Region > & regions()
Definition: RegionMapper.h:34
void addEmCalo(const l1t::PFCluster &t)
std::vector< l1t::PFTrack > PFTrackCollection
Definition: PFTrack.h:84
HLT enums.
l1tpf_impl::RegionMapper l1regions_
L1TPFProducer(const edm::ParameterSet &)
std::vector< edm::EDGetTokenT< l1t::PFClusterCollection > > emCands_
Log< level::Warning, false > LogWarning
std::vector< edm::EDGetTokenT< l1t::PFClusterCollection > > hadCands_
void produce(edm::Event &, const edm::EventSetup &) override
std::unique_ptr< l1t::PFCandidateCollection > fetch(bool puppi=true, float ptMin=0.01) const
Definition: Common.h:9
VertexAlgo
global operations
Definition: PUAlgoBase.h:15
Definition: event.py:1