37 #include "muse_cplwrappers.h"
79 cpl_ensure_code(aTarget && aImage, CPL_ERROR_NULL_INPUT);
80 cpl_ensure_code(cpl_image_get_type(aTarget) == CPL_TYPE_INT,
81 CPL_ERROR_INVALID_TYPE);
82 cpl_ensure_code(cpl_image_get_type(aImage) == CPL_TYPE_INT,
83 CPL_ERROR_INVALID_TYPE);
84 cpl_ensure_code(cpl_image_get_size_x(aTarget) == cpl_image_get_size_x(aImage),
85 CPL_ERROR_ILLEGAL_INPUT);
86 cpl_ensure_code(cpl_image_get_size_y(aTarget) == cpl_image_get_size_y(aImage),
87 CPL_ERROR_ILLEGAL_INPUT);
89 int *target = cpl_image_get_data_int(aTarget);
90 const int *data = cpl_image_get_data_int_const(aImage);
91 cpl_size nData = cpl_image_get_size_x(aImage) * cpl_image_get_size_y(aImage);
93 for (i = 0; i < nData; i++, data++, target++) {
94 *target |= *data & mask;
96 return CPL_ERROR_NONE;
117 cpl_ensure(aImage1 || aImage2, CPL_ERROR_NULL_INPUT, NULL);
118 if (aImage1 == NULL) {
119 return cpl_image_duplicate(aImage2);
121 if (aImage2 == NULL) {
122 return cpl_image_duplicate(aImage1);
124 cpl_type type = cpl_image_get_type(aImage1);
125 cpl_ensure(type == cpl_image_get_type(aImage2), CPL_ERROR_ILLEGAL_INPUT, NULL);
126 cpl_size xsize = cpl_image_get_size_x(aImage1);
127 cpl_ensure(xsize == cpl_image_get_size_x(aImage2), CPL_ERROR_ILLEGAL_INPUT, NULL);
129 cpl_size ysize1 = cpl_image_get_size_y(aImage1);
130 cpl_size ysize2 = cpl_image_get_size_y(aImage2);
131 cpl_image *res = cpl_image_new(xsize, ysize1 + ysize2, type);
132 void *resdata = cpl_image_get_data(res);
133 const void *data1 = cpl_image_get_data_const(aImage1);
134 cpl_size size1 = xsize * ysize1 * cpl_type_get_sizeof(type);
135 const void *data2 = cpl_image_get_data_const(aImage2);
136 cpl_size size2 = xsize * ysize2 * cpl_type_get_sizeof(type);
137 memcpy(resdata, data1, size1);
138 memcpy((
char *)resdata+size1, data2, size2);
161 cpl_ensure(aImage1 || aImage2, CPL_ERROR_NULL_INPUT, NULL);
162 if (aImage1 == NULL) {
163 return cpl_image_duplicate(aImage2);
165 if (aImage2 == NULL) {
166 return cpl_image_duplicate(aImage1);
168 cpl_type type = cpl_image_get_type(aImage1);
169 cpl_ensure(type == cpl_image_get_type(aImage2), CPL_ERROR_ILLEGAL_INPUT, NULL);
170 cpl_size ysize = cpl_image_get_size_y(aImage1);
171 cpl_ensure(ysize == cpl_image_get_size_y(aImage2), CPL_ERROR_ILLEGAL_INPUT, NULL);
173 cpl_size xsize1 = cpl_image_get_size_x(aImage1);
174 cpl_size xsize2 = cpl_image_get_size_x(aImage2);
175 cpl_image *res = cpl_image_new(xsize1 + xsize2, ysize, type);
176 void *resdata = cpl_image_get_data(res);
177 const void *data1 = cpl_image_get_data_const(aImage1);
178 cpl_size size1 = xsize1 * cpl_type_get_sizeof(type);
179 const void *data2 = cpl_image_get_data_const(aImage2);
180 cpl_size size2 = xsize2 * cpl_type_get_sizeof(type);
181 cpl_size size = (size1 + size2) * ysize;
183 for (y = 0, y3 = 0, y4 = 0; y < size; y+=size1+size2, y3+=size1, y4+=size2) {
184 memcpy((
char *)resdata + y, (
char *)data1 + y3, size1);
185 memcpy((
char *)resdata + y + size1, (
char *)data2 + y4, size2);
204 unsigned int aNX,
unsigned int aNY)
206 cpl_ensure(aImage, CPL_ERROR_NULL_INPUT, NULL);
208 cpl_ensure((aNX & 1) && (aNY & 1), CPL_ERROR_ILLEGAL_INPUT, NULL);
211 cpl_image *filtered = cpl_image_new(cpl_image_get_size_x(aImage),
212 cpl_image_get_size_y(aImage),
215 cpl_mask *mask = cpl_mask_new(aNX, aNY);
217 cpl_errorstate prestate = cpl_errorstate_get();
218 cpl_image_filter_mask(filtered, aImage, mask, CPL_FILTER_MEDIAN,
220 if (!cpl_errorstate_is_equal(prestate)) {
221 cpl_msg_error(__func__,
"filtering failed: %s", cpl_error_get_message());
222 cpl_mask_delete(mask);
223 cpl_image_delete(filtered);
226 cpl_mask_delete(mask);
229 cpl_image *subtracted = cpl_image_subtract_create(aImage, filtered);
230 cpl_image_delete(filtered);
260 cpl_ensure(aImage && aWindow, CPL_ERROR_NULL_INPUT, NULL);
262 cpl_image *image = cpl_image_duplicate(aImage);
263 cpl_image_accept_all(image);
265 cpl_vector *slopes = cpl_vector_new(2);
267 for (k = 0; k <= 1; k++) {
269 cpl_image *coll = cpl_image_collapse_window_create(image,
270 aWindow[0], aWindow[2],
271 aWindow[1], aWindow[3],
274 cpl_image_delete(image);
275 cpl_vector_delete(slopes);
280 cpl_image_divide_scalar(coll, aWindow[3] - aWindow[2] + 1);
282 cpl_image_divide_scalar(coll, aWindow[1] - aWindow[0] + 1);
284 int npx = k == 0 ? cpl_image_get_size_x(coll) : cpl_image_get_size_y(coll);
286 cpl_matrix *coords = cpl_matrix_new(1, npx);
287 cpl_vector *values = cpl_vector_new(npx);
288 float *data = cpl_image_get_data_float(coll);
290 for (i = 0; i < npx; i++) {
291 cpl_matrix_set(coords, 0, i, i + 1);
294 cpl_vector_set(values, i, data[i]);
297 cpl_polynomial *fit = cpl_polynomial_new(1);
298 const cpl_boolean sym = CPL_FALSE;
299 const cpl_size mindeg = 0, maxdeg = 1;
300 cpl_error_code err = cpl_polynomial_fit(fit, coords, &sym, values, NULL,
301 CPL_FALSE, &mindeg, &maxdeg);
302 cpl_matrix_delete(coords);
303 cpl_vector_delete(values);
304 cpl_image_delete(coll);
306 if (err != CPL_ERROR_NONE) {
307 cpl_msg_warning(__func__,
"Could not fit %s slope: %s",
308 k == 0 ?
"horizontal" :
"vertical",
309 cpl_error_get_message());
310 cpl_polynomial_delete(fit);
311 cpl_vector_delete(slopes);
312 cpl_image_delete(image);
316 printf(
"%s: fit (%s)\n", __func__, k == 0 ?
"rows" :
"cols");
317 cpl_polynomial_dump(fit, stdout);
320 const cpl_size pows = { 1 };
321 cpl_vector_set(slopes, k, cpl_polynomial_get_coeff(fit, &pows));
322 cpl_polynomial_delete(fit);
324 cpl_image_delete(image);
326 printf(
"slopes vector:\n");
327 cpl_vector_dump(slopes, stdout);
348 cpl_ensure(aImage != NULL, CPL_ERROR_NULL_INPUT, 0.0);
352 cpl_size n = cpl_array_get_size(a);
354 if (aFraction < 0) aFraction = 0;
355 if (aFraction > 1) aFraction = 1;
356 n = lround(n * aFraction);
357 double res = cpl_array_get(a, n-1, NULL);
381 cpl_ensure(imlist, CPL_ERROR_NULL_INPUT, NULL);
382 int count = cpl_imagelist_get_size(imlist);
383 cpl_ensure(count > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
384 cpl_image *res = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
386 unsigned int mask = 0xffffffff;
387 for (i = 1; i < count; i++) {
389 if (r != CPL_ERROR_NONE) {
390 cpl_image_delete(res);
410 cpl_ensure(aVector, CPL_ERROR_NULL_INPUT, 0.);
412 cpl_size i, n = cpl_vector_get_size(aVector);
413 for (i = 0; i < n; i++) {
414 mdev += fabs(cpl_vector_get(aVector, i) - aCenter);
416 return mdev / (double)n;
436 cpl_ensure(aVector, CPL_ERROR_NULL_INPUT, 0.);
437 double median = cpl_vector_get_median(aVector),
439 cpl_size i, n = cpl_vector_get_size(aVector);
440 for (i = 0; i < n; i++) {
441 mdev += fabs(cpl_vector_get(aVector, i) - median);
446 return mdev / (double)n;
468 double median = cpl_vector_get_median_const(aVector);
469 cpl_vector *v = cpl_vector_duplicate(aVector), *v2;
470 int i, splitindex = 0;
472 cpl_vector_sort(v, +1);
474 cpl_vector_dump(v, stdout);
476 printf(
"median=%f%d\n", median);
480 splitindex = cpl_vector_find(v, median);
483 v2 = cpl_vector_new(cpl_vector_get_size(v) - splitindex - 1);
485 printf(
"Copying elements %d to %d\n", splitindex+1, cpl_vector_get_size(v)-1);
487 for (i = splitindex; i < cpl_vector_get_size(v); i++){
489 printf(
" %d %f\n", i+1, cpl_vector_get(v, i));
491 cpl_vector_set(v2, i-splitindex, cpl_vector_get(v, i));
497 sqr = cpl_vector_get_median(v2);
498 cpl_vector_delete(v2);
501 v2 = cpl_vector_new(splitindex - 1);
503 printf(
"Copying elements %d to %d\n", 1, splitindex+1);
505 for (i = 0; i <= splitindex; i++) {
507 printf(
" %d %f\n", i+1, cpl_vector_get(v, i));
509 cpl_vector_set(v2, i, cpl_vector_get(v, i));
515 sqr -= cpl_vector_get_median(v2);
516 cpl_vector_delete(v2);
544 double aLoVal,
double aHiVal)
546 cpl_ensure_code(aVec, CPL_ERROR_NULL_INPUT);
547 cpl_ensure_code(aLoCut <= aHiCut, CPL_ERROR_ILLEGAL_INPUT);
549 double *data = cpl_vector_get_data(aVec);
550 int i, n = cpl_vector_get_size(aVec);
551 for (i = 0; i < n; i++) {
552 if (data[i] > aHiCut) {
554 }
else if (data[i] < aLoCut) {
559 return CPL_ERROR_NONE;
578 cpl_ensure_code(aVector, CPL_ERROR_NULL_INPUT);
579 int size = cpl_vector_get_size(aVector);
580 cpl_ensure_code(aElement >= 0 && aElement < size, CPL_ERROR_ILLEGAL_INPUT);
582 if (aElement < size - 1) {
585 double *data = cpl_vector_get_data(aVector);
586 memmove(&data[aElement], &data[aElement+1],
587 (size-1 - aElement) *
sizeof(
double));
591 return cpl_vector_set_size(aVector, size - 1);
606 cpl_ensure(aVector, CPL_ERROR_NULL_INPUT, -1);
607 cpl_vector *sorted = cpl_vector_duplicate(aVector);
608 cpl_vector_sort(sorted, CPL_SORT_ASCENDING);
609 double *data = cpl_vector_get_data(sorted);
610 cpl_size i, n = cpl_vector_get_size(sorted),
612 for (i = 1; i < n; i++) {
613 if (data[i] != data[i - 1]) {
617 cpl_vector_delete(sorted);
633 cpl_ensure(aVector, CPL_ERROR_NULL_INPUT, NULL);
634 cpl_vector *sorted = cpl_vector_duplicate(aVector);
635 cpl_vector_sort(sorted, CPL_SORT_ASCENDING);
636 double *data = cpl_vector_get_data(sorted);
637 cpl_size i, n = cpl_vector_get_size(sorted),
639 cpl_vector *vunique = cpl_vector_new(n);
640 cpl_vector_set(vunique, iunique++, data[0]);
641 for (i = 1; i < n; i++) {
642 if (data[i] != data[i - 1]) {
643 cpl_vector_set(vunique, iunique++, data[i]);
646 cpl_vector_delete(sorted);
647 cpl_vector_set_size(vunique, iunique);
665 cpl_ensure(aDef, CPL_ERROR_NULL_INPUT, NULL);
666 cpl_table *res = cpl_table_new(aLength);
667 for (; aDef->
name != NULL; aDef++) {
668 cpl_error_code rc = CPL_ERROR_NONE;
669 if (aDef->
type & CPL_TYPE_POINTER) {
670 rc = cpl_table_new_column_array(res, aDef->
name, aDef->
type, 2);
672 rc = cpl_table_new_column(res, aDef->
name, aDef->
type);
674 if (rc != CPL_ERROR_NONE) {
675 cpl_table_delete(res);
678 if (aDef->
unit != NULL) {
679 if (cpl_table_set_column_unit(res, aDef->
name,
680 aDef->
unit) != CPL_ERROR_NONE) {
684 if (aDef->
format != NULL) {
685 if (cpl_table_set_column_format(res, aDef->
name,
686 aDef->
format) != CPL_ERROR_NONE) {
711 int extension = cpl_fits_find_extension(aFile, aExtension);
712 if (extension <= 0) {
713 cpl_error_set_message(__func__, cpl_error_get_code(),
"%s['%s']: "
714 "extension not found by EXTNAME", aFile, aExtension);
717 cpl_msg_debug(__func__,
"Loading %s['%s'] from extension %d", aFile,
718 aExtension, extension);
719 cpl_table *tbl = cpl_table_load(aFile, extension, 2);
721 cpl_table_delete(tbl);
747 const char *aExtension,
749 cpl_ensure_code(aTable != NULL, CPL_ERROR_NULL_INPUT);
750 cpl_ensure_code(aFile != NULL, CPL_ERROR_NULL_INPUT);
751 cpl_ensure_code(aExtension != NULL, CPL_ERROR_NULL_INPUT);
753 if (r != CPL_ERROR_NONE) {
754 cpl_msg_error(__func__,
" %s['%s'] Table format error", aFile, aExtension);
755 cpl_error_set(__func__, r);
758 cpl_propertylist *props = cpl_propertylist_new();
759 cpl_propertylist_update_string(props,
"EXTNAME", aExtension);
760 r = cpl_table_save(aTable, NULL, props, aFile, CPL_IO_EXTEND);
761 cpl_propertylist_delete(props);
762 if (r != CPL_ERROR_NONE) {
763 cpl_msg_error(__func__,
"%s[%s]: %s", aFile, aExtension,
764 cpl_error_get_message());
780 if (aTable == NULL) {
781 cpl_msg_error(__func__,
"NULL table");
782 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT);
783 return CPL_ERROR_NULL_INPUT;
786 return CPL_ERROR_NONE;
788 cpl_error_code rc = CPL_ERROR_NONE;
789 for (; aDef->
name != NULL; aDef++) {
790 if (!cpl_table_has_column(aTable, aDef->
name)) {
792 rc = CPL_ERROR_ILLEGAL_INPUT;
793 cpl_error_set_message(__func__, rc,
"table column '%s' not found",
798 cpl_type coltype = cpl_table_get_column_type(aTable, aDef->
name);
799 if (((coltype | CPL_TYPE_POINTER) != (aDef->
type | CPL_TYPE_POINTER)) ||
800 ((coltype & CPL_TYPE_POINTER) && !(aDef->
type & CPL_TYPE_POINTER))) {
801 rc = CPL_ERROR_ILLEGAL_INPUT;
802 cpl_error_set_message(__func__, rc,
803 "table column '%s' format '%s' is not '%s'",
804 aDef->
name, cpl_type_get_name(coltype),
805 cpl_type_get_name(aDef->
type));
832 cpl_ensure(aTable && aColumn, CPL_ERROR_NULL_INPUT, NULL);
833 cpl_size nRows = cpl_table_get_nrow(aTable);
835 cpl_type type = cpl_table_get_column_type(aTable, aColumn);
837 return cpl_array_new(0, type);
839 if (type == CPL_TYPE_DOUBLE) {
840 double *src = cpl_table_get_data_double(aTable, aColumn);
841 return cpl_array_wrap_double(src, nRows);
842 }
else if (type == CPL_TYPE_FLOAT) {
843 float *src = cpl_table_get_data_float(aTable, aColumn);
844 return cpl_array_wrap_float(src, nRows);
845 }
else if (type == CPL_TYPE_INT) {
846 int *src = cpl_table_get_data_int(aTable, aColumn);
847 return cpl_array_wrap_int(src, nRows);
849 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
850 cpl_msg_error(__func__,
"%s: %i - %s", cpl_error_get_message(), type,
851 cpl_type_get_name(type));
869 const cpl_array *aArray)
871 cpl_ensure_code(aTable && aColumn && aArray, CPL_ERROR_NULL_INPUT);
872 cpl_size n_rows = cpl_table_get_nrow(aTable);
874 for (i = 0; i < n_rows; i++) {
876 double d = cpl_array_get(aArray, i, &flag);
878 cpl_table_set(aTable, aColumn, i, d);
880 cpl_table_set_invalid(aTable, aColumn, i);
883 return CPL_ERROR_NONE;
901 cpl_ensure(aTable && aColumn, CPL_ERROR_NULL_INPUT, NULL);
902 if (cpl_table_get_column_type(aTable, aColumn) & CPL_TYPE_POINTER) {
903 return cpl_array_duplicate(cpl_table_get_array(aTable, aColumn, aRow));
906 = cpl_array_new(1, cpl_table_get_column_type(aTable, aColumn));
908 cpl_array_set(res, 0, cpl_table_get(aTable, aColumn, aRow, &flag));
910 cpl_array_delete(res);
936 cpl_ensure(aTable && aColumn, CPL_ERROR_NULL_INPUT, 0);
939 cpl_array_unwrap(array);
954 cpl_size nx = cpl_image_get_size_x(aImage);
955 cpl_size ny = cpl_image_get_size_y(aImage);
956 cpl_array *array = cpl_array_new(nx*ny, cpl_image_get_type(aImage));
959 for (iy = 1; iy <= ny; iy++) {
961 for (ix = 1; ix <= nx; ix++, i++) {
963 double d = cpl_image_get(aImage, ix, iy, &rej);
964 cpl_array_set(array, i, d);
966 cpl_array_set_invalid(array, i);
990 cpl_ensure_code(aArray && aCoeff, CPL_ERROR_NULL_INPUT);
991 const cpl_size nrows = cpl_array_get_size(aArray);
992 cpl_size order = cpl_array_get_size(aCoeff);
994 cpl_array_fill_window(aArray, 0, nrows, 0.0);
995 return CPL_ERROR_NONE;
998 cpl_array *x = cpl_array_duplicate(aArray);
999 cpl_array_fill_window(aArray, 0, nrows, cpl_array_get(aCoeff, order, NULL));
1002 for (k = order-1; k >= 0; k--) {
1003 cpl_array_multiply(aArray, x);
1004 cpl_array_add_scalar(aArray, cpl_array_get(aCoeff, k, NULL));
1007 cpl_array_delete(x);
1009 return CPL_ERROR_NONE;
1028 cpl_ensure(aCoeff, CPL_ERROR_NULL_INPUT, NAN);
1029 cpl_size order = cpl_array_get_size(aCoeff);
1034 double res = cpl_array_get(aCoeff, order, NULL);
1036 for (k = order-1; k >= 0; k--) {
1037 res = res * aDouble + cpl_array_get(aCoeff, k, NULL);
1055 cpl_ensure_code(aArray && aName, CPL_ERROR_NULL_INPUT);
1056 cpl_size i, size = cpl_array_get_size(aArray);
1057 for (i = 0; i < size; i++) {
1058 printf(
"%s[%"CPL_SIZE_FORMAT
"] = %g\n", aName, i,
1059 cpl_array_get(aArray, i, NULL));
1061 return CPL_ERROR_NONE;
1074 cpl_ensure_code(aArray != NULL, CPL_ERROR_NULL_INPUT);
1075 cpl_size n = cpl_array_get_size(aArray);
1076 cpl_size n_val = n - cpl_array_count_invalid(aArray);
1077 cpl_msg_debug(__func__,
"size = %li, %li valid", (
long)n, (
long)n_val);
1079 return CPL_ERROR_NONE;
1083 for (i = 0; (i < n) && (idx < n_val); i++) {
1085 double d = cpl_array_get(aArray, i, &rej);
1088 cpl_array_set(aArray, idx, d);
1093 cpl_array_set_size(aArray, n_val);
1094 return CPL_ERROR_NONE;
1115 cpl_size aGap,
double aLimit)
1117 cpl_ensure(aArray && aHistogram, CPL_ERROR_NULL_INPUT, -1);
1120 double value = cpl_array_get(aArray, 0, &err);
1121 cpl_ensure(err >= 0, CPL_ERROR_ILLEGAL_INPUT, -2);
1124 const double *hpos = cpl_bivector_get_x_data_const(aHistogram),
1125 *hval = cpl_bivector_get_y_data_const(aHistogram);
1126 cpl_size nhist = cpl_bivector_get_size(aHistogram);
1127 cpl_array *ahist = cpl_array_wrap_double((
double *)hval, nhist);
1129 cpl_array_get_maxpos(ahist, &imax);
1130 cpl_array_unwrap(ahist);
1133 double loval = hpos[0],
1134 hival = hpos[nhist - 1];
1135 cpl_size i, nlow = 0;
1136 for (i = imax; i >= 0; i--) {
1137 if (hval[i] <= aLimit) {
1145 }
else if (nlow > 0) {
1151 for (i = imax; i < nhist; i++) {
1152 if (hval[i] <= aLimit) {
1160 }
else if (nlow > 0) {
1162 hival = hpos[nhist - 1];
1165 cpl_msg_debug(__func__,
"Histogram gaps (%"CPL_SIZE_FORMAT
" consecutive "
1166 "entries <= %f) at %f and %f", aGap, aLimit, loval, hival);
1170 cpl_size idx, narray = cpl_array_get_size(aArray);
1171 for (idx = 0; idx < narray; idx++) {
1172 value = cpl_array_get(aArray, idx, NULL);
1173 if (value > hival || value < loval) {
1174 cpl_array_set_invalid(aArray, idx);
1179 cpl_size nbad = cpl_array_count_invalid(aArray);
1189 static int cmp_double_asc(
const void *p1,
const void *p2) {
1190 double d = (*(
const double *)p1 - *(
const double *)p2);
1191 return (d < 0)?-1:(d>0)?1:0;
1194 static int cmp_double_desc(
const void *p1,
const void *p2) {
1195 double d = (*(
const double *)p1 - *(
const double *)p2);
1196 return (d < 0)?1:(d>0)?-1:0;
1199 static int cmp_float_asc(
const void *p1,
const void *p2) {
1200 float d = (*(
const float *)p1 - *(
const float *)p2);
1201 return (d < 0)?-1:(d>0)?1:0;
1204 static int cmp_float_desc(
const void *p1,
const void *p2) {
1205 float d = (*(
const float *)p1 - *(
const float *)p2);
1206 return (d < 0)?1:(d>0)?-1:0;
1209 static int cmp_int_asc(
const void *p1,
const void *p2) {
1210 return (*(
const int *)p1 - *(
const int *)p2);
1213 static int cmp_int_desc(
const void *p1,
const void *p2) {
1214 return (*(
const int *)p2 - *(
const int *)p1);
1231 cpl_ensure_code(aArray != NULL, CPL_ERROR_NULL_INPUT);
1232 cpl_ensure_code(!cpl_array_has_invalid(aArray), CPL_ERROR_NULL_INPUT);
1234 cpl_size n = cpl_array_get_size(aArray);
1235 if (cpl_array_get_type(aArray) == CPL_TYPE_DOUBLE) {
1236 double *d = cpl_array_get_data_double(aArray);
1237 qsort(d, n,
sizeof(
double), (aOrder)?cmp_double_asc:cmp_double_desc);
1238 return CPL_ERROR_NONE;
1239 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_FLOAT) {
1240 float *d = cpl_array_get_data_float(aArray);
1241 qsort(d, n,
sizeof(
float), (aOrder)?cmp_float_asc:cmp_float_desc);
1242 return CPL_ERROR_NONE;
1243 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_INT) {
1244 int *d = cpl_array_get_data_int(aArray);
1245 qsort(d, n,
sizeof(
int), (aOrder)?cmp_int_asc:cmp_int_desc);
1246 return CPL_ERROR_NONE;
1248 return CPL_ERROR_ILLEGAL_INPUT;
1274 double aMin,
double aMax)
1276 cpl_ensure(aArray, CPL_ERROR_NULL_INPUT, NULL);
1279 double value = cpl_array_get(aArray, 0, &err);
1280 cpl_ensure(err >= 0, CPL_ERROR_INVALID_TYPE, NULL);
1281 if (!isnan(aMin) && !isnan(aMax) && aMin >= aMax) {
1282 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
1286 aMin = cpl_array_get_min(aArray);
1289 aMax = cpl_array_get_max(aArray);
1291 cpl_size hlen = lround((aMax - aMin) / aWidth) + 1;
1292 cpl_bivector *histogram = cpl_bivector_new(hlen);
1295 double *hpos = cpl_bivector_get_x_data(histogram);
1297 for (i = 0; i < hlen; i++) {
1298 hpos[i] = i * aWidth + aMin;
1302 double *hval = cpl_bivector_get_y_data(histogram);
1304 cpl_vector_fill(cpl_bivector_get_y(histogram), 0.);
1305 cpl_size n = cpl_array_get_size(aArray);
1306 for (i = 0; i < n; i++) {
1307 value = cpl_array_get(aArray, i, &err);
1312 cpl_size idx = lround((value - aMin) / aWidth);
1313 if (idx >= hlen || idx < 0) {
1320 printf(
"histogram %f...%f / %f\n", aMin, aMax, aWidth);
1321 cpl_bivector_dump(histogram, stdout);
1344 cpl_ensure(aArray, CPL_ERROR_NULL_INPUT, 0);
1346 cpl_size max = cpl_array_get_size(aArray);
1347 cpl_type type = cpl_array_get_type(aArray);
1348 if (type == CPL_TYPE_DOUBLE) {
1349 const double *data = cpl_array_get_data_double_const(aArray);
1350 while (max - min > 1) {
1351 int i = (max + min)/2;
1352 if (data[i] > aValue) {
1358 }
else if (type == CPL_TYPE_FLOAT) {
1359 const float *data = cpl_array_get_data_float_const(aArray);
1360 while (max - min > 1) {
1361 int i = (max + min)/2;
1362 if (data[i] > aValue) {
1368 }
else if (type == CPL_TYPE_INT) {
1369 const int *data = cpl_array_get_data_int_const(aArray);
1370 while (max - min > 1) {
1371 int i = (max + min)/2;
1372 if (data[i] > aValue) {
1379 cpl_msg_error(__func__,
"illegal type %i", type);
1380 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
1405 cpl_ensure(aArray, CPL_ERROR_NULL_INPUT, CPL_FALSE);
1406 cpl_type type = cpl_array_get_type(aArray);
1410 case CPL_TYPE_LONG_LONG:
1414 cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
1418 cpl_size idx, n = cpl_array_get_size(aArray);
1419 for (idx = 0; idx < n - 1; idx++) {
1421 cpl_size v1 = cpl_array_get(aArray, idx, &err);
1426 for (idx2 = idx + 1; idx2 < n; idx2++) {
1427 cpl_size v2 = cpl_array_get(aArray, idx2, &err);
1433 cpl_msg_debug(__func__,
"entry[%"CPL_SIZE_FORMAT
"] == entry[%"
1434 CPL_SIZE_FORMAT
"] == %"CPL_SIZE_FORMAT, idx, idx2, v1);
1460 cpl_size nrows = cpl_array_get_size(aArray);
1461 if (aCount > nrows - aStart) {
1462 aCount = nrows - aStart;
1464 cpl_type type = cpl_array_get_type(aArray);
1465 if (type == CPL_TYPE_DOUBLE) {
1466 return cpl_array_wrap_double(cpl_array_get_data_double(aArray) + aStart,
1468 }
else if (type == CPL_TYPE_FLOAT) {
1469 return cpl_array_wrap_float(cpl_array_get_data_float(aArray) + aStart,
1471 }
else if (type == CPL_TYPE_INT) {
1472 return cpl_array_wrap_int(cpl_array_get_data_int(aArray) + aStart,
1475 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
1496 const cpl_array *aArray)
1498 cpl_ensure_code(aDest && aArray, CPL_ERROR_NULL_INPUT);
1499 cpl_size count = cpl_array_get_size(aArray);
1501 if (destArray == NULL) {
1502 return CPL_ERROR_ILLEGAL_INPUT;
1504 cpl_array_add(destArray, aArray);
1505 cpl_array_unwrap(destArray);
1507 return CPL_ERROR_NONE;
1524 cpl_ensure(aArray, CPL_ERROR_NULL_INPUT, NULL);
1525 cpl_ensure(aOffset > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1526 cpl_size nrows = cpl_array_get_size(aArray);
1528 cpl_array *a1 = cpl_array_extract(aArray, 0, nrows - aOffset);
1529 cpl_array *a2 = cpl_array_extract(aArray, aOffset, nrows - aOffset);
1530 if (a1 == NULL || a2 == NULL) {
1531 cpl_array_delete(a1);
1532 cpl_array_delete(a2);
1535 cpl_array_subtract(a2, a1);
1536 cpl_array_delete(a1);
1557 cpl_ensure_code(aArray, CPL_ERROR_NULL_INPUT);
1558 cpl_type type = cpl_array_get_type(aArray);
1559 cpl_size n = cpl_array_get_size(aArray);
1560 if (type == CPL_TYPE_DOUBLE) {
1561 double *d = cpl_array_get_data_double(aArray);
1563 for (i = 0; i < n; i++, d++) {
1566 }
else if (type == CPL_TYPE_FLOAT) {
1567 float *d = cpl_array_get_data_float(aArray);
1569 for (i = 0; i < n; i++, d++) {
1573 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
1574 return CPL_ERROR_ILLEGAL_INPUT;
1576 return CPL_ERROR_NONE;
1596 cpl_ensure_code(aArray, CPL_ERROR_NULL_INPUT);
1597 cpl_type type = cpl_array_get_type(aArray);
1598 cpl_size n = cpl_array_get_size(aArray);
1599 if (type == CPL_TYPE_DOUBLE) {
1600 double *d = cpl_array_get_data_double(aArray);
1602 for (i = 0; i < n; i++, d++) {
1605 }
else if (type == CPL_TYPE_FLOAT) {
1606 float *d = cpl_array_get_data_float(aArray);
1608 for (i = 0; i < n; i++, d++) {
1612 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
1613 return CPL_ERROR_ILLEGAL_INPUT;
1615 return CPL_ERROR_NONE;
1645 const cpl_array *aSourceAbscissa,
1646 const cpl_array *aSourceOrdinate)
1648 cpl_ensure(aTargetAbscissa && aSourceAbscissa && aSourceOrdinate,
1649 CPL_ERROR_NULL_INPUT, NULL);
1651 double *targetX = cpl_array_get_data_double((cpl_array *)aTargetAbscissa);
1652 double *srcX = cpl_array_get_data_double((cpl_array *)aSourceAbscissa);
1653 double *srcY = cpl_array_get_data_double((cpl_array *)aSourceOrdinate);
1654 cpl_ensure(targetX && srcX && srcY, CPL_ERROR_ILLEGAL_INPUT, NULL);
1656 cpl_array *targetOrdinate = cpl_array_duplicate(aTargetAbscissa);
1657 double *targetY = cpl_array_get_data_double(targetOrdinate);
1659 cpl_size n_src = cpl_array_get_size(aSourceAbscissa);
1660 cpl_vector *srcX_vec = cpl_vector_wrap(n_src, srcX);
1661 cpl_vector *srcY_vec = cpl_vector_wrap(n_src, srcY);
1662 cpl_bivector *src_vec = cpl_bivector_wrap_vectors(srcX_vec, srcY_vec);
1664 cpl_size offset = (srcX[0] <= targetX[0])?0:
1669 cpl_vector *targetX_vec = cpl_vector_wrap(n_target, targetX + offset);
1670 cpl_vector *targetY_vec = cpl_vector_wrap(n_target, targetY + offset);
1671 cpl_bivector *target_vec = cpl_bivector_wrap_vectors(targetX_vec,
1674 cpl_array_fill_window_invalid(targetOrdinate, 0, offset);
1676 if (offset + n_target < (
unsigned)cpl_array_get_size(targetOrdinate)) {
1677 cpl_array_fill_window_invalid(targetOrdinate, offset + n_target,
1678 cpl_array_get_size(targetOrdinate)
1679 - (offset + n_target));
1681 cpl_bivector_interpolate_linear(target_vec, src_vec);
1682 cpl_bivector_unwrap_vectors(target_vec);
1683 cpl_vector_unwrap(targetX_vec);
1684 cpl_vector_unwrap(targetY_vec);
1685 cpl_bivector_unwrap_vectors(src_vec);
1686 cpl_vector_unwrap(srcX_vec);
1687 cpl_vector_unwrap(srcY_vec);
1689 return targetOrdinate;
1714 const cpl_table *aSrcTable,
1715 const char *aSrcAbscissa,
1716 const char *aSrcOrdinate)
1723 cpl_array_unwrap(sabs);
1724 cpl_array_unwrap(sord);
1746 cpl_ensure(aString && aDelim, CPL_ERROR_NULL_INPUT, NULL);
1748 char *
string = cpl_strdup(aString);
1751 char *prev = string, *next;
1752 cpl_array *out = cpl_array_new(0, CPL_TYPE_STRING);
1755 next = strstr(prev, aDelim);
1760 cpl_array_set_size(out, ++ntok);
1761 cpl_array_set_string(out, ntok - 1, prev);
1763 prev = next + strlen(aDelim);
1768 printf(
"Input string %s and delimiter %s resulted in output\n",
1770 cpl_array_dump(out, 0, cpl_array_get_size(out), stdout);
1795 cpl_ensure(aArray, CPL_ERROR_NULL_INPUT, NULL);
1796 cpl_ensure(cpl_array_get_type(aArray) == CPL_TYPE_STRING,
1797 CPL_ERROR_ILLEGAL_INPUT, NULL);
1799 cpl_size i, n = cpl_array_get_size(aArray);
1800 cpl_array *darray = cpl_array_new(n, CPL_TYPE_DOUBLE);
1801 for (i = 0; i < n; i++) {
1802 const char *
string = cpl_array_get_string(aArray, i);
1806 cpl_array_set_double(darray, i, atof(
string));
1828 const char *aPrefix,
const char *aName)
1830 char *fullname = cpl_sprintf(
"%s.%s", aPrefix, aName);
1831 cpl_parameter *p = cpl_parameterlist_find(aParameters, fullname);
1857 const char *aKeyword, cpl_size aValue)
1859 cpl_ensure_code(aHeader && aKeyword, CPL_ERROR_NULL_INPUT);
1860 cpl_property *p = cpl_propertylist_get_property(aHeader, aKeyword);
1861 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
1862 cpl_error_code rc = CPL_ERROR_NONE;
1863 switch (cpl_property_get_type(p)) {
1864 case CPL_TYPE_LONG_LONG:
1865 rc = cpl_property_set_long_long(p, aValue);
1868 rc = cpl_property_set_long(p, aValue);
1871 rc = cpl_property_set_int(p, aValue);
1891 cpl_ensure_code(aFrames, CPL_ERROR_NULL_INPUT);
1892 cpl_error_code rc = CPL_ERROR_NONE;
1894 while (cpl_frameset_get_size(aFrames) > 0 && rc == CPL_ERROR_NONE) {
1895 cpl_frame *frame = cpl_frameset_get_position(aFrames, 0);
1896 rc = cpl_frameset_erase_frame(aFrames, frame);
1922 cpl_ensure_code(aFrames, CPL_ERROR_NULL_INPUT);
1924 printf(
"\n\n\n%s input frameset (with duplicates):\n", __func__);
1925 cpl_frameset_dump(aFrames, stdout);
1926 printf(
"---------------------------------------------------------------------------\n");
1929 cpl_error_code rc = CPL_ERROR_NONE;
1933 for (i = 0; i < cpl_frameset_get_size(aFrames) - 1; i++) {
1934 cpl_frame *fref = cpl_frameset_get_position(aFrames, i);
1936 for (j = i + 1; j < cpl_frameset_get_size(aFrames); j++) {
1937 cpl_frame *fother = cpl_frameset_get_position(aFrames, j);
1938 cpl_boolean areequal = CPL_FALSE;
1939 cpl_errorstate state = cpl_errorstate_get();
1940 const char *fn1 = cpl_frame_get_filename(fref),
1941 *fn2 = cpl_frame_get_filename(fother);
1942 if (!cpl_errorstate_is_equal(state)) {
1943 cpl_errorstate_set(state);
1945 if ((!fn1 && fn2) || (fn1 && !fn2)) {
1946 areequal = CPL_FALSE;
1947 }
else if (!fn1 && !fn2) {
1948 areequal = CPL_TRUE;
1950 areequal = !strcmp(fn1, fn2);
1953 && !strcmp(cpl_frame_get_tag(fref), cpl_frame_get_tag(fother));
1955 && (cpl_frame_get_group(fref) == cpl_frame_get_group(fother));
1957 && (cpl_frame_get_level(fref) == cpl_frame_get_level(fother));
1959 && (cpl_frame_get_type(fref) == cpl_frame_get_type(fother));
1962 printf(
"%ld/%ld are equal: %s/%s, %s/%s, %d/%d, %d/%d, %d/%d\n", i, j,
1963 fn1, fn2, tag1, tag2,
1964 cpl_frame_get_group(fref), cpl_frame_get_group(fother),
1965 cpl_frame_get_level(fref), cpl_frame_get_level(fother),
1966 cpl_frame_get_type(fref), cpl_frame_get_type(fother));
1971 rc = cpl_frameset_erase_frame(aFrames, fref);
1978 printf(
"---------------------------------------------------------------------------\n");
1979 printf(
"%s input frameset (without duplicates):\n", __func__);
1980 cpl_frameset_dump(aFrames, stdout);
1981 printf(
"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n\n");
2003 const cpl_boolean is_reverse = aFirst > aLast ? CPL_TRUE : CPL_FALSE;
2004 const char *revmsg = is_reverse ?
" in reverse order" :
"";
2005 const unsigned newest = is_reverse ? aFirst : aLast,
2006 nmax = labs(aLast - aFirst) + 1;
2007 unsigned ndump = 20;
2008 if (getenv(
"MUSE_CPL_ERRORSTATE_NDUMP") &&
2009 atoi(getenv(
"MUSE_CPL_ERRORSTATE_NDUMP")) > 0) {
2010 ndump = atoi(getenv(
"MUSE_CPL_ERRORSTATE_NDUMP"));
2012 ndump = nmax < ndump ? nmax : ndump;
2015 if (aCurrent == aLast - (ndump-1)) {
2016 cpl_msg_error(__func__,
"Dumping the %u most recent error(s) out of a "
2017 "total of %u errors%s:", ndump, newest, revmsg);
2018 cpl_msg_indent_more();
2020 if (aCurrent >= aLast - (ndump-1)) {
2021 cpl_msg_error(__func__,
"[%u/%u] '%s' (%u) at %s", aCurrent, newest,
2022 cpl_error_get_message(), cpl_error_get_code(),
2023 cpl_error_get_where());
2025 if (aCurrent == aLast) {
2026 cpl_msg_indent_less();
2029 cpl_msg_info(__func__,
"No error(s) to dump");
2049 #ifdef HAVE_READLINK
2050 char buffer[FILENAME_MAX] =
"\0";
2051 int length = readlink(
"/proc/self/exe", buffer,
sizeof(buffer) - 1);
2053 buffer[length] =
'\0';
2055 if (strstr(buffer,
"esorex")) {
2057 }
else if (strstr(buffer,
"python")) {
2059 }
else if (strstr(buffer,
"jre")) {
cpl_error_code muse_cplarray_erase_invalid(cpl_array *aArray)
Erase all invalid values from an array.
cpl_type type
Column type (use CPL_TYPE_POINTER for array columns).
cpl_array * muse_cplarray_interpolate_table_linear(const cpl_array *aTargetAbscissa, const cpl_table *aSrcTable, const char *aSrcAbscissa, const char *aSrcOrdinate)
Linear interpolation of a 1d column.
const int required
Is column required?
cpl_error_code muse_cplarray_dump_name(const cpl_array *aArray, const char *aName)
Dump a numerical array to stdout with a name prefixed to each line.
cpl_image * muse_cplimage_filter_median_subtract(cpl_image *aImage, unsigned int aNX, unsigned int aNY)
Subtract a median-filtered version of the input image from itself.
cpl_array * muse_cplarray_extract(cpl_array *aArray, cpl_size aStart, cpl_size aCount)
Create an array from a section of another array.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
cpl_array * muse_cplarray_string_to_double(const cpl_array *aArray)
Convert a string array into an array of type double.
cpl_error_code muse_cplarray_sort(cpl_array *aArray, cpl_boolean aOrder)
Sort float, int or double array by quicksort.
const char * unit
Column unit, or NULL.
cpl_error_code muse_cplarray_poly1d(cpl_array *aArray, const cpl_array *aCoeff)
Apply a polynomial to an array.
double muse_cplvector_get_median_dev(cpl_vector *aVector, double *aMedian)
Compute the median and average absolute deviation against the median of a vector. ...
cpl_vector * muse_cplvector_get_unique(const cpl_vector *aVector)
Separate out all unique entries in a given vector into a new one.
double muse_cplvector_get_semiquartile(cpl_vector *aVector)
compute the semi-quartile range of a vector of elements
cpl_boolean muse_cplarray_has_duplicate(const cpl_array *aArray)
Check, if an array contains duplicate values.
cpl_image * muse_cplimage_concat_y(const cpl_image *aImage1, const cpl_image *aImage2)
Concatenate two images in y direction.
cpl_error_code muse_cpltable_check(const cpl_table *aTable, const muse_cpltable_def *aDef)
Check whether the table contains the fields of the definition.
cpl_table * muse_cpltable_load(const char *aFile, const char *aExtension, const muse_cpltable_def aDefinition[])
Load a table from disk (and check against definition).
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
cpl_error_code muse_cplarray_exp(cpl_array *aArray)
Compute the exponential function of array elements.
cpl_error_code muse_cplimage_or(cpl_image *aTarget, const cpl_image *aImage, unsigned int mask)
Provide an 'OR' operation of two integer images.
cpl_array * muse_cplarray_new_from_delimited_string(const char *aString, const char *aDelim)
Convert a delimited string into an array of strings.
cpl_array * muse_cpltable_get_array_copy(cpl_table *aTable, const char *aColumn, cpl_size aRow)
Return the copy of an array of a table cell.
cpl_array * muse_cpltable_extract_column(cpl_table *aTable, const char *aColumn)
Create an array from a section of a column.
cpl_error_code muse_cplvector_erase_element(cpl_vector *aVector, int aElement)
delete the given element from the input vector
const char * name
Column name.
const char * format
Default print format, or NULL.
cpl_array * muse_cplarray_new_from_image(const cpl_image *aImage)
Copy the image data into an array.
cpl_bivector * muse_cplarray_histogram(const cpl_array *aArray, double aWidth, double aMin, double aMax)
Create a histogram for a numerical array.
cpl_array * muse_cplarray_interpolate_linear(const cpl_array *aTargetAbscissa, const cpl_array *aSourceAbscissa, const cpl_array *aSourceOrdinate)
Linear interpolation of a 1d array.
double muse_cplimage_get_percentile(const cpl_image *aImage, double aFraction)
Get the percentile of an image.
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
cpl_vector * muse_cplimage_slope_window(const cpl_image *aImage, const cpl_size *aWindow)
Compute slopes of an image, both horizontally and vertically.
cpl_error_code muse_cplarray_erf(cpl_array *aArray)
Compute the error function of array elements.
cpl_error_code muse_cplarray_add_window(cpl_array *aDest, cpl_size aStart, const cpl_array *aArray)
Add the value of an array to a window of a table column.
cpl_error_code muse_cplpropertylist_update_long_long(cpl_propertylist *aHeader, const char *aKeyword, cpl_size aValue)
Update an integer-like property irrespective of the real type.
cpl_size muse_cpltable_find_sorted(const cpl_table *aTable, const char *aColumn, double aValue)
Find a row in a table.
cpl_image * muse_cplimage_concat_x(const cpl_image *aImage1, const cpl_image *aImage2)
Concatenate two images in x direction.
cpl_error_code muse_cpltable_copy_array(cpl_table *aTable, const char *aColumn, const cpl_array *aArray)
Copy an array into a table.
cpl_array * muse_cplarray_diff(const cpl_array *aArray, int aOffset)
Build the difference of any element and one of the next elements.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
cpl_size muse_cplarray_erase_outliers(cpl_array *aArray, const cpl_bivector *aHistogram, cpl_size aGap, double aLimit)
Erase outliers from an array using histogram information.
muse_cplframework_type
Type for the framework that called the recipe.
cpl_size muse_cplvector_count_unique(const cpl_vector *aVector)
Count the number of unique entries in a given vector.
Definition of a cpl table structure.
double muse_cplvector_get_adev_const(const cpl_vector *aVector, double aCenter)
Compute the average absolute deviation of a (constant) vector.
cpl_parameter * muse_cplparamerterlist_find_prefix(cpl_parameterlist *aParameters, const char *aPrefix, const char *aName)
Return the full recipe parameter belonging to prefix and shortname.
double muse_cplarray_poly1d_double(double aDouble, const cpl_array *aCoeff)
Apply a polynomial to a double value.
cpl_size muse_cplarray_find_sorted(const cpl_array *aArray, double aValue)
Find a row in an array.
cpl_error_code muse_cplvector_threshold(cpl_vector *aVec, double aLoCut, double aHiCut, double aLoVal, double aHiVal)
Threshold a vector to a given interval.
cpl_image * muse_cplimagelist_collapse_or_create(const cpl_imagelist *imlist)
Compute the OR of an image list to a single image.
cpl_error_code muse_cpltable_append_file(const cpl_table *aTable, const char *aFile, const char *aExtension, const muse_cpltable_def aDefinition[])
Save a table to disk (into a FITS extension)