Subversion Repositories f9daq

Rev

Rev 262 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "redpitaya_gui.h"
#include <ansi_c.h>
#include <tcpsupp.h>
#include <utility.h>
#include <cvirte.h>
#include <userint.h>
#include "redpitaya_gui.h"

#include "H1D.h"


#define NBEFORE 150
#define MAXSAMPLES 16384
#define MINTRGDELAY -8192


static int panelHandle;

static unsigned int chandle = 0;
//static int tfID;
int pfreq;
static int plothandle[2]= {0,0};
static int tdcplothandle[2]= {0,0};
static int adcplothandle[2]= {0,0};
static int excludefirst[2]= {0,0};
int debug ;
int initialized = 0;
#define MAX_THREADS 10
int nsamples=0;
int adctype;
float athreshold, twin0,twin1;
float timebins[0XFFFF];
float daqtime;
double starttime;

FILE *foutput;
int outwaveforms=0;

static CmtThreadPoolHandle poolHandle = 0;
int ctrl_c=0;


int CVICALLBACK SocketCB (unsigned handle, int xType, int errCode, void *callbackData);



static int export_data (int hid) {

  char filename[0xFF],rootcmd[0xFF];
  char fname[0xFF];
  int type=0;

  GetCtrlVal(panelHandle,PANEL_EXPORTNAME,fname);
  GetCtrlVal(panelHandle,PANEL_FILETYPE,&type);

  FILE *fp;

  switch (type) {
    case 0:
    case 1:
      sprintf(filename,"%s_%d.root",fname, hid);
      fp  =fopen(filename,"wb");
      if (fp) {
        H1D_Write2File(hid,fp);
        fclose(fp);
        if (type) {
          sprintf(rootcmd ,"thisroot.bat && root.exe H1Dload.cxx(\\\"%s\\\")", filename);
          LaunchExecutable(rootcmd);

        }
        printf("Histogram %d exported to %s\n", hid, filename);
      }
      break;
    case 2:
      sprintf(filename,"%s_%d.txt",fname, hid);
      fp=fopen(filename,"w");
      if (fp) {
        for (int i=0; i<H1D_GetNbinsX(hid); i++) fprintf(fp,"%g\t%g\n", H1D_GetXBinCenter(hid,i), H1D_GetBinContent(hid,i) );
        fclose(fp);
        printf("Histogram %d exported to %s\n", hid, filename);
      }

      break;

  }


  return (0);
}


int main (int argc, char *argv[]) {
  if (InitCVIRTE (0, argv, 0) == 0)
    return -1;  /* out of memory */
  if ((panelHandle = LoadPanel (0, "redpitaya_gui.uir", PANEL)) < 0)
    return -1;


  SetStdioPort (CVI_STDIO_WINDOW);
  SetSleepPolicy(VAL_SLEEP_MORE);
  CmtNewThreadPool (MAX_THREADS,  &poolHandle);

 
  //printf("size of double = %d\n",sizeof(double));
  DisplayPanel (panelHandle);
  RunUserInterface ();
  DiscardPanel (panelHandle);
  CmtDiscardThreadPool (poolHandle);
  if (chandle!=0) DisconnectFromTCPServer (chandle);
  return 0;
}

char strbuf[0xFF];

int gLog=0;

int printf(const char *format, ...) {
  va_list aptr;
  int ret;
  FILE *flog;

  va_start(aptr, format);
  ret = vsprintf(strbuf, format, aptr);
  va_end(aptr);
  SetCtrlVal(panelHandle,PANEL_STDIO,strbuf);

  if (gLog) {
    flog = fopen ("stdio.log", "a");
    fprintf (flog, "%s", strbuf);
    fclose (flog);
  }
  return(ret);
}


int CVICALLBACK SetGraphLogYCB (int panel, int control, int event,
                                void *callbackData, int eventData1, int eventData2) {

  int cid=0;
  int logy=0;
  switch (event) {
    case EVENT_COMMIT:
      GetCtrlVal(panel,control, &logy);
      switch (control) {
        case PANEL_LOGY_1:
          cid = PANEL_TDC1;
          break;
        case PANEL_LOGY_2:
          cid = PANEL_ADC1;
          break;
        case PANEL_LOGY_3:
          cid = PANEL_TDC2;
          break;
        case PANEL_LOGY_4:
          cid = PANEL_ADC2;
          break;
      }
      if (logy) SetCtrlAttribute (panel, cid, ATTR_YMAP_MODE, VAL_LOG);
      else    SetCtrlAttribute (panel, cid, ATTR_YMAP_MODE, VAL_LINEAR);
      break;
  }
  return 0;
}

