LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArRawInputDriverShortBo.cxx
Go to the documentation of this file.
1 
9 
16 
17 #include <algorithm>
18 #include <fstream>
19 #include <stdlib.h>
20 #include <time.h>
21 
25 
28 
29 extern "C" {
30 #include <dirent.h>
31 }
32 
33 // ======================================================================
34 // ShortBo DAQ480 interface, adapted from code by Rebel/Soderberg:
35 
36 namespace {
37 
38  //Define Structures corresponding to Binary data file.
39 
40  // ======================================================================
41  struct header {
42  int fixed; //Fixed 32-bit word with value: 0x0000D480
43  unsigned short format; //File Format Version. 16-bit word. Currently = 0x0001
44  unsigned short software; //DAQ480 Software Version. 16-bit word. Currently 0x0600 (v6.0)
45  unsigned short run; //16-bit word.
46  unsigned short event; //16-bit word.
47  int time; //Event timestamp. Coordinated Universal Time. 32-bit word.
48  short spare; //Spare 16-bit word. Currently 0x0000
49  unsigned short nchan; //Total # of channels in readout. 16-bit word.
50  };
51 
52  // ======================================================================
53  struct channel {
54  unsigned short ch; //Channel #. 16-bit word.
55  unsigned short samples; //# samples for this channel. 16-bit word.
56  };
57 
58  // ======================================================================
59  struct footer {
60  int spare; //Spare 32-bit word. Currently 0x00000000
61  int checksum; //Reserved for checksum. 32-bit word. Currently 0x00000000
62  };
63 
64  // ======================================================================
65  int run(std::string s1)
66  {
67  size_t p1 = s1.find("R");
68  size_t p2 = s1.find("_E");
69 
70  int run = atoi((s1.substr(p1 + 1, p2 - p1 - 1)).c_str());
71  return run;
72  }
73 
74  // ======================================================================
75  int event(std::string s1)
76  {
77  size_t p1 = s1.find("E");
78  size_t p2 = s1.find("_T");
79 
80  int event = atoi((s1.substr(p1 + 1, p2 - p1 - 1)).c_str());
81  return event;
82  }
83 
84  // ======================================================================
85  bool compare(std::string s1, std::string s2)
86  {
87  int r1 = run(s1);
88  int r2 = run(s2);
89  int e1 = event(s1);
90  int e2 = event(s2);
91 
92  return r1 == r2 ? e1 < e2 : r1 < r2;
93  }
94 
95  // ======================================================================
96  std::vector<std::string> getsortedfiles(std::string dir)
97  {
98  if (dir == "")
99  throw art::Exception(art::errors::Configuration) << "Vacuous directory name" << std::endl;
100 
101  std::vector<std::string> files;
102 
103  DIR* dp = NULL;
104  if ((dp = opendir(dir.c_str())) == NULL) {
106  << "Error opening directory " << dir << std::endl;
107  }
108 
109  dirent* dirp = NULL;
110  while ((dirp = readdir(dp)) != NULL) {
111  std::string filename(dirp->d_name);
112  if (filename.find("bin") != std::string::npos) { files.push_back(filename); }
113  }
114  closedir(dp);
115 
116  sort(files.begin(), files.end(), compare);
117 
118  return files;
119  } // getsortedfiles()
120 
121  struct EventFileSentry {
122  // Use RAII (Resource Acquisition Is Initialization)
123  explicit EventFileSentry(std::string const& filepath)
124  : infile(filepath.c_str(), std::ios_base::in | std::ios_base::binary)
125  {}
126  ~EventFileSentry() { infile.close(); }
127 
128  std::ifstream infile;
129  };
130 
131  // ======================================================================
132  void process_LAr_file(std::string dir,
133  std::string const& filename,
134  std::vector<raw::RawDigit>& digitList,
135  raw::DAQHeader& daqHeader)
136  {
137  // Prepare the input file. The sentry is responsible for making the
138  // file stream object, and will *automatically* close it when it
139  // goes out of scope *for any reason*, including normal function
140  // exit or exception throw.
141  EventFileSentry efs(dir + "/" + filename);
142  std::ifstream& infile = efs.infile;
143 
144  if (!infile.is_open()) {
146  << "failed to open input file " << filename << std::endl;
147  }
148 
149  unsigned int wiresPerPlane = 48;
150  unsigned int planes = 3;
151 
152  header h1;
153  channel c1;
154  footer f1;
155 
156  //read in header section of file
157  infile.read((char*)&h1, sizeof h1);
158 
159  time_t mytime = h1.time;
160  mytime = mytime << 32; //Nov. 2, 2010 - "time_t" is a 64-bit word on many 64-bit machines
161  //so we had to change types in header struct to read in the correct
162  //number of bits. Once we have the 32-bit timestamp from the binary
163  //data, shift it up to the upper half of the 64-bit timestamp. - Mitch
164 
165  // std::cout << "Fixed Value (0x0000D480): " << std::hex << h1.fixed << std::endl;
166  // std::cout << "Output Format: " << std::hex << h1.format << std::endl;
167  // std::cout << "Software Version: " << std::hex << h1.software << std::dec << std::endl;
168  // std::cout << "Run " << std::setw(6) << std::left << h1.run
169  // << "Event " << std::setw(8) << std::left << h1.event
170  // << "h1.time " << std::setw(8) << std::left << h1.time;
171  // std::cout << " #Channels = " << h1.nchan << std::endl;
172 
173  daqHeader.SetStatus(1);
174  daqHeader.SetFixedWord(h1.fixed);
175  daqHeader.SetFileFormat(h1.format);
176  daqHeader.SetSoftwareVersion(h1.software);
177  daqHeader.SetRun(h1.run);
178  daqHeader.SetEvent(h1.event);
179  daqHeader.SetTimeStamp(mytime);
180  daqHeader.SetSpareWord(h1.spare);
181  daqHeader.SetNChannels(h1.nchan);
182 
183  //one digit for every wire on each plane
184  digitList.clear();
185  digitList.resize(wiresPerPlane * planes);
186 
187  for (int i = 0; i != h1.nchan; ++i) {
188  infile.read((char*)&c1, sizeof c1);
189  //Create vector for ADC data, with correct number of samples for this event
190  std::vector<short> adclist(c1.samples);
191  infile.read((char*)&adclist[0], sizeof(short) * c1.samples);
192  // std::cout << "Channel = " << c1.ch ;
193  // std::cout << " #Samples = " << c1.samples ;
194  // std::cout << " ADC[0] = " << adclist[0] << " ADC[2047] = " << adclist[2047] << std::endl;
195 
196  int iw = i;
197  if (h1.run < 280 && h1.run > 192) {
198  if (i == 92) iw = 95;
199  if (i == 93) iw = 94;
200  if (i == 94) iw = 93;
201  if (i == 95) iw = 92;
202  }
203 
204  digitList[i] = raw::RawDigit(iw, c1.samples, adclist); //subtract one from ch. number...
205  // digitList[i] = raw::RawDigit((c1.ch-1), c1.samples, adclist);//subtract one from ch. number...
206  //hence offline channels will always be one lower
207  //than the DAQ480 definition. - mitch 7/8/2009
208  digitList[i].SetPedestal(400.); //carl b assures me this will never change. bjr 4/15/2009
209  }
210  //read in footer section of file...though it's currently empty.
211  infile.read((char*)&f1, sizeof f1);
212 
213  // infile will be closed automatically as EventFileSentry goes out of scope.
214  } // process_LAr_file
215 
216 } // namespace
217 
218 namespace lris {
219  // ======================================================================
220  // class c'tor/d'tor:
221  LArRawInputDriverShortBo::LArRawInputDriverShortBo(fhicl::ParameterSet const&, // Not used
223  art::SourceHelper const& pm)
224  : principalMaker_(pm)
225  , currentDir_()
226  , inputfiles_()
227  , nextfile_(inputfiles_.begin())
228  , filesdone_(inputfiles_.end())
229  , currentSubRunID_()
230  {
231  helper.reconstitutes<raw::DAQHeader, art::InEvent>("daq");
232  helper.reconstitutes<std::vector<raw::RawDigit>, art::InEvent>("daq");
233  helper.reconstitutes<sumdata::RunData, art::InRun>("daq");
234  }
235 
237  {
238  // Nothing to do (See EventFileSentry).
239  }
240 
241  void LArRawInputDriverShortBo::readFile(std::string const& name, art::FileBlock*& fb)
242  {
243  // Get the list of event files for this directory.
244  currentDir_ = name;
245  inputfiles_ = getsortedfiles(currentDir_);
246  nextfile_ = inputfiles_.begin();
247  filesdone_ = inputfiles_.end();
249 
250  // Fill and return a new Fileblock.
251  fb = new art::FileBlock(art::FileFormatVersion(1, "LArRawInput 2011a"), currentDir_);
252  }
253 
255  art::SubRunPrincipal* const& /* inSR */,
256  art::RunPrincipal*& outR,
257  art::SubRunPrincipal*& outSR,
258  art::EventPrincipal*& outE)
259  {
260  if (inputfiles_.empty() || nextfile_ == filesdone_) return false;
261 
262  // Create empty result, then fill it from current filename:
263  std::unique_ptr<std::vector<raw::RawDigit>> rdcolsb(new std::vector<raw::RawDigit>);
264 
265  raw::DAQHeader daqHeader;
266  bool firstEventInRun = (nextfile_ == inputfiles_.begin());
267 
268  process_LAr_file(currentDir_, *nextfile_++, *rdcolsb, daqHeader);
269  std::unique_ptr<raw::DAQHeader> daqcolsb(new raw::DAQHeader(daqHeader));
270 
271  art::RunNumber_t rn = daqHeader.GetRun();
272  art::Timestamp tstamp = daqHeader.GetTimeStamp();
273 
274  if (firstEventInRun) {
275  std::unique_ptr<sumdata::RunData> rundatasb(new sumdata::RunData("bo"));
277  outR = principalMaker_.makeRunPrincipal(rn, tstamp);
279  art::put_product_in_principal(std::move(rundatasb), *outR, "daq");
280  }
281  else if (rn != currentSubRunID_.run()) {
282  throw cet::exception("InconsistentEventStream")
283  << "Encountered run #" << rn << " while processing events from run #"
284  << currentSubRunID_.run() << "\n";
285  }
286 
288  currentSubRunID_.run(), currentSubRunID_.subRun(), daqHeader.GetEvent(), tstamp);
289 
290  // Put products in the event.
291  art::put_product_in_principal(std::move(rdcolsb), *outE,
292  "daq"); // Module label
293  art::put_product_in_principal(std::move(daqcolsb), *outE,
294  "daq"); // Module label
295 
296  return true;
297  }
298 
299 }
void SetSpareWord(short s)
Definition: DAQHeader.h:117
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:68
void SetRun(unsigned short i)
Definition: DAQHeader.h:101
SubRunPrincipal * makeSubRunPrincipal(SubRunAuxiliary subRunAux) const
Source to convert raw binary files to root files for Short Bo TPC.
void SetTimeStamp(time_t t)
Definition: DAQHeader.h:113
stringvec_t::const_iterator filesdone_
EventPrincipal * makeEventPrincipal(EventAuxiliary eventAux) const
STL namespace.
Definition of basic raw digits.
art::SourceHelper const & principalMaker_
void readFile(std::string const &name, art::FileBlock *&fb)
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
TypeLabel const & reconstitutes(std::string const &modLabel, std::string const &instanceName={})
TCanvas * c1
Definition: plotHisto.C:7
RunNumber_t run() const
Definition: SubRunID.h:85
Float_t f1
void SetNChannels(uint32_t i)
Definition: DAQHeader.h:121
TFile fb("Li6.root")
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
ifstream in
Definition: comparison.C:7
RunPrincipal * makeRunPrincipal(RunAuxiliary runAux) const
Definition: SourceHelper.cc:89
std::enable_if_t<!detail::range_sets_supported(P::branch_type)> put_product_in_principal(std::unique_ptr< T > &&product, P &principal, std::string const &module_label, std::string const &instance_name={})
TDirectory * dir
Definition: macro.C:5
stringvec_t::const_iterator nextfile_
Conversion of binary data to root files.
void SetFixedWord(int i)
Definition: DAQHeader.h:89
unsigned short GetRun() const
Definition: DAQHeader.h:141
TH1F * h1
Definition: plot.C:41
unsigned short GetEvent() const
Definition: DAQHeader.h:149
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
SubRunNumber_t subRun() const
Definition: SubRunID.h:91
void SetSoftwareVersion(unsigned short i)
Definition: DAQHeader.h:97
void SetEvent(unsigned short i)
Definition: DAQHeader.h:109
bool readNext(art::RunPrincipal *const &inR, art::SubRunPrincipal *const &inSR, art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
void SetStatus(unsigned int i)
Definition: DAQHeader.h:85
void SetFileFormat(unsigned short i)
Definition: DAQHeader.h:93
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
time_t GetTimeStamp() const
Definition: DAQHeader.h:153
Event finding and building.
IDNumber_t< Level::Run > RunNumber_t
Definition: IDNumber.h:120