#include "H2D.h"
 
#include "H1D.h"
 
#include "inifile.h"
 
#include <utility.h>
 
#include <ansi_c.h>
 
#include <cvirte.h>
 
#include <userint.h>
 
#include "petdemo_uir.h"
 
 
 
#include "daq.h"
 
#include "PETProjDataMgr.h"
 
#include <math.h>
 
 
 
#define uSMC_USB
 
#ifdef uSMC_USB
 
#  include "uSMC.h"
 
#  define uSMC_SERIAL "0000000000005660"
 
const char serials[3][16]= {uSMC_SERIAL};
 
#endif /* uSMC_USB */
 
 
 
static int node;
 
static int CurPos = 0;
 
 
 
int p1;
 
#define MAX_THREADS 10
 
static CmtThreadPoolHandle poolHandle = 0;
 
int ctrl_c=0;
 
int daq_on=0;
 
int gadcchannel;
 
static int tfID;
 
static int controlID;
 
static int plothandle[0xFF]; 
 
char strbuf[0xFF];
 
 
 
int gLog=0;
 
 
 
 
 
 
 
int printf(const char *format
, ...
) {  
        va_list aptr;
 
        int ret;
 
        FILE *flog;
 
 
 
        SetCtrlVal(p1,P1_STDIO,strbuf);
 
 
 
        if (gLog) {
 
                flog 
= fopen ("stdio.log", "a"); 
        }
 
        return(ret);
 
}
 
 
 
void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle,
 
                                                                                                                         CmtThreadFunctionID functionID, unsigned int event,
 
                                                                                                                         int value, void *callbackData  ) {
 
 
 
        daq_on=0;
 
        //SetDimming(0);
 
        return ;
 
 
 
}
 
 
 
 
 
 
 
 
 
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
                                                                                         LPSTR lpszCmdLine, int nCmdShow) {
 
        if (InitCVIRTE (hInstance, 0, 0) == 0)
 
                return -1;      /* out of memory */
 
        if ((p1 = LoadPanel (0, "petdemo_uir.uir", P1)) < 0)
 
                return -1;
 
        SetStdioPort (CVI_STDIO_WINDOW);
 
        SetSleepPolicy(VAL_SLEEP_MORE);
 
        CmtNewThreadPool (MAX_THREADS,  &poolHandle);
 
#ifdef uSMC_USB
 
        uSMC_Open();
 
        node=uSMC_FindSerial(serials)+1;
 
        uSMC_Init(node,1);
 
        SetCtrlVal(p1, P1_STAGELED,1);
 
 
 
        uSMC_GetPosition(node,&CurPos);
 
        SetCtrlVal(p1,P1_CPOSITION,CurPos);
 
 
 
        SetCtrlVal(p1, P1_STAGELED,0);
 
 
 
#endif /* uSMC_USB */
 
 
 
        DisplayPanel (p1);
 
        RunUserInterface ();
 
        DiscardPanel (p1);
 
        CmtDiscardThreadPool (poolHandle);
 
 
 
#ifdef uSMC_USB
 
        uSMC_PowerOff(node);
 
        uSMC_Close();
 
#endif /* uSMC_USB */
 
 
 
        return 0;
 
}
 
 
 
 
 
 
 
 
 
