9#include "tpcclibConfig.h"
22#define M_2SQRT2LN2 2.354820045
27static char *info[] = {
28 "Corrects regional myocardium and blood time-activity curves (TACs)",
29 "measured with PET for recovery and spillover fractions, and contribution",
30 "of blood activity in vascular space (10%) (Henze et al., 1983).",
31 "This method works properly, if regions-of-interest (ROIs) are drawn",
32 "in the middle of cavity and muscle, excluding the border areas.",
33 "Method is valid when cavity radius >> wall thickness and FWHM/2.36.",
35 "Usage: @P tacfile cav_id myo_id diameter thickness FWHM outputfile",
37 "Tacfile must contain at least the TACs of myocardial cavity and entire",
38 "myocardial muscle (or representative region of it). The names or numbers",
39 "of these TACs must be given as next command-line parameters.",
40 "Corrections based on these TACs are applied to any additional TACs in tacfile.",
42 "The diameter of cavity, myocardial wall thickness, and PET image resolution",
43 "must be given in millimeters.",
46 " -Vb=<Vascular volume fraction>",
47 " Set vascular volume fraction (0-0.9) in myocardial tissue;",
48 " by default Vb=0.10",
50 " Recovery and spillover errors are simulated and added to initially",
51 " non-affected data, originating from compartmental model simulations;",
52 " enter blood and muscle tissue TACs instead of cavity and myocardial",
53 " region TACs, respectively.",
56 "Example 1: correction of regional PET data",
57 " @P s6368dy.tac lv myo 52 10 10 s6368dy_cor.tac",
59 "Example 2: simulation of recovery and spillover effects, assuming Vb=8%%",
60 " @P -simulate original.tac 1 2 40 10 8 simulated.tac",
61 "Example 3: calculate FMM, FMB, FBM, and FBB, without doing anything else",
62 " @P none 1 2 40 10 8 none",
65 "1. Henze E, Huang S-C, Ratib O, Hoffman E, Phelps ME, Schelbert HR.",
66 " Measurements of regional tissue and blood-pool radiotracer",
67 " concentrations from serial tomographic images of the heart.",
68 " J Nucl Med. 1983;24:987-996.",
70 "See also: fitmbf, patlak, logan, simimyoc, taccalc, taccbv, spillinp",
72 "Keywords: TAC, myocardium, cavity, spill-over, recovery, simulation",
91int main(
int argc,
char **argv)
93 int ai, help=0, version=0, verbose=1;
99 char *cptr, dfile[FILENAME_MAX], rfile[FILENAME_MAX];
100 char *cav_roi=NULL, *myo_roi=NULL;
110 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
111 dfile[0]=rfile[0]=(char)0;
114 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
116 cptr=argv[ai]+1;
if(!*cptr)
continue;
117 if(strncasecmp(cptr,
"SIMULATE", 3)==0) {
118 simulation=1;
continue;
119 }
else if(strncasecmp(cptr,
"VB=", 3)==0) {
121 if(ret==0 && Vb>=0.0 && Vb<1.0)
continue;
123 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
128 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
133 for(; ai<argc; ai++) {
135 strlcpy(dfile, argv[ai], FILENAME_MAX);
continue;
136 }
else if(cav_roi==NULL) {
137 cav_roi=argv[ai];
continue;
138 }
else if(myo_roi==NULL) {
139 myo_roi=argv[ai];
continue;
141 R=0.5*
atof_dpi(argv[ai]);
if(R>0.0)
continue;
142 fprintf(stderr,
"Error: invalid diameter '%s'\n", argv[ai]);
return(1);
144 d=
atof_dpi(argv[ai]);
if(d>0.0)
continue;
145 fprintf(stderr,
"Error: invalid thickness '%s'\n", argv[ai]);
return(1);
147 s=
atof_dpi(argv[ai])/M_2SQRT2LN2;
if(s>0.0)
continue;
148 fprintf(stderr,
"Error: invalid resolution '%s'\n", argv[ai]);
return(1);
149 }
else if(!rfile[0]) {
150 strlcpy(rfile, argv[ai], FILENAME_MAX);
continue;
152 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
157 if(!rfile[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
158 if(strcasecmp(dfile,
"NONE")==0 || strcasecmp(rfile,
"NONE")==0) {
159 strcpy(dfile,
""); strcpy(rfile,
"");
164 printf(
"dfile := %s\n", dfile);
165 printf(
"rfile := %s\n", rfile);
166 printf(
"cav_roi := %s\n", cav_roi);
167 printf(
"myo_roi := %s\n", myo_roi);
168 printf(
"R := %g\n", R);
169 printf(
"d := %g\n", d);
170 printf(
"s := %.6f\n", s);
171 printf(
"simulation := %d\n", simulation);
172 printf(
"Vb := %g\n", Vb);
179 double FMM, FMB, FBM, FBB;
181 &FMM, &FMB, &FBM, &FBB);
182 if(strlen(dfile)==0 || verbose>0) {
183 printf(
"FMB := %.6f\n", FMB);
184 printf(
"FMM := %.6f\n", FMM);
185 printf(
"FBB := %.6f\n", FBB);
186 printf(
"FBM := %.6f\n", FBM);
188 if(strlen(dfile)==0)
return(0);
192 if(verbose>1) printf(
"reading %s\n", dfile);
194 fprintf(stderr,
"Error in reading '%s': %s\n", dfile,
dfterrmsg);
201 fprintf(stderr,
"Error: ROI '%s' not found in %s\n", cav_roi, dfile);
204 int len=256, last_len=256;
205 for(ri=0; ri<dft.
voiNr; ri++)
206 if(dft.
voi[ri].
sw==1) {lv=ri; len=last_len=strlen(dft.
voi[ri].
name);
break;}
207 for(;ri<dft.
voiNr; ri++)
208 if(dft.
voi[ri].
sw==1 && (len=strlen(dft.
voi[ri].
name))<last_len)
209 {lv=ri; last_len=len;}
213 fprintf(stderr,
"Error: ROI '%s' not found in %s\n", myo_roi, dfile);
216 int len=256, last_len=256;
217 for(ri=0; ri<dft.
voiNr; ri++)
218 if(dft.
voi[ri].
sw==1) {myo=ri; len=last_len=strlen(dft.
voi[ri].
name);
break;}
219 for(;ri<dft.
voiNr; ri++)
220 if(dft.
voi[ri].
sw==1 && (len=strlen(dft.
voi[ri].
name))<last_len)
221 {myo=ri; last_len=len;}
224 printf(
"cavity := %s\n", dft.
voi[lv].
name);
225 printf(
"myocardium := %s\n", dft.
voi[myo].
name);
228 fprintf(stderr,
"Error: same ROI selected for cavity and myocardium.\n");
233 if(verbose>1) printf(
"correcting TACs\n");
237 double K=1.0/(FBB*FMM-FMB*FBM);
238 if(verbose>2 && simulation==0) printf(
"K := %.5f\n", K);
239 for(fi=0; fi<dft.
frameNr; fi++) {
242 CM=dft.
voi[myo].
y[fi];
243 CB=dft.
voi[lv].
y[fi];
244 CMO=FMM*CM + FBM*CB; dft.
voi[myo].
y[fi]=CMO;
245 CBO=FMB*CM + FBB*CB; dft.
voi[lv].
y[fi]=CBO;
247 for(ri=0; ri<dft.
voiNr; ri++)
if(ri!=lv && ri!=myo) {
248 CMs=dft.
voi[ri].
y[fi];
249 CMOs=FMM*CMs + FBM*CB; dft.
voi[ri].
y[fi]=CMOs;
253 CMO=dft.
voi[myo].
y[fi];
254 CBO=dft.
voi[lv].
y[fi];
255 CM=K*(FBB*CMO-FBM*CBO); dft.
voi[myo].
y[fi]=CM;
256 CB=K*(FMM*CBO-FMB*CMO); dft.
voi[lv].
y[fi]=CB;
258 for(ri=0; ri<dft.
voiNr; ri++)
if(ri!=lv && ri!=myo) {
259 CMOs=dft.
voi[ri].
y[fi];
261 CMs=(CMOs - FBM*CB) / FMM;
262 dft.
voi[ri].
y[fi]=CMs;
269 fprintf(stderr,
"Error in writing '%s': %s\n", rfile,
dfterrmsg);
272 if(verbose>0) printf(
"%s written.\n", rfile);
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
int dftSelectRegions(DFT *dft, char *region_name, int reset)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
int heartRecoverySpilloverCorrectionFactors(double R, double d, double s, double Vb, double *FMM, double *FMB, double *FBM, double *FBB)
Header file for libtpccurveio.
Header file for libtpcidi.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
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)
Header file for libtpcmodel.
char name[MAX_REGIONNAME_LEN+1]