Subversion Repositories f9daq

Rev

Rev 198 | Rev 207 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
195 f9daq 1
/********************************************************************\
2
 
3
  Name:         drsread.cpp
4
  Created by:   Rok Pestotnik
5
 
6
  Contents:     Simple example application to read out a DRS4
7
                evaluation board and save into the data file
8
                                Interface dll for LabWindows CVI
9
 
10
\********************************************************************/
11
#ifdef DLLMAIN
12
#define DLLEXPORT  __declspec(dllexport)
13
#else 
14
#define DLLEXPORT  
15
#endif
16
 
17
 
18
#include <stdio.h>
19
#include <string.h>
20
#include <stdlib.h>
21
 
22
#include <math.h>
23
#include <time.h>
24
#include <signal.h>
25
 
26
#include <TFile.h>
27
#include <TH2F.h>
28
#include <TCanvas.h>
29
//#include <TApplication.h>
30
 
31
#ifdef _MSC_VER
32
 
33
#include "gettimeofday.h"
34
#include "timer.h"
35
 
36
#define DIR_SEPARATOR '\\'
37
 
38
#elif defined(OS_LINUX) || defined(OS_DARWIN)
39
 
40
#define O_BINARY 0
41
#include <unistd.h>
42
#include <ctype.h>
43
#include <sys/ioctl.h>
44
#include <errno.h>
45
#define DIR_SEPARATOR '/'
46
#endif
47
 
48
#include "DRS.h"
49
#include "drsread.h"
50
 
51
 
52
/*------------------------------------------------------------------*/
53
class drssettings  {
54
    static drssettings *s_instance;
55
public:
56
   drssettings(){
57
       mask     = 0xF;
58
       range = 0;
59
       trigger_type = 1;
60
       sampling_frequency = 5;
61
       trigger_delay = 0;
62
       trigger_channel=0;
63
       trigger_polarity=false;
64
       trigger_level=0.05;
65
 
66
   };
67
   ~drssettings(){};
68
   static drssettings *instance()
69
    {
70
        if (!s_instance)
71
          s_instance = new drssettings;
72
        return s_instance;
73
    };
74
 
75
 
76
   unsigned char mask;
77
   double        range;
78
   int           trigger_type; // 0 software, 1 fast hardware, 2 slow hardware
79
   int           trigger_channel;
80
   int           sampling_frequency;
81
   double        trigger_delay;
82
   double        trigger_level;
83
   bool          trigger_polarity;
84
};
85
drssettings *drssettings::s_instance = 0;
86
drssettings *DRSParameters;
87
DLLEXPORT void DRSSetMask(int mask){ drssettings::instance()->mask;};
88
DLLEXPORT void DRSSetTriggerType(int type){ drssettings::instance()->trigger_type = type;};
89
DLLEXPORT void DRSSetFrequency(int freq){ drssettings::instance()->sampling_frequency = freq;};
90
DLLEXPORT void DRSSetRange(double range){ drssettings::instance()->range = range;};
91
DLLEXPORT void DRSSetTriggerChannel(int channel){ drssettings::instance()->trigger_channel = channel;};
92
DLLEXPORT void DRSSetTriggerDelay(double delay){ drssettings::instance()->trigger_delay = delay;};
93
DLLEXPORT void DRSSetTriggerLevel(double level){ drssettings::instance()->trigger_level = level;};
94
DLLEXPORT void DRSSetTriggerPolarity(int polarity){ drssettings::instance()->trigger_polarity = (polarity==1);};
95
 
96
 
97
static int DRSTimeout;
98
 
99
DLLEXPORT int DRSIsTimeout()
100
{
101
        return DRSTimeout;
102
}
103
 
104
DLLEXPORT void DRSSetTimeout ( void )
105
{
106
    DRSTimeout=1;
107
    printf("->>> Timer Out !!!\n");
108
}
109
 
110
static DRS *drs=NULL;
111
 
