Diana Software
MQinoDataReader.cc
Go to the documentation of this file.
1 /* Diana Reconstruction program
2  *
3  * Class QinoDataReader
4  *
5 */
6 
7 
8 #include "MQinoDataReader.hh"
9 #include "QInoDataReaderDebug.hh"
10 #include "QEvent.hh"
11 #include "QEventAssembler.hh"
12 #include "QRawEvent.hh"
13 #include <cstdlib>
14 #include <ctime>
15 #include <iostream>
16 
18 
19  using namespace std;
20 
21 
22 // ctor
24 {
25  fTimeZone = getenv("TZ");
26  setenv("TZ", ":Europe/Rome", 1);
27  tzset();
28 }
29 
30 // dtor
32 {
33  if (fTimeZone) {
34  setenv("TZ", fTimeZone, 1);
35  }
36  else {
37  unsetenv("TZ");
38  }
39  tzset();
40 }
41 
42 // Init method is called before event loop
44 {
45  // Reads multiple or single files
46  InitFileManager();
47  fIter = fFileList.begin();
48  fPreTriggerSamples = GetInt("PreTriggerSamples",128);
49  fIsNoise = GetBool("NoiseFile",false);
50  fDebugOn = GetBool("DebugOn",false,false);
51  if(fDebugOn) {
52  evi.GetEvent().Add<QInoDataReaderDebug>("DebugData");
53  }
54 
55  fSamplingFrequency = 0.;
56  NewRun();
57  fEventNumber = 0;
58  fFileUName = " ";
59  fDetector = DN_UNKNOWN;
60  // initialize event
61 
62  evi.Add<QHeader>("DAQ","Header");
63  evi.Add<QPulse>("DAQ","Pulse");
64  evi.Add<QPulseInfo>("DAQ","PulseInfo");
65 }
66 
67 // MARIA
68 const QError& MQinoDataReader::JumpToEvent(Long64_t event)
69 {
70  // CHECK IF THE PARTIAL IS CORRECT
71  int partial = filesIter-files.begin();
72  if (partial!=fPartialToJump)
73  {
74  Info("Jumping to event %d. Closing partial %d. Opening %d",event, partial, fPartialToJump);
75  gzclose(fCurrentFile);
76  filesIter = files.begin()+fPartialToJump;
77  fCurrentFile = gzopen(filesIter->filename.data(),"rb");
78  }
79 
80  z_off_t off = gzseek(fCurrentFile, event*frecord_size, SEEK_SET);
81 
82  if (off==-1)
83  {
84  fErr = QERR_OUT_OF_RANGE;
85  char buf[128];
86  sprintf(buf,"Cannot jump to event : %llu", event);
87  fErr.SetDescription(buf);
88  }
89  else
90  {
91  fErr = QERR_SUCCESS;
92  fEventNumber = event;
93  }
94  return fErr;
95 }
96 
97 
98 // Doit method is called for each event, getting the event as argument
100  // if first event open first file
101  if(fEventNumber == 0){
102  fCurrentFile = gzopen(filesIter->filename.data(),"rb");
103  }
104  // loop over events
105  struct QBinRecStruct_t p;
106  int ret = gzread(fCurrentFile,&p,frecord_size);
107  // end of file?
108  if ( ret != frecord_size) {
109  //end of partial measurement
110  Debug("End of file %s at event %d",filesIter->filename.data(),fEventNumber);
111  gzclose(fCurrentFile);
112  filesIter++;
113  if(filesIter != filesEnd){
114  fCurrentFile = gzopen(filesIter->filename.data(),"rb");
115  return Do(evi);
116  }
117  else {
118  fIter++;
119  //end of run
120  if (fIter != fFileList.end()){
121  NewRun();
122  fCurrentFile = gzopen(filesIter->filename.data(),"rb");
123  return Do(evi);
124  }
125  else{
126  // end of file list
127  return false;
128  }
129  }
130  }
131 
132  QHeader &header = evi.Get<QHeader>("DAQ","Header");
133  QPulse &pulse = evi.Get<QPulse>("DAQ","Pulse");
134  QPulseInfo &pulseInfo = evi.Get<QPulseInfo>("DAQ","PulseInfo");
135 
136 
137  QTime &time = header.GetTime();
138  header.SetEventNumber(fRunEventNumber);
139  QSampleInfo &sampleInfo = pulseInfo.GetMasterSample();
140  pulseInfo.SetChannelId(p.chan + 1);
141  QVectorI samplesADC;
142  sampleInfo.SetTriggerNumber(0);
143  sampleInfo.SetEventNumber(fRunEventNumber);
144 
145  WriteHandle<QInoDataReaderDebug> debugHandle("DebugData");
146  evi.GetEvent().Get(debugHandle);
147 
148 
149  if(fDebugOn) {
150  QInoDataReaderDebug& readerDebug = debugHandle.Get();
151  readerDebug.fEventNumber = fRunEventNumber;
152  readerDebug.fChannel = p.chan+1;
153  }
154  std::string headFlag = p.cHeader;
155  headFlag = headFlag.substr(0,8);
156  headFlag += "\0";
157 
158  // stabilization heater
159  if((headFlag == "HEADSRCE") || (headFlag == "headsrce")){
160  sampleInfo.SetIsPulser();
161  //sampleInfo.SetStabPulser(true);
162  sampleInfo.SetPulserDelay(1);
163  if(debugHandle.IsValid()) {
164  QInoDataReaderDebug& readerDebug = debugHandle.Get();
165  readerDebug.fIsHeater = true;
166  readerDebug.fIsStabHeater = true;
167  }
168  }
169 
170  // high amplitude heater
171  else if((headFlag == "HEADSRCH") || (headFlag == "headsrch")){
172  sampleInfo.SetIsPulser();
173  //sampleInfo.SetStabPulser(false);
174  sampleInfo.SetPulserDelay(2);
175  if(debugHandle.IsValid()) {
176  QInoDataReaderDebug& readerDebug = debugHandle.Get();
177  readerDebug.fIsHeater = true;
178  readerDebug.fIsHighHeater = true;
179  }
180  }
181 
182  // low amplitude heater
183  else if((headFlag == "HEADSRCL") || (headFlag == "headsrcl")){
184  sampleInfo.SetIsPulser();
185  // sampleInfo.SetStabPulser(false);
186  sampleInfo.SetPulserDelay(3);
187  if(debugHandle.IsValid()) {
188  QInoDataReaderDebug& readerDebug = debugHandle.Get();
189  readerDebug.fIsHeater = true;
190  readerDebug.fIsLowHeater = true;
191  }
192  }
193 
194  //physical pulses
195  else if((headFlag == "HEADSIGN") or (headFlag == "headsign") or
196  (headFlag == "HEADFLAG") or (headFlag == "headflag")){
197  sampleInfo.SetIsSignal();
198  sampleInfo.SetTriggerNumber(1);
199  if(debugHandle.IsValid()) {
200  QInoDataReaderDebug& readerDebug = debugHandle.Get();
201  readerDebug.fIsSignal = true;
202  readerDebug.fTriggerType = 1;
203  }
204  }
205  //random trigger
206  else if((headFlag == "HEADTRND") or (headFlag == "headtrnd") or
207  (headFlag == "HEADNOIS") or (headFlag == "headnois") ){
208  sampleInfo.SetIsNoise();
209  sampleInfo.SetTriggerNumber(2);
210  if(debugHandle.IsValid()) {
211  QInoDataReaderDebug& readerDebug = debugHandle.Get();
212  readerDebug.fTriggerType = 2;
213  readerDebug.fIsNoise = true;
214  }
215  }
216  else{
217  Debug(" record structure: %s at event %d, channel %d",headFlag.c_str(), fEventNumber,p.chan);
218  }
219 
220  if(fIsNoise == true)
221  {
222  sampleInfo.SetIsNoise();
223  sampleInfo.SetTriggerNumber(2);
224  if(debugHandle.IsValid()) {
225  QInoDataReaderDebug& readerDebug = debugHandle.Get();
226  readerDebug.fIsNoise = true;
227  }
228  }
229 
230  UInt_t timetenthms = (UInt_t)(p.pulseTime2 << 16) + (UInt_t)p.pulseTime1;
231  unsigned long long tNs = (unsigned long long)(timetenthms*1e5);
232  time.SetFromStartRunNs(tNs);
233  // parsing time of start of run
234  int month=atoi(fDate.substr(0,2).c_str());
235  int day=atoi(fDate.substr(3,2).c_str());
236  int year=atoi(fDate.substr(6,4).c_str());
237  int hour=atoi(fDate.substr(11,2).c_str());
238  int min=atoi(fDate.substr(14,2).c_str());
239  int sec=atoi(fDate.substr(17,2).c_str());
240  time.SetStartRunUnix(year,month,day,hour,min,sec);
241 
242  if(debugHandle.IsValid()) {
243  QInoDataReaderDebug& readerDebug = debugHandle.Get();
244  readerDebug.fTime = time;
245  }
246 
247  static UInt_t offset;
248  if(f.isDiff){
249  offset = 32768;
250  }
251  else{
252  offset = 0;
253  }
254  sampleInfo.SetSampleIndex(fPreTriggerSamples);
255  samplesADC.Resize(fNumSamples);
256  samplesADC[0] = p.first_sampl;
257  samplesADC[0] += offset;
258  if(f.isDiff){
259  samplesADC[1] = ((int)p.sampl[0] + samplesADC[0]);
260  for(Int_t i = 2; i < fNumSamples; i++){
261  samplesADC[i] = (int)(p.sampl[i-1] + samplesADC[i-1]);
262  }
263  }
264  else{
265  samplesADC[1] = ((int)p.sampl[0] );
266  for(Int_t i = 2; i < fNumSamples; i++){
267  samplesADC[i] = (int)(p.sampl[i-1] );
268  }
269  }
270  pulse.SetSamplesADC(samplesADC);
271  if(debugHandle.IsValid()) {
272  QInoDataReaderDebug& readerDebug = debugHandle.Get();
273  readerDebug.fSamples = samplesADC;
274  readerDebug.fTimedSample = fPreTriggerSamples;
275  }
276 
277  if(fName != fFileUName){
278  // notify open new file
279  OpenNewFile(fName + ".hdr");
280  fFileUName = fName;
281  std::string suffix = fName.substr(fName.length()-5 ,5);
282  fDetector = DN_UNKNOWN;
283  if(suffix.at(0) == 'c') {
284  fDetector = DN_HALLC;
285  }
286  else if(suffix.at(0) == 'q') {
287  fDetector = DN_CUORICINO;
288  }
289 
290  Info("Current file is %s", fFileUName.c_str());
291  }
292  int runInt = strtol(fRunNumber.c_str(),0,10)+(int)fDetector*100000;
293  //if(fIsNoise == true) runInt +=70000;
294  header.SetRun(runInt);
295  if(debugHandle.IsValid()) {
296  QInoDataReaderDebug& readerDebug = debugHandle.Get();
297  readerDebug.fRun = runInt;
298  }
299 
300  fEventNumber++;
301  fRunEventNumber++;
302  return true;
303 }
304 
305 // Done method is called after event loop
307 }
308 
310  fRunEventNumber = 0;
311  fName = fIter->c_str();
312  fRunNumber = fName;
313  fRunNumber.erase(0,fRunNumber.size()-4);
314  files.clear();
315 
316  char s[200];
317  sprintf(s,"%s.hdr",fName.c_str());
318  Info("Opening file: %s",s);
319 
320  // check that header exists
321  FILE *fp = fopen(s,"rt");
322  if ( !fp && !fIsNoise ) {
323  Panic("Cannot find file %s",s);
324  }
325  else if (fp){
326  // read from header
327  int pulseDurationMs;
328  if(GetBool("NewHDR",false,false)) {
329  float minADC, maxADC;
330  fscanf(fp,"%f %f\n",&minADC,&maxADC);
331  fMinAdcRange = minADC;
332  fMaxAdcRange = maxADC;
333  fscanf(fp,"%d\n",&fNumSamples);
334  fscanf(fp,"%i\n",&pulseDurationMs);
335  } else {
336  int minADC, maxADC;
337  fscanf(fp,"%d %d %i\n",&minADC,&maxADC, &fNumSamples);
338  fMinAdcRange = minADC;
339  fMaxAdcRange = maxADC;
340  fscanf(fp,"%i\n",&pulseDurationMs);
341  }
342 
343  fSamplingFrequency = float(fNumSamples) / pulseDurationMs * 1000;
344 
345  char c1[50],c2[50], d[50];
346  while(fscanf(fp,"%s %s \n",c1,c2)!=EOF){
347 
348  if(std::string(c1)=="Start"&&std::string(c2)=="date"){
349  fscanf(fp,"%s \n",d);
350  fDate=d+std::string(" ");
351 
352  }
353  if(std::string(c1)=="Start"&&std::string(c2)=="time"){
354  fscanf(fp,"%s \n",d);
355  fDate+=d;
356  }
357 
358  }
359 
360  fclose(fp);
361  Debug("header file closed");
362  Debug("%s",fDate.c_str());
363  }
364  else{//the file read is a noise one and no header file is prensent
365  Info("Header fime not found: using default values for ADC range, number of samples, sampling frequency and date");
366  fMinAdcRange = 0;
367  fMaxAdcRange = 10;
368  fNumSamples = 512;
369  fSamplingFrequency = 125;
370  fDate = "01-01-1980 00:00:00";
371  }
372 
373  frecord_size = 8 + 2 + 4 + (2 * fNumSamples);
374 
375  int NumFiles = 0;
376  bool isDiff;
377  if(fIsNoise == false){
378  while(1) {
379  char s[100];
380  sprintf(s,"%s.%03d.gz",fName.c_str(),NumFiles);
381  FILE *fp = fopen(s,"rb");
382  // try the differential option
383  if(!fp){
384  sprintf(s,"%s.%03d_d.gz",fName.c_str(),NumFiles);
385  fp = fopen(s,"rb");
386  isDiff=true;
387  } else {
388  isDiff=false;
389  }
390  if (fp) {
391  Debug("Found file %s.%03d_d.gz",fName.c_str(),NumFiles);
392  NumFiles++;
393  f.filename=s;
394  f.isDiff=isDiff;
395  files.push_back(f);
396  fclose(fp);
397  } else {
398  break;
399  }
400  }
401  }
402  else{
403  char s[100];
404  sprintf(s,"%s.noi",fName.c_str());
405  FILE *fp = fopen(s,"rb");
406  // try the differential option
407  if(!fp){
408  sprintf(s,"%s.noi_d.gz",fName.c_str());
409  fp = fopen(s,"rb");
410  isDiff=true;
411  } else {
412  isDiff=false;
413  }
414  if (fp) {
415  Debug("Found file %s.noi_d.gz",fName.c_str(),NumFiles);
416  NumFiles++;
417  f.filename=s;
418  f.isDiff=isDiff;
419  files.push_back(f);
420  fclose(fp);
421  } else {
422  Panic("No noise file found: exiting");
423  }
424 
425  }
426 
427  filesIter=files.begin();
428  filesEnd=files.end();
429 
430  if (NumFiles)
431  Debug("%d files found for header=%s",NumFiles,fName.c_str());
432  else
433  Panic("%d files found for header=%s",NumFiles,fName.c_str());
434 
435  Debug("NumSamples %d, SamplFreq %f, MinADC %f, MaxADC %f",fNumSamples, fSamplingFrequency, fMinAdcRange, fMaxAdcRange);
436 }
437 
chanRunData fSamplingFrequency
@ DN_UNKNOWN
@ DN_CUORICINO
@ DN_HALLC
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
@ QERR_OUT_OF_RANGE
Definition: QError.hh:28
@ QERR_SUCCESS
Definition: QError.hh:27
double min(const Diana::QVector &v)
Definition: QVector.cc:878
Milano-DAQ binary data reader.
virtual ~MQinoDataReader()
void Done()
Done method is called after event loop. This method must be implemented by inheriting classes.
bool Do(QEventAssembler &evi)
Do method is called for each event, getting the QEventAssembler as argument. This method must be impl...
const QError & JumpToEvent(Long64_t event)
Called when another module ask for a specific eventnumber in the next Do(). Implementation of this me...
void NewRun()
read header whenever tha run is changed
void Init(QEventAssembler &evi)
Init method is called before event loop, getting the QEventAssembler as argument This method must be ...
error class with error type and description
Definition: QError.hh:115
Visitor class of QEvent that provides full handling of QEvent.
QEvent & GetEvent()
Get the QEvent.
void Get(const char *owner, WriteHandle< Q > &handle)
Get QObject from the event in write mode. This method has to be called in the event loop,...
void Add(const char *owner, WriteHandle< Q > &handle)
Add QObject to the event. This method has to be called before the event loop, e.g....
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Definition: QEvent.hh:74
void Add(WriteHandle< Q > &handle)
Add a QObject to the event.
Definition: QEvent.hh:193
virtual bool IsValid() const
Check object validity.
Definition: QHandle.hh:34
Raw event: basic information like run number and time.
Definition: QHeader.hh:16
const Diana::QTime & GetTime() const
get time
Definition: QHeader.hh:28
void SetEventNumber(unsigned int eventNumber)
Set EventNumber.
Definition: QHeader.hh:41
void SetRun(unsigned int run)
Set Run.
Definition: QHeader.hh:39
debug data for test sequences
Raw event: bolometer channel, trigger positions and types.
Definition: QPulseInfo.hh:18
Raw event: sampled waveform.
Definition: QPulse.hh:22
contains information on flagged samples
Definition: QSampleInfo.hh:24
void SetPulserDelay(Int_t delay)
set pulser delay in ms
Definition: QSampleInfo.hh:77
void SetIsNoise()
Set event type to Noise.
Definition: QSampleInfo.hh:69
void SetEventNumber(Int_t eventNumber)
Set EventNumber.
Definition: QSampleInfo.hh:81
void SetIsPulser()
Set event type to Pulser.
Definition: QSampleInfo.hh:59
void SetTriggerNumber(Int_t n)
Set trigger number (1 to 4)
Definition: QSampleInfo.hh:75
void SetSampleIndex(Int_t index)
Set SampleIndex.
Definition: QSampleInfo.hh:79
void SetIsSignal()
Set event type to Signal.
Definition: QSampleInfo.hh:61
Diana time.
Definition: QTime.hh:17
write handle to access and add QEvent QObject's.
Definition: QHandle.hh:155
T & Get()
get object
Definition: QHandle.hh:161
structure for raw data Qino format
unsigned short pulseTime1
unsigned short pulseTime2