Subversion Repositories f9daq

Rev

Rev 203 | Go to most recent revision | 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. 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.                  memcpy(p, "DRS2", 4); // File identifier and version
  300.          p += 4;
  301.          // time calibration header
  302.                  memcpy(p, "TIME", 4);
  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;
  373.                            unsigned int s = drs->GetBoard(b)->GetScaler(i);
  374.                memcpy(p, &s, sizeof(int));
  375.                p += sizeof(int);
  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");
  423.     printf ("-r range \n");
  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.  
  624. #endif
  625.