112
DLLEXPORT int DRSInit()
113
{
114
 
115
   DRSBoard *b;
116
   /* do drsinitial scan */
117
   drs = new DRS();
118
   if (!drs) return -1;
119
   DRSParameters = drssettings::instance();
120
 
121
   /* show any found board(s) */
122
   for (int i=0 ; i<drs->GetNumberOfBoards() ; i++) {
123
      b = drs->GetBoard(i);
124
      printf("Found DRS4 evaluation board, serial #%d, firmware revision %d\n",
125
         b->GetBoardSerialNumber(), b->GetFirmwareVersion());
126
   }
127
 
128
   /* exit if no board found */
129
   int nBoards = drs->GetNumberOfBoards();
130
   if (nBoards == 0) {
131
      printf("No DRS4 evaluation board found\n");
132
      return -2;
133
   }
134
 
135
   /* continue working with first board only */
136
   b = drs->GetBoard(0);
137
 
138
   /* drsinitialize board */
139
   b->Init();
140
 
141
   /* set sampling frequency default 5 */
142
   b->SetFrequency(DRSParameters->sampling_frequency, true);
143
 
144
   /* enable transparent mode needed for analog trigger */
145
   b->SetTranspMode(1);
146
 
147
   /* set input range to -0.5V ... +0.5V -> range=0 */
148
   b->SetInputRange(DRSParameters->range);
149
 
150
   /* use following line to set range to 0..1V */
151
   //b->SetInputRange(0.5);
152
 
153
   /* use following line to turn on the internal 100 MHz clock connected to all channels  */
154
   //b->EnableTcal(1);
155
 
156
   /* kaj je to ....
157
    // Set domino mode
158
   // mode == 0: single sweep
159
   // mode == 1: run continously -- default
160
   b->SetDominoMode(1);
161
    // Set domino activity
162
   // mode == 0: stop during readout  
163
   // mode == 1: keep domino wave running -- default
164
   //  
165
   b->SetDominoActive(1);
166
 
167
   // Set readout mode
168
   // mode == 0: start from first bin  -- default
169
   // mode == 1: start from domino stop
170
   //
171
   b->SetReadoutMode(1);
172
   */
173
 
174
   /* use following lines to enable hardware trigger on CH1 at 50 mV positive edge */
175
   printf("Board Type:%d\n",b->GetBoardType() );
176
   if (b->GetBoardType() >= 8) {        // Evaluaiton Board V4&5
177
 
178
      b->EnableTrigger(DRSParameters->trigger_type, 0);           // enable hardware trigger - 1 fast trigger, 2 slow trigger, 0 disable hw trigger
179
      b->SetTriggerSource(1<<DRSParameters->trigger_channel);        // set CH1 as source // simple or of single channel
180
   } else if (b->GetBoardType() == 7) { // Evaluation Board V3
181
      b->EnableTrigger(0, 1);           // lemo off, analog trigger on
182
      b->SetTriggerSource(0);           // use CH1 as source
183
   }
184
   b->SetTriggerLevel(DRSParameters->trigger_level);            // 0.05 V
185
   b->SetTriggerPolarity(DRSParameters->trigger_polarity);        // positive edge
186
 
187
   /* use following lines to set individual trigger elvels */
188
   //b->SetIndividualTriggerLevel(1, 0.1);
189
   //b->SetIndividualTriggerLevel(2, 0.2);
190
   //b->SetIndividualTriggerLevel(3, 0.3);
191
   //b->SetIndividualTriggerLevel(4, 0.4);
192
   //b->SetTriggerSource(15);
193
 
194
   b->SetTriggerDelayNs( DRSParameters->trigger_delay);             // zero ns trigger delay
195
 
196
   /* use following lines to enable the external trigger */
197
   //if (b->GetBoardType() == 8) {     // Evaluaiton Board V4
198
   //   b->EnableTrigger(1, 0);           // enable hardware trigger
199
   //   b->SetTriggerSource(1<<4);        // set external trigger as source
200
   //} else {                          // Evaluation Board V3
201
   //   b->EnableTrigger(1, 0);           // lemo on, analog trigger off
202
   // }
203
 
204
   return 0;
205
 
206
 
207
}
208
 
209
static float DRSTimeArray[8][1024];
210
static float DRSWaveArray[8][1024];
211
 
212
DLLEXPORT float * DRSGetTime(int ch){ return DRSTimeArray[ch];}
213
DLLEXPORT float * DRSGetWave(int ch){ return DRSWaveArray[ch];}
214
 
