BadDataFilter_module.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file BadDataFilter.cxx
4 /// \brief Filter events from periods of bad data taking.
5 /// \author messier@indiana.edu
6 /// \date 04/24/2014
7 ///
8 /////////////////////////////////////////////////////////////////////////
9 // System includes
10 #include <sstream>
11 // ROOT includes
12 #include "TTimeStamp.h"
13 // ART includes
14 #include <cetlib_except/exception.h>
21 // NOVA includes
22 #ifdef NOVACMAKE
23 #include "Database/cxx/include/Table.h"
24 #include "Database/cxx/include/Util.h"
25 #else
26 #include "Database/Table.h"
27 #include "Database/Util.h"
28 #endif
29 #include "NovaDAQConventions/DAQConventions.h"
30 #include "SummaryData/RunData.h"
31 
32 
33 namespace runh
34 {
36  {
37  private:
38  int fRun; ///< Current run
39  int fSubrun; ///< Current subrun
40  bool fGoodRun; ///< Is the current run good?
41  bool fGoodSubrun; ///< Is the current subrun good?
42  unsigned int fBadSubrunSz; ///< # of bad subrun ranges for this run
43  unsigned int fBadTimeSz; ///< # of bad time ranges for this run
44  ///
45  /// Encapsulation of the database tables
46  ///
47  typedef std::pair<int,int> SubrunPair_t;
48  typedef std::pair<art::TimeValue_t,art::TimeValue_t> TimeValuePair_t;
49  std::vector<SubrunPair_t> fBadSubrun;
50  std::vector<TimeValuePair_t> fBadTime;
51 
52  public:
53  explicit BadDataFilter(fhicl::ParameterSet const& p) {}
54  virtual ~BadDataFilter() {}
55  virtual void reconfigure(fhicl::ParameterSet const& p) {}
56 
57  ///..................................................................
58  /// Load the data from the bad_subruns table into the module
59  ///
60  void LoadBadSubruns(int run, const std::string& det)
61  {
62  //
63  // Construct the handle to the bad_subruns database table
64  //
65  static const char* dbxml = "RunHistory/tables/BadSubruns.xml";
66  std::unique_ptr<nova::dbi::Table> table =
67  std::unique_ptr<nova::dbi::Table>(new nova::dbi::Table(dbxml));
68  table->SetDetector(det);
69  table->SetValidityRange("run",run);
70  table->LoadFromDB();
71  //if(table->LoadFromDB()) std::abort();
72  bool sucess = table->LoadFromDB();
73  if(sucess) std::cout<<"DEBUG:sucess"<<std::endl;
74  else std::cout<<"DEBUG:faiure"<<std::endl;
75  int sr1Idx = table->GetColIndex("subrun1");
76  int sr2Idx = table->GetColIndex("subrun2");
77 
78  //
79  // Add each row to the list of bad subrun periods
80  //
81  for (int i=0; i<table->NRow(); ++i) {
82  nova::dbi::Row* row = table->GetRow(i);
83 
84  int subrun1, subrun2;
85  row->Col(sr1Idx).Get(subrun1);
86  row->Col(sr2Idx).Get(subrun2);
87  fBadSubrun.push_back(SubrunPair_t(subrun1, subrun2));
88  }
89  fBadSubrunSz = fBadSubrun.size();
90  }
91 
92  ///.................................................................
93  /// Shuffle the text time stamp into a 64-bit word in the ART
94  /// format. Time is only accurate to nearest second; as such
95  /// its OK to leave the lower 32 bits set to 0
96  ///
97  /// @param t - text time stamp in format 1970-12-12 10:11:12
98  ///
100  struct tm tm1;
101  strptime(t.c_str(), "%Y-%m-%d %H:%M:%S",&tm1);
102  tm1.tm_year += 1900;
103  TTimeStamp ts(tm1.tm_year, tm1.tm_mon, tm1.tm_mday,
104  tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
105  art::TimeValue_t tv = (ts.GetSec() << 32);
106  return tv;
107  }
108 
109  ///.................................................................
110  /// This method should eventually read a database table of bad
111  /// time ranges into memory. Its a hook for possible future
112  /// implementation. Currently we have no mechanism for flagging
113  /// bad time ranges. Pattern should follow LoadBadSubruns above.
114  ///
116  {
117  //
118  // Construct the handle to the bad_time_ranges database table
119  //
120  static const char* dbxml = "RunHistory/tables/BadTimeRanges.xml";
121  std::unique_ptr<nova::dbi::Table> table =
122  std::unique_ptr<nova::dbi::Table>(new nova::dbi::Table(dbxml));
123  table->SetDetector(det);
124  table->SetValidityRange("run",run);
125  table->LoadFromDB();
126  bool sucess = table->LoadFromDB();
127  if(sucess) std::cout<<"DEBUG:sucess"<<std::endl;
128  else std::cout<<"DEBUG:faiure"<<std::endl;
129 
130 
131 
132 
133 
134 // if(!table->LoadFromDB()) std::abort();
135 
136  // Add each row to the list of bad subrun periods
137  //
138  int t1Idx=table->GetColIndex("t1");
139  int t2Idx=table->GetColIndex("t2");
140 
141  for (int i=0; i<table->NRow(); ++i) {
142  nova::dbi::Row* row = table->GetRow(i);
143 
144  std::string t1, t2;
145  row->Col(t1Idx).Get(t1);
146  row->Col(t2Idx).Get(t2);
147 
148  art::TimeValue_t tv1, tv2;
149  tv1 = this->TextToTimeValue(t1);
150  tv2 = this->TextToTimeValue(t2);
151 
152  fBadTime.push_back(TimeValuePair_t(tv1,tv2));
153  }
154  fBadTimeSz = fBadTime.size();
155  }
156 
157  ///.................................................................
158  /// At the start of a new run, connect to the database and pull
159  /// down any information about intervals of bad data.
160  ///
161  virtual bool beginRun(art::Run& r)
162  {
163  fRun = r.run();
164  //
165  // Extract the run summary data to discover the detector ID for
166  // this data
167  //
168  std::vector<art::Handle<sumdata::RunData>> rdcol;
169  r.getManyByType(rdcol);
171  if (!rdcol.empty()) {
172  det = novadaq::cnv::DetInfo::GetName(rdcol[0]->DetId());
173  }
174  else {
175 
176  // abort();
177  throw cet::exception("BadDataFilter") <<
178  "Cannot find sumdata::RunData" << std::endl;
179  }
180 
181  //
182  // Reset everything for this run to the good state
183  //
184  fGoodRun = true;
185  fBadSubrun.clear();
186  fBadTime. clear();
187 
188  //
189  // Now load bad periods from the database
190  //
191  this->LoadBadSubruns(fRun, det);
192  this->LoadBadTimeRanges(fRun, det);
193 
194  return fGoodRun;
195  }
196 
197  ///.................................................................
198  /// At the start of a new subrun check the list of bad subrun
199  /// ranges and mark the subrun accordingly
200  ///
201  virtual bool beginSubRun(art::SubRun& s)
202  {
203  fSubrun = s.subRun();
204 
205  fGoodSubrun = fGoodRun;
206  if (fGoodSubrun==false) {
207  std::cout << "Subrun " << fRun << ":" << fSubrun
208  << " is in bad run. Skipped."
209  << std::endl;
210  return false;
211  }
212  else {
213  //
214  // Its a good run. Check if there are any bad periods. If not,
215  // return 'good'.
216  //
217  if (fBadSubrunSz==0) return true;
218  }
219 
220  //
221  // Get here on good runs with bad subruns flagged
222  //
223  for (unsigned int i=0; i<fBadSubrunSz; ++i) {
224  if (fSubrun>=fBadSubrun[i].first &&
225  fSubrun<=fBadSubrun[i].second) {
226  std::cout << "Subrun " << fRun << ":" << fSubrun
227  << " is flagged as bad. Skipped."
228  << std::endl;
229  fGoodSubrun = false;
230  return fGoodSubrun;
231  }
232  }
233  return true;
234  }
235 
236  ///.................................................................
237  /// Check if this event should be filtered. Pass good data and
238  /// fail bad data
239  ///
240  virtual bool filter(art::Event& e)
241  {
242  //
243  // Not strictly necessary, but check if we are in a bad run or
244  // subrun
245  //
246  if (fGoodRun==false||fGoodSubrun==false) return false;
247 
248  //
249  // If there are no time ranges to check, then the event must be
250  // good
251  //
252  if (fBadTimeSz==0) return true;
253 
254  //
255  // Only thing left to check is the event time. Times in the
256  // table are already converted to ART 64-bit time.
257  //
258  art::TimeValue_t t = e.time().value();
259  for (unsigned int i=0; i<fBadTimeSz; ++i) {
260  if (t>=fBadTime[i].first && t<=fBadTime[i].second) {
261  std::cout << "Event "
262  << e.run() << ":"
263  << e.subRun() << ":"
264  << e.event()
265  << " is inside bad time range. Skipped." << std::endl;
266  return false;
267  }
268  }
269  return true;
270  }
271  }; // class BadDataFilter...
272 } // namespace runh
274 ////////////////////////////////////////////////////////////////////////
static std::string GetName(int id)
std::vector< SubrunPair_t > fBadSubrun
SubRunNumber_t subRun() const
Definition: Event.h:72
std::vector< TimeValuePair_t > fBadTime
virtual bool filter(art::Event &e)
Column & Col(int i)
Find index of column with name. Suitable for passing to Col.
Definition: Row.h:63
bool fGoodSubrun
Is the current subrun good?
SubRunNumber_t subRun() const
Definition: SubRun.h:44
std::pair< int, int > SubrunPair_t
virtual bool beginRun(art::Run &r)
const char * p
Definition: xmltok.h:285
vector< vector< double > > clear
unsigned int fBadSubrunSz
of bad subrun ranges for this run
void LoadBadSubruns(int run, const std::string &det)
::xsd::cxx::tree::exception< char > exception
Definition: Database.h:225
DEFINE_ART_MODULE(TestTMapFile)
RunNumber_t run() const
Definition: Run.h:47
int fSubrun
Current subrun.
bool Get(T &val) const
Definition: Column.h:85
virtual void reconfigure(fhicl::ParameterSet const &p)
constexpr TimeValue_t value() const
Definition: Timestamp.h:24
std::pair< art::TimeValue_t, art::TimeValue_t > TimeValuePair_t
Definition: Run.h:31
const XML_Char * s
Definition: expat.h:262
virtual bool beginSubRun(art::SubRun &s)
art::TimeValue_t TextToTimeValue(const std::string &t)
void getManyByType(std::vector< Handle< PROD >> &results) const
Definition: DataViewImpl.h:446
BadDataFilter(fhicl::ParameterSet const &p)
EventNumber_t event() const
Definition: Event.h:67
double t2
void LoadBadTimeRanges(int run, const std::string &det)
bool fGoodRun
Is the current run good?
Definition: run.py:1
OStream cout
Definition: OStream.cxx:6
std::uint64_t TimeValue_t
Definition: Timestamp.h:7
struct Table Table
Definition: TexBuilder.h:2
TRandom3 r(0)
Timestamp time() const
Definition: Event.h:61
Float_t e
Definition: plot.C:35
RunNumber_t run() const
Definition: Event.h:77
enum BeamMode string