int addheader(FILE *fp, int type, int *data) {
 
 
 
 
 
        time_t t;
 
 
 
 
 
 
 
        switch(type) {
 
                case RUNREC_ID: {
 
 
 
 
 
 
 
                        RUNREC runrec;  // start header: appears once at the start of the file
 
 
 
                        runrec.id = RUNREC_ID;
 
                        runrec.length = sizeof(runrec);
 
                        runrec.fver = 0x10000;
 
                        runrec.num_events = data[6];
 
                        runrec.num_channels = NUM_CHANNELS;
 
                        runrec.pedestal = PEDESTAL;
 
                        runrec.xy = SCAN_TYPE;  // 0 -> single data scan :: 1 -> XY position scan
 
                        runrec.nx = data[0];
 
                        runrec.x0 = data[1];
 
                        runrec.dx = data[2];
 
                        runrec.ny = data[3];
 
                        runrec.y0 = data[4];
 
                        runrec.dy = data[5];
 
 
 
                        printf("Writing header to file\n");  
                        printf("RECID = %u\n",runrec.
id);  
                        printf("Length = %u\n",runrec.
length);  
                        printf("File version = %u\n",runrec.
fver);  
                        printf("Number of events per step = %u\n",runrec.
num_events);  
                        printf("Number of channels measured = %u\n",runrec.
num_channels);  
                        printf("Pedestal = %u\n",runrec.
pedestal);  
                        printf("Scan type = %u :: 0 -> single data scan :: 1 -> XY position scan\n",runrec.
xy);  
                        printf("Number of steps in X = %d\n",runrec.
nx);  
                        printf("Start position X = %d\n",runrec.
x0);  
                        printf("Step size direction X = %d\n",runrec.
dx);  
                        printf("Number of steps in Y = %d\n",runrec.
ny);  
                        printf("Start position Y = %d\n",runrec.
y0);  
                        printf("Step size direction Y = %d\n",runrec.
dy);  
 
 
                        if (fp
) fwrite(&runrec
, runrec.
length,1,fp
);  
 
 
                }
 
                break;
 
 
 
 
 
                case ENDREC_ID: {
 
 
 
 
 
                        ENDREC endrec;  // end header: appears once at the end of the file
 
 
 
                        endrec.id = ENDREC_ID;
 
                        endrec.length = sizeof(endrec);
 
 
 
                        printf("Writing header to file\n");  
                        printf("RECID = %u\n",endrec.
id);  
                        printf("Length = %u\n",endrec.
length);  
 
 
                        if (fp
) fwrite(&endrec
, endrec.
length,1,fp
);  
 
 
 
 
                        break;
 
                }
 
                case POSREC_ID: {
 
 
 
 
 
                        POSREC posrec;  // position header: appears at every change of position
 
 
 
                        posrec.id = POSREC_ID;
 
                        posrec.length = sizeof(posrec);
 
                        posrec.num_iter_x  = data[0];
 
                        posrec.mikro_pos_x = data[1];
 
                        posrec.set_pos_x   = data[2];
 
                        posrec.num_iter_y  = data[3];
 
                        posrec.mikro_pos_y = data[4];
 
                        posrec.set_pos_y   = data[5];
 
 
 
                        printf("Writing header to file\n");  
                        printf("RECID = %u\n",posrec.
id);  
                        printf("Length = %u\n",posrec.
length);  
                        printf("Iteration X = %d\n",posrec.
num_iter_x);  
                        printf("MIKRO Position X = %d\n",posrec.
mikro_pos_x);  
                        printf("Set position X = %d\n",posrec.
set_pos_x);  
                        printf("Iteration Y = %d\n",posrec.
num_iter_y);  
                        printf("MIKRO Position Y = %d\n",posrec.
mikro_pos_y);  
                        printf("Set position Y = %d\n",posrec.
set_pos_y);  
 
 
                        if (fp
) fwrite(&posrec
, posrec.
length,1,fp
);  
 
 
 
 
 
 
                        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 Fi2Pos(float x) {
 
        // x in degrees
 
        return (int) (x/360*NSTEPS);
 
}
 
 
 
 
 
int mdaq_init(const char *fname){
 
 
 
        IniText iniText; 
 
char pathName[MAX_PATHNAME_LEN]; 
 
char dirName[MAX_PATHNAME_LEN]; 
 
 
 
 
 
/* set up the pathName for the .ini file */ 
 
GetProjectDir (dirName); 
 
MakePathname (dirName, fname, pathName); 
 
 
 
/* create object for holding the value/tag pairs */ 
 
iniText = Ini_New (TRUE); /* TRUE for automatic sorting */ 
 
 
 
/* read in the tag/value pairs */ 
 
Ini_ReadFromFile (iniText, pathName); 
 
 
 
/* create the in–memory tag/value pairs */ 
 
 
 
Ini_GetInt (iniText, "scintillator", "nofcrystalsx", &conf.nofcrystalsx);
 
Ini_GetInt (iniText, "scintillator", "nofcrystalsy", &conf.nofcrystalsy);
 
 
 
Ini_GetDouble (iniText, "scintillator", "crystalpitchx", &conf.crystalpitchx);
 
Ini_GetDouble (iniText, "scintillator", "crystalpitchy", &conf.crystalpitchy);
 
 
 
 
 
Ini_GetStringCopy (iniText, "sensor", "modules",  &conf.modules);   
 
Ini_GetStringCopy (iniText, "sensor", "channels", &conf.channels);
 
 
 
 
 
Ini_GetStringCopy (iniText, "calibration", "sumpedestals", &conf.sumpedestals);         
 
Ini_GetStringCopy (iniText, "calibration", "pedestals", &conf.pedestals); 
 
Ini_GetStringCopy (iniText, "calibration", "photopeak", &conf.photopeak);               
 
Ini_GetStringCopy (iniText, "calibration", "channelcalibration", &conf.channelcalibration);             
 
Ini_GetInt (iniText, "calibration", "adcthreshold", &conf.adcthreshold); 
 
 
 
/* dispose of the in–memory tag/value pairs */ 
 
Ini_Dispose (iniText);
 
return 0;
 
}
 
 
 
 
 
void ReadModuleMap(const char *fname){
 
    int id;
 
    float r,phi;
 
    char line[400];
 
                const int ndim=400;
 
    FILE 
*fp
=fopen(fname
,"r"); 
                if (!fp) return;
 
                while (fgets(line
,ndim
,fp
)!=NULL
) {  
      sscanf(line
,"%d%f%f",&id
,&r
,&phi
);  
                  if (id<16) {
 
                          conf.module[id].r=r;
 
                          conf.module[id].phi=phi*Pi()/180.; 
 
              if (debug
) printf("%s %d %f %f\n",fname
,id
, r
, phi
);  
            }
 
                }
 
 
 
}
 
 
 
void ReadChannelMap(const char *fname){
 
    int id;
 
    int ix, iy;
 
    char line[400];
 
                const int ndim=400;
 
    FILE 
*fp
=fopen(fname
,"r"); 
                if (!fp) return;
 
                while (fgets(line
,ndim
,fp
)!=NULL
) {  
      sscanf(line
,"%d%d%d",&id
,&ix
,&iy
);  
                  if (id<16) {
 
                          conf.channel[id].ix=ix;
 
                          conf.channel[id].iy=iy; 
 
              if (debug
) printf("%s %d %d %d\n",fname
,id
, ix
, iy
);  
            }
 
                }
 
 
 
}
 
 
 
 int readfile(const char *fname, float *x, int nmax, int defaultvalue){
 
    int id;
 
    float ix;
 
    char line[400];
 
                const int ndim=400;
 
    FILE 
*fp
=fopen(fname
,"r"); 
                for (int i=0;i<nmax;i++){
 
        x[i]=defaultvalue;
 
    }
 
                if (!fp) return -1;
 
                while (fgets(line
,ndim
,fp
)!=NULL
) {  
                
 
                  if (id<nmax)  x[id]=ix; 
 
            if (debug
) printf("%s %d %f\n",fname
,id
, ix
);  
          
 
                }
 
                return 0;
 
 }
 
  
 
 
 
 
 
 
 
 
 
 
 
 
 
  
 
 
 
 
 
 
 
 
 
int Geometry(const char *fnameconfig){
 
 
 
    mdaq_init(fnameconfig);
 
    
 
    ReadModuleMap(conf.modules);
 
    ReadChannelMap(conf.channels);
 
    
 
    printf( "Reading ...%s\n " ,conf.
channelcalibration );  
                /*
 
                m_calibration = new TFile(m_calibrationrootName);
 
    for (int i=0; i<4;i++) {
 
      char hn[256];
 
      sprintf(hn,"pmt1%d_calib",i);
 
      m_crystalid[i]= (TH1I *) m_calibration->Get(hn);
 
      m_crystalid[i]->ls();
 
    } 
 
    */
 
 
 
    conf.peakscaling=3000; 
 
    
 
    readfile(conf.pedestals,conf.apedestals,4*16, 0);
 
    readfile(conf.photopeak,conf.apeak,4*16, conf.peakscaling);
 
        return 0;
 
  };
 
 
 
 
 
int CVICALLBACK mdaq(void *functionData) {
 
 
 
        double dfi, fi0;
 
        unsigned int nsteps;
 
        char filename[0xFF];
 
        char fname[0xFF];
 
        int daqtime;
 
        daq_on = 1;
 
        ctrl_c=0;
 
        GetCtrlVal(p1,P1_DFI, &dfi);
 
        GetCtrlVal(p1,P1_FI0, &fi0);
 
        GetCtrlVal(p1,P1_NFI, &nsteps);
 
        GetCtrlVal(p1,P1_DAQTIME, &daqtime);
 
        GetCtrlVal(p1,P1_FILENAME, filename);
 
        GetCtrlVal(p1,P1_DEBUG, &debug);
 
        Geometry("config.ini");
 
        HistogramsInit();
 
        PETProjDataMgrFree(); 
 
        PETProjDataMgrInit();
 
 
 
  SetDebug(debug);
 
  SetRingDiameter(2*conf.module[0].r);
 
 
 
 
 
                
 
                
 
        FILE 
*fp 
= fopen(fname
, "wb"); 
        int runhdr[7]= {nsteps, Fi2Pos(fi0), Fi2Pos(dfi), 1,0,1, -daqtime};
 
        addheader(fp,RUNREC_ID, runhdr );
 
 
 
 
 
        vmconnect();
 
        for (int i=0; i<nsteps; i++) {
 
                 
 
                double fi=fi0+dfi*i;
 
                conf.rotation =  fi*Pi()/180;
 
#ifdef uSMC_USB
 
                SetCtrlVal(p1,P1_STAGELED,1);
 
                int SetPos = Fi2Pos(fi);
 
                uSMC_MoveTo(node,SetPos);
 
                uSMC_GetPosition (node,&CurPos);
 
                SetCtrlVal(p1,P1_CPOSITION,CurPos);
 
 
 
                SetCtrlVal(p1,P1_STAGELED,0);
 
                if (ctrl_c) break;
 
                int poshdr[6]= {i, CurPos, SetPos, 0,0,0};
 
                addheader(fp, POSREC_ID, poshdr );
 
                vmacquire(-daqtime,fp,  NULL);
 
#endif /* uSMC_USB */
 
                SetCtrlVal(p1,P1_CEVE,i);
 
                printf("Step =%d angle =%f\n", i
, fi
);  
 
 
        }
 
        addheader(fp, ENDREC_ID, NULL);
 
        daq_on = 1;
 
        
 
        WriteInterfile(filename);
 
        sprintf(fname
,"%s.sroot", filename
);   
  HistogramsWrite(fname);
 
 
 
                
 
        vmdisconnect();
 
        return 0;
 
}
 
 
 
 
 
 
 
int CVICALLBACK StartCB (int panel, int control, int event,
 
                                                                                                 void *callbackData, int eventData1, int eventData2) {
 
        ThreadFunctionPtr mythread = NULL;
 
        switch (event) {
 
 
 
                case EVENT_COMMIT:
 
 
 
                        controlID=0;
 
                        if (panel == p1 && control == P1_START) {
 
                                mythread = mdaq;
 
                                controlID= control;
 
                        }
 
                        if (mythread!=NULL) {
 
                                printf("New Thread panel=%d button=%d\n", panel
, control
);  
 
 
                                // SetDimming(1);
 
 
 
 
 
                                if (!daq_on) CmtScheduleThreadPoolFunctionAdv (poolHandle, mythread, &controlID,
 
                                                        DEFAULT_THREAD_PRIORITY,
 
                                                        EndOfThread,
 
                                                        EVENT_TP_THREAD_FUNCTION_END,
 
                                                        NULL, RUN_IN_SCHEDULED_THREAD,
 
                                                        &tfID);
 
                        }
 
                        break;
 
        }
 
        return 0;
 
}
 
 
 
int CVICALLBACK StopCB (int panel, int control, int event,
 
                                                                                                void *callbackData, int eventData1, int eventData2) {
 
        switch (event) {
 
                case EVENT_COMMIT:
 
                        ctrl_c=1;
 
                        break;
 
        }
 
        return 0;
 
}
 
 
 
int CVICALLBACK DebugCB (int panel, int control, int event,
 
                                                                                                 void *callbackData, int eventData1, int eventData2) {
 
        switch (event) {
 
                case EVENT_COMMIT:
 
                        GetCtrlVal(p1,P1_DEBUG, &debug); 
 
                        break;
 
        }
 
        return 0;
 
}
 
 
 
 
 
 
 
int CVICALLBACK RedrawCB (int panel, int control, int event,
 
                                                                                                                        void *callbackData, int eventData1, int eventData2) {
 
        int pmtid;
 
        switch (event) {
 
                case EVENT_COMMIT:
 
                case EVENT_TIMER_TICK:  
 
                        GetCtrlVal(p1,P1_CH, &gadcchannel);
 
      pmtid = gadcchannel/16;
 
                        if (H1D_Exist(m_Adc[gadcchannel])) H1D_Draw(m_Adc[gadcchannel], p1,P1_GADC, &plothandle[0]);
 
                        if (H2D_Exist( m_CenterOfGravity[pmtid])) H2D_Draw(m_CenterOfGravity[pmtid], p1,P1_GXY, &plothandle[1]);
 
                        if (H1D_Exist(m_AdcSum[pmtid])) H1D_Draw(m_AdcSum[pmtid], p1,P1_GSUMADC, &plothandle[2]);
 
                        break;
 
        }
 
        return 0;
 
}