Subversion Repositories f9daq

Rev

Rev 203 | 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) {
207 f9daq 299
                 memcpy(p, "DRS2", 4); // File identifier and version
300
         p += 4;
195 f9daq 301
         // time calibration header
207 f9daq 302
                 memcpy(p, "TIME", 4);
195 f9daq 303
         p += 4;
304
         for (int b=0 ; b<m_nBoards ; b++) {
305
            // store board serial number
306
            sprintf((char *)p, "B#");
307
            p += 2;
308
            *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
309
            p += sizeof(unsigned short);
310
 
311
            for (int i=0 ; i<4 ; i++) {
312
               if (DRSParameters->mask & (0x1<<i)) {
313
                  sprintf((char *)p, "C%03d", i+1);
314
                  p += 4;
315
                  float tcal[2048];
316
                  drs->GetBoard(b)->GetTimeCalibration(0, i*2, 0, tcal, 0);
317
                  for (int j=0 ; j<m_waveDepth ; j++) {
318
                     // save binary time as 32-bit float value
319
                     if (m_waveDepth == 2048) {
320
                        t = (tcal[j]+tcal[j+1])/2;
321
                        j++;
322
                     } else
323
                        t = tcal[j];
324
                     *(float *)p = t;
325
                     p += sizeof(float);
326
                  }
327
               }
328
            }
329
         }
330
      }
331
 
332
 
333
 
334
      memcpy(p, "EHDR", 4);
335
      p += 4;
336
      *(int *)p = m_evSerial;
337
      p += sizeof(int);
338
      *(unsigned short *)p = m_evTimestamp.tm_year;
339
      p += sizeof(unsigned short);
340
      *(unsigned short *)p = m_evTimestamp.tm_mon;
341
      p += sizeof(unsigned short);
342
      *(unsigned short *)p = m_evTimestamp.tm_mday;
343
      p += sizeof(unsigned short);
344
      *(unsigned short *)p = m_evTimestamp.tm_hour;
345
      p += sizeof(unsigned short);
346
      *(unsigned short *)p = m_evTimestamp.tm_min;
347
      p += sizeof(unsigned short);
348
      *(unsigned short *)p = m_evTimestamp.tm_sec;
349
      p += sizeof(unsigned short);
350
      *(unsigned short *)p = mtime.tv_usec/1000;
351
      p += sizeof(unsigned short);
352
      *(unsigned short *)p = (unsigned short)(m_inputRange * 1000); // range
353
      p += sizeof(unsigned short);
354
 
355
      int b=0; // only for board 0
356
 
357
         // store board serial number
358
         sprintf((char *)p, "B#");
359
         p += 2;
360
         *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
361
         p += sizeof(unsigned short);
362
 
363
         // store trigger cell
364
         sprintf((char *)p, "T#");
365
         p += 2;
366
         *(unsigned short *)p = drs->GetBoard(b)->GetTriggerCell(DRSParameters->trigger_channel);
367
         p += sizeof(unsigned short);
368
 
369
         for (int i=0 ; i<4 ; i++) {
370
            if (DRSParameters->mask & (0x1<<i)) {
371
               sprintf((char *)p, "C%03d", i+1);
372
               p += 4;
207 f9daq 373
                           unsigned int s = drs->GetBoard(b)->GetScaler(i);
374
               memcpy(p, &s, sizeof(int));
375
               p += sizeof(int);
195 f9daq 376
               for (int j=0 ; j<m_waveDepth ; j++) {
377
                  // save binary date as 16-bit value:
378
                  // 0 = -0.5V,  65535 = +0.5V    for range 0
379
                  // 0 = -0.05V, 65535 = +0.95V   for range 0.45
380
                  if (m_waveDepth == 2048) {
381
                     // in cascaded mode, save 1024 values as averages of the 2048 values
382
                     d = (unsigned short)(((DRSWaveArray[i][j]+DRSWaveArray[i][j+1])/2000.0 - m_inputRange + 0.5) * 65535);
383
                     *(unsigned short *)p = d;
384
                     p += sizeof(unsigned short);
385
                     j++;
386
                  } else {
387
                     d = (unsigned short)((DRSWaveArray[i][j]/1000.0 - m_inputRange + 0.5) * 65535);
388
                     *(unsigned short *)p = d;
389
                     p += sizeof(unsigned short);
390
                  }
391
               }
392
            }
393
         }
