TPCCLIB
Loading...
Searching...
No Matches
micropet.c File Reference

Procedures for reading Siemens Inveon images. More...

#include "libtpcimgio.h"

Go to the source code of this file.

Functions

int upetHeaderReadParameter (FILE *fp, char *parameter, char *value)
int upetIsHeader (char *hdrfile)
int upetExists (const char *upetname, char *hdrfile, char *imgfile, int verbose)
int upetGetImageDimensions (FILE *fp, int *z, int *x, int *y, int *f)
int upetScanStart (FILE *fp, time_t *scant)
int upetReadImagedata (FILE *fp, IFT *ift, int frame, float *data)

Variables

int MICROPET_TEST

Detailed Description

Procedures for reading Siemens Inveon images.

Author
Vesa Oikonen

Definition in file micropet.c.

Function Documentation

◆ upetExists()

int upetExists ( const char * upetname,
char * hdrfile,
char * imgfile,
int verbose )

Check if specified image filename is a Concorde/microPET file

Returns
Returns 0 if it is not, and >0 if it is: 1 if header but not image is found, or 2 if both image and header are found.
Parameters
upetnameFilename, either header file, image file, or base name without extensions.
hdrfileIf upetname is a Concorde/microPET file, then header filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
imgfileIf upetname is a Concorde/microPET file, then image filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 86 of file micropet.c.

99 {
100 char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
101
102 if(upetname==NULL || strlen(upetname)==0) return(0);
103 if(verbose>0) printf("\n%s(%s, *str, *str)\n", __func__, upetname);
104
105 /* Construct the base file name wo extensions */
106 strlcpy(basefile, upetname, FILENAME_MAX);
107 cptr=strrchr(basefile, '.');
108 if(cptr!=NULL) {
109 if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
110 *cptr=(char)0;
111 }
112 cptr=strrchr(basefile, '.');
113 if(cptr!=NULL) {
114 if(strncasecmp(cptr, ".IMG", 4)==0 )
115 *cptr=(char)0;
116 }
117 if(verbose>1) printf("\n basefile := %s\n", basefile);
118
119 /* Header file exists? */
120 strlcpy(temp, basefile, FILENAME_MAX-4); strcat(temp, ".hdr");
121 if(access(temp, 0) == -1) {
122 strlcpy(temp, basefile, FILENAME_MAX-8); strcat(temp, ".img.hdr");
123 if(access(temp, 0) == -1) {
124 if(verbose>0) printf("\n hdr file not found or accessible.\n");
125 return(0);
126 }
127 }
128 /* Is this microPET header file? */
129 if(upetIsHeader(temp)==0) {
130 if(verbose>0)
131 printf("\n %s was not identified as microPET header file.\n", temp);
132 return(0);
133 }
134 /* Preserve header filename */
135 if(hdrfile!=NULL) strlcpy(hdrfile, temp, FILENAME_MAX);
136
137 /* Image file exists? */
138 strlcpy(temp, basefile, FILENAME_MAX); strcat(temp, ".img");
139 if(access(temp, 0) == -1) {
140 if(verbose>0) printf("\n %s not found or accessible.\n", temp);
141 return(1);
142 }
143 /* Preserve image filename */
144 if(imgfile!=NULL) strlcpy(imgfile, temp, FILENAME_MAX);
145
146 return(2);
147}
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int upetIsHeader(char *hdrfile)
Definition micropet.c:55

Referenced by imgFormatDetermine(), imgMicropetToEcat7(), imgRead(), imgReadMicropetFrame(), and imgReadMicropetHeader().

◆ upetGetImageDimensions()

int upetGetImageDimensions ( FILE * fp,
int * z,
int * x,
int * y,
int * f )

Read image dimensions from header.

Returns
Returns 0 when successful.
Parameters
fpFile pointer to MicroPET image header
zPointers to dimensions: planes
xPointers to dimensions: columns
yPointers to dimensions: rows
fPointers to dimensions: frames; if not existent (CT), enter NULL

Definition at line 154 of file micropet.c.

