8#include "tpcclibConfig.h"
22static char *info[] = {
23 "Convert plasma time-activity curve (TAC) collected during a PET study",
24 "to blood TAC, based on tracer-dependent population-based",
25 "RBC/plasma or plasma/blood ratio functions over time.",
27 "Usage: @P [Options] tracer plasmafile HCr bloodfile",
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-s323.",
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 blood curve from measured FDG plasma TAC:",
114 " @P FDG i3344ap.kbq 0.38 i3344ab.kbq",
116 "See also: b2plasma, 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);
233 fprintf(stderr,
"Warning: sample times are assumed to be in minutes.\n");
236 if(verbose>1) printf(
"Sample times are converted to min\n");
244 if(verbose>1) printf(
"calculating ratio curve\n");
246 ratio_type=0;
if(verbose>2) printf(
"trying RBC/plasma ratio\n");
250 ratio_type=1;
if(verbose>2) printf(
"trying plasma/blood ratio\n");
254 fprintf(stderr,
"Error (%d): cannot calculate ratio.\n", ret);
257 if(verbose>2) printf(
"ratio_type := %d\n", ratio_type);
258 if(ratio_type==1 && verbose>1)
259 fprintf(stderr,
"Note: HCr is not used in conversion.\n");
261 if(ratio_type==0) strcpy(tmp,
"RBC-to-plasma");
262 else strcpy(tmp,
"plasma-to-blood");
263 for(fi=0; fi<data.
frameNr; fi++)
264 printf(
"%s[%g] := %.3f\n", tmp, data.
x[fi], data.
voi[0].
y2[fi]);
271 if(verbose>1) printf(
"calculating blood curve\n");
273 for(fi=0; fi<data.
frameNr; fi++)
274 for(ri=0; ri<data.
voiNr; ri++)
276 data.
voi[ri].
y[fi] * (HCR*data.
voi[0].
y2[fi] + (1-HCR));
278 for(fi=0; fi<data.
frameNr; fi++)
279 for(ri=0; ri<data.
voiNr; ri++)
284 if(times_converted==1) {
285 if(verbose>1) printf(
"Sample times are converted to sec\n");
292 for(fi=0; fi<data.
frameNr; fi++)
293 for(ri=0; ri<data.
voiNr; ri++)
296 if(verbose>1) printf(
"saving log information\n");
297 strcat(data.
comments,
"\n# converted to blood\n");
298 if(ratio_type==0) {sprintf(tmp,
"# HCT := %.2f\n", HCR); strcat(data.
comments, tmp);}
299 sprintf(tmp,
"# tracer_code := %d\n", tracer); strcat(data.
comments, tmp);
300 if(ratio_type==0) strcpy(tmp,
"# ratio := RBC/plasma\n");
301 else strcpy(tmp,
"# ratio := plasma/blood\n");
304 if(verbose>1) printf(
"writing %s\n", ofile);
306 fprintf(stderr,
"Error in writing '%s': %s\n", ofile,
dfterrmsg);
309 if(verbose>0) printf(
"Blood 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)
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]