394
 
395
   return (p-p0); // return number of bytes
396
}
397
 
398
 
399
 
400
#ifdef MAIN
401
 
402
 
403
 
404
#include "XGetopt.h"
405
#include "getopt.h"
406
 
407
TH2F *h[4];
408
 
409
typedef struct {
410
   char           recid[4];
411
   unsigned int posx, posy, posz;
412
   unsigned int iposx, iposy, iposz;
413
} POSREC;
414
 
415
 
416
int help() {
417
    printf ("*********************************************************************************:\n");
418
    printf ("Usage: Read of the DRS4 PSI board and dump of the waveforms in the file:\n\n");
419
    printf ("Arguments: \n");
420
    printf ("-v verbosity \n");
421
    printf ("-a output rootfile \n");
422
    printf ("-o output filename \n");
203 f9daq 423
    printf ("-r range \n");
195 f9daq 424
    printf ("-n number of events\n");
425
    printf ("-m channel bit mask\n");
426
    printf ("-h trigger type (0 software, 1 fast hardware, 2 slow hardware)\n");
427
    printf ("-d trigger delay in ns\n");
428
    printf ("-f sampling frequency\n");
429
    printf ("-t trigger channel\n");
430
        printf ("-l trigger level\n");
431
        printf ("-p trigger polarity (0 positive\n");
432
    printf ("*********************************************************************************:\n");
433
    printf ("Examples:\n\n");
434
 
435
    return 0;
436
}
437
 
438
 
439
 
440
char filename[0xFF]="";
441
char rootfile[0xFF]="";
442
int  neve          =  0;
443
int  verbose       =  0;
444
 
445
void Init(int argc, char **argv){
446
   DRSParameters = drssettings::instance();
447
   char c;
448
 
449
   extern char *optarg;
450
   extern int optind;
451
   extern int optopt;
452
   while ((c = getopt (argc, argv, "a:o:v:m:n:f:d:r:h:t:p:l:")) != -1){
453
 
454
        switch (c)
455
        {
456
 
457
        case 'a':
458
            sprintf(rootfile,"%s", optarg );
459
            break;       // root output
460
 
461
        case 'o':
462
            sprintf(filename,"%s", optarg );
463
            break;       // output
464
 
465
        case 'v':
466
             verbose = atoi(optarg);
467
            break;                       // verbosity
468
        case 'm':{
469
            unsigned long ul = strtoul (optarg,NULL,0);
470
            DRSSetMask( (unsigned char)( ul & 0xF ) ) ;
471
            break;
472
        }                               // channel mask
473
        case 'n':
474
            neve =  atoi (optarg);
475
            break;                          // number of events or number of scan points
476
 
477
        case 'f':
478
            DRSSetFrequency( atoi (optarg) );
479
            break;                          // sampling frequency
480
 
481
        case 'd':
482
            DRSSetTriggerDelay(  atof (optarg) );
483
            break;                          // trigger delay
484
        case 'p':
485
            DRSSetTriggerPolarity( atoi (optarg));
486
            break;                          // trigger polarity
487
        case 'l':
488
            DRSSetTriggerLevel(atoi (optarg));
489
            break;                          // trigger level
490
 
491
 
492
        case 'r':
493
            DRSSetRange (  atof (optarg) );
494
            break;                          // range 
495
        case 'h':
496
            DRSSetTriggerType( atoi (optarg) );
497
            break;         // send sotware trigger before reading out the dat
498
        case 't':
499
            DRSSetTriggerChannel( atoi(optarg) );
500
            break;         // trigger channel
501
 
502
 
503
        case '?':
504
            if (optopt == 'c')
505
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
506
            else if (isprint (optopt))
507
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
508
            else
509
                fprintf (stderr,
510
                         "Unknown option character `\\x%x'.\n",
511
                         optopt);
512
            abort ();
513
        default:
514
            abort ();
515
        }
516
    }
517
    //for (int i=optind; i<argc; i++) data = strtoul (argv[i],NULL,0);
518
 
519
}
520
 
