RunHistory.cxx
Go to the documentation of this file.
1 #include <RunHistory/RunHistory.h>
2 #include <DatabaseUtils/DAQConfig/PixelEnableMasks.h>
3 #include <DatabaseUtils/DAQConfig/PixelThresholds.h>
4 #include <DatabaseUtils/DCS/APDSettings.h>
5 #include <DAQChannelMap/DAQChannelMap.h>
6 #ifdef NOVACMAKE
7 #include <Database/cxx/include/Table.h>
8 #include <Database/cxx/include/Util.h>
9 #else
10 #include <Database/Table.h>
11 #include <Database/Util.h>
12 #endif
13 
15 #include <cetlib_except/exception.h>
16 
17 #include <cstdlib>
18 #include <bitset>
19 #include <algorithm>
20 #include <iostream>
21 #include <iomanip>
22 #include <TTimeStamp.h>
23 #include <TStopwatch.h>
24 
25 namespace db = nova::dbi;
26 namespace dcscfg = dbutils::dcs;
27 namespace daqcfg = dbutils::daqconfig;
28 
29 namespace nova {
30  namespace dbi {
31 
32  std::map<HardwareLocation, std::pair<FEBInfo, APDInfo>> gLocToFA; // map of location in DAQ space
33  // to the connected FEB and APD
34 
35  //**********************************************************************
37  std::unique_ptr<Table> const& hwTable)
38  {
39  bool gotConnection = hwTable->GetConnection();
40 
41  if (!gotConnection) {
42  LOG_WARNING("RunHistory") << "Failed to connect to hardware database! "
43  << "Failed to load hardware info.";
44  return nullptr;
45  }
46  LOG_DEBUG("RunHistory") << "about to execute query\n"
47  << query;
48 
49  PGresult *res = nullptr;
50 
51  if (hwTable->ExecuteSQL(query,res)) {
52  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
53  LOG_WARNING("RunHistory") << "Query failed: " << query;
54  PQclear(res);
55  hwTable->CloseConnection();
56  return nullptr;
57  }
58  } // end if the query worked
59  else {
60  LOG_WARNING("RunHistory") << "SQL error, failed query: " << query;
61  PQclear(res);
62  hwTable->CloseConnection();
63  return nullptr;
64  }
65 
66  LOG_DEBUG("RunHistory") << "query returned " << PQntuples(res) << " rows";
67 
68  return res;
69  }
70 
71  //**********************************************************************
73  {
74  return (db1.num < db2.num);
75  }
76 
77  //**********************************************************************
78 
80  {
81  isEnabled = false;
82  hasAPD = false;
83  apdV = 0;
84  isCooled = false;
85  tempEnabled = false;
86  temperature = -100;
87  gain = 0.;
88  pixelMask = 0xFFFFFFFF;
89  pixelGain.resize(32, 100.);
90  pixelThresh.resize(32, 0.);
91  }
92 
93  //**********************************************************************
94 
96  : _abort(0)
98  , _runNumber(-1)
99  , _nsubrun(0)
100  , _nTotTrig(0)
101  , _nActiveChannels(0)
102  , _nTotalChannels(0)
103  , _nTotalFEBs(0)
104  , _detId(novadaq::cnv::kUNKNOWN_DET)
105  , _partition(-1)
106  , _nDCMs(0)
107  , _dbname("")
108  , _dbhost("")
109  , _dbuser("")
110  , _dbport("")
111  , _tStart("2010-01-01 00:00:00")
112  , _tEnd("")
113  , _dbList(0)
114  , _bnevbList(0)
115  {
116  _badChanVersion="";
117  _dbMaskTag="";
118  _runType="";
119  _npot = 0.;
120  _avgpot = 0.;
121  _nInstalledAPDs=0;
125  _timeQueries=false;
126  _timeParsing=false;
128  _nRetryLoads = 0;
129  _getDiBlockMaskFromCondb = false;
130  _detGainTag="";
131  _verbosity=0;
132  _currentSR=0;
133  _ndRHCRunStart.clear();
134  _ndRHCRunStop.clear();
135  _fdRHCRunStart.clear();
136  _fdRHCRunStop.clear();
137  }
138  //**********************************************************************
139 
141  : _abort(0)
143  , _runNumber(run)
144  , _nsubrun(0)
145  , _nTotTrig(0)
146  , _nActiveChannels(0)
147  , _nTotalChannels(0)
148  , _nTotalFEBs(0)
149  , _partition(-1)
150  , _nDCMs(0)
151  , _dbname("")
152  , _dbhost("")
153  , _dbuser("")
154  , _dbport("")
155  , _tStart("2010-01-01 00:00:00")
156  , _tEnd("")
157  , _dbList(0)
158  , _bnevbList(0)
159  {
160  _badChanVersion="";
161  _dbMaskTag="";
162  _runType="";
163  _npot = 0.;
164  _avgpot = 0.;
165  _nInstalledAPDs=0;
167  _verbosity=0;
168 
169  SetDetector(det);
171  _timeQueries=false;
172  _timeParsing=false;
174  _nRetryLoads = 0;
175  _getDiBlockMaskFromCondb = false;
176  _detGainTag="";
177  _currentSR=0;
178  _ndRHCRunStart.clear();
179  _ndRHCRunStop.clear();
180  _fdRHCRunStart.clear();
181  _fdRHCRunStop.clear();
182  }
183  //**********************************************************************
184 
186  : _runNumber(run)
187  , _nsubrun(0)
188  , _nTotTrig(0)
189  , _nActiveChannels(0)
190  , _nTotalChannels(0)
191  , _nTotalFEBs(0)
192  , _partition(-1)
193  , _nDCMs(0)
194  , _dbname("")
195  , _dbhost("")
196  , _dbuser("")
197  , _dbport("")
198  , _tStart("2010-01-01 00:00:00")
199  , _tEnd("")
200  , _dbList(0)
201  , _bnevbList(0)
202  {
203  _badChanVersion="";
204  _dbMaskTag="";
205  _runType="";
206  _npot = 0.;
207  _avgpot = 0.;
208  _nInstalledAPDs=0;
210 
211  SetDetector(det);
213  _timeQueries=false;
214  _timeParsing=false;
216  _nRetryLoads = 0;
217  _getDiBlockMaskFromCondb = false;
218  _detGainTag="";
219  _verbosity = 0;
220  _currentSR=0;
221  _ndRHCRunStart.clear();
222  _ndRHCRunStop.clear();
223  _fdRHCRunStart.clear();
224  _fdRHCRunStop.clear();
225  }
226 
227  //**********************************************************************
228 
230  {
231  }
232 
233  //**********************************************************************
234 
236  {
238  return _nDCMs;
239  }
240 
241  //**********************************************************************
242 
244  {
246  int ndcm=0;
247  for (unsigned int i=0; i<_dbList.size(); ++i)
248  for (unsigned int j=0; j<_dbList[i].dcm.size(); ++j)
249  if (_dbList[i].dcm[j].isActive)
250  ++ndcm;
251 
252  return ndcm;
253  }
254 
255  //**********************************************************************
257  {
258  if (_subrunList[sr].gotNAnalysisDiBlocks) return _subrunList[sr].nAnalysisDiBlocks;
259 
260  _subrunList[sr].nAnalysisDiBlocks=0;
263  for (size_t i=0; i<_dbList.size(); ++i) {
264  int db = _dbList[i].num;
265  if (this->IsGoodDiBlock(db,sr))
266  _subrunList[sr].nAnalysisDiBlocks++;
267  }
268 
269  _subrunList[sr].gotNAnalysisDiBlocks=true;
270  return _subrunList[sr].nAnalysisDiBlocks;
271 
272  }
273 
274  //**********************************************************************
275  // This is an approximation of the number of analysis channels. It
276  // takes into account analysis masks of diblocks, but it does not
277  // account for DAQ masks of individual pixels. We could do that, but
278  // loading all the pixel masks is currently pretty slow. This number
279  // should over estimate by no more than a few percent. Since the primary
280  // customer of this method is analysis of BadChannels, this is actually
281  // the right thing to do, since BadChannels does not account for DAQ-masked
282  // pixels either.
283  //**********************************************************************
284 
286  {
287  if (_subrunList[sr].gotNAnalysisChannels) return _subrunList[sr].nAnalysisChannels;
288 
289  _subrunList[sr].nAnalysisChannels=0;
292  for (size_t i=0; i<_dbList.size(); ++i) {
293  int db = _dbList[i].num;
294  if (this->IsGoodDiBlock(db,sr))
295  _subrunList[sr].nAnalysisChannels += 32*_dbList[i].nInstrumentedFEBs;
296  }
297 
298  _subrunList[sr].gotNAnalysisChannels=true;
299  return _subrunList[sr].nAnalysisChannels;
300 
301  }
302 
303  //**********************************************************************
304 
306  std::string user, std::string dbport)
307  {
308  _dbname = dbname;
309  _dbhost = dbhost;
310  _dbuser = user;
311  _dbport = dbport;
312 
313  }
314 
315  //**********************************************************************
316 
318  {
319  if(_runNumber != run) InvalidateCaches();
320  _runNumber = run;
321  }
322 
323  //**********************************************************************
324 
326  {
327  if(_detId != det) InvalidateCaches();
328 
331  std::cerr << __PRETTY_FUNCTION__ << " Bad detector id: " << det << std::endl;
332  std::abort();
333  }
334  else{
335  _detId = det;
337  }
338  }
339 
340  //**********************************************************************
341 
343  {
345  std::cerr << __PRETTY_FUNCTION__ << " Bad detector id: " << det << std::endl;
346  std::abort();
347  }
348  else {
350  }
351  }
352 
353  //**********************************************************************
355  {
356  if (_detId == novadaq::cnv::kFARDET) {
357  if (_fdRHCRunStart.empty() || _fdRHCRunStop.empty()) {
358  std::cerr << __PRETTY_FUNCTION__ << " Empty FD RHC run list!" << std::endl;
359  std::abort();
360  }
361  if (_fdRHCRunStart.size() != _fdRHCRunStop.size() ) {
362  std::cerr << __PRETTY_FUNCTION__ << " FD RHC run start list is not the same length as the run stop list. Something is wrong..." << std::endl;
363  std::abort();
364  }
365 
366  for ( size_t i=0; i<_fdRHCRunStart.size(); ++i) {
367  if (_runNumber >= _fdRHCRunStart[i] &&
369  return true;
370  }
371  return false;
372  }
373  else if (_detId == novadaq::cnv::kNEARDET) {
374  if (_ndRHCRunStart.empty() || _ndRHCRunStop.empty()) {
375  std::cerr << __PRETTY_FUNCTION__ << " Empty ND RHC run list!" << std::endl;
376  std::abort();
377  }
378  if (_ndRHCRunStart.size() != _ndRHCRunStop.size() ) {
379  std::cerr << __PRETTY_FUNCTION__ << " ND RHC run start list is not the same length as the run stop list. Something is wrong..." << std::endl;
380  std::abort();
381  }
382 
383  for ( size_t i=0; i<_ndRHCRunStart.size(); ++i) {
384  if (_runNumber >= _ndRHCRunStart[i] &&
386  return true;
387  }
388  return false;
389  }
390  else {
391  std::cerr << __PRETTY_FUNCTION__ << " Unknown detector. Why are asking for beam mode?" << std::endl;
392 
393  }
394  return false;
395  }
396 
397  //**********************************************************************
398 
400  {
401  /*
402  if (!_gotDAQRunHistory) {
403  if (!LoadDAQRunHistory()) return false;
404  }
405  */
406 
407  return false;
408  }
409 
410  //**********************************************************************
411 
413  {
414  if (_gotHardwareInfo) return true;
415 
416  if (!LoadDAQRunHistory()) return false;
417 
418  LOG_INFO("RunHistory") << "RunHistory: Loading FEB and APD installation information" << std::endl;
419 
421 
422  std::unique_ptr<db::Table> hwTable;
423 
424  hwTable.reset(new db::Table());
425 
427  hwTable->SetDetector(_detector);
428  else
429  return false;
430 
431  hwTable->SetTableType(nova::dbi::kHardwareTable);
432  hwTable->SetTimeQueries(_timeQueries);
433  hwTable->SetVerbosity(_verbosity);
434 
435  bool gotConnection = hwTable->GetConnection(_nRetryLoads);
436 
437  if (!gotConnection) {
438  LOG_ERROR("RunHistory") <<"RunHistory::LoadHardwareInfo(): Failed to connect to hardware database! Failed to load hardware info." << std::endl;
439  std::abort();
440  }
441 
443  PGresult* res;
444 
445  if (detId == novadaq::cnv::kNEARDET) {
446  query="SELECT dcm_name,dcm_port,block,plane,module_position from hardware_position where detector='NearDet' and install_date at time zone 'UTC' < '" + _tStart + "' and (remove_date is NULL or remove_date at time zone 'UTC' > '" + _tStart + "') and hw_type='APD' order by dcm_name,dcm_port";
447 
448  if (hwTable->ExecuteSQL(query,res)) {
449  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
450  std::cerr << __PRETTY_FUNCTION__ << " Query failed: " << query << std::endl;
451  PQclear(res);
452  hwTable->CloseConnection();
453  return false;
454  }
455 
456  std::string dcmName;
457 
458  int nRow = PQntuples(res);
459  for (int i=0; i < nRow; i++) {
460  dcmName = PQgetvalue(res,i,0);
461  int ifeb = atoi(PQgetvalue(res,i,1));
462  short diblock = atoi(dcmName.substr(6,2).c_str());
463  // if(_useMasking && IsGoodDiBlock(int(diblock))==false) break; // ignore masked diblocks
464  unsigned int idcm = atoi(dcmName.substr(9,2).c_str());
465  int idb = _diblockIndex[diblock];
466  if (_dbList[idb].dcm[idcm-1].isActive) {
467  if (_dbList[idb].hasNoAPDs)
468  _dbList[idb].hasNoAPDs = false;
469  if (_dbList[idb].dcm[idcm-1].feb[ifeb].hasAPD) continue;
470  _dbList[idb].dcm[idcm-1].feb[ifeb].hasAPD = true;
471  _dbList[idb].dcm[idcm-1].feb[ifeb].block = atoi(PQgetvalue(res,i,2));
472  _dbList[idb].dcm[idcm-1].feb[ifeb].layer = atoi(PQgetvalue(res,i,3));
473  _dbList[idb].dcm[idcm-1].feb[ifeb].pos_in_layer = atoi(PQgetvalue(res,i,4));
474  _dbList[idb].dcm[idcm-1].nInstrumentedFEBs++;
475  _dbList[idb].nInstrumentedFEBs++;
476  ++_nInstalledAPDs;
477  }
478  }
479  PQclear(res);
480  }
481 
482  }
483  else if (detId == novadaq::cnv::kFARDET) {
484 
485  // get locations of installed APDs
486 
487  query="SELECT btrim(fcom.location1,'DIBLK:') diblk, btrim(fcom.position1,'DCM:') pos, CAST(btrim(fcom.port1,'PRT:') AS INT) feb, mod.block AS block, mod.layer AS plane, mod.position_in_layer AS position FROM public.feb_comm_cables fcom, ashriverprod_factory.module mod LEFT OUTER JOIN ashriverprod_factory.barcoded_item bm ON (mod.barcoded_item_id = bm.barcoded_item_id) LEFT OUTER JOIN ashriverprod_factory.module_apd_connection ON (mod.barcoded_item_id = module_apd_connection.module) LEFT OUTER JOIN ashriverprod_factory.apd ON (module_apd_connection.apd = apd.barcoded_item_id) LEFT OUTER JOIN ashriverprod_factory.barcoded_item ba ON (apd.barcoded_item_id = ba.barcoded_item_id) LEFT OUTER JOIN ashriverprod_factory.nova_connection mac ON (mac.connection_id = module_apd_connection.connection_id) WHERE mac.date_created AT TIME ZONE 'CDT' < '" + _tStart + "' and (mac.date_removed is NULL or mac.date_removed AT TIME ZONE 'CDT' > '" + _tStart + "') and (mod.block=CAST(btrim(fcom.location2,'BLK:') AS INT) and mod.layer=CAST(btrim(fcom.position2,'PLN:') AS INT) and mod.position_in_layer=CAST(btrim(fcom.port2,'POS:') AS INT)) ORDER BY diblk,pos,feb";
488 
489  if (hwTable->ExecuteSQL(query,res)) {
490  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
491  std::cerr << __PRETTY_FUNCTION__ << " Query failed: " << query << std::endl;
492  PQclear(res);
493  hwTable->CloseConnection();
494  return false;
495  }
496 
497  std::string dcmName;
498 
499  int nRow = PQntuples(res);
500  for (int i=0; i < nRow; i++) {
501  int diblock = atoi(PQgetvalue(res,i,0));
502  if(_useMasking && IsGoodDiBlock(diblock)==false) continue; // ignore masked diblocks
503  unsigned int idcm = atoi(PQgetvalue(res,i,1));
504  // if(std::string(PQgetvalue(res,i,6)).compare(0,3,"S11") != 0) // one possible way of checking for permanently bad APDs, depending on DB
505  int idb = _diblockIndex[diblock];
506  int ifeb = atoi(PQgetvalue(res,i,2));
507  if( (diblock==4 &&idcm==7 &&ifeb==15) || // hard code list of permanently bad APDs to ignore
508  (diblock==5 &&idcm==7 &&ifeb==59) ||
509  (diblock==14&&idcm==6 &&ifeb==42) ) continue;
510  if (_dbList[idb].dcm[idcm-1].isActive) {
511  if (_dbList[idb].hasNoAPDs)
512  _dbList[idb].hasNoAPDs = false;
513  if (_dbList[idb].dcm[idcm-1].feb[ifeb].hasAPD) continue;
514  _dbList[idb].dcm[idcm-1].feb[ifeb].hasAPD = true;
515  _dbList[idb].dcm[idcm-1].feb[ifeb].block = atoi(PQgetvalue(res,i,3));
516  _dbList[idb].dcm[idcm-1].feb[ifeb].layer = atoi(PQgetvalue(res,i,4));
517  _dbList[idb].dcm[idcm-1].feb[ifeb].pos_in_layer = atoi(PQgetvalue(res,i,5));
518  _dbList[idb].dcm[idcm-1].nInstrumentedFEBs++;
519  _dbList[idb].nInstrumentedFEBs++;
520  ++_nInstalledAPDs;
521  }
522  }
523  PQclear(res);
524  }
525  else {
526  std::cerr << __PRETTY_FUNCTION__ << " SQL error, failed query: " << query << std::endl;
527  PQclear(res);
528  hwTable->CloseConnection();
529  return false;
530  }
531  }
532 
533  hwTable->CloseConnection();
534  _gotHardwareInfo = true;
535 
536  return true;
537  }
538 
539  //**********************************************************************
540 
542  {
543  if (_runNumber >= 1000000 || _runNumber < 10000) {
544  LOG_ERROR("RunHistory") << "Ideal run number not acceptable for this method. Aborting.";
545  std::abort();
546  }
547 
548  if (_gotPedestals) return true;
549 
550  if (! LoadDAQRunHistory()) return false;
551  if (! LoadHardwareInfo()) return false;
552  if (! LoadFEBMasks()) return false;
553  if (! LoadPixelMasks()) return false;
554 
555  std::unique_ptr<db::Table> t;
556  t.reset(new db::Table("RunHistory/tables/PedestalsByRun.xml"));
557 
559  t->SetDetector(_detector);
560  else
561  return false;
562 
563  int pedIdx = t->GetColIndex("ped");
564 
565  t->SetDataTypeMask(nova::dbi::kDataOnly);
566  t->SetMinTSVld(_runNumber);
567  t->SetMaxTSVld(_runNumber);
568  t->SetTimeQueries(_timeQueries);
569  t->SetTimeParsing(_timeParsing);
570  t->SetVerbosity(_verbosity);
571 
572  LOG_INFO("RunHistory") << "RunHistory: loading channel pedestals" << std::endl;
573 
574  if (!t->Load()) {
575  std::cerr << __PRETTY_FUNCTION__ << "No pedestals found in DB!";
576  if(_abort) std::abort();
577  return false;
578  }
579  else {
580  if (t->NRow() == 0) {
581  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << ": failed to get any rows from database, which should not happen." << std::endl;
582  if (_abort) std::abort();
583  }
584  }
585 
586  t->FillChanRowMap();
588  // int nrow = t->NRow();
590  int16_t ped = 0;
592 
593  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
594  int dbNum = _dbList[idb].num;
595  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm) {
596  if (! _dbList[idb].dcm[idcm].isActive) continue;
597  int dcmNum = _dbList[idb].dcm[idcm].position;
598  int nfebs = _dbList[idb].dcm[idcm].feb.size();
599  int64_t febmask = _dbList[idb].dcm[idcm].febMask;
600  for (int ifeb=0; ifeb<nfebs; ++ifeb) {
601  if (!(febmask >> ifeb)&0x1) continue;
602  for (int ip=0; ip<32; ++ip) {
603  daqchannelmap::dchan daqChan = daqcmap->encodeDChan(detId,dbNum,
604  dcmNum,ifeb,ip);
605  daqchannelmap::lchan logChan = daqcmap->encodeLChan(daqChan);
606 
607  int plane = daqcmap->getPlane(logChan);
608  int cell = daqcmap->getCell(logChan);
609  geo::OfflineChan chan(plane, cell);
610  int tchan = chan.ToDBValidityChan();
611 
612  row = t->GetVldRow(tchan,_runNumber);
613  if (!row) {
614  LOG_WARNING("RunHistory") << "No row found for channel " << tchan << std::endl;
615  continue;
616  }
617  row->Col(pedIdx).Get(ped);
618  _dbList[idb].dcm[idcm].feb[ifeb].pixelThresh[ip] = ped;
619  }
620  }
621  }
622  }
623  LOG_INFO("RunHistory") << "done!" << std::endl;
624 
625  _gotPedestals = true;
626 
627  return true;
628  }
629 
630  //**********************************************************************
631 
632  int RunHistory::GetPedestal(const geo::OfflineChan& oChan, bool& ok)
633  {
634  if (!LoadDAQRunHistory()) {
635  if (_abort) std::abort();
636  return -1;
637  }
638  if (!LoadHardwareInfo()) {
639  if (_abort) std::abort();
640  return -1;
641  }
642  if (!LoadFEBMasks()) {
643  if (_abort) std::abort();
644  return -1;
645  }
646  if (!LoadPedestals()) {
647  if (_abort) std::abort();
648  return -1;
649  }
650 
652  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
653  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
654 
655  int diblk = int(dmap->getDiBlock(daqChan));
656  int dcmId = int(dmap->getDCM(daqChan));
657  int ifeb = int(dmap->getFEB(daqChan));
658  int ipix = int(dmap->getPixel(daqChan));
659 
660  int idb = _diblockIndex[diblk];
661  if (idb < (int)_dbList.size())
662  return _dbList[idb].dcm[dcmId-1].feb[ifeb].pixelThresh[ipix];
663 
664  return 0;
665  }
666 
667  //**********************************************************************
668 
669  int RunHistory::GetPedestal(const daqchannelmap::dchan& daqChan, bool& ok)
670  {
671  if (!LoadDAQRunHistory()) {
672  if (_abort) std::abort();
673  return -1;
674  }
675  if (!LoadHardwareInfo()) {
676  if (_abort) std::abort();
677  return -1;
678  }
679  if (!LoadFEBMasks()) {
680  if (_abort) std::abort();
681  return -1;
682  }
683  if (!LoadPixelMasks()) {
684  if (_abort) std::abort();
685  return -1;
686  }
687  if (!LoadPedestals()) {
688  if (_abort) std::abort();
689  return -1;
690  }
691 
693 
694  int diblk = int(dmap->getDiBlock(daqChan));
695  int dcmId = int(dmap->getDCM(daqChan));
696  int ifeb = int(dmap->getFEB(daqChan));
697  int ipix = int(dmap->getPixel(daqChan));
698 
699  int idb = _diblockIndex[diblk];
700  if (idb < (int)_dbList.size())
701  return _dbList[idb].dcm[dcmId-1].feb[ifeb].pixelThresh[ipix];
702 
703  return 0;
704 
705  }
706 
707  //**********************************************************************
708 
710  {
711  if (_runNumber >= 1000000 || _runNumber < 10000) {
712  LOG_ERROR("RunHistory") << "Ideal run number not acceptable for this method. Aborting.";
713  std::abort();
714  }
715 
716 
717  if (_gotPixelMasks) return true;
718 
719  if (! LoadDAQRunHistory()) return false;
720  if (! LoadHardwareInfo()) return false;
721  if (! LoadFEBMasks()) return false;
722 
723  std::unique_ptr<db::Table> t;
724  t.reset(new db::Table("RunHistory/tables/PixelMasksByRun.xml"));
725 
727  t->SetDetector(_detector);
728  else
729  return false;
730 
731  int maskIdx = t->GetColIndex("mask");
732 
733  t->SetDataTypeMask(nova::dbi::kDataOnly);
734  t->SetMinTSVld(_runNumber);
735  t->SetMaxTSVld(_runNumber);
736  t->SetTimeQueries(_timeQueries);
737  t->SetTimeParsing(_timeParsing);
738  t->SetVerbosity(_verbosity);
739 
740  LOG_INFO("RunHistory") << "RunHistory: loading pixel enable masks" << std::endl;
741 
742  if (!t->Load()) {
743  std::cerr << __PRETTY_FUNCTION__ << "No pixel masks found in DB!";
744  if(_abort) std::abort();
745  return false;
746  }
747  else {
748  if (t->NRow() == 0) {
749  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << ": failed to get any rows from database, which should not happen." << std::endl;
750  if (_abort) std::abort();
751  }
752  }
753 
754  t->FillChanRowMap();
756  // int nrow = t->NRow();
758  int32_t pMask;
759 
760  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
761  int dbNum = _dbList[idb].num;
762  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm) {
763  if (! _dbList[idb].dcm[idcm].isActive) continue;
764  int dcmNum = _dbList[idb].dcm[idcm].position;
765  int nfebs = _dbList[idb].dcm[idcm].feb.size();
766  for (int ifeb=0; ifeb<nfebs; ++ifeb) {
767  int tchan = detId*1000000 + 10000*dbNum + 100*dcmNum + ifeb;
768  row = t->GetVldRow(tchan,_runNumber);
769  if (!row) {
770  LOG_WARNING("RunHistory") << "No row found for channel " << tchan << std::endl;
771  continue;
772  }
773  row->Col(maskIdx).Get(pMask);
774  _dbList[idb].dcm[idcm].feb[ifeb].pixelMask = pMask;
775  }
776  }
777  }
778  _gotPixelMasks = true;
779 
780  return true;
781  }
782 
783  //**********************************************************************
784 
786  {
787  if (_gotFEBMasks) return true;
788 
789  if (! LoadDAQRunHistory()) return false;
790  if (! LoadHardwareInfo()) return false;
791 
792  std::unique_ptr<db::Table> t;
793  t.reset(new db::Table("RunHistory/tables/FEBMasksByRun.xml"));
794 
796  t->SetDetector(_detector);
797  else
798  return false;
799 
800  int maskIdx = t->GetColIndex("mask");
801 
802  t->SetDataTypeMask(nova::dbi::kDataOnly);
803  t->SetMinTSVld(_runNumber);
804  t->SetMaxTSVld(_runNumber);
805  t->SetTimeQueries(_timeQueries);
806  t->SetTimeParsing(_timeParsing);
807  t->SetVerbosity(_verbosity);
808 
809  LOG_INFO("RunHistory") << "RunHistory: loading FEB enable masks" << std::endl;
810 
811  if (!t->Load()) {
812  std::cerr << __PRETTY_FUNCTION__ << "No pixel masks found in DB!";
813  if(_abort) std::abort();
814  return false;
815  }
816  else {
817  if (t->NRow() == 0) {
818  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << ": failed to get any rows from database, which should not happen." << std::endl;
819  if (_abort) std::abort();
820  }
821  }
822 
823  t->FillChanRowMap();
825 
826  // int nrow = t->NRow();
828  int64_t pMask;
829 
830  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
831  int dbNum = _dbList[idb].num;
832  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm) {
833  if (! _dbList[idb].dcm[idcm].isActive) continue;
834  int dcmNum = _dbList[idb].dcm[idcm].position;
835  int tchan = detId*1000000 + 10000*dbNum + 100*dcmNum;
836  row = t->GetVldRow(tchan,_runNumber);
837  if (!row) {
838  LOG_WARNING("RunHistory") << "No row found for channel " << tchan << std::endl;
839  continue;
840  }
841  row->Col(maskIdx).Get(pMask);
842  _dbList[idb].dcm[idcm].febMask = pMask;
843  }
844  }
845  _gotFEBMasks = true;
846 
847  return true;
848 
849  }
850 
851  //**********************************************************************
852 
854  {
855  if (_gotPixelInfo) return true;
856  if (_gotFEBMasks) return true;
857 
858  if (! LoadDAQRunHistory()) return false;
859  if (! LoadHardwareInfo()) return false;
860 
861  _nTotalChannels=0;
862  _nTotalFEBs=0;
863 
864  char daqEnv[128];
865  sprintf(daqEnv,"NOVADAQ_ENVIRONMENT=%s",_detector.c_str());
866  putenv(daqEnv);
867 
868  std::vector<std::string> tmpDCMList;
869  for (unsigned int i=0; i<_dbList.size(); ++i)
870  for (unsigned int j=0; j < _dbList[i].dcm.size(); ++j) {
871  if (_dbList[i].dcm[j].isActive)
872  tmpDCMList.push_back(_dbList[i].dcm[j].appname);
873  }
874 
875  //TStopwatch ts;
876  //ts.Start();
877  LOG_INFO("RunHistory") << "RunHistory: loading pixel enable masks" << std::endl;
878  daqcfg::PixelEnableMasks pixelEnableMasks(_gCfgId, tmpDCMList);
879 
880  bool hasValidData = pixelEnableMasks.hasValidData();
881  if (hasValidData) {
882  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
883  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm) {
884  if (! _dbList[idb].dcm[idcm].isActive) continue;
885 
886  std::string dcmName = _dbList[idb].dcm[idcm].appname;
887  int64_t febMask = 0;
888  pixelEnableMasks.getFEBEnableMask(dcmName, febMask);
889  _dbList[idb].dcm[idcm].febMask = febMask;
890  }
891  }
892  }
893  else {
894  return false;
895  }
896 
897  _gotFEBMasks = true;
898  return true;
899  }
900 
901  //**********************************************************************
902 
903  bool RunHistory::LoadPixelInfo(int nAttempt)
904  {
905  if (nAttempt > _nRetryLoads) {
906  std::cerr << __PRETTY_FUNCTION__ << " giving up!"
907  << std::endl;
908  return false;
909  }
910 
911  if (_gotPixelInfo) return true;
912 
913  if (! LoadDAQRunHistory()) return false;
914  if (! LoadHardwareInfo()) return false;
915 
916  _nTotalChannels=0;
917  _nTotalFEBs=0;
918 
919  char daqEnv[128];
920  sprintf(daqEnv,"NOVADAQ_ENVIRONMENT=%s",_detector.c_str());
921  putenv(daqEnv);
922 
923  std::vector<std::string> tmpDCMList;
924  for (unsigned int i=0; i<_dbList.size(); ++i)
925  for (unsigned int j=0; j < _dbList[i].dcm.size(); ++j) {
926  if (_dbList[i].dcm[j].isActive)
927  tmpDCMList.push_back(_dbList[i].dcm[j].appname);
928  }
929 
930  //TStopwatch ts;
931  //ts.Start();
932  LOG_INFO("RunHistory") << "RunHistory: loading pixel enable masks" << std::endl;
933  daqcfg::PixelEnableMasks pixelEnableMasks(_gCfgId, tmpDCMList);
934  LOG_INFO("RunHistory") << "RunHistory: loading pixel thresholds" << std::endl;
935  daqcfg::PixelThresholds pixelThresholds(_gCfgId, tmpDCMList);
936  LOG_INFO("RunHistory") << "done!" << std::endl;
937  //ts.Stop();
938  //ts.Print();
939 
940  bool hasValidData = (pixelEnableMasks.hasValidData() &&
941  pixelThresholds.hasValidData());
942 
943  if (hasValidData) {
944  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
945  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm) {
946  if (! _dbList[idb].dcm[idcm].isActive) continue;
947 
948  std::string dcmName = _dbList[idb].dcm[idcm].appname;
949  int64_t febMask = 0;
950  pixelEnableMasks.getFEBEnableMask(dcmName, febMask);
951  _dbList[idb].dcm[idcm].febMask = febMask;
952  int nfeb = _dbList[idb].dcm[idcm].feb.size();
953  for (int ifeb = 0; ifeb < nfeb; ++ifeb) {
954  if (pixelEnableMasks.febIsEnabled(dcmName, ifeb)) {
955  _nTotalChannels += 32;
956  ++_nTotalFEBs;
957 
958  FEB& f = _dbList[idb].dcm[idcm].feb[ifeb];
959  f.isEnabled = true;
960  int32_t pixelMask;
961  pixelEnableMasks.getPixelEnableMask(dcmName, ifeb, pixelMask);
962  f.pixelMask = pixelMask;
963  f.nActivePix = pixelEnableMasks.
964  getEnabledPixelCountForFEB(dcmName, ifeb);
965  if (pixelThresholds.hasValidData())
966  pixelThresholds.getThresholdsForFEB(dcmName, ifeb,
967  f.pixelThresh);
968  } // end if (febIsEnabled)
969  } // end loop over FEBs
970  } // end loop over DCMs
971  } // end loop over DiBlocks
972  } // end if hasValidData
973  else {
974  std::cerr << __PRETTY_FUNCTION__ << " failed to get valid data"
975  << std::endl;
976  if (_nRetryLoads > 0) {
977  int sleepTime = 1 + ((double)random()/(double)RAND_MAX)*(1 << nAttempt++);
978  sleep(sleepTime);
979  return this->LoadPixelInfo(nAttempt+1);
980  }
981  else {
982  return false;
983  }
984  }
985 
986  _gotPixelInfo = true;
987 
988  return true;
989  }
990 
991  //**********************************************************************
993  {
994  if (_gotCoolingInfo) return true;
995 
996  /*
997  if (!_gotDAQRunHistory) {
998  if (!LoadDAQRunHistory()) return false;
999  }
1000  */
1001 
1002  return false;
1003  }
1004 
1005  //**********************************************************************
1006 
1008  {
1009  if (!_detGainSetting) {
1010  std::unique_ptr<db::Table> t;
1011  t.reset(new db::Table("RunHistory/tables/GainSetting.xml"));
1012 
1014  t->SetDetector(_detector);
1015  else
1016  return 0;
1017 
1018  int gainIdx = t->GetColIndex("gain");
1019 
1020  t->SetDataTypeMask(nova::dbi::kMCOnly|nova::dbi::kDataOnly);
1021  t->SetTag(_detGainTag);
1022  t->SetMinTSVld(_runNumber);
1023  t->SetMaxTSVld(_runNumber);
1024  t->SetTimeQueries(_timeQueries);
1025  t->SetTimeParsing(_timeParsing);
1026  t->SetVerbosity(_verbosity);
1027  if (!t->Load()) {
1028  std::cerr << __PRETTY_FUNCTION__ << "No gain setting found in DB!";
1029  if(_abort) std::abort();
1030  LOG_WARNING("RunHistory") << "WARNING: RunHistory::DetGainSetting(): No detector gain setting\n"
1031  " info found for run " << _runNumber << ", so setting gain to 1";
1032  _detGainSetting = 1;
1033  // get from the dB
1034  }
1035  else {
1036  if (t->NRow() != 1) {
1037  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << ": failed to get 1 row from database. Aborting." << std::endl;
1038  abort();
1039  }
1040  t->GetRow(0)->Col(gainIdx).Get(_detGainSetting);
1041  LOG_INFO("RunHistory") << "Gain setting for run " << _runNumber
1042  << " is " << _detGainSetting << std::endl;
1043  }
1044  }
1045 
1046  return _detGainSetting;
1047  }
1048 
1049  //**********************************************************************
1050 
1052  {
1053  // TODO. This really should be implemented by a database table like
1054  // DetGainSetting, but this is the best that can be done on short notice.
1055 
1056  // ND has always been fine-timing in any runs used for physics
1057  if(_detId != novadaq::cnv::kFARDET) return true;
1058 
1059  // FD switched at some point and never switched back. Ideal conditions
1060  // runs up at high run numbers are all fine timing. We use magic number
1061  // up there for gains, but so far not for timing. If that ever changes
1062  // will have to add more logic here.
1063 
1064  // https://cdcvs.fnal.gov/redmine/projects/novawatchdog/wiki/Far_Detector
1065  return _runNumber >= 17212;
1066  }
1067 
1068  //**********************************************************************
1069 
1071  {
1072  if (_gotAPDSettings) return true;
1073 
1074  if (!LoadDAQRunHistory()) return false;
1075 
1076  if (!LoadHardwareInfo()) return false;
1077 
1078  std::vector<std::string> tmpDCMList;
1079  for (unsigned int idb=0; idb<_dbList.size(); ++idb)
1080  for (unsigned int idcm=0; idcm<_dbList[idb].dcm.size(); ++idcm)
1081  if (_dbList[idb].dcm[idcm].isActive)
1082  tmpDCMList.push_back(_dbList[idb].dcm[idcm].appname);
1083 
1084  char daqEnv[128];
1085  sprintf(daqEnv,"NOVADAQ_ENVIRONMENT=%s",_detector.c_str());
1086  putenv(daqEnv);
1087 
1088  dcscfg::APDSettings apdSettings(_gCfgId, tmpDCMList);
1089 
1090  for (unsigned int idb=0; idb < _dbList.size(); ++idb) {
1091  for (unsigned int idcm = 0; idcm < _dbList[idb].dcm.size(); ++idcm) {
1092  if (! _dbList[idb].dcm[idcm].isActive) continue;
1093  std::string dcmName = _dbList[idb].dcm[idcm].appname;
1094  for (int ifeb = 0; ifeb < 64; ++ifeb) {
1095  FEB& f = _dbList[idb].dcm[idcm].feb[ifeb];
1096  apdSettings.getTemperatureEnable(dcmName,ifeb,f.tempEnabled);
1097  double temp;
1098  apdSettings.getTemperature (dcmName,ifeb,temp);
1099  f.temperature = temp;
1100  apdSettings.getVoltage (dcmName,ifeb,f.apdV);
1101  // apdSettings.getCoolingEnableFlag(dcmName,ifeb,f.isCooled);
1102  }
1103  }
1104  }
1105 
1106  // now get the gains
1107 
1109 
1110  if (detId == novadaq::cnv::kFARDET) {
1111 
1112  // get a map of the hardware locations to the installed APDs and FEBs
1113  this->MapHardwareToLocation();
1114 
1115  _nInstalledAPDs = gLocToFA.size();
1116 
1117  // loop over the gLocToFA map to fill the necessary information
1118  for(auto const& locitr : gLocToFA){
1119 
1120  auto const& hl = locitr.first;
1121  auto const& apd = locitr.second.second;
1122 
1123  if(hl._diblock > _dbList.size() ) continue;
1124  for (unsigned int idb=0; idb<_dbList.size(); ++idb) {
1125  if (_dbList[idb].num == (int)hl._diblock) {
1126 
1127  if(_dbList[idb].dcm[hl._dcm-1].isActive) {
1128  if(!_dbList[idb].dcm[hl._dcm-1].feb[hl._feb].hasAPD)
1129  continue;
1130 
1131  auto pixGain = apd._pixelGain;
1132  float avGain = 0.;
1133  float pGain = 0.;
1134  for(size_t p = 0; p < pixGain.size(); ++p){
1135  pGain = pixGain.at(p);
1136  _dbList[idb].dcm[hl._dcm-1].feb[hl._feb].pixelGain.at(p) = pGain;
1137  avGain += pGain;
1138  }
1139  avGain /= 32.;
1140  _dbList[idb].dcm[hl._dcm-1].feb[hl._feb].gain = avGain;
1141 
1142  if(std::abs(100. - avGain) > 10.){
1143  LOG_WARNING("RunHistory") << "average gain for APD "
1144  << apd._sn
1145  << " connected to "
1146  << "dcm-2-" << hl._diblock
1147  << "-" << hl._dcm
1148  << "-" << hl._feb
1149  << " is " << avGain
1150  << " : 100 expected so default to that";
1151  _dbList[idb].dcm[hl._dcm-1].feb[hl._feb].gain = 100.;
1152  for(size_t p = 0; p < pixGain.size(); ++p)
1153  _dbList[idb].dcm[hl._dcm-1].feb[hl._feb].pixelGain.at(p) = 100.;
1154  }
1155  }
1156  }
1157  } // end if the dcm is active
1158  } // end loop over location map
1159  } // end if far detector
1160 
1161  _gotAPDSettings = true;
1162 
1163  return true;
1164  }
1165 
1166  //**********************************************************************
1167  int RunHistory::GoodDiBlockMask(int subrun, bool reload)
1168  {
1169  if(reload)
1170  _gotGoodDiBlockMask=false;
1172 
1174  subrun = 0;
1175  else {
1176  if (subrun < 0 || subrun > 63) {
1177  if (subrun > 63)
1178  LOG_WARNING("RunHistory") << __PRETTY_FUNCTION__ << " invalid subrun " << subrun << ". Converted to subrun " << subrun << std::endl;
1179  subrun = _currentSR;
1180  }
1181 
1182  }
1183 
1184  return _subrunList[subrun].goodDiBlockMask;
1185  }
1186 
1187  //**********************************************************************
1189  {
1190 
1191  ///< Is diblock kept when applying mask? Generally don't use this, just ask for HasAPD (for a channel) or for nInstrumentedFEBs (in a DCM or Diblock) and any mask asked for will already be applied. Always returns good if masking turned off. Diblock number argument 1-14
1192  if(!_useMasking) return true;
1193 
1195  if (idb < 1) return false;
1196 
1198  subrun = 0;
1199  else {
1200  if (subrun < 0 || subrun > 63) {
1201  if (subrun>63)
1202  LOG_WARNING("RunHistory") << __PRETTY_FUNCTION__ << " invalid subrun " << subrun << ". Converted to subrun " << subrun << std::endl;
1203  subrun = _currentSR;
1204  }
1205 
1206  }
1207 
1208  return ((_subrunList[subrun].goodDiBlockMask >> (idb-1))&0x1);
1209  }
1210 
1211 
1212  //**********************************************************************
1213 
1215  {
1216  if (_gotDataEpoch) return true;
1217 
1218  std::unique_ptr<db::Table> t;
1219  t.reset(new db::Table("RunHistory/tables/DataEpochs.xml"));
1220 
1222  t->SetDetector(_detector);
1223  else
1224  return false;
1225 
1226  int nameIdx = t->GetColIndex("name");
1227  int rstartIdx = t->GetColIndex("run_start");
1228  int rendIdx = t->GetColIndex("run_end");
1229 
1230  t->SetVerbosity(_verbosity);
1231  t->SetTimeQueries(_timeQueries);
1232  t->SetTimeParsing(_timeParsing);
1233 
1234  bool loadFailed = false;
1235 
1236  // exclude these columns in case of formatting issues (,\', etc.)
1237  if (! t->Load()) loadFailed = true;
1238 
1239  if (loadFailed) {
1240  LOG_ERROR("RunHistory") << "Loading of data epoch info from database failed." << std::endl;
1241  return false;
1242  }
1243 
1244  int nRow = t->NRow();
1245  int runStart = 0;
1246  int runEnd = 0;
1247 
1248  for (int i=0; i<nRow; ++i) {
1249  t->GetRow(i)->Col(rstartIdx).Get(runStart);
1250  if (! t->GetRow(i)->Col(rendIdx).Get(runEnd))
1251  runEnd = 0;
1252  if (_runNumber >= runStart && (_runNumber <= runEnd || runEnd==0 )) {
1253  _dataEpoch.run_start = runStart;
1254  _dataEpoch.run_end = runEnd;
1255  t->GetRow(i)->Col(nameIdx).Get(_dataEpoch.name);
1256  _gotDataEpoch = true;
1257  break;
1258  }
1259  }
1260 
1261  if (!_gotDataEpoch) {
1262  LOG_ERROR("RunHistory") << "Failed to find data epoch in the database!" << std::endl;
1263  _gotDataEpoch = true;
1264  return false;
1265  }
1266 
1267  _gotDataEpoch = true;
1268  return true;
1269  }
1270 
1271  //**********************************************************************
1272 
1274  {
1275  if (_gotGoodDiBlockMask) return true;
1276 
1277  // if (!LoadDAQRunHistory()) return false;
1278 
1279  if(_useMasking==false) { // if masking is turned off, set the mask so the CAFs see this
1280  _subrunList[0].goodDiBlockMask = (1<<17)-1;
1281  _gotGoodDiBlockMask = true;
1282  return true;
1283  }
1284 
1286 
1287  if(detId==novadaq::cnv::kNEARDET) { // switch masking off for ND for now
1288  _useMasking = false;
1289  _gotGoodDiBlockMask = true;
1290  return true;
1291  }
1292 
1293  if(_customMasking && detId==novadaq::cnv::kFARDET) {
1294  for (int isr=0; isr<64; ++isr)
1295  _subrunList[isr].goodDiBlockMask = _customMask;
1296  _gotGoodDiBlockMask = true;
1297  LOG_INFO("RunHistory") << __PRETTY_FUNCTION__ << "Applying custom mask: " << DiBlockMaskToString(_subrunList[0].goodDiBlockMask) << std::endl;
1298  return true;
1299  }
1300 
1301  if(_runNumber >= 1000000 || _runNumber < 10000) { // for MC-like run numbers, leave these with no mask. no need to access DB and cause crashes in MC sim or old ideal MC
1302  _useMasking = false;
1303  _subrunList[0].goodDiBlockMask = (1<<17)-1;
1304  for (int isr=1; isr<64; ++isr)
1305  _subrunList[isr].goodDiBlockMask = _subrunList[0].goodDiBlockMask;
1306  _gotGoodDiBlockMask = true;
1307  return true;
1308  }
1309 
1310  bool fallback = false;
1311 
1312  std::unique_ptr<db::Table> t;
1313 
1315  t.reset(new db::Table("RunHistory/tables/DQValidity.xml"));
1316  else
1317  t.reset(new db::Table("RunHistory/tables/GoodDiBlocksVsRun.xml"));
1318 
1320  t->SetDetector(_detector);
1321  else
1322  return false;
1323 
1324  int maskIdx = t->GetColIndex("dbmask");
1325  t->SetVerbosity(_verbosity);
1326  t->SetTimeQueries(_timeQueries);
1327  t->SetTimeParsing(_timeParsing);
1328 
1329  if (!_getDiBlockMaskFromCondb) {
1330  t->SetValidityRange("run",_runNumber);
1331  t->AddOrderColumn("inserttime");
1332  t->SetOrderDesc();
1333  }
1334  else {
1335  t->SetTag(_dbMaskTag);
1336  t->SetMinTSVld(_runNumber*100);
1337  t->SetMaxTSVld((_runNumber+1)*100-1);
1338  t->SetDataTypeMask(nova::dbi::kDataOnly);
1339  t->AddExcludeCol(std::string("comment"));
1340  t->AddExcludeCol(std::string("flag"));
1341  t->AddExcludeCol(std::string("miprate"));
1342  t->AddExcludeCol(std::string("ngooddb"));
1343  t->AddExcludeCol(std::string("numslc"));
1344  t->AddExcludeCol(std::string("trkfrac"));
1345  }
1346  bool loadFailed = false;
1347 
1348  // exclude these columns in case of formatting issues (,\', etc.)
1349  if (! t->Load()) loadFailed = true;
1350 
1351  if (loadFailed || t->NRow() == 0) {
1352  std::cerr << __PRETTY_FUNCTION__ << "No mask found in DB!";
1353  if(_abort) std::abort();
1354  LOG_WARNING("RunHistory") << __PRETTY_FUNCTION__ << ": RunHistory::LoadGoodDiBlockMask(): No good diblock mask";
1355  LOG_WARNING("RunHistory") << " info found for run " << _runNumber << ", so assuming all";
1356  LOG_WARNING("RunHistory") << " good diblocks" << std::endl;
1357  fallback = true;
1358  // use a wide open mask; added benefit: the mask will appear in CAF files downstream as unphysical
1359  }
1360  else {
1361  if (!_getDiBlockMaskFromCondb) {
1362  t->GetRow(0)->Col(maskIdx).Get(_subrunList[0].goodDiBlockMask);
1363  for (size_t isr=1; isr<64; ++isr)
1364  _subrunList[isr].goodDiBlockMask = _subrunList[0].goodDiBlockMask;
1365  }
1366  else {
1367  t->FillChanRowMap();
1368  int tmask;
1369  for (int isr=0; isr<64; ++isr) {
1370  int tvld = _runNumber*100+isr;
1371  nova::dbi::Row* row = t->GetVldRow(0,tvld);
1372  row->Col(maskIdx).Get(tmask);
1373  _subrunList[isr].goodDiBlockMask = tmask;
1374  }
1375  }
1376  }
1377 
1378  // if asked for in the .fcl, modify the mask to meet analysis requirements
1379  // (far det only, and only if we found a real mask to begin with)
1380  if ( _analysisDiBlockMasking && detId==novadaq::cnv::kFARDET && !fallback) {
1381  LOG_DEBUG("RunHistory") << __PRETTY_FUNCTION__ << ": Applying analysis diblock masking: ";
1382  for (int isr=0; isr<64; ++isr) {
1383  int newMask = ApplyAnalysisDiBlockMask(_subrunList[isr].goodDiBlockMask);
1384  if (newMask==_subrunList[isr].goodDiBlockMask) {
1385  LOG_DEBUG("RunHistory") << "mask [" << isr << "] unchanged from " <<
1386  DiBlockMaskToString(_subrunList[isr].goodDiBlockMask) << std::endl;
1387  }
1388  else {
1389  LOG_INFO("RunHistory") << "mask [" << isr << "] modified from "
1390  << DiBlockMaskToString(_subrunList[isr].goodDiBlockMask)
1391  << " to "
1392  << DiBlockMaskToString(newMask) << std::endl;
1393  }
1394  _subrunList[isr].goodDiBlockMask = newMask;
1395 
1396  if (!_subrunList[isr].goodDiBlockMask) {
1397  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << "WARNING: entire detector masked off by analysis requirements!" << std::endl;
1398  LOG_ERROR("RunHistory") << __PRETTY_FUNCTION__ << "No analyzable detector region found for run " << _runNumber << ", subrun " << isr << std::endl;
1399  //// Not returning here, as this return value doesn't seem to be trapped by the invokers, so best
1400  //// to let the code fail gracefully downstream when it sees no hits.
1401  // return false;
1402  }
1403  }
1404  }
1405 
1406  _gotGoodDiBlockMask = true;
1407 
1408  return true;
1409  }
1410 
1411  //**********************************************************************
1412 
1414  {
1415  LoadHardwareInfo();
1417  if(detId==novadaq::cnv::kNEARDET) {
1418  bool diblocks[4] = {0};
1419  int config = 0;
1420  for(unsigned int i = 0; i < _dbList.size(); i++) {
1421  if(_dbList[i].nInstrumentedFEBs>=175 && i < 3) diblocks[_dbList[i].num-1] = true;
1422  if(_dbList[i].nInstrumentedFEBs>=45 && i == 3) diblocks[_dbList[i].num-1] = true;
1423  }
1424  for(int i = 0; i < 4; i++) {
1425  if(diblocks[i]) config+=1<<i;
1426  }
1427  return config;
1428  }
1429  if(detId==novadaq::cnv::kFARDET) {
1430  bool diblocks[14] = {0};
1431  int config = 0;
1432  for(unsigned int i = 0; i < _dbList.size(); i++) {
1433  if(_dbList[i].nInstrumentedFEBs>=700) diblocks[_dbList[i].num-1] = true;
1434  }
1435  for(int i = 0; i < 14; i++) {
1436  if(diblocks[i]) config+=1<<i;
1437  }
1438  return config;
1439  }
1440  return 0;
1441  }
1442  //**********************************************************************
1443 
1444  // For diagnostics and status messages, convert the diblock mask into
1445  // a human-readable string.
1447  {
1448  std::string answer = "";
1449  for (int iD=0;iD<14;iD++) {
1450  if (mask&(1<<(iD))) {
1451  answer += "#";
1452  }
1453  else {
1454  answer += "-";
1455  }
1456  }
1457  return answer;
1458  }
1459 
1460  //**********************************************************************
1461 
1462  // Apply the analysis masking to an input raw mask.
1463  // 4/04/17 switched function from strict FA rules to looser SA rules
1464  // FA style: Keeps the largest contiguous region of 4 or more diblocks, and keeps
1465  // the most downstream region if there is a tie for largest.
1466  // Current style: Keep ALL contiguous regions of 4 or more diblocks
1468  {
1469 
1470  // for convenience and clarity below, define dib[]...
1471  const int NUMDIB = 14;
1472  bool dib[NUMDIB];
1473  for (int iD=0;iD<NUMDIB;iD++) {
1474  dib[iD] = (mask&(1<<iD));
1475  }
1476 
1477  int answer = 0;
1478  int partial_answer = 0;
1479  int iStart = -1;
1480  for (int iD=0;iD<NUMDIB;iD++) {
1481 
1482  if (iStart<0&&dib[iD]) {
1483  // starting a string of diblocks
1484  iStart = iD;
1485  }
1486 
1487  if (iStart>=0&&dib[iD]) {
1488  // contributes to partial_answer
1489  partial_answer += (1<<iD);
1490  }
1491 
1492  if (iStart>=0&&(!dib[iD]||iD==NUMDIB-1)) {
1493  // just left a string of diblocks, or at last diblock
1494  int curr_size = iD-iStart;
1495  if (dib[iD]&&iD==NUMDIB-1) curr_size++;
1496  if (curr_size>=4) {
1497  // okay to keep
1498  answer += partial_answer;
1499  }
1500  iStart = -1;
1501  partial_answer = 0;
1502  }
1503 
1504  } // iD
1505 
1506  return answer;
1507  }
1508 
1509  //**********************************************************************
1510 
1512  {
1513  if (_gotPOT) return true;
1514 
1515  _npot = 0.;
1516 
1517  std::unique_ptr<db::Table> potTable;
1518 
1519  potTable.reset(new db::Table("RunHistory/tables/POTByRun.xml"));
1520 
1522  potTable->SetDetector(_detector);
1523  else
1524  return false;
1525 
1526  int potIdx = potTable->GetColIndex("npot");
1527  int avgIdx = potTable->GetColIndex("avg_i");
1528  potTable->SetTimeQueries(_timeQueries);
1529  potTable->SetTimeParsing(_timeParsing);
1530  potTable->SetVerbosity(_verbosity);
1531 
1532  potTable->SetValidityRange("run",_runNumber);
1533  potTable->Load();
1534  if (potTable->NRow() == 0) {
1535  std::cerr << __PRETTY_FUNCTION__ << " No POT info found for run "
1536  << _runNumber << std::endl;
1537  return false;
1538  }
1539  else {
1540  potTable->GetRow(0)->Col(potIdx).Get(_npot);
1541  potTable->GetRow(0)->Col(avgIdx).Get(_avgpot);
1542  }
1543 
1544  _gotPOT = true;
1545  return true;
1546 
1547  }
1548 
1549  //**********************************************************************
1550 
1552  {
1553  if (_gotDAQRunHistory) return true;
1554 
1555  if (_failedToFindRun) {
1556  if (_abortIfMissingRunInDB){
1557  LOG_ERROR("RunHistory")<<"LoadDAQRunHistory: failed to find the run in the runs table." << std::endl;
1558  std::abort();
1559  }
1560  else std::cerr << __PRETTY_FUNCTION__ << " failed to find the run in the runs table." << std::endl;
1561  return false;
1562 
1563  }
1564 
1565  if(_runNumber >= 1000000 || _runNumber < 10000) { // it's MC - assume perfect + mask
1566  LOG_INFO("RunHistory") << "Looks like a MC run number - assume perfect + any mask" << std::endl;
1567  _isMC = true;
1568  BuildMC();
1569  return true;
1570  }
1571 
1572  _nDCMs = 0;
1573 
1574  std::unique_ptr<db::Table> runsTable;
1575  std::unique_ptr<db::Table> resTable;
1576  std::unique_ptr<db::Table> srTable;
1577 
1578  runsTable.reset(new db::Table("RunHistory/tables/Runs.xml"));
1579  srTable.reset(new db::Table("RunHistory/tables/Subruns.xml"));
1580  resTable.reset(new db::Table("RunHistory/tables/DAQResourcesByRun.xml"));
1581  runsTable->SetTimeQueries(_timeQueries);
1582  runsTable->SetTimeParsing(_timeParsing);
1583  srTable->SetTimeQueries(_timeQueries);
1584  srTable->SetTimeParsing(_timeParsing);
1585  resTable->SetTimeQueries(_timeQueries);
1586  resTable->SetTimeParsing(_timeParsing);
1587  resTable->SetVerbosity(100);
1588 
1590  runsTable->SetDetector(_detector);
1591  srTable->SetDetector(_detector);
1592  resTable->SetDetector(_detector);
1593  }
1594  else {
1595  LOG_ERROR("RunHistory")<<"RunHistory::LoadDAQRun: invalid detector name!"<<std::endl;
1596  std::abort();
1597 
1598  }
1599 
1600  runsTable->SetSubSchema("daq");
1601  runsTable->SetValidityRange("run",_runNumber);
1602  runsTable->AddExcludeCol(std::string("nevents"));
1603  runsTable->AddExcludeCol(std::string("begin_comment"));
1604  runsTable->AddExcludeCol(std::string("end_comment"));
1605  runsTable->AddExcludeCol(std::string("shifter"));
1606  runsTable->SetVerbosity(_verbosity);
1607  if (!runsTable->Load()){
1608  LOG_ERROR("RunHistory")<<"LoadDAQRunHistory: failed to load the runs table." << std::endl;
1609  if(_detector=="TestBeam" && _abort) std::abort();
1610  else if (_detector!="TestBeam") std::abort();
1611  }
1612 
1613  if (runsTable->NRow() == 0) {
1614  std::cerr << __PRETTY_FUNCTION__ << " no entry found the runs table!" << std::endl;
1615  _failedToFindRun = true;
1616  return false;
1617  }
1618  db::Row* row = runsTable->GetRow(0);
1619  if (row) {
1620  std::string timeStr;
1621  if (row->Col(runsTable->GetColIndex("tstart")).Get(timeStr)) _tStart = timeStr;
1622  if (row->Col(runsTable->GetColIndex("tstop")).Get(timeStr)) _tEnd = timeStr;
1623  // row->Col(runsTable->GetColIndex("nevents")).Get(_nTotTrig);
1624  row->Col(runsTable->GetColIndex("configid")).Get(_gCfgId);
1625  row->Col(runsTable->GetColIndex("nsubruns")).Get(_nsubrun);
1626  row->Col(runsTable->GetColIndex("nactivechan")).Get(_nActiveChannels);
1627  row->Col(runsTable->GetColIndex("partition")).Get(_partition);
1628  row->Col(runsTable->GetColIndex("runtype")).Get(_runType);
1629  }
1630 
1631  // Load subrun information
1632  /*
1633  srTable->SetSubSchema("daq");
1634  srTable->SetValidityRange("run",_runNumber);
1635  srTable->Load();
1636  std::cout << srTable->NRow() << std::endl;
1637  std::cout << "_nsubrun = " << _nsubrun << std::endl;
1638  */
1639  /*
1640  if (srTable->NRow() == _nsubrun-1) {
1641  int srnum;
1642  std::string tstr1, tstr2;
1643 
1644  int numIdx = srTable->GetColIndex("subrun");
1645  int tstartIdx = srTable->GetColIndex("tstart");
1646  int tstopIdx = srTable->GetColIndex("tstop");
1647 
1648  for (int irow=0; irow<_nsubrun-1; ++irow) {
1649  row = srTable->GetRow(irow);
1650  if (row->Col(numIdx).Get(srnum) &&
1651  row->Col(tstartIdx).Get(tstr1) &&
1652  row->Col(tstopIdx).Get(tstr2)) {
1653  std::cout << srnum << ", " << tstr1 << ", " << tstr2 << std::endl;
1654  nova::dbi::Util::TimeAsStringToTime_t(tstr1,_subrunList[srnum].tstart);
1655  nova::dbi::Util::TimeAsStringToTime_t(tstr2,_subrunList[srnum].tstop);
1656  }
1657  }
1658  }
1659  */
1660 
1661  resTable->SetSubSchema("daq");
1662  resTable->SetValidityRange("run",_runNumber);
1663  resTable->AddOrderColumn("appname");
1664  resTable->SetVerbosity(_verbosity);
1665  if (!resTable->Load())
1666  {
1667  LOG_ERROR("RunHistory")<<"LoadDAQRunHistory: failed to load the resources table." << std::endl;
1668  std::abort();
1669  }
1670 
1671 
1672  int nResources = resTable->NRow();
1673  if (nResources == 0){
1674  LOG_ERROR("RunHistory")<<"LoadDAQRunHistory: no resources found for run " << _runNumber << std::endl;
1675  std::abort();
1676  }
1677 
1678  int rtIdx = resTable->GetColIndex("resource_type");
1679  int anIdx = resTable->GetColIndex("appname");
1680  int detIdx = resTable->GetColIndex("detector");
1681 
1683 
1684  for (int i=0; i<nResources; ++i) {
1685  row = resTable->GetRow(i);
1686  std::string rtype;
1687  std::string appname;
1689  if (row->Col(rtIdx).Get(rtype)) {
1690  row->Col(detIdx).Get(detector);
1691  if(detId == novadaq::cnv::kFARDET&&detector!="FarDet") continue;
1692  if(detId == novadaq::cnv::kNEARDET&&detector!="NearDet") continue;
1693  if (rtype == "bnevb") {
1694  BNEVB b;
1695  row->Col(anIdx).Get(appname);
1696  b.appname = appname;
1697  _bnevbList.push_back(b);
1698  }
1699  else if (rtype == "dcm") {
1700  row->Col(anIdx).Get(appname);
1701  bool foundDiBlock = false;
1702  short dbnum = atoi(appname.substr(6,2).c_str());
1703  short pos = atoi(appname.substr(9,2).c_str());
1704  _nDCMs++;
1705  /*
1706  JMP, 2015-11-03: this is strange logic, and created an infinite loop,
1707  since IsGoodDiBlock requires loading the DAQRunHistory. Removing.
1708  if(_useMasking && IsGoodDiBlock(int(dbnum))==false) {
1709  continue; // ignore masked diblocks
1710  }
1711  */
1712 
1713  for (unsigned int idb=0; idb < _dbList.size(); ++idb) {
1714  if (_dbList[idb].num == dbnum) {
1715  _dbList[idb].dcm[pos-1].appname = appname;
1716  _dbList[idb].dcm[pos-1].position = pos;
1717  _dbList[idb].dcm[pos-1].diblock = dbnum;
1718  _dbList[idb].dcm[pos-1].isActive = true;
1719  _dbList[idb].dcm[pos-1].feb.resize(64);
1720  _dbList[idb].dcm[pos-1].nInstrumentedFEBs = 0;
1721  foundDiBlock = true;
1722  break;
1723  }
1724  }
1725  if (!foundDiBlock) {
1726  // diblock does not yet exist, build it
1727  unsigned int ndcms=12;
1728  if (detId == novadaq::cnv::kNEARDET)
1729  ndcms=4;
1730  DiBlock db(ndcms);
1731  db.num = dbnum;
1732  _diblockIndex[dbnum] = _dbList.size();
1733  db.hasNoAPDs = true;
1734  db.nInstrumentedFEBs = 0;
1735  DCM d;
1736  d.appname = appname;
1737  d.diblock = dbnum;
1738  d.position = pos;
1739  d.isActive = true;
1740  d.feb.resize(64);
1741  d.nInstrumentedFEBs = 0;
1742  db.dcm[d.position-1] = d;
1743 
1744  _dbList.push_back(db);
1745  }
1746  }
1747  }
1748  }
1749  std::sort(_dbList.begin(), _dbList.end(), SortDiBlocks);
1750  for (size_t i=0; i<_dbList.size(); ++i)
1751  _diblockIndex[_dbList[i].num] = i;
1752 
1753 
1754  _gotDAQRunHistory = true;
1755  return true;
1756  }
1757 
1758  //**********************************************************************
1759 
1761  {
1762  LoadHardwareInfo();
1763  if (i >= int(_dbList.size())) {
1764  LOG_ERROR("RunHistory")<<"RunHistory::GetDiBlock: invalid diblock!"<<std::endl;
1765  std::abort();
1766  }
1767  if (loadAll) LoadAllDetInfo();
1768  return _dbList[i];
1769  }
1770 
1771  //**********************************************************************
1773  {
1774  if (! _gotHardwareInfo)
1775  LoadHardwareInfo();
1776 
1778  daqchannelmap::diblock_t diblk = daqcmap->getDiBlock(daqChan);
1779  daqchannelmap::dcm_id_t dcmId = daqcmap->getDCM(daqChan);
1780  daqchannelmap::feb_t ifeb = daqcmap->getFEB(daqChan);
1781 
1782  if(_runNumber >= 1000000 || _runNumber < 10000) { // it's MC - assume perfect + mask
1783  if(_useMasking) {if(IsGoodDiBlock(diblk)) return true;}
1784  else return true;
1785  }
1786 
1787  else {
1788  for (unsigned int i=0; i<_dbList.size(); ++i)
1789  if (_dbList[i].num == (short)diblk) {
1790  if (_dbList[i].hasNoAPDs) return false;
1791  if (_useMasking && IsGoodDiBlock(diblk)==false) return false;
1792  if (! _dbList[i].dcm[dcmId-1].isActive)
1793  return false;
1794  else
1795  return _dbList[i].dcm[dcmId-1].feb[ifeb].hasAPD;
1796  }
1797  }
1798  return false;
1799  }
1800 
1801  //**********************************************************************
1803  {
1805  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
1806  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
1807 
1808  return HasAPD(daqChan);
1809 
1810  }
1811 
1812  //**********************************************************************
1813 
1815  {
1816  LoadHardwareInfo();
1817 
1819 
1820  for (unsigned int i=0; i<_dbList.size(); ++i) {
1821  if (_dbList[i].num == idb) {
1822  if (detId==novadaq::cnv::kFARDET && _dbList[i].nInstrumentedFEBs >= 700) return true;
1823  if (detId==novadaq::cnv::kNEARDET && idb < 4 && _dbList[i].nInstrumentedFEBs >= 175) return true;
1824  if (detId==novadaq::cnv::kNEARDET && idb == 4 && _dbList[i].nInstrumentedFEBs >= 45) return true;
1825  return false;
1826  }
1827  }
1828 
1829  return false;
1830 
1831  }
1832 
1833  //**********************************************************************
1835  {
1836  std::cerr << __PRETTY_FUNCTION__ << " is not yet implemented!"
1837  << std::endl;
1838 
1839  bool iscooled = false;
1840 
1841  if (!LoadPixelInfo()) return false;
1842 
1844  daqchannelmap::diblock_t diblk = dmap->getDiBlock(daqChan);
1845  daqchannelmap::dcm_id_t dcmId = dmap->getDCM(daqChan);
1846  daqchannelmap::feb_t ifeb = dmap->getFEB(daqChan);
1847 
1848  for (unsigned int iDB=0; iDB<_dbList.size(); ++iDB) {
1849  if (_dbList[iDB].num == (short)diblk) {
1850  if (_dbList[iDB].hasNoAPDs) return iscooled;
1851  int iDCM = dcmId-1;
1852  if (iDCM >= (int)_dbList[iDB].dcm.size()) return iscooled;
1853 
1854  if (!_dbList[iDB].dcm[iDCM].isActive) return iscooled;
1855  if (_dbList[iDB].dcm[iDCM].position == -1) return iscooled;
1856 
1857  if (ifeb >= _dbList[iDB].dcm[iDCM].feb.size()) return iscooled;
1858 
1859  FEB& currFEB = _dbList[iDB].dcm[iDCM].feb[ifeb];
1860  if (!currFEB.isEnabled) return iscooled;
1861 
1862  if ( !currFEB.hasAPD ) return iscooled;
1863 
1864  //everything is fine
1865  iscooled = currFEB.isCooled;
1866  break;
1867  }
1868  }
1869 
1870  return iscooled;
1871  }
1872 
1873  //**********************************************************************
1875  {
1877  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
1878  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
1879 
1880  return IsCooled(daqChan);
1881  }
1882 
1883  //**********************************************************************
1885  bool & ok)
1886  {
1887  FEB feb;
1888  ok = false;
1889 
1890  if (!LoadAPDSettings()) return feb;
1891 
1893  daqchannelmap::diblock_t diblk = dmap->getDiBlock(daqChan);
1894  daqchannelmap::dcm_id_t dcmId = dmap->getDCM(daqChan);
1895  daqchannelmap::feb_t ifeb = dmap->getFEB(daqChan);
1896 
1897  for (size_t iDB = 0; iDB < _dbList.size(); ++iDB) {
1898  if (_dbList[iDB].num == (short)diblk) {
1899  DiBlock currDiBlock = GetDiBlock(iDB);
1900  if (currDiBlock.hasNoAPDs) return feb;
1901  int iDCM = dcmId-1;
1902  if (iDCM >= (int)currDiBlock.dcm.size()) return feb;
1903 
1904  DCM currDCM = currDiBlock.dcm[iDCM];
1905  if (currDCM.position == -1) return feb;
1906 
1907  std::bitset<64> febSet(currDCM.febMask);
1908  if (ifeb >= currDCM.feb.size()) return feb;
1909 
1910  FEB currFEB = currDCM.feb[ifeb];
1911  if (!febSet[ifeb] || !currFEB.isEnabled) return feb;
1912 
1913  if ( !currFEB.hasAPD ) return feb;
1914 
1915  //everything is fine
1916  ok = true;
1917  feb = currFEB;
1918 
1919  break;
1920  }
1921  }
1922 
1923  return feb;
1924  }
1925 
1926  //**********************************************************************
1928  bool & ok)
1929  {
1931  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
1932  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
1933 
1934  return this->GetFEB(daqChan, ok);
1935  }
1936 
1937  //**********************************************************************
1938  // GetFEB checks to make sure that the APD settings have been loaded properly
1939  float RunHistory::GetGain(const daqchannelmap::dchan& daqChan, bool& ok)
1940  {
1941  float gain=0.;
1942 
1943  FEB feb = this->GetFEB(daqChan, ok);
1944 
1945  if(ok) return feb.gain;
1946 
1947  return gain;
1948  }
1949 
1950  //**********************************************************************
1951  float RunHistory::GetGain(const geo::OfflineChan& oChan, bool& ok)
1952  {
1954  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
1955  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
1956 
1957  return GetGain(daqChan, ok);
1958  }
1959 
1960  //**********************************************************************
1962  bool & ok)
1963  {
1964 
1965  FEB feb = this->GetFEB(daqChan, ok);
1967  daqchannelmap::pixel_t pixel = dmap->getPixel(daqChan);
1968  if(ok && pixel < feb.pixelGain.size()) return feb.pixelGain[pixel];
1969 
1970  return 0.;
1971  }
1972 
1973  //**********************************************************************
1975  bool & ok)
1976  {
1978  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
1979  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
1980 
1981  return this->GetPixelGain(daqChan, ok);
1982  }
1983 
1984  //**********************************************************************
1985  std::vector<float> RunHistory::GetPixelGains(daqchannelmap::dchan const& daqChan,
1986  bool & ok)
1987  {
1988 
1989  FEB feb = this->GetFEB(daqChan, ok);
1990 
1991  if(ok) return feb.pixelGain;
1992 
1993  return std::vector<float>(32, 0.);
1994  }
1995 
1996  //**********************************************************************
1997  std::vector<float> RunHistory::GetPixelGains(geo::OfflineChan const& oChan,
1998  bool & ok)
1999  {
2001  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
2002  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
2003 
2004  return this->GetPixelGains(daqChan, ok);
2005  }
2006 
2007  //**********************************************************************
2008  int RunHistory::GetThreshold(const daqchannelmap::dchan& daqChan, bool& ok)
2009  {
2010  if (! _gotPixelInfo)
2011  LoadPixelInfo();
2012 
2013  ok = false;
2014  int threshold(4095);
2016  daqchannelmap::diblock_t diblk = dmap->getDiBlock(daqChan);
2017  daqchannelmap::dcm_id_t dcmId = dmap->getDCM(daqChan);
2018  daqchannelmap::feb_t ifeb = dmap->getFEB(daqChan);
2019  daqchannelmap::pixel_t ipix = dmap->getPixel(daqChan);
2020 
2021  //if (diblk > 2) return threshold;
2022 
2023  //daqchannelmap::diblock_t ranges from 1 to 17 -> subtract 1 to get c++ index
2024  for (unsigned int iDB=0; iDB<_dbList.size(); ++iDB) {
2025  if (_dbList[iDB].num == (short)diblk) {
2026  if (_dbList[iDB].hasNoAPDs) return threshold;
2027  //daqchannelmap::dcm_id_t ranges from 1 to 12 -> subtract 1 to get c++ index
2028  int iDCM = dcmId-1;
2029  if (iDCM >= (int)_dbList[iDB].dcm.size()) break;
2030 
2031  DCM& currDCM = _dbList[iDB].dcm[iDCM];
2032  if (currDCM.position == -1) break;
2033 
2034  std::bitset<64> febSet(currDCM.febMask);
2035  if (ifeb >= currDCM.feb.size()) break;
2036 
2037  FEB& currFEB = currDCM.feb[ifeb];
2038  if (!febSet[ifeb] || !currFEB.isEnabled) break;
2039 
2040  std::bitset<32> pixSet(currFEB.pixelMask);
2041  if (!pixSet[ipix]) break;
2042 
2043  if ( !currFEB.hasAPD ) break;
2044 
2045  //everything is fine
2046  ok = true;
2047  threshold = currFEB.pixelThresh[ipix];
2048  break;
2049  }
2050 
2051  }
2052 
2053  return threshold;
2054  }
2055 
2056  //**********************************************************************
2057  int RunHistory::GetThreshold(const geo::OfflineChan& oChan, bool& ok)
2058  {
2059  if (! _gotPixelInfo)
2060  LoadPixelInfo();
2061 
2063  daqchannelmap::lchan logChan = dmap->encodeLChan(_detId, oChan.Plane(), oChan.Cell());
2064  daqchannelmap::dchan daqChan = dmap->encodeDChan(logChan);
2065 
2066  int threshold = GetThreshold(daqChan, ok);
2067  return threshold;
2068  }
2069 
2070 
2071  //**********************************************************************
2072  std::vector<DQSubrunInfo> RunHistory::GetDQSubrunInfo()
2073  {
2074  if (!_gotDQSubrunInfo) {
2075  _dqSRInfo.clear();
2076 
2077  std::unique_ptr<db::Table> dqTable(new nova::dbi::Table("RunHistory/tables/DQSubrunInfo.xml"));
2078  dqTable->SetDetector(_detector);
2079  dqTable->SetValidityRange("run",_runNumber);
2080  dqTable->AddOrderColumn("version");
2081  dqTable->SetOrderDesc();
2082  dqTable->AddExcludeCol(std::string("comment"));
2083  dqTable->AddExcludeCol(std::string("inserttime"));
2084  dqTable->AddExcludeCol(std::string("insertuser"));
2085  dqTable->SetVerbosity(_verbosity);
2086  dqTable->Load();
2087 
2088  std::map<std::string,int> colName = dqTable->GetColNameToIndexMap();
2089 
2090  int version=0;
2091  int nextVersion=0;
2092  for (int i=0; i<dqTable->NRow(); ++i) {
2093  // make sure we only use rows with the latest version number
2094  if (i==0) {
2095  dqTable->GetRow(i)->Col(colName["version"]).Get(version);
2096  nextVersion=version;
2097  }
2098  else
2099  dqTable->GetRow(i)->Col(colName["version"]).Get(nextVersion);
2100 
2101  if (nextVersion != version) break;
2102 
2103  DQSubrunInfo sri;
2104  sri._run = _runNumber;
2105  sri._version = version;
2106  dqTable->GetRow(i)->Col(colName["subrun"]).Get(sri._subrun);
2107  dqTable->GetRow(i)->Col(colName["flag"]).Get(sri._flag);
2108  dqTable->GetRow(i)->Col(colName["miprate"]).Get(sri._miprate);
2109  dqTable->GetRow(i)->Col(colName["ngooddb"]).Get(sri._ngooddb);
2110  dqTable->GetRow(i)->Col(colName["numslc"]).Get(sri._numslc);
2111  dqTable->GetRow(i)->Col(colName["trkfrac"]).Get(sri._trkfrac);
2112  _dqSRInfo.push_back(sri);
2113  }
2114  _gotDQSubrunInfo = true;
2115  }
2116 
2117  return _dqSRInfo;
2118  }
2119 
2120  //**********************************************************************
2122  {
2123  std::map<geo::OfflineChan,std::vector<ChanInfo_t> >::iterator it = _chanInfo.begin();
2124  for (; it != _chanInfo.end(); ++it) {
2125  std::vector<ChanInfo_t>& ci = it->second;
2126  geo::OfflineChan chan = it->first;
2127  for (unsigned int j=0; j<ci.size(); ++j)
2128  std::cout << chan.Plane() << "," << chan.Cell() << "," << ci[j].occ
2129  << std::endl;
2130  }
2131  }
2132 
2133  //**********************************************************************
2134 
2135  void RunHistory::SetChanInfo(geo::OfflineChan chan, float occ, float coinc,
2136  time_t t)
2137  {
2138  ChanInfo_t ci;
2139  ci.occ = occ;
2140  ci.coinc = coinc;
2141  ci.tstart = t;
2142  _chanInfo[chan].push_back(ci);
2143  }
2144 
2145  //**********************************************************************
2146 
2148  {
2149  const std::vector<ChanInfo_t>& cis = _chanInfo[chan];
2150 
2151  unsigned int i=0;
2152  for (; i<cis.size() && cis[i].tstart<t; ++i);
2153  if (i>0)
2154  return cis[i-1].occ;
2155  else
2156  return -6.;
2157  }
2158 
2159  //**********************************************************************
2160 
2162  {
2163  const std::vector<ChanInfo_t>& cis = _chanInfo[chan];
2164 
2165  unsigned int i=0;
2166  for (; i<cis.size() && cis[i].tstart<t; ++i);
2167  if (i>0)
2168  return cis[i-1].coinc;
2169  else
2170  return 0.;
2171  }
2172 
2173  //**********************************************************************
2174 
2175  void RunHistory::SetIsBad(geo::OfflineChan chan, bool isBad, time_t t)
2176  {
2177  BadChan_t b;
2178  b.isBad = isBad;
2179  b.tstart = t;
2180  _badChan[chan].push_back(b);
2181  }
2182 
2183  //**********************************************************************
2184 
2186  {
2187  unsigned int i=0;
2188  for (; i<_badChan[chan].size() && _badChan[chan][i].tstart<t; ++i);
2189  return _badChan[chan][i-1].isBad;
2190  }
2191 
2192  //**********************************************************************
2193  time_t RunHistory::SubrunTStart(int isr) {
2195  if (isr < 0 || isr > _nsubrun) return 0;
2196  if (isr == 0) return this->TStart();
2197  return _subrunList[isr].tstart;
2198  }
2199 
2200  //**********************************************************************
2201  time_t RunHistory::SubrunTStop(int isr) {
2203  if (isr < 0 || isr > _nsubrun) return 0;
2204  if (isr == _nsubrun-1) return this->TStop();
2205  return _subrunList[isr+1].tstart;
2206  }
2207 
2208  //**********************************************************************
2211  time_t t;
2213  return t;
2214  else
2215  return 0;
2216  }
2217 
2218  //**********************************************************************
2219 
2222  time_t t;
2223  std::string tEnd = _tEnd;
2224  if (_tEnd == "")
2225  tEnd = "2000-01-01 00:00:00";
2227  return t;
2228  else
2229  return 0;
2230  }
2231 
2232  //**********************************************************************
2233 
2235  std::cout << "****************************************" << std::endl;
2236  std::cout << "Dump of run " << _runNumber << std::endl;
2237  std::cout << "****************************************\n" << std::endl;
2238  std::cout << "Num Subruns : " << _nsubrun << std::endl;
2239  std::cout << "Start time : " << TStartAsString() << std::endl;
2240  std::cout << "End time : " << TStopAsString() << std::endl;
2241  std::cout << "Trig Tot : " << _nTotTrig << std::endl;
2242  std::cout << "Num Active Channels: " << _nActiveChannels << std::endl;
2243  std::cout << "Num Total Channels: " << _nTotalChannels << std::endl;
2244  std::cout << "Num DCMs : " << NLiveDCMs() << std::endl;
2245  for (unsigned int i=0; i<_dbList.size(); ++i)
2246  for (unsigned int j=0; j<_dbList[i].dcm.size(); ++j)
2247  if (_dbList[i].dcm[j].isActive)
2248  std::cout << "\t" << _dbList[i].dcm[j].appname << std::endl;
2249  std::cout << "Num BNEVBs : " << _bnevbList.size() << std::endl;
2250  for (unsigned int i=0; i<_bnevbList.size(); ++i)
2251  std::cout << "\t" << _bnevbList[i].appname << std::endl;
2252 
2253  }
2254 
2255  //**********************************************************************
2256 
2258  {
2259  _failedToFindRun = false;
2260  _gotDAQRunHistory = false;
2261  _gotFEBMasks = false;
2262  _gotPixelInfo = false;
2263  _gotHardwareInfo = false;
2264  _gotAPDSettings = false;
2265  _gotCoolingInfo = false;
2266  _gotPOT = false;
2267  _gotGoodDiBlockMask = false;
2268  _gotDQSubrunInfo = false;
2269  _gotDataEpoch = false;
2270  _gotPixelMasks = false;
2271  _gotPedestals = false;
2272  _diblockIndex.clear();
2273 
2274  _isMC = false;
2275 
2276  _subrunList.clear();
2277  _subrunList.resize(64);
2278  for (int isr=0; isr<_nsubrun; ++isr) {
2279  _subrunList[isr].tstart = 0;
2280  _subrunList[isr].tstop = 0;
2281  _subrunList[isr].goodDiBlockMask = 0;
2282  _subrunList[isr].gotNAnalysisDiBlocks = false;
2283  _subrunList[isr].gotNAnalysisChannels = false;
2284  _subrunList[isr].nAnalysisDiBlocks = 0;
2285  _subrunList[isr].nAnalysisChannels = 0;
2286  }
2287 
2288 
2289  _npot = 0.;
2290  _avgpot = 0.;
2291  _nTotTrig = 0;
2292  _nActiveChannels=0;
2293  _nTotalChannels=0;
2294  _nTotalFEBs=0;
2295  _nInstalledAPDs=0;
2296  _customMask=0;
2297  _detGainSetting=0;
2298  _dbList.clear();
2299  _bnevbList.clear();
2300  }
2301 
2302  //**********************************************************************
2303  // the key for the returned map is the module # in the module_apd_connection table
2304  std::map<uint32_t, APDInfo> RunHistory::PullAPDInfoFromDB()
2305  {
2306  LOG_INFO("RunHistory") << "Pull APD Info from DB" << std::endl;
2307  //TStopwatch ts;
2308 
2309  std::map<uint32_t, APDInfo> apdinfomap;
2310  std::map<std::string, std::vector<float> > apdgains;
2311 
2312  std::list<std::string> notInstalledAPD;
2313 
2314  std::unique_ptr<db::Table> hwTable;
2315  hwTable.reset(new db::Table());
2316 
2318  hwTable->SetDetector(_detector);
2319  else {
2320  LOG_ERROR("RunHistory")<<"Could not establish detector table connection"<<std::endl;
2321  std::abort();
2322  }
2323  hwTable->SetTableType(nova::dbi::kHardwareTable);
2324  //hwTable->SetIgnoreEnvVar(false);
2325  hwTable->SetTimeQueries(_timeQueries);
2326  hwTable->SetVerbosity(_verbosity);
2327 
2328  std::string SQL;
2329 
2330  PGresult* res = nullptr;
2331  // PGresult* res2 = nullptr;
2332 
2333  if (_detId == novadaq::cnv::kFARDET) {
2334 
2335  // get test information for APDs
2336  SQL ="select right(gain.apd_id, 7), gain.batch_no, gain.target_degc, gain.pixel_col, gain.pixel_row, gain.pixel_m from public.apd_pixel_m gain where gain.target_degc<0 ORDER BY right(gain.apd_id, 7) ASC, gain.batch_no DESC, gain.target_degc ASC, gain.pixel_col ASC, gain.pixel_row ASC";
2337 
2338  res = PerformPGQuery(SQL, hwTable);
2339  uint32_t row;
2340  uint32_t col;
2341  uint32_t pixel;
2342  std::string colStr;
2343  std::string apdSN;
2344  int numRows = PQntuples(res);
2345  int batch;
2346 
2347  for(int r = 0; r < numRows; ++r){
2348 
2349  apdSN = PQgetvalue(res, r, 0);
2350  batch = std::atoi(PQgetvalue(res, r, 1));
2351 
2352  // the query is ordered by the batch number with the most recent first
2353  // so only grab those values
2354  if(apdgains.count(apdSN) < 1){
2355  apdgains[apdSN] = std::vector<float>(32,100.);
2356 
2357  while(apdSN.compare(PQgetvalue(res, r, 0)) == 0 &&
2358  batch == std::atoi(PQgetvalue(res, r, 1)) ){
2359  colStr = PQgetvalue(res, r, 3);
2360  row = std::atoi(PQgetvalue(res, r, 4)) - 1;
2361  col = 0;
2362  if (colStr.compare("B") == 0) col = 8;
2363  else if(colStr.compare("C") == 0) col = 16;
2364  else if(colStr.compare("D") == 0) col = 24;
2365 
2366  // encode "dummy" dchan with constant diblock, dcm and feb numbers as we only need the
2367  // correct pixel and detector to be encoded.
2370 
2371  apdgains[apdSN][pixel] = std::atof(PQgetvalue(res, r, 5));
2372 
2373  ++r;
2374  } // end loop to get the gains for the most recent batch of this apd
2375  // need to decrement r by 1 so that the end of the for loop doesn't push us one to far
2376  --r;
2377  } // end if the apd is not already in the map
2378 
2379  }// end loop over query to get the apd gain information
2380 
2381  SQL = "select right(astat.apd_id, 7), astat.batch_no, astat.target_degc, astat.vr, bi.barcoded_item_id, bi.date_added, mac.module, mac.connection_id, nc.date_removed from public.apd_stats astat, ashriverprod_factory.barcoded_item bi, ashriverprod_factory.module_apd_connection mac, ashriverprod_factory.nova_connection nc ";
2382  SQL += "where right(bi.barcode,7)=right(astat.apd_id,7) and bi.glassfish_discriminator='apd' and mac.apd=bi.barcoded_item_id and nc.connection_id=mac.connection_id and bi.date_added < '";
2383  SQL += _tStart;
2384  SQL += "' and (nc.date_removed is NULL or nc.date_removed > '";
2385  SQL += _tStart;
2386  SQL += "') and (bi.date_removed is NULL or bi.date_removed > '";
2387  SQL += _tStart;
2388  SQL += "')";
2389  // order the results by APD serial number and then temperature.
2390  // We only take the first result, ie the low temperature data, except
2391  // when there is only high temp data.
2392  SQL += "ORDER BY right(astat.apd_id, 7) ASC, astat.target_degc ASC";
2393 
2394  //ts.Start();
2395  res = PerformPGQuery(SQL, hwTable);
2396  //ts.Stop();
2397  //ts.Print();
2398  // LOG_DEBUG("APDInfo") << "query " << SQL << " returned " << PQntuples(res)
2399  // << " rows\n First Row: " << PQgetvalue(res, 0, 0)
2400  // << " " << PQgetvalue(res, 0, 1)
2401  // << " " << PQgetvalue(res, 0, 2)
2402  // << " " << PQgetvalue(res, 0, 3)
2403  // << " " << PQgetvalue(res, 0, 4)
2404  // << " " << PQgetvalue(res, 0, 5)
2405  // << " " << PQgetvalue(res, 0, 6)
2406  // << " " << PQgetvalue(res, 0, 7)
2407  // << " " << PQgetvalue(res, 0, 8)
2408  // << " in ";
2409 
2410  //ts.Reset();
2411  //ts.Start();
2412  std::string date;
2413  APDInfo apdi;
2414  APDInfo prevAPD;
2415  numRows = PQntuples(res);
2416 
2417  LOG_DEBUG("RunHistory") << "Found " << numRows << " apds in the db";
2418 
2419  for(int r = 0; r < numRows; ++r){
2420 
2421  // convert the date added to the number of seconds since 1970
2422  date = PQgetvalue(res, r, 5);
2423  TTimeStamp ts(std::atoi(date.substr(0,4).c_str()),
2424  std::atoi(date.substr(5,2).c_str()),
2425  std::atoi(date.substr(8,2).c_str()),
2426  std::atoi(date.substr(12,2).c_str()),
2427  std::atoi(date.substr(15,2).c_str()),
2428  std::atoi(date.substr(18,2).c_str()));
2429 
2430  apdi._sn = PQgetvalue(res, r, 0);
2431  apdi._batch = std::atoi(PQgetvalue(res, r, 1));
2432  apdi._temp = std::atoi(PQgetvalue(res, r, 2));
2433  apdi._voltage = std::atof(PQgetvalue(res, r, 3));
2434  apdi._barcode = std::atoi(PQgetvalue(res, r, 4));
2435  apdi._installed = ts.AsDouble();
2436  apdi._module = std::atoi(PQgetvalue(res, r, 6));
2437  apdi._modcon = std::atoi(PQgetvalue(res, r, 7));
2438 
2439  if(apdgains.count(apdi._sn) > 0)
2440  apdi._pixelGain = apdgains[apdi._sn];
2441  // else
2442  // std::cout << "no gains found for " << apdi._sn << std::endl;
2443 
2444  // make sure the current apd is not already in the map and
2445  // that the avGain is > 0
2446  // if it is already in the map, use the most recent
2447  if(apdinfomap.count(apdi._module) > 0){
2448 
2449  prevAPD = apdinfomap.at(apdi._module);
2450 
2451  // first check the installed date
2452  if(apdi._installed > prevAPD._installed)
2453  apdinfomap[apdi._module] = apdi;
2454  }
2455  else
2456  apdinfomap[apdi._module] = apdi;
2457 
2458  //LOG_DEBUG("APDInfo") << apdi;
2459 
2460  } // end loop over rows
2461  //ts.Stop();
2462  //ts.Print();
2463 
2464  PQclear(res);
2465 
2466  } // end if the far detector
2467 
2468  //ts.Stop();
2469  //ts.Print();
2470 
2471  LOG_DEBUG("APDInfo")
2472  << apdinfomap.size()
2473  << " apds were installed"
2474  << "print out info for all APDs";
2475 
2476  hwTable->CloseConnection();
2477 
2478  return apdinfomap;
2479  }
2480 
2481  //**********************************************************************
2482  std::map<HardwareLocation, std::pair<FEBInfo, APDInfo>> RunHistory::PullFEBInfoFromDB(std::map<uint32_t, APDInfo> apdinfomap)
2483  {
2484  //std::cout << "Pull FEB Info from DB" << std::endl;
2485  //TStopwatch ts;
2486  //ts.Start();
2487 
2488  // the key for this map is the module # in the module_feb_connection table
2489  std::list<std::pair<FEBInfo, APDInfo>> febtoapd;
2490  std::map<uint32_t, FEBInfo> febinfomap;
2491 
2492  std::unique_ptr<db::Table> hwTable;
2493  hwTable.reset(new db::Table());
2494 
2496  hwTable->SetDetector(_detector);
2497  else {
2498  LOG_ERROR("RunHistory")<<"could not extablish table connection for detector"<<std::endl;
2499  std::abort();
2500  }
2501  hwTable->SetTableType(nova::dbi::kHardwareTable);
2502  //hwTable->SetIgnoreEnvVar(false);
2503  hwTable->SetTimeQueries(_timeQueries);
2504  hwTable->SetVerbosity(_verbosity);
2505 
2506  std::string SQL;
2507 
2508  PGresult* res = nullptr;
2509 
2510  std::map<HardwareLocation, std::pair<FEBInfo, APDInfo>> htol;
2511 
2512  if (_detId == novadaq::cnv::kFARDET) {
2513 
2514  // get locations of installed FEBs
2515  SQL = "select bi.barcode, febtest.hvfitintercept, febtest.hvfitslope, bi.barcoded_item_id, bi.date_added, mfc.module, mfc.connection_id, nc.date_removed from ashriverprod_factory.barcoded_item bi, ashriverprod_factory.module_feb_connection mfc, ashriverprod_factory.nova_connection nc, public.feb_test_summary febtest where bi.barcode=overlay(overlay(febtest.febsn placing '.' from 5 for 1) placing '.' from 7 for 1) and bi.glassfish_discriminator='feb' and mfc.feb=bi.barcoded_item_id and nc.connection_id=mfc.connection_id and bi.date_added < '";
2516  SQL += _tStart;
2517  SQL += "' and (nc.date_removed is NULL or nc.date_removed > '";
2518  SQL += _tStart;
2519  SQL += "') and (bi.date_removed is NULL or bi.date_removed > '";
2520  SQL += _tStart;
2521  SQL += "') ORDER BY bi.date_added DESC";
2522 
2523  res = PerformPGQuery(SQL, hwTable);
2524  // std::cout << SQL << "\n returned "
2525  // << PQntuples(res)
2526  // << " rows" << std::endl;
2527 
2528  int nRow = PQntuples(res);
2529  for(int r = 0; r < nRow; ++r){
2530  // convert the date added to the number of seconds since 1970
2531  std::string date = PQgetvalue(res, 0, 4);
2532  TTimeStamp ts(std::atoi(date.substr(0,4).c_str()),
2533  std::atoi(date.substr(5,2).c_str()),
2534  std::atoi(date.substr(8,2).c_str()),
2535  std::atoi(date.substr(12,2).c_str()),
2536  std::atoi(date.substr(15,2).c_str()),
2537  std::atoi(date.substr(18,2).c_str()));
2538 
2539  FEBInfo febi;
2540  febi._sn = PQgetvalue(res, r, 0);
2541  febi._intercept = std::atof(PQgetvalue(res, r, 1));
2542  febi._slope = std::atof(PQgetvalue(res, r, 2));
2543  febi._barcode = std::atoi(PQgetvalue(res, r, 3));
2544  febi._module = std::atoi(PQgetvalue(res, r, 5));
2545  febi._modcon = std::atoi(PQgetvalue(res, r, 6));
2546  febi._installed = ts.AsDouble();
2547 
2548  // use the default slope from Leon M. if the returned slope is 0
2549  if(febi._slope == 0.) febi._slope = 0.02586;
2550 
2551  // make sure the current feb is not already in the map
2552  // if it is, use the most recent
2553  if(febinfomap.count(febi._module) > 0){
2554 
2555  if(febi._installed > febinfomap[febi._module]._installed)
2556  febinfomap[febi._module] = febi;
2557  }
2558  else
2559  febinfomap[febi._module] = febi;
2560 
2561  } // end loop over febs
2562  PQclear(res);
2563 
2564  LOG_DEBUG("RunHistory")
2565  << "there are " << febinfomap.size()
2566  << " febs installed and put in the map and "
2567  << apdinfomap.size() << " apds";
2568 
2569  // now get the module to hardware location map
2570  SQL = "select btrim(fcom.location1, 'DIBLK:') diblk, btrim(fcom.position1, 'DCM:') dcm, btrim(fcom.port1,'PRT:') feb, mod.block, mod.layer, mod.position_in_layer, mod.barcoded_item_id from public.feb_comm_cables fcom, ashriverprod_factory.module mod where (mod.block=CAST(btrim(fcom.location2,'BLK:') AS INT) and mod.layer=CAST(btrim(fcom.position2,'PLN:') AS INT) and mod.position_in_layer=CAST(btrim(fcom.port2,'POS:') AS INT)) ORDER BY diblk ASC, dcm ASC, feb ASC";
2571 
2572  res = PerformPGQuery(SQL, hwTable);
2573 
2574  HardwareLocation hl;
2575  uint32_t mod = 0;
2576  uint32_t noapd = 0;
2577  for(int r = 0; r < PQntuples(res); ++r){
2578 
2579  hl._detid = _detId;
2580  hl._diblock = std::atoi(PQgetvalue(res, r, 0));
2581  hl._dcm = std::atoi(PQgetvalue(res, r, 1));
2582  hl._feb = std::atoi(PQgetvalue(res, r, 2));
2583  hl._block = std::atoi(PQgetvalue(res, r, 3));
2584  hl._layer = std::atoi(PQgetvalue(res, r, 4));
2585  hl._layerPos = std::atoi(PQgetvalue(res, r, 5));
2586  mod = std::atoi(PQgetvalue(res, r, 6));
2587 
2588  // find the FEB for this module
2589  if(febinfomap.count(mod) > 0){
2590  std::pair<FEBInfo, APDInfo> hwpair;
2591  hwpair.first = febinfomap[mod];
2592 
2593  // find the corresponding apd
2594  if(apdinfomap.count(mod) > 0)
2595  hwpair.second = apdinfomap[mod];
2596  else{
2597  LOG_DEBUG("RunHistory")
2598  << noapd
2599  << " no APD found for "
2600  << hwpair.first << " installed at " << hl;
2601 
2602  ++noapd;
2603  }
2604  htol[hl] = hwpair;
2605  }
2606  }
2607 
2608  PQclear(res);
2609 
2610  LOG_DEBUG("RunHistory")
2611  << "There are " << febinfomap.size()
2612  << " febs in the db, and " << htol.size()
2613  << " are connected to a harward location" << std::endl
2614  << "There are " << apdinfomap.size() << " apds installed";
2615 
2616 
2617  } // end if the right detector
2618 
2619  //ts.Stop();
2620  //ts.Print();
2621 
2622  hwTable->CloseConnection();
2623 
2624  return htol;
2625  }
2626 
2627  //**********************************************************************
2629  {
2630  // TStopwatch ts;
2631  // ts.Start();
2632 
2633  // get the location to installed hardware map
2634  auto htol = this->PullFEBInfoFromDB(this->PullAPDInfoFromDB());
2635 
2636  gLocToFA.swap(htol);
2637 
2638  if (_detId == novadaq::cnv::kFARDET) {
2639 
2640  // look for missing hardware locations
2641  int missingHardware = 0;
2642  for (int idb=0; idb<14; ++idb) {
2643  for (unsigned int idcm=0; idcm<12; ++idcm) {
2644  for (int j=0; j<64; ++j) {
2645  // no gain recorded for the FEB, see if it is in the hardware
2646  // location map
2647  HardwareLocation hl;
2648  hl._detid = _detId;
2649  hl._diblock = idb + 1;
2650  hl._dcm = idcm + 1;
2651  hl._feb = j;
2652 
2653  if(gLocToFA.count(hl) < 1){
2654  LOG_DEBUG("RunHistory") << hl << " is not in the location map";
2655  ++missingHardware;
2656  }
2657  }// end loop over febs
2658  }// end loop over dcms
2659  }// end loop over diblocks
2660  LOG_DEBUG("RunHistory") << "there are " << missingHardware << " locations without hardware";
2661  }
2662 
2663  // ts.Stop();
2664  // ts.Print();
2665 
2666  return;
2667  }
2668 
2669  void RunHistory::BuildMC() // build fake everything for MC
2670  {
2671 
2672  unsigned int fNDiblocks = 14;
2673  unsigned int fNDCMs = 12;
2674 
2675  if (_detId == novadaq::cnv::kNEARDET) {
2676  fNDiblocks = 4;
2677  fNDCMs = 4;
2678  }
2679 
2680  for (unsigned int ndib = 1; ndib<=fNDiblocks; ndib++) { // make full set of diblocks
2681 
2682  if(!IsGoodDiBlock(ndib)) continue;
2683 
2684  if(_detId == novadaq::cnv::kNEARDET && ndib==4) fNDCMs = 2;
2685  DiBlock db(fNDCMs);
2686  db.num = ndib;
2687  _diblockIndex[ndib] = ndib-1;
2688  db.hasNoAPDs = false;
2690  if(ndib == 4) db.nInstrumentedFEBs = 53;
2691  else db.nInstrumentedFEBs = 192;
2692  }
2693  else db.nInstrumentedFEBs = fNDCMs*64;
2694  for(unsigned int ndcm = 1; ndcm <= fNDCMs; ndcm++) {
2695  DCM d;
2696  d.diblock = ndib;
2697  d.position = ndcm;
2698  d.isActive = true;
2699  if(_detId == novadaq::cnv::kNEARDET && ndib<4 && (ndcm==1 || ndcm==4)) {
2700  d.feb.resize(32);
2701  d.nInstrumentedFEBs = 32;
2702  }
2703  else if(_detId == novadaq::cnv::kNEARDET && ndib==4 && ndcm==1) {
2704  d.feb.resize(31);
2705  d.nInstrumentedFEBs = 31;
2706  }
2707  else if(_detId == novadaq::cnv::kNEARDET && ndib==4 && ndcm==2) {
2708  d.feb.resize(22);
2709  d.nInstrumentedFEBs = 22;
2710  }
2711  else {
2712  d.feb.resize(64);
2713  d.nInstrumentedFEBs = 64;
2714  }
2715  db.dcm[d.position-1] = d;
2716  }
2717  _dbList.push_back(db);
2718  }
2719 
2720  _gotDAQRunHistory = true; // don't want to be asking about these things for MC runs, leave the parameters these functions fill at 0
2721  _gotPixelInfo = true;
2722  _gotHardwareInfo = true;
2723  _gotAPDSettings = true;
2724  _gotCoolingInfo = true;
2725  _gotPOT = true;
2726  _nsubrun = 64;
2727  }
2728 
2729  } // end of namespace dbi
2730 } // end of namespace nova
static std::string GetName(int id)
#define LOG_DEBUG(stream)
Definition: Messenger.h:149
std::vector< DQSubrunInfo > _dqSRInfo
Definition: RunHistory.h:560
float _intercept
intercept for voltage setting
Definition: RunHistory.h:163
::xsd::cxx::tree::date< char, simple_type > date
Definition: Database.h:186
diblock
print "ROW IS " print row
Definition: geo2elec.py:31
Column & Col(int i)
Find index of column with name. Suitable for passing to Col.
Definition: Row.h:63
std::string _tStart
Definition: RunHistory.h:551
uint32_t _layerPos
position in the layer
Definition: RunHistory.h:203
set< int >::iterator it
bool IsDiBlockFullyInstrumented(int idb)
returns true if nInstrumentedFEBs in diblock (which counts FEBs that are instrumented, active, and unmasked only) is >= 700
time_t SubrunTStop(int isr)
int NAnalysisChannels(int sr=0)
Definition: RunHistory.cxx:285
bool getFEBEnableMask(const std::string &dcmName, int64_t &febMask)
bool isActive
if it was active in run according to DAQ
Definition: RunHistory.h:282
void SetDetector(novadaq::cnv::DetId det)
Definition: RunHistory.cxx:325
std::string _runType
Definition: RunHistory.h:547
uint32_t _modcon
module connection id
Definition: RunHistory.h:133
std::string _detGainTag
Definition: RunHistory.h:548
uint32_t pixel_t
Type for physical pixel on APD.
std::string _dbuser
Definition: RunHistory.h:545
bool LoadPixelInfo(int nAttempt=0)
Definition: RunHistory.cxx:903
Float_t x1[n_points_granero]
Definition: compare.C:5
static bool TimeAsStringToTime_t(std::string ts, time_t &t)
Definition: Util.cpp:86
PGresult * PerformPGQuery(std::string const &query, std::unique_ptr< Table > const &hwTable)
Definition: RunHistory.cxx:36
float GetPixelGain(geo::OfflineChan const &, bool &)
std::vector< float > _pixelGain
pixel gain map for APD
Definition: RunHistory.h:136
bool DetFineTimingSetting() const
const char * p
Definition: xmltok.h:285
std::map< HardwareLocation, std::pair< FEBInfo, APDInfo > > gLocToFA
Definition: RunHistory.cxx:32
DiBlock GetDiBlock(int i, bool loadAll=true)
get ith diblock is RH list (which only includes diblocks with activity), starting with i=0...
int ApplyAnalysisDiBlockMask(const int mask) const
converts normal mask to analysis rules mask (any continuous chunk of four or more diblocks kept) ...
OStream cerr
Definition: OStream.cxx:7
bool getTemperatureEnable(const std::string &dcmName, const int &febId, bool &enableFlag)
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
time_t SubrunTStart(int isr)
Definition: config.py:1
TString ip
Definition: loadincs.C:5
std::vector< DQSubrunInfo > GetDQSubrunInfo()
cell_t getCell(lchan logicalchan) const
Decode the cell number from an lchan.
std::vector< BNEVB > _bnevbList
Definition: RunHistory.h:556
bool Get(T &val) const
Definition: Column.h:85
lchan encodeLChan(int detId, plane_t plane, cell_t cell) const
uint32_t _diblock
Diblock.
Definition: RunHistory.h:198
uint32_t _batch
APD batch number.
Definition: RunHistory.h:129
std::vector< int16_t > pixelThresh
Definition: RunHistory.h:269
float abs(float number)
Definition: d0nt_math.hpp:39
std::vector< float > pixelGain
each entry is the gain for the pixel with the number of the index
Definition: RunHistory.h:276
bool getThresholdsForFEB(const std::string &dcmName, const int &febId, std::vector< int16_t > &thresholdList)
void SetRunNumber(int run)
Definition: RunHistory.cxx:317
std::string TStopAsString()
Definition: RunHistory.h:384
bool getPixelEnableMask(const std::string &dcmName, const int &febId, int32_t &pixelMask)
int ToDBValidityChan() const
Definition: OfflineChan.cxx:19
Far Detector at Ash River, MN.
std::vector< FEB > feb
Definition: RunHistory.h:291
uint32_t _modcon
module connection id
Definition: RunHistory.h:167
int GetPedestal(const geo::OfflineChan &, bool &)
Definition: RunHistory.cxx:632
std::string _dbhost
Definition: RunHistory.h:544
std::string _badChanVersion
Definition: RunHistory.h:553
bool SortDiBlocks(RunHistory::DiBlock db1, RunHistory::DiBlock db2)
Definition: RunHistory.cxx:72
static DAQChannelMap * getInstance(int detID)
void SetChanInfo(geo::OfflineChan, float, float, time_t)
std::string DiBlockMaskToString(const int mask) const
uint32_t _layer
layer in the block
Definition: RunHistory.h:202
std::map< int, int > _diblockIndex
Definition: RunHistory.h:495
float _slope
slope for voltage setting
Definition: RunHistory.h:164
uint32_t _module
module APD is connected to
Definition: RunHistory.h:132
Int_t col[ntarg]
Definition: Style.C:29
bool IsCooled(const geo::OfflineChan &)
std::vector< DiBlock > _dbList
Definition: RunHistory.h:555
std::string _detector
Definition: RunHistory.h:550
static bool DetIdOk(int id)
Near Detector in the NuMI cavern.
std::map< uint32_t, APDInfo > PullAPDInfoFromDB()
Float_t d
Definition: plot.C:236
uint32_t feb_t
Type for DCM link port. Counts from 0.
nova::dbi::DataType _dataType
Definition: RunHistory.h:532
const double j
Definition: BetheBloch.cxx:29
float GetGain(const geo::OfflineChan &, bool &)
std::string _dbport
Definition: RunHistory.h:546
Hold drift constants from current run.
Definition: DriftCache.h:17
void InvalidateCaches()
Call at new run/detector etc.
void SetIsBad(geo::OfflineChan, bool, time_t)
uint32_t _module
module FEB is connected to
Definition: RunHistory.h:166
bool febIsEnabled(const std::string &dcmName, const int &febId)
bool getTemperature(const std::string &dcmName, const int &febId, int &temperature)
Definition: run.py:1
std::vector< int > _fdRHCRunStart
Definition: RunHistory.h:563
#define LOG_WARNING(category)
std::string name
Definition: RunHistory.h:59
bool hasAPD
true if instrumented and active in run, and not masked
Definition: RunHistory.h:263
OStream cout
Definition: OStream.cxx:6
unsigned short Plane() const
Definition: OfflineChan.h:31
const XML_Char * version
Definition: expat.h:187
uint32_t dcm_id_t
Type for DCM number, counts from 1.
static int GetId(std::string name)
pg_result PGresult
Definition: Table.h:25
bool IsGoodDiBlock(int idb, int subrun=-1)
pixel_t getPixel(dchan daqchan) const
Decode the pixel id from a dchan.
std::map< geo::OfflineChan, std::vector< BadChan_t > > _badChan
Definition: RunHistory.h:557
std::vector< DCM > dcm
Definition: RunHistory.h:311
float Coincidence(geo::OfflineChan, time_t)
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
std::vector< int > _fdRHCRunStop
Definition: RunHistory.h:564
unsigned short Cell() const
Definition: OfflineChan.h:32
std::vector< Subrun > _subrunList
Definition: RunHistory.h:559
uint32_t _block
installed block
Definition: RunHistory.h:201
bool IsBad(geo::OfflineChan, time_t)
uint32_t _feb
FEB port.
Definition: RunHistory.h:200
int NAnalysisDiBlocks(int sr=0)
Definition: RunHistory.cxx:256
std::vector< int > _ndRHCRunStart
Definition: RunHistory.h:561
int num
Definition: f2_nu.C:119
std::vector< int > _ndRHCRunStop
Definition: RunHistory.h:562
A (plane, cell) pair.
Definition: OfflineChan.h:17
FEB GetFEB(geo::OfflineChan const &, bool &)
bool HasAPD(const geo::OfflineChan &)
basic check for if a channel should be live. Used by BadChannels. Checks if channel has instrumented ...
int32_t _temp
operating temperature
Definition: RunHistory.h:130
std::vector< float > GetPixelGains(geo::OfflineChan const &, bool &)
const hit & b
Definition: hits.cxx:21
plane_t getPlane(lchan logicalchan) const
Decode the plane number from an lchan.
std::map< geo::OfflineChan, std::vector< ChanInfo_t > > _chanInfo
Definition: RunHistory.h:558
uint32_t diblock_t
Type for diblocks and blocks.
TRandom3 r(0)
dcm_id_t getDCM(dchan daqchan) const
Decode the dcm ID from a dchan.
bool getVoltage(const std::string &dcmName, const int &febId, int &regulatorSetting)
std::string _dbname
Definition: RunHistory.h:543
std::string _sn
APD SN.
Definition: RunHistory.h:127
dchan encodeDChan(int detID, diblock_t diblock, dcm_id_t dcm, feb_t feb, pixel_t pixel) const
virtual fiber_t computeFiberInModule(dchan daqchan) const =0
Which fiber does this dchan readout?
bool LoadDCSAlarms(int subrun=-1)
Definition: RunHistory.cxx:399
uint32_t _barcode
barcoded_item_id from barcoded_item table
Definition: RunHistory.h:165
#define LOG_INFO(stream)
Definition: Messenger.h:144
int GoodDiBlockMask(int subrun=-1, bool reload=false)
float Occupancy(geo::OfflineChan, time_t)
uint32_t dchan
< DAQ Channel Map Package
int nInstrumentedFEBs
number of FEBs that were instrumented and active in run and not masked
Definition: RunHistory.h:287
void SetDBInfo(std::string dbname="", std::string dbhost="", std::string user="", std::string port="")
Definition: RunHistory.cxx:305
int nInstrumentedFEBs
number of FEBs that were intrumented and active in run and not masked
Definition: RunHistory.h:310
static bool DetNameOk(std::string name)
float _voltage
operating voltage
Definition: RunHistory.h:131
uint32_t _barcode
barcode id from barcoded_item table
Definition: RunHistory.h:128
diblock_t getDiBlock(dchan daqchan) const
Decode the diblock ID from a dchan.
std::string _sn
FEB SN.
Definition: RunHistory.h:162
std::map< HardwareLocation, std::pair< FEBInfo, APDInfo > > PullFEBInfoFromDB(std::map< uint32_t, APDInfo > apdinfomap)
#define LOG_ERROR(stream)
Definition: Messenger.h:129
std::string TStartAsString()
Definition: RunHistory.h:383
static constexpr Double_t sr
Definition: Munits.h:164
int GetThreshold(const geo::OfflineChan &, bool &)
int32_t _detid
Detector ID.
Definition: RunHistory.h:197
feb_t getFEB(dchan daqchan) const
Decode the feb id from a dchan.
std::string _dbMaskTag
Definition: RunHistory.h:488