TPCCLIB
Loading...
Searching...
No Matches
mkcalhdr.c
Go to the documentation of this file.
1
28/*****************************************************************************/
29#include "tpcclibConfig.h"
30/*****************************************************************************/
31#include <stdio.h>
32#include <stdlib.h>
33#include <math.h>
34#include <string.h>
35#include <unistd.h>
36#include <ctype.h>
37#include <dirent.h>
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <sys/types.h>
41#include <time.h>
42/*****************************************************************************/
43#include "libtpcmisc.h"
44#include "libtpcimgio.h"
45/*****************************************************************************/
46
47/*****************************************************************************/
48static char *info[] = {
49 "Calculates HRRT calibration factor, assuming that there is a cylindrical",
50 "phantom with 20 cm diameter in the FOV.",
51 "Resulting calibration header file is written in file",
52 "STUDY_RECMETHOD_iMNsXY_sS.cal.hdr, where STUDY is the part of the calibration",
53 "study name preceding delimiter \"_\", \"-\", \".\" or space, RECMETHOD is",
54 "the utilised reconstruction method, iMN is the number of iterations preceded",
55 "by char i, sXY is the number of subsets preceded by char s and sS is the span",
56 "preceded by char s. If calibration is calculated for 128x128 matrix size,",
57 "suffix m128 is appended in header file name.",
58 " ",
59 "Efficient (sensitivity) factor for each plane is calculated as mean over",
60 "planes 19-188 divided by plane average. Efficient factor is set to zero for",
61 "planes 1-6 and 201-207 (HRRT has 207 image planes).",
62 " ",
63 "Usage: @P [Options] -a=<Activity> Interfile(s)",
64 " ",
65 "Options:",
66 " -a=<Activity> or -a <Activity>",
67 " Activity concentration at scan start time in Bq/mL; required option.",
68 " -l=<First eff plane> or -l <First eff plane>",
69 " First plane for which the efficient factor is set; default is 7.",
70 " -L=<Last eff plane> or -L <Last eff plane>",
71 " Last plane for which the efficient factor is set; default is 200.",
72 " -m=<First mean plane> or -m <First mean plane>",
73 " First plane used for mean calculation; default is 19.",
74 " -M=<Last mean plane> or M <Last mean plane>",
75 " Last plane used for mean calculation; default is 188.",
76 " -sd=<Y|n>",
77 " Calculate standard deviation inside VOI (y, default), or not (n).",
78 " -stdoptions", // List standard options like --help, -v, etc
79 " ",
80 "Example:",
81 " @P -a=4120 calrx-0004-2006.3.1.15.16.23_em_3D_256i01.i",
82 " ",
83// "See also: if2e7, run_if2e7",
84// " ",
85 "Keywords: HRRT, Interfile, calibration",
86 0};
87/*****************************************************************************/
88
89/*****************************************************************************/
90/* Turn on the globbing of the command line, since it is disabled by default in
91 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
92 In Unix&Linux wildcard command line processing is enabled by default. */
93/*
94#undef _CRT_glob
95#define _CRT_glob -1
96*/
97int _dowildcard = -1;
98/*****************************************************************************/
100/*****************************************************************************/
107 char *imgName,
109 int firstplane,
111 int lastplane,
113 int startplane,
115 int endplane,
117 float activityConcentration,
119 int calcSTDV,
122 char *status,
124 int verbose
125) {
126 int i, j, k, ret;
127 char buf[512];
128
129 /* Check the input */
130 if(status!=NULL) sprintf(status, "invalid filename");
131 if(imgName==NULL || !imgName[0]) return(1);
132 if(status!=NULL) sprintf(status, "invalid efficient plane settings");
133 if(firstplane<1 || firstplane>lastplane) return(2);
134 if(status!=NULL) sprintf(status, "invalid mean plane settings");
135 if(startplane<1 || startplane>endplane) return(3);
136 if(status!=NULL) sprintf(status, "invalid activity concentration");
137
138 /*
139 * Read Interfile header
140 */
141 char hdrFile[FILENAME_MAX];
142 char imgFile[FILENAME_MAX];
143 strlcpy(imgFile, imgName, FILENAME_MAX);
144 strlcpy(hdrFile, imgName, FILENAME_MAX-4);
145 strcat(hdrFile, ".hdr");
146 if(verbose>2) printf("reading header in %s\n", hdrFile);
147 IFT ift; iftInit(&ift);
148 ret=iftRead(&ift, hdrFile, 0, 0);
149 /* If error, try to add .i to filenames */
150 if(ret!=0) {
151 strlcpy(hdrFile, imgName, FILENAME_MAX-4);
152 strcat(hdrFile, ".i.hdr");
153 if(verbose>2) printf("reading header in %s\n", hdrFile);
154 ret=iftRead(&ift, hdrFile, 0, 0);
155 if(ret==0) {
156 /* That was good, therefore fix image filename too */
157 strlcpy(imgFile, imgName, FILENAME_MAX);
158 strcat(imgFile, ".i");
159 }
160 }
161 /* In case of error, stop trying */
162 if(ret!=0) {
163 if(status!=NULL) sprintf(status, "cannot read file");
164 return(11);
165 }
166
167 /* Matrix size */
168 int dimx, dimy, dimz;
169 if(iftGetIntValue(&ift, 0, "matrix size [1]", &dimx, 0)<0 || dimx<1) {
170 if(status!=NULL) sprintf(status, "cannot read dimx");
171 iftEmpty(&ift); return(21);
172 }
173 if(iftGetIntValue(&ift, 0, "matrix size [2]", &dimy, 0)<0 || dimy<1) {
174 if(status!=NULL) sprintf(status, "cannot read dimy");
175 iftEmpty(&ift); return(22);
176 }
177 if(iftGetIntValue(&ift, 0, "matrix size [3]", &dimz, 0)<0 || dimz<1) {
178 if(status!=NULL) sprintf(status, "cannot read dimz");
179 iftEmpty(&ift); return(23);
180 }
181 if(verbose>1) printf(" matrix_size := %d x %d x %d\n", dimx, dimy, dimz);
182 /* Check plane limits against dimz */
183 if(lastplane>dimz) {
184 if(status!=NULL) sprintf(status, "invalid efficient plane settings");
185 iftEmpty(&ift); return(24);
186 }
187 if(endplane>dimz) {
188 if(status!=NULL) sprintf(status, "invalid mean plane settings");
189 iftEmpty(&ift); return(25);
190 }
191 if(verbose>0) {
192 printf(" Efficient factor set to 0 for %d first planes\n", firstplane-1);
193 printf(" Efficient factor set to 0 for %d last planes\n", dimz-lastplane);
194 printf(" Excluding %d first planes from the mean calculation\n", startplane-1);
195 printf(" Excluding %d last planes from the mean calculation\n", dimz-endplane-1);
196 }
197
198 /* Pixel size */
199 double xsize, ysize, zsize;
200 if(iftGetDoubleValue(&ift, 0, "scaling factor (mm/pixel) [1]", &xsize, 0)<0 || xsize<=0.0) {
201 if(status!=NULL) sprintf(status, "cannot read x size");
202 iftEmpty(&ift); return(31);
203 }
204 if(iftGetDoubleValue(&ift, 0, "scaling factor (mm/pixel) [2]", &ysize, 0)<0 || ysize<=0.0) {
205 if(status!=NULL) sprintf(status, "cannot read y size");
206 iftEmpty(&ift); return(32);
207 }
208 if(iftGetDoubleValue(&ift, 0, "scaling factor (mm/pixel) [3]", &zsize, 0)<0 || zsize<=0.0) {
209 if(status!=NULL) sprintf(status, "cannot read z size");
210 iftEmpty(&ift); return(33);
211 }
212 if(verbose>1) printf(" pixel_size := %g x %g x %g\n", xsize, ysize, zsize);
213 if(fabs(xsize-ysize)>0.01) {
214 if(status!=NULL) sprintf(status, "invalid x and y pixel sizes");
215 iftEmpty(&ift); return(34);
216 }
217 /* Calculate ROI radius in pixels */
218 float ROIradius;
219 ROIradius=75.0/xsize; /* 15 cm diameter ROI = 75 mm Radius */
220 if(verbose>0) printf(" ROIradius := %g\n", ROIradius);
221
222 /* Scan duration */
223 double scanDuration;
224 if(iftGetDoubleValue(&ift, 0, "image duration", &scanDuration, 0)<0 || scanDuration<=0.0) {
225 if(status!=NULL) sprintf(status, "cannot read scan duration");
226 iftEmpty(&ift); return(41);
227 }
228 if(verbose>1) printf(" scanDuration := %g\n", scanDuration);
229
230 /* Branching fraction */
231 double branchingFraction;
232 if(iftGetDoubleValue(&ift, 0, "branching factor", &branchingFraction, 0)<0 || branchingFraction<=0.0) {
233 if(status!=NULL) sprintf(status, "cannot read branching fraction");
234 iftEmpty(&ift); return(42);
235 }
236 if(verbose>1) printf(" branchingFraction := %g\n", branchingFraction);
237
238 /* Halflife */
239 double halflife;
240 if(iftGetDoubleValue(&ift, 0, "isotope halflife", &halflife, 0)<0 || halflife<=0.0) {
241 if(status!=NULL) sprintf(status, "cannot read halflife");
242 iftEmpty(&ift); return(43);
243 }
244 if(verbose>1) printf(" halflife := %g\n", halflife);
245
246 /* Dead time */
247 double deadtimeCorFactor;
248 if(iftGetDoubleValue(&ift, 0, "Dead time correction factor", &deadtimeCorFactor, 0)<0
249 || deadtimeCorFactor<=0.0) {
250 if(status!=NULL) sprintf(status, "cannot read dead time");
251 iftEmpty(&ift); return(44);
252 }
253 if(verbose>1) printf(" deadtimeCorFactor := %g\n", deadtimeCorFactor);
254
255 /* Span */
256 int span;
257 if(iftGetIntValue(&ift, 0, "axial compression", &span, 0)<0) {
258 if(status!=NULL) sprintf(status, "cannot read span");
259 iftEmpty(&ift); return(45);
260 }
261 if(verbose>1) printf(" span := %d\n", span);
262
263 /* Reconstruction method */
264 char recMethod[256];
265 i=iftGetFrom(&ift, 0, "method of reconstruction used", 0);
266 if(i<0) i=iftGetFrom(&ift, 0, "reconstruction method", 0);
267 if(i<0) {
268 if(status!=NULL) sprintf(status, "cannot read reconstruction method");
269 iftEmpty(&ift); return(46);
270 }
271 strlcpy(buf, ift.item[i].value, 256);
272 for(i=j=0; i<(int)strlen(buf); i++) {
273 if(buf[i]!='/' && buf[i]!=' ') recMethod[j++]=buf[i];
274 }
275 recMethod[j]=(char)0;
276 if(verbose>1) printf(" reconstruction method := %s\n", recMethod);
277
278 /* Nr of iterations (not always present) */
279 int numIter;
280 if(iftGetIntValue(&ift, 0, "number of iterations", &numIter, 0)<0) {
281 numIter=0;
282 }
283 if(verbose>1) printf(" numIter := %d\n", numIter);
284
285 /* Nr of subsets (not always present) */
286 int numSubsets;
287 if(iftGetIntValue(&ift, 0, "number of subsets", &numSubsets, 0)<0) {
288 numSubsets=0;
289 }
290 if(verbose>1) printf(" numSubsets := %d\n", numSubsets);
291
292 /* Check that image data is saved as 4-byte floats */
293 i=iftGetFrom(&ift, 0, "number format", 0);
294 if(i<0 || strcasecmp(ift.item[i].value, "float")!=0) {
295 if(status!=NULL) sprintf(status, "data is not stored as floats");
296 iftEmpty(&ift); return(51);
297 }
298 i=iftGetFrom(&ift, 0, "number of bytes per pixel", 0);
299 if(i<0 || strcasecmp(ift.item[i].value, "4")!=0) {
300 if(status!=NULL) sprintf(status, "data is not stored as 4-byte floats");
301 iftEmpty(&ift); return(52);
302 }
303
304 /* free header data */
305 iftEmpty(&ift);
306
307
308 /*
309 * Read Interfile image data
310 */
311 if(verbose>2) printf("reading image data in %s\n", imgFile);
312 float *img;
313 unsigned int pxlNr, n;
314 pxlNr=dimx*dimy*dimz;
315 img=(float*)malloc(pxlNr*sizeof(float));
316 if(img==NULL) {
317 if(status!=NULL) sprintf(status, "out of memory");
318 return(100);
319 }
320 FILE *fp;
321 fp=fopen(imgFile, "rb");
322 if(fp==NULL) {
323 if(status!=NULL) sprintf(status, "cannot open image file");
324 free(img); return(101);
325 }
326 n=fread(img, sizeof(float), pxlNr, fp);
327 fclose(fp);
328 if(n<pxlNr) {
329 if(status!=NULL) sprintf(status, "cannot read image");
330 free(img); return(102);
331 }
332 /* Swap bytes if necessary */
333 if(little_endian()==0) {
334 if(verbose>1) printf(" swapping bytes\n");
335 for(n=0; n<pxlNr; n++) swawbip(&img[n], sizeof(float));
336 }
337
338 /*
339 * ROI evaluation
340 */
341 if(verbose>2) printf("ROI evaluation (circular, centered, 15 cm diameter)\n");
342 int numpix=0, planenumpix, x, y, z;
343 double sqrSum=0.0;
344 double VoISTDV=0.0;
345 float ROIsum=0.0, ROIavg;
346 float planesum, xsum, ysum, x0, y0;
347 float planeROIavg[dimz], planeROIsum;
348 for(i=0; i<dimz; i++) planeROIavg[i]=0.0;
349 j=k=0; //dimx*dimy*(startplane-1);
350 //for(z=startplane-1; z<endplane; z++) {
351 for(z=0; z<dimz; z++) {
352 planesum=xsum=ysum=0.0;
353 /* centre of gravity */
354 for(y=0; y<dimy; y++) {
355 for(x=0; x<dimx; x++) {
356 planesum+=img[j];
357 xsum+=(float)x*img[j];
358 ysum+=(float)y*img[j];
359 j++;
360 }
361 }
362 x0=xsum/planesum;
363 y0=ysum/planesum;
364 if(!isnormal(x0) || (int)x0<=0 || (int)x0>=dimx) x0=0.5*dimx;
365 if(!isnormal(y0) || (int)y0<=0 || (int)y0>=dimy) y0=0.5*dimy;
366 if(verbose>3) printf(" ROIcenter[%d] = (%f/%f)\n", z, x0, y0);
367 planeROIsum=0.0;
368 planenumpix=0;
369 for(y=0; y<dimy; y++) {
370 for(x=0; x<dimx; x++) {
371 if(hypotf((float)x-x0, (float)y-y0) <= ROIradius) {
372 planenumpix++;
373 planeROIsum+=img[k];
374 if((z+1)>=startplane && (z+1)<=endplane) {
375 /* Only these are included in the VOI mean */
376 numpix++;
377 ROIsum+=img[k];
378 }
379 }
380 k++;
381 }
382 }
383 planeROIavg[z]=planeROIsum/(float)planenumpix;
384 if(verbose>0) printf(" VOIaverage[%d] := %g\n", z, planeROIavg[z]);
385 }
386 ROIavg=ROIsum/(float)numpix;
387 if(verbose>2) printf(" ROIavg := %g\n", ROIavg);
388
389 /* Calculate standard deviation inside VOI, if requested */
390 if(calcSTDV!=0) {
391 j=k=dimx*dimy*(startplane-1);
392 for(z=startplane; z<endplane; z++) {
393 planesum=xsum=ysum=0.0;
394 /* centre of gravity */
395 for(y=0; y<dimy; y++) {
396 for(x=0; x<dimx; x++) {
397 planesum+=img[j];
398 xsum+=(float)x*img[j];
399 ysum+=(float)y*img[j];
400 j++;
401 }
402 }
403 x0=xsum/planesum;
404 y0=ysum/planesum;
405 for(y=0; y<dimy; y++) {
406 for(x=0; x<dimx; x++) {
407 if(hypotf((float)x-x0, (float)y-y0) <= ROIradius) {
408 sqrSum+=(img[k]-ROIavg)*(img[k]-ROIavg);
409 }
410 k++;
411 }
412 }
413 }
414 VoISTDV=sqrt(sqrSum/(double)numpix);
415 if(verbose>2) {
416 fprintf(stdout, " standard deviation in VoI := %f\n", VoISTDV);
417 fflush(stdout);
418 }
419 }
420
421 free(img);
422
423
424 /*
425 * Calculate calibration factor
426 */
427 if(verbose>2) printf("Calculating calibration factor\n");
428 /* normalise mean for duration of acquisition */
429 double corROIavg=ROIavg/scanDuration;
430 /* divide by branching fraction */
431 corROIavg=corROIavg/branchingFraction;
432 /* in frame decay correction */
433 double dfrac=scanDuration/halflife*log(2);
434 dfrac/=(1.0-exp(-dfrac));
435 if(verbose>0) printf(" decay correction := %f\n", dfrac);
436 corROIavg*=dfrac;
437 /* deadtime correction */
438 corROIavg*=deadtimeCorFactor;
439 /* calculate calibration factor */
440 float calibFactor=activityConcentration/corROIavg;
441 if(verbose>2) {
442 fprintf(stdout, " calibration factor := %e (counts/s)/(Bq/ml)\n",
443 calibFactor);
444 fflush(stdout);
445 }
446
447 /*
448 * Write output file
449 */
450 if(verbose>2) printf("Writing output file\n");
451 /* Construct output file name */
452 char *cptr, calHdrName[512];
453 strlcpy(buf, imgFile, 512);
454 if((cptr=strpbrk(buf, "_-. "))!=NULL) *cptr='\0';
455 strcpy(calHdrName, buf);
456 strlcat(calHdrName, "_", 512); strlcat(calHdrName, recMethod, 512);
457 if(numIter>0) {
458 sprintf(buf, "_i%02d", numIter); strlcat(calHdrName, buf, 512);
459 } else {
460 strlcat(calHdrName, "_i0", 512);
461 }
462 sprintf(buf, "s%d", numSubsets); strlcat(calHdrName, buf, 512);
463 sprintf(buf, "_s%d", span); strlcat(calHdrName, buf, 512);
464 if(dimx!=256) {sprintf(buf, "_m%d", dimx); strlcat(calHdrName, buf, 512);}
465 strlcat(calHdrName, ".cal.hdr", 512);
466 /* Fill IFT struct */
467 ret=iftPut(&ift, NULL, imgName, ";", 0);
468 if(ret==0)
469 ret=iftPutDouble(&ift, "activity concentration used (Bq/ml)",
470 (double)activityConcentration, ";", 0);
471 if(ret==0) {
472 sprintf(buf, "VOI mean from planes %d - %d", startplane, endplane);
473 ret=iftPut(&ift, NULL, buf, ";", 0);
474 }
475 if(ret==0) ret=iftPutDouble(&ift, "mean activity concentration in VOI", (double)ROIavg, ";", 0);
476 if(calcSTDV!=0) {
477 if(ret==0) ret=iftPutDouble(&ift, "standard deviation in VOI", (double)VoISTDV, ";", 0);
478 if(ret==0) ret=iftPutDouble(&ift, "CV in VOI", (double)VoISTDV/ROIavg, ";", 0);
479 }
480 if(ret==0)
481 ret=iftPutDouble(&ift, "corrected VOI activity concentration", (double)corROIavg, ";", 0);
482 if(ret==0) ret=iftPut(&ift, NULL, " ", NULL, 0);
483 if(ret==0) ret=iftPut(&ift, NULL, "calibration factor in (Bq/cc)/(counts/s)", ";", 0);
484 if(ret==0) ret=iftPutDouble(&ift, "calibration factor", (double)calibFactor, NULL, 0);
485 if(ret==0) ret=iftPut(&ift, NULL, " ", NULL, 0);
486 for(j=1; j<=dimz && ret==0; j++) {
487 sprintf(buf, "efficient factor for plane %d", j-1);
488 if(j<firstplane || j>lastplane)
489 ret=iftPutDouble(&ift, buf, 0.0, NULL, 0);
490 else
491 ret=iftPutDouble(&ift, buf, ROIavg/planeROIavg[j-1], NULL, 0);
492 }
493 if(ret!=0) {
494 if(status!=NULL) sprintf(status, "cannot make calibration file");
495 iftEmpty(&ift); return(201);
496 }
497 if(verbose>0) {
498 printf("\n--------------------------------------------------\n");
499 printf("%s :\n", calHdrName);
500 printf("--------------------------------------------------\n");
501 iftWrite(&ift, "stdout", 0);
502 }
503 /* Write the file */
504 ret=iftWrite(&ift, calHdrName, 0);
505 iftEmpty(&ift);
506 if(ret!=0) {
507 if(status!=NULL) sprintf(status, "cannot write calibration file");
508 return(202);
509 }
510 fprintf(stdout, "\ncalibrations written in %s\n\n", calHdrName);
511 fflush(stdout);
512
513 return(0);
514}
515/*****************************************************************************/
517/*****************************************************************************/
521int main(int argc, char **argv)
522{
523 int ai, help=0, version=0, verbose=1;
524 int ret, fileNr=0, firstfile=0;
525 int calcSTDV=1; // 0=SD not calculated; 1=SD calculated
526 float activityConcentration=0.0;
527 int firstplane, lastplane, startplane, endplane;
528 char imgfile[FILENAME_MAX];
529 char *cptr;
530
531
532 /*
533 * Get arguments
534 */
535 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
536 firstplane=7; lastplane=200; startplane=19; endplane=188;
537 imgfile[0]=(char)0;
538 /* Options */
539 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
540 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
541 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
542 if(strncasecmp(cptr, "SD=", 3)==0) {
543 cptr+=3;
544 if(strncasecmp(cptr, "YES", 1)==0 || strcasecmp(cptr, "ON")==0) {
545 calcSTDV=1; continue;
546 }
547 if(strncasecmp(cptr, "NO", 1)==0 || strcasecmp(cptr, "OFF")==0) {
548 calcSTDV=0; continue;
549 }
550 } else if(strncasecmp(cptr, "A=", 2)==0) {
551 double v;
552 ret=atof_with_check(cptr+2, &v);
553 if(ret==0 && v>0.0) {activityConcentration=v; continue;}
554 } else if(strcasecmp(cptr, "A")==0 && ai<argc-1) {
555 ai++; cptr=argv[ai];
556 double v;
557 ret=atof_with_check(cptr, &v);
558 if(ret==0 && v>0.0) {activityConcentration=v; continue;}
559 } else if(strncmp(cptr, "l=", 2)==0) {
560 ret=atoi_with_check(cptr+2, &firstplane);
561 if(ret==0 && firstplane>0) {continue;}
562 } else if(strcmp(cptr, "l")==0 && ai<argc-1) {
563 ai++; cptr=argv[ai];
564 ret=atoi_with_check(cptr, &firstplane);
565 if(ret==0 && firstplane>0) {continue;}
566 } else if(strncmp(cptr, "L=", 2)==0) {
567 ret=atoi_with_check(cptr+2, &lastplane);
568 if(ret==0 && lastplane>0) {continue;}
569 } else if(strcmp(cptr, "L")==0 && ai<argc-1) {
570 ai++; cptr=argv[ai];
571 ret=atoi_with_check(cptr, &lastplane);
572 if(ret==0 && lastplane>0) {continue;}
573 } else if(strncmp(cptr, "m=", 2)==0) {
574 ret=atoi_with_check(cptr+2, &startplane);
575 if(ret==0 && startplane>0) {continue;}
576 } else if(strcmp(cptr, "m")==0 && ai<argc-1) {
577 ai++; cptr=argv[ai];
578 ret=atoi_with_check(cptr, &startplane);
579 if(ret==0 && startplane>0) {continue;}
580 } else if(strncmp(cptr, "M=", 2)==0) {
581 ret=atoi_with_check(cptr+2, &endplane);
582 if(ret==0 && endplane>0) {continue;}
583 } else if(strcmp(cptr, "M")==0 && ai<argc-1) {
584 ai++; cptr=argv[ai];
585 ret=atoi_with_check(cptr, &endplane);
586 if(ret==0 && endplane>0) {continue;}
587 }
588 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
589 return(1);
590 } else break;
591
592 /* Print help or version? */
593 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
594 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
595 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
596
597 /* Process other arguments, starting from the first non-option */
598 for(; ai<argc; ai++) {
599 if(firstfile==0) firstfile=ai;
600 fileNr++;
601 }
602 /* Did we get all the information that we need? */
603 if(fileNr==0) {tpcPrintUsage(argv[0], info, stderr); return(1);}
604
605 /* Are options set to reasonable values? */
606 if(firstplane>=lastplane) {
607 fprintf(stderr, "Error: invalid efficient plane settings.\n");
608 return(1);
609 }
610 if(startplane>=endplane) {
611 fprintf(stderr, "Error: invalid mean plane settings.\n");
612 return(1);
613 }
614 if(activityConcentration<=0.0) {
615 fprintf(stderr, "Error: missing activity concentration.\n");
616 return(1);
617 }
618 if(activityConcentration<=50.0) {
619 fprintf(stderr, "Warning: activity concentration must be given in Bq/mL.\n");
620 }
621
622
623 /* In verbose mode print arguments and options */
624 if(verbose>3) {
625 printf("activityConcentration := %g\n", activityConcentration);
626 printf("firstplane := %d\n", firstplane);
627 printf("lastplane := %d\n", lastplane);
628 printf("startplane := %d\n", startplane);
629 printf("endplane := %d\n", endplane);
630 printf("fileNr := %d\n", fileNr);
631 }
632
633
634 /*
635 * Process each file
636 */
637 if(verbose>0) printf("processing %d file(s)...\n", fileNr);
638 char buf[256];
639 for(ai=firstfile; ai<argc; ai++) {
640 strlcpy(imgfile, argv[ai], FILENAME_MAX);
641 if(verbose>1) printf("processing %s\n", imgfile);
642 ret=hrrtMakeCalHdr(imgfile, firstplane, lastplane, startplane, endplane,
643 activityConcentration, calcSTDV, buf, verbose-1);
644 if(ret!=0) {
645 fprintf(stderr, "Error: %s\n", buf);
646 return(100+ret);
647 }
648 }
649
650 if(verbose>0) printf("... done.\n");
651 return(0);
652}
653/*****************************************************************************/
654
655/*****************************************************************************/
float branchingFraction(int isotope)
Definition branch.c:14
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int atoi_with_check(const char *int_as_string, int *result_value)
Definition decpoint.c:238
int iftPutDouble(IFT *ift, char *key, double value, char *cmt_type, int verbose)
Definition ift.c:145
int iftPut(IFT *ift, char *key, char *value, char *cmt_type, int verbose)
Definition ift.c:82
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
int iftGetDoubleValue(IFT *ift, int si, const char *key, double *value, int verbose)
Definition iftsrch.c:268
int iftGetIntValue(IFT *ift, int si, const char *key, int *value, int verbose)
Definition iftsrch.c:309
int iftGetFrom(IFT *ift, int si, const char *key, int verbose)
Definition iftsrch.c:156
Header file for libtpcimgio.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
void swawbip(void *buf, long long int size)
Definition swap.c:93
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int little_endian()
Definition swap.c:14
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition strext.c:206
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
int hrrtMakeCalHdr(char *imgName, int firstplane, int lastplane, int startplane, int endplane, float activityConcentration, int calcSTDV, char *status, int verbose)
Definition mkcalhdr.c:105
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279