521
int ctrl_c=0;
522
DLLEXPORT void DRSSigInt ( int )
523
{
524
    ctrl_c = 1;
525
    printf("->>> CTRL+c !!!\n");
526
}
527
 
528
//#ifdef __CINT__
529
int main(int argc, char **argv){
530
//#else
531
//int drsread(int argc, char **argv){   
532
//#endif
533
 
534
 if (signal (SIGINT, DRSSigInt) == SIG_ERR) {
535
   perror ("sigignore");
536
 }
537
 
538
 
539
Init(argc, argv);
540
if (argc==1) { help(); return 0; }
541
 
542
FILE *fp=NULL;
543
if (strlen(filename)>0) {
544
  if (verbose) printf("Data in the file:%s\n", filename);
545
  fp=fopen(filename,"wb");
546
}
547
 
548
TFile *rfile= NULL;
549
if (strlen(rootfile)>0) {
550
  if (verbose) printf("Data in the file:%s\n", rootfile);  
551
  rfile = new TFile(rootfile,"RECREATE");
552
}
553
 
554
 
555
TCanvas *c = new TCanvas(); c->Divide(2,2);
556
c->Draw();
557
for (int i=0;i<4;i++){
558
   if (! (DRSParameters->mask & ( 0x1<<i ))  ) continue;       
559
   char name[0xff];
560
   sprintf(name,"h%d",i);
561
   h[i]=new TH2F(name,name,1024,0,204,1024,-0.6+DRSParameters->range,0.6+DRSParameters->range);
562
   c->cd(i+1); h[i]->Draw("colz");
563
 
564
}
565
 
566
 
567
 
568
//---------------------------------------
569
static unsigned char *buffer;
570
static int buffer_size = 0;
571
const int nBoards=1;
572
const int waveDepth=1024;
573
if (buffer_size == 0) {
574
         buffer_size =  4 +  nBoards * (4 + 4*(4+waveDepth*4));
575
         buffer_size += 24 + nBoards * (8 + 4*(4+waveDepth*2));
576
         buffer = (unsigned char *)malloc(buffer_size);
577
}
578
 
579
time_t t,told, tstart;
580
if (!DRSInit()){
581
  time(&tstart);
582
  told=tstart;
583
  int i=0;
584
  for (i=0; i<neve; i++) {
585
    int nb =  (DRSRead(1) == 0 && fp ) ? DRSToBuffer( buffer , i ) : 0;
586
 
587
        if (DRSTimeout) i--;
588
    if (ctrl_c) break;
589
    time(&t);
590
    if (t!=told ) {
591
                printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
592
                c->Modified(); c->Update();
593
        }      
594
    told=t;
595
// Save data    
596
        if (nb>0 && fp) fwrite(buffer, 1,nb ,fp);
597
// Plot Data
598
        for (int k=0;k<4;k++){
599
        if (! (DRSParameters->mask & ( 0x1<<k ))  ) continue;
600
        float *t=DRSGetTime(k);
601
        float *x=DRSGetWave(k);        
602
            for (int i=0 ; i<1024 ; i++) {
603
           if (verbose) printf("[%d] %d. x= %3.2f  y=%3.2f\n", k, i, t[i], x[i] );
604
           h[k]->Fill( t[i], x[i]*1e-3);
605
        }
606
        }
607
  }
608
  time(&t);
609
  printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
610
 
611
  DRSEnd();
612
}
613
//---------------------------------------
614
if (rfile !=NULL) rfile->Write();
615
if (fp) fclose(fp);
616
if (c) c->SaveAs("drsread.pdf");
617
// TApplication* theApp = new TApplication("App", NULL, NULL);
618
// theApp->Run();
619
 
620
 
621
 
622
}
623
 
207 f9daq 624
#endif