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