Commit 5a2647a0 authored by Vesa Oikonen's avatar Vesa Oikonen
Browse files

continued; first tests passed.

parent 524eb03d
......@@ -15,6 +15,7 @@
#include <unistd.h>
/*****************************************************************************/
#include "tpcextensions.h"
//#include "tpcfileutil.h"
#include "tpcift.h"
#include "tpctac.h"
/*****************************************************************************/
......@@ -60,6 +61,9 @@ int _dowildcard = -1;
/*****************************************************************************/
/*****************************************************************************/
/** How to deal with overlap */
enum {OVL_USE_BOTH, OVL_USE_FIRST, OVL_USE_SECOND, OVL_CUTTIME};
/**
* Main
*/
......@@ -68,6 +72,9 @@ int main(int argc, char **argv)
int ai, help=0, version=0, verbose=1;
char tacfile1[FILENAME_MAX], tacfile2[FILENAME_MAX], outfile[FILENAME_MAX];
int forceMode=0;
int overlapMode=OVL_USE_BOTH;
double cutTime=nan("");
/*
......@@ -82,6 +89,29 @@ int main(int argc, char **argv)
char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
if(strcasecmp(cptr, "F")==0 || strcasecmp(cptr, "FORCE")==0) {
forceMode=1; continue;
} else if(strncasecmp(cptr, "BOTH", 1)==0) {
overlapMode=OVL_USE_BOTH; continue;
} else if(strncasecmp(cptr, "FIRST", 2)==0) {
overlapMode=OVL_USE_FIRST; continue;
} else if(strncasecmp(cptr, "SECOND", 2)==0) {
overlapMode=OVL_USE_SECOND; continue;
} else if(strncasecmp(cptr, "CUT=", 4)==0) {
overlapMode=OVL_CUTTIME;
cptr+=4;
/* Try as a value first */
cutTime=atofVerified(cptr);
if(cutTime>0.0) continue;
/* Then try as a IFT file */
FILE *fp=fopen(cptr, "r");
if(fp==NULL) {fprintf(stderr, "Error: invalid cut time.\n"); return(1);}
IFT ift; iftInit(&ift);
if(iftRead(&ift, fp, 1, 0, NULL)==0) {
if(iftGetDoubleValue(&ift, "x", 0, &cutTime)>=0 && cutTime>0.0) {iftFree(&ift); continue;}
if(iftGetDoubleValue(&ift, "time", 0, &cutTime)>=0 && cutTime>0.0) {iftFree(&ift); continue;}
if(iftGetDoubleValue(&ift, "cut", 0, &cutTime)>=0 && cutTime>0.0) {iftFree(&ift); continue;}
iftFree(&ift);
}
fprintf(stderr, "Error: invalid cut time.\n"); return(1);
}
fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
return(1);
......@@ -105,6 +135,7 @@ int main(int argc, char **argv)
/* Is something missing? */
if(!tacfile2[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
if(!outfile[0]) strcpy(outfile, tacfile1);
if(overlapMode==OVL_CUTTIME && !(cutTime>0.0)) {fprintf(stderr, "Error: invalid cut time.\n"); return(1);}
/* In verbose mode print arguments and options */
if(verbose>1) {
......@@ -113,6 +144,8 @@ int main(int argc, char **argv)
printf("tacfile1 := %s\n", tacfile1);
printf("tacfile2 := %s\n", tacfile2);
printf("outfile := %s\n", outfile);
printf("overlapMode := %d\n", overlapMode);
if(overlapMode==OVL_CUTTIME) printf("cutTime := %g\n", cutTime);
printf("forceMode := %d\n", forceMode);
fflush(stdout);
}
......@@ -231,243 +264,126 @@ int main(int argc, char **argv)
}
}
tacFree(&tac1); tacFree(&tac2);
return(0);
}
/*****************************************************************************/
/*****************************************************************************/
#if(0)
/**
* Main
*/
int main(int argc, char **argv)
{
int ai, help=0, version=0, verbose=1;
int ret;
int checkData=1;
char tacfile[FILENAME_MAX], outfile[FILENAME_MAX];
int fileNr=0, file1=0;
/* If one of TAC files only has frame mid times, then we only use mid times */
if(tac1.isframe==0 || tac2.isframe==0) tac1.isframe=tac2.isframe=0;
/* Remove weighting unless both have similar weighting */
if(tac1.weighting!=tac2.weighting) tac1.weighting=tac2.weighting=WEIGHTING_OFF;
/*
* Get arguments
* Check if there is overlap in sample times of the two files
*/
if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
tacfile[0]=outfile[0]=(char)0;
/* Options */
for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
if(strcasecmp(cptr, "F")==0 || strcasecmp(cptr, "FORCE")==0) {
checkData=0; continue;
}
fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
return(1);
} else break; // tac name argument may start with '-'
TPCSTATUS status; statusInit(&status);
statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
status.verbose=verbose-3;
/* Print help or version? */
if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
/* Process other arguments, starting from the first non-option */
if(ai<argc) strlcpy(outfile, argv[ai++], FILENAME_MAX);
for(; ai<argc; ai++) {
if(fileNr==0) file1=ai;
fileNr++;
if(verbose>1) printf("checking for time overlap\n");
int isOverlap=0;
double xmin1, xmax1, xmin2, xmax2, xmin, xmax;
if(tacXRange(&tac1, &xmin1, &xmax1) || tacXRange(&tac2, &xmin2, &xmax2)) {
fprintf(stderr, "Error: invalid sample times.\n");
tacFree(&tac1); tacFree(&tac2); return(5);
}
/* In verbose mode print arguments and options */
if(verbose>1) {
for(ai=0; ai<argc; ai++) printf("%s ", argv[ai]);
printf("\n");
printf("fileNr := %d\n", fileNr);
printf("outfile := %s\n", outfile);
fflush(stdout);
if(verbose>3) {
printf("x range 1 := %g - %g\n", xmin1, xmax1);
printf("x range 2 := %g - %g\n", xmin2, xmax2);
}
/* Is something missing? */
if(!outfile[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
if(fileNr==0) {
fprintf(stderr, "Error: missing command-line argument; try %s --help\n", argv[0]);
return(1);
}
if(fileNr==1) {
fprintf(stderr, "Error: only one input file specified.\n");
return(1);
xmin=xmin1; if(xmin2<xmin) xmin=xmin2;
xmax=xmax1; if(xmax2>xmax) xmax=xmax2;
if(overlapMode==OVL_CUTTIME && (cutTime<xmin || cutTime>xmax)) {
fprintf(stderr, "Error: cut time outside of data time range %g - %g\n", xmin, xmax);
tacFree(&tac1); tacFree(&tac2); return(5);
}
/* Check that all input files do exist, and that their name does not match output file name */
for(ai=file1; ai<argc; ai++) {
strlcpy(tacfile, argv[ai], FILENAME_MAX);
if(access(tacfile, 0) == -1) {
fprintf(stderr, "Error: input file %s does not exist.\n", tacfile);
return(2);
if(xmax1>=xmin2) {
isOverlap=1;
int fail=0;
if(overlapMode==OVL_USE_FIRST && xmin1>xmin2) fail=1;
if(overlapMode==OVL_USE_SECOND && xmin2<=xmin1) fail=2;
if(overlapMode==OVL_CUTTIME && (xmin1>cutTime || xmax2<cutTime)) fail=3;
if(fail) {
fprintf(stderr, "Error: incompatible sample time ranges or wrong file order.\n");
tacFree(&tac1); tacFree(&tac2); return(5);
}
if(strcasecmp(outfile, tacfile)==0) {
fprintf(stderr, "Error: input file would be overwritten.\n");
return(2);
}
/* Do not care about overlap if all data is used anyway */
if(isOverlap) {
if(overlapMode==OVL_USE_BOTH) {
isOverlap=0;
if(verbose>1) printf("overlap in sample times is ignored.\n");
} else {
if(verbose>1) printf("overlap in sample times will be removed.\n");
}
}
/*
* Read the first file
*/
TAC tac, pool;
tacInit(&tac); tacInit(&pool);
strlcpy(tacfile, argv[file1], FILENAME_MAX);
if(verbose>1) printf("reading %s\n", tacfile);
ret=tacRead(&pool, tacfile, &status);
if(ret!=TPCERROR_OK) {
fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
tacFree(&pool); return(2);
}
if(checkData) tacSortByName(&pool, &status);
if(verbose>2) {
printf("fileformat := %s\n", tacFormattxt(pool.format));
printf("tacNr := %d\n", pool.tacNr);
printf("sampleNr := %d\n", pool.sampleNr);
printf("xunit := %s\n", unitName(pool.tunit));
printf("yunit := %s\n", unitName(pool.cunit));
/* Set cut time based on TAC preference, if that is given */
if(overlapMode==OVL_USE_FIRST) cutTime=xmax1;
if(overlapMode==OVL_USE_SECOND) cutTime=xmin2;
/* Delete overlapping part from first dataset, if necessary */
if(isOverlap && xmax1>=cutTime) {
if(verbose>1) printf("deleting overlap from the first dataset\n");
for(int i=tac1.sampleNr-1; i>=0; i--)
if(tac1.x[i]>=cutTime) tacDeleteSample(&tac1, i);
if(tac1.sampleNr<1 || tacXRange(&tac1, &xmin1, &xmax1)) {
fprintf(stderr, "Error: no data from file 1 included.\n");
tacFree(&tac1); tacFree(&tac2); return(5);
}
if(verbose>3) printf("final x range 1 := %g - %g\n", xmin1, xmax1);
}
if(tacXNaNs(&pool)>0) {
fprintf(stderr, "Error: missing x values in %s\n", tacfile);
tacFree(&pool); return(2);
/* Delete overlapping part from second dataset, if necessary */
if(isOverlap && xmin2<=cutTime) {
if(verbose>1) printf("deleting overlap from the second dataset\n");
for(int i=tac2.sampleNr-1; i>=0; i--)
if(tac2.x[i]<=cutTime) tacDeleteSample(&tac2, i);
if(tac2.sampleNr<1 || tacXRange(&tac2, &xmin2, &xmax2)) {
fprintf(stderr, "Error: no data from file 2 included.\n");
tacFree(&tac1); tacFree(&tac2); return(5);
}
if(verbose>3) printf("final x range 2 := %g - %g\n", xmin2, xmax2);
}
/*
* Add the data from the other files
* Add data from second file in to the first one
*/
int differentTUnits=0;
int differentCUnits=0;
for(ai=file1+1; ai<argc; ai++) {
strlcpy(tacfile, argv[ai], FILENAME_MAX);
if(verbose>1) printf("reading %s\n", tacfile);
ret=tacRead(&tac, tacfile, &status);
if(ret!=TPCERROR_OK) {
fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
tacFree(&pool); tacFree(&tac); return(2);
}
if(checkData) tacSortByName(&tac, &status);
if(verbose>2) {
printf("fileformat := %s\n", tacFormattxt(tac.format));
printf("tacNr := %d\n", tac.tacNr);
printf("sampleNr := %d\n", tac.sampleNr);
printf("xunit := %s\n", unitName(tac.tunit));
printf("yunit := %s\n", unitName(tac.cunit));
}
if(tacXNaNs(&pool)>0) {
fprintf(stderr, "Error: missing x values in %s\n", tacfile);
tacFree(&pool); tacFree(&tac); return(2);
}
/* Check if the TAC number is different */
if(pool.tacNr!=tac.tacNr) {
fprintf(stderr, "Error: different number of TACs.\n");
tacFree(&pool); tacFree(&tac); return(3);
}
/* Check that TAC names match, if requested */
if(checkData && tacCompareNames(&pool, &tac, -1, &status)!=0) {
fprintf(stderr, "Error: TAC names do not match.\n");
tacFree(&pool); tacFree(&tac); return(3);
}
/* Try to convert time units to time units in the first file */
ret=tacXUnitConvert(&tac, pool.tunit, &status);
if(ret==TPCERROR_UNKNOWN_UNIT) ret=TPCERROR_OK;
if(ret!=TPCERROR_OK) {
if(verbose>2) fprintf(stderr, "Status: %s\n", errorMsg(status.error));
if(checkData) {
fprintf(stderr, "Error: non-compatible TAC time units.\n");
tacFree(&pool); tacFree(&tac); return(4);
}
differentTUnits++;
}
/* Try to convert concentration units to time units in the first file */
ret=tacYUnitConvert(&tac, pool.cunit, &status);
if(ret==TPCERROR_UNKNOWN_UNIT) ret=TPCERROR_OK;
if(ret!=TPCERROR_OK) {
if(verbose>2) fprintf(stderr, "Status: %s\n", errorMsg(status.error));
if(checkData) {
fprintf(stderr, "Error: non-compatible TAC concentration units.\n");
tacFree(&pool); tacFree(&tac); return(5);
}
differentCUnits++;
}
/* If at least one of TAC files only has frame mid times, then all have */
if(tac.isframe==0) pool.isframe=0;
/* Add the new sample values */
ret=tacAllocateMoreSamples(&pool, tac.sampleNr);
if(ret!=TPCERROR_OK) {
fprintf(stderr, "Error: cannot allocate memory.\n");
tacFree(&pool); tacFree(&tac); return(6);
}
for(int i=0; i<tac.sampleNr; i++) {
pool.x[pool.sampleNr]=tac.x[i];
pool.x1[pool.sampleNr]=tac.x1[i];
pool.x2[pool.sampleNr]=tac.x2[i];
for(int j=0; j<pool.tacNr; j++) pool.c[j].y[pool.sampleNr]=tac.c[j].y[i];
pool.w[pool.sampleNr]=tac.w[i];
pool.sampleNr++;
}
tacFree(&tac);
if(verbose>1) printf("combining data\n");
if(tacAllocateMoreSamples(&tac1, tac2.sampleNr)) {
fprintf(stderr, "Error: cannot allocate memory.\n");
tacFree(&tac1); tacFree(&tac2); return(6);
}
if(verbose>0 && differentTUnits>1) fprintf(stderr,
"Warning: time units could not be converted for %d file(s).\n", differentTUnits);
if(verbose>0 && differentCUnits>1) fprintf(stderr,
"Warning: concentration units could not be converted for %d file(s).\n", differentCUnits);
/*
* Sort pooled data by sample time
*/
ret=tacSortByTime(&pool, &status);
if(ret!=TPCERROR_OK) {
fprintf(stderr, "Error: cannot sort the pooled data.\n");
tacFree(&pool); return(8);
for(int i=0; i<tac2.sampleNr; i++) {
tac1.x[tac1.sampleNr]=tac2.x[i];
tac1.x1[tac1.sampleNr]=tac2.x1[i];
tac1.x2[tac1.sampleNr]=tac2.x2[i];
for(int j=0; j<tac1.tacNr; j++) tac1.c[j].y[tac1.sampleNr]=tac2.c[j].y[i];
tac1.w[tac1.sampleNr]=tac2.w[i];
tac1.sampleNr++;
}
/* Delete study number, if one exists */
(void)tacSetHeaderStudynr(&pool.h, "");
/* Sort by sample time, if there was overlap */
if(isOverlap) tacSortByTime(&tac1, NULL);
/* No need for the second dataset */
tacFree(&tac2);
/*
* Save data
*/
if(verbose>1) printf("writing %s\n", outfile);
{
FILE *fp; fp=fopen(outfile, "w");
if(fp==NULL) {
fprintf(stderr, "Error: cannot open file for writing (%s)\n", outfile);
tacFree(&tac); return(11);
tacFree(&tac1); return(11);
}
ret=tacWrite(&pool, fp, TAC_FORMAT_UNKNOWN, 1, &status);
int ret=tacWrite(&tac1, fp, TAC_FORMAT_UNKNOWN, 1, &status);
fclose(fp);
if(ret!=TPCERROR_OK) {
fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
tacFree(&pool); return(12);
tacFree(&tac1); return(12);
}
if(verbose>=0) {
printf("%d samples from %d TAC files pooled.\n", pool.sampleNr, fileNr);
printf("%s saved.\n", outfile);
printf("%d samples saved in %s.\n", tac1.sampleNr, outfile);
}
}
tacFree(&pool);
tacFree(&tac1);
return(0);
}
#endif
/*****************************************************************************/
/*****************************************************************************/
......
#!/bin/bash
#: Title : test_taccat
#: Date : 2020-07-16
#: Date : 2021-02-08
#: Author : "Vesa Oikonen" <vesa.oikonen@utu.fi>
#: Options : None
......@@ -21,21 +21,93 @@ printf "creating test data for %s\n" $PROGRAM
printf "=====================================================================\n"
if [ ! -f test1a.tac ] || [ ! -f test1b.tac ] || [ -f correct_output1.tac ]; then
printf "start[minutes] end[Bq/cc] par__All occ__All tem__All cer__All weight\n" > test1a.tac
printf "0.00 1.00 2.410e+02 2.576e+02 2.181e+02 2.203e+02 1.863e+00\n" >> test1a.tac
printf "1.00 2.00 2.888e+03 2.558e+03 2.776e+03 3.518e+03 1.843e-01\n" >> test1a.tac
printf "2.00 6.00 7.605e+03 6.306e+03 6.520e+03 8.464e+03 7.599e-02\n" >> test1a.tac
printf "6.00 10.00 1.022e+04 9.182e+03 9.171e+03 1.112e+04 5.491e-02\n" >> test1a.tac
printf "start[minutes] end[Bq/cc] par__All occ__All tem__All cer__All\n" > test1b.tac
printf "10.00 20.00 2.010e+04 1.176e+04 6.281e+03 2.293e+03\n" >> test1b.tac
printf "20.00 30.00 2.888e+04 1.555e+04 2.133e+03 8.551e+02\n" >> test1b.tac
printf "start[minutes] end[Bq/cc] par__All occ__All tem__All cer__All weight\n" > correct_output1.tac
printf "0.00 1.00 2.410e+02 2.576e+02 2.181e+02 2.203e+02 1.863e+00\n" >> correct_output1.tac
printf "1.00 2.00 2.888e+03 2.558e+03 2.776e+03 3.518e+03 1.843e-01\n" >> correct_output1.tac
printf "2.00 6.00 7.605e+03 6.306e+03 6.520e+03 8.464e+03 7.599e-02\n" >> correct_output1.tac
printf "6.00 10.00 1.022e+04 9.182e+03 9.171e+03 1.112e+04 5.491e-02\n" >> correct_output1.tac
printf "10.00 20.00 2.010e+04 1.176e+04 6.281e+03 2.293e+03\n" >> correct_output1.tac
printf "20.00 30.00 2.888e+04 1.555e+04 2.133e+03 8.551e+02\n" >> correct_output1.tac
fi
printf "\n\n"
printf "=====================================================================\n"
printf "testing %s\n" $PROGRAM
printf "=====================================================================\n"
exit 1
printf "\n 1.0.0 \n"
printf " Test case 1: Reasonable data in PMOD TAC format without options. \n"
printf " Test case 2: New file name given. \n"
printf " Test case 3: First file contains weights. \n"
printf " Expected result: Correctly catenated data is written in new file. \n"
printf " Expected result 2: Weights are silently ignored. \n"
rm -f output.tac
$PROGRAM test1a.tac test1b.tac output.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n ok \n"
tacmatch -abs=0.1 -rel=1 correct_output1.tac output.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n ok \n"
tacweigh -list output.tac
if [ $? -eq 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n passed. \n\n"
printf "\n 1.0.1 \n"
printf " Test case 1: Output file exists. \n"
printf " Expected result: Existing file is overwritten with new file. \n"
cp -f test1a.tac output.tac
$PROGRAM test1a.tac test1b.tac output.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n ok \n"
tacmatch -abs=0.1 -rel=1 correct_output1.tac output.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n passed. \n\n"
printf "\n 1.1.0 \n"
printf " Test case 1: Output file name is NOT given. \n"
printf " Expected result: First file is overwritten with catenated data. \n"
cp -f test1a.tac output.tac
$PROGRAM output.tac test1b.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n ok \n"
tacmatch -abs=0.1 -rel=1 correct_output1.tac output.tac
if [ $? -ne 0 ] ; then printf "\nFailed!\n" ; exit 1 ; fi
printf "\n passed. \n\n"
printf "\n\n"
printf "=====================================================================\n"
printf "testing %s\n" $PROGRAM
printf " All current tests passed, but more testing needed!\n"
printf "=====================================================================\n"
exit 1
printf "=====================================================================\n"
printf " All passed!\n"
printf "=====================================================================\n"
exit 0
printf "\n0.1.0 Unknown option \n\n"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment