35 #include "irplib_utils.h"
52 #ifndef CPL_SIZE_FORMAT
53 #define CPL_SIZE_FORMAT "d"
70 inline static double irplib_data_get_double(
const void *, cpl_type,
int)
71 #ifdef CPL_HAVE_GNUC_NONNULL
72 __attribute__((nonnull))
76 inline static void irplib_data_set_double(
void *, cpl_type,
int,
double)
77 #ifdef CPL_HAVE_GNUC_NONNULL
78 __attribute__((nonnull))
84 void irplib_errorstate_dump_one_level(
void (*)(
const char *,
87 __attribute__((format (printf, 2, 3)))
89 ,
unsigned,
unsigned,
unsigned);
90 static double frame_get_exptime(
const cpl_frame * pframe);
91 static void quicksort(
int* index,
double* exptime,
int left,
int right);
93 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
95 const cpl_parameterlist *,
98 const cpl_imagelist *,
102 const cpl_propertylist *,
104 const cpl_propertylist *,
134 irplib_errorstate_dump_one_level(&cpl_msg_warning,
self, first, last);
138 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
139 const cpl_vector * x_pos,
140 const cpl_vector * values,
161 irplib_errorstate_dump_one_level(&cpl_msg_info,
self, first, last);
181 irplib_errorstate_dump_one_level(&cpl_msg_debug,
self, first, last);
209 const cpl_parameterlist * parlist,
210 const cpl_frameset * usedframes,
211 const cpl_image * image,
215 const cpl_propertylist * applist,
216 const char * remregexp,
217 const char * pipe_id,
218 const char * filename)
220 cpl_errorstate prestate = cpl_errorstate_get();
221 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
222 : cpl_propertylist_new();
224 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
227 bpp, recipe, prolist, remregexp, pipe_id, filename);
229 cpl_propertylist_delete(prolist);
231 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
233 return CPL_ERROR_NONE;
257 const cpl_parameterlist * parlist,
258 const cpl_frameset * usedframes,
261 const cpl_propertylist * applist,
262 const char * remregexp,
263 const char * pipe_id,
264 const char * filename)
266 cpl_errorstate prestate = cpl_errorstate_get();
267 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
268 : cpl_propertylist_new();
270 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
272 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
273 recipe, prolist, remregexp, pipe_id, filename);
275 cpl_propertylist_delete(prolist);
277 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
279 return CPL_ERROR_NONE;
304 const cpl_parameterlist * parlist,
305 const cpl_frameset * usedframes,
306 const cpl_imagelist * imagelist,
310 const cpl_propertylist * applist,
311 const char * remregexp,
312 const char * pipe_id,
313 const char * filename)
315 cpl_errorstate prestate = cpl_errorstate_get();
316 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
317 : cpl_propertylist_new();
319 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
321 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
322 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
325 cpl_propertylist_delete(prolist);
327 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
329 return CPL_ERROR_NONE;
352 const cpl_parameterlist * parlist,
353 const cpl_frameset * usedframes,
354 const cpl_table * table,
355 const cpl_propertylist * tablelist,
358 const cpl_propertylist * applist,
359 const char * remregexp,
360 const char * pipe_id,
361 const char * filename)
364 cpl_errorstate prestate = cpl_errorstate_get();
365 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
366 : cpl_propertylist_new();
368 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
370 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
371 table, tablelist, recipe, prolist, remregexp,
374 cpl_propertylist_delete(prolist);
376 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
378 return CPL_ERROR_NONE;
412 cpl_propertylist * header,
413 const cpl_parameterlist * parlist,
414 const cpl_frameset * usedframes,
415 const cpl_frame * inherit,
416 const cpl_image * image,
419 const cpl_propertylist * applist,
420 const char * remregexp,
421 const char * pipe_id,
422 const char * filename)
425 irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
426 NULL, image, type, NULL, NULL, recipe,
427 applist, remregexp, pipe_id, filename)
428 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
460 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
461 cpl_propertylist * header,
462 const cpl_parameterlist * parlist,
463 const cpl_frameset * usedframes,
464 const cpl_frame * inherit,
465 const cpl_imagelist * imagelist,
466 const cpl_image * image,
468 const cpl_table * table,
469 const cpl_propertylist * tablelist,
471 const cpl_propertylist * applist,
472 const char * remregexp,
473 const char * pipe_id,
474 const char * filename) {
477 cpl_propertylist * plist;
478 cpl_frame * product_frame;
485 const unsigned pronum
486 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
487 const char * proname[] = {
"imagelist",
"table",
"image",
490 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
491 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
492 cpl_error_code error = CPL_ERROR_NONE;
497 if (imagelist != NULL) {
499 assert(image == NULL);
500 assert(table == NULL);
501 assert(tablelist == NULL);
502 }
else if (table != NULL) {
504 assert(imagelist == NULL);
505 assert(image == NULL);
506 }
else if (image != NULL) {
508 assert(imagelist == NULL);
509 assert(table == NULL);
510 assert(tablelist == NULL);
513 assert(imagelist == NULL);
514 assert(table == NULL);
515 assert(tablelist == NULL);
516 assert(image == NULL);
519 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
520 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
521 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
522 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
523 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
524 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
525 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
527 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
529 cpl_ensure_code(procat != NULL, cpl_error_get_code());
531 cpl_msg_info(cpl_func,
"Writing FITS %s product(%s): %s", proname[pronum],
534 product_frame = cpl_frame_new();
537 error |= cpl_frame_set_filename(product_frame, filename);
538 error |= cpl_frame_set_tag(product_frame, procat);
539 error |= cpl_frame_set_type(product_frame, protype[pronum]);
540 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
541 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
544 cpl_frame_delete(product_frame);
545 return cpl_error_set_where(cpl_func);
548 if (header != NULL) {
549 cpl_propertylist_empty(header);
552 plist = cpl_propertylist_new();
556 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
562 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
563 parlist, recipe, pipe_id,
564 "PRO-1.15", inherit);
566 if (remregexp != NULL && !error) {
567 cpl_errorstate prestate = cpl_errorstate_get();
568 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
569 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
575 error = cpl_imagelist_save(imagelist, filename, type, plist,
579 error = cpl_table_save(table, plist, tablelist, filename,
583 error = cpl_image_save(image, filename, type, plist,
588 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
594 error = cpl_frameset_insert(allframes, product_frame);
597 cpl_frame_delete(product_frame);
600 if (plist != header) cpl_propertylist_delete(plist);
602 cpl_ensure_code(!error, error);
604 return CPL_ERROR_NONE;
670 cpl_boolean isleq_low,
672 cpl_boolean isgeq_high,
675 cpl_boolean isbad_low,
676 cpl_boolean isbad_mid,
677 cpl_boolean isbad_high)
680 const void * selfdata = cpl_image_get_data_const(
self);
684 const cpl_boolean hasbpm
685 = cpl_image_count_rejected(
self) ? CPL_TRUE : CPL_FALSE;
686 const cpl_binary * selfbpm = hasbpm
687 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(
self)) : NULL;
688 const cpl_type selftype = cpl_image_get_type(
self);
689 const int nx = cpl_image_get_size_x(
self);
690 const int ny = cpl_image_get_size_y(
self);
691 const int npix = nx * ny;
692 const cpl_boolean do_low = im_low != NULL;
693 const cpl_boolean do_mid = im_mid != NULL;
694 const cpl_boolean do_high = im_high != NULL;
695 void * lowdata = NULL;
696 void * middata = NULL;
697 void * highdata = NULL;
698 cpl_binary * lowbpm = NULL;
699 cpl_binary * midbpm = NULL;
700 cpl_binary * highbpm = NULL;
701 const cpl_type lowtype
702 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
703 const cpl_type midtype
704 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
705 const cpl_type hightype
706 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
710 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
711 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
712 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
715 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
716 CPL_ERROR_INCOMPATIBLE_INPUT);
717 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
718 CPL_ERROR_INCOMPATIBLE_INPUT);
719 lowdata = cpl_image_get_data(im_low);
723 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
724 CPL_ERROR_INCOMPATIBLE_INPUT);
725 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
726 CPL_ERROR_INCOMPATIBLE_INPUT);
727 middata = cpl_image_get_data(im_mid);
731 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
732 CPL_ERROR_INCOMPATIBLE_INPUT);
733 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
734 CPL_ERROR_INCOMPATIBLE_INPUT);
735 highdata = cpl_image_get_data(im_high);
740 for (i = 0; i < npix; i++) {
741 const double value = irplib_data_get_double(selfdata, selftype, i);
742 cpl_boolean isalt_low = do_low;
743 cpl_boolean isalt_mid = do_mid;
744 cpl_boolean isalt_high = do_high;
745 cpl_boolean setbad_low = do_low;
746 cpl_boolean setbad_mid = do_mid;
747 cpl_boolean setbad_high = do_high;
748 const void * setdata = NULL;
749 double alt_mid = 0.0;
751 if (isleq_low ? value <= th_low : value < th_low) {
753 isalt_low = CPL_FALSE;
754 irplib_data_set_double(lowdata, lowtype, i, value);
755 setbad_low = hasbpm && selfbpm[i];
759 }
else if (isgeq_high ? value >= th_high : value > th_high) {
761 isalt_high = CPL_FALSE;
762 irplib_data_set_double(highdata, hightype, i, value);
763 setbad_high = hasbpm && selfbpm[i];
768 isalt_mid = CPL_FALSE;
769 irplib_data_set_double(middata, midtype, i, value);
770 setbad_mid = hasbpm && selfbpm[i];
774 if (isalt_low && lowdata != setdata) {
775 irplib_data_set_double(lowdata, lowtype, i, alt_low);
776 setbad_low = isbad_low;
778 if (isalt_mid && middata != setdata) {
779 irplib_data_set_double(middata, midtype, i, alt_mid);
780 setbad_mid = isbad_mid;
782 if (isalt_high && highdata != setdata) {
783 irplib_data_set_double(highdata, hightype, i, alt_high);
784 setbad_high = isbad_high;
788 if (lowbpm == NULL) lowbpm
789 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
790 lowbpm[i] = CPL_BINARY_1;
793 if (midbpm == NULL) midbpm
794 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
795 midbpm[i] = CPL_BINARY_1;
798 if (highbpm == NULL) highbpm
799 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
800 highbpm[i] = CPL_BINARY_1;
804 return CPL_ERROR_NONE;
861 cpl_frameset * allframes,
862 const cpl_frameset * useframes,
865 const char * product_name,
866 const char * procatg,
867 const cpl_parameterlist * parlist,
868 const char * recipe_name,
869 const cpl_propertylist * mainlist,
870 const cpl_propertylist * extlist,
871 const char * remregexp,
872 const char * instrume,
873 const char * pipe_id,
874 cpl_boolean (*table_set_row)
875 (cpl_table *,
const char *,
int,
877 const cpl_parameterlist *),
878 cpl_error_code (*table_check)
880 const cpl_frameset *,
881 const cpl_parameterlist *))
884 const char * filename;
885 cpl_propertylist * applist = NULL;
886 cpl_errorstate prestate = cpl_errorstate_get();
887 cpl_error_code error;
888 char * fallback_filename = NULL;
890 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
891 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
892 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
893 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
894 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
895 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
896 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
897 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
904 cpl_error_get_code());
906 if (table_check != NULL && (table_check(
self, useframes, parlist) ||
907 !cpl_errorstate_is_equal(prestate))) {
908 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
909 "Consistency check of table failed");
912 fallback_filename = cpl_sprintf(
"%s" CPL_DFS_FITS, recipe_name);
913 filename = product_name != NULL ? product_name : fallback_filename;
915 applist = mainlist == NULL
916 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
918 error = cpl_propertylist_update_string(applist,
"INSTRUME", instrume);
922 extlist, recipe_name, procatg, applist,
923 remregexp, pipe_id, filename);
925 cpl_propertylist_delete(applist);
926 cpl_free(fallback_filename);
929 cpl_ensure_code(!error, error);
931 return CPL_ERROR_NONE;
990 const cpl_frameset * useframes,
993 const cpl_parameterlist * parlist,
994 cpl_boolean (*table_set_row)
995 (cpl_table *,
const char *,
int,
997 const cpl_parameterlist *))
1000 const cpl_frame * rawframe;
1001 char * linebuffer = NULL;
1002 FILE * stream = NULL;
1004 int nrow = cpl_table_get_nrow(
self);
1006 cpl_errorstate prestate = cpl_errorstate_get();
1008 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
1009 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
1010 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
1011 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
1012 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
1014 linebuffer = cpl_malloc(maxlinelen);
1016 for (rawframe = cpl_frameset_get_first_const(useframes);
1018 rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
1020 const char * rawfile = cpl_frame_get_filename(rawframe);
1022 const int irowpre = irow;
1026 if (rawfile == NULL)
break;
1028 stream = fopen(rawfile,
"r");
1030 if (stream == NULL) {
1031 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1032 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1033 "open %s for reading", rawfile);
1035 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO,
"Could not "
1036 "open file for reading");
1041 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
1043 if (linebuffer[0] != commentchar) {
1045 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1046 const int prerow = irow;
1050 nrow += nrow ? nrow : 1;
1051 if (cpl_table_set_size(
self, nrow))
break;
1054 didset = table_set_row(
self, linebuffer, irow, rawframe,
1058 if (!cpl_errorstate_is_equal(prestate)) {
1060 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1061 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1062 "Failed to set table row %d "
1063 "using line %d from %d. file %s",
1067 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1068 "Failure with line %d from %d. "
1072 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1073 "Failed to set table row"
1074 "using catalogue line");
1076 cpl_error_set_message(cpl_func, cpl_error_get_code(),
1077 "Failure with catalogue line");
1084 if (done != NULL)
break;
1086 ierror = fclose(stream);
1091 if (irow == irowpre)
1092 cpl_msg_warning(cpl_func,
"No usable lines in the %d. file: %s",
1096 cpl_free(linebuffer);
1097 if (stream != NULL) fclose(stream);
1100 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1103 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1104 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1105 "No usable lines in the %d input "
1106 "frame(s)", nfiles);
1108 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1109 "No usable lines in the input frame(s)");
1114 cpl_ensure_code(!cpl_table_set_size(
self, irow), cpl_error_get_code());
1116 return CPL_ERROR_NONE;
1155 if (frame1==NULL || frame2==NULL)
return -1 ;
1158 if ((v1 = cpl_frame_get_tag(frame1)) == NULL)
return -1 ;
1159 if ((v2 = cpl_frame_get_tag(frame2)) == NULL)
return -1 ;
1162 if (strcmp(v1, v2))
return 0 ;
1186 const cpl_frame * frame = cpl_frameset_find_const(
self, tag);
1189 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1191 if (frame == NULL)
return NULL;
1193 if (cpl_frameset_find_const(
self, NULL))
1194 cpl_msg_warning(cpl_func,
1195 "Frameset has more than one file with tag: %s",
1198 return cpl_frame_get_filename(frame);
1215 cpl_frame_group group)
1217 const cpl_frame * frame;
1219 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1221 for (frame = cpl_frameset_get_first_const(
self); frame != NULL ;
1222 frame = cpl_frameset_get_next_const(
self)) {
1223 if (cpl_frame_get_group(frame) == group)
break;
1249 int * ind,
int nfind)
1251 const int nsize = cpl_apertures_get_size(
self);
1255 cpl_ensure_code(nsize > 0, cpl_error_get_code());
1256 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1257 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1258 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1260 for (ifind=0; ifind < nfind; ifind++) {
1261 double maxflux = -1;
1264 for (i=1; i <= nsize; i++) {
1268 for (k=0; k < ifind; k++)
if (ind[k] == i)
break;
1272 const double flux = cpl_apertures_get_flux(
self, i);
1274 if (maxind < 0 || flux > maxflux) {
1280 ind[ifind] = maxind;
1283 return CPL_ERROR_NONE;
1304 double irplib_data_get_double(
const void *
self, cpl_type type,
int i)
1311 case CPL_TYPE_FLOAT:
1313 const float * pself = (
const float*)
self;
1314 value = (double)pself[i];
1319 const int * pself = (
const int*)
self;
1320 value = (double)pself[i];
1325 const double * pself = (
const double*)
self;
1349 void irplib_data_set_double(
void *
self, cpl_type type,
int i,
double value)
1353 case CPL_TYPE_FLOAT:
1355 float * pself = (
float*)
self;
1356 pself[i] = (float)value;
1361 int * pself = (
int*)
self;
1362 pself[i] = (int)value;
1367 double * pself = (
double*)
self;
1391 void irplib_errorstate_dump_one_level(
void (*messenger)(
const char *,
1393 unsigned self,
unsigned first,
1397 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
1398 const unsigned newest = is_reverse ? first : last;
1399 const unsigned oldest = is_reverse ? last : first;
1400 const char * revmsg = is_reverse ?
" in reverse order" :
"";
1410 messenger(cpl_func,
"No error(s) to dump");
1417 if (
self == first) {
1419 messenger(cpl_func,
"Dumping all %u error(s)%s:", newest,
1422 messenger(cpl_func,
"Dumping the %u most recent error(s) "
1423 "out of a total of %u errors%s:",
1424 newest - oldest + 1, newest, revmsg);
1426 cpl_msg_indent_more();
1429 messenger(cpl_func,
"[%u/%u] '%s' (%u) at %s",
self, newest,
1430 cpl_error_get_message(), cpl_error_get_code(),
1431 cpl_error_get_where());
1433 if (
self == last) cpl_msg_indent_less();
1437 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
1438 const cpl_vector * x_pos,
1439 const cpl_vector * values,
1444 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
1446 cpl_polynomial * irplib_polynomial_fit_1d_create(
1447 const cpl_vector * x_pos,
1448 const cpl_vector * values,
1454 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
1456 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
1457 const cpl_vector * x_pos,
1458 const cpl_vector * values,
1464 cpl_polynomial * fit1d = NULL;
1465 cpl_size loc_degree = (cpl_size)degree ;
1467 fit1d = cpl_polynomial_new(1);
1468 x_size = cpl_vector_get_size(x_pos);
1469 if(fit1d != NULL && x_size > 1)
1471 cpl_matrix * samppos = NULL;
1472 cpl_vector * fitresidual = NULL;
1473 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1474 samppos = cpl_matrix_wrap(1, x_size,
1475 (
double*)cpl_vector_get_data_const(x_pos));
1476 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1477 fitresidual = cpl_vector_new(x_size);
1478 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1479 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
1480 CPL_FALSE, NULL, &loc_degree);
1481 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1482 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1483 fit1d, samppos, rechisq);
1484 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1487 *mse = cpl_vector_product(fitresidual, fitresidual)
1488 / cpl_vector_get_size(fitresidual);
1490 cpl_matrix_unwrap(samppos);
1491 cpl_vector_delete(fitresidual);
1496 static void quicksort(
int* iindex,
double* exptime,
int left,
int right)
1500 int pivot = (i + j) / 2;
1501 double index_value = exptime[pivot];
1504 while(exptime[i] < index_value) i++;
1505 while(exptime[j] > index_value) j--;
1510 int tmp = iindex[i];
1511 double dtmp = exptime[i];
1512 iindex[i]=iindex[j];
1514 exptime[i] = exptime[j];
1524 quicksort(iindex, exptime, i, right);
1528 quicksort(iindex, exptime,left, j);
1531 cpl_error_code irplib_frameset_sort(
const cpl_frameset *
self,
int* iindex,
double* exptime)
1535 const cpl_frame* tmp_frame = 0;
1536 cpl_error_code error = CPL_ERROR_NONE;
1537 sz = cpl_frameset_get_size(
self);
1540 tmp_frame = cpl_frameset_get_first_const(
self);
1543 exptime[i] = frame_get_exptime(tmp_frame);
1545 tmp_frame = cpl_frameset_get_next_const(
self);
1549 quicksort(iindex, exptime, 0, sz - 1);
1554 static double frame_get_exptime(
const cpl_frame * pframe)
1557 cpl_propertylist * plist =
1558 cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1559 "EXPTIME", CPL_FALSE);
1561 dval = cpl_propertylist_get_double(plist,
"EXPTIME");
1562 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1563 cpl_msg_error(cpl_func,
"error during reading EXPTIME key from "
1564 "the frame [%s]", cpl_frame_get_filename(pframe));
1568 cpl_propertylist_delete(plist);
1588 void * irplib_aligned_malloc(
size_t alignment,
size_t size)
1590 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
1591 return aligned_alloc(alignment, size);
1592 #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)
1608 if (alignment & (alignment - 1)) {
1620 if (alignment < 2 *
sizeof (
void *))
1621 alignment = 2 *
sizeof (
void *);
1623 malloc_ptr = malloc (size + alignment);
1628 aligned_ptr = (
void *) (((
size_t) malloc_ptr + alignment)
1629 & ~((size_t) (alignment) - 1));
1632 *(((
void **) aligned_ptr) - 1) = malloc_ptr;
1650 void * irplib_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);
1670 void irplib_aligned_free (
void * aligned_ptr)
1672 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
1674 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1678 free (*(((
void **) aligned_ptr) - 1));