int CVICALLBACK SetGraphPropertiesCB (int panel, int control, int event,
                                      void *callbackData, int eventData1, int eventData2) {

  float min, max;
  int autoscale;
  switch (event) {
    case EVENT_COMMIT:
      GetCtrlVal(panelHandle,PANEL_MINX_5, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_5, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOY, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);

      GetCtrlVal(panelHandle,PANEL_MINX_6, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_6, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOX, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_BOTTOM_XAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_GRAPH, VAL_BOTTOM_XAXIS, VAL_MANUAL, min, max);


      GetCtrlVal(panelHandle,PANEL_MINX_7, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_7, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOY_2, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_TDC1, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_TDC1, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);

      GetCtrlVal(panelHandle,PANEL_MINX_8, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_8, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOY_3, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_ADC1, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_ADC1, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);

      GetCtrlVal(panelHandle,PANEL_MINX_9, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_9, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOY_4, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_TDC2, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_TDC2, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);

      GetCtrlVal(panelHandle,PANEL_MINX_10, &min);
      GetCtrlVal(panelHandle,PANEL_MAXX_10, &max);
      GetCtrlVal(panelHandle,PANEL_AUTOY_5, &autoscale);
      if (autoscale)
        SetAxisScalingMode (panelHandle, PANEL_ADC2, VAL_LEFT_YAXIS, VAL_AUTOSCALE, min, max);
      else
        SetAxisScalingMode (panelHandle, PANEL_ADC2, VAL_LEFT_YAXIS, VAL_MANUAL, min, max);



      break;
  }
  return 0;
}


int histoinit() {
  int nch;
  float min,max;

  GetCtrlVal(panelHandle,PANEL_NCH_1, &nch);
  GetCtrlVal(panelHandle,PANEL_MINX_1, &min);
  GetCtrlVal(panelHandle,PANEL_MAXX_1, &max);

  H1D_Init(1, "ADC ch 1","Pulse height", nch, min, max );
  H1D_SetTitleX(1,"ADC (V)");
  H1D_SetTitleY(1,"N");

  GetCtrlVal(panelHandle,PANEL_NCH_2, &nch);
  GetCtrlVal(panelHandle,PANEL_MINX_2, &min);
  GetCtrlVal(panelHandle,PANEL_MAXX_2, &max);

  H1D_Init(2, "ADC ch 2","Pulse height", nch, min, max );
  H1D_SetTitleX(2,"ADC (V)");
  H1D_SetTitleY(2,"N");

  GetCtrlVal(panelHandle,PANEL_NCH_3, &nch);
  GetCtrlVal(panelHandle,PANEL_MINX_3, &min);
  GetCtrlVal(panelHandle,PANEL_MAXX_3, &max);

  H1D_Init(3, "TDC ch 1","TDC", nch, min, max  );
  H1D_SetTitleX(3,"TDC (us)");
  H1D_SetTitleY(3,"N");

  GetCtrlVal(panelHandle,PANEL_NCH_4, &nch);
  GetCtrlVal(panelHandle,PANEL_MINX_4, &min);
  GetCtrlVal(panelHandle,PANEL_MAXX_4, &max);

  H1D_Init(4, "TDC ch 2","TDC", nch, min, max   );
  H1D_SetTitleX(4,"TDC (us)");
  H1D_SetTitleY(4,"N");

  SetCtrlAttribute  (panelHandle, PANEL_ADC1, ATTR_XNAME, H1D_GetTitleX(1) );
  SetCtrlAttribute  (panelHandle, PANEL_ADC1, ATTR_YNAME, H1D_GetTitleY(1) );
  SetCtrlAttribute  (panelHandle, PANEL_ADC2, ATTR_XNAME, H1D_GetTitleX(2) );
  SetCtrlAttribute  (panelHandle, PANEL_ADC2, ATTR_YNAME, H1D_GetTitleY(2) );

  SetCtrlAttribute  (panelHandle, PANEL_TDC1, ATTR_XNAME, H1D_GetTitleX(3) );
  SetCtrlAttribute  (panelHandle, PANEL_TDC1, ATTR_YNAME, H1D_GetTitleY(3) );
  SetCtrlAttribute  (panelHandle, PANEL_TDC2, ATTR_XNAME, H1D_GetTitleX(4) );
  SetCtrlAttribute  (panelHandle, PANEL_TDC2, ATTR_YNAME, H1D_GetTitleY(4) );
  SetGraphLogYCB( panelHandle, PANEL_LOGY_1,  EVENT_COMMIT,NULL,0,0);
  SetGraphLogYCB( panelHandle, PANEL_LOGY_2,  EVENT_COMMIT,NULL,0,0);
  SetGraphLogYCB( panelHandle, PANEL_LOGY_3,  EVENT_COMMIT,NULL,0,0);
  SetGraphLogYCB( panelHandle, PANEL_LOGY_4,  EVENT_COMMIT,NULL,0,0);

  SetGraphPropertiesCB( panelHandle, PANEL, EVENT_COMMIT,NULL,0,0);

  SetCtrlAttribute  (panelHandle, PANEL_GRAPH, ATTR_LABEL_TEXT , "sampling adc data");
  SetCtrlAttribute  (panelHandle, PANEL_GRAPH, ATTR_XNAME, "t(us)" );
  SetCtrlAttribute  (panelHandle, PANEL_GRAPH, ATTR_YNAME, "U(V)" );

  GetCtrlVal(panelHandle,PANEL_TWIN0, &twin0);
  GetCtrlVal(panelHandle,PANEL_TWIN1, &twin1);
  GetCtrlVal(panelHandle,PANEL_ADCTYPE, &adctype);
  GetCtrlVal(panelHandle,PANEL_ITRGLEVEL  , &athreshold);
  return 0;
}