215
DLLEXPORT int DRSRead( int DRStimer)
216
{
217
 
218
   DRSBoard *b = drs->GetBoard(0);
219
 
220
 
221
 
222
      /* wait for trigger */
223
 
224
 
225
      int tout=1000; /* timeout in mili seconds */
226
      DRSTimeout=0;
227
 
228
      if (DRStimer) start_timer(tout, &DRSSetTimeout);
229
 
230
          /* start board (activate domino wave) */
231
      b->StartDomino();
232
 
233
      if (!DRSParameters->trigger_type) b->SoftTrigger();
234
 
235
      while (b->IsBusy()){
236
 
237
        if (DRSTimeout) {
238
          printf("Waiting for Trigger.. at line %d\n",  __LINE__);
239
 
240
          if (DRStimer) stop_timer();
241
 
242
          return -1;
243
        }
244
          };
245
 
246
 
247
      if (DRStimer) stop_timer();
248
 
249
 
250
 
251
      /* read all waveforms */
252
      b->TransferWaves(0, 8);
253
 
254
 
255
      for (int k=0;k<4;k++){
256
        if (! (DRSParameters->mask & ( 0x1<<k ))  ) continue;
257
      /* Note: On the evaluation board input #1 is connected to channel 0 and 1 of
258
       the DRS chip, input #2 is connected to channel 2 and 3 and so on. So to
259
       get the input #2 we have to read DRS channel #2, not #1. */
260
 
261
      /* read time (X) array of k-th channel in ns and waveform (Y) array of k-th channel in mV */
262
        b->GetTime(0, 2*k, b->GetTriggerCell(DRSParameters->trigger_channel), DRSTimeArray[k]);
263
        b->GetWave(0, 2*k, DRSWaveArray[k]);
264
 
265
 
266
      }
267
 
268
  return 0;    
269
}
270
 
271
DLLEXPORT int DRSEnd(){
272
 
273
   /* delete DRS object -> close USB connection */
274
   if (drs) delete drs;
275
   drs = NULL;
276
   return 0;
277
}
278
 
279
 
280
 
281
DLLEXPORT int DRSToBuffer( unsigned char *p, int m_evSerial  )
282
{
283
 
284
   unsigned short d;
285
   float t;
286
   unsigned char *p0 = p;
287
 
288
   int m_nBoards    = drs->GetNumberOfBoards();
289
   int m_waveDepth  = 1024 ;// 2048
290
   int m_inputRange = drs->GetBoard(0)->GetInputRange();  
291
   time_t rawtime;
292
   time ( &rawtime );
293
   struct tm m_evTimestamp;
294
   m_evTimestamp = *(localtime ( &rawtime ));
295
   struct timeval mtime;
296
   gettimeofday(&mtime, NULL);
297
 
298
      if (m_evSerial == 0) {
299
         // time calibration header
300
         memcpy(p, "TIME", 4);
301
         p += 4;
302
 
303
         for (int b=0 ; b<m_nBoards ; b++) {
304
            // store board serial number
305
            sprintf((char *)p, "B#");
306
            p += 2;
307
            *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
308
            p += sizeof(unsigned short);
309
 
310
            for (int i=0 ; i<4 ; i++) {
311
               if (DRSParameters->mask & (0x1<<i)) {
312
                  sprintf((char *)p, "C%03d", i+1);
313
                  p += 4;
314
                  float tcal[2048];
315
                  drs->GetBoard(b)->GetTimeCalibration(0, i*2, 0, tcal, 0);
316
                  for (int j=0 ; j<m_waveDepth ; j++) {
317
                     // save binary time as 32-bit float value
318
                     if (m_waveDepth == 2048) {
319
                        t = (tcal[j]+tcal[j+1])/2;
320
                        j++;
321
                     } else
322
                        t = tcal[j];
323
                     *(float *)p = t;
324
                     p += sizeof(float);
325
                  }
326
               }
327
            }
328
         }
329
      }
330
 
331
 
332
 
333
      memcpy(p, "EHDR", 4);
334
      p += 4;
335
      *(int *)p = m_evSerial;
336
      p += sizeof(int);
337
      *(unsigned short *)p = m_evTimestamp.tm_year;
338
      p += sizeof(unsigned short);
339
      *(unsigned short *)p = m_evTimestamp.tm_mon;
340
      p += sizeof(unsigned short);
341
      *(unsigned short *)p = m_evTimestamp.tm_mday;
342
      p += sizeof(unsigned short);
343
      *(unsigned short *)p = m_evTimestamp.tm_hour;
344
      p += sizeof(unsigned short);
345
      *(unsigned short *)p = m_evTimestamp.tm_min;
346
      p += sizeof(unsigned short);
347
      *(unsigned short *)p = m_evTimestamp.tm_sec;
348
      p += sizeof(unsigned short);
349
      *(unsigned short *)p = mtime.tv_usec/1000;
350
      p += sizeof(unsigned short);
351
      *(unsigned short *)p = (unsigned short)(m_inputRange * 1000); // range
352
      p += sizeof(unsigned short);
353
 
354
      int b=0; // only for board 0
355
 
356
         // store board serial number
357
         sprintf((char *)p, "B#");
358
         p += 2;
359
         *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
360
         p += sizeof(unsigned short);
361
 
362
         // store trigger cell
363
         sprintf((char *)p, "T#");
364
         p += 2;
365
         *(unsigned short *)p = drs->GetBoard(b)->GetTriggerCell(DRSParameters->trigger_channel);
366
         p += sizeof(unsigned short);
367
 
368
         for (int i=0 ; i<4 ; i++) {
369
            if (DRSParameters->mask & (0x1<<i)) {
370
               sprintf((char *)p, "C%03d", i+1);
371
               p += 4;
372
               for (int j=0 ; j<m_waveDepth ; j++) {
373
                  // save binary date as 16-bit value:
374
                  // 0 = -0.5V,  65535 = +0.5V    for range 0
375
                  // 0 = -0.05V, 65535 = +0.95V   for range 0.45
376
                  if (m_waveDepth == 2048) {
377
                     // in cascaded mode, save 1024 values as averages of the 2048 values
378
                     d = (unsigned short)(((DRSWaveArray[i][j]+DRSWaveArray[i][j+1])/2000.0 - m_inputRange + 0.5) * 65535);
379
                     *(unsigned short *)p = d;
380
                     p += sizeof(unsigned short);
381
                     j++;
382
                  } else {
383
                     d = (unsigned short)((DRSWaveArray[i][j]/1000.0 - m_inputRange + 0.5) * 65535);
384
                     *(unsigned short *)p = d;
385
                     p += sizeof(unsigned short);
386
                  }
387
               }
388
            }
389
         }
390
 
391
   return (p-p0); // return number of bytes
392
}
393
 
