28#include "irplib_utils.h"
51inline static double irplib_data_get_double(
const void *, cpl_type,
int)
52#ifdef CPL_HAVE_GNUC_NONNULL
53 __attribute__((nonnull))
57inline static void irplib_data_set_double(
void *, cpl_type,
int,
double)
58#ifdef CPL_HAVE_GNUC_NONNULL
59 __attribute__((nonnull))
65irplib_errorstate_dump_one_level(
void (*)(
const char *,
const char *, ...)
67 __attribute__((format(printf, 2, 3)))
73static double frame_get_exptime(
const cpl_frame *pframe);
74static void quicksort(
int *index,
double *exptime,
int left,
int right);
76static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
78 const cpl_parameterlist *,
81 const cpl_imagelist *,
85 const cpl_propertylist *,
87 const cpl_propertylist *,
116 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
119static cpl_polynomial *
120irplib_polynomial_fit_1d_create_common(
const cpl_vector *x_pos,
121 const cpl_vector *values,
140 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
158 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
186 const cpl_parameterlist *parlist,
187 const cpl_frameset *usedframes,
188 const cpl_image *image,
192 const cpl_propertylist *applist,
193 const char *remregexp,
195 const char *filename)
197 cpl_errorstate prestate = cpl_errorstate_get();
198 cpl_propertylist *prolist =
199 applist ? cpl_propertylist_duplicate(applist) : cpl_propertylist_new();
201 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
204 bpp, recipe, prolist, remregexp, pipe_id, filename);
206 cpl_propertylist_delete(prolist);
208 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
210 return CPL_ERROR_NONE;
233 const cpl_parameterlist *parlist,
234 const cpl_frameset *usedframes,
237 const cpl_propertylist *applist,
238 const char *remregexp,
240 const char *filename)
242 cpl_errorstate prestate = cpl_errorstate_get();
243 cpl_propertylist *prolist =
244 applist ? cpl_propertylist_duplicate(applist) : cpl_propertylist_new();
246 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
248 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
249 recipe, prolist, remregexp, pipe_id, filename);
251 cpl_propertylist_delete(prolist);
253 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
255 return CPL_ERROR_NONE;
280 const cpl_parameterlist *parlist,
281 const cpl_frameset *usedframes,
282 const cpl_imagelist *imagelist,
286 const cpl_propertylist *applist,
287 const char *remregexp,
289 const char *filename)
291 cpl_errorstate prestate = cpl_errorstate_get();
292 cpl_propertylist *prolist =
293 applist ? cpl_propertylist_duplicate(applist) : cpl_propertylist_new();
295 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
297 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
298 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
301 cpl_propertylist_delete(prolist);
303 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
305 return CPL_ERROR_NONE;
329 const cpl_parameterlist *parlist,
330 const cpl_frameset *usedframes,
331 const cpl_table *table,
332 const cpl_propertylist *tablelist,
335 const cpl_propertylist *applist,
336 const char *remregexp,
338 const char *filename)
340 cpl_errorstate prestate = cpl_errorstate_get();
341 cpl_propertylist *prolist =
342 applist ? cpl_propertylist_duplicate(applist) : cpl_propertylist_new();
344 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
346 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL, table,
347 tablelist, recipe, prolist, remregexp, pipe_id,
350 cpl_propertylist_delete(prolist);
352 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
354 return CPL_ERROR_NONE;
388 cpl_propertylist *header,
389 const cpl_parameterlist *parlist,
390 const cpl_frameset *usedframes,
391 const cpl_frame *inherit,
392 const cpl_image *image,
395 const cpl_propertylist *applist,
396 const char *remregexp,
398 const char *filename)
400 return irplib_dfs_product_save(allframes, header, parlist, usedframes,
401 inherit, NULL, image, type, NULL, NULL,
402 recipe, applist, remregexp, pipe_id,
404 ? cpl_error_set_where(cpl_func)
436irplib_dfs_product_save(cpl_frameset *allframes,
437 cpl_propertylist *header,
438 const cpl_parameterlist *parlist,
439 const cpl_frameset *usedframes,
440 const cpl_frame *inherit,
441 const cpl_imagelist *imagelist,
442 const cpl_image *image,
444 const cpl_table *table,
445 const cpl_propertylist *tablelist,
447 const cpl_propertylist *applist,
448 const char *remregexp,
450 const char *filename)
453 cpl_propertylist *plist;
454 cpl_frame *product_frame;
461 const unsigned pronum = imagelist != NULL ? 0
463 : (image != NULL ? 2 : 3);
464 const char *proname[] = {
"imagelist",
"table",
"image",
"propertylist"};
466 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
467 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
468 cpl_error_code error = CPL_ERROR_NONE;
473 if (imagelist != NULL) {
475 assert(image == NULL);
476 assert(table == NULL);
477 assert(tablelist == NULL);
479 else if (table != NULL) {
481 assert(imagelist == NULL);
482 assert(image == NULL);
484 else if (image != NULL) {
486 assert(imagelist == NULL);
487 assert(table == NULL);
488 assert(tablelist == NULL);
492 assert(imagelist == NULL);
493 assert(table == NULL);
494 assert(tablelist == NULL);
495 assert(image == NULL);
498 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
499 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
500 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
501 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
502 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
503 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
504 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
506 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
508 cpl_ensure_code(procat != NULL, cpl_error_get_code());
510 cpl_msg_info(cpl_func,
"Writing FITS %s product(%s): %s", proname[pronum],
513 product_frame = cpl_frame_new();
516 error |= cpl_frame_set_filename(product_frame, filename);
517 error |= cpl_frame_set_tag(product_frame, procat);
518 error |= cpl_frame_set_type(product_frame, protype[pronum]);
519 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
520 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
523 cpl_frame_delete(product_frame);
524 return cpl_error_set_where(cpl_func);
527 if (header != NULL) {
528 cpl_propertylist_empty(header);
532 plist = cpl_propertylist_new();
537 error = cpl_propertylist_copy_property_regexp(plist, applist,
".", 0);
541 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
542 parlist, recipe, pipe_id,
543 "PRO-1.16", inherit);
545 if (remregexp != NULL && !error) {
546 cpl_errorstate prestate = cpl_errorstate_get();
547 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
548 if (!cpl_errorstate_is_equal(prestate))
549 error = cpl_error_get_code();
555 error = cpl_imagelist_save(imagelist, filename, type, plist,
559 error = cpl_table_save(table, plist, tablelist, filename,
564 cpl_image_save(image, filename, type, plist, CPL_IO_CREATE);
568 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
574 error = cpl_frameset_insert(allframes, product_frame);
577 cpl_frame_delete(product_frame);
581 cpl_propertylist_delete(plist);
583 cpl_ensure_code(!error, error);
585 return CPL_ERROR_NONE;
651 cpl_boolean isleq_low,
653 cpl_boolean isgeq_high,
656 cpl_boolean isbad_low,
657 cpl_boolean isbad_mid,
658 cpl_boolean isbad_high)
660 const void *selfdata = cpl_image_get_data_const(self);
664 const cpl_boolean hasbpm =
665 cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
666 const cpl_binary *selfbpm =
667 hasbpm ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
668 const cpl_type selftype = cpl_image_get_type(self);
669 const int nx = cpl_image_get_size_x(self);
670 const int ny = cpl_image_get_size_y(self);
671 const int npix = nx * ny;
672 const cpl_boolean do_low = im_low != NULL;
673 const cpl_boolean do_mid = im_mid != NULL;
674 const cpl_boolean do_high = im_high != NULL;
675 void *lowdata = NULL;
676 void *middata = NULL;
677 void *highdata = NULL;
678 cpl_binary *lowbpm = NULL;
679 cpl_binary *midbpm = NULL;
680 cpl_binary *highbpm = NULL;
681 const cpl_type lowtype =
682 do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
683 const cpl_type midtype =
684 do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
685 const cpl_type hightype =
686 do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
690 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
691 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
692 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
695 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
696 CPL_ERROR_INCOMPATIBLE_INPUT);
697 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
698 CPL_ERROR_INCOMPATIBLE_INPUT);
699 lowdata = cpl_image_get_data(im_low);
703 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
704 CPL_ERROR_INCOMPATIBLE_INPUT);
705 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
706 CPL_ERROR_INCOMPATIBLE_INPUT);
707 middata = cpl_image_get_data(im_mid);
711 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
712 CPL_ERROR_INCOMPATIBLE_INPUT);
713 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
714 CPL_ERROR_INCOMPATIBLE_INPUT);
715 highdata = cpl_image_get_data(im_high);
720 for (i = 0; i < npix; i++) {
721 const double value = irplib_data_get_double(selfdata, selftype, i);
722 cpl_boolean isalt_low = do_low;
723 cpl_boolean isalt_mid = do_mid;
724 cpl_boolean isalt_high = do_high;
725 cpl_boolean setbad_low = do_low;
726 cpl_boolean setbad_mid = do_mid;
727 cpl_boolean setbad_high = do_high;
728 const void *setdata = NULL;
729 double alt_mid = 0.0;
731 if (isleq_low ? value <= th_low : value < th_low) {
733 isalt_low = CPL_FALSE;
734 irplib_data_set_double(lowdata, lowtype, i, value);
735 setbad_low = hasbpm && selfbpm[i];
740 else if (isgeq_high ? value >= th_high : value > th_high) {
742 isalt_high = CPL_FALSE;
743 irplib_data_set_double(highdata, hightype, i, value);
744 setbad_high = hasbpm && selfbpm[i];
750 isalt_mid = CPL_FALSE;
751 irplib_data_set_double(middata, midtype, i, value);
752 setbad_mid = hasbpm && selfbpm[i];
756 if (isalt_low && lowdata != setdata) {
757 irplib_data_set_double(lowdata, lowtype, i, alt_low);
758 setbad_low = isbad_low;
760 if (isalt_mid && middata != setdata) {
761 irplib_data_set_double(middata, midtype, i, alt_mid);
762 setbad_mid = isbad_mid;
764 if (isalt_high && highdata != setdata) {
765 irplib_data_set_double(highdata, hightype, i, alt_high);
766 setbad_high = isbad_high;
771 lowbpm = cpl_mask_get_data(cpl_image_get_bpm(im_low));
772 lowbpm[i] = CPL_BINARY_1;
776 midbpm = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
777 midbpm[i] = CPL_BINARY_1;
781 highbpm = cpl_mask_get_data(cpl_image_get_bpm(im_high));
782 highbpm[i] = CPL_BINARY_1;
786 return CPL_ERROR_NONE;
843 cpl_frameset *allframes,
844 const cpl_frameset *useframes,
847 const char *product_name,
849 const cpl_parameterlist *parlist,
850 const char *recipe_name,
851 const cpl_propertylist *mainlist,
852 const cpl_propertylist *extlist,
853 const char *remregexp,
854 const char *instrume,
856 cpl_boolean (*table_set_row)(cpl_table *,
860 const cpl_parameterlist *),
861 cpl_error_code (*table_check)(cpl_table *,
862 const cpl_frameset *,
863 const cpl_parameterlist *))
865 const char *filename;
866 cpl_propertylist *applist = NULL;
867 cpl_errorstate prestate = cpl_errorstate_get();
868 cpl_error_code error;
869 char *fallback_filename = NULL;
871 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
872 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
873 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
874 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
875 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
876 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
877 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
878 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
881 maxlinelen, commentchar,
882 parlist, table_set_row),
883 cpl_error_get_code());
885 if (table_check != NULL && (table_check(self, useframes, parlist) ||
886 !cpl_errorstate_is_equal(prestate))) {
887 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
888 "Consistency check of table failed");
891 fallback_filename = cpl_sprintf(
"%s" CPL_DFS_FITS, recipe_name);
892 filename = product_name != NULL ? product_name : fallback_filename;
894 applist = mainlist == NULL ? cpl_propertylist_new()
895 : cpl_propertylist_duplicate(mainlist);
897 error = cpl_propertylist_update_string(applist,
"INSTRUME", instrume);
901 extlist, recipe_name, procatg, applist,
902 remregexp, pipe_id, filename);
904 cpl_propertylist_delete(applist);
905 cpl_free(fallback_filename);
908 cpl_ensure_code(!error, error);
910 return CPL_ERROR_NONE;
968 const cpl_frameset *useframes,
971 const cpl_parameterlist *parlist,
972 cpl_boolean (*table_set_row)(cpl_table *,
976 const cpl_parameterlist *))
978 const cpl_frame *rawframe;
979 char *linebuffer = NULL;
982 int nrow = cpl_table_get_nrow(self);
984 cpl_errorstate prestate = cpl_errorstate_get();
985 cpl_frameset_iterator *iterator = NULL;
987 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
988 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
989 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
990 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
991 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
993 linebuffer = cpl_malloc(maxlinelen);
995 for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
997 rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
998 const char *rawfile = cpl_frame_get_filename(rawframe);
1000 const int irowpre = irow;
1004 if (rawfile == NULL)
1007 stream = fopen(rawfile,
"r");
1009 if (stream == NULL) {
1010#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1011 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
1013 "open %s for reading",
1016 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
1018 "open file for reading");
1023 for (; (done = fgets(linebuffer, maxlinelen, stream)) != NULL;
1025 if (linebuffer[0] != commentchar) {
1027#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1028 const int prerow = irow;
1032 nrow += nrow ? nrow : 1;
1033 if (cpl_table_set_size(self, nrow))
1038 table_set_row(self, linebuffer, irow, rawframe, parlist);
1042 if (!cpl_errorstate_is_equal(prestate)) {
1044#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1045 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1046 "Failed to set table row %d "
1047 "using line %d from %d. file %s",
1048 1 + prerow, iirow + 1, nfiles + 1,
1051 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1052 "Failure with line %d from %d. "
1054 iirow + 1, nfiles + 1, rawfile);
1056 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1057 "Failed to set table row"
1058 "using catalogue line");
1060 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1061 "Failure with catalogue line");
1071 ierror = fclose(stream);
1077 if (irow == irowpre)
1078 cpl_msg_warning(cpl_func,
"No usable lines in the %d. file: %s",
1079 1 + nfiles, rawfile);
1082 cpl_frameset_iterator_delete(iterator);
1083 cpl_free(linebuffer);
1088 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1091#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1092 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1093 "No usable lines in the %d input "
1097 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1098 "No usable lines in the input frame(s)");
1103 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
1105 return CPL_ERROR_NONE;
1143 if (frame1 == NULL || frame2 == NULL)
1147 if ((v1 = cpl_frame_get_tag(frame1)) == NULL)
1149 if ((v2 = cpl_frame_get_tag(frame2)) == NULL)
1179 const cpl_frame *frame = cpl_frameset_find_const(self, tag);
1182 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1187 if (cpl_frameset_find_const(self, NULL))
1188 cpl_msg_warning(cpl_func,
1189 "Frameset has more than one file with tag: %s", tag);
1191 return cpl_frame_get_filename(frame);
1207 cpl_frame_group group)
1209 const cpl_frame *frame;
1210 cpl_frameset_iterator *iterator = NULL;
1212 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1214 for (frame = irplib_frameset_get_first_const(&iterator, self);
1215 frame != NULL; frame = irplib_frameset_get_next_const(iterator)) {
1216 if (cpl_frame_get_group(frame) == group)
1219 cpl_frameset_iterator_delete(iterator);
1246 const int nsize = cpl_apertures_get_size(self);
1250 cpl_ensure_code(nsize > 0, cpl_error_get_code());
1251 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1252 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1253 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1255 for (ifind = 0; ifind < nfind; ifind++) {
1256 double maxflux = -1;
1259 for (i = 1; i <= nsize; i++) {
1263 for (k = 0; k < ifind; k++)
1269 const double flux = cpl_apertures_get_flux(self, i);
1271 if (maxind < 0 || flux > maxflux) {
1277 ind[ifind] = maxind;
1280 return CPL_ERROR_NONE;
1299irplib_data_get_double(
const void *self, cpl_type type,
int i)
1305 case CPL_TYPE_FLOAT: {
1306 const float *pself = (
const float *)self;
1307 value = (double)pself[i];
1310 case CPL_TYPE_INT: {
1311 const int *pself = (
const int *)self;
1312 value = (double)pself[i];
1317 const double *pself = (
const double *)self;
1340irplib_data_set_double(
void *self, cpl_type type,
int i,
double value)
1343 case CPL_TYPE_FLOAT: {
1344 float *pself = (
float *)self;
1345 pself[i] = (float)value;
1348 case CPL_TYPE_INT: {
1349 int *pself = (
int *)self;
1350 pself[i] = (int)value;
1355 double *pself = (
double *)self;
1376irplib_errorstate_dump_one_level(
void (*messenger)(
const char *,
1383 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
1384 const unsigned newest = is_reverse ? first : last;
1385 const unsigned oldest = is_reverse ? last : first;
1386 const char *revmsg = is_reverse ?
" in reverse order" :
"";
1396 messenger(cpl_func,
"No error(s) to dump");
1404 if (self == first) {
1406 messenger(cpl_func,
"Dumping all %u error(s)%s:", newest,
1411 "Dumping the %u most recent error(s) "
1412 "out of a total of %u errors%s:",
1413 newest - oldest + 1, newest, revmsg);
1415 cpl_msg_indent_more();
1418 messenger(cpl_func,
"[%u/%u] '%s' (%u) at %s", self, newest,
1419 cpl_error_get_message(), cpl_error_get_code(),
1420 cpl_error_get_where());
1423 cpl_msg_indent_less();
1428irplib_polynomial_fit_1d_create_chiq(
const cpl_vector *x_pos,
1429 const cpl_vector *values,
1433 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL,
1437irplib_polynomial_fit_1d_create(
const cpl_vector *x_pos,
1438 const cpl_vector *values,
1442 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse,
1445static cpl_polynomial *
1446irplib_polynomial_fit_1d_create_common(
const cpl_vector *x_pos,
1447 const cpl_vector *values,
1452 cpl_polynomial *fit1d = NULL;
1453 cpl_size loc_degree = (cpl_size)degree;
1455 fit1d = cpl_polynomial_new(1);
1456 x_size = cpl_vector_get_size(x_pos);
1457 if (fit1d != NULL && x_size > 1) {
1458 cpl_matrix *samppos = NULL;
1459 cpl_vector *fitresidual = NULL;
1460 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1461 samppos = cpl_matrix_wrap(1, x_size,
1462 (
double *)cpl_vector_get_data_const(x_pos));
1463 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1464 fitresidual = cpl_vector_new(x_size);
1465 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1466 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL, CPL_FALSE, NULL,
1468 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1469 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1470 fit1d, samppos, rechisq);
1471 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1473 *mse = cpl_vector_product(fitresidual, fitresidual) /
1474 cpl_vector_get_size(fitresidual);
1476 cpl_matrix_unwrap(samppos);
1477 cpl_vector_delete(fitresidual);
1483quicksort(
int *iindex,
double *exptime,
int left,
int right)
1487 int pivot = (i + j) / 2;
1488 double index_value = exptime[pivot];
1490 while (exptime[i] < index_value)
1492 while (exptime[j] > index_value)
1496 int tmp = iindex[i];
1497 double dtmp = exptime[i];
1498 iindex[i] = iindex[j];
1500 exptime[i] = exptime[j];
1509 quicksort(iindex, exptime, i, right);
1512 quicksort(iindex, exptime, left, j);
1516irplib_frameset_sort(
const cpl_frameset *self,
int *iindex,
double *exptime)
1519 const cpl_frame *tmp_frame = 0;
1520 cpl_error_code error = CPL_ERROR_NONE;
1521 int sz = cpl_frameset_get_size(self);
1522 cpl_frameset_iterator *iterator = NULL;
1525 tmp_frame = irplib_frameset_get_first_const(&iterator, self);
1527 exptime[i] = frame_get_exptime(tmp_frame);
1529 tmp_frame = irplib_frameset_get_next_const(iterator);
1532 cpl_frameset_iterator_delete(iterator);
1534 quicksort(iindex, exptime, 0, sz - 1);
1540frame_get_exptime(
const cpl_frame *pframe)
1543 cpl_propertylist *plist =
1544 cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1545 "EXPTIME", CPL_FALSE);
1547 dval = cpl_propertylist_get_double(plist,
"EXPTIME");
1548 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1549 cpl_msg_error(cpl_func,
1550 "error during reading EXPTIME key from "
1552 cpl_frame_get_filename(pframe));
1556 cpl_propertylist_delete(plist);
1577irplib_aligned_malloc(
size_t alignment,
size_t size)
1582 if (alignment & (alignment - 1)) {
1587 if ((size % alignment) != 0) {
1588 size += alignment - (size % alignment);
1591#if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1592 return aligned_alloc(alignment, size);
1593#elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1597 return malloc(size);
1598 if (alignment == 2 || (
sizeof(
void *) == 8 && alignment == 4))
1599 alignment =
sizeof(
void *);
1600 if (posix_memalign(&ptr, alignment, size) == 0)
1618 if (alignment < 2 *
sizeof(
void *))
1619 alignment = 2 *
sizeof(
void *);
1621 malloc_ptr = malloc(size + alignment);
1626 aligned_ptr = (
void *)(((
size_t)malloc_ptr + alignment) &
1627 ~((
size_t)(alignment)-1));
1630 *(((
void **)aligned_ptr) - 1) = malloc_ptr;
1650irplib_aligned_calloc(
size_t alignment,
size_t nelem,
size_t nbytes)
1652 void *buffer = irplib_aligned_malloc(alignment, nelem * nbytes);
1656 memset((
size_t *)buffer, 0, nelem * nbytes);
1671irplib_aligned_free(
void *aligned_ptr)
1673#if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1675#elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1679 free(*(((
void **)aligned_ptr) - 1));
1699irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
1700 const cpl_frameset *frameset)
1702 cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
1703 *iterator = cpl_frameset_iterator_new(frameset);
1704 return cpl_frameset_iterator_get_const(*iterator);
1718irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
1720 cpl_errorstate prestate = cpl_errorstate_get();
1721 cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
1722 if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1723 cpl_errorstate_set(prestate);
1726 else if (error != CPL_ERROR_NONE) {
1729 return cpl_frameset_iterator_get_const(iterator);
1758irplib_vector_get_kth(cpl_vector *self, cpl_size k)
1761 cpl_size m = cpl_vector_get_size(self) - 1;
1764 double *pself = cpl_vector_get_data(self);
1766 if (pself == NULL) {
1767 (void)cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1771 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1775 (void)cpl_error_set(cpl_func, CPL_ERROR_ACCESS_OUT_OF_RANGE);
1780 const double x = pself[k];
1783 while (pself[i] < x)
1785 while (x < pself[j])
1788 IRPLIB_SWAP_DOUBLE(pself[i], pself[j]);
cpl_error_code irplib_dfs_save_image_(cpl_frameset *allframes, cpl_propertylist *header, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_frame *inherit, const cpl_image *image, cpl_type type, const char *recipe, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
void irplib_errorstate_dump_debug(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL debug level.
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
cpl_error_code irplib_dfs_table_convert(cpl_table *self, cpl_frameset *allframes, const cpl_frameset *useframes, int maxlinelen, char commentchar, const char *product_name, const char *procatg, const cpl_parameterlist *parlist, const char *recipe_name, const cpl_propertylist *mainlist, const cpl_propertylist *extlist, const char *remregexp, const char *instrume, const char *pipe_id, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *), cpl_error_code(*table_check)(cpl_table *, const cpl_frameset *, const cpl_parameterlist *))
Create a DFS product with one table from one or more (ASCII) file(s)
cpl_error_code irplib_dfs_save_propertylist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a propertylist as a DFS-compliant pipeline product.
cpl_error_code irplib_table_read_from_frameset(cpl_table *self, const cpl_frameset *useframes, int maxlinelen, char commentchar, const cpl_parameterlist *parlist, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *))
Set the rows of a table with data from one or more (ASCII) files.
cpl_error_code irplib_dfs_save_table(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_table *table, const cpl_propertylist *tablelist, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a table as a DFS-compliant pipeline product.
cpl_error_code irplib_dfs_save_imagelist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_imagelist *imagelist, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an imagelist as a DFS-compliant pipeline product.
void irplib_errorstate_dump_warning(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL warning level.
cpl_error_code irplib_image_split(const cpl_image *self, cpl_image *im_low, cpl_image *im_mid, cpl_image *im_high, double th_low, cpl_boolean isleq_low, double th_high, cpl_boolean isgeq_high, double alt_low, double alt_high, cpl_boolean isbad_low, cpl_boolean isbad_mid, cpl_boolean isbad_high)
Split the values in an image in three according to two thresholds.
void irplib_errorstate_dump_info(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL info level.
const cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset *self, cpl_frame_group group)
Find the first frame belonging to the given group.
const char * irplib_frameset_find_file(const cpl_frameset *self, const char *tag)
Find the filename with the given tag in a frame set.
cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *self, int *ind, int nfind)
Find the aperture(s) with the greatest flux.
int irplib_compare_tags(cpl_frame *frame1, cpl_frame *frame2)
Comparison function to identify different input frames.
void irplib_reset(void)
Reset IRPLIB state.