All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LArRawInputDriverLongBo.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file LArRawInputDriverLongBo.cxx
3 /// \brief Source to convert raw binary files to root files
4 ///
5 /// \author brebel@fnal.gov, soderber@fnal.gov
6 ////////////////////////////////////////////////////////////////////////
7 
9 
14 
15 #include "art/Framework/IO/Sources/put_product_in_principal.h"
16 #include "art/Framework/Core/FileBlock.h"
17 #include "art/Framework/Core/ProductRegistryHelper.h"
18 #include "art/Framework/IO/Sources/SourceHelper.h"
19 #include "art/Framework/Principal/EventPrincipal.h"
20 #include "art/Framework/Principal/RunPrincipal.h"
21 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
22 #include "canvas/Persistency/Provenance/Timestamp.h"
23 #include "canvas/Utilities/Exception.h"
24 #include "cetlib_except/coded_exception.h"
25 #include "cetlib_except/exception.h"
26 
27 #include <algorithm>
28 #include <fstream>
29 #include <stdlib.h>
30 #include <time.h>
31 
32 extern "C" {
33 #include <dirent.h>
34 }
35 
36 // ======================================================================
37 // LongBo DAQ480 interface, adapted from code by Rebel/Soderberg:
38 // modified M. Stancari Jan 4, 2013
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  std::vector<raw::ExternalTrigger>& extTrig)
150  {
151  // Prepare the input file. The sentry is responsible for making the
152  // file stream object, and will *automatically* close it when it
153  // goes out of scope *for any reason*, including normal function
154  // exit or exception throw.
155  EventFileSentry efs(dir+"/"+filename);
156  std::ifstream &infile = efs.infile;
157 
158  if( !infile.is_open() ) {
159  throw art::Exception( art::errors::FileReadError )
160  << "failed to open input file " << filename << std::endl;
161  }
162 
163  ///\todo Total number of channels=144 in Long Bo is hardcoded in LArRawInputDriver_LongBo.cxx
164  unsigned int wiresPerPlane = 48;
165  unsigned int planes = 3;
166  int nwires = wiresPerPlane*planes;
167 
168  header h1;
169  channel c1;
170  // footer f1;
171 
172  //read in header section of file
173  infile.read((char *) &h1, sizeof h1);
174 
175  time_t mytime = h1.time;
176  mytime = mytime << 32;//Nov. 2, 2010 - "time_t" is a 64-bit word on many 64-bit machines
177  //so we had to change types in header struct to read in the correct
178  //number of bits. Once we have the 32-bit timestamp from the binary
179  //data, shift it up to the upper half of the 64-bit timestamp. - Mitch
180 
181  // std::cout << "Fixed Value (0x0000D480): " << std::hex << h1.fixed << std::endl;
182  // std::cout << "Output Format: " << std::hex << h1.format << std::endl;
183  // std::cout << "Software Version: " << std::hex << h1.software << std::dec << std::endl;
184  // std::cout << "Run " << std::setw(6) << std::left << h1.run
185  // << "Event " << std::setw(8) << std::left << h1.event
186  // << "h1.time " << std::setw(8) << std::left << h1.time;
187  // std::cout << " #Channels = " << h1.nchan << std::endl;
188 
189  daqHeader.SetStatus(1);
190  daqHeader.SetFixedWord(h1.fixed);
191  daqHeader.SetFileFormat(h1.format);
192  daqHeader.SetSoftwareVersion(h1.software);
193  daqHeader.SetRun(h1.run);
194  daqHeader.SetEvent(h1.event);
195  daqHeader.SetTimeStamp(mytime);
196  daqHeader.SetSpareWord(h1.spare);
197  daqHeader.SetNChannels(h1.nchan);
198 
199  //one digit for every wire on each plane
200  digitList.clear();
201  digitList.resize(wiresPerPlane*planes);
202 
203  //16 external trigger inputs
204  extTrig.clear();
205  extTrig.resize(16);
206 
207  for( int i = 0; i != nwires; ++i ) {
208  infile.read((char *) &c1, sizeof c1);
209  //Create vector for ADC data, with correct number of samples for this event
210  std::vector<short> adclist(c1.samples);
211  infile.read((char*)&adclist[0],sizeof(short)*c1.samples);
212  // std::cout << "Channel = " << c1.ch ;
213  // std::cout << " #Samples = " << c1.samples ;
214  // std::cout << " ADC[0] = " << adclist[0] << " ADC[2047] = " << adclist[2047] << std::endl;
215 
216  // set signal to be 400 if it is 0 (bad pedestal)
217  for (int ijk=0;ijk<c1.samples;++ijk) {
218  if (std::abs(adclist[ijk])<1e-5)
219  adclist[ijk]+=400;
220  }
221 
222  // invert the signals from the BNL ASIC
223  if (i>63 && i<80) {
224  for (int ijk=0;ijk<c1.samples;++ijk) {
225  int mysig=adclist[ijk]-400;
226  adclist[ijk]=400-mysig;
227  }
228  }
229 
230  if (i<96){
231  // digitList[i] = raw::RawDigit((c1.ch-1), c1.samples, adclist);//subtract one from ch. number...
232  digitList[i] = raw::RawDigit(i, c1.samples, adclist);//subtract one from ch. number...
233  //hence offline channels will always be one lower
234  //than the DAQ480 definition. - mitch 7/8/2009
235  digitList[i].SetPedestal(400.); //carl b assures me this will never change. bjr 4/15/2009
236  }
237  else{//flip collection wires to be consistent with offline geometry. TYang 12/23/2013
238  digitList[239-i] = raw::RawDigit(239-i, c1.samples, adclist);
239  digitList[239-i].SetPedestal(400.); //carl b assures me this will never change. bjr 4/15/2009
240  }
241  }
242 
243  //
244  // MStancari, TYang - Apr 4 2013
245  //
246  // Add trigger information to the record
247 
248  unsigned int ichan;
249  for( int i = 0; i < 16; ++i ) {
250  unsigned int utrigtime = 0;
251  infile.read((char *) &c1, sizeof c1);
252  //Create vector for ADC data, with correct number of samples for this event
253  std::vector<short> adclist(c1.samples);
254  infile.read((char*)&adclist[0],sizeof(short)*c1.samples);
255 
256  int j=0;
257  while (j<c1.samples){
258  float test = 400.0-adclist[j];
259  if (test>10 && j>0) {
260  utrigtime=j;
261  break;
262  }
263  j++;
264  }
265  ichan=i+144;
266  extTrig[i] = raw::ExternalTrigger(ichan,utrigtime);
267  }
268 
269 
270 
271  // infile will be closed automatically as EventFileSentry goes out of scope.
272  } // process_LAr_file
273 
274 } // namespace
275 
276 namespace lris {
277  // ======================================================================
278  // class c'tor/d'tor:
279  LArRawInputDriverLongBo::LArRawInputDriverLongBo(fhicl::ParameterSet const &, // Not used
280  art::ProductRegistryHelper &helper,
281  art::SourceHelper const &pm)
282  :
283  principalMaker_(pm)
284  , currentDir_ ()
285  , inputfiles_ ( )
286  , nextfile_ ( inputfiles_.begin() )
287  , filesdone_ ( inputfiles_.end() )
288  , currentSubRunID_ ( )
289  {
290  helper.reconstitutes<raw::DAQHeader, art::InEvent>("daq");
291  helper.reconstitutes<std::vector<raw::RawDigit>, art::InEvent>("daq");
292  helper.reconstitutes<std::vector<raw::ExternalTrigger>,art::InEvent>("daq");
293  helper.reconstitutes<sumdata::RunData, art::InRun> ("daq");
294  }
295 
297  {
298  // Nothing to do (See EventFileSentry).
299  }
300 
301  void LArRawInputDriverLongBo::readFile(std::string const &name,
302  art::FileBlock* &fb)
303  {
304  // Get the list of event files for this directory.
305  currentDir_ = name;
306  inputfiles_ = getsortedfiles(currentDir_);
307  nextfile_ = inputfiles_.begin();
308  filesdone_ = inputfiles_.end();
309  currentSubRunID_ = art::SubRunID();
310 
311  // Fill and return a new Fileblock.
312  fb = new art::FileBlock(art::FileFormatVersion(1, "LArRawInput 2011a"),
313  currentDir_);
314  }
315 
316  bool LArRawInputDriverLongBo::readNext(art::RunPrincipal* const & /* inR */,
317  art::SubRunPrincipal* const & /* inSR */,
318  art::RunPrincipal* &outR,
319  art::SubRunPrincipal* &outSR,
320  art::EventPrincipal* &outE)
321  {
322  if (inputfiles_.empty() || nextfile_ == filesdone_ ) return false;
323 
324  // Create empty result, then fill it from current filename:
325  std::unique_ptr<std::vector<raw::RawDigit> > rdcollb ( new std::vector<raw::RawDigit> );
326  std::unique_ptr<std::vector<raw::ExternalTrigger> > etcollb ( new std::vector<raw::ExternalTrigger> );
327 
328  raw::DAQHeader daqHeader;
329  bool firstEventInRun = (nextfile_ == inputfiles_.begin());
330 
331  process_LAr_file( currentDir_, *nextfile_++, *rdcollb, daqHeader, *etcollb);
332  std::unique_ptr<raw::DAQHeader> daqcollb( new raw::DAQHeader(daqHeader) );
333 
334  art::RunNumber_t rn = daqHeader.GetRun();
335  art::Timestamp tstamp = daqHeader.GetTimeStamp();
336 
337  if (firstEventInRun)
338  {
339  std::unique_ptr<sumdata::RunData> rundata(new sumdata::RunData("bo") );
340  currentSubRunID_ = art::SubRunID(rn, 1);
341  outR = principalMaker_.makeRunPrincipal(rn, tstamp);
342  outSR = principalMaker_.makeSubRunPrincipal(rn,
343  currentSubRunID_.subRun(),
344  tstamp);
345  art::put_product_in_principal(std::move(rundata), *outR, "daq");
346  } else if (rn != currentSubRunID_.run())
347  {
348  throw cet::exception("InconsistentEventStream")
349  << "Encountered run #" << rn
350  << " while processing events from run #" << currentSubRunID_.run()
351  << "\n";
352  }
353 
354  outE = principalMaker_.makeEventPrincipal(currentSubRunID_.run(),
355  currentSubRunID_.subRun(),
356  daqHeader.GetEvent(),
357  tstamp);
358 
359  // Put products in the event.
360  art::put_product_in_principal(std::move(etcollb),
361  *outE,
362  "daq"); // Module label
363  art::put_product_in_principal(std::move(rdcollb),
364  *outE,
365  "daq"); // Module label
366  art::put_product_in_principal(std::move(daqcollb),
367  *outE,
368  "daq"); // Module label
369 
370  return true;
371  }
372 
373 }
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
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_
T abs(T value)
LArRawInputDriverLongBo(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
void readFile(std::string const &name, art::FileBlock *&fb)
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
void SetFixedWord(int i)
Definition: DAQHeader.h:90
bool readNext(art::RunPrincipal *const &inR, art::SubRunPrincipal *const &inSR, art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
unsigned short GetRun() const
Definition: DAQHeader.h:103
do i e
unsigned short GetEvent() const
Definition: DAQHeader.h:105
then echo fcl name
then echo fcl sbnd_project sbnd_project sbnd_project sbnd_project software
stringvec_t::const_iterator filesdone_
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
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