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
00050 #ifndef CPL_SIZE_FORMAT
00051 #define CPL_SIZE_FORMAT "d"
00052 #define cpl_size int
00053 #endif
00054
00055
00056 #ifndef inline
00057 #define inline
00058 #endif
00059
00060
00061
00062
00063
00064 #if defined HAVE_ISNAN && HAVE_ISNAN != 0
00065 #if !defined isnan && defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 0
00066
00067
00068 int isnan(double);
00069 #endif
00070 #endif
00071
00072
00073
00074
00075
00076 inline static double irplib_data_get_double(const void *, cpl_type, int)
00077 #ifdef CPL_HAVE_GNUC_NONNULL
00078 __attribute__((nonnull))
00079 #endif
00080 ;
00081
00082 inline static void irplib_data_set_double(void *, cpl_type, int, double)
00083 #ifdef CPL_HAVE_GNUC_NONNULL
00084 __attribute__((nonnull))
00085 #endif
00086 ;
00087
00088
00089 static
00090 void irplib_errorstate_dump_one_level(void (*)(const char *,
00091 const char *, ...)
00092 #ifdef __GNUC__
00093 __attribute__((format (printf, 2, 3)))
00094 #endif
00095 , unsigned, unsigned, unsigned);
00096 static double frame_get_exptime(const cpl_frame * pframe);
00097 static void quicksort(int* index, double* exptime, int left, int right);
00098
00099 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
00100 cpl_propertylist *,
00101 const cpl_parameterlist *,
00102 const cpl_frameset *,
00103 const cpl_frame *,
00104 const cpl_imagelist *,
00105 const cpl_image *,
00106 cpl_type,
00107 const cpl_table *,
00108 const cpl_propertylist *,
00109 const char *,
00110 const cpl_propertylist *,
00111 const char *,
00112 const char *,
00113 const char *);
00114
00115
00119
00123
00135
00136 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
00137 unsigned last)
00138 {
00139
00140 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
00141
00142 }
00143
00144 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
00145 const cpl_vector * x_pos,
00146 const cpl_vector * values,
00147 int degree,
00148 double * mse,
00149 double * rechisq
00150 );
00151
00152
00162
00163 void irplib_errorstate_dump_info(unsigned self, unsigned first,
00164 unsigned last)
00165 {
00166
00167 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
00168
00169 }
00170
00171
00172
00182
00183 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
00184 unsigned last)
00185 {
00186
00187 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
00188
00189 }
00190
00191
00192
00213
00214 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
00215 const cpl_parameterlist * parlist,
00216 const cpl_frameset * usedframes,
00217 const cpl_image * image,
00218 cpl_type_bpp bpp,
00219 const char * recipe,
00220 const char * procat,
00221 const cpl_propertylist * applist,
00222 const char * remregexp,
00223 const char * pipe_id,
00224 const char * filename)
00225 {
00226 cpl_errorstate prestate = cpl_errorstate_get();
00227 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00228 : cpl_propertylist_new();
00229
00230 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00231
00232 irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
00233 bpp, recipe, prolist, remregexp, pipe_id, filename);
00234
00235 cpl_propertylist_delete(prolist);
00236
00237 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00238
00239 return CPL_ERROR_NONE;
00240
00241 }
00242
00243
00260
00261 cpl_error_code
00262 irplib_dfs_save_propertylist(cpl_frameset * allframes,
00263 const cpl_parameterlist * parlist,
00264 const cpl_frameset * usedframes,
00265 const char * recipe,
00266 const char * procat,
00267 const cpl_propertylist * applist,
00268 const char * remregexp,
00269 const char * pipe_id,
00270 const char * filename)
00271 {
00272 cpl_errorstate prestate = cpl_errorstate_get();
00273 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00274 : cpl_propertylist_new();
00275
00276 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00277
00278 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00279 recipe, prolist, remregexp, pipe_id, filename);
00280
00281 cpl_propertylist_delete(prolist);
00282
00283 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00284
00285 return CPL_ERROR_NONE;
00286
00287 }
00288
00289
00308
00309 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
00310 const cpl_parameterlist * parlist,
00311 const cpl_frameset * usedframes,
00312 const cpl_imagelist * imagelist,
00313 cpl_type_bpp bpp,
00314 const char * recipe,
00315 const char * procat,
00316 const cpl_propertylist * applist,
00317 const char * remregexp,
00318 const char * pipe_id,
00319 const char * filename)
00320 {
00321 cpl_errorstate prestate = cpl_errorstate_get();
00322 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00323 : cpl_propertylist_new();
00324
00325 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00326
00327 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00328 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00329 filename);
00330
00331 cpl_propertylist_delete(prolist);
00332
00333 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00334
00335 return CPL_ERROR_NONE;
00336 }
00337
00338
00356
00357 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
00358 const cpl_parameterlist * parlist,
00359 const cpl_frameset * usedframes,
00360 const cpl_table * table,
00361 const cpl_propertylist * tablelist,
00362 const char * recipe,
00363 const char * procat,
00364 const cpl_propertylist * applist,
00365 const char * remregexp,
00366 const char * pipe_id,
00367 const char * filename)
00368 {
00369
00370 cpl_errorstate prestate = cpl_errorstate_get();
00371 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00372 : cpl_propertylist_new();
00373
00374 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00375
00376 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00377 table, tablelist, recipe, prolist, remregexp,
00378 pipe_id, filename);
00379
00380 cpl_propertylist_delete(prolist);
00381
00382 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00383
00384 return CPL_ERROR_NONE;
00385 }
00386
00387
00388
00389
00416
00417 cpl_error_code irplib_dfs_save_image_(cpl_frameset * allframes,
00418 cpl_propertylist * header,
00419 const cpl_parameterlist * parlist,
00420 const cpl_frameset * usedframes,
00421 const cpl_frame * inherit,
00422 const cpl_image * image,
00423 cpl_type type,
00424 const char * recipe,
00425 const cpl_propertylist * applist,
00426 const char * remregexp,
00427 const char * pipe_id,
00428 const char * filename)
00429 {
00430 return
00431 irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
00432 NULL, image, type, NULL, NULL, recipe,
00433 applist, remregexp, pipe_id, filename)
00434 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00435
00436 }
00437
00438
00439
00463
00464
00465 static
00466 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
00467 cpl_propertylist * header,
00468 const cpl_parameterlist * parlist,
00469 const cpl_frameset * usedframes,
00470 const cpl_frame * inherit,
00471 const cpl_imagelist * imagelist,
00472 const cpl_image * image,
00473 cpl_type type,
00474 const cpl_table * table,
00475 const cpl_propertylist * tablelist,
00476 const char * recipe,
00477 const cpl_propertylist * applist,
00478 const char * remregexp,
00479 const char * pipe_id,
00480 const char * filename) {
00481
00482 const char * procat;
00483 cpl_propertylist * plist;
00484 cpl_frame * product_frame;
00485
00486
00487
00488
00489
00490
00491 const unsigned pronum
00492 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
00493 const char * proname[] = {"imagelist", "table", "image",
00494 "propertylist"};
00495
00496 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
00497 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
00498 cpl_error_code error = CPL_ERROR_NONE;
00499
00500
00501
00502
00503 if (imagelist != NULL) {
00504 assert(pronum == 0);
00505 assert(image == NULL);
00506 assert(table == NULL);
00507 assert(tablelist == NULL);
00508 } else if (table != NULL) {
00509 assert(pronum == 1);
00510 assert(imagelist == NULL);
00511 assert(image == NULL);
00512 } else if (image != NULL) {
00513 assert(pronum == 2);
00514 assert(imagelist == NULL);
00515 assert(table == NULL);
00516 assert(tablelist == NULL);
00517 } else {
00518 assert(pronum == 3);
00519 assert(imagelist == NULL);
00520 assert(table == NULL);
00521 assert(tablelist == NULL);
00522 assert(image == NULL);
00523 }
00524
00525 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00526 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00527 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
00528 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
00529 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
00530 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00531 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
00532
00533 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
00534
00535 cpl_ensure_code(procat != NULL, cpl_error_get_code());
00536
00537 cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", proname[pronum],
00538 procat, filename);
00539
00540 product_frame = cpl_frame_new();
00541
00542
00543 error |= cpl_frame_set_filename(product_frame, filename);
00544 error |= cpl_frame_set_tag(product_frame, procat);
00545 error |= cpl_frame_set_type(product_frame, protype[pronum]);
00546 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
00547 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
00548
00549 if (error) {
00550 cpl_frame_delete(product_frame);
00551 return cpl_error_set_where(cpl_func);
00552 }
00553
00554 if (header != NULL) {
00555 cpl_propertylist_empty(header);
00556 plist = header;
00557 } else {
00558 plist = cpl_propertylist_new();
00559 }
00560
00561
00562 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
00563 applist,
00564 ".", 0);
00565
00566
00567 if (!error)
00568 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
00569 parlist, recipe, pipe_id,
00570 "PRO-1.15", inherit);
00571
00572 if (remregexp != NULL && !error) {
00573 cpl_errorstate prestate = cpl_errorstate_get();
00574 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
00575 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
00576 }
00577
00578 if (!error) {
00579 switch (pronum) {
00580 case 0:
00581 error = cpl_imagelist_save(imagelist, filename, type, plist,
00582 CPL_IO_CREATE);
00583 break;
00584 case 1:
00585 error = cpl_table_save(table, plist, tablelist, filename,
00586 CPL_IO_CREATE);
00587 break;
00588 case 2:
00589 error = cpl_image_save(image, filename, type, plist,
00590 CPL_IO_CREATE);
00591 break;
00592 default:
00593
00594 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
00595 }
00596 }
00597
00598 if (!error) {
00599
00600 error = cpl_frameset_insert(allframes, product_frame);
00601
00602 } else {
00603 cpl_frame_delete(product_frame);
00604 }
00605
00606 if (plist != header) cpl_propertylist_delete(plist);
00607
00608 cpl_ensure_code(!error, error);
00609
00610 return CPL_ERROR_NONE;
00611
00612 }
00613
00614
00615
00670
00671 cpl_error_code irplib_image_split(const cpl_image * self,
00672 cpl_image * im_low,
00673 cpl_image * im_mid,
00674 cpl_image * im_high,
00675 double th_low,
00676 cpl_boolean isleq_low,
00677 double th_high,
00678 cpl_boolean isgeq_high,
00679 double alt_low,
00680 double alt_high,
00681 cpl_boolean isbad_low,
00682 cpl_boolean isbad_mid,
00683 cpl_boolean isbad_high)
00684 {
00685
00686 const void * selfdata = cpl_image_get_data_const(self);
00687
00688
00689
00690 const cpl_boolean hasbpm
00691 = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
00692 const cpl_binary * selfbpm = hasbpm
00693 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
00694 const cpl_type selftype = cpl_image_get_type(self);
00695 const int nx = cpl_image_get_size_x(self);
00696 const int ny = cpl_image_get_size_y(self);
00697 const int npix = nx * ny;
00698 const cpl_boolean do_low = im_low != NULL;
00699 const cpl_boolean do_mid = im_mid != NULL;
00700 const cpl_boolean do_high = im_high != NULL;
00701 void * lowdata = NULL;
00702 void * middata = NULL;
00703 void * highdata = NULL;
00704 cpl_binary * lowbpm = NULL;
00705 cpl_binary * midbpm = NULL;
00706 cpl_binary * highbpm = NULL;
00707 const cpl_type lowtype
00708 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
00709 const cpl_type midtype
00710 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
00711 const cpl_type hightype
00712 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
00713 int i;
00714
00715
00716 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00717 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
00718 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
00719
00720 if (do_low) {
00721 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
00722 CPL_ERROR_INCOMPATIBLE_INPUT);
00723 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
00724 CPL_ERROR_INCOMPATIBLE_INPUT);
00725 lowdata = cpl_image_get_data(im_low);
00726 }
00727
00728 if (do_mid) {
00729 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
00730 CPL_ERROR_INCOMPATIBLE_INPUT);
00731 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
00732 CPL_ERROR_INCOMPATIBLE_INPUT);
00733 middata = cpl_image_get_data(im_mid);
00734 }
00735
00736 if (do_high) {
00737 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
00738 CPL_ERROR_INCOMPATIBLE_INPUT);
00739 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
00740 CPL_ERROR_INCOMPATIBLE_INPUT);
00741 highdata = cpl_image_get_data(im_high);
00742 }
00743
00744
00745
00746 for (i = 0; i < npix; i++) {
00747 const double value = irplib_data_get_double(selfdata, selftype, i);
00748 cpl_boolean isalt_low = do_low;
00749 cpl_boolean isalt_mid = do_mid;
00750 cpl_boolean isalt_high = do_high;
00751 cpl_boolean setbad_low = do_low;
00752 cpl_boolean setbad_mid = do_mid;
00753 cpl_boolean setbad_high = do_high;
00754 const void * setdata = NULL;
00755 double alt_mid = 0.0;
00756
00757 if (isleq_low ? value <= th_low : value < th_low) {
00758 if (do_low) {
00759 isalt_low = CPL_FALSE;
00760 irplib_data_set_double(lowdata, lowtype, i, value);
00761 setbad_low = hasbpm && selfbpm[i];
00762 setdata = lowdata;
00763 }
00764 alt_mid = alt_low;
00765 } else if (isgeq_high ? value >= th_high : value > th_high) {
00766 if (do_high) {
00767 isalt_high = CPL_FALSE;
00768 irplib_data_set_double(highdata, hightype, i, value);
00769 setbad_high = hasbpm && selfbpm[i];
00770 setdata = highdata;
00771 }
00772 alt_mid = alt_high;
00773 } else if (do_mid) {
00774 isalt_mid = CPL_FALSE;
00775 irplib_data_set_double(middata, midtype, i, value);
00776 setbad_mid = hasbpm && selfbpm[i];
00777 setdata = middata;
00778 }
00779
00780 if (isalt_low && lowdata != setdata) {
00781 irplib_data_set_double(lowdata, lowtype, i, alt_low);
00782 setbad_low = isbad_low;
00783 }
00784 if (isalt_mid && middata != setdata) {
00785 irplib_data_set_double(middata, midtype, i, alt_mid);
00786 setbad_mid = isbad_mid;
00787 }
00788 if (isalt_high && highdata != setdata) {
00789 irplib_data_set_double(highdata, hightype, i, alt_high);
00790 setbad_high = isbad_high;
00791 }
00792
00793 if (setbad_low) {
00794 if (lowbpm == NULL) lowbpm
00795 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
00796 lowbpm[i] = CPL_BINARY_1;
00797 }
00798 if (setbad_mid) {
00799 if (midbpm == NULL) midbpm
00800 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
00801 midbpm[i] = CPL_BINARY_1;
00802 }
00803 if (setbad_high) {
00804 if (highbpm == NULL) highbpm
00805 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
00806 highbpm[i] = CPL_BINARY_1;
00807 }
00808 }
00809
00810 return CPL_ERROR_NONE;
00811
00812 }
00813
00814
00815
00863
00864
00865 cpl_error_code
00866 irplib_dfs_table_convert(cpl_table * self,
00867 cpl_frameset * allframes,
00868 const cpl_frameset * useframes,
00869 int maxlinelen,
00870 char commentchar,
00871 const char * product_name,
00872 const char * procatg,
00873 const cpl_parameterlist * parlist,
00874 const char * recipe_name,
00875 const cpl_propertylist * mainlist,
00876 const cpl_propertylist * extlist,
00877 const char * remregexp,
00878 const char * instrume,
00879 const char * pipe_id,
00880 cpl_boolean (*table_set_row)
00881 (cpl_table *, const char *, int,
00882 const cpl_frame *,
00883 const cpl_parameterlist *),
00884 cpl_error_code (*table_check)
00885 (cpl_table *,
00886 const cpl_frameset *,
00887 const cpl_parameterlist *))
00888 {
00889
00890 const char * filename;
00891 cpl_propertylist * applist = NULL;
00892 cpl_errorstate prestate = cpl_errorstate_get();
00893 cpl_error_code error;
00894
00895 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00896 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00897 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00898 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
00899 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00900 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00901 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00902 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00903
00904 cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00905 maxlinelen,
00906 commentchar,
00907 parlist,
00908 table_set_row),
00909 cpl_error_get_code());
00910
00911 if (table_check != NULL && (table_check(self, useframes, parlist) ||
00912 !cpl_errorstate_is_equal(prestate))) {
00913 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00914 "Consistency check of table failed");
00915 }
00916
00917 filename = product_name != NULL
00918 ? product_name : cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00919
00920 applist = mainlist == NULL
00921 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00922
00923 error = cpl_propertylist_append_string(applist, "INSTRUME", instrume);
00924
00925 if (!error)
00926 error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00927 extlist, recipe_name, procatg, applist,
00928 remregexp, pipe_id, filename);
00929
00930 cpl_propertylist_delete(applist);
00931 if (filename != product_name) cpl_free((char*)filename);
00932
00933
00934 cpl_ensure_code(!error, error);
00935
00936 return CPL_ERROR_NONE;
00937
00938 }
00939
00940
00941
00942
00991
00992
00993 cpl_error_code
00994 irplib_table_read_from_frameset(cpl_table * self,
00995 const cpl_frameset * useframes,
00996 int maxlinelen,
00997 char commentchar,
00998 const cpl_parameterlist * parlist,
00999 cpl_boolean (*table_set_row)
01000 (cpl_table *, const char *, int,
01001 const cpl_frame *,
01002 const cpl_parameterlist *))
01003 {
01004
01005 const cpl_frame * rawframe;
01006 char * linebuffer = NULL;
01007 FILE * stream = NULL;
01008 int nfiles = 0;
01009 int nrow = cpl_table_get_nrow(self);
01010 int irow = 0;
01011 cpl_errorstate prestate = cpl_errorstate_get();
01012
01013 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
01014 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
01015 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
01016 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
01017 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
01018
01019 linebuffer = cpl_malloc(maxlinelen);
01020
01021 for (rawframe = cpl_frameset_get_first_const(useframes);
01022 rawframe != NULL;
01023 rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
01024
01025 const char * rawfile = cpl_frame_get_filename(rawframe);
01026 const char * done;
01027 const int irowpre = irow;
01028 int iirow = 0;
01029 int ierror;
01030
01031 if (rawfile == NULL) break;
01032
01033 stream = fopen(rawfile, "r");
01034
01035 if (stream == NULL) {
01036 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01037 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01038 "open %s for reading", rawfile);
01039 #else
01040 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01041 "open file for reading");
01042 #endif
01043 break;
01044 }
01045
01046 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
01047
01048 if (linebuffer[0] != commentchar) {
01049 cpl_boolean didset;
01050 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01051 const int prerow = irow;
01052 #endif
01053
01054 if (irow == nrow) {
01055 nrow += nrow ? nrow : 1;
01056 if (cpl_table_set_size(self, nrow)) break;
01057 }
01058
01059 didset = table_set_row(self, linebuffer, irow, rawframe,
01060 parlist);
01061 if (didset) irow++;
01062
01063 if (!cpl_errorstate_is_equal(prestate)) {
01064 if (didset)
01065 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01066 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01067 "Failed to set table row %d "
01068 "using line %d from %d. file %s",
01069 1+prerow, iirow+1,
01070 nfiles+1, rawfile);
01071 else
01072 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01073 "Failure with line %d from %d. "
01074 "file %s", iirow+1,
01075 nfiles+1, rawfile);
01076 #else
01077 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01078 "Failed to set table row"
01079 "using catalogue line");
01080 else
01081 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01082 "Failure with catalogue line");
01083 #endif
01084
01085 break;
01086 }
01087 }
01088 }
01089 if (done != NULL) break;
01090
01091 ierror = fclose(stream);
01092 stream = NULL;
01093 if (ierror) break;
01094
01095
01096 if (irow == irowpre)
01097 cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
01098 1+nfiles, rawfile);
01099 }
01100
01101 cpl_free(linebuffer);
01102 if (stream != NULL) fclose(stream);
01103
01104
01105 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
01106
01107 if (irow == 0) {
01108 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01109 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01110 "No usable lines in the %d input "
01111 "frame(s)", nfiles);
01112 #else
01113 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01114 "No usable lines in the input frame(s)");
01115 #endif
01116 }
01117
01118
01119 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
01120
01121 return CPL_ERROR_NONE;
01122 }
01123
01124
01125
01126
01138
01139 void irplib_reset(void)
01140 {
01141 return;
01142 }
01143
01144
01151
01152 int irplib_compare_tags(
01153 cpl_frame * frame1,
01154 cpl_frame * frame2)
01155 {
01156 char * v1 ;
01157 char * v2 ;
01158
01159
01160 if (frame1==NULL || frame2==NULL) return -1 ;
01161
01162
01163 if ((v1 = (char*)cpl_frame_get_tag(frame1)) == NULL) return -1 ;
01164 if ((v2 = (char*)cpl_frame_get_tag(frame2)) == NULL) return -1 ;
01165
01166
01167 if (strcmp(v1, v2)) return 0 ;
01168 else return 1 ;
01169 }
01170
01171
01187
01188 const char * irplib_frameset_find_file(const cpl_frameset * self,
01189 const char * tag)
01190 {
01191 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
01192
01193
01194 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01195
01196 if (frame == NULL) return NULL;
01197
01198 if (cpl_frameset_find_const(self, NULL))
01199 cpl_msg_warning(cpl_func,
01200 "Frameset has more than one file with tag: %s",
01201 tag);
01202
01203 return cpl_frame_get_filename(frame);
01204
01205 }
01206
01207
01217
01218 const
01219 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
01220 cpl_frame_group group)
01221 {
01222 const cpl_frame * frame;
01223
01224 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01225
01226 for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
01227 frame = cpl_frameset_get_next_const(self)) {
01228 if (cpl_frame_get_group(frame) == group) break;
01229 }
01230 return frame;
01231 }
01232
01233
01252
01253 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01254 int * ind, int nfind)
01255 {
01256 const int nsize = cpl_apertures_get_size(self);
01257 int ifind;
01258
01259
01260 cpl_ensure_code(nsize > 0, cpl_error_get_code());
01261 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
01262 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
01263 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01264
01265 for (ifind=0; ifind < nfind; ifind++) {
01266 double maxflux = -1;
01267 int maxind = -1;
01268 int i;
01269 for (i=1; i <= nsize; i++) {
01270 int k;
01271
01272
01273 for (k=0; k < ifind; k++) if (ind[k] == i) break;
01274
01275 if (k == ifind) {
01276
01277 const double flux = cpl_apertures_get_flux(self, i);
01278
01279 if (maxind < 0 || flux > maxflux) {
01280 maxind = i;
01281 maxflux = flux;
01282 }
01283 }
01284 }
01285 ind[ifind] = maxind;
01286 }
01287
01288 return CPL_ERROR_NONE;
01289
01290 }
01291
01292
01296
01297 int irplib_isinf(double value)
01298 {
01299 #if defined HAVE_ISINF && HAVE_ISINF
01300 return isinf(value);
01301 #else
01302 return value != 0 && value == 2 * value;
01303 #endif
01304 }
01305
01306
01310
01311 int irplib_isnan(double value)
01312 {
01313 #if defined HAVE_ISNAN && HAVE_ISNAN
01314 return isnan(value);
01315 #else
01316 return value != value;
01317 #endif
01318 }
01319
01320
01321
01322
01333
01334 void irplib_errorstate_warning(unsigned self, unsigned first, unsigned last)
01335 {
01336
01337 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01338 const unsigned newest = is_reverse ? first : last;
01339 const unsigned oldest = is_reverse ? last : first;
01340 const char * revmsg = is_reverse ? " in reverse order" : "";
01341
01342
01343 assert( oldest <= self );
01344 assert( newest >= self );
01345
01346 if (newest == 0) {
01347 cpl_msg_info(cpl_func, "No error(s) to dump");
01348 assert( oldest == 0);
01349 } else {
01350 assert( oldest > 0);
01351 assert( newest >= oldest);
01352 if (self == first) {
01353 if (oldest == 1) {
01354 cpl_msg_warning(cpl_func, "Dumping all %u error(s)%s:", newest,
01355 revmsg);
01356 } else {
01357 cpl_msg_warning(cpl_func, "Dumping the %u most recent error(s) "
01358 "out of a total of %u errors%s:",
01359 newest - oldest + 1, newest, revmsg);
01360 }
01361 cpl_msg_indent_more();
01362 }
01363
01364 cpl_msg_warning(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01365 cpl_error_get_message(), cpl_error_get_code(),
01366 cpl_error_get_where());
01367
01368 if (self == last) cpl_msg_indent_less();
01369 }
01370 }
01371
01372
01377
01388
01389 inline static
01390 double irplib_data_get_double(const void * self, cpl_type type, int i)
01391 {
01392
01393 double value;
01394
01395
01396 switch (type) {
01397 case CPL_TYPE_FLOAT:
01398 {
01399 const float * pself = (const float*)self;
01400 value = (double)pself[i];
01401 break;
01402 }
01403 case CPL_TYPE_INT:
01404 {
01405 const int * pself = (const int*)self;
01406 value = (double)pself[i];
01407 break;
01408 }
01409 default:
01410 {
01411 const double * pself = (const double*)self;
01412 value = pself[i];
01413 break;
01414 }
01415 }
01416
01417 return value;
01418
01419 }
01420
01421
01422
01433
01434 inline static
01435 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01436 {
01437
01438 switch (type) {
01439 case CPL_TYPE_FLOAT:
01440 {
01441 float * pself = (float*)self;
01442 pself[i] = (float)value;
01443 break;
01444 }
01445 case CPL_TYPE_INT:
01446 {
01447 int * pself = (int*)self;
01448 pself[i] = (int)value;
01449 break;
01450 }
01451 default:
01452 {
01453 double * pself = (double*)self;
01454 pself[i] = value;
01455 break;
01456 }
01457 }
01458 }
01459
01460
01461
01462
01463
01464
01475
01476 static
01477 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01478 const char *, ...),
01479 unsigned self, unsigned first,
01480 unsigned last)
01481 {
01482
01483 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01484 const unsigned newest = is_reverse ? first : last;
01485 const unsigned oldest = is_reverse ? last : first;
01486 const char * revmsg = is_reverse ? " in reverse order" : "";
01487
01488
01489
01490
01491
01492
01493
01494
01495 if (newest == 0) {
01496 messenger(cpl_func, "No error(s) to dump");
01497
01498 } else {
01499
01500
01501
01502
01503 if (self == first) {
01504 if (oldest == 1) {
01505 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01506 revmsg);
01507 } else {
01508 messenger(cpl_func, "Dumping the %u most recent error(s) "
01509 "out of a total of %u errors%s:",
01510 newest - oldest + 1, newest, revmsg);
01511 }
01512 cpl_msg_indent_more();
01513 }
01514
01515 messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01516 cpl_error_get_message(), cpl_error_get_code(),
01517 cpl_error_get_where());
01518
01519 if (self == last) cpl_msg_indent_less();
01520 }
01521 }
01522
01523 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01524 const cpl_vector * x_pos,
01525 const cpl_vector * values,
01526 int degree,
01527 double * rechisq
01528 )
01529 {
01530 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01531 }
01532 cpl_polynomial * irplib_polynomial_fit_1d_create(
01533 const cpl_vector * x_pos,
01534 const cpl_vector * values,
01535 int degree,
01536 double * mse
01537 )
01538 {
01539
01540 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01541 }
01542 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01543 const cpl_vector * x_pos,
01544 const cpl_vector * values,
01545 int degree,
01546 double * mse,
01547 double * rechisq
01548 )
01549 {
01550 cpl_polynomial * fit1d = NULL;
01551 cpl_size loc_degree = (cpl_size)degree ;
01552 int x_size = 0;
01553 fit1d = cpl_polynomial_new(1);
01554 x_size = cpl_vector_get_size(x_pos);
01555 if(fit1d != NULL && x_size > 1)
01556 {
01557 cpl_matrix * samppos = NULL;
01558 cpl_vector * fitresidual = NULL;
01559 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01560 samppos = cpl_matrix_wrap(1, x_size,
01561 (double*)cpl_vector_get_data_const(x_pos));
01562 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01563 fitresidual = cpl_vector_new(x_size);
01564 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01565 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01566 CPL_FALSE, NULL, &loc_degree);
01567 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01568 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, fit1d,
01569 samppos, rechisq);
01570 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01571 if (mse)
01572 {
01573 *mse = cpl_vector_product(fitresidual, fitresidual)
01574 / cpl_vector_get_size(fitresidual);
01575 }
01576 cpl_matrix_unwrap(samppos);
01577 cpl_vector_delete(fitresidual);
01578 }
01579 return fit1d;
01580 }
01581
01582 static void quicksort(int* iindex, double* exptime, int left, int right)
01583 {
01584 int i = left;
01585 int j = right;
01586 int pivot = (i + j) / 2;
01587 double index_value = exptime[pivot];
01588 do
01589 {
01590 while(exptime[i] < index_value) i++;
01591 while(exptime[j] > index_value) j--;
01592 if (i <= j)
01593 {
01594 if(i < j)
01595 {
01596 int tmp = iindex[i];
01597 double dtmp = exptime[i];
01598 iindex[i]=iindex[j];
01599 iindex[j]=tmp;
01600 exptime[i] = exptime[j];
01601 exptime[j] = dtmp;
01602 }
01603 i++;
01604 j--;
01605 }
01606 } while (i <= j);
01607
01608 if (i < right)
01609 {
01610 quicksort(iindex, exptime, i, right);
01611 }
01612 if (left < j)
01613 {
01614 quicksort(iindex, exptime,left, j);
01615 }
01616 }
01617 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
01618 {
01619 int sz = 0;
01620 int i = 0;
01621 const cpl_frame* tmp_frame = 0;
01622 cpl_error_code error = CPL_ERROR_NONE;
01623 sz = cpl_frameset_get_size(self);
01624
01625
01626 tmp_frame = cpl_frameset_get_first_const(self);
01627 while(tmp_frame)
01628 {
01629 exptime[i] = frame_get_exptime(tmp_frame);
01630 iindex[i] = i;
01631 tmp_frame = cpl_frameset_get_next_const(self);
01632 i++;
01633 }
01634
01635 quicksort(iindex, exptime, 0, sz - 1);
01636
01637 return error;
01638 }
01639
01640 static double frame_get_exptime(const cpl_frame * pframe)
01641 {
01642 cpl_propertylist *plist = 0;
01643 double dval = 0;
01644
01645 plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01646 if(plist)
01647 {
01648 cpl_error_code err = CPL_ERROR_NONE;
01649 dval = cpl_propertylist_get_double(plist, "EXPTIME");
01650 err = cpl_error_get_code();
01651 if (err != CPL_ERROR_NONE)
01652 {
01653 cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01654 }
01655 }
01656
01657 cpl_propertylist_delete(plist);
01658 return dval;
01659 }