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))
65void irplib_errorstate_dump_one_level(
void (*)(
const char *,
68 __attribute__((format (printf, 2, 3)))
70 ,
unsigned,
unsigned,
unsigned);
71static double frame_get_exptime(
const cpl_frame * pframe);
72static void quicksort(
int* index,
double* exptime,
int left,
int right);
74static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
76 const cpl_parameterlist *,
79 const cpl_imagelist *,
83 const cpl_propertylist *,
85 const cpl_propertylist *,
115 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
119static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
120 const cpl_vector * x_pos,
121 const cpl_vector * values,
142 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
162 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
190 const cpl_parameterlist * parlist,
191 const cpl_frameset * usedframes,
192 const cpl_image * image,
196 const cpl_propertylist * applist,
197 const char * remregexp,
198 const char * pipe_id,
199 const char * filename)
201 cpl_errorstate prestate = cpl_errorstate_get();
202 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
203 : cpl_propertylist_new();
205 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
208 bpp, recipe, prolist, remregexp, pipe_id, filename);
210 cpl_propertylist_delete(prolist);
212 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
214 return CPL_ERROR_NONE;
238 const cpl_parameterlist * parlist,
239 const cpl_frameset * usedframes,
242 const cpl_propertylist * applist,
243 const char * remregexp,
244 const char * pipe_id,
245 const char * filename)
247 cpl_errorstate prestate = cpl_errorstate_get();
248 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
249 : cpl_propertylist_new();
251 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
253 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
254 recipe, prolist, remregexp, pipe_id, filename);
256 cpl_propertylist_delete(prolist);
258 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
260 return CPL_ERROR_NONE;
285 const cpl_parameterlist * parlist,
286 const cpl_frameset * usedframes,
287 const cpl_imagelist * imagelist,
291 const cpl_propertylist * applist,
292 const char * remregexp,
293 const char * pipe_id,
294 const char * filename)
296 cpl_errorstate prestate = cpl_errorstate_get();
297 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
298 : cpl_propertylist_new();
300 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
302 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
303 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
306 cpl_propertylist_delete(prolist);
308 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
310 return CPL_ERROR_NONE;
333 const cpl_parameterlist * parlist,
334 const cpl_frameset * usedframes,
335 const cpl_table * table,
336 const cpl_propertylist * tablelist,
339 const cpl_propertylist * applist,
340 const char * remregexp,
341 const char * pipe_id,
342 const char * filename)
345 cpl_errorstate prestate = cpl_errorstate_get();
346 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
347 : cpl_propertylist_new();
349 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
351 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
352 table, tablelist, recipe, prolist, remregexp,
355 cpl_propertylist_delete(prolist);
357 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
359 return CPL_ERROR_NONE;
393 cpl_propertylist * header,
394 const cpl_parameterlist * parlist,
395 const cpl_frameset * usedframes,
396 const cpl_frame * inherit,
397 const cpl_image * image,
400 const cpl_propertylist * applist,
401 const char * remregexp,
402 const char * pipe_id,
403 const char * filename)
406 irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
407 NULL, image, type, NULL, NULL, recipe,
408 applist, remregexp, pipe_id, filename)
409 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
441cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
442 cpl_propertylist * header,
443 const cpl_parameterlist * parlist,
444 const cpl_frameset * usedframes,
445 const cpl_frame * inherit,
446 const cpl_imagelist * imagelist,
447 const cpl_image * image,
449 const cpl_table * table,
450 const cpl_propertylist * tablelist,
452 const cpl_propertylist * applist,
453 const char * remregexp,
454 const char * pipe_id,
455 const char * filename) {
458 cpl_propertylist * plist;
459 cpl_frame * product_frame;
466 const unsigned pronum
467 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
468 const char * proname[] = {
"imagelist",
"table",
"image",
471 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
472 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
473 cpl_error_code error = CPL_ERROR_NONE;
478 if (imagelist != NULL) {
480 assert(image == NULL);
481 assert(table == NULL);
482 assert(tablelist == NULL);
483 }
else if (table != NULL) {
485 assert(imagelist == NULL);
486 assert(image == NULL);
487 }
else if (image != NULL) {
489 assert(imagelist == NULL);
490 assert(table == NULL);
491 assert(tablelist == NULL);
494 assert(imagelist == NULL);
495 assert(table == NULL);
496 assert(tablelist == NULL);
497 assert(image == NULL);
500 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
501 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
502 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
503 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
504 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
505 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
506 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
508 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
510 cpl_ensure_code(procat != NULL, cpl_error_get_code());
512 cpl_msg_info(cpl_func,
"Writing FITS %s product(%s): %s", proname[pronum],
515 product_frame = cpl_frame_new();
518 error |= cpl_frame_set_filename(product_frame, filename);
519 error |= cpl_frame_set_tag(product_frame, procat);
520 error |= cpl_frame_set_type(product_frame, protype[pronum]);
521 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
522 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
525 cpl_frame_delete(product_frame);
526 return cpl_error_set_where(cpl_func);
529 if (header != NULL) {
530 cpl_propertylist_empty(header);
533 plist = cpl_propertylist_new();
537 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
543 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
544 parlist, recipe, pipe_id,
545 "PRO-1.16", inherit);
547 if (remregexp != NULL && !error) {
548 cpl_errorstate prestate = cpl_errorstate_get();
549 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
550 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
556 error = cpl_imagelist_save(imagelist, filename, type, plist,
560 error = cpl_table_save(table, plist, tablelist, filename,
564 error = cpl_image_save(image, filename, type, plist,
569 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
575 error = cpl_frameset_insert(allframes, product_frame);
578 cpl_frame_delete(product_frame);
581 if (plist != header) 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)
661 const void * selfdata = cpl_image_get_data_const(self);
665 const cpl_boolean hasbpm
666 = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
667 const cpl_binary * selfbpm = hasbpm
668 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
669 const cpl_type selftype = cpl_image_get_type(self);
670 const int nx = cpl_image_get_size_x(self);
671 const int ny = cpl_image_get_size_y(self);
672 const int npix = nx * ny;
673 const cpl_boolean do_low = im_low != NULL;
674 const cpl_boolean do_mid = im_mid != NULL;
675 const cpl_boolean do_high = im_high != NULL;
676 void * lowdata = NULL;
677 void * middata = NULL;
678 void * highdata = NULL;
679 cpl_binary * lowbpm = NULL;
680 cpl_binary * midbpm = NULL;
681 cpl_binary * highbpm = NULL;
682 const cpl_type lowtype
683 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
684 const cpl_type midtype
685 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
686 const cpl_type hightype
687 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
691 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
692 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
693 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
696 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
697 CPL_ERROR_INCOMPATIBLE_INPUT);
698 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
699 CPL_ERROR_INCOMPATIBLE_INPUT);
700 lowdata = cpl_image_get_data(im_low);
704 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
705 CPL_ERROR_INCOMPATIBLE_INPUT);
706 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
707 CPL_ERROR_INCOMPATIBLE_INPUT);
708 middata = cpl_image_get_data(im_mid);
712 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
713 CPL_ERROR_INCOMPATIBLE_INPUT);
714 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
715 CPL_ERROR_INCOMPATIBLE_INPUT);
716 highdata = cpl_image_get_data(im_high);
721 for (i = 0; i < npix; i++) {
722 const double value = irplib_data_get_double(selfdata, selftype, i);
723 cpl_boolean isalt_low = do_low;
724 cpl_boolean isalt_mid = do_mid;
725 cpl_boolean isalt_high = do_high;
726 cpl_boolean setbad_low = do_low;
727 cpl_boolean setbad_mid = do_mid;
728 cpl_boolean setbad_high = do_high;
729 const void * setdata = NULL;
730 double alt_mid = 0.0;
732 if (isleq_low ? value <= th_low : value < th_low) {
734 isalt_low = CPL_FALSE;
735 irplib_data_set_double(lowdata, lowtype, i, value);
736 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];
749 isalt_mid = CPL_FALSE;
750 irplib_data_set_double(middata, midtype, i, value);
751 setbad_mid = hasbpm && selfbpm[i];
755 if (isalt_low && lowdata != setdata) {
756 irplib_data_set_double(lowdata, lowtype, i, alt_low);
757 setbad_low = isbad_low;
759 if (isalt_mid && middata != setdata) {
760 irplib_data_set_double(middata, midtype, i, alt_mid);
761 setbad_mid = isbad_mid;
763 if (isalt_high && highdata != setdata) {
764 irplib_data_set_double(highdata, hightype, i, alt_high);
765 setbad_high = isbad_high;
769 if (lowbpm == NULL) lowbpm
770 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
771 lowbpm[i] = CPL_BINARY_1;
774 if (midbpm == NULL) midbpm
775 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
776 midbpm[i] = CPL_BINARY_1;
779 if (highbpm == NULL) highbpm
780 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
781 highbpm[i] = CPL_BINARY_1;
785 return CPL_ERROR_NONE;
842 cpl_frameset * allframes,
843 const cpl_frameset * useframes,
846 const char * product_name,
847 const char * procatg,
848 const cpl_parameterlist * parlist,
849 const char * recipe_name,
850 const cpl_propertylist * mainlist,
851 const cpl_propertylist * extlist,
852 const char * remregexp,
853 const char * instrume,
854 const char * pipe_id,
855 cpl_boolean (*table_set_row)
856 (cpl_table *,
const char *,
int,
858 const cpl_parameterlist *),
859 cpl_error_code (*table_check)
861 const cpl_frameset *,
862 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);
885 cpl_error_get_code());
887 if (table_check != NULL && (table_check(self, useframes, parlist) ||
888 !cpl_errorstate_is_equal(prestate))) {
889 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
890 "Consistency check of table failed");
893 fallback_filename = cpl_sprintf(
"%s" CPL_DFS_FITS, recipe_name);
894 filename = product_name != NULL ? product_name : fallback_filename;
896 applist = mainlist == NULL
897 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
899 error = cpl_propertylist_update_string(applist,
"INSTRUME", instrume);
903 extlist, recipe_name, procatg, applist,
904 remregexp, pipe_id, filename);
906 cpl_propertylist_delete(applist);
907 cpl_free(fallback_filename);
910 cpl_ensure_code(!error, error);
912 return CPL_ERROR_NONE;
971 const cpl_frameset * useframes,
974 const cpl_parameterlist * parlist,
975 cpl_boolean (*table_set_row)
976 (cpl_table *,
const char *,
int,
978 const cpl_parameterlist *))
981 const cpl_frame * rawframe;
982 char * linebuffer = NULL;
983 FILE * stream = NULL;
985 int nrow = cpl_table_get_nrow(self);
987 cpl_errorstate prestate = cpl_errorstate_get();
988 cpl_frameset_iterator * iterator = NULL;
990 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
991 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
992 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
993 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
994 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
996 linebuffer = cpl_malloc(maxlinelen);
998 for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
1000 rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
1002 const char * rawfile = cpl_frame_get_filename(rawframe);
1004 const int irowpre = irow;
1008 if (rawfile == NULL)
break;
1010 stream = fopen(rawfile,
"r");
1012 if (stream == NULL) {
1013#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1014 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1015 "open %s for reading", rawfile);
1017 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1018 "open file for reading");
1023 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
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))
break;
1036 didset = table_set_row(self, linebuffer, irow, rawframe,
1040 if (!cpl_errorstate_is_equal(prestate)) {
1042#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1043 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1044 "Failed to set table row %d "
1045 "using line %d from %d. file %s",
1049 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1050 "Failure with line %d from %d. "
1054 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1055 "Failed to set table row"
1056 "using catalogue line");
1058 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1059 "Failure with catalogue line");
1066 if (done != NULL)
break;
1068 ierror = fclose(stream);
1073 if (irow == irowpre)
1074 cpl_msg_warning(cpl_func,
"No usable lines in the %d. file: %s",
1078 cpl_frameset_iterator_delete(iterator);
1079 cpl_free(linebuffer);
1080 if (stream != NULL) fclose(stream);
1083 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1086#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1087 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1088 "No usable lines in the %d input "
1089 "frame(s)", nfiles);
1091 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1092 "No usable lines in the input frame(s)");
1097 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
1099 return CPL_ERROR_NONE;
1138 if (frame1==NULL || frame2==NULL)
return -1 ;
1141 if ((v1 = cpl_frame_get_tag(frame1)) == NULL)
return -1 ;
1142 if ((v2 = cpl_frame_get_tag(frame2)) == NULL)
return -1 ;
1145 if (strcmp(v1, v2))
return 0 ;
1169 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
1172 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1174 if (frame == NULL)
return NULL;
1176 if (cpl_frameset_find_const(self, NULL))
1177 cpl_msg_warning(cpl_func,
1178 "Frameset has more than one file with tag: %s",
1181 return cpl_frame_get_filename(frame);
1198 cpl_frame_group group)
1200 const cpl_frame * frame;
1201 cpl_frameset_iterator * iterator = NULL;
1203 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1205 for (frame = irplib_frameset_get_first_const(&iterator, self);
1207 frame = irplib_frameset_get_next_const(iterator)) {
1208 if (cpl_frame_get_group(frame) == group)
break;
1210 cpl_frameset_iterator_delete(iterator);
1235 int * ind,
int nfind)
1237 const int nsize = cpl_apertures_get_size(self);
1241 cpl_ensure_code(nsize > 0, cpl_error_get_code());
1242 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1243 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1244 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1246 for (ifind=0; ifind < nfind; ifind++) {
1247 double maxflux = -1;
1250 for (i=1; i <= nsize; i++) {
1254 for (k=0; k < ifind; k++)
if (ind[k] == i)
break;
1258 const double flux = cpl_apertures_get_flux(self, i);
1260 if (maxind < 0 || flux > maxflux) {
1266 ind[ifind] = maxind;
1269 return CPL_ERROR_NONE;
1290double irplib_data_get_double(
const void * self, cpl_type type,
int i)
1297 case CPL_TYPE_FLOAT:
1299 const float * pself = (
const float*)self;
1300 value = (double)pself[i];
1305 const int * pself = (
const int*)self;
1306 value = (double)pself[i];
1311 const double * pself = (
const double*)self;
1335void irplib_data_set_double(
void * self, cpl_type type,
int i,
double value)
1339 case CPL_TYPE_FLOAT:
1341 float * pself = (
float*)self;
1342 pself[i] = (float)value;
1347 int * pself = (
int*)self;
1348 pself[i] = (int)value;
1353 double * pself = (
double*)self;
1377void irplib_errorstate_dump_one_level(
void (*messenger)(
const char *,
1379 unsigned self,
unsigned first,
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");
1403 if (self == first) {
1405 messenger(cpl_func,
"Dumping all %u error(s)%s:", newest,
1408 messenger(cpl_func,
"Dumping the %u most recent error(s) "
1409 "out of a total of %u errors%s:",
1410 newest - oldest + 1, newest, revmsg);
1412 cpl_msg_indent_more();
1415 messenger(cpl_func,
"[%u/%u] '%s' (%u) at %s", self, newest,
1416 cpl_error_get_message(), cpl_error_get_code(),
1417 cpl_error_get_where());
1419 if (self == last) cpl_msg_indent_less();
1423cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
1424 const cpl_vector * x_pos,
1425 const cpl_vector * values,
1430 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
1432cpl_polynomial * irplib_polynomial_fit_1d_create(
1433 const cpl_vector * x_pos,
1434 const cpl_vector * values,
1440 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
1442static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
1443 const cpl_vector * x_pos,
1444 const cpl_vector * values,
1450 cpl_polynomial * fit1d = NULL;
1451 cpl_size loc_degree = (cpl_size)degree ;
1453 fit1d = cpl_polynomial_new(1);
1454 x_size = cpl_vector_get_size(x_pos);
1455 if(fit1d != NULL && x_size > 1)
1457 cpl_matrix * samppos = NULL;
1458 cpl_vector * fitresidual = NULL;
1459 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1460 samppos = cpl_matrix_wrap(1, x_size,
1461 (
double*)cpl_vector_get_data_const(x_pos));
1462 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1463 fitresidual = cpl_vector_new(x_size);
1464 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1465 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
1466 CPL_FALSE, NULL, &loc_degree);
1467 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1468 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1469 fit1d, samppos, rechisq);
1470 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);
1482static void quicksort(
int* iindex,
double* exptime,
int left,
int right)
1486 int pivot = (i + j) / 2;
1487 double index_value = exptime[pivot];
1490 while(exptime[i] < index_value) i++;
1491 while(exptime[j] > index_value) j--;
1496 int tmp = iindex[i];
1497 double dtmp = exptime[i];
1498 iindex[i]=iindex[j];
1500 exptime[i] = exptime[j];
1510 quicksort(iindex, exptime, i, right);
1514 quicksort(iindex, exptime,left, j);
1517cpl_error_code irplib_frameset_sort(
const cpl_frameset * self,
int* iindex,
double* exptime)
1520 const cpl_frame* tmp_frame = 0;
1521 cpl_error_code error = CPL_ERROR_NONE;
1522 int sz = cpl_frameset_get_size(self);
1523 cpl_frameset_iterator* iterator = NULL;
1526 tmp_frame = irplib_frameset_get_first_const(&iterator, self);
1529 exptime[i] = frame_get_exptime(tmp_frame);
1531 tmp_frame = irplib_frameset_get_next_const(iterator);
1534 cpl_frameset_iterator_delete(iterator);
1536 quicksort(iindex, exptime, 0, sz - 1);
1541static double frame_get_exptime(
const cpl_frame * pframe)
1544 cpl_propertylist * plist =
1545 cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1546 "EXPTIME", CPL_FALSE);
1548 dval = cpl_propertylist_get_double(plist,
"EXPTIME");
1549 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1550 cpl_msg_error(cpl_func,
"error during reading EXPTIME key from "
1551 "the frame [%s]", cpl_frame_get_filename(pframe));
1555 cpl_propertylist_delete(plist);
1575void * irplib_aligned_malloc(
size_t alignment,
size_t size)
1580 if (alignment & (alignment - 1)) {
1585 if ((size % alignment) != 0) {
1586 size += alignment - (size % alignment);
1589#if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1590 return aligned_alloc(alignment, size);
1591#elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1595 return malloc (size);
1596 if (alignment == 2 || (
sizeof (
void *) == 8 && alignment == 4))
1597 alignment =
sizeof (
void *);
1598 if (posix_memalign (&ptr, alignment, size) == 0)
1616 if (alignment < 2 *
sizeof (
void *))
1617 alignment = 2 *
sizeof (
void *);
1619 malloc_ptr = malloc (size + alignment);
1624 aligned_ptr = (
void *) (((
size_t) malloc_ptr + alignment)
1625 & ~((size_t) (alignment) - 1));
1628 *(((
void **) aligned_ptr) - 1) = malloc_ptr;
1647void * irplib_aligned_calloc(
size_t alignment,
size_t nelem,
size_t nbytes)
1649 void * buffer = irplib_aligned_malloc(alignment, nelem * nbytes);
1653 memset((
size_t *)buffer, 0, nelem * nbytes);
1667void irplib_aligned_free (
void * aligned_ptr)
1669#if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1671#elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1675 free (*(((
void **) aligned_ptr) - 1));
1695irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
1696 const cpl_frameset *frameset)
1698 cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
1699 *iterator = cpl_frameset_iterator_new(frameset);
1700 return cpl_frameset_iterator_get_const(*iterator);
1714irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
1716 cpl_errorstate prestate = cpl_errorstate_get();
1717 cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
1718 if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1719 cpl_errorstate_set(prestate);
1721 }
else if (error != CPL_ERROR_NONE) {
1724 return cpl_frameset_iterator_get_const(iterator);
1752void irplib_vector_get_kth(cpl_vector * self, cpl_size k)
1756 cpl_size m = cpl_vector_get_size(self) - 1;
1759 double* pself = cpl_vector_get_data(self);
1761 if (pself == NULL) {
1762 (void)cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1765 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1768 (void)cpl_error_set(cpl_func, CPL_ERROR_ACCESS_OUT_OF_RANGE);
1773 const double x = pself[k];
1776 while (pself[i] < x) i++;
1777 while (x < pself[j]) j--;
1779 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.