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