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 #include "irplib_utils.h"
00036
00037 #include <math.h>
00038
00039 #include <string.h>
00040 #include <assert.h>
00041
00042 #include <cpl.h>
00043
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_update_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_update_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_update_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_update_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 char * fallback_filename = NULL;
00895
00896 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00897 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00898 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00899 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
00900 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00901 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00902 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00903 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00904
00905 cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00906 maxlinelen,
00907 commentchar,
00908 parlist,
00909 table_set_row),
00910 cpl_error_get_code());
00911
00912 if (table_check != NULL && (table_check(self, useframes, parlist) ||
00913 !cpl_errorstate_is_equal(prestate))) {
00914 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00915 "Consistency check of table failed");
00916 }
00917
00918 fallback_filename = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00919 filename = product_name != NULL ? product_name : fallback_filename;
00920
00921 applist = mainlist == NULL
00922 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00923
00924 error = cpl_propertylist_update_string(applist, "INSTRUME", instrume);
00925
00926 if (!error)
00927 error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00928 extlist, recipe_name, procatg, applist,
00929 remregexp, pipe_id, filename);
00930
00931 cpl_propertylist_delete(applist);
00932 cpl_free(fallback_filename);
00933
00934
00935 cpl_ensure_code(!error, error);
00936
00937 return CPL_ERROR_NONE;
00938
00939 }
00940
00941
00942
00943
00992
00993
00994 cpl_error_code
00995 irplib_table_read_from_frameset(cpl_table * self,
00996 const cpl_frameset * useframes,
00997 int maxlinelen,
00998 char commentchar,
00999 const cpl_parameterlist * parlist,
01000 cpl_boolean (*table_set_row)
01001 (cpl_table *, const char *, int,
01002 const cpl_frame *,
01003 const cpl_parameterlist *))
01004 {
01005
01006 const cpl_frame * rawframe;
01007 char * linebuffer = NULL;
01008 FILE * stream = NULL;
01009 int nfiles = 0;
01010 int nrow = cpl_table_get_nrow(self);
01011 int irow = 0;
01012 cpl_errorstate prestate = cpl_errorstate_get();
01013
01014 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
01015 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
01016 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
01017 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
01018 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
01019
01020 linebuffer = cpl_malloc(maxlinelen);
01021
01022 for (rawframe = cpl_frameset_get_first_const(useframes);
01023 rawframe != NULL;
01024 rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
01025
01026 const char * rawfile = cpl_frame_get_filename(rawframe);
01027 const char * done;
01028 const int irowpre = irow;
01029 int iirow = 0;
01030 int ierror;
01031
01032 if (rawfile == NULL) break;
01033
01034 stream = fopen(rawfile, "r");
01035
01036 if (stream == NULL) {
01037 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01038 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01039 "open %s for reading", rawfile);
01040 #else
01041 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01042 "open file for reading");
01043 #endif
01044 break;
01045 }
01046
01047 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
01048
01049 if (linebuffer[0] != commentchar) {
01050 cpl_boolean didset;
01051 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01052 const int prerow = irow;
01053 #endif
01054
01055 if (irow == nrow) {
01056 nrow += nrow ? nrow : 1;
01057 if (cpl_table_set_size(self, nrow)) break;
01058 }
01059
01060 didset = table_set_row(self, linebuffer, irow, rawframe,
01061 parlist);
01062 if (didset) irow++;
01063
01064 if (!cpl_errorstate_is_equal(prestate)) {
01065 if (didset)
01066 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01067 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01068 "Failed to set table row %d "
01069 "using line %d from %d. file %s",
01070 1+prerow, iirow+1,
01071 nfiles+1, rawfile);
01072 else
01073 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01074 "Failure with line %d from %d. "
01075 "file %s", iirow+1,
01076 nfiles+1, rawfile);
01077 #else
01078 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01079 "Failed to set table row"
01080 "using catalogue line");
01081 else
01082 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01083 "Failure with catalogue line");
01084 #endif
01085
01086 break;
01087 }
01088 }
01089 }
01090 if (done != NULL) break;
01091
01092 ierror = fclose(stream);
01093 stream = NULL;
01094 if (ierror) break;
01095
01096
01097 if (irow == irowpre)
01098 cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
01099 1+nfiles, rawfile);
01100 }
01101
01102 cpl_free(linebuffer);
01103 if (stream != NULL) fclose(stream);
01104
01105
01106 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
01107
01108 if (irow == 0) {
01109 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01110 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01111 "No usable lines in the %d input "
01112 "frame(s)", nfiles);
01113 #else
01114 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01115 "No usable lines in the input frame(s)");
01116 #endif
01117 }
01118
01119
01120 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
01121
01122 return CPL_ERROR_NONE;
01123 }
01124
01125
01126
01127
01139
01140 void irplib_reset(void)
01141 {
01142 return;
01143 }
01144
01145
01152
01153 int irplib_compare_tags(
01154 cpl_frame * frame1,
01155 cpl_frame * frame2)
01156 {
01157 const char * v1 ;
01158 const char * v2 ;
01159
01160
01161 if (frame1==NULL || frame2==NULL) return -1 ;
01162
01163
01164 if ((v1 = cpl_frame_get_tag(frame1)) == NULL) return -1 ;
01165 if ((v2 = cpl_frame_get_tag(frame2)) == NULL) return -1 ;
01166
01167
01168 if (strcmp(v1, v2)) return 0 ;
01169 else return 1 ;
01170 }
01171
01172
01188
01189 const char * irplib_frameset_find_file(const cpl_frameset * self,
01190 const char * tag)
01191 {
01192 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
01193
01194
01195 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01196
01197 if (frame == NULL) return NULL;
01198
01199 if (cpl_frameset_find_const(self, NULL))
01200 cpl_msg_warning(cpl_func,
01201 "Frameset has more than one file with tag: %s",
01202 tag);
01203
01204 return cpl_frame_get_filename(frame);
01205
01206 }
01207
01208
01218
01219 const
01220 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
01221 cpl_frame_group group)
01222 {
01223 const cpl_frame * frame;
01224
01225 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01226
01227 for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
01228 frame = cpl_frameset_get_next_const(self)) {
01229 if (cpl_frame_get_group(frame) == group) break;
01230 }
01231 return frame;
01232 }
01233
01234
01253
01254 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01255 int * ind, int nfind)
01256 {
01257 const int nsize = cpl_apertures_get_size(self);
01258 int ifind;
01259
01260
01261 cpl_ensure_code(nsize > 0, cpl_error_get_code());
01262 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
01263 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
01264 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01265
01266 for (ifind=0; ifind < nfind; ifind++) {
01267 double maxflux = -1;
01268 int maxind = -1;
01269 int i;
01270 for (i=1; i <= nsize; i++) {
01271 int k;
01272
01273
01274 for (k=0; k < ifind; k++) if (ind[k] == i) break;
01275
01276 if (k == ifind) {
01277
01278 const double flux = cpl_apertures_get_flux(self, i);
01279
01280 if (maxind < 0 || flux > maxflux) {
01281 maxind = i;
01282 maxflux = flux;
01283 }
01284 }
01285 }
01286 ind[ifind] = maxind;
01287 }
01288
01289 return CPL_ERROR_NONE;
01290
01291 }
01292
01293
01297
01298 int irplib_isinf(double value)
01299 {
01300 #if defined HAVE_ISINF && HAVE_ISINF
01301 return isinf(value);
01302 #else
01303 return value != 0 && value == 2 * value;
01304 #endif
01305 }
01306
01307
01311
01312 int irplib_isnan(double value)
01313 {
01314 #if defined HAVE_ISNAN && HAVE_ISNAN
01315 return isnan(value);
01316 #else
01317 return value != value;
01318 #endif
01319 }
01320
01325
01336
01337 inline static
01338 double irplib_data_get_double(const void * self, cpl_type type, int i)
01339 {
01340
01341 double value;
01342
01343
01344 switch (type) {
01345 case CPL_TYPE_FLOAT:
01346 {
01347 const float * pself = (const float*)self;
01348 value = (double)pself[i];
01349 break;
01350 }
01351 case CPL_TYPE_INT:
01352 {
01353 const int * pself = (const int*)self;
01354 value = (double)pself[i];
01355 break;
01356 }
01357 default:
01358 {
01359 const double * pself = (const double*)self;
01360 value = pself[i];
01361 break;
01362 }
01363 }
01364
01365 return value;
01366
01367 }
01368
01369
01370
01381
01382 inline static
01383 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01384 {
01385
01386 switch (type) {
01387 case CPL_TYPE_FLOAT:
01388 {
01389 float * pself = (float*)self;
01390 pself[i] = (float)value;
01391 break;
01392 }
01393 case CPL_TYPE_INT:
01394 {
01395 int * pself = (int*)self;
01396 pself[i] = (int)value;
01397 break;
01398 }
01399 default:
01400 {
01401 double * pself = (double*)self;
01402 pself[i] = value;
01403 break;
01404 }
01405 }
01406 }
01407
01408
01409
01410
01411
01412
01423
01424 static
01425 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01426 const char *, ...),
01427 unsigned self, unsigned first,
01428 unsigned last)
01429 {
01430
01431 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01432 const unsigned newest = is_reverse ? first : last;
01433 const unsigned oldest = is_reverse ? last : first;
01434 const char * revmsg = is_reverse ? " in reverse order" : "";
01435
01436
01437
01438
01439
01440
01441
01442
01443 if (newest == 0) {
01444 messenger(cpl_func, "No error(s) to dump");
01445
01446 } else {
01447
01448
01449
01450
01451 if (self == first) {
01452 if (oldest == 1) {
01453 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01454 revmsg);
01455 } else {
01456 messenger(cpl_func, "Dumping the %u most recent error(s) "
01457 "out of a total of %u errors%s:",
01458 newest - oldest + 1, newest, revmsg);
01459 }
01460 cpl_msg_indent_more();
01461 }
01462
01463 messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01464 cpl_error_get_message(), cpl_error_get_code(),
01465 cpl_error_get_where());
01466
01467 if (self == last) cpl_msg_indent_less();
01468 }
01469 }
01470
01471 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01472 const cpl_vector * x_pos,
01473 const cpl_vector * values,
01474 int degree,
01475 double * rechisq
01476 )
01477 {
01478 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01479 }
01480 cpl_polynomial * irplib_polynomial_fit_1d_create(
01481 const cpl_vector * x_pos,
01482 const cpl_vector * values,
01483 int degree,
01484 double * mse
01485 )
01486 {
01487
01488 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01489 }
01490 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01491 const cpl_vector * x_pos,
01492 const cpl_vector * values,
01493 int degree,
01494 double * mse,
01495 double * rechisq
01496 )
01497 {
01498 cpl_polynomial * fit1d = NULL;
01499 cpl_size loc_degree = (cpl_size)degree ;
01500 int x_size = 0;
01501 fit1d = cpl_polynomial_new(1);
01502 x_size = cpl_vector_get_size(x_pos);
01503 if(fit1d != NULL && x_size > 1)
01504 {
01505 cpl_matrix * samppos = NULL;
01506 cpl_vector * fitresidual = NULL;
01507 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01508 samppos = cpl_matrix_wrap(1, x_size,
01509 (double*)cpl_vector_get_data_const(x_pos));
01510 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01511 fitresidual = cpl_vector_new(x_size);
01512 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01513 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01514 CPL_FALSE, NULL, &loc_degree);
01515 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01516 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
01517 fit1d, samppos, rechisq);
01518 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01519 if (mse)
01520 {
01521 *mse = cpl_vector_product(fitresidual, fitresidual)
01522 / cpl_vector_get_size(fitresidual);
01523 }
01524 cpl_matrix_unwrap(samppos);
01525 cpl_vector_delete(fitresidual);
01526 }
01527 return fit1d;
01528 }
01529
01530 static void quicksort(int* iindex, double* exptime, int left, int right)
01531 {
01532 int i = left;
01533 int j = right;
01534 int pivot = (i + j) / 2;
01535 double index_value = exptime[pivot];
01536 do
01537 {
01538 while(exptime[i] < index_value) i++;
01539 while(exptime[j] > index_value) j--;
01540 if (i <= j)
01541 {
01542 if(i < j)
01543 {
01544 int tmp = iindex[i];
01545 double dtmp = exptime[i];
01546 iindex[i]=iindex[j];
01547 iindex[j]=tmp;
01548 exptime[i] = exptime[j];
01549 exptime[j] = dtmp;
01550 }
01551 i++;
01552 j--;
01553 }
01554 } while (i <= j);
01555
01556 if (i < right)
01557 {
01558 quicksort(iindex, exptime, i, right);
01559 }
01560 if (left < j)
01561 {
01562 quicksort(iindex, exptime,left, j);
01563 }
01564 }
01565 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
01566 {
01567 int sz = 0;
01568 int i = 0;
01569 const cpl_frame* tmp_frame = 0;
01570 cpl_error_code error = CPL_ERROR_NONE;
01571 sz = cpl_frameset_get_size(self);
01572
01573
01574 tmp_frame = cpl_frameset_get_first_const(self);
01575 while(tmp_frame)
01576 {
01577 exptime[i] = frame_get_exptime(tmp_frame);
01578 iindex[i] = i;
01579 tmp_frame = cpl_frameset_get_next_const(self);
01580 i++;
01581 }
01582
01583 quicksort(iindex, exptime, 0, sz - 1);
01584
01585 return error;
01586 }
01587
01588 static double frame_get_exptime(const cpl_frame * pframe)
01589 {
01590 cpl_propertylist *plist = 0;
01591 double dval = 0;
01592
01593 plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01594 if(plist)
01595 {
01596 cpl_error_code err = CPL_ERROR_NONE;
01597 dval = cpl_propertylist_get_double(plist, "EXPTIME");
01598 err = cpl_error_get_code();
01599 if (err != CPL_ERROR_NONE)
01600 {
01601 cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01602 }
01603 }
01604
01605 cpl_propertylist_delete(plist);
01606 return dval;
01607 }