394
 
395
 
396
#ifdef MAIN
397
 
398
 
399
 
400
#include "XGetopt.h"
401
#include "getopt.h"
402
 
403
TH2F *h[4];
404
 
405
typedef struct {
406
   char           recid[4];
407
   unsigned int posx, posy, posz;
408
   unsigned int iposx, iposy, iposz;
409
} POSREC;
410
 
411
 
412
int help() {
413
    printf ("*********************************************************************************:\n");
414
    printf ("Usage: Read of the DRS4 PSI board and dump of the waveforms in the file:\n\n");
415
    printf ("Arguments: \n");
416
    printf ("-v verbosity \n");
417
    printf ("-a output rootfile \n");
418
    printf ("-o output filename \n");
203 f9daq 419
    printf ("-r range \n");
195 f9daq 420
    printf ("-n number of events\n");
421
    printf ("-m channel bit mask\n");
422
    printf ("-h trigger type (0 software, 1 fast hardware, 2 slow hardware)\n");
423
    printf ("-d trigger delay in ns\n");
424
    printf ("-f sampling frequency\n");
425
    printf ("-t trigger channel\n");
426
        printf ("-l trigger level\n");
427
        printf ("-p trigger polarity (0 positive\n");
428
    printf ("*********************************************************************************:\n");
429
    printf ("Examples:\n\n");
430
 
431
    return 0;
432
}
433
 
434
 
435
 
436
char filename[0xFF]="";
437
char rootfile[0xFF]="";
438
int  neve          =  0;
439
int  verbose       =  0;
440
 
441
void Init(int argc, char **argv){
442
   DRSParameters = drssettings::instance();
443
   char c;
444
 
445
   extern char *optarg;
446
   extern int optind;
447
   extern int optopt;
448
   while ((c = getopt (argc, argv, "a:o:v:m:n:f:d:r:h:t:p:l:")) != -1){
449
 
450
        switch (c)
451
        {
452
 
453
        case 'a':
454
            sprintf(rootfile,"%s", optarg );
455
            break;       // root output
456
 
457
        case 'o':
458
            sprintf(filename,"%s", optarg );
459
            break;       // output
460
 
461
        case 'v':
462
             verbose = atoi(optarg);
463
            break;                       // verbosity
464
        case 'm':{
465
            unsigned long ul = strtoul (optarg,NULL,0);
466
            DRSSetMask( (unsigned char)( ul & 0xF ) ) ;
467
            break;
468
        }                               // channel mask
469
        case 'n':
470
            neve =  atoi (optarg);
471
            break;                          // number of events or number of scan points
472
 
473
        case 'f':
474
            DRSSetFrequency( atoi (optarg) );
475
            break;                          // sampling frequency
476
 
477
        case 'd':
478
            DRSSetTriggerDelay(  atof (optarg) );
479
            break;                          // trigger delay
480
        case 'p':
481
            DRSSetTriggerPolarity( atoi (optarg));
482
            break;                          // trigger polarity
483
        case 'l':
484
            DRSSetTriggerLevel(atoi (optarg));
485
            break;                          // trigger level
486
 
487
 
488
        case 'r':
489
            DRSSetRange (  atof (optarg) );
490
            break;                          // range 
491
        case 'h':
492
            DRSSetTriggerType( atoi (optarg) );
493
            break;         // send sotware trigger before reading out the dat
494
        case 't':
495
            DRSSetTriggerChannel( atoi(optarg) );
496
            break;         // trigger channel
497
 
498
 
499
        case '?':
500
            if (optopt == 'c')
501
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
502
            else if (isprint (optopt))
503
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
504
            else
505
                fprintf (stderr,
506
                         "Unknown option character `\\x%x'.\n",
507
                         optopt);
508
            abort ();
509
        default:
510
            abort ();
511
        }
512
    }
513
    //for (int i=optind; i<argc; i++) data = strtoul (argv[i],NULL,0);
514
 
515
}
516
 
