LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LArRawInputDriver.cxx
Go to the documentation of this file.
1 
9 
14 
17 
18 extern "C" {
19 #include <sys/types.h>
20 #include <dirent.h>
21 }
22 
23 // ======================================================================
24 // ArgoNeuT DAQ480 interface, adapted from code by Rebel/Soderberg:
25 
26 namespace {
27 
28  //Define Structures corresponding to Binary data file.
29 
30  // ======================================================================
31  struct header
32  {
33  int fixed; //Fixed 32-bit word with value: 0x0000D480
34  unsigned short format; //File Format Version. 16-bit word. Currently = 0x0001
35  unsigned short software; //DAQ480 Software Version. 16-bit word. Currently 0x0600 (v6.0)
36  unsigned short run; //16-bit word.
37  unsigned short event; //16-bit word.
38  int time; //Event timestamp. Coordinated Universal Time. 32-bit word.
39  short spare; //Spare 16-bit word. Currently 0x0000
40  unsigned short nchan; //Total # of channels in readout. 16-bit word.
41  };
42 
43  // ======================================================================
44  struct channel
45  {
46  unsigned short ch; //Channel #. 16-bit word.
47  unsigned short samples; //# samples for this channel. 16-bit word.
48  };
49 
50  // ======================================================================
51  struct footer
52  {
53  int spare; //Spare 32-bit word. Currently 0x00000000
54  int checksum; //Reserved for checksum. 32-bit word. Currently 0x00000000
55  };
56 
57  // ======================================================================
58  int run( std::string s1 )
59  {
60  size_t p1 = s1.find("R");
61  size_t p2 = s1.find("_E");
62 
63  int run = atoi((s1.substr(p1+1,p2-p1-1)).c_str());
64  return run;
65  }
66 
67 
68  // ======================================================================
69  int event( std::string s1 )
70  {
71  size_t p1 = s1.find("E");
72  size_t p2 = s1.find("_T");
73 
74  int event = atoi((s1.substr(p1+1,p2-p1-1)).c_str());
75  return event;
76  }
77 
78 
79  // ======================================================================
80  bool compare( std::string s1, std::string s2 )
81  {
82  int r1 = run(s1);
83  int r2 = run(s2);
84  int e1 = event(s1);
85  int e2 = event(s2);
86 
87  return r1 == r2 ? e1 < e2
88  : r1 < r2;
89  }
90 
91 
92  // ======================================================================
93  std::vector<std::string> getsortedfiles( std::string dir )
94  {
95  if( dir == "" )
97  << "Vacuous directory name" << std::endl;
98 
99  std::vector<std::string> files;
100 
101  DIR * dp = NULL;
102  if( (dp = opendir(dir.c_str())) == NULL ) {
104  << "Error opening directory " << dir << std::endl;
105  }
106 
107  dirent * dirp = NULL;
108  while( (dirp = readdir(dp)) != NULL ) {
109  std::string filename( dirp->d_name );
110  if( filename.find("bin") != std::string::npos ) {
111  files.push_back(filename);
112  }
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 = 240;
150  unsigned int planes = 2;
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  digitList[i] = raw::RawDigit((c1.ch-1), c1.samples, adclist);//subtract one from ch. number...
197  //hence offline channels will always be one lower
198  //than the DAQ480 definition. - mitch 7/8/2009
199  digitList[i].SetPedestal(400.); //carl b assures me this will never change. bjr 4/15/2009
200  }
201  //read in footer section of file...though it's currently empty.
202  infile.read((char *) &f1, sizeof f1);
203 
204  // infile will be closed automatically as EventFileSentry goes out of scope.
205  } // process_LAr_file
206 
207 } // namespace
208 
209 namespace lris {
210  // ======================================================================
211  // class c'tor/d'tor:
212  LArRawInputDriver::LArRawInputDriver(fhicl::ParameterSet const &, // Not used
214  art::SourceHelper const &pm)
215  :
216  principalMaker_(pm)
217  , currentDir_ ()
218  , inputfiles_ ( )
219  , nextfile_ ( inputfiles_.begin() )
220  , filesdone_ ( inputfiles_.end() )
221  , currentSubRunID_ ( )
222  {
223  helper.reconstitutes<raw::DAQHeader, art::InEvent>("daq");
224  helper.reconstitutes<std::vector<raw::RawDigit>, art::InEvent>("daq");
225  helper.reconstitutes<sumdata::RunData, art::InRun> ("daq");
226  }
227 
229  {
230  // Nothing to do (See EventFileSentry).
231  }
232 
233  void LArRawInputDriver::readFile(std::string const &name,
234  art::FileBlock* &fb)
235  {
236  // Get the list of event files for this directory.
237  currentDir_ = name;
238  inputfiles_ = getsortedfiles(currentDir_);
239  nextfile_ = inputfiles_.begin();
240  filesdone_ = inputfiles_.end();
242 
243  // Fill and return a new Fileblock.
244  fb = new art::FileBlock(art::FileFormatVersion(1, "LArRawInput 2011a"),
245  currentDir_);
246  }
247 
249  art::SubRunPrincipal* const & /* inSR */,
250  art::RunPrincipal* &outR,
251  art::SubRunPrincipal* &outSR,
252  art::EventPrincipal* &outE)
253  {
254  if (inputfiles_.empty() || nextfile_ == filesdone_ ) return false;
255 
256  // Create empty result, then fill it from current filename:
257  std::unique_ptr<std::vector<raw::RawDigit> > rdcol ( new std::vector<raw::RawDigit> );
258 
259  raw::DAQHeader daqHeader;
260  bool firstEventInRun = (nextfile_ == inputfiles_.begin());
261 
262  process_LAr_file( currentDir_, *nextfile_++, *rdcol, daqHeader );
263  std::unique_ptr<raw::DAQHeader> daqcol( new raw::DAQHeader(daqHeader) );
264 
265  art::RunNumber_t rn = daqHeader.GetRun();
266  art::Timestamp tstamp = daqHeader.GetTimeStamp();
267 
268  if (firstEventInRun){
269  std::unique_ptr<sumdata::RunData> rundata(new sumdata::RunData("argoneut") );
271  outR = principalMaker_.makeRunPrincipal(rn, tstamp);
274  tstamp);
275  art::put_product_in_principal(std::move(rundata), *outR, "daq");
276  }
277  else if (rn != currentSubRunID_.run()){
278  throw cet::exception("InconsistentEventStream")
279  << "Encountered run #" << rn
280  << " while processing events from run #" << currentSubRunID_.run()
281  << "\n";
282  }
283 
286  daqHeader.GetEvent(),
287  tstamp);
288 
289  // Put products in the event.
290  art::put_product_in_principal(std::move(rdcol),
291  *outE,
292  "daq"); // Module label
293  art::put_product_in_principal(std::move(daqcol),
294  *outE,
295  "daq"); // Module label
296 
297  return true;
298  }
299 
300 }
void SetSpareWord(short s)
Definition: DAQHeader.h:99
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:68
void SetRun(unsigned short i)
Definition: DAQHeader.h:95
art::SubRunID currentSubRunID_
std::enable_if_t< P::branch_type==InEvent||P::branch_type==InResults > put_product_in_principal(std::unique_ptr< T > &&product, P &principal, std::string const &module_label, std::string const &instance_name={})
void readFile(std::string const &name, art::FileBlock *&fb)
void SetTimeStamp(time_t t)
Definition: DAQHeader.h:98
stringvec_t::const_iterator nextfile_
SubRunPrincipal * makeSubRunPrincipal(SubRunAuxiliary const &subRunAux) const
Definition: SourceHelper.cc:59
STL namespace.
Definition of basic raw digits.
art::SourceHelper const & principalMaker_
RunPrincipal * makeRunPrincipal(RunAuxiliary const &runAux) const
Definition: SourceHelper.cc:36
TypeLabel const & reconstitutes(std::string const &modLabel, std::string const &instanceName={})
TCanvas * c1
Definition: plotHisto.C:7
EmPhysicsFactory f1
RunNumber_t run() const
Definition: SubRunID.h:84
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
Source to convert raw binary files to root files.
TFile fb("Li6.root")
stringvec_t::const_iterator filesdone_
void SetNChannels(uint32_t i)
Definition: DAQHeader.h:100
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
ifstream in
Definition: comparison.C:7
TDirectory * dir
Definition: macro.C:5
Conversion of binary data to root files.
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:92
unsigned short GetRun() const
Definition: DAQHeader.h:105
TH1F * h1
Definition: plot.C:43
unsigned short GetEvent() const
Definition: DAQHeader.h:107
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
SubRunNumber_t subRun() const
Definition: SubRunID.h:90
void SetSoftwareVersion(unsigned short i)
Definition: DAQHeader.h:94
EventPrincipal * makeEventPrincipal(EventAuxiliary const &eventAux, std::shared_ptr< History > &&history) const
Definition: SourceHelper.cc:83
void SetEvent(unsigned short i)
Definition: DAQHeader.h:97
art framework interface to geometry description
void SetStatus(unsigned int i)
Definition: DAQHeader.h:91
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:108
Event finding and building.
IDNumber_t< Level::Run > RunNumber_t
Definition: IDNumber.h:119