int analyse(int nb, unsigned char *cdata, int *info, int *ninfo) {

  int   *ibuf = (int *)cdata;
  float *fbuf = (float *)cdata;
  float *finfo = (float *)info;
  int neve=0;
  int *data = (ibuf+3);
  int nr=0;
  static float adc = 10000;
  static float qdc = 0;
  *ninfo = 0;
  printf("Run HDR LEN=%d NEVE=%d dt=%f adc=%f qdc=%f\n", ibuf[0],ibuf[1],fbuf[2],adc,qdc);
  daqtime += fbuf[2];

  SetCtrlVal(panelHandle, PANEL_CDAQTIME,daqtime);
  SetCtrlVal(panelHandle, PANEL_CTIME, Timer() -starttime);
  daqtime  =0;
  while (nr<nb) {

    int recid   = *data++;
    int chmask  = *data++;
    nr +=8;
    if (recid!=0x2) continue;
    for (int id=0; id<2; id++) {
      if ( !(chmask & (1 << id)) ) {
        if (neve % pfreq == 0)
          if (plothandle[id]) {
            DeleteGraphPlot (panelHandle, PANEL_GRAPH, plothandle[id], VAL_IMMEDIATE_DRAW);
            plothandle[id] = 0;
          }
        continue;
      }
      if ( id != *(data++) ) printf("Error\n");

      int nsamples = *(data++);
      if (nsamples<=0 || nsamples>16*1024) {
        printf("Error nsamples %d\n", nsamples);
        return -1;
      }
      float *fdata = (float *) data;
      if ( nsamples>0  && neve % pfreq == 0) {
        const int col[4]= {VAL_RED,VAL_GREEN,VAL_BLUE,VAL_WHITE};
        if (plothandle[id]) DeleteGraphPlot (panelHandle, PANEL_GRAPH, plothandle[id], VAL_IMMEDIATE_DRAW);

        plothandle[id] = PlotXY (panelHandle, PANEL_GRAPH, timebins, fdata, nsamples, VAL_FLOAT, VAL_FLOAT, VAL_FAT_LINE, VAL_NO_POINT, VAL_SOLID, 1, col[id]);

        H1D_Draw(1,panelHandle,PANEL_ADC1,&adcplothandle[0]);
        H1D_Draw(2,panelHandle,PANEL_ADC2,&adcplothandle[1]);
        H1D_Draw(3,panelHandle,PANEL_TDC1,&tdcplothandle[0]);
        H1D_Draw(4,panelHandle,PANEL_TDC2,&tdcplothandle[1]);

        if (debug) for (int k=0; k<10; k++) printf("%d %d (%f , %d)\n", id,k, timebins[k],data[k]);
      }

      nr+=8;
      adc=10000;
      qdc=0;
      int nqdc=0;
      int ntdc=0;
      for (int k=1; k<nsamples; k++) {
        float t =timebins[k];
        float tp=timebins[k-1];
        if (fdata[k] < adc) adc = fdata[k];
        if (t>twin0 && t<twin1 ) {
          nqdc++;
          qdc+=fdata[k];
        }
        if (fdata[k]< athreshold && fdata[k-1]> athreshold) {
          double t0= tp+(athreshold-fdata[k-1])/(fdata[k]-fdata[k-1])* (t-tp);
          if (ntdc>0) H1D_Fill(3+id, t0,1);
          if (ntdc==0 && !excludefirst[id]) H1D_Fill(3+id, t0,1);
          finfo[*ninfo+4+ntdc]=t0;
          ntdc++;
        }
      }
      if (nqdc) qdc/=nqdc;
      //printf("adc %f qdc %f\n", adc,qdc);
      info[*ninfo]=(ntdc+4)*sizeof(int); // len
      info[*ninfo+1]=id | 0xF0000000;    // recid
      finfo[*ninfo+2]=adc;
      finfo[*ninfo+3]=qdc;
      *ninfo+= ntdc+4;

      if (adctype)
        H1D_Fill(1+id, -adc,1);
      else
        H1D_Fill(1+id, -qdc,1);

      nr+=4*nsamples;
      data+=nsamples;
    }
    recid      = *data++;
    int event  = *data++;
    nr+=8;
    neve++;
    if (debug) printf("recid %d event %d\n",recid, event );
  }

  return neve;
}

