#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;
}