165 {
166 char tmp[MAX_MICROPET_LINE_LEN];
167
168 if(fp==NULL) return 1;
169 *z=*x=*y=0; if(f!=NULL) *f=0;
170 rewind(fp);
171
172 if(f!=NULL) {
173 if(upetHeaderReadParameter(fp, "time_frames", tmp)!=0) {
174 if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
175 }
176 *f=-1; (void)sscanf(tmp, "%d", f);
177 }
178 if(upetHeaderReadParameter(fp, "x_dimension", tmp)!=0) return 12;
179 *x=-1; (void)sscanf(tmp, "%d", x);
180 if(upetHeaderReadParameter(fp, "y_dimension", tmp)!=0) return 13;
181 *y=-1; (void)sscanf(tmp, "%d", y);
182 if(upetHeaderReadParameter(fp, "z_dimension", tmp)!=0) return 14;
183 *z=-1; (void)sscanf(tmp, "%d", z);
184 if(*z<1 || *x<1 || *y<1) return 2;
185 if(f!=NULL && *f<1) return 2;
186 return 0;
187}
#define MAX_MICROPET_LINE_LEN
int upetHeaderReadParameter(FILE *fp, char *parameter, char *value)
Definition micropet.c:16

Referenced by imgMicropetCTToEcat7(), and imgMicropetPETToEcat7().

◆ upetHeaderReadParameter()

int upetHeaderReadParameter ( FILE * fp,
char * parameter,
char * value )

Read specified parameter value from Concorde/MicroPET header.

Returns
Returns 0 if parameter was found, even if value is empty, and 1, if parameter was not found, and <0 in case of other errors.
Parameters
fpFile pointer to Concorde/MicroPET header; parameter is read starting from file pointer forward, therefore rewind file pointer before calling this routine if you want to search parameter from beginning.
parameterPointer to string which contains the header parameter name.
valuePointer to allocated string where parameter value will be written; memory for at least MAX_MICROPET_LINE_LEN chars must be allocated; NULL if not needed.

Definition at line 16 of file micropet.c.

27 {
28 char *cptr, tmp[MAX_MICROPET_LINE_LEN];
29
30 if(fp==NULL) return -1;
31 if(parameter==NULL || strlen(parameter)<1) return -2;
32 do {
33 if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) return 1;
34 if(tmp[0]=='#') continue;
35 if(strncasecmp(tmp, parameter, strlen(parameter))!=0) continue;
36 /* Get parameter value, if one exists */
37 cptr=tmp+strlen(parameter)+1;
38 if(strlen(cptr)>0) {
39 if(value!=0) strnCopyClean(value, cptr, MAX_MICROPET_LINE_LEN-1);
40 } else {
41 if(value!=0) strcpy(value, "");
42 }
43 /* In any case, we found the parameter */
44 if(MICROPET_TEST>9) printf("%s := %s\n", parameter, value);
45 return 0;
46 } while(1);
47 return 0;
48}
int MICROPET_TEST
Definition micropet.c:6
int strnCopyClean(char *str1, const char *str2, int maxlen)
Definition quots.c:52

Referenced by imgGetMicropetFrameHeader(), imgGetMicropetMainHeader(), imgGetMicropetSIF(), imgMicropetCTToEcat7(), imgMicropetToEcat7(), upetGetImageDimensions(), upetIsHeader(), and upetScanStart().

◆ upetIsHeader()

int upetIsHeader ( char * hdrfile)

Verify that given file is a valid Concorde/microPET file header file.

Returns
Returns 0 if not, and 1 if it is a valid header file.
Parameters
hdrfileConcorde/microPET file header filename, with correct extension

Definition at line 55 of file micropet.c.

58 {
59 char tmp[MAX_MICROPET_LINE_LEN];
60 FILE *fp;
61 int ret;
62
63 if(hdrfile==NULL || strlen(hdrfile)<5) return 0;
64 if(MICROPET_TEST>1) printf("\n%s(%s)\n", __func__, hdrfile);
65 if((fp=fopen(hdrfile, "r"))==NULL) return 0;
66 /* Check that first line starts with '#' */
67 if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) {fclose(fp); return 0;}
68 if(tmp[0]!='#') {fclose(fp); return 0;}
69 /* Check that certain header parameters do exist */
70 ret=upetHeaderReadParameter(fp, "version", tmp);
71 if(ret!=0) {fclose(fp); return 0;}
72 ret=upetHeaderReadParameter(fp, "model", tmp);
73 if(ret!=0) {fclose(fp); return 0;}
74 ret=upetHeaderReadParameter(fp, "institution", tmp);
75 if(ret!=0) {fclose(fp); return 0;}
76 fclose(fp);
77 return 1;
78}