517
int ctrl_c=0;
518
DLLEXPORT void DRSSigInt ( int )
519
{
520
    ctrl_c = 1;
521
    printf("->>> CTRL+c !!!\n");
522
}
523
 
524
//#ifdef __CINT__
525
int main(int argc, char **argv){
526
//#else
527
//int drsread(int argc, char **argv){   
528
//#endif
529
 
530
 if (signal (SIGINT, DRSSigInt) == SIG_ERR) {
531
   perror ("sigignore");
532
 }
533
 
534
 
535
Init(argc, argv);
536
if (argc==1) { help(); return 0; }
537
 
538
FILE *fp=NULL;
539
if (strlen(filename)>0) {
540
  if (verbose) printf("Data in the file:%s\n", filename);
541
  fp=fopen(filename,"wb");
542
}
543
 
544
TFile *rfile= NULL;
545
if (strlen(rootfile)>0) {
546
  if (verbose) printf("Data in the file:%s\n", rootfile);  
547
  rfile = new TFile(rootfile,"RECREATE");
548
}
549
 
550
 
551
TCanvas *c = new TCanvas(); c->Divide(2,2);
552
c->Draw();
553
for (int i=0;i<4;i++){
554
   if (! (DRSParameters->mask & ( 0x1<<i ))  ) continue;       
555
   char name[0xff];
556
   sprintf(name,"h%d",i);
557
   h[i]=new TH2F(name,name,1024,0,204,1024,-0.6+DRSParameters->range,0.6+DRSParameters->range);
558
   c->cd(i+1); h[i]->Draw("colz");
559
 
560
}
561
 
562
 
563
 
564
//---------------------------------------
565
static unsigned char *buffer;
566
static int buffer_size = 0;
567
const int nBoards=1;
568
const int waveDepth=1024;
569
if (buffer_size == 0) {
570
         buffer_size =  4 +  nBoards * (4 + 4*(4+waveDepth*4));
571
         buffer_size += 24 + nBoards * (8 + 4*(4+waveDepth*2));
572
         buffer = (unsigned char *)malloc(buffer_size);
573
}
574
 
575
time_t t,told, tstart;
576
if (!DRSInit()){
577
  time(&tstart);
578
  told=tstart;
579
  int i=0;
580
  for (i=0; i<neve; i++) {
581
    int nb =  (DRSRead(1) == 0 && fp ) ? DRSToBuffer( buffer , i ) : 0;
582
 
583
        if (DRSTimeout) i--;
584
    if (ctrl_c) break;
585
    time(&t);
586
    if (t!=told ) {
587
                printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
588
                c->Modified(); c->Update();
589
        }      
590
    told=t;
591
// Save data    
592
        if (nb>0 && fp) fwrite(buffer, 1,nb ,fp);
593
// Plot Data
594
        for (int k=0;k<4;k++){
595
        if (! (DRSParameters->mask & ( 0x1<<k ))  ) continue;
596
        float *t=DRSGetTime(k);
597
        float *x=DRSGetWave(k);        
598
            for (int i=0 ; i<1024 ; i++) {
599
           if (verbose) printf("[%d] %d. x= %3.2f  y=%3.2f\n", k, i, t[i], x[i] );
600
           h[k]->Fill( t[i], x[i]*1e-3);
601
        }
602
        }
603
  }
604
  time(&t);
605
  printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
606
 
607
  DRSEnd();
608
}
609
//---------------------------------------
610
if (rfile !=NULL) rfile->Write();
611
if (fp) fclose(fp);
612
if (c) c->SaveAs("drsread.pdf");
613
// TApplication* theApp = new TApplication("App", NULL, NULL);
614
// theApp->Run();
615
 
616
 
617
 
618
}
619
 
620
#endif