summaryrefslogtreecommitdiff
path: root/spectro/average.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/average.c')
-rw-r--r--spectro/average.c194
1 files changed, 142 insertions, 52 deletions
diff --git a/spectro/average.c b/spectro/average.c
index 5e659b8..5a8fb3f 100644
--- a/spectro/average.c
+++ b/spectro/average.c
@@ -1,6 +1,8 @@
/*
* Argyll Color Correction System
* Average one or more .ti3 (or other CGATS like) file values together.
+ * If just one file is supplied, all patches within it with
+ * the same device value are averaged together.
*
* Author: Graeme W. Gill
* Date: 18/1/2011
@@ -85,7 +87,7 @@ int main(int argc, char *argv[]) {
error_program = "average";
- if (argc <= 3)
+ if (argc < 2)
usage("Too few arguments (%d, minimum is 2)",argc-1);
/* Process the arguments */
@@ -147,7 +149,7 @@ int main(int argc, char *argv[]) {
ninps--; /* Number of inputs */
- /* Open and read each input file */
+ /* Open and read each input file, and create output file */
for (n = 0; n <= ninps; n++) {
if ((inps[n].c = new_cgats()) == NULL)
@@ -190,16 +192,18 @@ int main(int argc, char *argv[]) {
ocg->add_field(ocg, n, inps[0].c->t[n].fsym[i], inps[0].c->t[n].ftype[i]);
}
- /* Duplicate all of the data */
- if ((setel = (cgats_set_elem *)malloc(
- sizeof(cgats_set_elem) * inps[0].c->t[n].nfields)) == NULL)
- error("Malloc failed!");
-
- for (i = 0; i < inps[0].c->t[n].nsets; i++) {
- inps[0].c->get_setarr(inps[0].c, n, i, setel);
- ocg->add_setarr(ocg, n, setel);
+ if (ninps > 1) {
+ /* Duplicate all of the data */
+ if ((setel = (cgats_set_elem *)malloc(
+ sizeof(cgats_set_elem) * inps[0].c->t[n].nfields)) == NULL)
+ error("Malloc failed!");
+
+ for (i = 0; i < inps[0].c->t[n].nsets; i++) {
+ inps[0].c->get_setarr(inps[0].c, n, i, setel);
+ ocg->add_setarr(ocg, n, setel);
+ }
+ free(setel);
}
- free(setel);
}
/* Figure out the indexes of the device channels */
@@ -295,44 +299,41 @@ int main(int argc, char *argv[]) {
sizeof(cgats_set_elem) * inps[0].c->t[0].nfields)) == NULL)
error("Malloc failed!");
- /* Process all the other input files */
- for (n = 1; n < ninps; n++) {
+ /* If averaging values within the one file */
+ if (ninps == 1) {
+ int *valdone;
+ double npatches;
+ int k;
+ n = 0; /* Output set index */
- /* Check all the fields match */
- if (inps[0].c->t[0].nfields != inps[n].c->t[0].nfields)
- error ("File '%s' has %d fields, file '%s has %d",
- inps[n].name, inps[n].c->t[0].nfields, inps[0].name, inps[0].c->t[0].nfields);
- for (j = 0; j < inps[0].c->t[0].nfields; j++) {
- if (inps[0].c->t[0].ftype[j] != inps[n].c->t[0].ftype[j])
- error ("File '%s' field no. %d named '%s' doesn't match file '%s' field '%s'",
- inps[n].name, j, inps[n].c->t[0].fsym[j], inps[0].name, inps[0].c->t[0].fsym[j]);
- }
+ if ((valdone = (int *)calloc(inps[0].c->t[0].nsets, sizeof(int))) == NULL)
+ error("Malloc failed!");
- /* If merging, append all the values */
- if (domerge) {
- for (i = 0; i < inps[n].c->t[0].nsets; i++) {
- inps[n].c->get_setarr(inps[n].c, 0, i, setel);
- ocg->add_setarr(ocg, 0, setel);
- }
+ for (i = 0; i < inps[0].c->t[0].nsets; i++) {
- } else { /* Averaging */
- /* Check the number of values matches */
- if (inps[0].c->t[0].nsets != inps[n].c->t[0].nsets)
- error ("File '%s' has %d sets, file '%s has %d",
- inps[n].name, inps[n].c->t[0].nsets, inps[0].name, inps[0].c->t[0].nsets);
-
- /* Add the numeric field values to corresponding output */
- for (i = 0; i < inps[n].c->t[0].nsets; i++) {
+ if (valdone[i])
+ continue;
+
+ inps[0].c->get_setarr(inps[0].c, 0, i, setel);
+ ocg->add_setarr(ocg, 0, setel);
+ npatches = 1.0;
- /* Check that the device values match */
+ /* Locate and patches with matching device values */
+ for (k = i+1; k < inps[0].c->t[0].nsets; k++) {
+
+ /* Check if the device values match */
for (j = 0; j < nchan; j++) {
double diff;
+
diff = *((double *)inps[0].c->t[0].fdata[i][chix[j]])
- - *((double *)inps[n].c->t[0].fdata[i][chix[j]]);
+ - *((double *)inps[0].c->t[0].fdata[k][chix[j]]);
- if (diff > 0.001)
- error ("File '%s' set %d has field '%s' value that differs from '%s'",
- inps[n].name, i+1, inps[n].c->t[0].fsym[j], inps[0].name);
+ if (fabs(diff) > 0.001) {
+ break;
+ }
+ }
+ if (j < nchan) {
+ continue;
}
/* Add all the non-device real field values */
@@ -351,18 +352,13 @@ int main(int argc, char *argv[]) {
if (jj < nchan)
continue;
- *((double *)ocg->t[0].fdata[i][j])
- += *((double *)inps[n].c->t[0].fdata[i][j]);
+ *((double *)ocg->t[0].fdata[n][j])
+ += *((double *)inps[0].c->t[0].fdata[k][j]);
}
+ npatches++;
+ valdone[k] = 1;
}
- }
- }
-
- /* If averaging, divide out the number of files */
- if (!domerge) {
-
- for (i = 0; i < inps[n].c->t[0].nsets; i++) {
-
+ /* Average them out */
for (j = 0; j < inps[0].c->t[0].nfields; j++) {
int jj;
@@ -378,7 +374,101 @@ int main(int argc, char *argv[]) {
if (jj < nchan)
continue;
- *((double *)ocg->t[0].fdata[i][j]) /= (double)ninps;
+ *((double *)ocg->t[0].fdata[n][j]) /= npatches;
+ }
+ n++; /* One more output set */
+ }
+
+ free(valdone);
+
+ /* Averaging patches between identical files, */
+ /* or concatenating (merging) several files */
+ } else {
+ /* Process all the other input files */
+ for (n = 1; n < ninps; n++) {
+
+ /* Check all the fields match */
+ if (inps[0].c->t[0].nfields != inps[n].c->t[0].nfields)
+ error ("File '%s' has %d fields, file '%s has %d",
+ inps[n].name, inps[n].c->t[0].nfields, inps[0].name, inps[0].c->t[0].nfields);
+ for (j = 0; j < inps[0].c->t[0].nfields; j++) {
+ if (inps[0].c->t[0].ftype[j] != inps[n].c->t[0].ftype[j])
+ error ("File '%s' field no. %d named '%s' doesn't match file '%s' field '%s'",
+ inps[n].name, j, inps[n].c->t[0].fsym[j], inps[0].name, inps[0].c->t[0].fsym[j]);
+ }
+
+ /* If merging, append all the values */
+ if (domerge) {
+ for (i = 0; i < inps[n].c->t[0].nsets; i++) {
+ inps[n].c->get_setarr(inps[n].c, 0, i, setel);
+ ocg->add_setarr(ocg, 0, setel);
+ }
+
+ } else { /* Averaging */
+ /* Check the number of values matches */
+ if (inps[0].c->t[0].nsets != inps[n].c->t[0].nsets)
+ error ("File '%s' has %d sets, file '%s has %d",
+ inps[n].name, inps[n].c->t[0].nsets, inps[0].name, inps[0].c->t[0].nsets);
+
+ /* Add the numeric field values to corresponding output */
+ for (i = 0; i < inps[n].c->t[0].nsets; i++) {
+
+ /* Check that the device values match */
+ for (j = 0; j < nchan; j++) {
+ double diff;
+ diff = *((double *)inps[0].c->t[0].fdata[i][chix[j]])
+ - *((double *)inps[n].c->t[0].fdata[i][chix[j]]);
+
+ if (fabs(diff) > 0.001)
+ error ("File '%s' set %d has field '%s' value that differs from '%s'",
+ inps[n].name, i+1, inps[n].c->t[0].fsym[j], inps[0].name);
+ }
+
+ /* Add all the non-device real field values */
+ for (j = 0; j < inps[0].c->t[0].nfields; j++) {
+ int jj;
+
+ /* Only real types */
+ if (inps[0].c->t[0].ftype[j] != r_t)
+ continue;
+
+ /* Not device channels */
+ for (jj = 0; jj < nchan; jj++) {
+ if (chix[jj] == j)
+ break;
+ }
+ if (jj < nchan)
+ continue;
+
+ *((double *)ocg->t[0].fdata[i][j])
+ += *((double *)inps[n].c->t[0].fdata[i][j]);
+ }
+ }
+ }
+ }
+
+ /* If averaging, divide out the number of files */
+ if (!domerge) {
+
+ for (i = 0; i < inps[n].c->t[0].nsets; i++) {
+
+ for (j = 0; j < inps[0].c->t[0].nfields; j++) {
+ int jj;
+
+ /* Only real types */
+ if (inps[0].c->t[0].ftype[j] != r_t)
+ continue;
+
+ /* Not device channels */
+ for (jj = 0; jj < nchan; jj++) {
+ if (chix[jj] == j)
+ break;
+ }
+ if (jj < nchan)
+ continue;
+
+ *((double *)ocg->t[0].fdata[i][j]) /= (double)ninps;
+ }
}
}
}