8#include "tpcclibConfig.h"
22static char *info[] = {
23 "Program for adding Gaussian noise to dynamic PET time-activity curve (TAC)",
24 "or TACs using equation",
25 " TAC_noisy(t) = TAC(t) + (CV/100)*TAC(t)*G(0,1) ,",
26 "G(0,1) is a pseudo random number from a Gaussian distribution",
27 "with zero mean and SD of one.",
29 "Usage: @P [Options] tacfile CV outputfile ",
32 " -minsd=<Minimum SD>",
33 " Based on CV only the samples with little or no activity would have",
34 " very little or no noise. With this option at least the given noise",
35 " level (SD) will be added to all samples.",
37 " N noisy copies of each TAC are made (by default just one).",
38 " If CV is set to zero, this option can be used to make multiple copies",
41 " When used with option -x=<N>, copies are written in separate files",
42 " named as (*_NNNN.*).",
45 "Frame durations or weights are not used, even if available in the TAC file.",
48 " @P -minsd=0.2 simulated.tac 10 noisy.tac",
50 "See also: var4tac, fvar4tac, sim_3tcm, sim_h2o, tacadd, tacmean",
52 "Keywords: TAC, simulation, noise",
71int main(
int argc,
char **argv)
74 int ai, help=0, version=0, verbose=1;
75 char tacfile[FILENAME_MAX], simfile[FILENAME_MAX];
85 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
86 tacfile[0]=simfile[0]=(char)0;
88 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
90 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
91 if(strncasecmp(cptr,
"MINSD=", 6)==0) {
93 }
else if(strncasecmp(cptr,
"X=", 2)==0) {
94 if(
atoiCheck(cptr+2, &nCopies)==0 && nCopies>0)
continue;
95 }
else if(strncasecmp(cptr,
"SEPARATE", 3)==0) {
98 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
107 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
112 if(ai<argc) {
strlcpy(tacfile, argv[ai++], FILENAME_MAX);}
115 if(isnan(cv) || cv<0.0 || cv>1000.0) {
116 fprintf(stderr,
"Error: invalid CV%% '%s'.\n", argv[ai]);
return(1);}
117 if(cv<1.0) fprintf(stderr,
"Warning: CV is set to %g%%.\n", cv);
120 if(ai<argc) {
strlcpy(simfile, argv[ai++], FILENAME_MAX);}
122 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
128 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
132 fprintf(stderr,
"Error: number of copies is too high.\n");
135 if(!(cv>0.0) && isnan(minsd)) {
137 fprintf(stderr,
"Error: no variance specified.\n");
140 fprintf(stderr,
"Warning: no variance specified; only making copies.\n");
145 printf(
"tacfile := %s\n", tacfile);
146 printf(
"simfile := %s\n", simfile);
147 printf(
"CV := %g%%\n", cv);
148 if(!isnan(minsd)) printf(
"minsd := %g\n", minsd);
149 printf(
"nCopies := %d\n", nCopies);
150 printf(
"separate := %d\n", separate);
154 if(nCopies<2) separate=0;
160 if(verbose>1) fprintf(stdout,
"reading %s\n", tacfile);
163 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), tacfile);
168 printf(
"tacNr := %d\n", tac.
tacNr);
169 printf(
"sampleNr := %d\n", tac.
sampleNr);
176 fprintf(stderr,
"Warning: missing frame times.\n");
180 fprintf(stderr,
"Warning: missing concentrations.\n");
182 if(nCopies*tac.
tacNr>maxNr) {
183 fprintf(stderr,
"Error: number of output TACs is too high.\n");
186 int origTacNr=tac.
tacNr;
193 if(verbose>1) fprintf(stdout,
"allocating space for copies\n");
196 fprintf(stderr,
"Error: cannot allocate memory for %d additional TACs.\n", nCopies*tac.
tacNr-1);
200 if(verbose>1) fprintf(stdout,
"copying TACs\n");
202 for(
int ci=1; ci<nCopies; ci++) {
204 for(
int j=0; j<tac.
tacNr; j++) {
212 fprintf(stderr,
"Error: cannot copy TACs.\n");
221 if(verbose>1) printf(
"adding noise\n");
224 for(
int fi=0; fi<tac.
sampleNr; fi++) {
225 for(
int ri=0; ri<tac.
tacNr; ri++) {
226 double sd=0.01*cv*tac.
c[ri].
y[fi];
227 if(isnormal(minsd) && sd<minsd) sd=minsd;
236 if(verbose>1) printf(
"writing noisy data in %s\n", simfile);
237 FILE *fp; fp=fopen(simfile,
"w");
239 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", simfile);
245 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
248 if(verbose>=0) printf(
"Noisy data saved in %s\n", simfile);
250 if(verbose>1) printf(
"writing noisy data in %d files\n", nCopies);
252 char basisname[FILENAME_MAX], fnextens[FILENAME_MAX];
256 printf(
"basis_of_filename := %s\n", basisname);
257 printf(
"extensions := %s\n", fnextens);
259 if(strlen(basisname)<1 || ((5+strlen(basisname)+strlen(fnextens))>=FILENAME_MAX)) {
260 fprintf(stderr,
"Error: invalid output file name.\n");
264 int currTacNr=tac.
tacNr;
265 for(
int ni=0; ni<nCopies; ni++) {
267 snprintf(simfile, FILENAME_MAX,
"%s_%04u%s", basisname, 1+ni, fnextens);
268 if(verbose>2) printf(
" %s\n", simfile);
272 FILE *fp; fp=fopen(simfile,
"w");
274 fprintf(stderr,
"\nError: cannot open file for writing (%s)\n", simfile);
280 fprintf(stderr,
"\nError (%d): %s\n", ret,
errorMsg(status.
error));
double atofVerified(const char *s)
char * filenameGetExtensions(const char *s)
Get all extensions of a file name.
void filenameRmExtensions(char *s)
int atoiCheck(const char *s, int *v)
void mertwiInitWithSeed64(MERTWI *mt, uint64_t seed)
Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random num...
double mertwiRandomGaussian(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number with normal (Gaussian) distrib...
uint64_t mertwiSeed64(void)
Make uint64_t seed for pseudo-random number generators.
void mertwiInit(MERTWI *mt)
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)
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 tacAllocateMore(TAC *tac, int tacNr)
int tacCopyTacc(TACC *d1, TACC *d2, int sampleNr)
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 tacDeleteTACC(TAC *d, int i)
int tacIsWeighted(TAC *tac)
Header file for library libtpcextensions.
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcrand.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.