Referenced by upetExists().

◆ upetReadImagedata()

int upetReadImagedata ( FILE * fp,
IFT * ift,
int frame,
float * data )

Reads microPET image data, scaling values to floats if necessary.

Reads only one frame at a time!

Returns
0 when successful, otherwise <>0.
Parameters
fpfile opened previously in binary mode
iftmicroPET header in IFT struct
frameframe number to read [1..number of frames]
datapointer to image float data allocated previously

Definition at line 243 of file micropet.c.

252 {
253 int dimx, dimy, dimz=1, dimt=1;
254 int i, fi, data_type, data_bytes, little;
255 char *mdata, *mptr;
256 float f, cf, bf, *fptr;
257 short int *sptr;
258 int *iptr;
260
261
262 if(MICROPET_TEST) printf("%s(fp, ift, %d, data)\n", __func__, frame);
263
264 /* Check the arguments */
265 if(frame<=0 || fp==NULL || ift==NULL || data==NULL) return(1);
266
267 /* Get the image dimensions from header */
268 i=iftGetIntValue(ift, 0, "time_frames", &dimt, 0);
269 if(i<0 || dimt<1) {
270 i=iftGetIntValue(ift, 0, "total_frames", &dimt, 0);
271 if(i<0 || dimt<1) return 4;
272 }
273 i=iftGetIntValue(ift, 0, "x_dimension", &dimx, 0);
274 if(i<0 || dimx<1) return 4;
275 i=iftGetIntValue(ift, 0, "y_dimension", &dimy, 0);
276 if(i<0 || dimy<1) return 4;
277 i=iftGetIntValue(ift, 0, "z_dimension", &dimz, 0);
278 if(i<0 || dimz<1) return 4;
279 long long pxlNr=dimx*dimy*dimz;
280 if(pxlNr<1) return(4);
281 if(frame>dimt) return(3); // do not change this return value
282
283 /* Get the data type (little=Intel, big=Sun) */
284 i=iftGetIntValue(ift, 0, "data_type", &data_type, 0);
285 if(i<0 || data_type<1) return 5;
286 switch(data_type) {
287 case 1: data_bytes=1; little=little_endian(); break;
288 case 2: data_bytes=2; little=1; break;
289 case 3: data_bytes=4; little=1; break;
290 case 4: data_bytes=4; little=1; break;
291 case 5: data_bytes=4; little=0; break;
292 case 6: data_bytes=2; little=0; break;
293 case 7: data_bytes=4; little=0; break;
294 default: return 5;
295 }
296 long long rawSize=pxlNr*data_bytes;
297 if(MICROPET_TEST>0) {
298 printf(" data_type=%d\n data_bytes=%d\n", data_type, data_bytes);
299 printf(" pxlNr=%lld\n rawSize=%lld\n", pxlNr, rawSize);
300 }
301
302 /* Allocate memory for the binary data */
303 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
304
305 /* Seek the start of current frame data */
306 long long start_pos=(frame-1)*rawSize;
307 if(MICROPET_TEST>2) printf(" start_pos=%lld\n", start_pos);
308 fseeko(fp, start_pos, SEEK_SET);
309 if(ftello(fp)!=start_pos) {
310 if(MICROPET_TEST>5) printf("could not move to start_pos\n");
311 free(mdata); return(7);
312 }
313
314 /* Read the data */
315 mptr=mdata;
316 {
317 size_t n=fread(mptr, rawSize, 1, fp);
318 if(n<1) {
319 if(MICROPET_TEST>5)
320 printf("could read only %zu bytes when request was %lld\n", n, rawSize);
321 free(mdata); return(8);
322 }
323 }
324
325 /* Convert byte order if necessary */
326 mptr=mdata;
327 if(little!=little_endian()) {
328 if(MICROPET_TEST>0) {printf("byte conversion\n"); fflush(stdout);}
329 switch(data_bytes) {
330 case 1: /* no conversion needed */ break;
331 case 2: swabip(mptr, rawSize); break;
332 case 4: swawbip(mptr, rawSize); break;
333 default:
334 if(MICROPET_TEST>5) printf("unsupported data_type := %d\n", data_type);
335 free(mdata); return(5);
336 }
337 }
338
339 /* Get scale factor for this frame */
340 strcpy(key, "frame"); sprintf(value, "%d", frame-1);
341 fi=iftGetFullmatchFrom(ift, 0, key, value, 0); if(fi<0) {free(mdata); return(6);}
342 i=iftGetFloatValue(ift, fi+1, "scale_factor", &f, 0);
343 if(i<0 || f<=0.0) {free(mdata); return(6);}
344 if(MICROPET_TEST>5) printf(" scale_factor := %g\n", f);
345
346 /* calibration factor */
347 i=iftGetFloatValue(ift, 0, "calibration_factor", &cf, 0);
348 if(i<0 || cf<0.0) {free(mdata); return 7;}
349 if(MICROPET_TEST>5) printf(" calibration_factor := %g\n", cf);
350 /* branching_fraction */
351 i=iftGetFloatValue(ift, 0, "isotope_branching_fraction", &bf, 0);
352 if(i<0 || bf<0.0) {free(mdata); return 7;}
353 if(MICROPET_TEST>5) printf(" branching_fraction := %g\n", bf);
354 if(cf>0.0) {f=cf; if(bf>0.0) f/=bf;}
355 if(MICROPET_TEST>5) printf(" f := %g\n", f);
356
357 /* Copy data to float pixel values */
358 mptr=mdata; fptr=data;
359 switch(data_type) {
360 case 1: // unsigned char
361 for(long long i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(float)(*mptr);
362 break;
363 case 2: // short int
364 case 6:
365 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
366 sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
367 }
368 break;
369 case 3: // int
370 case 7:
371 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
372 iptr=(int*)mptr; *fptr=f*(float)(*iptr);
373 }
374 break;
375 case 4: // float
376 case 5:
377 memcpy(fptr, mptr, pxlNr*data_bytes);
378 for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=f;
379 break;
380 default:
381 if(MICROPET_TEST>5)
382 printf("unsupported data_type := %d\n", data_type);
383 free(mdata); return(5);
384 }
385
386 free(mdata);
387 if(MICROPET_TEST>1) printf("%s() succeeded\n", __func__);
388 return(0);
389}
int iftGetFloatValue(IFT *ift, int si, const char *key, float *value, int verbose)
Definition iftsrch.c:228
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
void swabip(void *buf, long long int size)
Definition swap.c:72
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14

