TimeFilter_module.cc
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 /// \brief Filter events based on their run/subrun and event (trigger) time
3 /// \author lackey32@fnal.gov
4 /// \date
5 ///////////////////////////////////////////////////////////////////////////
6 // C/C++ includes
7 #include <cstdlib>
8 #include <iostream>
9 #include <fstream>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 // Framework includes
20 
21 // Novasoft includes
22 #include "NovaTimingUtilities/TimingUtilities.h"
23 #include "RawData/RawTrigger.h"
24 
25 namespace util {
26  ///
27  /// Select events based on a list of run/subrun and times.
28  /// Compares trigger time of current event with time in input file.
29  /// If the times are within Delta of each other, keep (or exclude) the event.
30  /// File format is expected to be a list of run/subrun/event/event_time:
31  /// # run subrun event event_time
32  /// 100442 18 1963 1578454974.061060
33  /// 100442 28 466 1578457923.335764
34  /// 100442 33 138 1578459414.524462
35  /// with comments marked by a leading '#'.
36  /// The event column is not used, it's just there so the same file can
37  /// be used by a different module for the use-case this was originally designed for.
38  /// (Looking at TB Spill events to determine if FEBs were shutoff for
39  /// a corresponding Beamline event). If you don't have an event number,
40  /// set FileHasEvent to false. By default the module
41  /// looks for these to be in a file called "time-list.txt",
42  /// although the filename can be reconfigured. The module can be
43  /// configured to run in one of two modes. The configuration
44  /// include_runeventfilter sets Mode=0 which means that the events
45  /// listed in the file are to be included in the output. The
46  /// configuration exclude_runeventfilter sets Mode=1 which means
47  /// that the events listed are to be excluded from the output
48  /// file.
49  ///
50  class TimeFilter : public art::EDFilter
51  {
52  public:
53  explicit TimeFilter(fhicl::ParameterSet const& p);
54  virtual ~TimeFilter();
55 
56  virtual void ReadEventFile();
57 
58  virtual bool beginRun(art::Run& run) override;
59  virtual bool beginSubRun(art::SubRun& sr) override;
60  virtual bool filter(art::Event& e) override;
61 
62 
63  private:
64  std::string fRawDataLabel; ///< Raw trigger label (to get trigger/event time)
65  double fDelta; ///< Acceptable difference in trigger timestamp from user-provided time
66  std::string fEventFile; ///< List of run/subrun/evt_times
67  bool fFileHasEvent; ///< True if file-format contains event number (4 columns instead of 3)
68  int fMode; ///< 0=include, 1=exclude list
69 
70  bool fSkip; ///< Parameter to skip full run or subrun
71 
72  std::set<unsigned int> fRuns;
73  std::set< std::pair<unsigned int, unsigned int> > fSubRuns;
74  std::set< std::tuple<unsigned int, unsigned int,
75  double> > fTimes;
76 
77  };
78 }
79 
80 
81 ////////////////////////////////////////////////////////////////////////
82 namespace util
83 {
84  //......................................................................
86  : fRawDataLabel(p.get<std::string>("RawDataLabel")),
87  fDelta(p.get<double>("Delta")),
88  fEventFile(p.get<std::string>("EventFile")),
89  fFileHasEvent(p.get<bool>("FileHasEvent")),
90  fMode(p.get<int>("Mode"))
91  {
92  ReadEventFile();
93  }
94 
95  //......................................................................
97  {
98 
99  fRuns. clear();
100  fSubRuns. clear();
101  fTimes. clear();
102  std::ifstream ifs;
103  ifs.open(fEventFile.c_str());
104  if (ifs.is_open()) {
105  while (ifs.good()) {
106  std::string buff;
107  std::getline(ifs, buff);
108  if (buff[0]=='#') continue;
109 
110  int run, subrun, event;
111  double time;
112 
113  if (fFileHasEvent)
114  sscanf(buff.c_str(), "%d %d %d %lf", &run, &subrun, &event, &time);
115  else
116  sscanf(buff.c_str(), "%d %d %lf", &run, &subrun, &time);
117 
118  fRuns.insert(run);
119  fSubRuns.insert(std::make_pair(run, subrun));
120  fTimes.insert(std::make_tuple(run, subrun, time));
121  } // close while loop
122  ifs.close();
123  } // close input file
124  else {
125  std::cerr << __FILE__ << ":" << __LINE__
126  << " Failed to open file " << fEventFile << " for read"
127  << std::endl;
128  }
129  }
130 
131  //......................................................................
133  {
134  }
135 
136  //......................................................................
138  {
139  fSkip = (fMode == 0 && !fRuns.count(run.run()));
140  return fSkip;
141  }
142 
143  //......................................................................
145  {
146  fSkip = (fMode == 0 && !fSubRuns.count(std::make_pair(sr.run(), sr.subRun())));
147  return fSkip;
148  }
149 
150  //......................................................................
152  {
153 
154  // Skipping full run or subrun
155  if (fSkip){
156  return false;
157  }
158 
159  bool inlist = false;
160  // Is this run/subrun pair in the list?
161  inlist = fSubRuns.count(std::make_pair(evt.run(), evt.subRun()));
162 
163  // If we're looking for the events in the list, and this one isn't, then
164  // we can skip this event.
165  if(fMode == 0 && !inlist){
166  return false;
167  }
168  // If we're rejecting events in the list, and this event is in we can
169  // reject it, so long as it's not just the slices we're supposed to be
170  // rejecting.
171  if(fMode == 1 && inlist){
172  return false;
173  }
174 
175  // Now find the trigger time for this event and compare to list.
177  evt.getByLabel(fRawDataLabel, trigs);
178  const rawdata::RawTrigger trig = trigs->at(0);
179 
180  struct timespec unixTime;
182 
183  unsigned long int unixTimeSec = unixTime.tv_sec;
184  unsigned long int unixTimeNanoSec = unixTime.tv_nsec;
185  double evtTime = unixTimeSec + (1e-9)*unixTimeNanoSec;
186 
187  // lower_bound returns value in set just above (or equal to) the key you give it
188  // in this case, returns the first input event time after the current event's trigger time
189  // (so the first event time that could be contained within the current trigger)
190  // Then check the time difference between the trigger time and the time you're trying to match
191  // If the delta is too large, reject the event (or keep if mode is 1)
192  std::set< std::tuple<unsigned int, unsigned int, double> >::iterator it
193  = fTimes.lower_bound(std::make_tuple(evt.run(),evt.subRun(),evtTime));
194  double input_time = std::get<2>(*it);
195  // bound function will only find *next* time in list. Check previous time to see if diff is closer.
196  it--;
197  double input_time_prev = std::get<2>(*it);
198  double diff = evtTime - input_time;
199  double diff2 = evtTime - input_time_prev;
200  if (abs(diff2)<abs(diff)) {
201  input_time = input_time_prev;
202  diff = diff2;
203  }
204 
205  // If we're keeping times in the list, and this event has too large
206  // a time difference, reject it.
207  if (fMode == 0 && abs(diff) > fDelta){
208  return false;
209  }
210  // If we're rejecting times in the list, and this event is within Delta
211  // of a time in the list, reject it.
212  if (fMode == 1 && abs(diff) <= fDelta){
213  return false;
214  }
215 
216  LOG_INFO("TimeFilter")<<"Kept (or rejected if Mode=1) event with trigger time: "<<std::fixed<<evtTime
217  <<". Closest time in list: "<<input_time<<". Diff: "<<diff<<std::endl;
218 
219  return true;
220  }
221 
222 } // end namespace util
223 
224 
225 ////////////////////////////////////////////////////////////////////////
226 namespace util
227 {
229 }
230 ////////////////////////////////////////////////////////////////////////
std::set< std::pair< unsigned int, unsigned int > > fSubRuns
SubRunNumber_t subRun() const
Definition: Event.h:72
Filter events based on their run/event numbers.
set< int >::iterator it
SubRunNumber_t subRun() const
Definition: SubRun.h:44
TimeFilter(fhicl::ParameterSet const &p)
const char * p
Definition: xmltok.h:285
vector< vector< double > > clear
std::set< std::tuple< unsigned int, unsigned int, double > > fTimes
std::set< unsigned int > fRuns
OStream cerr
Definition: OStream.cxx:7
void abs(TH1 *hist)
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
virtual void ReadEventFile()
DEFINE_ART_MODULE(TestTMapFile)
RunNumber_t run() const
Definition: Run.h:47
bool convertNovaTimeToUnixTime(uint64_t const &inputNovaTime, struct timespec &outputUnixTime)
::xsd::cxx::tree::time< char, simple_type > time
Definition: Database.h:194
std::string fEventFile
List of run/subrun/evt_times.
Definition: Run.h:31
virtual bool beginRun(art::Run &run) override
int fMode
0=include, 1=exclude list
bool fSkip
Parameter to skip full run or subrun.
Definition: run.py:1
bool fFileHasEvent
True if file-format contains event number (4 columns instead of 3)
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
virtual bool beginSubRun(art::SubRun &sr) override
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
unsigned long long fTriggerTimingMarker_TimeStart
Definition: RawTrigger.h:38
#define LOG_INFO(stream)
Definition: Messenger.h:144
std::string fRawDataLabel
Raw trigger label (to get trigger/event time)
double fDelta
Acceptable difference in trigger timestamp from user-provided time.
Float_t e
Definition: plot.C:35
RunNumber_t run() const
Definition: Event.h:77
RunNumber_t run() const
Definition: SubRun.h:49
virtual bool filter(art::Event &e) override
static constexpr Double_t sr
Definition: Munits.h:164