Subversion Repositories f9daq

Rev

Rev 207 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.  
  113. DLLEXPORT int DRSCalibrateTiming( )
  114. {
  115.    DRSBoard *b;
  116.    if (drs == NULL) drs = new DRS();
  117.    if (!drs) return -1;
  118.    DRSParameters = drssettings::instance();
  119.    
  120.    //fCalMode = 2;
  121.    if (drs->GetNumberOfBoards() ) {
  122.         /* continue working with first board only */
  123.      b = drs->GetBoard(0);
  124.      
  125.       if (b->GetFirmwareVersion() < 13279)
  126.          printf("Firmware revision 13279 or later\nrequired for timing calibration\n");
  127.       else if (b->GetInputRange() != 0)
  128.          printf("Timing calibration can only be done\nat the -0.5V to +0.5V input range\n");
  129.  
  130.       else {
  131.  
  132.  
  133.          /* remember current settings */
  134.          double acalVolt   = b->GetAcalVolt();
  135.          int    acalMode   = b->GetAcalMode();
  136.          int    tcalFreq   = b->GetTcalFreq();
  137.          int    tcalLevel  = b->GetTcalLevel();
  138.          int    tcalSource = b->GetTcalSource();
  139.          int    flag1      = b->GetTriggerEnable(0);
  140.          int    flag2      = b->GetTriggerEnable(1);
  141.          int    trgSource  = b->GetTriggerSource();
  142.          int    trgDelay   = b->GetTriggerDelay();
  143.          double range      = b->GetInputRange();
  144.          int    config     = b->GetReadoutChannelConfig();
  145.  
  146.      
  147.          int status = b->CalibrateTiming(NULL);
  148.  
  149.          if (!status)
  150.             printf("Error performing timing calibration, please check waveforms and redo voltage calibration.\n");
  151.          else
  152.            printf("Timing calibration successfully finished.\n");
  153.                      
  154.  
  155.          /* restore old values */
  156.          b->EnableAcal(acalMode, acalVolt);
  157.          b->EnableTcal(tcalFreq, tcalLevel);
  158.          b->SelectClockSource(tcalSource);
  159.          b->EnableTrigger(flag1, flag2);
  160.          b->SetTriggerSource(trgSource);
  161.          b->SetTriggerDelayPercent(trgDelay);
  162.          b->SetInputRange(range);
  163.          b->SetChannelConfig(config, 8, 8);
  164.  
  165.          if (b->GetBoardType() == 5)
  166.             b->SetTranspMode(1); // Evaluation board with build-in trigger
  167.          else
  168.             b->SetTranspMode(1); // VPC Mezzanine board
  169.  
  170.          return status;
  171.       }
  172.      
  173.    }
  174.    return -1;
  175. }
  176.  
  177.  
  178. DLLEXPORT int DRSInit()
  179. {
  180.  
  181.    DRSBoard *b;
  182.    /* do drsinitial scan */
  183.    if (drs == NULL) drs = new DRS();
  184.    if (!drs) return -1;
  185.    DRSParameters = drssettings::instance();
  186.    
  187.    /* show any found board(s) */
  188.    for (int i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  189.       b = drs->GetBoard(i);
  190.       printf("Found DRS4 evaluation board, serial #%d, firmware revision %d\n",
  191.          b->GetBoardSerialNumber(), b->GetFirmwareVersion());
  192.    }
  193.  
  194.    /* exit if no board found */
  195.    int nBoards = drs->GetNumberOfBoards();
  196.    if (nBoards == 0) {
  197.       printf("No DRS4 evaluation board found\n");
  198.       return -2;
  199.    }
  200.  
  201.    /* continue working with first board only */
  202.    b = drs->GetBoard(0);
  203.  
  204.    /* drsinitialize board */
  205.    b->Init();
  206.  
  207.    /* set sampling frequency default 5 */
  208.    b->SetFrequency(DRSParameters->sampling_frequency, true);
  209.  
  210.    /* enable transparent mode needed for analog trigger */
  211.    b->SetTranspMode(1);
  212.  
  213.    /* set input range to -0.5V ... +0.5V -> range=0 */
  214.    b->SetInputRange(DRSParameters->range);
  215.  
  216.    /* use following line to set range to 0..1V */
  217.    //b->SetInputRange(0.5);
  218.    
  219.    /* use following line to turn on the internal 100 MHz clock connected to all channels  */
  220.    //b->EnableTcal(1);
  221.  
  222.    /* kaj je to ....
  223.     // Set domino mode
  224.    // mode == 0: single sweep
  225.    // mode == 1: run continously -- default
  226.    b->SetDominoMode(1);
  227.     // Set domino activity
  228.    // mode == 0: stop during readout  
  229.    // mode == 1: keep domino wave running -- default
  230.    //  
  231.    b->SetDominoActive(1);
  232.    
  233.    // Set readout mode
  234.    // mode == 0: start from first bin  -- default
  235.    // mode == 1: start from domino stop
  236.    //
  237.    b->SetReadoutMode(1);
  238.    */
  239.    
  240.    /* use following lines to enable hardware trigger on CH1 at 50 mV positive edge */
  241.    printf("Board Type:%d\n",b->GetBoardType() );
  242.    if (b->GetBoardType() >= 8) {        // Evaluaiton Board V4&5
  243.      
  244.       b->EnableTrigger(DRSParameters->trigger_type, 0);           // enable hardware trigger - 1 fast trigger, 2 slow trigger, 0 disable hw trigger
  245.       b->SetTriggerSource(1<<DRSParameters->trigger_channel);        // set CH1 as source // simple or of single channel
  246.    } else if (b->GetBoardType() == 7) { // Evaluation Board V3
  247.       b->EnableTrigger(0, 1);           // lemo off, analog trigger on
  248.       b->SetTriggerSource(0);           // use CH1 as source
  249.    }
  250.    b->SetTriggerLevel(DRSParameters->trigger_level);            // 0.05 V
  251.    b->SetTriggerPolarity(DRSParameters->trigger_polarity);        // positive edge
  252.    
  253.    /* use following lines to set individual trigger elvels */
  254.    //b->SetIndividualTriggerLevel(1, 0.1);
  255.    //b->SetIndividualTriggerLevel(2, 0.2);
  256.    //b->SetIndividualTriggerLevel(3, 0.3);
  257.    //b->SetIndividualTriggerLevel(4, 0.4);
  258.    //b->SetTriggerSource(15);
  259.    
  260.    b->SetTriggerDelayNs( DRSParameters->trigger_delay);             // zero ns trigger delay
  261.    
  262.    /* use following lines to enable the external trigger */
  263.    //if (b->GetBoardType() == 8) {     // Evaluaiton Board V4
  264.    //   b->EnableTrigger(1, 0);           // enable hardware trigger
  265.    //   b->SetTriggerSource(1<<4);        // set external trigger as source
  266.    //} else {                          // Evaluation Board V3
  267.    //   b->EnableTrigger(1, 0);           // lemo on, analog trigger off
  268.    // }
  269.  
  270.    return 0;
  271.  
  272.  
  273. }
  274.  
  275. static float DRSTimeArray[8][1024];
  276. static float DRSWaveArray[8][1024];
  277.  
  278. DLLEXPORT float * DRSGetTime(int ch){ return DRSTimeArray[ch];}
  279. DLLEXPORT float * DRSGetWave(int ch){ return DRSWaveArray[ch];}
  280.  
  281. DLLEXPORT int DRSRead( int DRStimer)
  282. {
  283.  
  284.    DRSBoard *b = drs->GetBoard(0);
  285.  
  286.      
  287.  
  288.       /* wait for trigger */
  289.          
  290.  
  291.       int tout=1000; /* timeout in mili seconds */
  292.       DRSTimeout=0;
  293.  
  294.       if (DRStimer) start_timer(tout, &DRSSetTimeout);
  295.        
  296.           /* start board (activate domino wave) */
  297.       b->StartDomino();
  298.            
  299.       if (!DRSParameters->trigger_type) b->SoftTrigger();
  300.          
  301.       while (b->IsBusy()){
  302.                        
  303.         if (DRSTimeout) {
  304.           printf("Waiting for Trigger.. at line %d\n",  __LINE__);
  305.  
  306.           if (DRStimer) stop_timer();
  307.          
  308.           return -1;
  309.         }
  310.           };
  311.      
  312.  
  313.       if (DRStimer) stop_timer();
  314.  
  315.    
  316.        
  317.       /* read all waveforms */
  318.       b->TransferWaves(0, 8);
  319.  
  320.  
  321.       for (int k=0;k<4;k++){
  322.         if (! (DRSParameters->mask & ( 0x1<<k ))  ) continue;
  323.       /* Note: On the evaluation board input #1 is connected to channel 0 and 1 of
  324.        the DRS chip, input #2 is connected to channel 2 and 3 and so on. So to
  325.        get the input #2 we have to read DRS channel #2, not #1. */
  326.  
  327.       /* read time (X) array of k-th channel in ns and waveform (Y) array of k-th channel in mV */
  328.         b->GetTime(0, 2*k, b->GetTriggerCell(DRSParameters->trigger_channel), DRSTimeArray[k]);
  329.         b->GetWave(0, 2*k, DRSWaveArray[k]);
  330.        
  331.          
  332.       }
  333.  
  334.   return 0;    
  335. }
  336.  
  337. DLLEXPORT int DRSEnd(){
  338.    
  339.    /* delete DRS object -> close USB connection */
  340.    if (drs) delete drs;
  341.    drs = NULL;
  342.    return 0;
  343. }
  344.  
  345.  
  346.  
  347. DLLEXPORT int DRSToBuffer( unsigned char *p, int m_evSerial  )
  348. {
  349.  
  350.    unsigned short d;
  351.    float t;
  352.    unsigned char *p0 = p;
  353.  
  354.    int m_nBoards    = drs->GetNumberOfBoards();
  355.    int m_waveDepth  = 1024 ;// 2048
  356.    int m_inputRange = drs->GetBoard(0)->GetInputRange();  
  357.    time_t rawtime;
  358.    time ( &rawtime );
  359.    struct tm m_evTimestamp;
  360.    m_evTimestamp = *(localtime ( &rawtime ));
  361.    struct timeval mtime;
  362.    gettimeofday(&mtime, NULL);
  363.      
  364.       if (m_evSerial == 0) {
  365.                  memcpy(p, "DRS2", 4); // File identifier and version
  366.          p += 4;
  367.          // time calibration header
  368.                  memcpy(p, "TIME", 4);
  369.          p += 4;
  370.          for (int b=0 ; b<m_nBoards ; b++) {
  371.             // store board serial number
  372.             sprintf((char *)p, "B#");
  373.             p += 2;
  374.             *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
  375.             p += sizeof(unsigned short);
  376.  
  377.             for (int i=0 ; i<4 ; i++) {
  378.                if (DRSParameters->mask & (0x1<<i)) {
  379.                   sprintf((char *)p, "C%03d", i+1);
  380.                   p += 4;
  381.                   float tcal[2048];
  382.                   drs->GetBoard(b)->GetTimeCalibration(0, i*2, 0, tcal, 0);
  383.                   for (int j=0 ; j<m_waveDepth ; j++) {
  384.                      // save binary time as 32-bit float value
  385.                      if (m_waveDepth == 2048) {
  386.                         t = (tcal[j]+tcal[j+1])/2;
  387.                         j++;
  388.                      } else
  389.                         t = tcal[j];
  390.                      *(float *)p = t;
  391.                      p += sizeof(float);
  392.                   }
  393.                }
  394.             }
  395.          }
  396.       }
  397.  
  398.  
  399.  
  400.       memcpy(p, "EHDR", 4);
  401.       p += 4;
  402.       *(int *)p = m_evSerial;
  403.       p += sizeof(int);
  404.       *(unsigned short *)p = m_evTimestamp.tm_year;
  405.       p += sizeof(unsigned short);
  406.       *(unsigned short *)p = m_evTimestamp.tm_mon;
  407.       p += sizeof(unsigned short);
  408.       *(unsigned short *)p = m_evTimestamp.tm_mday;
  409.       p += sizeof(unsigned short);
  410.       *(unsigned short *)p = m_evTimestamp.tm_hour;
  411.       p += sizeof(unsigned short);
  412.       *(unsigned short *)p = m_evTimestamp.tm_min;
  413.       p += sizeof(unsigned short);
  414.       *(unsigned short *)p = m_evTimestamp.tm_sec;
  415.       p += sizeof(unsigned short);
  416.       *(unsigned short *)p = mtime.tv_usec/1000;
  417.       p += sizeof(unsigned short);
  418.       *(unsigned short *)p = (unsigned short)(m_inputRange * 1000); // range
  419.       p += sizeof(unsigned short);
  420.      
  421.       int b=0; // only for board 0
  422.  
  423.          // store board serial number
  424.          sprintf((char *)p, "B#");
  425.          p += 2;
  426.          *(unsigned short *)p = drs->GetBoard(b)->GetBoardSerialNumber();
  427.          p += sizeof(unsigned short);
  428.          
  429.          // store trigger cell
  430.          sprintf((char *)p, "T#");
  431.          p += 2;
  432.          *(unsigned short *)p = drs->GetBoard(b)->GetTriggerCell(DRSParameters->trigger_channel);
  433.          p += sizeof(unsigned short);
  434.          
  435.          for (int i=0 ; i<4 ; i++) {
  436.             if (DRSParameters->mask & (0x1<<i)) {
  437.                sprintf((char *)p, "C%03d", i+1);
  438.                p += 4;
  439.                            unsigned int s = drs->GetBoard(b)->GetScaler(i);
  440.                memcpy(p, &s, sizeof(int));
  441.                p += sizeof(int);
  442.                for (int j=0 ; j<m_waveDepth ; j++) {
  443.                   // save binary date as 16-bit value:
  444.                   // 0 = -0.5V,  65535 = +0.5V    for range 0
  445.                   // 0 = -0.05V, 65535 = +0.95V   for range 0.45
  446.                   if (m_waveDepth == 2048) {
  447.                      // in cascaded mode, save 1024 values as averages of the 2048 values
  448.                      d = (unsigned short)(((DRSWaveArray[i][j]+DRSWaveArray[i][j+1])/2000.0 - m_inputRange + 0.5) * 65535);
  449.                      *(unsigned short *)p = d;
  450.                      p += sizeof(unsigned short);
  451.                      j++;
  452.                   } else {
  453.                      d = (unsigned short)((DRSWaveArray[i][j]/1000.0 - m_inputRange + 0.5) * 65535);
  454.                      *(unsigned short *)p = d;
  455.                      p += sizeof(unsigned short);
  456.                   }
  457.                }
  458.             }
  459.          }
  460.    
  461.    return (p-p0); // return number of bytes
  462. }
  463.  
  464.  
  465.  
  466. #ifdef MAIN
  467.  
  468.  
  469.  
  470. #include "XGetopt.h"
  471. #include "getopt.h"
  472.  
  473. TH2F *h[4];
  474.  
  475. typedef struct {
  476.    char           recid[4];
  477.    unsigned int posx, posy, posz;
  478.    unsigned int iposx, iposy, iposz;
  479. } POSREC;
  480.  
  481.  
  482. int help() {
  483.     printf ("*********************************************************************************:\n");
  484.     printf ("Usage: Read of the DRS4 PSI board and dump of the waveforms in the file:\n\n");
  485.     printf ("Arguments: \n");
  486.     printf ("-v verbosity \n");
  487.     printf ("-a output rootfile \n");
  488.     printf ("-o output filename \n");
  489.     printf ("-r range \n");
  490.     printf ("-n number of events\n");
  491.     printf ("-m channel bit mask\n");
  492.     printf ("-h trigger type (0 software, 1 fast hardware, 2 slow hardware)\n");
  493.     printf ("-d trigger delay in ns\n");
  494.     printf ("-f sampling frequency\n");
  495.     printf ("-t trigger channel\n");
  496.         printf ("-l trigger level\n");
  497.         printf ("-p trigger polarity (0 positive\n");
  498.     printf ("*********************************************************************************:\n");
  499.     printf ("Examples:\n\n");
  500.    
  501.     return 0;
  502. }
  503.  
  504.  
  505.  
  506. char filename[0xFF]="";
  507. char rootfile[0xFF]="";
  508. int  neve          =  0;
  509. int  verbose       =  0;
  510.  
  511. void Init(int argc, char **argv){
  512.    DRSParameters = drssettings::instance();
  513.    char c;
  514.    
  515.    extern char *optarg;
  516.    extern int optind;
  517.    extern int optopt;
  518.    while ((c = getopt (argc, argv, "a:o:v:m:n:f:d:r:h:t:p:l:")) != -1){
  519.  
  520.         switch (c)
  521.         {
  522.  
  523.         case 'a':
  524.             sprintf(rootfile,"%s", optarg );
  525.             break;       // root output
  526.  
  527.         case 'o':
  528.             sprintf(filename,"%s", optarg );
  529.             break;       // output
  530.  
  531.         case 'v':
  532.              verbose = atoi(optarg);
  533.             break;                       // verbosity
  534.         case 'm':{
  535.             unsigned long ul = strtoul (optarg,NULL,0);
  536.             DRSSetMask( (unsigned char)( ul & 0xF ) ) ;
  537.             break;
  538.         }                               // channel mask
  539.         case 'n':
  540.             neve =  atoi (optarg);
  541.             break;                          // number of events or number of scan points
  542.  
  543.         case 'f':
  544.             DRSSetFrequency( atoi (optarg) );
  545.             break;                          // sampling frequency
  546.  
  547.         case 'd':
  548.             DRSSetTriggerDelay(  atof (optarg) );
  549.             break;                          // trigger delay
  550.         case 'p':
  551.             DRSSetTriggerPolarity( atoi (optarg));
  552.             break;                          // trigger polarity
  553.         case 'l':
  554.             DRSSetTriggerLevel(atoi (optarg));
  555.             break;                          // trigger level
  556.  
  557.  
  558.         case 'r':
  559.             DRSSetRange (  atof (optarg) );
  560.             break;                          // range
  561.         case 'h':
  562.             DRSSetTriggerType( atoi (optarg) );
  563.             break;         // send sotware trigger before reading out the dat
  564.         case 't':
  565.             DRSSetTriggerChannel( atoi(optarg) );
  566.             break;         // trigger channel
  567.  
  568.  
  569.         case '?':
  570.             if (optopt == 'c')
  571.                 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  572.             else if (isprint (optopt))
  573.                 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
  574.             else
  575.                 fprintf (stderr,
  576.                          "Unknown option character `\\x%x'.\n",
  577.                          optopt);
  578.             abort ();
  579.         default:
  580.             abort ();
  581.         }
  582.     }
  583.     //for (int i=optind; i<argc; i++) data = strtoul (argv[i],NULL,0);
  584.  
  585. }
  586.  
  587. int ctrl_c=0;
  588. DLLEXPORT void DRSSigInt ( int )
  589. {
  590.     ctrl_c = 1;
  591.     printf("->>> CTRL+c !!!\n");
  592. }
  593.  
  594. //#ifdef __CINT__
  595. int main(int argc, char **argv){
  596. //#else
  597. //int drsread(int argc, char **argv){  
  598. //#endif
  599.  
  600.  if (signal (SIGINT, DRSSigInt) == SIG_ERR) {
  601.    perror ("sigignore");
  602.  }
  603.  
  604.  
  605. Init(argc, argv);
  606. if (argc==1) { help(); return 0; }
  607.  
  608. FILE *fp=NULL;
  609. if (strlen(filename)>0) {
  610.   if (verbose) printf("Data in the file:%s\n", filename);
  611.   fp=fopen(filename,"wb");
  612. }
  613.  
  614. TFile *rfile= NULL;
  615. if (strlen(rootfile)>0) {
  616.   if (verbose) printf("Data in the file:%s\n", rootfile);  
  617.   rfile = new TFile(rootfile,"RECREATE");
  618. }
  619.  
  620.  
  621. TCanvas *c = new TCanvas(); c->Divide(2,2);
  622. c->Draw();
  623. for (int i=0;i<4;i++){
  624.    if (! (DRSParameters->mask & ( 0x1<<i ))  ) continue;       
  625.    char name[0xff];
  626.    sprintf(name,"h%d",i);
  627.    h[i]=new TH2F(name,name,1024,0,204,1024,-0.6+DRSParameters->range,0.6+DRSParameters->range);
  628.    c->cd(i+1); h[i]->Draw("colz");
  629.    
  630. }
  631.  
  632.  
  633.  
  634. //---------------------------------------
  635. static unsigned char *buffer;
  636. static int buffer_size = 0;
  637. const int nBoards=1;
  638. const int waveDepth=1024;
  639. if (buffer_size == 0) {
  640.          buffer_size =  4 +  nBoards * (4 + 4*(4+waveDepth*4));
  641.          buffer_size += 24 + nBoards * (8 + 4*(4+waveDepth*2));
  642.          buffer = (unsigned char *)malloc(buffer_size);
  643. }
  644.    
  645. time_t t,told, tstart;
  646. if (!DRSInit()){
  647.   time(&tstart);
  648.   told=tstart;
  649.   int i=0;
  650.   for (i=0; i<neve; i++) {
  651.     int nb =  (DRSRead(1) == 0 && fp ) ? DRSToBuffer( buffer , i ) : 0;
  652.        
  653.         if (DRSTimeout) i--;
  654.     if (ctrl_c) break;
  655.     time(&t);
  656.     if (t!=told ) {
  657.                 printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
  658.                 c->Modified(); c->Update();
  659.         }      
  660.     told=t;
  661. // Save data   
  662.         if (nb>0 && fp) fwrite(buffer, 1,nb ,fp);
  663. // Plot Data
  664.         for (int k=0;k<4;k++){
  665.         if (! (DRSParameters->mask & ( 0x1<<k ))  ) continue;
  666.         float *t=DRSGetTime(k);
  667.         float *x=DRSGetWave(k);        
  668.             for (int i=0 ; i<1024 ; i++) {
  669.            if (verbose) printf("[%d] %d. x= %3.2f  y=%3.2f\n", k, i, t[i], x[i] );
  670.            h[k]->Fill( t[i], x[i]*1e-3);
  671.         }
  672.         }
  673.   }
  674.   time(&t);
  675.   printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,int(t-tstart), ctime(&t));
  676.  
  677.   DRSEnd();
  678. }
  679. //---------------------------------------
  680. if (rfile !=NULL) rfile->Write();
  681. if (fp) fclose(fp);
  682. if (c) c->SaveAs("drsread.pdf");
  683. // TApplication* theApp = new TApplication("App", NULL, NULL);
  684. // theApp->Run();
  685.  
  686.  
  687.    
  688. }
  689.  
  690. #endif
  691.