TPCCLIB
Loading...
Searching...
No Matches
dftscale.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <math.h>
14#include <string.h>
15/*****************************************************************************/
16#include "libtpcmisc.h"
17#include "libtpccurveio.h"
18#include "libtpcmodel.h"
19#include "libtpcmodext.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Adjusts TACs in two files into the same level to make visual comparison",
25 "easier, or, adjust the TAC peak to specified value.",
26 " ",
27 "Usage: @P [Options] tacfile1 tacfile2 scaled_tacfile2",
28 "or",
29 "Usage: @P [Options] new_peak tacfile scaled_tacfile",
30 " ",
31 "Options:",
32 " -x1=<start time>",
33 " Time where AUC calculation is started (by default start of data).",
34 " -x2=<end time>",
35 " Time where AUC calculation is stopped (by default end of data).",
36 " --force",
37 " Program does not mind if the time or calibration units",
38 " cannot be converted to match.",
39 " -stdoptions", // List standard options like --help, -v, etc
40 " ",
41 "The procedure for adjusting TACs in file2 to TACs in file1 is:",
42 "1. if times x1 and x2 are not set by user, then set these based on",
43 " the common time ranges in data1 and data2",
44 "2. calculate AUC1 between x1 and x2 in data1 (mean AUC if several TACs)",
45 "3. calculate AUC2 between x1 and x2 in data2 (mean AUC if several TACs)",
46 "4. calculate the scale factor as AUC1/AUC2",
47 "5. multiply data2 with the scale factor, and save the file.",
48 " ",
49 "The procedure for adjusting TAC peak is:",
50 "1. find the maximum TAC value (max of all TACs, if several TACs)",
51 "2. calculate the scale factor as peak/maximum",
52 "3. multiply data with the scale factor, and save the file.",
53 " ",
54 "See also: taccalc, dftsuv, dftsums, dfteven, dftavg, dftmax, tac2svg",
55 " ",
56 "Keywords: TAC, input, simulation, plotting, AUC, peak, scaling",
57 0};
58/*****************************************************************************/
59
60/*****************************************************************************/
61/* Turn on the globbing of the command line, since it is disabled by default in
62 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
63 In Unix&Linux wildcard command line processing is enabled by default. */
64/*
65#undef _CRT_glob
66#define _CRT_glob -1
67*/
68int _dowildcard = -1;
69/*****************************************************************************/
70
71/*****************************************************************************/
75int main(int argc, char **argv)
76{
77 int ai, help=0, version=0, verbose=1;
78 int fi, ri, ret;
79 char *cptr, dfile1[FILENAME_MAX], ofile[FILENAME_MAX], dfile2[FILENAME_MAX];
80 char tmp[2*FILENAME_MAX];
81 int checkUnits=1;
82 DFT dft1, dft2, idft;
83 double x1, x2;
84 double auc1=0.0, auc2=0.0, scalef=0.0, newmax, peakval;
85
86
87 /*
88 * Get arguments
89 */
90 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
91 dfile1[0]=dfile2[0]=ofile[0]=(char)0;
92 dftInit(&dft1); dftInit(&dft2); dftInit(&idft);
93 x1=x2=newmax=nan("");
94 /* Options */
95 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
96 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
97 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
98 if(strncasecmp(cptr, "X1=", 3)==0) {
99 x1=atof_dpi(cptr+3); if(x1>=0.0) continue;
100 } else if(strncasecmp(cptr, "X2=", 3)==0) {
101 x2=atof_dpi(cptr+3); if(x2>=0.0) continue;
102 } else if(strcasecmp(cptr, "FORCE")==0) {
103 checkUnits=0; continue;
104 }
105 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
106 return(1);
107 } else break;
108
109 /* Print help or version? */
110 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
111 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
112 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
113
114 /* Process other arguments, starting from the first non-option */
115 for(; ai<argc; ai++) {
116 if(!dfile1[0] && isnan(newmax)) {
117 if(access(argv[ai], 0)!=-1) {strcpy(dfile1, argv[ai]); continue;}
118 newmax=atof_dpi(argv[ai]); if(newmax>0.0) continue;
119 } else if(!dfile2[0]) {
120 if(access(argv[ai], 0)!=-1) {strcpy(dfile2, argv[ai]); continue;}
121 } else if(!ofile[0]) {
122 strcpy(ofile, argv[ai]); continue;
123 }
124 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
125 return(1);
126 }
127
128 /* Is something missing? */
129 if(!ofile[0]) {
130 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
131 return(1);
132 }
133
134
135 /* In verbose mode print arguments and options */
136 if(verbose>1) {
137 printf("dfile1 := %s\n", dfile1);
138 if(!isnan(newmax)) printf("newmax := %g\n", newmax);
139 printf("dfile2 := %s\n", dfile2);
140 printf("ofile := %s\n", ofile);
141 if(!isnan(x1)) printf("requested_x1 := %g\n", x1);
142 if(!isnan(x2)) printf("requested_x2 := %g\n", x2);
143 }
144
145
146 /* Read data */
147 if(dfile1[0]) {
148 if(verbose>1) printf("reading %s\n", dfile1);
149 if(dftRead(dfile1, &dft1)) {
150 fprintf(stderr, "Error in reading '%s': %s\n", dfile1, dfterrmsg);
151 return(2);
152 }
153 }
154 if(verbose>1) printf("reading %s\n", dfile2);
155 if(dftRead(dfile2, &dft2)) {
156 fprintf(stderr, "Error in reading '%s': %s\n", dfile2, dfterrmsg);
157 dftEmpty(&dft1); return(3);
158 }
159
160 /*
161 * If two files, then check the units,
162 * and get/check the time range
163 */
164 if(dfile1[0] && dfile2[0]) {
165
166 /* Check that files have the same time unit */
167 if(dft1.timeunit==TUNIT_UNKNOWN || dft2.timeunit==TUNIT_UNKNOWN) {
168 fprintf(stderr, "Warning: unknown time units.\n");
169 if(dft1.timeunit!=TUNIT_UNKNOWN) dft2.timeunit=dft1.timeunit;
170 else if(dft2.timeunit!=TUNIT_UNKNOWN) dft1.timeunit=dft2.timeunit;
171 } else {
172 if(dft1.timeunit!=dft2.timeunit) {
173 fprintf(stderr, "Warning: different time units.\n");
174 if(verbose>0)
175 fprintf(stdout, " converting units '%s' to '%s'\n",
176 petTunit(dft2.timeunit), petTunit(dft1.timeunit));
177 ret=dftTimeunitConversion(&dft2, dft1.timeunit);
178 if(ret!=0) {
179 fprintf(stderr, "Error: cannot convert time units.\n");
180 dftEmpty(&dft1); dftEmpty(&dft2); return(3);
181 }
182 }
183 }
184
185 /* Check that files have the same concentration unit */
186 int unit1, unit2;
187 unit1=dftUnitId(dft1.unit);
188 unit2=dftUnitId(dft2.unit);
189 if(unit1==CUNIT_UNKNOWN || unit2==CUNIT_UNKNOWN) {
190 fprintf(stderr, "Warning: unknown concentration units.\n");
191 if(unit1!=CUNIT_UNKNOWN) strcpy(dft2.unit, dft1.unit);
192 else if(unit2!=CUNIT_UNKNOWN) strcpy(dft1.unit, dft2.unit);
193 } else {
194 if(unit1!=unit2) {
195 fprintf(stderr, "Warning: different concentration units.\n");
196 if(verbose>0)
197 fprintf(stdout, " converting units '%s' to '%s'\n",
198 petCunit(unit2), petCunit(unit1));
199 ret=dftUnitConversion(&dft2, unit1);
200 if(ret!=0) {
201 fprintf(stderr, "Error: cannot convert concentration units.\n");
202 if(checkUnits) {dftEmpty(&dft1); dftEmpty(&dft2); return(3);}
203 }
204 }
205 }
206
207 /* Get the time range in both files */
208 double f1a, f1b, f2a, f2b;
209 ret=dftMinMax(&dft1, &f1a, &f1b, NULL, NULL);
210 if(!ret) ret=dftMinMax(&dft2, &f2a, &f2b, NULL, NULL);
211 if(ret) {
212 fprintf(stderr, "Error: invalid TAC data.\n");
213 dftEmpty(&dft1); dftEmpty(&dft2); return(4);
214 }
215 if(f2a>f1a) f1a=f2a;
216 if(f2b<f1b) f1b=f2b;
217 if(isnan(x1) || x1<f1a) x1=f1a;
218 if(isnan(x2) || x2>f1b) x2=f1b;
219 if(verbose>1) {
220 printf("final_x1 := %g\n", x1);
221 printf("final_x2 := %g\n", x2);
222 }
223 if(x1>=x2) {
224 fprintf(stderr, "Error: invalid TAC data.\n");
225 dftEmpty(&dft1); dftEmpty(&dft2); return(4);
226 }
227
228 }
229
230
231 /*
232 * Calculate the scale factor
233 */
234 if(dfile1[0]) { // adjust two TACs
235 /* Calculate AUC1 */
236 ret=dftTimeIntegral(&dft1, x1, x2, &idft, 0, tmp, verbose-2);
237 if(ret) {
238 fprintf(stderr, "Error: %s\n", tmp);
239 dftEmpty(&dft1); dftEmpty(&dft2); dftEmpty(&idft); return(5);
240 }
241 for(ri=0, auc1=0.0; ri<dft1.voiNr; ri++) auc1+=idft.voi[ri].y[0];
242 auc1/=(double)dft1.voiNr; if(verbose>1) printf("auc1 := %g\n", auc1);
243 dftEmpty(&idft);
244 ret=dftTimeIntegral(&dft2, x1, x2, &idft, 0, tmp, verbose-2);
245 if(ret) {
246 fprintf(stderr, "Error: %s\n", tmp);
247 dftEmpty(&dft1); dftEmpty(&dft2); dftEmpty(&idft); return(5);
248 }
249 for(ri=0, auc2=0.0; ri<dft2.voiNr; ri++) auc2+=idft.voi[ri].y[0];
250 auc2/=(double)dft2.voiNr; if(verbose>1) printf("auc2 := %g\n", auc2);
251 dftEmpty(&idft);
252 /* Calculate the scale factor */
253 if((fabs(auc2)<1.0E-30) || !isnormal(scalef=(auc1/auc2))) {
254 fprintf(stderr, "Error: cannot calculate scale factor.\n");
255 dftEmpty(&dft1); dftEmpty(&dft2); return(6);
256 }
257
258 } else { // adjust peak value
259
260 peakval=dft_kBqMax(&dft2);
261 if((peakval<1.0E-30) || !isnormal(scalef=(newmax/peakval))) {
262 fprintf(stderr, "Error: cannot calculate scale factor.\n");
263 dftEmpty(&dft1); dftEmpty(&dft2); return(6);
264 }
265 }
266 if(verbose>0) printf("scale_factor := %g\n", scalef);
267
268 /* Multiply data2 by the scale factor */
269 for(ri=0; ri<dft2.voiNr; ri++)
270 for(fi=0; fi<dft2.frameNr; fi++)
271 dft2.voi[ri].y[fi]*=scalef;
272
273
274 /*
275 * Save the scaled data
276 */
277 if(verbose>1) printf("saving data\n");
278 if(strlen(dft2.comments)>0) strcat(dft2.comments, "\n");
279 sprintf(tmp, "# scale_factor := %g\n", scalef);
280 strcat(dft2.comments, tmp);
281 /* write */
282 if(dftWrite(&dft2, ofile)) {
283 fprintf(stderr, "Error in writing '%s': %s\n", ofile, dfterrmsg);
284 dftEmpty(&dft1); dftEmpty(&dft2); return(11);
285 }
286
287 /* free memory */
288 dftEmpty(&dft1); dftEmpty(&dft2);
289
290 return(0);
291}
292/*****************************************************************************/
293
294/*****************************************************************************/
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
int dftMinMax(DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
Definition dft.c:974
void dftEmpty(DFT *data)
Definition dft.c:20
double dft_kBqMax(DFT *data)
Definition dft.c:1148
int dftTimeIntegral(DFT *dft, double t1, double t2, DFT *idft, int calc_mode, char *status, int verbose)
Definition dftint.c:382
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int dftUnitConversion(DFT *dft, int dunit)
Definition dftunit.c:25
int dftTimeunitConversion(DFT *dft, int tunit)
Definition dftunit.c:119
Header file for libtpccurveio.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
char * petCunit(int cunit)
Definition petunits.c:211
char * petTunit(int tunit)
Definition petunits.c:226
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodel.
Header file for libtpcmodext.
Voi * voi
int timeunit
char comments[_DFT_COMMENT_LEN+1]
int voiNr
int frameNr
char unit[MAX_UNITS_LEN+1]
double * y