const int maxlen = 100000000;
unsigned char data[maxlen];
int *idata = (int *) &data[0];


int evinfo[maxlen];
int CVICALLBACK SocketCB (unsigned handle, int xType, int errCode, void *callbackData) {

  int nb = 0 ;
  static int event = 0;
  static int ncalls = 0;
  static time_t t0, t1;
  time(&t0);
  switch (xType) {
    case TCP_DISCONNECT:
      printf("TCP_DISCONNECT ErrorString %s\n",GetTCPErrorString(errCode));
      printf("TCP_DISCONNECT SystemErrorString %s\n",GetTCPSystemErrorString());

      chandle = 0;
      break;
    case TCP_DATAREADY: {
      int  hdr[2]= {0,0};
      nb = ClientTCPRead(handle,&hdr[0],8,1000);

      int size = hdr[1] - 8;
      if (size>maxlen) size=maxlen;
      nb = 0;
      while (nb < size) {
        int retval = ClientTCPRead(handle,&data[nb],size-nb,1000);
        if (retval<1) break;
        nb += retval;
      }
      if (debug) printf("Received RECID %d HDRLEN %d == read %d\n", hdr[0], size, nb);

      int ninfo=0;
      switch (hdr[0]) {
        case 0:
          data[nb]=0;
          printf("%s\n",data);
          break;
        case 1:// read

          GetCtrlVal(panelHandle,PANEL_CEVE     , &event);
          GetCtrlVal(panelHandle,PANEL_NTOTAL   , &ncalls);

          event += analyse(nb,data, evinfo, &ninfo);
          if (foutput) {
            if (outwaveforms) fwrite(data, 1, nb, foutput);
            fwrite(evinfo, 1, ninfo*sizeof(int), foutput);
            time(&t1);
            if ((t1-t0)>10000) {
              for (int i=0; i<4; i++) H1D_Write2File(1+i,foutput);

              time(&t0);
            }
          }
          SetCtrlVal(panelHandle,PANEL_CEVE     , event);
          if (event>=ncalls) StartCB (panelHandle, PANEL_START, EVENT_COMMIT, NULL,1,0);

          break;
        default:
          printf("Unknown command = %d\n", hdr[0]);
          break;
      }
      break;

    }
  }
  return 0;
}

int rpdecimation(int i) {

  switch (i) {
    case 1:
      return 0;
    case 8:
      return 1;
    case 64:
      return 2;
    case 1024:
      return 3;
    case 8192:
      return 4;
    case 65536:
      return 5;
  }
  return 0;

}

