9#include "tpcclibConfig.h"
25static char *info[] = {
26 "Simulation or correction of input curve dispersion and delay.",
28 "Usage: @P [Options] tacfile dispersion delay [outputfile] ",
33 "If file name for output is not given, then the TAC file is modified.",
34 "The units of dispersion and delay time must be the same as sample time",
36 "Negative values can be used to correct the TAC for dispersion and/or delay.",
37 "Zero can be given for dispersion time constant or delay time.",
38 "Simulated data is saved with original sample times.",
39 "For accurate results, input TAC should have very short sampling intervals,",
40 "and in case of dispersion correction also noise-free.",
42 "Example of dispersion and delay simulation:",
43 " @P blood.tac 5.0 17 simulated.tac",
45 "Example of dispersion and delay correction:",
46 " @P blood.tac -5.0 -15 corrected.tac",
49 " Iida H, Kanno I, Miura S, Murakami M, Takahashi K, Uemura K. Error",
50 " analysis of a quantitative cerebral blood flow measurement using H215O",
51 " autoradiography and positron emission tomography, with respect to the",
52 " dispersion of the input function.",
53 " J Cereb Blood Flow Metab. 1986;6:536-545.",
54 " https://doi.org/10.1038/jcbfm.1986.99",
56 "See also: conv1tcm, convexpf, sim_av, interpol, tactime, fitdelay",
58 "Keywords: TAC, input, blood, simulation, dispersion, time delay",
77int main(
int argc,
char **argv)
79 int ai, help=0, version=0, verbose=1;
80 char tacfile[FILENAME_MAX], simfile[FILENAME_MAX];
81 double dispersion=nan(
""), delay=nan(
"");
87 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
88 tacfile[0]=simfile[0]=(char)0;
90 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
93 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
102 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
107 if(ai<argc) {
strlcpy(tacfile, argv[ai++], FILENAME_MAX);}
110 if(!isfinite(dispersion)) {fprintf(stderr,
"Error: invalid dispersion '%s'.\n", argv[ai]);
return(1);}
115 if(!isfinite(delay)) {fprintf(stderr,
"Error: invalid delay '%s'.\n", argv[ai]);
return(1);}
118 if(ai<argc) {
strlcpy(simfile, argv[ai++], FILENAME_MAX);}
120 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
126 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
127 fflush(stderr);
return(1);
129 if(dispersion==0.0 && delay==0.0) {
130 fprintf(stderr,
"Warning: neither dispersion or delay effect simulated.\n");
133 if(!simfile[0]) strcpy(simfile, tacfile);
138 printf(
"tacfile := %s\n", tacfile);
139 printf(
"simfile := %s\n", simfile);
140 printf(
"dispersion := %g\n", dispersion);
141 printf(
"delay := %g\n", delay);
149 if(verbose>1) fprintf(stdout,
"reading %s\n", tacfile);
152 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), tacfile);
157 printf(
"tacNr := %d\n", tac.
tacNr);
158 printf(
"sampleNr := %d\n", tac.
sampleNr);
165 fprintf(stderr,
"Error: missing frame times.\n");
170 fprintf(stderr,
"Error: missing concentrations.\n");
174 fprintf(stderr,
"Error: too few samples in plasma data.\n");
178 fprintf(stderr,
"Warning: file contains %d TACs.\n", tac.
tacNr);
182 fprintf(stderr,
"Error: invalid sample times.\n");
185 if(tac.
isframe!=0 && verbose>0) {
187 fprintf(stderr,
"Error: invalid sample times.\n");
199 fprintf(stderr,
"Error: %s.\n",
errorMsg(ret));
208 if(verbose>1) {fprintf(stdout,
"simulating delay...\n"); fflush(stdout);}
209 for(
int i=0; i<stac.
sampleNr; i++) {stac.
x[i]+=delay; stac.
x1[i]+=delay; stac.
x2[i]+=delay;}
214 }
else if(delay<0.0) {
215 if(verbose>1) {fprintf(stdout,
"removing delay...\n"); fflush(stdout);}
216 for(
int i=0; i<stac.
sampleNr; i++) {
218 if(stac.
x[i]>=0.0) {stac.
x1[i]+=delay; stac.
x2[i]+=delay;}
219 else stac.
x[i]=stac.
x1[i]=stac.
x2[i]=nan(
"");
222 fprintf(stderr,
"Error: invalid delay correction for the data.\n");
231 if(verbose>1) {fprintf(stdout,
"simulating dispersion...\n"); fflush(stdout);}
232 double *t=(
double*)malloc(stac.
sampleNr*
sizeof(
double));
234 fprintf(stderr,
"Error: cannot allocate memory.\n");
238 for(
int i=0; i<stac.
tacNr; i++) {
244 fprintf(stderr,
"Error: cannot calculate dispersed curve.\n");
247 }
else if(dispersion<0.0) {
248 if(verbose>1) {fprintf(stdout,
"correcting dispersion...\n"); fflush(stdout);}
249 double *t=(
double*)malloc(stac.
sampleNr*
sizeof(
double));
251 fprintf(stderr,
"Error: cannot allocate memory.\n");
255 for(
int i=0; i<stac.
tacNr; i++) {
261 fprintf(stderr,
"Error: cannot calculate dispersion corrected curve.\n");
270 if(verbose>1) {fprintf(stdout,
"interpolating to original sample times...\n"); fflush(stdout);}
273 for(
int i=0; i<stac.
tacNr; i++) {
279 for(
int i=0; i<stac.
tacNr; i++) {
281 NULL, NULL, tac.
sampleNr, 4, 1, verbose-10);
286 fprintf(stderr,
"Error: cannot interpolate back.\n");
297 if(verbose>1) printf(
"writing noisy data in %s\n", simfile);
298 FILE *fp; fp=fopen(simfile,
"w");
300 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", simfile);
309 if(verbose>=0) printf(
"Simulated TAC saved in %s\n", simfile);
double atofVerified(const char *s)
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
int liInterpolateForPET(double *x, double *y, const int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear TAC interpolation and/or integration to PET frames.
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 simDispersion(double *x, double *y, const int n, const double tau1, const double tau2, double *tmp)
int corDispersion(double *x, double *y, const int n, const double tau, double *tmp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
int tacYNaNs(TAC *tac, const int i)
int tacSortByTime(TAC *d, TPCSTATUS *status)
int tacIsWeighted(TAC *tac)
int tacDeleteMissingSamples(TAC *d)
Delete those samples (time frames) from TAC structure, which contain only missing y values,...
int tacAddZeroSample(TAC *d, TPCSTATUS *status)
Add an initial sample to TAC(s) with zero time and concentration.
int tacSetX(TAC *d, TPCSTATUS *status)
Set TAC x values based on x1 and x2 values, or guess x1 and x2 values based on x values.
Header file for libtpccm.
Header file for library libtpcextensions.
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcli.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Header file for libtpctacmod.