Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
264 | f9daq | 1 | #include "H2D.h" |
2 | #include "H1D.h" |
||
3 | #include "inifile.h" |
||
4 | #include <utility.h> |
||
5 | #include <ansi_c.h> |
||
6 | #include <cvirte.h> |
||
7 | #include <userint.h> |
||
8 | #include "petdemo_uir.h" |
||
9 | |||
10 | #include "daq.h" |
||
11 | #include "PETProjDataMgr.h" |
||
12 | #include <math.h> |
||
13 | |||
14 | #define uSMC_USB |
||
15 | #ifdef uSMC_USB |
||
16 | # include "uSMC.h" |
||
17 | # define uSMC_SERIAL "0000000000005660" |
||
18 | const char serials[3][16]= {uSMC_SERIAL}; |
||
19 | #endif /* uSMC_USB */ |
||
20 | |||
21 | static int node; |
||
22 | static int CurPos = 0; |
||
23 | |||
24 | int p1; |
||
25 | #define MAX_THREADS 10 |
||
26 | static CmtThreadPoolHandle poolHandle = 0; |
||
27 | int ctrl_c=0; |
||
28 | int daq_on=0; |
||
29 | int gadcchannel; |
||
30 | static int tfID; |
||
31 | static int controlID; |
||
32 | static int plothandle[0xFF]; |
||
33 | char strbuf[0xFF]; |
||
34 | |||
35 | int gLog=0; |
||
36 | |||
37 | |||
38 | |||
39 | int printf(const char *format, ...) { |
||
40 | va_list aptr; |
||
41 | int ret; |
||
42 | FILE *flog; |
||
43 | |||
44 | va_start(aptr, format); |
||
45 | ret = vsprintf(strbuf, format, aptr); |
||
46 | va_end(aptr); |
||
47 | SetCtrlVal(p1,P1_STDIO,strbuf); |
||
48 | |||
49 | if (gLog) { |
||
50 | flog = fopen ("stdio.log", "a"); |
||
51 | fprintf (flog, "%s", strbuf); |
||
52 | fclose (flog); |
||
53 | } |
||
54 | return(ret); |
||
55 | } |
||
56 | |||
57 | void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle, |
||
58 | CmtThreadFunctionID functionID, unsigned int event, |
||
59 | int value, void *callbackData ) { |
||
60 | |||
61 | daq_on=0; |
||
62 | //SetDimming(0); |
||
63 | printf("End of Thread \n"); |
||
64 | return ; |
||
65 | |||
66 | } |
||
67 | |||
68 | |||
69 | |||
70 | |||
71 | int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, |
||
72 | LPSTR lpszCmdLine, int nCmdShow) { |
||
73 | if (InitCVIRTE (hInstance, 0, 0) == 0) |
||
74 | return -1; /* out of memory */ |
||
75 | if ((p1 = LoadPanel (0, "petdemo_uir.uir", P1)) < 0) |
||
76 | return -1; |
||
77 | SetStdioPort (CVI_STDIO_WINDOW); |
||
78 | SetSleepPolicy(VAL_SLEEP_MORE); |
||
79 | CmtNewThreadPool (MAX_THREADS, &poolHandle); |
||
80 | #ifdef uSMC_USB |
||
81 | uSMC_Open(); |
||
82 | node=uSMC_FindSerial(serials)+1; |
||
83 | uSMC_Init(node,1); |
||
84 | SetCtrlVal(p1, P1_STAGELED,1); |
||
85 | |||
86 | uSMC_GetPosition(node,&CurPos); |
||
87 | SetCtrlVal(p1,P1_CPOSITION,CurPos); |
||
88 | |||
89 | SetCtrlVal(p1, P1_STAGELED,0); |
||
90 | |||
91 | #endif /* uSMC_USB */ |
||
92 | |||
93 | DisplayPanel (p1); |
||
94 | RunUserInterface (); |
||
95 | DiscardPanel (p1); |
||
96 | CmtDiscardThreadPool (poolHandle); |
||
97 | |||
98 | #ifdef uSMC_USB |
||
99 | uSMC_PowerOff(node); |
||
100 | uSMC_Close(); |
||
101 | #endif /* uSMC_USB */ |
||
102 | |||
103 | return 0; |
||
104 | } |
||
105 | |||
106 | |||
107 | |||
108 | |||
109 | int addheader(FILE *fp, int type, int *data) { |
||
110 | |||
111 | |||
112 | time_t t; |
||
113 | |||
114 | |||
115 | |||
116 | switch(type) { |
||
117 | case RUNREC_ID: { |
||
118 | |||
119 | |||
120 | |||
121 | RUNREC runrec; // start header: appears once at the start of the file |
||
122 | |||
123 | runrec.id = RUNREC_ID; |
||
124 | runrec.length = sizeof(runrec); |
||
125 | runrec.fver = 0x10000; |
||
126 | time(&t); |
||
127 | runrec.time=t; |
||
128 | runrec.num_events = data[6]; |
||
129 | runrec.num_channels = NUM_CHANNELS; |
||
130 | runrec.pedestal = PEDESTAL; |
||
131 | runrec.xy = SCAN_TYPE; // 0 -> single data scan :: 1 -> XY position scan |
||
132 | runrec.nx = data[0]; |
||
133 | runrec.x0 = data[1]; |
||
134 | runrec.dx = data[2]; |
||
135 | runrec.ny = data[3]; |
||
136 | runrec.y0 = data[4]; |
||
137 | runrec.dy = data[5]; |
||
138 | |||
139 | printf("Writing header to file\n"); |
||
140 | printf("RECID = %u\n",runrec.id); |
||
141 | printf("Length = %u\n",runrec.length); |
||
142 | printf("File version = %u\n",runrec.fver); |
||
143 | printf("Time = %u\n",runrec.time); |
||
144 | printf("Number of events per step = %u\n",runrec.num_events); |
||
145 | printf("Number of channels measured = %u\n",runrec.num_channels); |
||
146 | printf("Pedestal = %u\n",runrec.pedestal); |
||
147 | printf("Scan type = %u :: 0 -> single data scan :: 1 -> XY position scan\n",runrec.xy); |
||
148 | printf("Number of steps in X = %d\n",runrec.nx); |
||
149 | printf("Start position X = %d\n",runrec.x0); |
||
150 | printf("Step size direction X = %d\n",runrec.dx); |
||
151 | printf("Number of steps in Y = %d\n",runrec.ny); |
||
152 | printf("Start position Y = %d\n",runrec.y0); |
||
153 | printf("Step size direction Y = %d\n",runrec.dy); |
||
154 | |||
155 | if (fp) fwrite(&runrec, runrec.length,1,fp); |
||
156 | |||
157 | } |
||
158 | break; |
||
159 | |||
160 | |||
161 | case ENDREC_ID: { |
||
162 | |||
163 | |||
164 | ENDREC endrec; // end header: appears once at the end of the file |
||
165 | |||
166 | endrec.id = ENDREC_ID; |
||
167 | endrec.length = sizeof(endrec); |
||
168 | time(&t); |
||
169 | endrec.time=t; |
||
170 | |||
171 | printf("Writing header to file\n"); |
||
172 | printf("RECID = %u\n",endrec.id); |
||
173 | printf("Length = %u\n",endrec.length); |
||
174 | printf("Time = %u\n",endrec.time); |
||
175 | |||
176 | if (fp) fwrite(&endrec, endrec.length,1,fp); |
||
177 | |||
178 | |||
179 | break; |
||
180 | } |
||
181 | case POSREC_ID: { |
||
182 | |||
183 | |||
184 | POSREC posrec; // position header: appears at every change of position |
||
185 | |||
186 | posrec.id = POSREC_ID; |
||
187 | posrec.length = sizeof(posrec); |
||
188 | time(&t); |
||
189 | posrec.time = t; |
||
190 | posrec.num_iter_x = data[0]; |
||
191 | posrec.mikro_pos_x = data[1]; |
||
192 | posrec.set_pos_x = data[2]; |
||
193 | posrec.num_iter_y = data[3]; |
||
194 | posrec.mikro_pos_y = data[4]; |
||
195 | posrec.set_pos_y = data[5]; |
||
196 | |||
197 | printf("Writing header to file\n"); |
||
198 | printf("RECID = %u\n",posrec.id); |
||
199 | printf("Length = %u\n",posrec.length); |
||
200 | printf("Time = %u\n",posrec.time); |
||
201 | printf("Iteration X = %d\n",posrec.num_iter_x); |
||
202 | printf("MIKRO Position X = %d\n",posrec.mikro_pos_x); |
||
203 | printf("Set position X = %d\n",posrec.set_pos_x); |
||
204 | printf("Iteration Y = %d\n",posrec.num_iter_y); |
||
205 | printf("MIKRO Position Y = %d\n",posrec.mikro_pos_y); |
||
206 | printf("Set position Y = %d\n",posrec.set_pos_y); |
||
207 | |||
208 | if (fp) fwrite(&posrec, posrec.length,1,fp); |
||
209 | |||
210 | |||
211 | |||
212 | break; |
||
213 | } |
||
214 | } |
||
215 | |||
216 | return 0; |
||
217 | } |
||
218 | |||
219 | |||
220 | int CVICALLBACK ExitCB (int panel, int control, int event, |
||
221 | void *callbackData, int eventData1, int eventData2) { |
||
222 | switch (event) { |
||
223 | case EVENT_COMMIT: |
||
224 | QuitUserInterface (0); |
||
225 | break; |
||
226 | } |
||
227 | return 0; |
||
228 | } |
||
229 | |||
230 | |||
231 | int Fi2Pos(float x) { |
||
232 | // x in degrees |
||
233 | return (int) (x/360*NSTEPS); |
||
234 | } |
||
235 | |||
236 | |||
237 | int mdaq_init(const char *fname){ |
||
238 | |||
239 | IniText iniText; |
||
240 | char pathName[MAX_PATHNAME_LEN]; |
||
241 | char dirName[MAX_PATHNAME_LEN]; |
||
242 | |||
243 | |||
244 | /* set up the pathName for the .ini file */ |
||
245 | GetProjectDir (dirName); |
||
246 | MakePathname (dirName, fname, pathName); |
||
247 | |||
248 | /* create object for holding the value/tag pairs */ |
||
249 | iniText = Ini_New (TRUE); /* TRUE for automatic sorting */ |
||
250 | |||
251 | /* read in the tag/value pairs */ |
||
252 | Ini_ReadFromFile (iniText, pathName); |
||
253 | |||
254 | /* create the in–memory tag/value pairs */ |
||
255 | |||
256 | Ini_GetInt (iniText, "scintillator", "nofcrystalsx", &conf.nofcrystalsx); |
||
257 | Ini_GetInt (iniText, "scintillator", "nofcrystalsy", &conf.nofcrystalsy); |
||
258 | |||
259 | Ini_GetDouble (iniText, "scintillator", "crystalpitchx", &conf.crystalpitchx); |
||
260 | Ini_GetDouble (iniText, "scintillator", "crystalpitchy", &conf.crystalpitchy); |
||
261 | |||
262 | |||
263 | Ini_GetStringCopy (iniText, "sensor", "modules", &conf.modules); |
||
264 | Ini_GetStringCopy (iniText, "sensor", "channels", &conf.channels); |
||
265 | |||
266 | |||
267 | Ini_GetStringCopy (iniText, "calibration", "sumpedestals", &conf.sumpedestals); |
||
268 | Ini_GetStringCopy (iniText, "calibration", "pedestals", &conf.pedestals); |
||
269 | Ini_GetStringCopy (iniText, "calibration", "photopeak", &conf.photopeak); |
||
270 | Ini_GetStringCopy (iniText, "calibration", "channelcalibration", &conf.channelcalibration); |
||
271 | Ini_GetInt (iniText, "calibration", "adcthreshold", &conf.adcthreshold); |
||
272 | |||
273 | /* dispose of the in–memory tag/value pairs */ |
||
274 | Ini_Dispose (iniText); |
||
275 | return 0; |
||
276 | } |
||
277 | |||
278 | |||
279 | void ReadModuleMap(const char *fname){ |
||
280 | int id; |
||
281 | float r,phi; |
||
282 | char line[400]; |
||
283 | const int ndim=400; |
||
284 | FILE *fp=fopen(fname,"r"); |
||
285 | if (!fp) return; |
||
286 | while (fgets(line,ndim,fp)!=NULL) { |
||
287 | sscanf(line,"%d%f%f",&id,&r,&phi); |
||
288 | if (id<16) { |
||
289 | conf.module[id].r=r; |
||
290 | conf.module[id].phi=phi*Pi()/180.; |
||
291 | if (debug) printf("%s %d %f %f\n",fname,id, r, phi); |
||
292 | } |
||
293 | } |
||
294 | fclose(fp); |
||
295 | |||
296 | } |
||
297 | |||
298 | void ReadChannelMap(const char *fname){ |
||
299 | int id; |
||
300 | int ix, iy; |
||
301 | char line[400]; |
||
302 | const int ndim=400; |
||
303 | FILE *fp=fopen(fname,"r"); |
||
304 | if (!fp) return; |
||
305 | while (fgets(line,ndim,fp)!=NULL) { |
||
306 | sscanf(line,"%d%d%d",&id,&ix,&iy); |
||
307 | if (id<16) { |
||
308 | conf.channel[id].ix=ix; |
||
309 | conf.channel[id].iy=iy; |
||
310 | if (debug) printf("%s %d %d %d\n",fname,id, ix, iy); |
||
311 | } |
||
312 | } |
||
313 | fclose(fp); |
||
314 | |||
315 | } |
||
316 | |||
317 | int readfile(const char *fname, float *x, int nmax, int defaultvalue){ |
||
318 | int id; |
||
319 | float ix; |
||
320 | char line[400]; |
||
321 | const int ndim=400; |
||
322 | FILE *fp=fopen(fname,"r"); |
||
323 | for (int i=0;i<nmax;i++){ |
||
324 | x[i]=defaultvalue; |
||
325 | } |
||
326 | if (!fp) return -1; |
||
327 | while (fgets(line,ndim,fp)!=NULL) { |
||
328 | sscanf(line,"%d%f",&id,&ix); |
||
329 | |||
330 | if (id<nmax) x[id]=ix; |
||
331 | if (debug) printf("%s %d %f\n",fname,id, ix); |
||
332 | |||
333 | } |
||
334 | fclose(fp); |
||
335 | return 0; |
||
336 | } |
||
337 | |||
338 | |||
339 | |||
340 | |||
341 | |||
342 | |||
343 | |||
344 | |||
345 | |||
346 | |||
347 | |||
348 | |||
349 | int Geometry(const char *fnameconfig){ |
||
350 | |||
351 | mdaq_init(fnameconfig); |
||
352 | |||
353 | ReadModuleMap(conf.modules); |
||
354 | ReadChannelMap(conf.channels); |
||
355 | |||
356 | printf( "Reading ...%s\n " ,conf.channelcalibration ); |
||
357 | /* |
||
358 | m_calibration = new TFile(m_calibrationrootName); |
||
359 | for (int i=0; i<4;i++) { |
||
360 | char hn[256]; |
||
361 | sprintf(hn,"pmt1%d_calib",i); |
||
362 | m_crystalid[i]= (TH1I *) m_calibration->Get(hn); |
||
363 | m_crystalid[i]->ls(); |
||
364 | } |
||
365 | */ |
||
366 | |||
367 | conf.peakscaling=3000; |
||
368 | |||
369 | readfile(conf.pedestals,conf.apedestals,4*16, 0); |
||
370 | readfile(conf.photopeak,conf.apeak,4*16, conf.peakscaling); |
||
371 | return 0; |
||
372 | }; |
||
373 | |||
374 | |||
375 | int CVICALLBACK mdaq(void *functionData) { |
||
376 | |||
377 | double dfi, fi0; |
||
378 | unsigned int nsteps; |
||
379 | char filename[0xFF]; |
||
380 | char fname[0xFF]; |
||
381 | int daqtime; |
||
382 | daq_on = 1; |
||
383 | ctrl_c=0; |
||
384 | GetCtrlVal(p1,P1_DFI, &dfi); |
||
385 | GetCtrlVal(p1,P1_FI0, &fi0); |
||
386 | GetCtrlVal(p1,P1_NFI, &nsteps); |
||
387 | GetCtrlVal(p1,P1_DAQTIME, &daqtime); |
||
388 | GetCtrlVal(p1,P1_FILENAME, filename); |
||
389 | GetCtrlVal(p1,P1_DEBUG, &debug); |
||
390 | sprintf(fname,"%s.dat", filename); |
||
391 | Geometry("config.ini"); |
||
392 | HistogramsInit(); |
||
393 | PETProjDataMgrFree(); |
||
394 | PETProjDataMgrInit(); |
||
395 | |||
396 | SetDebug(debug); |
||
397 | SetRingDiameter(2*conf.module[0].r); |
||
398 | |||
399 | |||
400 | |||
401 | |||
402 | FILE *fp = fopen(fname, "wb"); |
||
403 | int runhdr[7]= {nsteps, Fi2Pos(fi0), Fi2Pos(dfi), 1,0,1, -daqtime}; |
||
404 | addheader(fp,RUNREC_ID, runhdr ); |
||
405 | |||
406 | |||
407 | vmconnect(); |
||
408 | for (int i=0; i<nsteps; i++) { |
||
409 | |||
410 | double fi=fi0+dfi*i; |
||
411 | conf.rotation = fi*Pi()/180; |
||
412 | #ifdef uSMC_USB |
||
413 | SetCtrlVal(p1,P1_STAGELED,1); |
||
414 | int SetPos = Fi2Pos(fi); |
||
415 | uSMC_MoveTo(node,SetPos); |
||
416 | uSMC_GetPosition (node,&CurPos); |
||
417 | SetCtrlVal(p1,P1_CPOSITION,CurPos); |
||
418 | |||
419 | SetCtrlVal(p1,P1_STAGELED,0); |
||
420 | if (ctrl_c) break; |
||
421 | int poshdr[6]= {i, CurPos, SetPos, 0,0,0}; |
||
422 | addheader(fp, POSREC_ID, poshdr ); |
||
423 | vmacquire(-daqtime,fp, NULL); |
||
424 | #endif /* uSMC_USB */ |
||
425 | SetCtrlVal(p1,P1_CEVE,i); |
||
426 | printf("Step =%d angle =%f\n", i, fi); |
||
427 | |||
428 | } |
||
429 | addheader(fp, ENDREC_ID, NULL); |
||
430 | fclose(fp); |
||
431 | daq_on = 1; |
||
432 | |||
433 | WriteInterfile(filename); |
||
434 | sprintf(fname,"%s.sroot", filename); |
||
435 | HistogramsWrite(fname); |
||
436 | |||
437 | |||
438 | vmdisconnect(); |
||
439 | return 0; |
||
440 | } |
||
441 | |||
442 | |||
443 | |||
444 | int CVICALLBACK StartCB (int panel, int control, int event, |
||
445 | void *callbackData, int eventData1, int eventData2) { |
||
446 | ThreadFunctionPtr mythread = NULL; |
||
447 | switch (event) { |
||
448 | |||
449 | case EVENT_COMMIT: |
||
450 | |||
451 | controlID=0; |
||
452 | if (panel == p1 && control == P1_START) { |
||
453 | mythread = mdaq; |
||
454 | controlID= control; |
||
455 | } |
||
456 | if (mythread!=NULL) { |
||
457 | printf("New Thread panel=%d button=%d\n", panel, control); |
||
458 | |||
459 | // SetDimming(1); |
||
460 | |||
461 | |||
462 | if (!daq_on) CmtScheduleThreadPoolFunctionAdv (poolHandle, mythread, &controlID, |
||
463 | DEFAULT_THREAD_PRIORITY, |
||
464 | EndOfThread, |
||
465 | EVENT_TP_THREAD_FUNCTION_END, |
||
466 | NULL, RUN_IN_SCHEDULED_THREAD, |
||
467 | &tfID); |
||
468 | } |
||
469 | break; |
||
470 | } |
||
471 | return 0; |
||
472 | } |
||
473 | |||
474 | int CVICALLBACK StopCB (int panel, int control, int event, |
||
475 | void *callbackData, int eventData1, int eventData2) { |
||
476 | switch (event) { |
||
477 | case EVENT_COMMIT: |
||
478 | ctrl_c=1; |
||
479 | break; |
||
480 | } |
||
481 | return 0; |
||
482 | } |
||
483 | |||
484 | int CVICALLBACK DebugCB (int panel, int control, int event, |
||
485 | void *callbackData, int eventData1, int eventData2) { |
||
486 | switch (event) { |
||
487 | case EVENT_COMMIT: |
||
488 | GetCtrlVal(p1,P1_DEBUG, &debug); |
||
489 | break; |
||
490 | } |
||
491 | return 0; |
||
492 | } |
||
493 | |||
494 | |||
495 | |||
496 | int CVICALLBACK RedrawCB (int panel, int control, int event, |
||
497 | void *callbackData, int eventData1, int eventData2) { |
||
498 | int pmtid; |
||
499 | switch (event) { |
||
500 | case EVENT_COMMIT: |
||
501 | case EVENT_TIMER_TICK: |
||
502 | GetCtrlVal(p1,P1_CH, &gadcchannel); |
||
503 | pmtid = gadcchannel/16; |
||
504 | if (H1D_Exist(m_Adc[gadcchannel])) H1D_Draw(m_Adc[gadcchannel], p1,P1_GADC, &plothandle[0]); |
||
505 | if (H2D_Exist( m_CenterOfGravity[pmtid])) H2D_Draw(m_CenterOfGravity[pmtid], p1,P1_GXY, &plothandle[1]); |
||
506 | if (H1D_Exist(m_AdcSum[pmtid])) H1D_Draw(m_AdcSum[pmtid], p1,P1_GSUMADC, &plothandle[2]); |
||
507 | break; |
||
508 | } |
||
509 | return 0; |
||
510 | } |
||
511 |