RunEventFilter_module.cc
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 /// \brief Filter events based on their run/event numbers
3 /// \author messier@indiana.edu
4 /// \date
5 ///////////////////////////////////////////////////////////////////////////
6 #include <cstdlib>
7 #include <iostream>
8 #include <fstream>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
19 
21 #include "RecoBase/Cluster.h"
22 #include "RecoBase/FilterList.h"
23 
24 namespace util {
25  /// Select events based on a list of run and event numbers
26  ///
27  /// File format is expected to be a list of run/subrun/event triplets:
28  ///
29  /// # run subrun event
30  /// 10796 4 102012
31  /// 10796 2 121093
32  /// 10796 11 133092
33  ///
34  /// with comments marked by a leading '#'. By default the module
35  /// looks for these to be in a file called "event-list.txt",
36  /// although the filename can be reconfigured. The module can be
37  /// configured to run in one of two modes. The configuration
38  /// include_runeventfilter sets Mode=0 which means that the events
39  /// listed in the file are to be included in the output. The
40  /// configuration exclude_runeventfilter sets Mode=1 which means
41  /// that the events listed are to be excluded from the output
42  /// file. See RunEventFilter.fcl.
43  ///
44  class RunEventFilter : public art::EDFilter
45  {
46  public:
47  explicit RunEventFilter(fhicl::ParameterSet const& p);
48  virtual ~RunEventFilter();
49 
50  virtual void reconfigure(fhicl::ParameterSet const& p);
51 
52  virtual bool beginRun(art::Run& run) override;
53  virtual bool beginSubRun(art::SubRun& sr) override;
54  virtual bool filter(art::Event& e) override;
55 
56 
57  private:
58  std::string fEventFile; ///< List of event numbers
59  int fMode; ///< 0=include, 1=exclude list
60  bool fFilterSlice; ///< Apply filter at slice level
61  bool fIsMC; ///< Data or MC? Hence cycle number
62  bool fUseBatchNum; ///< Batch number may be neeed for MC
63  std::string fSlicerLabel; ///< Module that produced slices
64 
65  bool fSkipping;
66  int fCycle;
67  int fBatch;
68 
69  std::set<unsigned int> fRuns;
70  std::set< std::pair<unsigned int, unsigned int> > fSubRuns;
71  std::set< std::tuple<unsigned int, unsigned int,
72  unsigned int> > fEvents;
73  std::set< std::tuple<unsigned int, unsigned int,
74  unsigned int, unsigned int> > fSlices;
75  std::set< std::tuple<unsigned int, unsigned int,
76  unsigned int, unsigned int,
77  unsigned int> > fCycles;
78  std::set< std::tuple<unsigned int, unsigned int,
79  unsigned int, unsigned int,
80  unsigned int, unsigned int> > fBatches;
81 
82  };
83 }
84 
85 
86 ////////////////////////////////////////////////////////////////////////
87 namespace util
88 {
89  //......................................................................
91  : fSkipping(false), fCycle(-5), fBatch(-5)
92  {
93  this->reconfigure(p);
94 
95  if (fFilterSlice) produces< rb::FilterList<rb::Cluster> >();
96  }
97 
98  //......................................................................
100  {
101  fEventFile = p.get<std::string>("EventFile");
102  fMode = p.get<int>("Mode");
103  fFilterSlice = p.get<bool>("FilterSlice");
104  fIsMC = p.get<bool>("IsMC");
105  fUseBatchNum = p.get<bool>("UseBatchNum");
106  fSlicerLabel = p.get<std::string>("SlicerLabel");
107 
108  //
109  // Reconfigure the run and event list given the new file name.
110  //
111  fRuns. clear();
112  fSubRuns. clear();
113  fEvents. clear();
114  fSlices. clear();
115  fCycles. clear();
116  fBatches. clear();
117  std::ifstream ifs;
118  ifs.open(fEventFile.c_str());
119  if (ifs.is_open()) {
120  while (ifs.good()) {
121  std::string buff;
122  std::getline(ifs, buff);
123  if (buff[0]=='#') continue;
124 
125  int run, subrun, event, cycle;
126  // if we're filtering the slice
127  if (fFilterSlice){
128  int slice;
129  // for MC we need run/subrun/cycle/event/slice
130  if(fIsMC){
131  if(fUseBatchNum){
132  int batch;
133  // for MC with batch numbers we need run/subrun/cycle/batch/event/slice
134  sscanf(buff.c_str(), "%d %d %d %d %d %d", &run, &subrun, &cycle, &batch, &event, &slice);
135  fCycles.insert(std::make_tuple(run, subrun, cycle, batch, event));
136  fBatches.insert(std::make_tuple(run, subrun, cycle, batch, event, slice));
137  }
138  else{
139  sscanf(buff.c_str(), "%d %d %d %d %d", &run, &subrun, &cycle, &event, &slice);
140  fCycles.insert(std::make_tuple(run, subrun, cycle, event, slice));
141  fSlices.insert(std::make_tuple(run, subrun, cycle, event));
142  }
143  } // fIsMC = true
144  // for Data run/subrun/event/slice
145  else{
146  sscanf(buff.c_str(), "%d %d %d %d", &run, &subrun, &event, &slice);
147  fSlices.insert(std::make_tuple(run, subrun, event, slice));
148  } // fIsMC = false
149  } // if fFilterSlice
150  // And if we're not filtering the slice
151  else{
152  // for MC we need run/subrun/cycle/event
153  if(fIsMC){
154  if(fUseBatchNum){
155  int batch;
156  // for MC with batch numbers we need run/subrun/cycle/batch/event/slice
157  sscanf(buff.c_str(), "%d %d %d %d %d", &run, &subrun, &cycle, &batch, &event);
158  fCycles.insert(std::make_tuple(run, subrun, cycle, batch, event));
159  }
160  else{
161 
162  sscanf(buff.c_str(), "%d %d %d %d", &run, &subrun, &cycle, &event);
163  // Have to be careful here since fSlices can hold 4 tuple values
164  // and fCycles 5. In this case we only want to fill 4 fields)
165  // I'm sure there's a smarter way to do this...
166  fSlices.insert(std::make_tuple(run, subrun, cycle, event));
167  }
168  } // fIsMC = true
169  // for Data we only need run/subrun/event
170  else{
171  sscanf(buff.c_str(), "%d %d %d", &run, &subrun, &event);
172  }
173  } // fFilterSlice = false
174  fRuns.insert(run);
175  fSubRuns.insert(std::make_pair(run, subrun));
176  fEvents.insert(std::make_tuple(run, subrun, event));
177  } // close while loop
178  ifs.close();
179  } // close input file
180  else {
181  std::cerr << __FILE__ << ":" << __LINE__
182  << " Failed to open file " << fEventFile << " for read"
183  << std::endl;
184  }
185  }
186 
187  //......................................................................
189  {
190  }
191 
192  //......................................................................
194  {
195  // If we're only accepting events in the list and there were no entries
196  // for this run go ahead and skip it.
197  fSkipping = (fMode == 0 && !fRuns.count(run.run()));
198  return !fSkipping;
199  }
200 
201  //......................................................................
203  {
204 
205  // If we're only accepting events in the list and there were no entries
206  // for this subrun go ahead and skip it.
207  fSkipping = (fMode == 0 && !fSubRuns.count(std::make_pair(sr.run(), sr.subRun())));
208  return !fSkipping;
209  }
210 
211  //......................................................................
213  {
214  std::unique_ptr< rb::FilterList<rb::Cluster> > filtcol(new rb::FilterList<rb::Cluster>);
215 
216  // Already skipping the whole run or subrun
217  if(fSkipping){
218  if(fFilterSlice)
219  evt.put(std::move(filtcol));
220  return false;
221  }
222 
223  // We're going to pull cycle number from the metadata
225  // Check it exists in the metadata
226  // Convert the std::string to int
227  std::string cycle = fManager.GetMetadata()["simulated.cycle"];
228  if(cycle != "") fCycle = std::stoi(cycle);
229 
230  std::string batch = fManager.GetMetadata()["simulated.batch"];
231  if(batch != "") fBatch = std::stoi(batch);
232 
233  bool inlist = false;
234  // Is this event in the list?
235  if(fIsMC && fUseBatchNum)
236  inlist = fCycles.count(std::make_tuple(evt.run(),
237  evt.subRun(),
238  fCycle,
239  fBatch,
240  evt.event()));
241  if(fIsMC && !fUseBatchNum)
242  inlist = fSlices.count(std::make_tuple(evt.run(),
243  evt.subRun(),
244  fCycle,
245  evt.event()));
246 
247  if(!fIsMC)
248  inlist = fEvents.count(std::make_tuple(evt.run(),
249  evt.subRun(),
250  evt.event()));
251 
252  // If we're looking for the events in the list, and this one isn't, then
253  // we can skip this event.
254  if(fMode == 0 && !inlist){
255  if(fFilterSlice)
256  evt.put(std::move(filtcol));
257  return false;
258  }
259  // If we're rejecting events in the list, and this event is in we can
260  // reject it, so long as it's not just the slices we're supposed to be
261  // rejecting.
262  if(fMode == 1 && !fFilterSlice && inlist){
263  if(fFilterSlice)
264  evt.put(std::move(filtcol));
265  return false;
266  }
267 
268  if(fFilterSlice){
270  evt.getByLabel(fSlicerLabel, slices);
271 
272  // How many slices have we rejected?
273  unsigned int count = 0;
274 
275  for(unsigned int slcIdx = 0; slcIdx < slices->size(); ++slcIdx){
276  // This is a bit tricky. The != operator here is acting as a XOR.
277  // We either want to be accepting slices in the list and to have
278  // not found one, or we want to be rejecting slices in the list and
279  // to have found it. In either case we filter the slice out of
280  // the slices.
281  bool sliceIsInList = false;
282  if(fIsMC && fUseBatchNum)
283  sliceIsInList = fBatches.count(std::make_tuple(evt.run(),
284  evt.subRun(),
285  fCycle,
286  fBatch,
287  evt.event(),
288  slcIdx));
289  if(fIsMC && !fUseBatchNum)
290  sliceIsInList = fCycles.count(std::make_tuple(evt.run(),
291  evt.subRun(),
292  fCycle,
293  evt.event(),
294  slcIdx));
295 
296  if(!fIsMC)
297  sliceIsInList = fSlices.count(std::make_tuple(evt.run(),
298  evt.subRun(),
299  evt.event(),
300  slcIdx));
301 
302 
303 
304  if( (fMode == 1 && sliceIsInList) ||
305  (fMode == 0 && !sliceIsInList) ){
306  filtcol->Add(slices, slcIdx);
307  ++count;
308  }
309 
310  } // end for slcIdx
311 
312  // If we're rejecting slices in the list, and we rejected every slice,
313  // let's reject the whole event instead.
314  if(fMode == 1 && count == slices->size()){
315  evt.put(std::move(filtcol));
316  return false;
317  }
318 
319  evt.put(std::move(filtcol));
320  } // end if fFilterSlice
321 
322  return true;
323  }
324 
325 } // end namespace util
326 
327 
328 ////////////////////////////////////////////////////////////////////////
329 namespace util
330 {
332 }
333 ////////////////////////////////////////////////////////////////////////
bool fFilterSlice
Apply filter at slice level.
A simple list of products that have been marked "filtered out".
Definition: FilterList.h:74
SubRunNumber_t subRun() const
Definition: Event.h:72
static MetadataManager & getInstance()
Filter events based on their run/event numbers.
SubRunNumber_t subRun() const
Definition: SubRun.h:44
RunEventFilter(fhicl::ParameterSet const &p)
virtual bool beginRun(art::Run &run) override
bool fUseBatchNum
Batch number may be neeed for MC.
const char * p
Definition: xmltok.h:285
vector< vector< double > > clear
OStream cerr
Definition: OStream.cxx:7
std::map< std::string, std::string > & GetMetadata()
std::pair< Spectrum *, CheatDecomp * > make_pair(SpectrumLoaderBase &loader_data, SpectrumLoaderBase &loader_mc, HistAxis *axis, Cut *cut, const SystShifts &shift, const Var &wei)
Definition: DataMCLoad.C:336
std::string fEventFile
List of event numbers.
std::set< unsigned int > fRuns
DEFINE_ART_MODULE(TestTMapFile)
RunNumber_t run() const
Definition: Run.h:47
std::string fSlicerLabel
Module that produced slices.
Definition: Run.h:31
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
std::set< std::pair< unsigned int, unsigned int > > fSubRuns
std::set< std::tuple< unsigned int, unsigned int, unsigned int, unsigned int, unsigned int > > fCycles
std::set< std::tuple< unsigned int, unsigned int, unsigned int > > fEvents
T get(std::string const &key) const
Definition: ParameterSet.h:231
int evt
caf::StandardRecord * sr
EventNumber_t event() const
Definition: Event.h:67
std::set< std::tuple< unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int > > fBatches
virtual bool filter(art::Event &e) override
Definition: run.py:1
bool fIsMC
Data or MC? Hence cycle number.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
std::set< std::tuple< unsigned int, unsigned int, unsigned int, unsigned int > > fSlices
virtual void reconfigure(fhicl::ParameterSet const &p)
virtual bool beginSubRun(art::SubRun &sr) override
int fMode
0=include, 1=exclude list
Float_t e
Definition: plot.C:35
RunNumber_t run() const
Definition: Event.h:77
RunNumber_t run() const
Definition: SubRun.h:49
enum BeamMode string