27 #include "irplib_utils.h"
53 inline static double irplib_data_get_double(
const void *, cpl_type,
int)
54 #ifdef CPL_HAVE_GNUC_NONNULL
55 __attribute__((nonnull))
59 inline static void irplib_data_set_double(
void *, cpl_type,
int,
double)
60 #ifdef CPL_HAVE_GNUC_NONNULL
61 __attribute__((nonnull))
67 void irplib_errorstate_dump_one_level(
void (*)(
const char *,
70 __attribute__((format (printf, 2, 3)))
72 ,
unsigned,
unsigned,
unsigned);
73 static double frame_get_exptime(
const cpl_frame * pframe);
74 static void quicksort(
int* index,
double* exptime,
int left,
int right);
78 const cpl_parameterlist *,
81 const cpl_imagelist *,
85 const cpl_propertylist *,
87 const cpl_propertylist *,
117 irplib_errorstate_dump_one_level(&cpl_msg_warning,
self, first, last);
121 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
122 const cpl_vector * x_pos,
123 const cpl_vector * values,
144 irplib_errorstate_dump_one_level(&cpl_msg_info,
self, first, last);
164 irplib_errorstate_dump_one_level(&cpl_msg_debug,
self, first, last);
192 const cpl_parameterlist * parlist,
193 const cpl_frameset * usedframes,
194 const cpl_image * image,
198 const cpl_propertylist * applist,
199 const char * remregexp,
200 const char * pipe_id,
201 const char * filename)
203 cpl_errorstate prestate = cpl_errorstate_get();
204 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
205 : cpl_propertylist_new();
207 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
210 bpp, recipe, prolist, remregexp, pipe_id, filename);
212 cpl_propertylist_delete(prolist);
214 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
216 return CPL_ERROR_NONE;
240 const cpl_parameterlist * parlist,
241 const cpl_frameset * usedframes,
244 const cpl_propertylist * applist,
245 const char * remregexp,
246 const char * pipe_id,
247 const char * filename)
249 cpl_errorstate prestate = cpl_errorstate_get();
250 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
251 : cpl_propertylist_new();
253 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
255 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
256 recipe, prolist, remregexp, pipe_id, filename);
258 cpl_propertylist_delete(prolist);
260 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
262 return CPL_ERROR_NONE;
287 const cpl_parameterlist * parlist,
288 const cpl_frameset * usedframes,
289 const cpl_imagelist * imagelist,
293 const cpl_propertylist * applist,
294 const char * remregexp,
295 const char * pipe_id,
296 const char * filename)
298 cpl_errorstate prestate = cpl_errorstate_get();
299 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
300 : cpl_propertylist_new();
302 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
304 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
305 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
308 cpl_propertylist_delete(prolist);
310 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
312 return CPL_ERROR_NONE;
335 const cpl_parameterlist * parlist,
336 const cpl_frameset * usedframes,
337 const cpl_table * table,
338 const cpl_propertylist * tablelist,
341 const cpl_propertylist * applist,
342 const char * remregexp,
343 const char * pipe_id,
344 const char * filename)
347 cpl_errorstate prestate = cpl_errorstate_get();
348 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
349 : cpl_propertylist_new();
351 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
353 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
354 table, tablelist, recipe, prolist, remregexp,
357 cpl_propertylist_delete(prolist);
359 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
361 return CPL_ERROR_NONE;
395 cpl_propertylist * header,
396 const cpl_parameterlist * parlist,
397 const cpl_frameset * usedframes,
398 const cpl_frame * inherit,
399 const cpl_image * image,
402 const cpl_propertylist * applist,
403 const char * remregexp,
404 const char * pipe_id,
405 const char * filename)
409 NULL, image, type, NULL, NULL, recipe,
410 applist, remregexp, pipe_id, filename)
411 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
444 cpl_propertylist * header,
445 const cpl_parameterlist * parlist,
446 const cpl_frameset * usedframes,
447 const cpl_frame * inherit,
448 const cpl_imagelist * imagelist,
449 const cpl_image * image,
451 const cpl_table * table,
452 const cpl_propertylist * tablelist,
454 const cpl_propertylist * applist,
455 const char * remregexp,
456 const char * pipe_id,
457 const char * filename) {
460 cpl_propertylist * plist;
461 cpl_frame * product_frame;
468 const unsigned pronum
469 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
470 const char * proname[] = {
"imagelist",
"table",
"image",
473 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
474 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
475 cpl_error_code error = CPL_ERROR_NONE;
480 if (imagelist != NULL) {
482 assert(image == NULL);
483 assert(table == NULL);
484 assert(tablelist == NULL);
485 }
else if (table != NULL) {
487 assert(imagelist == NULL);
488 assert(image == NULL);
489 }
else if (image != NULL) {
491 assert(imagelist == NULL);
492 assert(table == NULL);
493 assert(tablelist == NULL);
496 assert(imagelist == NULL);
497 assert(table == NULL);
498 assert(tablelist == NULL);
499 assert(image == NULL);
502 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
503 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
504 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
505 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
506 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
507 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
508 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
510 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
512 cpl_ensure_code(procat != NULL, cpl_error_get_code());
514 cpl_msg_info(cpl_func,
"Writing FITS %s product(%s): %s", proname[pronum],
517 product_frame = cpl_frame_new();
520 error |= cpl_frame_set_filename(product_frame, filename);
521 error |= cpl_frame_set_tag(product_frame, procat);
522 error |= cpl_frame_set_type(product_frame, protype[pronum]);
523 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
524 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
527 cpl_frame_delete(product_frame);
528 return cpl_error_set_where(cpl_func);
531 if (header != NULL) {
532 cpl_propertylist_empty(header);
535 plist = cpl_propertylist_new();
539 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
545 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
546 parlist, recipe, pipe_id,
547 "PRO-1.15", inherit);
549 if (remregexp != NULL && !error) {
550 cpl_errorstate prestate = cpl_errorstate_get();
551 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
552 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
558 error = cpl_imagelist_save(imagelist, filename, type, plist,
562 error = cpl_table_save(table, plist, tablelist, filename,
566 error = cpl_image_save(image, filename, type, plist,
571 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
577 error = cpl_frameset_insert(allframes, product_frame);
580 cpl_frame_delete(product_frame);
583 if (plist != header) cpl_propertylist_delete(plist);
585 cpl_ensure_code(!error, error);
587 return CPL_ERROR_NONE;
653 cpl_boolean isleq_low,
655 cpl_boolean isgeq_high,
658 cpl_boolean isbad_low,
659 cpl_boolean isbad_mid,
660 cpl_boolean isbad_high)
663 const void * selfdata = cpl_image_get_data_const(
self);
667 const cpl_boolean hasbpm
668 = cpl_image_count_rejected(
self) ? CPL_TRUE : CPL_FALSE;
669 const cpl_binary * selfbpm = hasbpm
670 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(
self)) : NULL;
671 const cpl_type selftype = cpl_image_get_type(
self);
672 const int nx = cpl_image_get_size_x(
self);
673 const int ny = cpl_image_get_size_y(
self);
674 const int npix = nx * ny;
675 const cpl_boolean do_low = im_low != NULL;
676 const cpl_boolean do_mid = im_mid != NULL;
677 const cpl_boolean do_high = im_high != NULL;
678 void * lowdata = NULL;
679 void * middata = NULL;
680 void * highdata = NULL;
681 cpl_binary * lowbpm = NULL;
682 cpl_binary * midbpm = NULL;
683 cpl_binary * highbpm = NULL;
684 const cpl_type lowtype
685 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
686 const cpl_type midtype
687 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
688 const cpl_type hightype
689 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
693 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
694 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
695 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
698 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
699 CPL_ERROR_INCOMPATIBLE_INPUT);
700 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
701 CPL_ERROR_INCOMPATIBLE_INPUT);
702 lowdata = cpl_image_get_data(im_low);
706 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
707 CPL_ERROR_INCOMPATIBLE_INPUT);
708 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
709 CPL_ERROR_INCOMPATIBLE_INPUT);
710 middata = cpl_image_get_data(im_mid);
714 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
715 CPL_ERROR_INCOMPATIBLE_INPUT);
716 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
717 CPL_ERROR_INCOMPATIBLE_INPUT);
718 highdata = cpl_image_get_data(im_high);
723 for (i = 0; i < npix; i++) {
724 const double value = irplib_data_get_double(selfdata, selftype, i);
725 cpl_boolean isalt_low = do_low;
726 cpl_boolean isalt_mid = do_mid;
727 cpl_boolean isalt_high = do_high;
728 cpl_boolean setbad_low = do_low;
729 cpl_boolean setbad_mid = do_mid;
730 cpl_boolean setbad_high = do_high;
731 const void * setdata = NULL;
732 double alt_mid = 0.0;
734 if (isleq_low ? value <= th_low : value < th_low) {
736 isalt_low = CPL_FALSE;
737 irplib_data_set_double(lowdata, lowtype, i, value);
738 setbad_low = hasbpm && selfbpm[i];
742 }
else if (isgeq_high ? value >= th_high : value > th_high) {
744 isalt_high = CPL_FALSE;
745 irplib_data_set_double(highdata, hightype, i, value);
746 setbad_high = hasbpm && selfbpm[i];
751 isalt_mid = CPL_FALSE;
752 irplib_data_set_double(middata, midtype, i, value);
753 setbad_mid = hasbpm && selfbpm[i];
757 if (isalt_low && lowdata != setdata) {
758 irplib_data_set_double(lowdata, lowtype, i, alt_low);
759 setbad_low = isbad_low;
761 if (isalt_mid && middata != setdata) {
762 irplib_data_set_double(middata, midtype, i, alt_mid);
763 setbad_mid = isbad_mid;
765 if (isalt_high && highdata != setdata) {
766 irplib_data_set_double(highdata, hightype, i, alt_high);
767 setbad_high = isbad_high;
771 if (lowbpm == NULL) lowbpm
772 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
773 lowbpm[i] = CPL_BINARY_1;
776 if (midbpm == NULL) midbpm
777 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
778 midbpm[i] = CPL_BINARY_1;
781 if (highbpm == NULL) highbpm
782 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
783 highbpm[i] = CPL_BINARY_1;
787 return CPL_ERROR_NONE;
844 cpl_frameset * allframes,
845 const cpl_frameset * useframes,
848 const char * product_name,
849 const char * procatg,
850 const cpl_parameterlist * parlist,
851 const char * recipe_name,
852 const cpl_propertylist * mainlist,
853 const cpl_propertylist * extlist,
854 const char * remregexp,
855 const char * instrume,
856 const char * pipe_id,
857 cpl_boolean (*table_set_row)
858 (cpl_table *,
const char *,
int,
860 const cpl_parameterlist *),
861 cpl_error_code (*table_check)
863 const cpl_frameset *,
864 const cpl_parameterlist *))
867 const char * filename;
868 cpl_propertylist * applist = NULL;
869 cpl_errorstate prestate = cpl_errorstate_get();
870 cpl_error_code error;
871 char * fallback_filename = NULL;
873 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
874 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
875 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
876 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
877 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
878 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
879 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
880 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
887 cpl_error_get_code());
889 if (table_check != NULL && (table_check(
self, useframes, parlist) ||
890 !cpl_errorstate_is_equal(prestate))) {
891 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
892 "Consistency check of table failed");
895 fallback_filename = cpl_sprintf(
"%s" CPL_DFS_FITS, recipe_name);
896 filename = product_name != NULL ? product_name : fallback_filename;
898 applist = mainlist == NULL
899 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
901 error = cpl_propertylist_update_string(applist,
"INSTRUME", instrume);
905 extlist, recipe_name, procatg, applist,
906 remregexp, pipe_id, filename);
908 cpl_propertylist_delete(applist);
909 cpl_free(fallback_filename);
912 cpl_ensure_code(!error, error);
914 return CPL_ERROR_NONE;
973 const cpl_frameset * useframes,
976 const cpl_parameterlist * parlist,
977 cpl_boolean (*table_set_row)
978 (cpl_table *,
const char *,
int,
980 const cpl_parameterlist *))
983 const cpl_frame * rawframe;
984 char * linebuffer = NULL;
985 FILE * stream = NULL;
987 int nrow = cpl_table_get_nrow(
self);
989 cpl_errorstate prestate = cpl_errorstate_get();
990 cpl_frameset_iterator * iterator = NULL;
992 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
993 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
994 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
995 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
996 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
998 linebuffer = cpl_malloc(maxlinelen);
1000 for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
1002 rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
1004 const char * rawfile = cpl_frame_get_filename(rawframe);
1006 const int irowpre = irow;
1010 if (rawfile == NULL)
break;
1012 stream = fopen(rawfile,
"r");
1014 if (stream == NULL) {
1015 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1016 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1017 "open %s for reading", rawfile);
1019 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1020 "open file for reading");
1025 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
1027 if (linebuffer[0] != commentchar) {
1029 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1030 const int prerow = irow;
1034 nrow += nrow ? nrow : 1;
1035 if (cpl_table_set_size(
self, nrow))
break;
1038 didset = table_set_row(
self, linebuffer, irow, rawframe,
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",
1051 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1052 "Failure with line %d from %d. "
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");
1068 if (done != NULL)
break;
1070 ierror = fclose(stream);
1075 if (irow == irowpre)
1076 cpl_msg_warning(cpl_func,
"No usable lines in the %d. file: %s",
1080 cpl_frameset_iterator_delete(iterator);
1081 cpl_free(linebuffer);
1082 if (stream != NULL) fclose(stream);
1085 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1088 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1089 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1090 "No usable lines in the %d input "
1091 "frame(s)", nfiles);
1093 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1094 "No usable lines in the input frame(s)");
1099 cpl_ensure_code(!cpl_table_set_size(
self, irow), cpl_error_get_code());
1101 return CPL_ERROR_NONE;
1140 if (frame1==NULL || frame2==NULL)
return -1 ;
1143 if ((v1 = cpl_frame_get_tag(frame1)) == NULL)
return -1 ;
1144 if ((v2 = cpl_frame_get_tag(frame2)) == NULL)
return -1 ;
1147 if (strcmp(v1, v2))
return 0 ;
1171 const cpl_frame *
frame = cpl_frameset_find_const(
self, tag);
1174 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1176 if (frame == NULL)
return NULL;
1178 if (cpl_frameset_find_const(
self, NULL))
1179 cpl_msg_warning(cpl_func,
1180 "Frameset has more than one file with tag: %s",
1183 return cpl_frame_get_filename(frame);
1200 cpl_frame_group group)
1202 const cpl_frame *
frame;
1203 cpl_frameset_iterator * iterator = NULL;
1205 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1207 for (frame = irplib_frameset_get_first_const(&iterator,
self);
1209 frame = irplib_frameset_get_next_const(iterator)) {
1210 if (cpl_frame_get_group(frame) == group)
break;
1212 cpl_frameset_iterator_delete(iterator);
1237 int * ind,
int nfind)
1239 const int nsize = cpl_apertures_get_size(
self);
1243 cpl_ensure_code(nsize > 0, cpl_error_get_code());
1244 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1245 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1246 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1248 for (ifind=0; ifind < nfind; ifind++) {
1249 double maxflux = -1;
1252 for (i=1; i <= nsize; i++) {
1256 for (k=0; k < ifind; k++)
if (ind[k] == i)
break;
1260 const double flux = cpl_apertures_get_flux(
self, i);
1262 if (maxind < 0 || flux > maxflux) {
1268 ind[ifind] = maxind;
1271 return CPL_ERROR_NONE;
1292 double irplib_data_get_double(
const void *
self, cpl_type type,
int i)
1299 case CPL_TYPE_FLOAT:
1301 const float * pself = (
const float*)
self;
1302 value = (double)pself[i];
1307 const int * pself = (
const int*)
self;
1308 value = (double)pself[i];
1313 const double * pself = (
const double*)
self;
1337 void irplib_data_set_double(
void *
self, cpl_type type,
int i,
double value)
1341 case CPL_TYPE_FLOAT:
1343 float * pself = (
float*)
self;
1344 pself[i] = (float)value;
1349 int * pself = (
int*)
self;
1350 pself[i] = (int)value;
1355 double * pself = (
double*)
self;
1379 void irplib_errorstate_dump_one_level(
void (*messenger)(
const char *,
1381 unsigned self,
unsigned first,
1385 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
1386 const unsigned newest = is_reverse ? first : last;
1387 const unsigned oldest = is_reverse ? last : first;
1388 const char * revmsg = is_reverse ?
" in reverse order" :
"";
1398 messenger(cpl_func,
"No error(s) to dump");
1405 if (
self == first) {
1407 messenger(cpl_func,
"Dumping all %u error(s)%s:", newest,
1410 messenger(cpl_func,
"Dumping the %u most recent error(s) "
1411 "out of a total of %u errors%s:",
1412 newest - oldest + 1, newest, revmsg);
1414 cpl_msg_indent_more();
1417 messenger(cpl_func,
"[%u/%u] '%s' (%u) at %s",
self, newest,
1418 cpl_error_get_message(), cpl_error_get_code(),
1419 cpl_error_get_where());
1421 if (
self == last) cpl_msg_indent_less();
1425 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
1426 const cpl_vector * x_pos,
1427 const cpl_vector * values,
1432 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
1434 cpl_polynomial * irplib_polynomial_fit_1d_create(
1435 const cpl_vector * x_pos,
1436 const cpl_vector * values,
1442 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
1444 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
1445 const cpl_vector * x_pos,
1446 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)
1459 cpl_matrix * samppos = NULL;
1460 cpl_vector * fitresidual = NULL;
1461 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1462 samppos = cpl_matrix_wrap(1, x_size,
1463 (
double*)cpl_vector_get_data_const(x_pos));
1464 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1465 fitresidual = cpl_vector_new(x_size);
1466 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1467 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
1468 CPL_FALSE, NULL, &loc_degree);
1469 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1470 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1471 fit1d, samppos, rechisq);
1472 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1475 *mse = cpl_vector_product(fitresidual, fitresidual)
1476 / cpl_vector_get_size(fitresidual);
1478 cpl_matrix_unwrap(samppos);
1479 cpl_vector_delete(fitresidual);
1484 static void quicksort(
int* iindex,
double* exptime,
int left,
int right)
1488 int pivot = (i + j) / 2;
1489 double index_value = exptime[pivot];
1492 while(exptime[i] < index_value) i++;
1493 while(exptime[j] > index_value) j--;
1498 int tmp = iindex[i];
1499 double dtmp = exptime[i];
1500 iindex[i]=iindex[j];
1502 exptime[i] = exptime[j];
1512 quicksort(iindex, exptime, i, right);
1516 quicksort(iindex, exptime,left, j);
1519 cpl_error_code irplib_frameset_sort(
const cpl_frameset *
self,
int* iindex,
double* exptime)
1522 const cpl_frame* tmp_frame = 0;
1523 cpl_error_code error = CPL_ERROR_NONE;
1524 int sz = cpl_frameset_get_size(
self);
1525 cpl_frameset_iterator* iterator = NULL;
1528 tmp_frame = irplib_frameset_get_first_const(&iterator,
self);
1531 exptime[i] = frame_get_exptime(tmp_frame);
1533 tmp_frame = irplib_frameset_get_next_const(iterator);
1536 cpl_frameset_iterator_delete(iterator);
1538 quicksort(iindex, exptime, 0, sz - 1);
1543 static double frame_get_exptime(
const cpl_frame * pframe)
1546 cpl_propertylist * plist =
1547 cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1548 "EXPTIME", CPL_FALSE);
1550 dval = cpl_propertylist_get_double(plist,
"EXPTIME");
1551 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1552 cpl_msg_error(cpl_func,
"error during reading EXPTIME key from "
1553 "the frame [%s]", cpl_frame_get_filename(pframe));
1557 cpl_propertylist_delete(plist);
1577 void * irplib_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 __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
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;
1649 void * irplib_aligned_calloc(
size_t alignment,
size_t nelem,
size_t nbytes)
1651 void * buffer = irplib_aligned_malloc(alignment, nelem * nbytes);
1655 memset((
size_t *)buffer, 0, nelem * nbytes);
1669 void irplib_aligned_free (
void * aligned_ptr)
1671 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
1673 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1677 free (*(((
void **) aligned_ptr) - 1));
1697 irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
1698 const cpl_frameset *frameset)
1700 cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
1701 *iterator = cpl_frameset_iterator_new(frameset);
1702 return cpl_frameset_iterator_get_const(*iterator);
1716 irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
1718 cpl_errorstate prestate = cpl_errorstate_get();
1719 cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
1720 if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1721 cpl_errorstate_set(prestate);
1723 }
else if (error != CPL_ERROR_NONE) {
1726 return cpl_frameset_iterator_get_const(iterator);
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.
static cpl_error_code irplib_dfs_product_save(cpl_frameset *, cpl_propertylist *, const cpl_parameterlist *, const cpl_frameset *, const cpl_frame *, const cpl_imagelist *, const cpl_image *, cpl_type, const cpl_table *, const cpl_propertylist *, const char *, const cpl_propertylist *, const char *, const char *, const char *)
Save either an image or table as a pipeline product.
void irplib_errorstate_dump_info(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL info level.
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.
void irplib_reset(void)
Reset IRPLIB state.
cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *self, int *ind, int nfind)
Find the aperture(s) with the greatest flux.
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_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.
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.
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)
void irplib_errorstate_dump_warning(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL warning level.
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.
int irplib_compare_tags(cpl_frame *frame1, cpl_frame *frame2)
Comparison function to identify different input frames.
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_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.
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.