00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037
00038 #include <string.h>
00039 #include <assert.h>
00040
00041 #include <cpl.h>
00042
00043 #include "irplib_utils.h"
00044
00045
00046
00047
00048
00049 #ifndef inline
00050 #define inline
00051 #endif
00052
00053
00054
00055
00056
00057 #if defined HAVE_ISNAN && HAVE_ISNAN != 0
00058 #if !defined isnan && defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 0
00059
00060
00061 int isnan(double);
00062 #endif
00063 #endif
00064
00065
00066
00067
00068
00069 inline static double irplib_data_get_double(const void *, cpl_type, int)
00070 #ifdef CPL_HAVE_GNUC_NONNULL
00071 __attribute__((nonnull))
00072 #endif
00073 ;
00074
00075 inline static void irplib_data_set_double(void *, cpl_type, int, double)
00076 #ifdef CPL_HAVE_GNUC_NONNULL
00077 __attribute__((nonnull))
00078 #endif
00079 ;
00080
00081
00082 static
00083 void irplib_errorstate_dump_one_level(void (*)(const char *,
00084 const char *, ...)
00085 #ifdef __GNUC__
00086 __attribute__((format (printf, 2, 3)))
00087 #endif
00088 , unsigned, unsigned, unsigned);
00089 static double frame_get_exptime(const cpl_frame * pframe);
00090 static void quicksort(int* index, double* exptime, int left, int right);
00091
00092 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
00093 cpl_propertylist *,
00094 const cpl_parameterlist *,
00095 const cpl_frameset *,
00096 const cpl_frame *,
00097 const cpl_imagelist *,
00098 const cpl_image *,
00099 cpl_type,
00100 const cpl_table *,
00101 const cpl_propertylist *,
00102 const char *,
00103 const cpl_propertylist *,
00104 const char *,
00105 const char *,
00106 const char *);
00107
00108
00112
00116
00128
00129 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
00130 unsigned last)
00131 {
00132
00133 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
00134
00135 }
00136
00137 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
00138 const cpl_vector * x_pos,
00139 const cpl_vector * values,
00140 int degree,
00141 double * mse,
00142 double * rechisq
00143 );
00144
00145
00155
00156 void irplib_errorstate_dump_info(unsigned self, unsigned first,
00157 unsigned last)
00158 {
00159
00160 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
00161
00162 }
00163
00164
00165
00175
00176 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
00177 unsigned last)
00178 {
00179
00180 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
00181
00182 }
00183
00184
00185
00206
00207 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
00208 const cpl_parameterlist * parlist,
00209 const cpl_frameset * usedframes,
00210 const cpl_image * image,
00211 cpl_type_bpp bpp,
00212 const char * recipe,
00213 const char * procat,
00214 const cpl_propertylist * applist,
00215 const char * remregexp,
00216 const char * pipe_id,
00217 const char * filename)
00218 {
00219 cpl_errorstate prestate = cpl_errorstate_get();
00220 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00221 : cpl_propertylist_new();
00222
00223 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00224
00225 irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
00226 bpp, recipe, prolist, remregexp, pipe_id, filename);
00227
00228 cpl_propertylist_delete(prolist);
00229
00230 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00231
00232 return CPL_ERROR_NONE;
00233
00234 }
00235
00236
00253
00254 cpl_error_code
00255 irplib_dfs_save_propertylist(cpl_frameset * allframes,
00256 const cpl_parameterlist * parlist,
00257 const cpl_frameset * usedframes,
00258 const char * recipe,
00259 const char * procat,
00260 const cpl_propertylist * applist,
00261 const char * remregexp,
00262 const char * pipe_id,
00263 const char * filename)
00264 {
00265 cpl_errorstate prestate = cpl_errorstate_get();
00266 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00267 : cpl_propertylist_new();
00268
00269 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00270
00271 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00272 recipe, prolist, remregexp, pipe_id, filename);
00273
00274 cpl_propertylist_delete(prolist);
00275
00276 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00277
00278 return CPL_ERROR_NONE;
00279
00280 }
00281
00282
00301
00302 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
00303 const cpl_parameterlist * parlist,
00304 const cpl_frameset * usedframes,
00305 const cpl_imagelist * imagelist,
00306 cpl_type_bpp bpp,
00307 const char * recipe,
00308 const char * procat,
00309 const cpl_propertylist * applist,
00310 const char * remregexp,
00311 const char * pipe_id,
00312 const char * filename)
00313 {
00314 cpl_errorstate prestate = cpl_errorstate_get();
00315 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00316 : cpl_propertylist_new();
00317
00318 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00319
00320 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00321 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00322 filename);
00323
00324 cpl_propertylist_delete(prolist);
00325
00326 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00327
00328 return CPL_ERROR_NONE;
00329 }
00330
00331
00349
00350 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
00351 const cpl_parameterlist * parlist,
00352 const cpl_frameset * usedframes,
00353 const cpl_table * table,
00354 const cpl_propertylist * tablelist,
00355 const char * recipe,
00356 const char * procat,
00357 const cpl_propertylist * applist,
00358 const char * remregexp,
00359 const char * pipe_id,
00360 const char * filename)
00361 {
00362
00363 cpl_errorstate prestate = cpl_errorstate_get();
00364 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00365 : cpl_propertylist_new();
00366
00367 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00368
00369 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00370 table, tablelist, recipe, prolist, remregexp,
00371 pipe_id, filename);
00372
00373 cpl_propertylist_delete(prolist);
00374
00375 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00376
00377 return CPL_ERROR_NONE;
00378 }
00379
00380
00381
00382
00409
00410 cpl_error_code irplib_dfs_save_image_(cpl_frameset * allframes,
00411 cpl_propertylist * header,
00412 const cpl_parameterlist * parlist,
00413 const cpl_frameset * usedframes,
00414 const cpl_frame * inherit,
00415 const cpl_image * image,
00416 cpl_type type,
00417 const char * recipe,
00418 const cpl_propertylist * applist,
00419 const char * remregexp,
00420 const char * pipe_id,
00421 const char * filename)
00422 {
00423 return
00424 irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
00425 NULL, image, type, NULL, NULL, recipe,
00426 applist, remregexp, pipe_id, filename)
00427 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00428
00429 }
00430
00431
00432
00456
00457
00458 static
00459 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
00460 cpl_propertylist * header,
00461 const cpl_parameterlist * parlist,
00462 const cpl_frameset * usedframes,
00463 const cpl_frame * inherit,
00464 const cpl_imagelist * imagelist,
00465 const cpl_image * image,
00466 cpl_type type,
00467 const cpl_table * table,
00468 const cpl_propertylist * tablelist,
00469 const char * recipe,
00470 const cpl_propertylist * applist,
00471 const char * remregexp,
00472 const char * pipe_id,
00473 const char * filename) {
00474
00475 const char * procat;
00476 cpl_propertylist * plist;
00477 cpl_frame * product_frame;
00478
00479
00480
00481
00482
00483
00484 const unsigned pronum
00485 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
00486 const char * proname[] = {"imagelist", "table", "image",
00487 "propertylist"};
00488
00489 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
00490 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
00491 cpl_error_code error = CPL_ERROR_NONE;
00492
00493
00494
00495
00496 if (imagelist != NULL) {
00497 assert(pronum == 0);
00498 assert(image == NULL);
00499 assert(table == NULL);
00500 assert(tablelist == NULL);
00501 } else if (table != NULL) {
00502 assert(pronum == 1);
00503 assert(imagelist == NULL);
00504 assert(image == NULL);
00505 } else if (image != NULL) {
00506 assert(pronum == 2);
00507 assert(imagelist == NULL);
00508 assert(table == NULL);
00509 assert(tablelist == NULL);
00510 } else {
00511 assert(pronum == 3);
00512 assert(imagelist == NULL);
00513 assert(table == NULL);
00514 assert(tablelist == NULL);
00515 assert(image == NULL);
00516 }
00517
00518 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00519 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00520 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
00521 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
00522 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
00523 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00524 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
00525
00526 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
00527
00528 cpl_ensure_code(procat != NULL, cpl_error_get_code());
00529
00530 cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", proname[pronum],
00531 procat, filename);
00532
00533 product_frame = cpl_frame_new();
00534
00535
00536 error |= cpl_frame_set_filename(product_frame, filename);
00537 error |= cpl_frame_set_tag(product_frame, procat);
00538 error |= cpl_frame_set_type(product_frame, protype[pronum]);
00539 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
00540 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
00541
00542 if (error) {
00543 cpl_frame_delete(product_frame);
00544 return cpl_error_set_where(cpl_func);
00545 }
00546
00547 if (header != NULL) {
00548 cpl_propertylist_empty(header);
00549 plist = header;
00550 } else {
00551 plist = cpl_propertylist_new();
00552 }
00553
00554
00555 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
00556 applist,
00557 ".", 0);
00558
00559
00560 if (!error)
00561 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
00562 parlist, recipe, pipe_id,
00563 "PRO-1.15", inherit);
00564
00565 if (remregexp != NULL && !error) {
00566 cpl_errorstate prestate = cpl_errorstate_get();
00567 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
00568 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
00569 }
00570
00571 if (!error) {
00572 switch (pronum) {
00573 case 0:
00574 error = cpl_imagelist_save(imagelist, filename, type, plist,
00575 CPL_IO_CREATE);
00576 break;
00577 case 1:
00578 error = cpl_table_save(table, plist, tablelist, filename,
00579 CPL_IO_CREATE);
00580 break;
00581 case 2:
00582 error = cpl_image_save(image, filename, type, plist,
00583 CPL_IO_CREATE);
00584 break;
00585 default:
00586
00587 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
00588 }
00589 }
00590
00591 if (!error) {
00592
00593 error = cpl_frameset_insert(allframes, product_frame);
00594
00595 } else {
00596 cpl_frame_delete(product_frame);
00597 }
00598
00599 if (plist != header) cpl_propertylist_delete(plist);
00600
00601 cpl_ensure_code(!error, error);
00602
00603 return CPL_ERROR_NONE;
00604
00605 }
00606
00607
00608
00663
00664 cpl_error_code irplib_image_split(const cpl_image * self,
00665 cpl_image * im_low,
00666 cpl_image * im_mid,
00667 cpl_image * im_high,
00668 double th_low,
00669 cpl_boolean isleq_low,
00670 double th_high,
00671 cpl_boolean isgeq_high,
00672 double alt_low,
00673 double alt_high,
00674 cpl_boolean isbad_low,
00675 cpl_boolean isbad_mid,
00676 cpl_boolean isbad_high)
00677 {
00678
00679 const void * selfdata = cpl_image_get_data_const(self);
00680
00681
00682
00683 const cpl_boolean hasbpm
00684 = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
00685 const cpl_binary * selfbpm = hasbpm
00686 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
00687 const cpl_type selftype = cpl_image_get_type(self);
00688 const int nx = cpl_image_get_size_x(self);
00689 const int ny = cpl_image_get_size_y(self);
00690 const int npix = nx * ny;
00691 const cpl_boolean do_low = im_low != NULL;
00692 const cpl_boolean do_mid = im_mid != NULL;
00693 const cpl_boolean do_high = im_high != NULL;
00694 void * lowdata = NULL;
00695 void * middata = NULL;
00696 void * highdata = NULL;
00697 cpl_binary * lowbpm = NULL;
00698 cpl_binary * midbpm = NULL;
00699 cpl_binary * highbpm = NULL;
00700 const cpl_type lowtype
00701 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
00702 const cpl_type midtype
00703 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
00704 const cpl_type hightype
00705 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
00706 int i;
00707
00708
00709 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00710 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
00711 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
00712
00713 if (do_low) {
00714 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
00715 CPL_ERROR_INCOMPATIBLE_INPUT);
00716 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
00717 CPL_ERROR_INCOMPATIBLE_INPUT);
00718 lowdata = cpl_image_get_data(im_low);
00719 }
00720
00721 if (do_mid) {
00722 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
00723 CPL_ERROR_INCOMPATIBLE_INPUT);
00724 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
00725 CPL_ERROR_INCOMPATIBLE_INPUT);
00726 middata = cpl_image_get_data(im_mid);
00727 }
00728
00729 if (do_high) {
00730 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
00731 CPL_ERROR_INCOMPATIBLE_INPUT);
00732 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
00733 CPL_ERROR_INCOMPATIBLE_INPUT);
00734 highdata = cpl_image_get_data(im_high);
00735 }
00736
00737
00738
00739 for (i = 0; i < npix; i++) {
00740 const double value = irplib_data_get_double(selfdata, selftype, i);
00741 cpl_boolean isalt_low = do_low;
00742 cpl_boolean isalt_mid = do_mid;
00743 cpl_boolean isalt_high = do_high;
00744 cpl_boolean setbad_low = do_low;
00745 cpl_boolean setbad_mid = do_mid;
00746 cpl_boolean setbad_high = do_high;
00747 const void * setdata = NULL;
00748 double alt_mid = 0.0;
00749
00750 if (isleq_low ? value <= th_low : value < th_low) {
00751 if (do_low) {
00752 isalt_low = CPL_FALSE;
00753 irplib_data_set_double(lowdata, lowtype, i, value);
00754 setbad_low = hasbpm && selfbpm[i];
00755 setdata = lowdata;
00756 }
00757 alt_mid = alt_low;
00758 } else if (isgeq_high ? value >= th_high : value > th_high) {
00759 if (do_high) {
00760 isalt_high = CPL_FALSE;
00761 irplib_data_set_double(highdata, hightype, i, value);
00762 setbad_high = hasbpm && selfbpm[i];
00763 setdata = highdata;
00764 }
00765 alt_mid = alt_high;
00766 } else if (do_mid) {
00767 isalt_mid = CPL_FALSE;
00768 irplib_data_set_double(middata, midtype, i, value);
00769 setbad_mid = hasbpm && selfbpm[i];
00770 setdata = middata;
00771 }
00772
00773 if (isalt_low && lowdata != setdata) {
00774 irplib_data_set_double(lowdata, lowtype, i, alt_low);
00775 setbad_low = isbad_low;
00776 }
00777 if (isalt_mid && middata != setdata) {
00778 irplib_data_set_double(middata, midtype, i, alt_mid);
00779 setbad_mid = isbad_mid;
00780 }
00781 if (isalt_high && highdata != setdata) {
00782 irplib_data_set_double(highdata, hightype, i, alt_high);
00783 setbad_high = isbad_high;
00784 }
00785
00786 if (setbad_low) {
00787 if (lowbpm == NULL) lowbpm
00788 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
00789 lowbpm[i] = CPL_BINARY_1;
00790 }
00791 if (setbad_mid) {
00792 if (midbpm == NULL) midbpm
00793 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
00794 midbpm[i] = CPL_BINARY_1;
00795 }
00796 if (setbad_high) {
00797 if (highbpm == NULL) highbpm
00798 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
00799 highbpm[i] = CPL_BINARY_1;
00800 }
00801 }
00802
00803 return CPL_ERROR_NONE;
00804
00805 }
00806
00807
00808
00856
00857
00858 cpl_error_code
00859 irplib_dfs_table_convert(cpl_table * self,
00860 cpl_frameset * allframes,
00861 const cpl_frameset * useframes,
00862 int maxlinelen,
00863 char commentchar,
00864 const char * product_name,
00865 const char * procatg,
00866 const cpl_parameterlist * parlist,
00867 const char * recipe_name,
00868 const cpl_propertylist * mainlist,
00869 const cpl_propertylist * extlist,
00870 const char * remregexp,
00871 const char * instrume,
00872 const char * pipe_id,
00873 cpl_boolean (*table_set_row)
00874 (cpl_table *, const char *, int,
00875 const cpl_frame *,
00876 const cpl_parameterlist *),
00877 cpl_error_code (*table_check)
00878 (cpl_table *,
00879 const cpl_frameset *,
00880 const cpl_parameterlist *))
00881 {
00882
00883 const char * filename;
00884 cpl_propertylist * applist = NULL;
00885 cpl_errorstate prestate = cpl_errorstate_get();
00886 cpl_error_code error;
00887
00888 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00889 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00890 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00891 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
00892 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00893 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00894 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00895 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00896
00897 cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00898 maxlinelen,
00899 commentchar,
00900 parlist,
00901 table_set_row),
00902 cpl_error_get_code());
00903
00904 if (table_check != NULL && (table_check(self, useframes, parlist) ||
00905 !cpl_errorstate_is_equal(prestate))) {
00906 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00907 "Consistency check of table failed");
00908 }
00909
00910 filename = product_name != NULL
00911 ? product_name : cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00912
00913 applist = mainlist == NULL
00914 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00915
00916 error = cpl_propertylist_append_string(applist, "INSTRUME", instrume);
00917
00918 if (!error)
00919 error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00920 extlist, recipe_name, procatg, applist,
00921 remregexp, pipe_id, filename);
00922
00923 cpl_propertylist_delete(applist);
00924 if (filename != product_name) cpl_free((char*)filename);
00925
00926
00927 cpl_ensure_code(!error, error);
00928
00929 return CPL_ERROR_NONE;
00930
00931 }
00932
00933
00934
00935
00984
00985
00986 cpl_error_code
00987 irplib_table_read_from_frameset(cpl_table * self,
00988 const cpl_frameset * useframes,
00989 int maxlinelen,
00990 char commentchar,
00991 const cpl_parameterlist * parlist,
00992 cpl_boolean (*table_set_row)
00993 (cpl_table *, const char *, int,
00994 const cpl_frame *,
00995 const cpl_parameterlist *))
00996 {
00997
00998 const cpl_frame * rawframe;
00999 char * linebuffer = NULL;
01000 FILE * stream = NULL;
01001 int nfiles = 0;
01002 int nrow = cpl_table_get_nrow(self);
01003 int irow = 0;
01004 cpl_errorstate prestate = cpl_errorstate_get();
01005
01006 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
01007 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
01008 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
01009 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
01010 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
01011
01012 linebuffer = cpl_malloc(maxlinelen);
01013
01014 for (rawframe = cpl_frameset_get_first_const(useframes);
01015 rawframe != NULL;
01016 rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
01017
01018 const char * rawfile = cpl_frame_get_filename(rawframe);
01019 const char * done;
01020 const int irowpre = irow;
01021 int iirow = 0;
01022 int ierror;
01023
01024 if (rawfile == NULL) break;
01025
01026 stream = fopen(rawfile, "r");
01027
01028 if (stream == NULL) {
01029 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01030 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01031 "open %s for reading", rawfile);
01032 #else
01033 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01034 "open file for reading");
01035 #endif
01036 break;
01037 }
01038
01039 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
01040
01041 if (linebuffer[0] != commentchar) {
01042 cpl_boolean didset;
01043 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01044 const int prerow = irow;
01045 #endif
01046
01047 if (irow == nrow) {
01048 nrow += nrow ? nrow : 1;
01049 if (cpl_table_set_size(self, nrow)) break;
01050 }
01051
01052 didset = table_set_row(self, linebuffer, irow, rawframe,
01053 parlist);
01054 if (didset) irow++;
01055
01056 if (!cpl_errorstate_is_equal(prestate)) {
01057 if (didset)
01058 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01059 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01060 "Failed to set table row %d "
01061 "using line %d from %d. file %s",
01062 1+prerow, iirow+1,
01063 nfiles+1, rawfile);
01064 else
01065 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01066 "Failure with line %d from %d. "
01067 "file %s", iirow+1,
01068 nfiles+1, rawfile);
01069 #else
01070 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01071 "Failed to set table row"
01072 "using catalogue line");
01073 else
01074 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01075 "Failure with catalogue line");
01076 #endif
01077
01078 break;
01079 }
01080 }
01081 }
01082 if (done != NULL) break;
01083
01084 ierror = fclose(stream);
01085 stream = NULL;
01086 if (ierror) break;
01087
01088
01089 if (irow == irowpre)
01090 cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
01091 1+nfiles, rawfile);
01092 }
01093
01094 cpl_free(linebuffer);
01095 if (stream != NULL) fclose(stream);
01096
01097
01098 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
01099
01100 if (irow == 0) {
01101 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01102 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01103 "No usable lines in the %d input "
01104 "frame(s)", nfiles);
01105 #else
01106 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01107 "No usable lines in the input frame(s)");
01108 #endif
01109 }
01110
01111
01112 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
01113
01114 return CPL_ERROR_NONE;
01115 }
01116
01117
01118
01119
01131
01132 void irplib_reset(void)
01133 {
01134 return;
01135 }
01136
01137
01144
01145 int irplib_compare_tags(
01146 cpl_frame * frame1,
01147 cpl_frame * frame2)
01148 {
01149 char * v1 ;
01150 char * v2 ;
01151
01152
01153 if (frame1==NULL || frame2==NULL) return -1 ;
01154
01155
01156 if ((v1 = (char*)cpl_frame_get_tag(frame1)) == NULL) return -1 ;
01157 if ((v2 = (char*)cpl_frame_get_tag(frame2)) == NULL) return -1 ;
01158
01159
01160 if (strcmp(v1, v2)) return 0 ;
01161 else return 1 ;
01162 }
01163
01164
01180
01181 const char * irplib_frameset_find_file(const cpl_frameset * self,
01182 const char * tag)
01183 {
01184 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
01185
01186
01187 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01188
01189 if (frame == NULL) return NULL;
01190
01191 if (cpl_frameset_find_const(self, NULL))
01192 cpl_msg_warning(cpl_func,
01193 "Frameset has more than one file with tag: %s",
01194 tag);
01195
01196 return cpl_frame_get_filename(frame);
01197
01198 }
01199
01200
01210
01211 const
01212 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
01213 cpl_frame_group group)
01214 {
01215 const cpl_frame * frame;
01216
01217 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01218
01219 for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
01220 frame = cpl_frameset_get_next_const(self)) {
01221 if (cpl_frame_get_group(frame) == group) break;
01222 }
01223 return frame;
01224 }
01225
01226
01245
01246 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01247 int * ind, int nfind)
01248 {
01249 const int nsize = cpl_apertures_get_size(self);
01250 int ifind;
01251
01252
01253 cpl_ensure_code(nsize > 0, cpl_error_get_code());
01254 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
01255 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
01256 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01257
01258 for (ifind=0; ifind < nfind; ifind++) {
01259 double maxflux = -1;
01260 int maxind = -1;
01261 int i;
01262 for (i=1; i <= nsize; i++) {
01263 int k;
01264
01265
01266 for (k=0; k < ifind; k++) if (ind[k] == i) break;
01267
01268 if (k == ifind) {
01269
01270 const double flux = cpl_apertures_get_flux(self, i);
01271
01272 if (maxind < 0 || flux > maxflux) {
01273 maxind = i;
01274 maxflux = flux;
01275 }
01276 }
01277 }
01278 ind[ifind] = maxind;
01279 }
01280
01281 return CPL_ERROR_NONE;
01282
01283 }
01284
01285
01289
01290 int irplib_isinf(double value)
01291 {
01292 #if defined HAVE_ISINF && HAVE_ISINF
01293 return isinf(value);
01294 #else
01295 return value != 0 && value == 2 * value;
01296 #endif
01297 }
01298
01299
01303
01304 int irplib_isnan(double value)
01305 {
01306 #if defined HAVE_ISNAN && HAVE_ISNAN
01307 return isnan(value);
01308 #else
01309 return value != value;
01310 #endif
01311 }
01312
01313
01314
01315
01326
01327 void irplib_errorstate_warning(unsigned self, unsigned first, unsigned last)
01328 {
01329
01330 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01331 const unsigned newest = is_reverse ? first : last;
01332 const unsigned oldest = is_reverse ? last : first;
01333 const char * revmsg = is_reverse ? " in reverse order" : "";
01334
01335
01336 assert( oldest <= self );
01337 assert( newest >= self );
01338
01339 if (newest == 0) {
01340 cpl_msg_info(cpl_func, "No error(s) to dump");
01341 assert( oldest == 0);
01342 } else {
01343 assert( oldest > 0);
01344 assert( newest >= oldest);
01345 if (self == first) {
01346 if (oldest == 1) {
01347 cpl_msg_warning(cpl_func, "Dumping all %u error(s)%s:", newest,
01348 revmsg);
01349 } else {
01350 cpl_msg_warning(cpl_func, "Dumping the %u most recent error(s) "
01351 "out of a total of %u errors%s:",
01352 newest - oldest + 1, newest, revmsg);
01353 }
01354 cpl_msg_indent_more();
01355 }
01356
01357 cpl_msg_warning(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01358 cpl_error_get_message(), cpl_error_get_code(),
01359 cpl_error_get_where());
01360
01361 if (self == last) cpl_msg_indent_less();
01362 }
01363 }
01364
01365
01370
01381
01382 inline static
01383 double irplib_data_get_double(const void * self, cpl_type type, int i)
01384 {
01385
01386 double value;
01387
01388
01389 switch (type) {
01390 case CPL_TYPE_FLOAT:
01391 {
01392 const float * pself = (const float*)self;
01393 value = (double)pself[i];
01394 break;
01395 }
01396 case CPL_TYPE_INT:
01397 {
01398 const int * pself = (const int*)self;
01399 value = (double)pself[i];
01400 break;
01401 }
01402 default:
01403 {
01404 const double * pself = (const double*)self;
01405 value = pself[i];
01406 break;
01407 }
01408 }
01409
01410 return value;
01411
01412 }
01413
01414
01415
01426
01427 inline static
01428 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01429 {
01430
01431 switch (type) {
01432 case CPL_TYPE_FLOAT:
01433 {
01434 float * pself = (float*)self;
01435 pself[i] = (float)value;
01436 break;
01437 }
01438 case CPL_TYPE_INT:
01439 {
01440 int * pself = (int*)self;
01441 pself[i] = (int)value;
01442 break;
01443 }
01444 default:
01445 {
01446 double * pself = (double*)self;
01447 pself[i] = value;
01448 break;
01449 }
01450 }
01451 }
01452
01453
01454
01455
01456
01457
01468
01469 static
01470 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01471 const char *, ...),
01472 unsigned self, unsigned first,
01473 unsigned last)
01474 {
01475
01476 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01477 const unsigned newest = is_reverse ? first : last;
01478 const unsigned oldest = is_reverse ? last : first;
01479 const char * revmsg = is_reverse ? " in reverse order" : "";
01480
01481
01482
01483
01484
01485
01486
01487
01488 if (newest == 0) {
01489 messenger(cpl_func, "No error(s) to dump");
01490
01491 } else {
01492
01493
01494
01495
01496 if (self == first) {
01497 if (oldest == 1) {
01498 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01499 revmsg);
01500 } else {
01501 messenger(cpl_func, "Dumping the %u most recent error(s) "
01502 "out of a total of %u errors%s:",
01503 newest - oldest + 1, newest, revmsg);
01504 }
01505 cpl_msg_indent_more();
01506 }
01507
01508 messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01509 cpl_error_get_message(), cpl_error_get_code(),
01510 cpl_error_get_where());
01511
01512 if (self == last) cpl_msg_indent_less();
01513 }
01514 }
01515
01516 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01517 const cpl_vector * x_pos,
01518 const cpl_vector * values,
01519 int degree,
01520 double * rechisq
01521 )
01522 {
01523 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01524 }
01525 cpl_polynomial * irplib_polynomial_fit_1d_create(
01526 const cpl_vector * x_pos,
01527 const cpl_vector * values,
01528 int degree,
01529 double * mse
01530 )
01531 {
01532
01533 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01534 }
01535 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01536 const cpl_vector * x_pos,
01537 const cpl_vector * values,
01538 int degree,
01539 double * mse,
01540 double * rechisq
01541 )
01542 {
01543 cpl_polynomial * fit1d = NULL;
01544 int x_size = 0;
01545 fit1d = cpl_polynomial_new(1);
01546 x_size = cpl_vector_get_size(x_pos);
01547 if(fit1d != NULL && x_size > 1)
01548 {
01549 cpl_matrix * samppos = NULL;
01550 cpl_vector * fitresidual = NULL;
01551 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01552 samppos = cpl_matrix_wrap(1, x_size,
01553 (double*)cpl_vector_get_data_const(x_pos));
01554 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01555 fitresidual = cpl_vector_new(x_size);
01556 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01557 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01558 CPL_FALSE, NULL, °ree);
01559 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01560 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, fit1d,
01561 samppos, rechisq);
01562 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01563 if (mse)
01564 {
01565 *mse = cpl_vector_product(fitresidual, fitresidual)
01566 / cpl_vector_get_size(fitresidual);
01567 }
01568 cpl_matrix_unwrap(samppos);
01569 cpl_vector_delete(fitresidual);
01570 }
01571 return fit1d;
01572 }
01573
01574 static void quicksort(int* iindex, double* exptime, int left, int right)
01575 {
01576 int i = left;
01577 int j = right;
01578 int pivot = (i + j) / 2;
01579 double index_value = exptime[pivot];
01580 do
01581 {
01582 while(exptime[i] < index_value) i++;
01583 while(exptime[j] > index_value) j--;
01584 if (i <= j)
01585 {
01586 if(i < j)
01587 {
01588 int tmp = iindex[i];
01589 double dtmp = exptime[i];
01590 iindex[i]=iindex[j];
01591 iindex[j]=tmp;
01592 exptime[i] = exptime[j];
01593 exptime[j] = dtmp;
01594 }
01595 i++;
01596 j--;
01597 }
01598 } while (i <= j);
01599
01600 if (i < right)
01601 {
01602 quicksort(iindex, exptime, i, right);
01603 }
01604 if (left < j)
01605 {
01606 quicksort(iindex, exptime,left, j);
01607 }
01608 }
01609 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
01610 {
01611 int sz = 0;
01612 int i = 0;
01613 const cpl_frame* tmp_frame = 0;
01614 cpl_error_code error = CPL_ERROR_NONE;
01615 sz = cpl_frameset_get_size(self);
01616
01617
01618 tmp_frame = cpl_frameset_get_first_const(self);
01619 while(tmp_frame)
01620 {
01621 exptime[i] = frame_get_exptime(tmp_frame);
01622 iindex[i] = i;
01623 tmp_frame = cpl_frameset_get_next_const(self);
01624 i++;
01625 }
01626
01627 quicksort(iindex, exptime, 0, sz - 1);
01628
01629 return error;
01630 }
01631
01632 static double frame_get_exptime(const cpl_frame * pframe)
01633 {
01634 cpl_propertylist *plist = 0;
01635 double dval = 0;
01636
01637 plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01638 if(plist)
01639 {
01640 cpl_error_code err = CPL_ERROR_NONE;
01641 dval = cpl_propertylist_get_double(plist, "EXPTIME");
01642 err = cpl_error_get_code();
01643 if (err != CPL_ERROR_NONE)
01644 {
01645 cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01646 }
01647 }
01648
01649 cpl_propertylist_delete(plist);
01650 return dval;
01651 }