int CVICALLBACK StartCB (int panel, int control, int event,
                         void *callbackData, int eventData1, int eventData2) {
  char ip[0xFF];
  int hdr[0xFF];
  char filename[0xFF];
  unsigned short *sbuff = (unsigned short *)&hdr[5] ;
  unsigned char  *cbuff = (unsigned char *)&sbuff[3] ;
  int imask[2];
  unsigned char mask;
  unsigned char trigger;
  unsigned short nsamples;
  int delay;
  int nbefore;
  unsigned int decimation;
  unsigned short neve;
  int output;
  switch (event) {
    case EVENT_COMMIT: {
      GetCtrlVal(panel,PANEL_IP, ip);
      GetCtrlVal(panel,PANEL_TRIGGER, &trigger);
      GetCtrlVal(panel,PANEL_SAMPLES, &nsamples);
      GetCtrlVal(panel,PANEL_DECIMATION,&decimation);
      GetCtrlVal(panel,PANEL_NEVE   , &neve);
      GetCtrlVal(panel,PANEL_CH0    , &imask[0] );
      GetCtrlVal(panel,PANEL_CH1    , &imask[1]  );
      GetCtrlVal(panel,PANEL_PFREQ  , &pfreq);
      GetCtrlVal(panel,PANEL_DEBUG  , &debug);
      GetCtrlVal(panel,PANEL_NBEFORE  , &nbefore);
      GetCtrlVal(panel,PANEL_ENABLEDOUTPUT, &output);
      GetCtrlVal(panel,PANEL_OUTWAVE, &outwaveforms);
      GetCtrlVal(panel,PANEL_FILENAME, filename);

      delay= MINTRGDELAY + nsamples - nbefore + 1;

      mask = 0;
      for (int i=0; i<2; i++) {
        if (imask[i]) mask |= (1<<i);
      }

      double level =0;
      GetCtrlVal(panel,PANEL_TRGLEVEL , &level);


      switch (control) {
        case PANEL_CONNECT: {
          int state;
          GetCtrlVal(panel,PANEL_CONNECT, &state);
          if (state) {
            ConnectToTCPServerEx (&chandle, 9930, ip, SocketCB, NULL, 0, TCP_ANY_LOCAL_PORT);
          } else {
            if (chandle!=0) DisconnectFromTCPServer (chandle);
            chandle = 0;
          }
        }
        break;
        case PANEL_START: {
          int state;
          GetCtrlVal(panel,PANEL_START, &state);
          GetCtrlVal(panel,PANEL_EXCLUDE_1, &excludefirst[0]);
          GetCtrlVal(panel,PANEL_EXCLUDE_2, &excludefirst[1]);
          if (state && eventData1==0) {
            histoinit();
            starttime=Timer();
            daqtime  =0;
            /* decimation n (=1,8,64...) : frequency = 125/n MHz*/
            for (int i=0; i<nsamples; i++) timebins[i]=(i-nbefore)* (float)decimation /125.;
            if (output) foutput = fopen(filename, "wb");
            printf("decimation %d\n", decimation);
            SetCtrlVal(panel,PANEL_CEVE  , 0);
            ctrl_c=0;
            hdr[0] = 0;
            hdr[1] = 7*sizeof(int);
            hdr[2] = delay;
            hdr[3] = rpdecimation(decimation);
            hdr[4] = level * 1000;
            sbuff[0] = neve;
            sbuff[1] = nsamples;
            sbuff[2] = 1000; //tout
            cbuff[0] = trigger;
            cbuff[1] = mask;
            ClientTCPWrite(chandle,&hdr[0],hdr[1],5000);  // acquire
          } else {
            hdr[0] = 1;
            hdr[1] = 2*sizeof(int);
            ClientTCPWrite(chandle,&hdr[0],hdr[1],5000);  // stop the transfer
            printf("INFO Stopping the acquisition\n");
            SetCtrlVal(panel,PANEL_START, 0);
            if (foutput) fclose(foutput);
            foutput=NULL;
          }
          break;
        }
        default:
          printf("Unknown command\n");
          break;
      }




      ProcessSystemEvents ();
      break;
    }
  }
  return 0;
}


int CVICALLBACK ExitCB (int panel, int control, int event,
                        void *callbackData, int eventData1, int eventData2) {
  switch (event) {
    case EVENT_COMMIT:
      QuitUserInterface(0);
      break;
  }
  return 0;
}



int CVICALLBACK ExportCB (int panel, int control, int event,
                          void *callbackData, int eventData1, int eventData2) {
  int hid=0;
  switch (event) {
    case EVENT_COMMIT:
      switch (control) {
        case PANEL_EXPORT_1:
          hid=1;
          break;
        case PANEL_EXPORT_2:
          hid=2;
          break;
        case PANEL_EXPORT_3:
          hid=3;
          break;
        case PANEL_EXPORT_4:
          hid=4;
          break;

      }
      export_data(hid);
      break;
  }
  return 0;
}

int CVICALLBACK ResetCB (int panel, int control, int event,
                         void *callbackData, int eventData1, int eventData2) {
  switch (event) {
    case EVENT_COMMIT:

      for (int i=1; i<=4; i++) H1D_Clear(i);
      break;
  }
  return 0;
}