Referenced by imgReadMicropetFrame().

◆ upetScanStart()

int upetScanStart ( FILE * fp,
time_t * scant )

Read scan start time from Concorde/MicroPET header.

Returns
Returns 0 when successful.
Parameters
fpFile pointer to Concorde/MicroPET header
scantPointer to time_t where time and date will be saved

Definition at line 194 of file micropet.c.

199 {
200 char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
201 int n, i;
202#pragma clang diagnostic push
203#pragma clang diagnostic ignored "-Wmissing-field-initializers"
204 struct tm scanstart={0};
205#pragma clang diagnostic pop
206
207 if(fp==NULL || scant==NULL) return 1;
208
209 rewind(fp);
210 if(upetHeaderReadParameter(fp, "scan_time", tmp)!=0) return 2;
211 n=sscanf(tmp, "%s %s %d %d:%d:%d %d", tmp2, tmp3, &scanstart.tm_mday,
212 &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
213 if(n==7) {
214 scanstart.tm_year=i-1900;
215 if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
216 else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
217 else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
218 else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
219 else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
220 else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
221 else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
222 else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
223 else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
224 else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
225 else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
226 else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
227 scanstart.tm_isdst=-1;
228 //*scant=mktime(&scanstart); if(*scant<0) return 4;
229 *scant=timegm(&scanstart); if(*scant<0) return 4;
230 } else return 5;
231
232 return 0;
233}
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69

Referenced by imgGetMicropetSIF(), imgMicropetCTToEcat7(), and imgMicropetPETToEcat7().

Variable Documentation

◆ MICROPET_TEST

int MICROPET_TEST

Verbose prints from microPET functions

Definition at line 6 of file micropet.c.

Referenced by imgGetMicropetHeader(), upetHeaderReadParameter(), upetIsHeader(), and upetReadImagedata().