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