00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037
00038 #include <string.h>
00039 #include <assert.h>
00040
00041 #include <cpl.h>
00042
00043 #include "irplib_utils.h"
00044
00045
00046
00047
00048
00049 #ifndef inline
00050 #define inline
00051 #endif
00052
00053
00054
00055
00056
00057 #if defined HAVE_ISNAN && HAVE_ISNAN != 0
00058 #if !defined isnan && defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 0
00059
00060
00061 int isnan(double);
00062 #endif
00063 #endif
00064
00065
00066
00067
00068
00069 inline static double irplib_data_get_double(const void *, cpl_type, int)
00070 #ifdef CPL_HAVE_GNUC_NONNULL
00071 __attribute__((nonnull))
00072 #endif
00073 ;
00074
00075 inline static void irplib_data_set_double(void *, cpl_type, int, double)
00076 #ifdef CPL_HAVE_GNUC_NONNULL
00077 __attribute__((nonnull))
00078 #endif
00079 ;
00080
00081
00082 static
00083 void irplib_errorstate_dump_one_level(void (*)(const char *,
00084 const char *, ...)
00085 #ifdef __GNUC__
00086 __attribute__((format (printf, 2, 3)))
00087 #endif
00088 , unsigned, unsigned, unsigned);
00089 static double frame_get_exptime(const cpl_frame * pframe);
00090 static void quicksort(cpl_size* index, double* exptime, cpl_size left,
00091 cpl_size right);
00092
00096
00100
00112
00113 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
00114 unsigned last)
00115 {
00116
00117 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
00118
00119 }
00120
00121 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
00122 const cpl_vector * x_pos,
00123 const cpl_vector * values,
00124 cpl_size degree,
00125 double * mse,
00126 double * rechisq
00127 );
00128
00129
00139
00140 void irplib_errorstate_dump_info(unsigned self, unsigned first,
00141 unsigned last)
00142 {
00143
00144 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
00145
00146 }
00147
00148
00149
00159
00160 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
00161 unsigned last)
00162 {
00163
00164 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
00165
00166 }
00167
00168
00169
00190
00191 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
00192 const cpl_parameterlist * parlist,
00193 const cpl_frameset * usedframes,
00194 const cpl_image * image,
00195 cpl_type_bpp bpp,
00196 const char * recipe,
00197 const char * procat,
00198 const cpl_propertylist * applist,
00199 const char * remregexp,
00200 const char * pipe_id,
00201 const char * filename)
00202 {
00203 cpl_errorstate prestate = cpl_errorstate_get();
00204 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00205 : cpl_propertylist_new();
00206
00207 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00208
00209 cpl_dfs_save_image(allframes, NULL, parlist, usedframes, NULL, image, bpp,
00210 recipe, prolist, remregexp, pipe_id, filename);
00211
00212 cpl_propertylist_delete(prolist);
00213
00214 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00215
00216 return CPL_ERROR_NONE;
00217
00218 }
00219
00220
00237
00238 cpl_error_code
00239 irplib_dfs_save_propertylist(cpl_frameset * allframes,
00240 const cpl_parameterlist * parlist,
00241 const cpl_frameset * usedframes,
00242 const char * recipe,
00243 const char * procat,
00244 const cpl_propertylist * applist,
00245 const char * remregexp,
00246 const char * pipe_id,
00247 const char * filename)
00248 {
00249 cpl_errorstate prestate = cpl_errorstate_get();
00250 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00251 : cpl_propertylist_new();
00252
00253 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00254
00255 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00256 recipe, prolist, remregexp, pipe_id, filename);
00257
00258 cpl_propertylist_delete(prolist);
00259
00260 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00261
00262 return CPL_ERROR_NONE;
00263
00264 }
00265
00266
00285
00286 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
00287 const cpl_parameterlist * parlist,
00288 const cpl_frameset * usedframes,
00289 const cpl_imagelist * imagelist,
00290 cpl_type_bpp bpp,
00291 const char * recipe,
00292 const char * procat,
00293 const cpl_propertylist * applist,
00294 const char * remregexp,
00295 const char * pipe_id,
00296 const char * filename)
00297 {
00298 cpl_errorstate prestate = cpl_errorstate_get();
00299 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00300 : cpl_propertylist_new();
00301
00302 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00303
00304 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00305 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00306 filename);
00307
00308 cpl_propertylist_delete(prolist);
00309
00310 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00311
00312 return CPL_ERROR_NONE;
00313 }
00314
00315
00333
00334 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
00335 const cpl_parameterlist * parlist,
00336 const cpl_frameset * usedframes,
00337 const cpl_table * table,
00338 const cpl_propertylist * tablelist,
00339 const char * recipe,
00340 const char * procat,
00341 const cpl_propertylist * applist,
00342 const char * remregexp,
00343 const char * pipe_id,
00344 const char * filename)
00345 {
00346
00347 cpl_errorstate prestate = cpl_errorstate_get();
00348 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00349 : cpl_propertylist_new();
00350
00351 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00352
00353 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00354 table, tablelist, recipe, prolist, remregexp,
00355 pipe_id, filename);
00356
00357 cpl_propertylist_delete(prolist);
00358
00359 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00360
00361 return CPL_ERROR_NONE;
00362 }
00363
00364
00419
00420 cpl_error_code irplib_image_split(const cpl_image * self,
00421 cpl_image * im_low,
00422 cpl_image * im_mid,
00423 cpl_image * im_high,
00424 double th_low,
00425 cpl_boolean isleq_low,
00426 double th_high,
00427 cpl_boolean isgeq_high,
00428 double alt_low,
00429 double alt_high,
00430 cpl_boolean isbad_low,
00431 cpl_boolean isbad_mid,
00432 cpl_boolean isbad_high)
00433 {
00434
00435 const void * selfdata = cpl_image_get_data_const(self);
00436
00437
00438
00439 const cpl_boolean hasbpm
00440 = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
00441 const cpl_binary * selfbpm = hasbpm
00442 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
00443 const cpl_type selftype = cpl_image_get_type(self);
00444 const int nx = cpl_image_get_size_x(self);
00445 const int ny = cpl_image_get_size_y(self);
00446 const int npix = nx * ny;
00447 const cpl_boolean do_low = im_low != NULL;
00448 const cpl_boolean do_mid = im_mid != NULL;
00449 const cpl_boolean do_high = im_high != NULL;
00450 void * lowdata = NULL;
00451 void * middata = NULL;
00452 void * highdata = NULL;
00453 cpl_binary * lowbpm = NULL;
00454 cpl_binary * midbpm = NULL;
00455 cpl_binary * highbpm = NULL;
00456 const cpl_type lowtype
00457 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
00458 const cpl_type midtype
00459 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
00460 const cpl_type hightype
00461 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
00462 int i;
00463
00464
00465 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00466 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
00467 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
00468
00469 if (do_low) {
00470 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
00471 CPL_ERROR_INCOMPATIBLE_INPUT);
00472 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
00473 CPL_ERROR_INCOMPATIBLE_INPUT);
00474 lowdata = cpl_image_get_data(im_low);
00475 }
00476
00477 if (do_mid) {
00478 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
00479 CPL_ERROR_INCOMPATIBLE_INPUT);
00480 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
00481 CPL_ERROR_INCOMPATIBLE_INPUT);
00482 middata = cpl_image_get_data(im_mid);
00483 }
00484
00485 if (do_high) {
00486 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
00487 CPL_ERROR_INCOMPATIBLE_INPUT);
00488 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
00489 CPL_ERROR_INCOMPATIBLE_INPUT);
00490 highdata = cpl_image_get_data(im_high);
00491 }
00492
00493
00494
00495 for (i = 0; i < npix; i++) {
00496 const double value = irplib_data_get_double(selfdata, selftype, i);
00497 cpl_boolean isalt_low = do_low;
00498 cpl_boolean isalt_mid = do_mid;
00499 cpl_boolean isalt_high = do_high;
00500 cpl_boolean setbad_low = do_low;
00501 cpl_boolean setbad_mid = do_mid;
00502 cpl_boolean setbad_high = do_high;
00503 const void * setdata = NULL;
00504 double alt_mid = 0.0;
00505
00506 if (isleq_low ? value <= th_low : value < th_low) {
00507 if (do_low) {
00508 isalt_low = CPL_FALSE;
00509 irplib_data_set_double(lowdata, lowtype, i, value);
00510 setbad_low = hasbpm && selfbpm[i];
00511 setdata = lowdata;
00512 }
00513 alt_mid = alt_low;
00514 } else if (isgeq_high ? value >= th_high : value > th_high) {
00515 if (do_high) {
00516 isalt_high = CPL_FALSE;
00517 irplib_data_set_double(highdata, hightype, i, value);
00518 setbad_high = hasbpm && selfbpm[i];
00519 setdata = highdata;
00520 }
00521 alt_mid = alt_high;
00522 } else if (do_mid) {
00523 isalt_mid = CPL_FALSE;
00524 irplib_data_set_double(middata, midtype, i, value);
00525 setbad_mid = hasbpm && selfbpm[i];
00526 setdata = middata;
00527 }
00528
00529 if (isalt_low && lowdata != setdata) {
00530 irplib_data_set_double(lowdata, lowtype, i, alt_low);
00531 setbad_low = isbad_low;
00532 }
00533 if (isalt_mid && middata != setdata) {
00534 irplib_data_set_double(middata, midtype, i, alt_mid);
00535 setbad_mid = isbad_mid;
00536 }
00537 if (isalt_high && highdata != setdata) {
00538 irplib_data_set_double(highdata, hightype, i, alt_high);
00539 setbad_high = isbad_high;
00540 }
00541
00542 if (setbad_low) {
00543 if (lowbpm == NULL) lowbpm
00544 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
00545 lowbpm[i] = CPL_BINARY_1;
00546 }
00547 if (setbad_mid) {
00548 if (midbpm == NULL) midbpm
00549 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
00550 midbpm[i] = CPL_BINARY_1;
00551 }
00552 if (setbad_high) {
00553 if (highbpm == NULL) highbpm
00554 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
00555 highbpm[i] = CPL_BINARY_1;
00556 }
00557 }
00558
00559 return CPL_ERROR_NONE;
00560
00561 }
00562
00563
00564
00612
00613
00614 cpl_error_code
00615 irplib_dfs_table_convert(cpl_table * self,
00616 cpl_frameset * allframes,
00617 const cpl_frameset * useframes,
00618 int maxlinelen,
00619 char commentchar,
00620 const char * product_name,
00621 const char * procatg,
00622 const cpl_parameterlist * parlist,
00623 const char * recipe_name,
00624 const cpl_propertylist * mainlist,
00625 const cpl_propertylist * extlist,
00626 const char * remregexp,
00627 const char * instrume,
00628 const char * pipe_id,
00629 cpl_boolean (*table_set_row)
00630 (cpl_table *, const char *, int,
00631 const cpl_frame *,
00632 const cpl_parameterlist *),
00633 cpl_error_code (*table_check)
00634 (cpl_table *,
00635 const cpl_frameset *,
00636 const cpl_parameterlist *))
00637 {
00638
00639 const char * filename;
00640 cpl_propertylist * applist = NULL;
00641 cpl_errorstate prestate = cpl_errorstate_get();
00642 cpl_error_code error;
00643
00644 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00645 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00646 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00647 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
00648 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00649 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00650 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00651 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00652
00653 cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00654 maxlinelen,
00655 commentchar,
00656 parlist,
00657 table_set_row),
00658 cpl_error_get_code());
00659
00660 if (table_check != NULL && (table_check(self, useframes, parlist) ||
00661 !cpl_errorstate_is_equal(prestate))) {
00662 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00663 "Consistency check of table failed");
00664 }
00665
00666 filename = product_name != NULL
00667 ? product_name : cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00668
00669 applist = mainlist == NULL
00670 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00671
00672 error = cpl_propertylist_append_string(applist, "INSTRUME", instrume);
00673
00674 if (!error)
00675 error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00676 extlist, recipe_name, procatg, applist,
00677 remregexp, pipe_id, filename);
00678
00679 cpl_propertylist_delete(applist);
00680 if (filename != product_name) cpl_free((char*)filename);
00681
00682
00683 cpl_ensure_code(!error, error);
00684
00685 return CPL_ERROR_NONE;
00686
00687 }
00688
00689
00690
00691
00740
00741
00742 cpl_error_code
00743 irplib_table_read_from_frameset(cpl_table * self,
00744 const cpl_frameset * useframes,
00745 int maxlinelen,
00746 char commentchar,
00747 const cpl_parameterlist * parlist,
00748 cpl_boolean (*table_set_row)
00749 (cpl_table *, const char *, int,
00750 const cpl_frame *,
00751 const cpl_parameterlist *))
00752 {
00753
00754 const cpl_frame * rawframe;
00755 char * linebuffer = NULL;
00756 FILE * stream = NULL;
00757 int nfiles = 0;
00758 int nrow = cpl_table_get_nrow(self);
00759 int irow = 0;
00760 cpl_errorstate prestate = cpl_errorstate_get();
00761
00762 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00763 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00764 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
00765 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00766 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
00767
00768 linebuffer = cpl_malloc(maxlinelen);
00769
00770 for (rawframe = cpl_frameset_get_first_const(useframes);
00771 rawframe != NULL;
00772 rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
00773
00774 const char * rawfile = cpl_frame_get_filename(rawframe);
00775 const char * done;
00776 const int irowpre = irow;
00777 int iirow = 0;
00778 int ierror;
00779
00780 if (rawfile == NULL) break;
00781
00782 stream = fopen(rawfile, "r");
00783
00784 if (stream == NULL) {
00785 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00786 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
00787 "open %s for reading", rawfile);
00788 #else
00789 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
00790 "open file for reading");
00791 #endif
00792 break;
00793 }
00794
00795 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
00796
00797 if (linebuffer[0] != commentchar) {
00798 cpl_boolean didset;
00799 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00800 const int prerow = irow;
00801 #endif
00802
00803 if (irow == nrow) {
00804 nrow += nrow ? nrow : 1;
00805 if (cpl_table_set_size(self, nrow)) break;
00806 }
00807
00808 didset = table_set_row(self, linebuffer, irow, rawframe,
00809 parlist);
00810 if (didset) irow++;
00811
00812 if (!cpl_errorstate_is_equal(prestate)) {
00813 if (didset)
00814 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00815 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00816 "Failed to set table row %d "
00817 "using line %d from %d. file %s",
00818 1+prerow, iirow+1,
00819 nfiles+1, rawfile);
00820 else
00821 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00822 "Failure with line %d from %d. "
00823 "file %s", iirow+1,
00824 nfiles+1, rawfile);
00825 #else
00826 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00827 "Failed to set table row"
00828 "using catalogue line");
00829 else
00830 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00831 "Failure with catalogue line");
00832 #endif
00833
00834 break;
00835 }
00836 }
00837 }
00838 if (done != NULL) break;
00839
00840 ierror = fclose(stream);
00841 stream = NULL;
00842 if (ierror) break;
00843
00844
00845 if (irow == irowpre)
00846 cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
00847 1+nfiles, rawfile);
00848 }
00849
00850 cpl_free(linebuffer);
00851 if (stream != NULL) fclose(stream);
00852
00853
00854 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
00855
00856 if (irow == 0) {
00857 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00858 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00859 "No usable lines in the %d input "
00860 "frame(s)", nfiles);
00861 #else
00862 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00863 "No usable lines in the input frame(s)");
00864 #endif
00865 }
00866
00867
00868 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
00869
00870 return CPL_ERROR_NONE;
00871 }
00872
00873
00874
00875
00887
00888 void irplib_reset(void)
00889 {
00890 return;
00891 }
00892
00893
00900
00901 int irplib_compare_tags(
00902 cpl_frame * frame1,
00903 cpl_frame * frame2)
00904 {
00905 char * v1 ;
00906 char * v2 ;
00907
00908
00909 if (frame1==NULL || frame2==NULL) return -1 ;
00910
00911
00912 if ((v1 = (char*)cpl_frame_get_tag(frame1)) == NULL) return -1 ;
00913 if ((v2 = (char*)cpl_frame_get_tag(frame2)) == NULL) return -1 ;
00914
00915
00916 if (strcmp(v1, v2)) return 0 ;
00917 else return 1 ;
00918 }
00919
00920
00936
00937 const char * irplib_frameset_find_file(const cpl_frameset * self,
00938 const char * tag)
00939 {
00940 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
00941
00942
00943 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00944
00945 if (frame == NULL) return NULL;
00946
00947 if (cpl_frameset_find_const(self, NULL))
00948 cpl_msg_warning(cpl_func,
00949 "Frameset has more than one file with tag: %s",
00950 tag);
00951
00952 return cpl_frame_get_filename(frame);
00953
00954 }
00955
00956
00966
00967 const
00968 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
00969 cpl_frame_group group)
00970 {
00971 const cpl_frame * frame;
00972
00973 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00974
00975 for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
00976 frame = cpl_frameset_get_next_const(self)) {
00977 if (cpl_frame_get_group(frame) == group) break;
00978 }
00979 return frame;
00980 }
00981
00982
01001
01002 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01003 int * ind, int nfind)
01004 {
01005 const int nsize = cpl_apertures_get_size(self);
01006 int ifind;
01007
01008
01009 cpl_ensure_code(nsize > 0, cpl_error_get_code());
01010 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
01011 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
01012 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01013
01014 for (ifind=0; ifind < nfind; ifind++) {
01015 double maxflux = -1;
01016 int maxind = -1;
01017 int i;
01018 for (i=1; i <= nsize; i++) {
01019 int k;
01020
01021
01022 for (k=0; k < ifind; k++) if (ind[k] == i) break;
01023
01024 if (k == ifind) {
01025
01026 const double flux = cpl_apertures_get_flux(self, i);
01027
01028 if (maxind < 0 || flux > maxflux) {
01029 maxind = i;
01030 maxflux = flux;
01031 }
01032 }
01033 }
01034 ind[ifind] = maxind;
01035 }
01036
01037 return CPL_ERROR_NONE;
01038
01039 }
01040
01041
01045
01046 int irplib_isinf(double value)
01047 {
01048 #if defined HAVE_ISINF && HAVE_ISINF
01049 return isinf(value);
01050 #else
01051 return value != 0 && value == 2 * value;
01052 #endif
01053 }
01054
01055
01059
01060 int irplib_isnan(double value)
01061 {
01062 #if defined HAVE_ISNAN && HAVE_ISNAN
01063 return isnan(value);
01064 #else
01065 return value != value;
01066 #endif
01067 }
01068
01069
01070
01071
01082
01083 void irplib_errorstate_warning(unsigned self, unsigned first, unsigned last)
01084 {
01085
01086 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01087 const unsigned newest = is_reverse ? first : last;
01088 const unsigned oldest = is_reverse ? last : first;
01089 const char * revmsg = is_reverse ? " in reverse order" : "";
01090
01091
01092 assert( oldest <= self );
01093 assert( newest >= self );
01094
01095 if (newest == 0) {
01096 cpl_msg_info(cpl_func, "No error(s) to dump");
01097 assert( oldest == 0);
01098 } else {
01099 assert( oldest > 0);
01100 assert( newest >= oldest);
01101 if (self == first) {
01102 if (oldest == 1) {
01103 cpl_msg_warning(cpl_func, "Dumping all %u error(s)%s:", newest,
01104 revmsg);
01105 } else {
01106 cpl_msg_warning(cpl_func, "Dumping the %u most recent error(s) "
01107 "out of a total of %u errors%s:",
01108 newest - oldest + 1, newest, revmsg);
01109 }
01110 cpl_msg_indent_more();
01111 }
01112
01113 cpl_msg_warning(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01114 cpl_error_get_message(), cpl_error_get_code(),
01115 cpl_error_get_where());
01116
01117 if (self == last) cpl_msg_indent_less();
01118 }
01119 }
01120
01121
01124
01135
01136 inline static
01137 double irplib_data_get_double(const void * self, cpl_type type, int i)
01138 {
01139
01140 double value;
01141
01142
01143 switch (type) {
01144 case CPL_TYPE_FLOAT:
01145 {
01146 const float * pself = (const float*)self;
01147 value = (double)pself[i];
01148 break;
01149 }
01150 case CPL_TYPE_INT:
01151 {
01152 const int * pself = (const int*)self;
01153 value = (double)pself[i];
01154 break;
01155 }
01156 default:
01157 {
01158 const double * pself = (const double*)self;
01159 value = pself[i];
01160 break;
01161 }
01162 }
01163
01164 return value;
01165
01166 }
01167
01168
01169
01180
01181 inline static
01182 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01183 {
01184
01185 switch (type) {
01186 case CPL_TYPE_FLOAT:
01187 {
01188 float * pself = (float*)self;
01189 pself[i] = (float)value;
01190 break;
01191 }
01192 case CPL_TYPE_INT:
01193 {
01194 int * pself = (int*)self;
01195 pself[i] = (int)value;
01196 break;
01197 }
01198 default:
01199 {
01200 double * pself = (double*)self;
01201 pself[i] = value;
01202 break;
01203 }
01204 }
01205 }
01206
01207
01208
01209
01210
01211
01222
01223 static
01224 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01225 const char *, ...),
01226 unsigned self, unsigned first,
01227 unsigned last)
01228 {
01229
01230 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01231 const unsigned newest = is_reverse ? first : last;
01232 const unsigned oldest = is_reverse ? last : first;
01233 const char * revmsg = is_reverse ? " in reverse order" : "";
01234
01235
01236
01237
01238
01239
01240
01241
01242 if (newest == 0) {
01243 messenger(cpl_func, "No error(s) to dump");
01244
01245 } else {
01246
01247
01248
01249
01250 if (self == first) {
01251 if (oldest == 1) {
01252 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01253 revmsg);
01254 } else {
01255 messenger(cpl_func, "Dumping the %u most recent error(s) "
01256 "out of a total of %u errors%s:",
01257 newest - oldest + 1, newest, revmsg);
01258 }
01259 cpl_msg_indent_more();
01260 }
01261
01262 messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01263 cpl_error_get_message(), cpl_error_get_code(),
01264 cpl_error_get_where());
01265
01266 if (self == last) cpl_msg_indent_less();
01267 }
01268 }
01269
01270 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01271 const cpl_vector * x_pos,
01272 const cpl_vector * values,
01273 int degree,
01274 double * rechisq
01275 )
01276 {
01277 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01278 }
01279 cpl_polynomial * irplib_polynomial_fit_1d_create(
01280 const cpl_vector * x_pos,
01281 const cpl_vector * values,
01282 int degree,
01283 double * mse
01284 )
01285 {
01286
01287 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01288 }
01289 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01290 const cpl_vector * x_pos,
01291 const cpl_vector * values,
01292 cpl_size degree,
01293 double * mse,
01294 double * rechisq
01295 )
01296 {
01297 cpl_polynomial * fit1d = NULL;
01298 int x_size = 0;
01299 fit1d = cpl_polynomial_new(1);
01300 x_size = cpl_vector_get_size(x_pos);
01301 if(fit1d != NULL && x_size > 1)
01302 {
01303 cpl_matrix * samppos = NULL;
01304 cpl_vector * fitresidual = NULL;
01305 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01306 samppos = cpl_matrix_wrap(1, x_size,
01307 (double*)cpl_vector_get_data_const(x_pos));
01308 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01309 fitresidual = cpl_vector_new(x_size);
01310 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01311 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01312 CPL_FALSE, NULL, °ree);
01313 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01314 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, fit1d,
01315 samppos, rechisq);
01316 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01317 if (mse)
01318 {
01319 *mse = cpl_vector_product(fitresidual, fitresidual)
01320 / cpl_vector_get_size(fitresidual);
01321 }
01322 cpl_matrix_unwrap(samppos);
01323 cpl_vector_delete(fitresidual);
01324 }
01325 return fit1d;
01326 }
01327
01328 static void quicksort(cpl_size* iindex, double* exptime,
01329 cpl_size left, cpl_size right)
01330 {
01331 cpl_size i = left;
01332 cpl_size j = right;
01333 cpl_size pivot = (i + j) / 2;
01334 double index_value = exptime[pivot];
01335 do
01336 {
01337 while(exptime[i] < index_value) i++;
01338 while(exptime[j] > index_value) j--;
01339 if (i <= j)
01340 {
01341 if(i < j)
01342 {
01343 int tmp = iindex[i];
01344 double dtmp = exptime[i];
01345 iindex[i]=iindex[j];
01346 iindex[j]=tmp;
01347 exptime[i] = exptime[j];
01348 exptime[j] = dtmp;
01349 }
01350 i++;
01351 j--;
01352 }
01353 } while (i <= j);
01354
01355 if (i < right)
01356 {
01357 quicksort(iindex, exptime, i, right);
01358 }
01359 if (left < j)
01360 {
01361 quicksort(iindex, exptime,left, j);
01362 }
01363 }
01364 cpl_error_code irplib_frameset_sort(const cpl_frameset * self,
01365 cpl_size* iindex, double* exptime)
01366 {
01367 cpl_size sz = 0;
01368 cpl_size i = 0;
01369 const cpl_frame* tmp_frame = 0;
01370 cpl_error_code error = CPL_ERROR_NONE;
01371 sz = cpl_frameset_get_size(self);
01372
01373
01374 tmp_frame = cpl_frameset_get_first_const(self);
01375 while(tmp_frame)
01376 {
01377 exptime[i] = frame_get_exptime(tmp_frame);
01378 iindex[i] = i;
01379 tmp_frame = cpl_frameset_get_next_const(self);
01380 i++;
01381 }
01382
01383 quicksort(iindex, exptime, 0, sz - 1);
01384
01385 return error;
01386 }
01387
01388 static double frame_get_exptime(const cpl_frame * pframe)
01389 {
01390 cpl_propertylist *plist = 0;
01391 double dval = 0;
01392
01393 plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01394 if(plist)
01395 {
01396 cpl_error_code err = CPL_ERROR_NONE;
01397 dval = cpl_propertylist_get_double(plist, "EXPTIME");
01398 err = cpl_error_get_code();
01399 if (err != CPL_ERROR_NONE)
01400 {
01401 cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01402 }
01403 }
01404
01405 cpl_propertylist_delete(plist);
01406 return dval;
01407 }