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