TPCCLIB
Loading...
Searching...
No Matches
pardiff.c
Go to the documentation of this file.
1
9/*****************************************************************************/
10#include "tpcclibConfig.h"
11/*****************************************************************************/
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <strings.h>
16#include <math.h>
17/*****************************************************************************/
18#include "tpcextensions.h"
19#include "tpcift.h"
20#include "tpcpar.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Calculate difference between parameters in two files as percent change",
26 "in file2 from file1 using equation 100%*(result2-result1)/|result1|.",
27 "If file name for %-difference is not given, output is printed",
28 "on screen (stdout).",
29 " ",
30 "Usage: @P [options] <file1> <file2> [%-difference file]",
31 " ",
32 "Options ",
33 " -occ[upance]",
34 " -inh[ibition]",
35 " Occupance or inhibition percentage is calculated, that is,",
36 " 100%*(result1-result2)/result1.",
37 " -dif[ference]",
38 " Difference result2-result1 is calculated.",
39 " --force",
40 " Result files are allowed to contain different parameter and TAC names",
41 " and units.",
42 " -round",
43 " Differences are rounded to the nearest integer percentage.",
44 " -stdoptions", // List standard options like --help, -v, etc
45 " ",
46 "See also: parrenp, parcoll, parai, parformat, parmatch, paradd, parsort",
47 " ",
48 "Keywords: parameter, modelling, simulation, occupancy, inhibition",
49 0};
50/*****************************************************************************/
51
52/*****************************************************************************/
53/* Turn on the globbing of the command line, since it is disabled by default in
54 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
55 In Unix&Linux wildcard command line processing is enabled by default. */
56/*
57#undef _CRT_glob
58#define _CRT_glob -1
59*/
60int _dowildcard = -1;
61/*****************************************************************************/
62
63/*****************************************************************************/
67int main(int argc, char **argv)
68{
69 int ai, help=0, version=0, verbose=1;
70 int ri, pi;
71 int use_force=0;
72 int diff_type=0; // 0=res2/res1-1; 1=1-res2/res1 (occ); 2=1-res2/res1 (inh);
73 // 3=res2-res1 (dif)
74 int rounding=0; // Rounding of percentages: 0=no; 1=yes
75 PAR par1, par2;
76 char parfile1[FILENAME_MAX], parfile2[FILENAME_MAX], diffile[FILENAME_MAX];
77 double f;
78
79
80 /*
81 * Get arguments
82 */
83 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
84 parInit(&par1); parInit(&par2);
85 parfile1[0]=parfile2[0]=diffile[0]=(char)0;
86 /* Options */
87 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
88 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
89 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
90 if(strcasecmp(cptr, "F")==0 || strcasecmp(cptr, "FORCE")==0) {
91 use_force=1; continue;
92 } else if(strncasecmp(cptr, "NOCHECK", 4)==0) { // deprecated
93 use_force=1; continue;
94 } else if(strncasecmp(cptr, "OCCUPANCE", 3)==0) {
95 diff_type=1; continue;
96 } else if(strncasecmp(cptr, "INHIBITION", 3)==0) {
97 diff_type=2; continue;
98 } else if(strncasecmp(cptr, "DIFFERENCE", 3)==0) {
99 diff_type=3; continue;
100 } else if(strcasecmp(cptr, "ROUND")==0) {
101 rounding=1; continue;
102 }
103 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
104 return(1);
105 } else break;
106
107 /* Print help or version? */
108 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
109 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
110 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
111
112 /* Arguments */
113 for(; ai<argc; ai++) {
114 if(!parfile1[0]) {
115 strlcpy(parfile1, argv[ai], FILENAME_MAX); continue;
116 } else if(!parfile2[0]) {
117 strlcpy(parfile2, argv[ai], FILENAME_MAX); continue;
118 } else if(!diffile[0]) {
119 strlcpy(diffile, argv[ai], FILENAME_MAX); continue;
120 }
121 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
122 return(1);
123 }
124
125 TPCSTATUS status; statusInit(&status);
126 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
127 status.verbose=verbose-1;
128
129 /* Is something missing? */
130 if(!parfile2[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
131
132 /* In verbose mode print arguments and options */
133 if(verbose>1) {
134 for(ai=0; ai<argc; ai++) printf("%s ", argv[ai]);
135 printf("\n");
136 printf("parfile1 := %s\n", parfile1);
137 printf("parfile2 := %s\n", parfile2);
138 printf("diffile := %s\n", diffile);
139 printf("diff_type := %d\n", diff_type);
140 printf("use_force := %d\n", use_force);
141 printf("rounding := %d\n", rounding);
142 fflush(stdout);
143 }
144
145
146 /*
147 * Read parameter files
148 */
149 if(verbose>1) fprintf(stdout, "reading %s\n", parfile1);
150 if(parRead(&par1, parfile1, &status)) {
151 fprintf(stderr, "Error: %s (%s)\n", errorMsg(status.error), parfile1);
152 parFree(&par1); parFree(&par2);
153 return(2);
154 }
155 if(verbose>1) printf("reading %s\n", parfile2);
156 if(parRead(&par2, parfile2, &status)) {
157 fprintf(stderr, "Error: %s (%s)\n", errorMsg(status.error), parfile2);
158 parFree(&par1); parFree(&par2);
159 return(3);
160 }
161
162 /* Sort regions by region name */
163 if(verbose>1) fprintf(stdout, "sorting regions\n");
164 parSortByName(&par1, &status);
165 parSortByName(&par2, &status);
166
167 /* Check that contents are matching */
168 if(verbose>1) fprintf(stdout, "check for matching results\n");
169 if(par1.tacNr!=par2.tacNr) {
170 fprintf(stderr, "Error: different TAC number in parameter files.\n");
171 parFree(&par1); parFree(&par2); return(4);
172 }
173 if(par1.parNr!=par2.parNr && use_force==0) {
174 fprintf(stderr, "Error: different parameters in parameter files.\n");
175 parFree(&par1); parFree(&par2); return(4);
176 }
177 if(use_force==0 && parCompareTacNames(&par1, &par2, -1, 0, &status)) {
178 fprintf(stderr, "Error: different TAC names in parameter files.\n");
179 parFree(&par1); parFree(&par2); return(4);
180 }
181
182 /*
183 * Calculate the differences
184 */
185 if(verbose>1) fprintf(stdout, "calculating differences\n");
186 for(ri=0; ri<par1.tacNr; ri++) {
187 for(pi=0; pi<par1.parNr && pi<par2.parNr; pi++) {
188 if(par1.r[ri].p[pi]!=0.0) {
189 if(diff_type==0) {
190 f=par2.r[ri].p[pi]-par1.r[ri].p[pi];
191 f/=fabs(par1.r[ri].p[pi]);
192 f*=100.0; if(rounding) f=roundf(f);
193 } else if(diff_type==3) {
194 f=par2.r[ri].p[pi]-par1.r[ri].p[pi];
195 } else { // 1 or 2
196 f=par1.r[ri].p[pi]-par2.r[ri].p[pi];
197 f/=par1.r[ri].p[pi];
198 f*=100.0; if(rounding) f=roundf(f);
199 }
200 par1.r[ri].p[pi]=f;
201 } else
202 par1.r[ri].p[pi]=0.0;
203 /* Set SDs and CLs to NA */
204 par1.r[ri].sd[pi]=par1.r[ri].cl1[pi]=par1.r[ri].cl2[pi]=nan("");
205 }
206 }
207 if(par2.parNr<par1.parNr) par1.parNr=par2.parNr;
208
209 /*
210 * Write the differences
211 */
212 if(verbose>1) fprintf(stdout, "writing differences in %s\n", diffile);
213 {
214 int i, j;
215 char buf[256];
216 /* change program name */
217 tpcProgramName(argv[0], 1, 1, buf, 256);
218 i=iftFindKey(&par1.h, "program", 0); if(i>=0) iftDelete(&par1.h, i);
219 iftPut(&par1.h, "program", buf, 0, NULL);
220 /* change file names */
221 i=iftFindKey(&par1.h, "plasmafile", 0); if(i>=0) iftDelete(&par1.h, i);
222 i=iftFindKey(&par1.h, "plasmafile2", 0); if(i>=0) iftDelete(&par1.h, i);
223 i=iftFindKey(&par1.h, "bloodfile", 0); if(i>=0) iftDelete(&par1.h, i);
224 i=iftFindKey(&par1.h, "refname", 0); if(i>=0) iftDelete(&par1.h, i);
225 i=iftFindKey(&par1.h, "reffile", 0); if(i>=0) iftDelete(&par1.h, i);
226 i=iftFindKey(&par1.h, "datafile", 0); if(i>=0) iftDelete(&par1.h, i);
227 iftPut(&par1.h, "reffile", parfile1, 0, NULL);
228 iftPut(&par1.h, "datafile", parfile2, 0, NULL);
229 /* set study id based on file 2 */
230 i=iftFindKey(&par1.h, "studynr", 0);
231 if(i<0) i=iftFindKey(&par1.h, "study_number", 0);
232 j=iftFindKey(&par2.h, "studynr", 0);
233 if(j<0) j=iftFindKey(&par2.h, "study_number", 0);
234 if(j>=0) {
235 if(i>=0) iftDelete(&par1.h, i);
236 iftPut(&par1.h, "studynr", par2.h.item[j].value, 0, NULL);
237 }
238 }
239 /* set units */
240 if(diff_type!=3) {
241 for(pi=0; pi<par1.parNr; pi++) par1.n[pi].unit=UNIT_PERCENTAGE;
242 }
243 /* remove WSS */
244 for(ri=0; ri<par1.tacNr; ri++) par1.r[ri].wss=nan("");
245 /* Save file */
246 FILE *fp;
247 int ret;
248 if(!diffile[0]) fp=stdout; else fp=fopen(diffile, "w");
249 if(fp==NULL) {
250 fprintf(stderr, "Error: cannot open file for writing.\n");
251 parFree(&par1); parFree(&par2); return(11);
252 }
253 ret=parWrite(&par1, fp, PAR_FORMAT_UNKNOWN, 1, &status);
254 if(diffile[0]) fclose(fp);
255 parFree(&par1); parFree(&par2);
256 if(ret!=TPCERROR_OK) {
257 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
258 return(12);
259 }
260 if(verbose>0 && diffile[0])
261 printf("parameter differences saved in %s\n", diffile);
262 return(0);
263}
264/*****************************************************************************/
265
266/*****************************************************************************/
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftDelete(IFT *ift, int index)
Definition ift.c:206
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
void parFree(PAR *par)
Definition par.c:75
void parInit(PAR *par)
Definition par.c:25
int parCompareTacNames(PAR *d1, PAR *d2, const int i, const int casens, TPCSTATUS *status)
Definition parcomp.c:157
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
Definition pario.c:148
int parRead(PAR *par, const char *fname, TPCSTATUS *status)
Definition pario.c:232
int parSortByName(PAR *d, TPCSTATUS *status)
Definition parorder.c:30
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
Definition proginfo.c:406
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:169
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:339
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:114
void statusInit(TPCSTATUS *s)
Definition statusmsg.c:104
char * errorMsg(tpcerror e)
Definition statusmsg.c:68
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * value
Definition tpcift.h:37
IFT_ITEM * item
Definition tpcift.h:57
Definition tpcpar.h:100
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:147
int parNr
Definition tpcpar.h:108
int tacNr
Definition tpcpar.h:104
PARR * r
Definition tpcpar.h:114
PARN * n
Definition tpcpar.h:112
int unit
Definition tpcpar.h:86
double wss
Definition tpcpar.h:72
double * cl2
Definition tpcpar.h:70
double * p
Definition tpcpar.h:64
double * sd
Definition tpcpar.h:66
double * cl1
Definition tpcpar.h:68
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpcextensions.
@ UNIT_PERCENTAGE
Percentage (%).
@ TPCERROR_OK
No error.
Header file for library libtpcift.
Header file for libtpcpar.
@ PAR_FORMAT_UNKNOWN
Unknown format.
Definition tpcpar.h:28