8#include "tpcclibConfig.h"
22static char *info[] = {
23 "Convert blood time-activity curve (TAC) collected during a PET study",
24 "to plasma TAC, based on tracer-dependent population-based",
25 "RBC/plasma or plasma/blood ratio functions over time.",
27 "Usage: @P [Options] tracer bloodfile HCr plasmafile",
31 " Log information is saved in output file.",
34 "The following human PET tracer TACs can be converted:",
36 " ratio is assumed to follow a population average curve.",
38 " ratio is assumed to follow a population average curve.",
40 " ratio is assumed to follow a population average curve",
41 " (unpublished measurements from eight 70-min PET studies).",
43 " ratio is assumed to rise from zero with slope 0.00888",
44 " (unpublished measurement from 10 subjects).",
46 " ratio is assumed to be 0.8 in the beginning and to rise with",
47 " slope 0.0012/min (Phelps ME et al. Ann Neurol 1979;6:371-388).",
49 " ratio is assumed to follow equation R(t)=(Rmax*t)/(Th+t),",
50 " where Rmax=1.446 and Th=83.56 (unpublished results).",
52 " ratio is assumed to follow an average curve based on two",
53 " subjects with assumed HCR=0.43.",
55 " ratio is assumed to be 1.23 in the beginning and to decrease slowly",
56 " with slope 0.00123/min (Hawkins et al., JNM 1992;33:633-642.).",
58 " ratio is assumed to follow a population average curve.",
60 " concentration in red blood cells is assumed to be zero.",
62 " ratio is assumed to rise from zero with slope 0.00398",
63 " (unpublished measurement from 7 subjects).",
65 " concentration is the same in RBC and plasma water.",
67 " ratio is assumed to follow a population average curve",
68 " (unpublished measurement from 6 subjects studied twice).",
70 " ratio is assumed to follow a population average curve",
71 " (unpublished measurement from 8 subjects).",
72 " PBR28HAB, PBR28MAB, PBR28LAB",
73 " ratio is assumed to follow a binding-type specific population average",
74 " curve (unpublished measurements from 90-min PET studies).",
76 " ratio is assumed to follow a population average curve",
77 " (unpublished measurements from ten 70-min PET studies).",
79 " ratio is assumed to follow a population average curve,",
80 " currently based on 15 subjects.",
82 " ratio is assumed to follow a curve based on one",
83 " subject with measured HCr.",
85 " ratio is assumed to follow a population average curve,",
86 " currently based on 11 subjects.",
88 " ratio is assumed to follow a population average curve,",
89 " currently based on 7 subjects.",
90 "For mice and rats (these conversion do not utilize hematocrit):",
92 " plasma-to-blood ratio is assumed to follow the function published by",
93 " Yu AS et al. J Nucl Med 2009;50(6):966-973.",
95 " plasma-to-blood ratio is assumed to follow the function published by",
96 " Huang et al. J Nucl Med 2017;58(4):611-616.",
98 " plasma-to-blood ratio is assumed to follow the function published by",
99 " Weber et al. Eur J Nucl Med 2002;29(3):319-323.",
101 "Codes for tracers that have below mentioned properties:",
103 " concentration in red blood cells is assumed to be zero.",
105 " concentration is the same in RBC and plasma water.",
107 "Times must be in minutes in data files, or seconds, if appropriately",
108 "specified inside the file.",
110 "The hematocrit (HCr, HCT) is normally between 0.40-0.51 in men and 0.36-0.47",
111 "in women. Note that HCr is lower in small vessels in tissue.",
113 "Example: estimate plasma curve from measured FDG blood TAC:",
114 " @P FDG i3344ab.kbq 0.38 i3344ap.kbq",
116 "See also: p2blood, b2rbc, bpr2cpr, taccalc, taccat, fit_bpr, p2bfuncs",
118 "Keywords: input, modelling, simulation, blood, plasma, RBC, hematocrit",
137int main(
int argc,
char **argv)
139 int ai, help=0, version=0, verbose=1;
143 int times_converted=0;
144 char ifile[FILENAME_MAX], ofile[FILENAME_MAX], *cptr;
154 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
155 ifile[0]=ofile[0]=(char)0;
158 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
159 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
162 if(strcasecmp(cptr,
"L")==0 || strcasecmp(cptr,
"LOG")==0) {
163 save_log=1;
continue;
165 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
170 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
178 fprintf(stderr,
"Error: invalid tracer code '%s'.\n", argv[ai]);
185 if(ai<argc) {strcpy(ifile, argv[ai]); ai++;}
189 HCR=
atof_dpi(argv[ai]);
if(HCR>1.0) HCR/=100.0;
190 if(HCR<0.01 || HCR>1.0) {fprintf(stderr,
"Error: bad HCr %g.\n", HCR);
return(1);}
195 if(ai<argc) {strcpy(ofile, argv[ai]); ai++;}
199 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
205 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
211 printf(
"save_log := %d\n", save_log);
212 printf(
"ifile := %s\n", ifile);
213 printf(
"ofile := %s\n", ofile);
214 printf(
"HCR := %.2f\n", HCR);
215 printf(
"tracer := %d\n", tracer);
222 if(verbose>1) printf(
"reading %s\n", ifile);
224 fprintf(stderr,
"Error in reading '%s': %s\n", ifile,
dfterrmsg);
228 fprintf(stderr,
"Warning: %s contains %d TACs.\n", ifile, data.
voiNr);
231 printf(
"tacNr := %d\n", data.
voiNr);
232 printf(
"sampleNr := %d\n", data.
frameNr);
234 printf(
"cunit := %s\n", data.
unit);
235 printf(
"fileformat := %d\n", data.
_type);
240 fprintf(stderr,
"Warning: sample times are assumed to be in minutes.\n");
243 if(verbose>1) printf(
"Sample times are converted to min\n");
250 if(verbose>1) printf(
"calculating ratio curve\n");
252 ratio_type=0;
if(verbose>2) printf(
"trying RBC/plasma ratio\n");
256 ratio_type=1;
if(verbose>2) printf(
"trying plasma/blood ratio\n");
260 fprintf(stderr,
"Error (%d): cannot calculate ratio.\n", ret);
263 if(verbose>2) printf(
"ratio_type := %d\n", ratio_type);
264 if(ratio_type==1 && verbose>1)
265 fprintf(stderr,
"Note: HCr is not used in conversion.\n");
267 if(ratio_type==0) strcpy(tmp,
"RBC-to-plasma");
268 else strcpy(tmp,
"plasma-to-blood");
269 for(fi=0; fi<data.
frameNr; fi++)
270 printf(
"%s[%g] := %.3f\n", tmp, data.
x[fi], data.
voi[0].
y2[fi]);
276 if(verbose>1) printf(
"calculating plasma curve\n");
278 for(fi=0; fi<data.
frameNr; fi++)
279 for(ri=0; ri<data.
voiNr; ri++)
281 data.
voi[ri].
y[fi] / (HCR*data.
voi[0].
y2[fi] + (1-HCR));
283 for(fi=0; fi<data.
frameNr; fi++)
284 for(ri=0; ri<data.
voiNr; ri++)
289 if(times_converted==1) {
290 if(verbose>1) printf(
"Sample times are converted to sec\n");
297 for(fi=0; fi<data.
frameNr; fi++)
298 for(ri=0; ri<data.
voiNr; ri++)
301 if(verbose>1) printf(
"saving log information\n");
302 strcat(data.
comments,
"\n# converted to plasma\n");
303 if(ratio_type==0) {sprintf(tmp,
"# HCT := %.2f\n", HCR); strcat(data.
comments, tmp);}
304 sprintf(tmp,
"# tracer_code := %d\n", tracer); strcat(data.
comments, tmp);
305 if(ratio_type==0) strcpy(tmp,
"# ratio := RBC/plasma\n");
306 else strcpy(tmp,
"# ratio := plasma/blood\n");
309 if(verbose>1) printf(
"writing %s\n", ofile);
311 fprintf(stderr,
"Error in writing '%s': %s\n", ofile,
dfterrmsg);
314 if(verbose>0) printf(
"Plasma TAC written in %s\n", ofile);
double atof_dpi(char *str)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
void dftSec2min(DFT *dft)
void dftMin2sec(DFT *dft)
Header file for libtpccurveio.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
char * petTunit(int tunit)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
int rbc_plasma_ratio(int tracer, double *t, double *r, int nr)
int tracer_code(char *tracer)
int plasma_to_blood_ratio(int tracer, double *t, double *r, int nr)
Header file for pbconv.c.
char comments[_DFT_COMMENT_LEN+1]
char unit[MAX_UNITS_LEN+1]