TPCCLIB
Loading...
Searching...
No Matches
img_upet.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgio.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
17 char *upetname,
19 char *ecatfile,
21 int verbose
22) {
23 char upetheader[FILENAME_MAX], upetimage[FILENAME_MAX];
24 int n, ret;
25 int acquisition_mode, data_type;
26 char tmp[MAX_MICROPET_LINE_LEN];
27
28
29 if(verbose>1) printf("\n%s(%s, %s, %d)\n", __func__, upetname, ecatfile, verbose);
30 /* Check the arguments */
31 if(upetname==NULL || ecatfile==NULL) return STATUS_FAULT;
32 ret=upetExists(upetname, upetheader, upetimage, verbose-1);
33 if(ret!=2) return STATUS_NOFILE;
34
35 /*
36 * Open Micropet Header and binary data files
37 */
38 FILE *fph, *fpi;
39 if((fph=fopen(upetheader, "r"))==NULL) return(STATUS_NOHEADERFILE);
40 if((fpi=fopen(upetimage, "rb"))==NULL) {fclose(fph); return(STATUS_NOIMGDATA);}
41
42
43 /*
44 * Check that image format is (currently) supported
45 */
46 rewind(fph);
47 if(verbose>1) printf("checking that image format is supported\n");
48 n=-1; if(upetHeaderReadParameter(fph, "file_type", tmp)==0)
49 (void)sscanf(tmp, "%d", &n);
50 if(verbose>2) printf("file_type := %d\n", n);
51 if(n!=5) {fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
52 acquisition_mode=-1;
53 if(upetHeaderReadParameter(fph, "acquisition_mode", tmp)==0)
54 (void)sscanf(tmp, "%d", &acquisition_mode);
55 if(verbose>2) printf("acquisition_mode := %d\n", acquisition_mode);
56 if(acquisition_mode!=2 && acquisition_mode!=3 && acquisition_mode!=9) {
57 fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
58 data_type=-1;
59 if(upetHeaderReadParameter(fph, "data_type", tmp)==0)
60 (void)sscanf(tmp, "%d", &data_type);
61 if(verbose>2) printf("data_type := %d\n", data_type);
62 if(data_type!=4 && data_type!=2) {
63 fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
64
65 /*
66 * Convert PET or CT image
67 */
68 if(acquisition_mode==2 || acquisition_mode==3) {
69 ret=imgMicropetPETToEcat7(fph, fpi, ecatfile, verbose);
70 } else if(acquisition_mode==9) {
71 ret=imgMicropetCTToEcat7(fph, fpi, ecatfile, verbose);
72 } else {
73 ret=STATUS_UNSUPPORTED;
74 }
75 fclose(fph); fclose(fpi);
76 return ret;
77}
78/*****************************************************************************/
79
80/*****************************************************************************/
87 FILE *fph,
89 FILE *fpi,
91 char *ecatfile,
93 int verbose
94) {
95 int n, zi, xi, yi, ti, ret;
96
97
98 if(verbose>1) printf("%s(*fph, *fpi, %s, %d)\n", __func__, ecatfile, verbose);
99 /* Check input */
100 if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
101
102 /* Remove existing ECAT file */
103 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
104 return(STATUS_CANNOTERASE);
105 }
106
107 /*
108 * Read image dimensions from header
109 */
110 int zdim, xdim, ydim, tdim;
111 ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, &tdim);
112 if(ret) {return(STATUS_INVALIDHEADER);}
113 if(verbose>1) {
114 printf("z_dim := %d\n", zdim);
115 printf("x_dim := %d\n", xdim);
116 printf("y_dim := %d\n", ydim);
117 printf("t_dim := %d\n", tdim);
118 }
119
120 /*
121 * Read and write image frame-by-frame
122 */
123 IMG img; imgInit(&img);
124 /* Allocate memory for one frame */
125 ret=imgAllocate(&img, zdim, ydim, xdim, 1);
126 if(ret) {return(STATUS_NOMEMORY);}
127 /* Fill header with what we now can */
128 float calibration_factor;
129 ret=imgGetMicropetMainHeader(fph, &img, &calibration_factor, verbose-2);
130 if(ret) {
131 if(verbose>2) printf("ret := %d\n", ret);
132 imgEmpty(&img); return(STATUS_INVALIDHEADER);
133 }
134 if(verbose>1) printf("calibration_factor := %g\n", calibration_factor);
137 studynr_from_fname(ecatfile, img.studyNr);
138 upetScanStart(fph, &img.scanStart);
139 /* Allocate memory for the binary data */
140 long long int pxlnr=xdim*ydim*zdim;
141 char *mdata, *mptr;
142 mdata=(char*)malloc(pxlnr*sizeof(float)); if(mdata==NULL) {
143 imgEmpty(&img); return(STATUS_NOMEMORY);
144 }
145 /* Frame-by-frame */
146 float *fptr;
147 for(ti=0; ti<tdim; ti++) {
148 if(verbose>3) {printf("ti=%d\n", ti); fflush(stdout);}
149 /* Read frame information from MicroPET header into IMG */
150 ret=imgGetMicropetFrameHeader(fph, &img, ti, verbose-2);
151 if(ret) {
152 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
153 free(mdata); imgEmpty(&img);
154 return(STATUS_INVALIDHEADER);
155 }
156 /* Read floats */
157 mptr=mdata;
158 if((n=fread(mptr, 4, pxlnr, fpi)) < pxlnr) {
159 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
160 free(mdata); imgEmpty(&img);
161 return(STATUS_NOMATRIX);
162 }
163 /* Copy floats to IMG */
164 mptr=mdata;
165 for(zi=0; zi<zdim; zi++)
166 for(yi=0; yi<ydim; yi++)
167 for(xi=0; xi<xdim; xi++) {
168 fptr=(float*)mptr;
169 img.m[zi][yi][xi][0]=(*fptr)*img.weight[0]*calibration_factor;
170 mptr+=4;
171 }
172 /* Write frame */
173 ret=imgWriteFrame(ecatfile, ti+1, &img, 0); //printf("ret := %d\n", ret);
174 if(ret!=STATUS_OK) break;
175 if(verbose>1) {printf(" frame written.\n"); fflush(stdout);}
176 else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
177 };
178 free(mdata); imgEmpty(&img);
179 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
180 if(verbose==0 && ret==STATUS_NOMATRIX) {
181 fprintf(stdout, " %d frame(s) processed.\n", ti);
182 }
183 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
184 remove(ecatfile); return ret;
185 }
186
187 return STATUS_OK;
188}
189/*****************************************************************************/
190
191/*****************************************************************************/
198 FILE *fph,
200 FILE *fpi,
202 char *ecatfile,
204 int verbose
205) {
206 IMG img;
207 int n, zi, xi, yi, zdim, xdim, ydim, ret;
208 float scale_factor;
209 char *mdata, *mptr;
210 char tmp[MAX_MICROPET_LINE_LEN];
211 short int *si;
212
213
214 if(verbose>1) printf("%s(*fph, *fpi, %s, %d)\n", __func__, ecatfile, verbose);
215 /* Check input */
216 if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
217
218 /*
219 * Read image dimensions from header
220 */
221 ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, NULL);
222 if(ret) {return(STATUS_INVALIDHEADER);}
223 if(verbose>2) {
224 printf("z_dim := %d\n", zdim);
225 printf("x_dim := %d\n", xdim);
226 printf("y_dim := %d\n", ydim);
227 }
228
229 /* Read scale factor */
230 rewind(fph);
231 if(upetHeaderReadParameter(fph, "scale_factor", tmp)!=0) {
232 return(STATUS_INVALIDHEADER);}
233 scale_factor=-1; (void)sscanf(tmp, "%f", &scale_factor);
234 if(scale_factor<=0) return(STATUS_INVALIDHEADER);
235 if(verbose>2) {
236 printf("scale_factor := %g\n", scale_factor);
237 }
238
239 /* Remove existing ECAT file */
240 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
241 return(STATUS_CANNOTERASE);
242 }
243
244 /*
245 * Read and write image
246 */
247 imgInit(&img);
248 /* Allocate memory for one frame */
249 ret=imgAllocate(&img, zdim, ydim, xdim, 1);
250 if(ret) {return(STATUS_NOMEMORY);}
251 /* Fill header with what we now can */
252 ret=imgGetMicropetMainHeader(fph, &img, NULL, verbose-2);
253 if(ret) {
254 if(verbose>1) printf("ret := %d\n", ret);
255 imgEmpty(&img); return(STATUS_INVALIDHEADER);
256 }
259 studynr_from_fname(ecatfile, img.studyNr);
260 upetScanStart(fph, &img.scanStart);
261 /* Allocate memory for the binary data */
262 long long pxlNr=xdim*ydim;
263 mdata=(char*)malloc(pxlNr*sizeof(short int)); if(mdata==NULL) {
264 imgEmpty(&img); return(STATUS_NOMEMORY);
265 }
266 /* Read image data, plane-by-plane */
267 for(zi=0; zi<zdim; zi++) {
268 mptr=mdata;
269 if((n=fread(mptr, 2, pxlNr, fpi)) < pxlNr) {
270 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
271 free(mdata); imgEmpty(&img);
272 return(STATUS_NOMATRIX);
273 }
274 /* Copy short ints to IMG */
275 mptr=mdata;
276 for(yi=0; yi<ydim; yi++)
277 for(xi=0; xi<xdim; xi++) {
278 si=(short int*)mptr;
279 img.m[zi][yi][xi][0]=(float)*si*scale_factor;
280 mptr+=2;
281 }
282 if(verbose>3) printf(" plane %d\n", zi+1);
283 else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
284 }
285 free(mdata);
286 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
287 /* Save ECAT 7 image volume */
288 ret=imgWrite(ecatfile, &img);
289 if(ret!=0) {imgEmpty(&img); return(STATUS_CANNOTWRITE);}
290
291 imgEmpty(&img);
292 return STATUS_OK;
293}
294/*****************************************************************************/
295
296/*****************************************************************************/
302 FILE *fp,
304 IMG *img,
306 float *calibration_factor,
308 int verbose
309) {
310 char tmp[MAX_MICROPET_LINE_LEN];
311 int n;
312 float f;
313
314
315 if(verbose>0) printf("%s(*fp, *img, *f)\n", __func__);
316 if(fp==NULL) return 1;
317 if(img==NULL) return 2;
318
319 /* scanner model */
320 rewind(fp);
321 if(verbose>1) printf(" reading 'model'\n");
322 if(upetHeaderReadParameter(fp, "model", tmp)!=0) return 11;
323 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
324 img->scanner=n;
325
326 /* zoom */
327 rewind(fp);
328 if(verbose>1) printf(" reading 'zoom'\n");
329 if(upetHeaderReadParameter(fp, "zoom", tmp)!=0) return 11;
330 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 11;
331 img->zoom=f;
332
333 /* If 'pixel_size' is found, use it as initial value for pixel x, y, and z size */
334 rewind(fp);
335 if(verbose>1) printf(" reading 'pixel_size'\n");
336 if(upetHeaderReadParameter(fp, "pixel_size", tmp)==0) {
337 f=-1; (void)sscanf(tmp, "%f", &f);
338 if(f>0.0) {
339 if(verbose>2) printf(" pixel_size := %g cm\n", f);
340 img->sizex=img->sizey=img->sizez=10.0*f;
341 }
342 }
343
344 /* pixel size x */
345 rewind(fp);
346 if(verbose>1) printf(" reading 'pixel_size_x'\n");
347 if(upetHeaderReadParameter(fp, "pixel_size_x", tmp)==0) {
348 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
349 if(verbose>2) printf(" pixel_size_x := %g\n", f);
350 img->sizex=f;
351 }
352
353 /* pixel size y */
354 rewind(fp);
355 if(verbose>1) printf(" reading 'pixel_size_y'\n");
356 if(upetHeaderReadParameter(fp, "pixel_size_y", tmp)==0) {
357 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
358 if(verbose>2) printf(" pixel_size_y := %g\n", f);
359 img->sizey=f;
360 }
361
362 /* pixel size z; note that transaxial_bin_size may be better in case of plane gaps */
363 rewind(fp);
364 if(verbose>1) printf(" reading 'pixel_size_z'\n");
365 if(upetHeaderReadParameter(fp, "pixel_size_z", tmp)==0) {
366 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
367 if(verbose>2) printf(" pixel_size_z := %g\n", f);
368 img->sizez=f;
369 } else {
370 if(verbose>0) printf(" cannot find 'pixel_size_z'\n");
371 rewind(fp);
372 if(verbose>1) printf(" reading 'axial_plane_size'\n");
373 if(upetHeaderReadParameter(fp, "axial_plane_size", tmp)!=0) {
374 if(verbose>0) printf(" cannot find 'axial_plane_size'\n");
375 img->sizez=0.0;
376 } else {
377 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
378 if(verbose>2) printf(" axial_pixel_size := %g cm\n", f);
379 img->sizez=10.*f;
380 }
381 }
382 /* transaxial_bin_size; in case of plane gaps this could be better than pixel_size_z */
383 rewind(fp);
384 if(verbose>1) printf(" reading 'transaxial_bin_size'\n");
385 if(upetHeaderReadParameter(fp, "transaxial_bin_size", tmp)==0) {
386 f=-1; (void)sscanf(tmp, "%f", &f);
387 if(verbose>2) printf(" transaxial_pixel_size := %g cm\n", f);
388 //if(f>0) img->sizez=10.0*f;
389 }
390
391 /* isotope halflife */
392 rewind(fp);
393 if(verbose>1) printf(" reading 'isotope_half_life'\n");
394 if(upetHeaderReadParameter(fp, "isotope_half_life", tmp)==0) {
395 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 15;
396 img->isotopeHalflife=f;
397 }
398
399 /* branching_fraction */
400 rewind(fp);
401 if(verbose>1) printf(" reading 'isotope_branching_fraction'\n");
402 if(upetHeaderReadParameter(fp, "isotope_branching_fraction", tmp)==0) {
403 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 16;
404 img->branchingFraction=f;
405 }
406
407 /* decay correction applied */
408 rewind(fp);
409 if(verbose>1) printf(" reading 'decay_correction_applied'\n");
410 if(upetHeaderReadParameter(fp, "decay_correction_applied", tmp)==0) {
411 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 17;
414 }
415
416 /* calibration units */
417 rewind(fp);
418 if(verbose>1) printf(" reading 'calibration_units'\n");
419 if(upetHeaderReadParameter(fp, "calibration_units", tmp)==0) {
420 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 18;
421 switch(n) {
422 case 1: img->unit=CUNIT_NCI_PER_ML; break;
423 case 2: img->unit=CUNIT_BQ_PER_ML; break;
424 case 3: img->unit=CUNIT_HU; break;
425 case 0:
426 default: img->unit=CUNIT_UNKNOWN; break;
427 }
428 }
429
430 /* calibration factor */
431 rewind(fp);
432 if(verbose>1) printf(" reading 'calibration_factor'\n");
433 if(calibration_factor!=NULL &&
434 upetHeaderReadParameter(fp, "calibration_factor", tmp)==0)
435 {
436 f=-1; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 19;
437 *calibration_factor=f;
438 if(img->branchingFraction>0.0) *calibration_factor/=img->branchingFraction;
439 }
440
441 /* FOV */
442 rewind(fp);
443 if(verbose>1) printf(" reading 'radial_fov'\n");
444 if(upetHeaderReadParameter(fp, "radial_fov", tmp)==0) {
445 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 20;
446 img->transaxialFOV=10.0*f;
447 }
448
449 return 0;
450}
451/*****************************************************************************/
452
453/*****************************************************************************/
459 FILE *fp,
461 IMG *img,
463 int frame_index,
465 int verbose
466) {
467 char tmp[MAX_MICROPET_LINE_LEN];
468 float f;
469
470
471 if(verbose>0) printf("%s(*fp, *img, %d)\n", __func__, frame_index);
472 if(fp==NULL) return 1;
473 if(img==NULL) return 2;
474 if(frame_index<0) return 3;
475
476 /* Search required frame from the beginning of header file */
477 rewind(fp);
478
479 /* Find correct frame index */
480 sprintf(tmp, "frame %d", frame_index);
481 if(verbose>1) printf(" reading '%s'\n", tmp);
482 if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 5;
483
484 /* frame start time */
485 if(verbose>1) printf(" reading 'frame_start'\n");
486 if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 11;
487 f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<0.0) return 11;
488 img->start[0]=f;
489
490 /* frame duration; can be 0 at least in single-frame image */
491 if(verbose>1) printf(" reading 'frame_duration'\n");
492 if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 12;
493 f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<0.0) return 12;
494 img->end[0]=img->start[0]+f;
495 img->mid[0]=0.5*(img->end[0]+img->start[0]);
496
497 /* scale factor (written in 'weight' since there is no better place) */
498 if(verbose>1) printf(" reading 'scale_factor'\n");
499 if(upetHeaderReadParameter(fp, "scale_factor", tmp)!=0) return 13;
500 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
501 img->weight[0]=f;
502
503 /* decay correction */
504 if(verbose>1) printf(" reading 'decay_correction'\n");
505 if(upetHeaderReadParameter(fp, "decay_correction", tmp)!=0) return 14;
506 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
507 img->decayCorrFactor[0]=f;
508
509 return 0;
510}
511/*****************************************************************************/
512
513/*****************************************************************************/
519 FILE *fp,
521 SIF *sif
522) {
523 char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
524 int n, i, ret;
525
526
527 if(fp==NULL) return 1;
528 if(sif==NULL) return 2;
529
530
531 /* Get frame number */
532 rewind(fp);
533 if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
534 n=-1; (void)sscanf(tmp, "%d", &n); if(n<1) return 11;
535
536 /* Allocate memory for SIF */
537 ret=sifSetmem(sif, n); if(ret!=0) return 4;
538 sif->frameNr=n;
539 sif->colNr=4;
540 sif->version=1;
541
542 /* Scan time */
543 upetScanStart(fp, &sif->scantime);
544
545 /* Isotope */
546 rewind(fp);
547 if(upetHeaderReadParameter(fp, "isotope", tmp)!=0) return 13;
548 strlcpy(sif->isotope_name, tmp, 8);
549
550 /* Frames */
551 for(i=0; i<sif->frameNr; i++) {
552 /* Find correct frame index */
553 sprintf(tmp, "frame %d", i);
554 if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 21;
555 /* frame start time */
556 if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 22;
557 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 22;
558 sif->x1[i]=n;
559 /* frame duration */
560 if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 23;
561 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 23;
562 sif->x2[i]=sif->x1[i]+n;
563 /* prompts */
564 if(upetHeaderReadParameter(fp, "prompts", tmp)!=0) return 24;
565 n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 24;
566 sif->prompts[i]=n;
567 /* delays */
568 if(upetHeaderReadParameter(fp, "delays", tmp)!=0) return 25;
569 n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 25;
570 sif->randoms[i]=n;
571 /* trues */
572 sif->trues[i]=sif->prompts[i]-sif->randoms[i];
573 }
574 return 0;
575}
576/*****************************************************************************/
577
578/*****************************************************************************/
585 IMG *img
586) {
587 int i, n;
588 float f;
589 char key[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
590#pragma clang diagnostic push
591#pragma clang diagnostic ignored "-Wmissing-field-initializers"
592 struct tm scanstart={0};
593#pragma clang diagnostic pop
594
595 if(MICROPET_TEST) printf("\n%s(*img)\n", __func__);
596
597 /* Check the input */
598 if(img==NULL) return STATUS_FAULT;
600 return STATUS_FAULT;
601 imgSetStatus(img, STATUS_FAULT);
602 if(img->ift.keyNr<10) return STATUS_FAULT;
603
604 imgSetStatus(img, STATUS_INVALIDHEADER);
605
606 /* Check image format */
607 i=iftGetIntValue(&img->ift, 0, "file_type", &n, 0);
608 if(i<0) return STATUS_INVALIDHEADER;
609 if(n!=5) {imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
610
611 i=iftGetIntValue(&img->ift, 0, "acquisition_mode", &n, 0);
612 if(i<0) return STATUS_INVALIDHEADER;
613 if(n!=2 && n!=3) { // CT (9) not yet supported
614 imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
615
616 i=iftGetIntValue(&img->ift, 0, "data_type", &n, 0);
617 if(i<0) return STATUS_INVALIDHEADER;
618 if(n!=4 && n!=2) {
619 imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
620
621 /* scanner model */
622 i=iftGetIntValue(&img->ift, 0, "model", &img->scanner, 0);
623 if(i<0) return STATUS_INVALIDHEADER;
624 if(img->scanner<0) return STATUS_INVALIDHEADER;
625
626 /* image dimensions */
627 i=iftGetIntValue(&img->ift, 0, "total_frames", &n, 0);
628 if(i<0) return STATUS_INVALIDHEADER;
629 img->dimt=n; if(img->dimt<1) return STATUS_INVALIDHEADER;
630 i=iftGetIntValue(&img->ift, 0, "x_dimension", &n, 0);
631 if(i<0) return STATUS_INVALIDHEADER;
632 img->dimx=n; if(img->dimx<1) return STATUS_INVALIDHEADER;
633 i=iftGetIntValue(&img->ift, 0, "y_dimension", &n, 0);
634 if(i<0) return STATUS_INVALIDHEADER;
635 img->dimy=n; if(img->dimy<1) return STATUS_INVALIDHEADER;
636 i=iftGetIntValue(&img->ift, 0, "z_dimension", &n, 0);
637 if(i<0) return STATUS_INVALIDHEADER;
638 img->dimz=n; if(img->dimz<1) return STATUS_INVALIDHEADER;
639
640 /* zoom */
641 i=iftGetFloatValue(&img->ift, 0, "zoom", &img->zoom, 0);
642 if(i<0) return STATUS_INVALIDHEADER;
643 if(img->zoom<0.0) return STATUS_INVALIDHEADER;
644
645 /* pixel size x */
646 i=iftGetFloatValue(&img->ift, 0, "pixel_size_x", &img->sizex, 0);
647 if(i>=0) {
648 if(img->sizex<0.0) return STATUS_INVALIDHEADER;
649 } else {
650 i=iftGetFloatValue(&img->ift, 0, "pixel_size", &img->sizex, 0);
651 if(i<0 || img->sizex<0.0) return STATUS_INVALIDHEADER;
652 img->sizex*=10.0;
653 }
654
655 /* pixel size y */
656 i=iftGetFloatValue(&img->ift, 0, "pixel_size_y", &img->sizey, 0);
657 if(i>=0) {
658 if(img->sizey<0.0) return STATUS_INVALIDHEADER;
659 } else {
660 i=iftGetFloatValue(&img->ift, 0, "pixel_size", &img->sizey, 0);
661 if(i<0 || img->sizey<0.0) return STATUS_INVALIDHEADER;
662 img->sizey*=10.0;
663 }
664
665 /* pixel size z, replaced by transaxial_bin_size, if available */
666 /* transaxial_bin_size */
667 i=iftGetFloatValue(&img->ift, 0, "pixel_size_z", &img->sizez, 0);
668 if(i>=0) {
669 if(img->sizez<0.0) return STATUS_INVALIDHEADER;
670 } else {
671 i=iftGetFloatValue(&img->ift, 0, "axial_plane_size", &img->sizez, 0);
672 if(i<0 || img->sizez<0.0) return STATUS_INVALIDHEADER;
673 img->sizez*=10.0;
674 }
675 i=iftGetFloatValue(&img->ift, 0, "transaxial_bin_size", &f, 0);
676 if(i>=0 && f>0.0) img->sizez=10.0*f;
677
678 /* isotope halflife */
679 i=iftGetFloatValue(&img->ift, 0, "isotope_half_life", &img->isotopeHalflife, 0);
680 if(i<0 || img->isotopeHalflife<0.0) return STATUS_INVALIDHEADER;
681
682 /* branching_fraction */
683 i=iftGetFloatValue(&img->ift, 0, "isotope_branching_fraction", &img->branchingFraction, 0);
684 if(i<0 || img->branchingFraction<0.0) return STATUS_INVALIDHEADER;
685
686 /* decay correction applied */
687 i=iftGetIntValue(&img->ift, 0, "decay_correction_applied", &n, 0);
688 if(i<0 || n<0.0) return STATUS_INVALIDHEADER;
691
692 /* calibration units */
693 i=iftGetIntValue(&img->ift, 0, "calibration_units", &n, 0);
694 if(i<0 || n<0.0) return STATUS_INVALIDHEADER;
695 switch(n) {
696 case 1: img->unit=CUNIT_NCI_PER_ML; break;
697 case 2: img->unit=CUNIT_BQ_PER_ML; break;
698 case 3: img->unit=CUNIT_HU; break;
699 case 0:
700 default: img->unit=CUNIT_UNKNOWN; break;
701 }
702
703 /* calibration factor */
704 i=iftGetFloatValue(&img->ift, 0, "calibration_factor", &img->calibrationFactor, 0);
705 if(i<0 || img->calibrationFactor<0.0) return STATUS_INVALIDHEADER;
707
708 /* FOV */
709 i=iftGetFloatValue(&img->ift, 0, "radial_fov", &img->transaxialFOV, 0);
710 if(i<0) return STATUS_INVALIDHEADER;
711 img->transaxialFOV*=10.0;
712
713 /* General */
715 img->type=IMG_TYPE_IMAGE;
716
717 /* Studynumber, if possible */
718 strcpy(key, "study"); n=1;
719 if((i=iftGet(&img->ift, key, 0))>=0)
720 n=studynr_from_fname2(img->ift.item[i].value, img->studyNr, 0);
721 if(n!=0) {
722 strcpy(key, "file_name");
723 if((i=iftGet(&img->ift, key, 0))>=0)
724 n=studynr_from_fname2(img->ift.item[i].value, img->studyNr, 0);
725 }
726 if(n!=0 && MICROPET_TEST>1) printf("Valid studyNr could not be read.\n");
727
728 /* Scan start */
729 strcpy(key, "scan_time");
730 if((i=iftGet(&img->ift, key, 0))<0) return STATUS_INVALIDHEADER;
731 n=sscanf(img->ift.item[i].value, "%s %s %d %d:%d:%d %d",
732 tmp2, tmp3, &scanstart.tm_mday,
733 &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
734 if(n==7) {
735 scanstart.tm_year=i-1900;
736 if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
737 else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
738 else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
739 else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
740 else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
741 else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
742 else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
743 else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
744 else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
745 else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
746 else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
747 else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
748 scanstart.tm_isdst=-1;
749 img->scanStart=timegm(&scanstart); //mktime(&scanstart);
750 if(img->scanStart<0) img->scanStart=0;
751 } else return STATUS_INVALIDHEADER;
752
753
754 imgSetStatus(img, STATUS_OK);
755 return STATUS_OK;
756}
757/******************************************************************************/
758
759/******************************************************************************/
769 const char *dbname,
771 IMG *img
772) {
773 char hdrfile[FILENAME_MAX];
774 int ret;
775
776 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, dbname);
777
778 /* Check the input */
779 if(img==NULL) return STATUS_FAULT;
780 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
781 imgSetStatus(img, STATUS_FAULT);
782 if(dbname==NULL) return STATUS_FAULT;
783
784 /* Determine the names of hdr and sif files */
785 ret=upetExists(dbname, hdrfile, NULL, IMG_TEST-1);
786 if(ret==0) return STATUS_NOFILE;
787
788 /* Read microPET header file into IFT */
789 iftEmpty(&img->ift);
790 ret=defRead(&img->ift, hdrfile, 0);
791 if(ret!=0) {
792 if(IMG_TEST>1) printf("defRead() return value := %d\n", ret);
793 return(STATUS_FAULT);
794 }
795 /* and set IMG contents */
796 ret=imgGetMicropetHeader(img);
797 if(ret!=0) {
798 imgSetStatus(img, ret);
799 return(ret);
800 }
801
802 return STATUS_OK;
803}
804/******************************************************************************/
805
806/******************************************************************************/
822 const char *fname,
824 int frame_to_read,
826 IMG *img,
828 int frame_index
829) {
830 FILE *fp;
831 int i, fi, ret, zi, xi, yi;
832 float *fdata=NULL, *fptr, f;
833 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX];
835
836
837 if(IMG_TEST) printf("\n%s(%s, %d, *img, %d)\n", __func__, fname, frame_to_read, frame_index);
838
839 /* Check the input */
840 if(img==NULL) return STATUS_FAULT;
841 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
842 if(fname==NULL) return STATUS_FAULT;
843 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
844 if(frame_to_read<1) return STATUS_FAULT;
845 imgSetStatus(img, STATUS_FAULT);
846
847 /* Determine the names of hdr and data files */
848 ret=upetExists(fname, hdrfile, datfile, IMG_TEST-1);
849 if(ret<2) {imgSetStatus(img, STATUS_NOFILE); return STATUS_NOFILE;}
850
851 /* Read microPET header file into IFT, if not available already */
852 imgSetStatus(img, STATUS_INVALIDHEADER);
853 if(img->ift.keyNr<10) {
854 iftEmpty(&img->ift);
855 ret=defRead(&img->ift, hdrfile, 0);
856 if(ret!=0) {
857 if(IMG_TEST>1) printf("defRead() return value := %d\n", ret);
858 return(STATUS_INVALIDHEADER);
859 }
860 if(IMG_TEST>3) printf("ift.keyNr := %d\n", img->ift.keyNr);
861 }
862
863 /* Read frame header information */
864 strcpy(key, "frame"); sprintf(value, "%d", frame_to_read-1);
865 fi=iftGetFullmatchFrom(&img->ift, 0, key, value, 0);
866 if(fi<0) {imgSetStatus(img, STATUS_NOMATRIX); return STATUS_NOMATRIX;}
867 i=iftGetFloatValue(&img->ift, fi+1, "frame_start", &f, 0);
868 if(i<0 || isnan(f)) {return STATUS_INVALIDHEADER;}
869 img->start[frame_index]=f;
870 i=iftGetFloatValue(&img->ift, fi+1, "frame_duration", &f, 0);
871 if(i<0 || isnan(f) || f<0.0) {return STATUS_INVALIDHEADER;}
872 img->end[frame_index]=img->start[frame_index]+f;
873 img->mid[frame_index]=0.5*(img->end[frame_index]+img->start[frame_index]);
874 /* decay correction */
875 i=iftGetFloatValue(&img->ift, fi+1, "decay_correction", &f, 0);
876 if(i<0 || isnan(f) || f<0.0) {return STATUS_INVALIDHEADER;}
877 img->decayCorrFactor[frame_index]=f;
878 //printf(" decayCorrFactor=%g\n", img->decayCorrFactor[0]);
879 /* set plane numbers */
880 for(zi=0; zi<img->dimz; zi++) img->planeNumber[zi]=zi+1;
881 /* prompts and randoms (delays), without checking the result */
882 i=iftGetFloatValue(&img->ift, fi+1, "prompts_rate", &img->prompts[frame_index], 0);
883 i=iftGetFloatValue(&img->ift, fi+1, "delays_rate", &img->randoms[frame_index], 0);
884
885 /* Open image datafile */
886 if(IMG_TEST>2) fprintf(stdout, "reading image data %s\n", datfile);
887 if((fp=fopen(datfile, "rb"))==NULL) {
888 imgSetStatus(img, STATUS_NOIMGDATA); return STATUS_NOIMGDATA;}
889
890 /* Allocate memory for one image frame */
891 fdata=malloc((size_t)img->dimx*img->dimy*img->dimz*sizeof(float));
892 if(fdata==NULL) {
893 fclose(fp); imgSetStatus(img, STATUS_NOMEMORY);
894 return STATUS_NOMEMORY;
895 }
896
897 /* Read the required image frame */
898 fptr=fdata;
899 ret=upetReadImagedata(fp, &img->ift, frame_to_read, fptr);
900 if(ret!=0 && IMG_TEST) fprintf(stdout, "upetReadImagedata() := %d\n", ret);
901 fclose(fp);
902 if(ret==3) { /* no more frames */
903 free(fdata); imgSetStatus(img, STATUS_NOMATRIX); return STATUS_NOMATRIX;}
904 if(ret!=0) {
905 free(fdata); imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
906
907 /* Copy pixel values to IMG */
908 fptr=fdata;
909 for(zi=0; zi<img->dimz; zi++)
910 for(yi=0; yi<img->dimy; yi++)
911 for(xi=0; xi<img->dimx; xi++)
912 img->m[zi][yi][xi][frame_index]=*fptr++;
913 free(fdata);
914
915 imgSetStatus(img, STATUS_OK); /* If the rest is failed, no problem */
916 return STATUS_OK;
917}
918/******************************************************************************/
919
920/******************************************************************************/
928 const char *fname,
930 IMG *img
931) {
932 int ret=0;
933
934 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, fname);
935 /* Check the input */
936 if(img==NULL) return STATUS_FAULT;
937 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
938 imgSetStatus(img, STATUS_FAULT);
939 if(fname==NULL) return STATUS_FAULT;
940
941 /* Read header information from file */
942 ret=imgReadMicropetHeader(fname, img);
943 if(IMG_TEST>1) printf("imgReadMicropetHeader() := %s\n", img->statmsg);
944 if(ret) return(ret);
945 if(IMG_TEST>3) imgInfo(img);
946
947 /* Allocate memory for one frame */
948 img->dimt=1;
949 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
950 if(ret) return STATUS_NOMEMORY;
951
952 /* Read the first frame */
953 ret=imgReadMicropetFrame(fname, 1, img, 0);
954 if(IMG_TEST>1) printf("imgReadMicropetFrame() := %s\n", img->statmsg);
955 if(ret) return(ret);
956
957 /* All went well */
958 imgSetStatus(img, STATUS_OK);
959 return STATUS_OK;
960}
961/******************************************************************************/
962
963/******************************************************************************/
974 const char *fname,
976 IMG *img
977) {
978 int fi=0, ret=0;
979
980 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, fname);
981 /* Check the input */
982 if(img==NULL) return STATUS_FAULT;
983 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
984 imgSetStatus(img, STATUS_FAULT);
985 if(fname==NULL) return STATUS_FAULT;
986
987 /* Read the first frame into IMG struct */
988 fi=0;
989 if(IMG_TEST>2) printf("reading frame %d\n", fi+1);
990 ret=imgReadMicropetFirstFrame(fname, img);
991 if(ret!=STATUS_OK) {
992 if(IMG_TEST>0) printf("imgReadMicropetFirstFrame() := %s\n", img->statmsg);
993 imgEmpty(img); return ret;
994 }
995 /* Read rest of the frames */
996 do {
997 fi++;
998 if(IMG_TEST>2) printf("reading frame %d\n", fi+1);
999 ret=imgReadMicropetFrame(fname, fi+1, img, fi);
1000 } while(ret==0);
1001 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
1002 if(IMG_TEST>0) printf("imgReadMicropetFrame() := %s\n", img->statmsg);
1003 imgEmpty(img); return ret;
1004 }
1005 if(IMG_TEST>1) printf("%d frame(s) were read.\n", fi);
1006
1007 /* All went well */
1008 imgSetStatus(img, STATUS_OK);
1009 return STATUS_OK;
1010}
1011/******************************************************************************/
1012
1013/******************************************************************************/
float branchingFraction(int isotope)
Definition branch.c:14
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69
void iftEmpty(IFT *ift)
Definition ift.c:60
int defRead(IFT *ift, char *filename, int verbose)
Definition iftfile.c:321
int iftGetFloatValue(IFT *ift, int si, const char *key, float *value, int verbose)
Definition iftsrch.c:228
int iftGet(IFT *ift, char *key, int verbose)
Definition iftsrch.c:15
int iftGetFullmatchFrom(IFT *ift, int si, const char *key, const char *value, int verbose)
Definition iftsrch.c:191
int iftGetIntValue(IFT *ift, int si, const char *key, int *value, int verbose)
Definition iftsrch.c:309
int IMG_TEST
Definition img.c:6
void imgInfo(IMG *image)
Definition img.c:359
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
void imgSetStatus(IMG *img, int status_index)
Definition img.c:345
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgMicropetPETToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition img_upet.c:85
int imgGetMicropetMainHeader(FILE *fp, IMG *img, float *calibration_factor, int verbose)
Definition img_upet.c:300
int imgGetMicropetHeader(IMG *img)
Definition img_upet.c:583
int imgGetMicropetFrameHeader(FILE *fp, IMG *img, int frame_index, int verbose)
Definition img_upet.c:457
int imgReadMicropetFirstFrame(const char *fname, IMG *img)
Definition img_upet.c:925
int imgMicropetCTToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition img_upet.c:196
int imgReadMicropetFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_upet.c:819
int imgMicropetToEcat7(char *upetname, char *ecatfile, int verbose)
Definition img_upet.c:15
int imgGetMicropetSIF(FILE *fp, SIF *sif)
Definition img_upet.c:517
int imgReadMicropetHeader(const char *dbname, IMG *img)
Definition img_upet.c:767
int imgReadMicropet(const char *fname, IMG *img)
Definition img_upet.c:971
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition imgfile.c:392
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
Header file for libtpcimgio.
#define IMG_E7
#define IMG_STATUS_OCCUPIED
int MICROPET_TEST
Definition micropet.c:6
int upetScanStart(FILE *fp, time_t *scant)
Definition micropet.c:194
#define IMG_DC_CORRECTED
#define IMG_STATUS_INITIALIZED
int upetGetImageDimensions(FILE *fp, int *z, int *x, int *y, int *f)
Definition micropet.c:154
#define IMG_DC_NONCORRECTED
#define IMG_MICROPET
int upetHeaderReadParameter(FILE *fp, char *parameter, char *value)
Definition micropet.c:16
int upetExists(const char *upetname, char *hdrfile, char *imgfile, int verbose)
Definition micropet.c:86
int sifSetmem(SIF *data, int frameNr)
Definition sif.c:56
int upetReadImagedata(FILE *fp, IFT *ift, int frame, float *data)
Definition micropet.c:243
#define IMG_TYPE_IMAGE
#define MAX_MICROPET_LINE_LEN
int studynr_from_fname2(char *fname, char *studynr, int force)
Definition studynr.c:67
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int studynr_from_fname(char *fname, char *studynr)
Definition studynr.c:119
int keyNr
Definition libtpcmisc.h:270
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279
float sizex
unsigned short int dimx
float branchingFraction
char type
float **** m
char decayCorrection
float transaxialFOV
char unit
char status
time_t scanStart
int _fileFormat
float * prompts
unsigned short int dimt
int * planeNumber
IFT ift
int scanner
float sizey
float * weight
float * start
unsigned short int dimz
unsigned short int dimy
float * end
float calibrationFactor
float zoom
float * decayCorrFactor
const char * statmsg
float isotopeHalflife
char studyNr[MAX_STUDYNR_LEN+1]
float * randoms
float * mid
float sizez
double * x1
double * prompts
int frameNr
double * x2
int version
time_t scantime
char isotope_name[8]
int colNr
double * randoms
double * trues