EventFEBStatus_module.cc
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 // \file EventFEBStatus_module.cc
3 // \brief Analyzer module that counts hits on each FEB to determine if the FEB was live for a given event time.
4 // \author lackey32@fnal.gov
5 ////////////////////////////////////////////////////////////////////////
6 
7 // C/C++ includes
8 #include <map>
9 #include <set>
10 #include <string>
11 
12 // ROOT includes
13 #include "TTree.h"
14 #include "TH2F.h"
15 #include "TFile.h"
16 
17 // Framework includes
28 #include "fhiclcpp/ParameterSet.h"
30 
31 // Novasoft DAQ includes
32 #include "DAQChannelMap/DAQChannelMap.h"
33 #include "NovaDAQConventions/DAQConventions.h"
34 // Novasoft includes
36 #include "NovaTimingUtilities/TimingUtilities.h"
37 #include "RawData/RawDigit.h"
38 #include "RawData/RawTrigger.h"
39 
40 namespace febstat {
42  public:
43  explicit EventFEBStatus(fhicl::ParameterSet const& pset);
45  void ReadEventFile();
46  void beginJob() override;
47  void analyze(const art::Event& evt) override;
48  void ClearMapAndVectors();
49 
50  private:
51 
52  std::string fRawDataLabel; ///< Module that produced raw digits (to get trigger/event time)
53  std::string fCellHitLabel; ///< Module that produced cell hits
54  std::string fEventFile; ///< List of run/subrun/event/evt_times
55  double fWindow; ///< Time window to check before/after event
56  unsigned int fNhitCut; ///< If # hits on an FEB in fWindow before or after the event time is below this, the feb is marked bad
57 
58  int run;
59  int subrun;
60  int spillEvent; ///< Event number of current art event (last event with window in it is the number that goes in the TTree)
61  int beamlineEvent; ///< Event number of corresponding event in Beamline stream (provided in event-list file)
62  Double_t spillEvtTime; ///< Trigger time of current art event
63  Double_t beamlineEvtTime; ///< Trigger time of corresponding Beamline event
64  std::vector<uint32_t> dcm;
65  std::vector<uint32_t> feb;
66  std::vector<int> nhit_pre; ///< Number of hits in fWindow before beamline event time
67  std::vector<int> nhit_post; ///< Number of hits in fWindow after beamline event time
68  std::vector<bool> febStatus; ///< 0 if nhit_pre or nhit_post is less than fNhitCut
69  std::vector<bool> febShutoffBit; ///< 1 if shutoff bit set prior to event time and FEB recorded no hits after
70  bool eventStatus; ///< 0 if any FEB has a status of 0
71 
72  TTree *febshutoff;
73 
74  std::set<unsigned int> fRuns;
75  std::set< std::pair<unsigned int, unsigned int> > fSubRuns;
76  std::set< std::tuple<unsigned int, unsigned int, double> > fTimes;
77 
78  std::map< double, unsigned int > fEventMap; ///< Map of beamline event time to event number
79 
80  std::map< std::pair<unsigned int, unsigned int> ,
81  std::pair<unsigned int, unsigned int> > fFEBhitsNULL; ///< Null map to set hit count to zero for every FEB
82  std::map< std::pair<unsigned int, unsigned int> ,
83  std::pair<unsigned int, unsigned int> > fFEBhits; ///< Map of hits counts before and after event for each dcm,feb combination
84 
85  std::map< std::pair<unsigned int, unsigned int>,
86  std::pair<bool, double> > fShutoffMapNULL; ///< Null map to reset shutoff state for every FEB
87  std::map< std::pair<unsigned int, unsigned int>,
88  std::pair<bool, double> > fShutoffMap; ///< Map of shutoff status and last hit time for each dcm,feb combination
89 
90  // Completeness booleans to determine if map needs to be reset
91  bool completePre; ///< Have we looked at the full fWindow before the event?
92  bool completePost; ///< Have we looked at the full fWindow after the event?
93 
94  };
95 
96  //......................................................................
97 
99  : EDAnalyzer(pset),
100  fRawDataLabel(pset.get<std::string>("RawDataLabel")),
101  fCellHitLabel(pset.get<std::string>("CellHitLabel")),
102  fEventFile(pset.get<std::string>("EventFile")),
103  fWindow(pset.get<double>("Window")),
104  fNhitCut(pset.get<unsigned int>("NhitCut"))
105  {
106  ReadEventFile();
107  }
108 
109  //......................................................................
110 
112  {
113  }
114 
115  //......................................................................
116  ///
117  /// Read in beamline event information from text file.
118  /// File format should be (lines starting with # are ignored):
119  /// # run subrun event event time
120  /// 100792 1 3860 1583451706.619207
121  /// 100792 2 13403 1583452785.790757
122  /// 100792 5 9158 1583454586.687062
123  /// 100792 7 11686 1583455849.647850
124  ///
126  {
127  fRuns. clear();
128  fSubRuns. clear();
129  fTimes. clear();
130  std::ifstream ifs;
131  ifs.open(fEventFile.c_str());
132  if (ifs.is_open()) {
133  while (ifs.good()) {
134  std::string buff;
135  std::getline(ifs, buff);
136  if (buff[0]=='#') continue;
137 
138  int run, subrun, event;
139  double time;
140 
141  sscanf(buff.c_str(), "%d %d %d %lf", &run, &subrun, &event, &time);
142 
143  fRuns.insert(run);
144  fSubRuns.insert(std::make_pair(run, subrun));
145  fEventMap.insert( std::pair<double, unsigned int>(time, event) );
146  fTimes.insert(std::make_tuple(run, subrun, time));
147  } // close while loop
148  ifs.close();
149  } // close input file
150  else {
151  std::cerr << __FILE__ << ":" << __LINE__
152  << " Failed to open file " << fEventFile << " for read"
153  << std::endl;
154  }
155 
156  }
157 
158  //......................................................................
159  ///
160  /// Clear vectors and map that are filled for each beamline event.
161  /// Since these are filled by beamline event, but this module runs over the spill stream,
162  /// they should not be cleared after each art event, but rather once we know we have the
163  /// full window before/after the time of interest.
164  ///
166  {
167  fFEBhits.clear();
168  // Cleanup vectors
169  dcm.clear();
170  feb.clear();
171  nhit_pre.clear();
172  nhit_post.clear();
173  febStatus.clear();
174  febShutoffBit.clear();
175 
176  // Reset map to zeros and completion flags to false
179  completePre = false;
180  completePost = false;
181 
182  }
183 
184  //......................................................................
185 
187  {
188 
189  // Initialize null map
190  for (unsigned int dcmId=1; dcmId<4; ++dcmId){
191  for (unsigned int febId=0; febId<64; ++febId){
192  if ( (dcmId<3&&(febId==8||febId==24||febId==40||febId==56)) || (dcmId==2&&(febId==47||febId==63)) || (dcmId==3&&febId>7) )
193  continue;
194  fFEBhitsNULL.insert(std::pair <std::pair <unsigned int, unsigned int>, std::pair <unsigned int, unsigned int> >
195  (std::make_pair(dcmId,febId),std::make_pair(0,0)));
196  // Start with assuming all FEBs are shutoff - only set to false if a hit is detected in 110 ms before
197  // This takes care of FEBs that didn't have a single hit during this time and therefore did not report the shutoff bit.
198  fShutoffMapNULL.insert(std::pair <std::pair <unsigned int, unsigned int>, std::pair <bool, double> >
199  (std::make_pair(dcmId,febId),std::make_pair(true,0)));
200  }
201  }
203 
205  febshutoff = tfs->make<TTree>("evts","");
206  febshutoff->Branch("run",&run,"run/I");
207  febshutoff->Branch("subrun",&subrun,"subrun/I");
208  febshutoff->Branch("spillEvent",&spillEvent,"spillEvent/I");
209  febshutoff->Branch("beamlineEvent",&beamlineEvent,"beamlineEvent/I");
210  febshutoff->Branch("dcm",&dcm);
211  febshutoff->Branch("feb",&feb);
212  febshutoff->Branch("spillEvtTime",&spillEvtTime,"spillEvtTime/D");
213  febshutoff->Branch("beamlineEvtTime",&beamlineEvtTime,"beamlineEvtTime/D");
214  febshutoff->Branch("nhit_pre",&nhit_pre);
215  febshutoff->Branch("nhit_post",&nhit_post);
216  febshutoff->Branch("febStatus",&febStatus);
217  febshutoff->Branch("eventStatus",&eventStatus,"eventStatus/O");
218 
219  febshutoff->Branch("febShutoffBit",&febShutoffBit);
220 
221  }
222 
223  //......................................................................
224 
226 
227 {
228  bool inlist = false;
229  // Is this run/subrun pair in the list?
230  inlist = fSubRuns.count(std::make_pair(evt.run(), evt.subRun()));
231 
232  // Skip the event if the run, subrun pair is not in the list
233  if(!inlist){
234  return;
235  }
236 
237  run = evt.run();
238  subrun = evt.subRun();
239  spillEvent = evt.event();
240 
241  // Load services
243 
244  // Get trigger time
246  evt.getByLabel(fRawDataLabel, trigs);
247  const rawdata::RawTrigger trig = trigs->at(0);
248 
249  struct timespec unixTime;
251  unsigned long int unixTimeSec = unixTime.tv_sec;
252  unsigned long int unixTimeNanoSec = unixTime.tv_nsec;
253  spillEvtTime = unixTimeSec + (1e-9)*unixTimeNanoSec;
254 
255  // Check event list for first time after current trigger time (first time potentially contained within event)
256  std::set< std::tuple<unsigned int, unsigned int, double> >::iterator setIt
257  = fTimes.lower_bound(std::make_tuple(run,subrun,spillEvtTime));
258  beamlineEvtTime = std::get<2>(*setIt);
259  //bound functiion will only find *next* time in list. Check previous time to see if diff is closer.
260  setIt--;
261  double beamlineEvtTime_prev = std::get<2>(*setIt);
262  double diff = beamlineEvtTime - spillEvtTime;
263  double diff2 = beamlineEvtTime_prev - spillEvtTime;
264  if (abs(diff2)<abs(diff)){
265  beamlineEvtTime = beamlineEvtTime_prev;
266  diff = diff2;
267  }
268  // Skip event if it does not contain any of window of interest
269  //if ( (diff-fWindow<0 || diff-fWindow>0.2) && (diff+fWindow<0 || diff+fWindow>0.2) )
270  // Need to keep longer before for shutfoff bit stuff
271  if ( (diff-0.11<0 || diff-0.11>0.2) && (diff+fWindow<0 || diff+fWindow>0.2) )
272  return;
273 
274  // Lookup beamline event number in event map using beamline event time
275  beamlineEvent = fEventMap.find(beamlineEvtTime)->second;
276 
277  // Check if you have the full time window of interest yet
278  if (!completePre && spillEvtTime < (beamlineEvtTime-fWindow) ){
279  completePre = true;
280  }
281  if (!completePost && (spillEvtTime + 0.2) > (beamlineEvtTime+fWindow) ) {
282  completePost = true;
283  }
284 
285  // Get CellHits
287  evt.getByLabel(fCellHitLabel,cellhits);
288  double hitTimePrev = 0;
289  for (unsigned int hitIdx=0; hitIdx<cellhits->size(); ++hitIdx){
290  art::Ptr<rb::CellHit> ihit(cellhits,hitIdx);
291  uint32_t dchan = ihit->DaqChannel();
292  unsigned int dcmId = cmap->Map()->getDCM(dchan);
293  unsigned int febId = cmap->Map()->getFEB(dchan);
294  double hitTime = spillEvtTime + ihit->TNS()*1e-9;
295 
296 
297  // Check for FEB shutoff in 110 ms before event
298  if ( (beamlineEvtTime - hitTime) < 0.110 && (beamlineEvtTime - hitTime) > 0 ) {
299  uint8_t febStatusNano = ihit->fFEBStatus;
300  hitTimePrev = fShutoffMap.at(std::make_pair(dcmId,febId)).second;
301  if ( febStatusNano == 32) {
302  //std::cout<<std::fixed<<"Shutoff detected. dcm: "<<dcmId<<" feb: "<<febId<<" hitTime: "<<hitTime<<std::endl;
303  fShutoffMap.at(std::make_pair(dcmId,febId)).first = true;
304  fShutoffMap.at(std::make_pair(dcmId,febId)).second = hitTime;
305  }
306  else if (febStatusNano == 48 && hitTime > hitTimePrev ) {
307  //if (fShutoffMap.at(std::make_pair(dcmId,febId)).first)
308  //std::cout<<std::fixed<<"Hits after shutoff. dcm: "<<dcmId<<" feb: "<<febId<<" hitTime: "<<hitTime<<std::endl;
309  fShutoffMap.at(std::make_pair(dcmId,febId)).first = false;
310  fShutoffMap.at(std::make_pair(dcmId,febId)).second = hitTime;
311  }
312  }
313 
314  // count hits for fWindow before
315  if ( (beamlineEvtTime - hitTime) < fWindow && (beamlineEvtTime - hitTime) > 0 ) {
316  fFEBhits.at(std::make_pair(dcmId,febId)).first++;
317  }
318  // count hits for fWindow after
319  else if ( (hitTime - beamlineEvtTime) < fWindow && (hitTime - beamlineEvtTime) > 0 ) {
320  fFEBhits.at(std::make_pair(dcmId,febId)).second++;
321  }
322 
323  } // end loop over cellhits
324 
325 
326  // Fill tree if we have information from the full window and reset map to zeroes
327  if (completePre && completePost) {
328 
329  // Iterate over map and fill nhit stuff, including boolean of good/bad feb
330  for (auto &mapIt: fFEBhits) {
331  dcm.push_back((mapIt.first).first);
332  feb.push_back((mapIt.first).second);
333  nhit_pre.push_back((mapIt.second).first);
334  nhit_post.push_back((mapIt.second).second);
335  if ( (mapIt.second).first > fNhitCut && (mapIt.second).second > fNhitCut )
336  febStatus.push_back(1);
337  else
338  febStatus.push_back(0);
339  } // end loop over map
340 
341  // Iterate over shutoff bit map and fill
342  for (auto &mapIt: fShutoffMap) {
343  febShutoffBit.push_back((mapIt.second).first);
344  }
345 
346  if (std::count(febStatus.begin(), febStatus.end(), true) == 126)
347  eventStatus = 1;
348  else
349  eventStatus = 0;
350 
351  febshutoff->Fill();
353 
354  } // end filling tree
355 
356  } // end analyze
357 
358  //......................................................................
360 } // end namespace febstat
float TNS() const
Definition: CellHit.h:46
SubRunNumber_t subRun() const
Definition: Event.h:72
double fWindow
Time window to check before/after event.
std::vector< bool > febShutoffBit
1 if shutoff bit set prior to event time and FEB recorded no hits after
std::string fEventFile
List of run/subrun/event/evt_times.
std::vector< uint32_t > feb
Double_t spillEvtTime
Trigger time of current art event.
std::map< std::pair< unsigned int, unsigned int >, std::pair< bool, double > > fShutoffMapNULL
Null map to reset shutoff state for every FEB.
vector< vector< double > > clear
OStream cerr
Definition: OStream.cxx:7
const daqchannelmap::DAQChannelMap * Map() const
Definition: CMap.h:57
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
std::string fCellHitLabel
Module that produced cell hits.
DEFINE_ART_MODULE(TestTMapFile)
bool convertNovaTimeToUnixTime(uint64_t const &inputNovaTime, struct timespec &outputUnixTime)
::xsd::cxx::tree::time< char, simple_type > time
Definition: Database.h:194
std::vector< uint32_t > dcm
uint32_t DaqChannel() const
Definition: RawDigit.h:85
std::vector< int > nhit_pre
Number of hits in fWindow before beamline event time.
std::map< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > fFEBhits
Map of hits counts before and after event for each dcm,feb combination.
std::set< std::pair< unsigned int, unsigned int > > fSubRuns
EventNumber_t event() const
Definition: Event.h:67
EDAnalyzer(Table< Config > const &config)
Definition: EDAnalyzer.h:100
Double_t beamlineEvtTime
Trigger time of corresponding Beamline event.
std::set< std::tuple< unsigned int, unsigned int, double > > fTimes
bool completePost
Have we looked at the full fWindow after the event?
std::map< std::pair< unsigned int, unsigned int >, std::pair< bool, double > > fShutoffMap
Map of shutoff status and last hit time for each dcm,feb combination.
Definition: run.py:1
unsigned int fNhitCut
If # hits on an FEB in fWindow before or after the event time is below this, the feb is marked bad...
bool completePre
Have we looked at the full fWindow before the event?
EventFEBStatus(fhicl::ParameterSet const &pset)
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
T * make(ARGS...args) const
std::map< double, unsigned int > fEventMap
Map of beamline event time to event number.
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
void analyze(const art::Event &evt) override
int beamlineEvent
Event number of corresponding event in Beamline stream (provided in event-list file) ...
int spillEvent
Event number of current art event (last event with window in it is the number that goes in the TTree)...
dcm_id_t getDCM(dchan daqchan) const
Decode the dcm ID from a dchan.
std::map< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > fFEBhitsNULL
Null map to set hit count to zero for every FEB.
std::set< unsigned int > fRuns
Float_t e
Definition: plot.C:35
uint32_t dchan
< DAQ Channel Map Package
RunNumber_t run() const
Definition: Event.h:77
bool eventStatus
0 if any FEB has a status of 0
std::vector< bool > febStatus
0 if nhit_pre or nhit_post is less than fNhitCut
std::vector< int > nhit_post
Number of hits in fWindow after beamline event time.
std::string fRawDataLabel
Module that produced raw digits (to get trigger/event time)
feb_t getFEB(dchan daqchan) const
Decode the feb id from a dchan.
uint8_t fFEBStatus
Definition: RawDigit.h:43