All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LArRawInputDriverShortBo.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file LArRawInputDriverShortBo.cxx
3 /// \brief Source to convert raw binary files to root files for Short Bo TPC
4 ///
5 /// \author brebel@fnal.gov, soderber@fnal.gov
6 ////////////////////////////////////////////////////////////////////////
7 
9 
10 #include "art/Framework/Core/FileBlock.h"
11 #include "art/Framework/Core/ProductRegistryHelper.h"
12 #include "art/Framework/IO/Sources/SourceHelper.h"
13 #include "art/Framework/Principal/EventPrincipal.h"
14 #include "art/Framework/Principal/RunPrincipal.h"
15 #include "canvas/Persistency/Provenance/Timestamp.h"
16 
17 #include <algorithm>
18 #include <fstream>
19 #include <stdlib.h>
20 #include <time.h>
21 
25 
26 #include "art/Framework/IO/Sources/put_product_in_principal.h"
27 #include "canvas/Utilities/Exception.h"
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  {
43  int fixed; //Fixed 32-bit word with value: 0x0000D480
44  unsigned short format; //File Format Version. 16-bit word. Currently = 0x0001
45  unsigned short software; //DAQ480 Software Version. 16-bit word. Currently 0x0600 (v6.0)
46  unsigned short run; //16-bit word.
47  unsigned short event; //16-bit word.
48  int time; //Event timestamp. Coordinated Universal Time. 32-bit word.
49  short spare; //Spare 16-bit word. Currently 0x0000
50  unsigned short nchan; //Total # of channels in readout. 16-bit word.
51  };
52 
53  // ======================================================================
54  struct channel
55  {
56  unsigned short ch; //Channel #. 16-bit word.
57  unsigned short samples; //# samples for this channel. 16-bit word.
58  };
59 
60  // ======================================================================
61  struct footer
62  {
63  int spare; //Spare 32-bit word. Currently 0x00000000
64  int checksum; //Reserved for checksum. 32-bit word. Currently 0x00000000
65  };
66 
67  // ======================================================================
68  int run( std::string s1 )
69  {
70  size_t p1 = s1.find("R");
71  size_t p2 = s1.find("_E");
72 
73  int run = atoi((s1.substr(p1+1,p2-p1-1)).c_str());
74  return run;
75  }
76 
77 
78  // ======================================================================
79  int event( std::string s1 )
80  {
81  size_t p1 = s1.find("E");
82  size_t p2 = s1.find("_T");
83 
84  int event = atoi((s1.substr(p1+1,p2-p1-1)).c_str());
85  return event;
86  }
87 
88 
89  // ======================================================================
90  bool compare( std::string s1, std::string s2 )
91  {
92  int r1 = run(s1);
93  int r2 = run(s2);
94  int e1 = event(s1);
95  int e2 = event(s2);
96 
97  return r1 == r2 ? e1 < e2
98  : r1 < r2;
99  }
100 
101 
102  // ======================================================================
103  std::vector<std::string> getsortedfiles( std::string dir )
104  {
105  if( dir == "" )
106  throw art::Exception( art::errors::Configuration )
107  << "Vacuous directory name" << std::endl;
108 
109  std::vector<std::string> files;
110 
111  DIR * dp = NULL;
112  if( (dp = opendir(dir.c_str())) == NULL ) {
113  throw art::Exception( art::errors::FileOpenError )
114  << "Error opening directory " << dir << std::endl;
115  }
116 
117  dirent * dirp = NULL;
118  while( (dirp = readdir(dp)) != NULL ) {
119  std::string filename( dirp->d_name );
120  if( filename.find("bin") != std::string::npos ) {
121  files.push_back(filename);
122  }
123  }
124  closedir(dp);
125 
126  sort( files.begin(), files.end(), compare );
127 
128  return files;
129  } // getsortedfiles()
130 
131  struct EventFileSentry {
132  // Use RAII (Resource Acquisition Is Initialization)
133  explicit EventFileSentry(std::string const &filepath)
134  : infile(filepath.c_str(), std::ios_base::in | std::ios_base::binary)
135  { }
136  ~EventFileSentry() { infile.close(); }
137 
138  std::ifstream infile;
139  };
140 
141  // ======================================================================
142  void process_LAr_file(std::string dir,
143  std::string const & filename,
144  std::vector<raw::RawDigit>& digitList,
145  raw::DAQHeader& daqHeader)
146  {
147  // Prepare the input file. The sentry is responsible for making the
148  // file stream object, and will *automatically* close it when it
149  // goes out of scope *for any reason*, including normal function
150  // exit or exception throw.
151  EventFileSentry efs(dir+"/"+filename);
152  std::ifstream &infile = efs.infile;
153 
154  if( !infile.is_open() ) {
155  throw art::Exception( art::errors::FileReadError )
156  << "failed to open input file " << filename << std::endl;
157  }
158 
159  unsigned int wiresPerPlane = 48;
160  unsigned int planes = 3;
161 
162  header h1;
163  channel c1;
164  footer f1;
165 
166  //read in header section of file
167  infile.read((char *) &h1, sizeof h1);
168 
169  time_t mytime = h1.time;
170  mytime = mytime << 32;//Nov. 2, 2010 - "time_t" is a 64-bit word on many 64-bit machines
171  //so we had to change types in header struct to read in the correct
172  //number of bits. Once we have the 32-bit timestamp from the binary
173  //data, shift it up to the upper half of the 64-bit timestamp. - Mitch
174 
175  // std::cout << "Fixed Value (0x0000D480): " << std::hex << h1.fixed << std::endl;
176  // std::cout << "Output Format: " << std::hex << h1.format << std::endl;
177  // std::cout << "Software Version: " << std::hex << h1.software << std::dec << std::endl;
178  // std::cout << "Run " << std::setw(6) << std::left << h1.run
179  // << "Event " << std::setw(8) << std::left << h1.event
180  // << "h1.time " << std::setw(8) << std::left << h1.time;
181  // std::cout << " #Channels = " << h1.nchan << std::endl;
182 
183  daqHeader.SetStatus(1);
184  daqHeader.SetFixedWord(h1.fixed);
185  daqHeader.SetFileFormat(h1.format);
186  daqHeader.SetSoftwareVersion(h1.software);
187  daqHeader.SetRun(h1.run);
188  daqHeader.SetEvent(h1.event);
189  daqHeader.SetTimeStamp(mytime);
190  daqHeader.SetSpareWord(h1.spare);
191  daqHeader.SetNChannels(h1.nchan);
192 
193  //one digit for every wire on each plane
194  digitList.clear();
195  digitList.resize(wiresPerPlane*planes);
196 
197  for( int i = 0; i != h1.nchan; ++i ) {
198  infile.read((char *) &c1, sizeof c1);
199  //Create vector for ADC data, with correct number of samples for this event
200  std::vector<short> adclist(c1.samples);
201  infile.read((char*)&adclist[0],sizeof(short)*c1.samples);
202  // std::cout << "Channel = " << c1.ch ;
203  // std::cout << " #Samples = " << c1.samples ;
204  // std::cout << " ADC[0] = " << adclist[0] << " ADC[2047] = " << adclist[2047] << std::endl;
205 
206  int iw = i;
207  if (h1.run<280 && h1.run>192) {
208  if (i==92) iw=95;
209  if (i==93) iw=94;
210  if (i==94) iw=93;
211  if (i==95) iw=92;
212  }
213 
214  digitList[i] = raw::RawDigit(iw, c1.samples, adclist);//subtract one from ch. number...
215  // digitList[i] = raw::RawDigit((c1.ch-1), c1.samples, adclist);//subtract one from ch. number...
216  //hence offline channels will always be one lower
217  //than the DAQ480 definition. - mitch 7/8/2009
218  digitList[i].SetPedestal(400.); //carl b assures me this will never change. bjr 4/15/2009
219  }
220  //read in footer section of file...though it's currently empty.
221  infile.read((char *) &f1, sizeof f1);
222 
223  // infile will be closed automatically as EventFileSentry goes out of scope.
224  } // process_LAr_file
225 
226 } // namespace
227 
228 namespace lris {
229  // ======================================================================
230  // class c'tor/d'tor:
231  LArRawInputDriverShortBo::LArRawInputDriverShortBo(fhicl::ParameterSet const &, // Not used
232  art::ProductRegistryHelper &helper,
233  art::SourceHelper const &pm)
234  :
235  principalMaker_(pm)
236  , currentDir_ ()
237  , inputfiles_ ( )
238  , nextfile_ ( inputfiles_.begin() )
239  , filesdone_ ( inputfiles_.end() )
240  , currentSubRunID_ ( )
241  {
242  helper.reconstitutes<raw::DAQHeader, art::InEvent>("daq");
243  helper.reconstitutes<std::vector<raw::RawDigit>, art::InEvent>("daq");
244  helper.reconstitutes<sumdata::RunData, art::InRun> ("daq");
245  }
246 
248  {
249  // Nothing to do (See EventFileSentry).
250  }
251 
252  void LArRawInputDriverShortBo::readFile(std::string const &name,
253  art::FileBlock* &fb)
254  {
255  // Get the list of event files for this directory.
256  currentDir_ = name;
257  inputfiles_ = getsortedfiles(currentDir_);
258  nextfile_ = inputfiles_.begin();
259  filesdone_ = inputfiles_.end();
260  currentSubRunID_ = art::SubRunID();
261 
262  // Fill and return a new Fileblock.
263  fb = new art::FileBlock(art::FileFormatVersion(1, "LArRawInput 2011a"),
264  currentDir_);
265  }
266 
267  bool LArRawInputDriverShortBo::readNext(art::RunPrincipal* const & /* inR */,
268  art::SubRunPrincipal* const & /* inSR */,
269  art::RunPrincipal* &outR,
270  art::SubRunPrincipal* &outSR,
271  art::EventPrincipal* &outE)
272  {
273  if (inputfiles_.empty() || nextfile_ == filesdone_ ) return false;
274 
275  // Create empty result, then fill it from current filename:
276  std::unique_ptr<std::vector<raw::RawDigit> > rdcolsb ( new std::vector<raw::RawDigit> );
277 
278  raw::DAQHeader daqHeader;
279  bool firstEventInRun = (nextfile_ == inputfiles_.begin());
280 
281  process_LAr_file( currentDir_, *nextfile_++, *rdcolsb, daqHeader );
282  std::unique_ptr<raw::DAQHeader> daqcolsb( new raw::DAQHeader(daqHeader) );
283 
284  art::RunNumber_t rn = daqHeader.GetRun();
285  art::Timestamp tstamp = daqHeader.GetTimeStamp();
286 
287  if (firstEventInRun)
288  {
289  std::unique_ptr<sumdata::RunData> rundatasb(new sumdata::RunData("bo") );
290  currentSubRunID_ = art::SubRunID(rn, 1);
291  outR = principalMaker_.makeRunPrincipal(rn, tstamp);
292  outSR = principalMaker_.makeSubRunPrincipal(rn,
293  currentSubRunID_.subRun(),
294  tstamp);
295  art::put_product_in_principal(std::move(rundatasb), *outR, "daq");
296  } else if (rn != currentSubRunID_.run())
297  {
298  throw cet::exception("InconsistentEventStream")
299  << "Encountered run #" << rn
300  << " while processing events from run #" << currentSubRunID_.run()
301  << "\n";
302  }
303 
304  outE = principalMaker_.makeEventPrincipal(currentSubRunID_.run(),
305  currentSubRunID_.subRun(),
306  daqHeader.GetEvent(),
307  tstamp);
308 
309  // Put products in the event.
310  art::put_product_in_principal(std::move(rdcolsb),
311  *outE,
312  "daq"); // Module label
313  art::put_product_in_principal(std::move(daqcolsb),
314  *outE,
315  "daq"); // Module label
316 
317  return true;
318  }
319 
320 }
void SetSpareWord(short s)
Definition: DAQHeader.h:97
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
void SetRun(unsigned short i)
Definition: DAQHeader.h:93
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
Source to convert raw binary files to root files for Short Bo TPC.
then echo fcl sbnd_project sbnd_project sbnd_project sbnd_project production production checksum
BEGIN_PROLOG could also be dds filename
void SetTimeStamp(time_t t)
Definition: DAQHeader.h:96
stringvec_t::const_iterator filesdone_
Definition of basic raw digits.
art::SourceHelper const & principalMaker_
void readFile(std::string const &name, art::FileBlock *&fb)
LArRawInputDriverShortBo(fhicl::ParameterSet const &pset, art::ProductRegistryHelper &helper, art::SourceHelper const &pm)
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
void SetNChannels(uint32_t i)
Definition: DAQHeader.h:98
tuple dir
Definition: dropbox.py:28
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
BEGIN_PROLOG Z planes
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
stringvec_t::const_iterator nextfile_
void SetFixedWord(int i)
Definition: DAQHeader.h:90
unsigned short GetRun() const
Definition: DAQHeader.h:103
unsigned short GetEvent() const
Definition: DAQHeader.h:105
then echo fcl name
then echo fcl sbnd_project sbnd_project sbnd_project sbnd_project software
void SetSoftwareVersion(unsigned short i)
Definition: DAQHeader.h:92
void SetEvent(unsigned short i)
Definition: DAQHeader.h:95
bool readNext(art::RunPrincipal *const &inR, art::SubRunPrincipal *const &inSR, art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
physics pm2 e1
physics associatedGroupsWithLeft p1
void SetStatus(unsigned int i)
Definition: DAQHeader.h:89
void SetFileFormat(unsigned short i)
Definition: DAQHeader.h:91
time_t GetTimeStamp() const
Definition: DAQHeader.h:106