Subversion Repositories f9daq

Rev

Rev 198 | 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.          // 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");
  419.     printf ("-r range \n");
  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