00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025
00026
00027
00028 #include "irplib_utils.h"
00029
00030 #include <string.h>
00031 #include <assert.h>
00032 #include <stdlib.h>
00033 #include <errno.h>
00034
00035 #include <cpl.h>
00036 #include <math.h>
00037
00038
00039
00040
00041
00042 #ifndef inline
00043 #define inline
00044 #endif
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 inline static double irplib_data_get_double(const void *, cpl_type, int)
00055 #ifdef CPL_HAVE_GNUC_NONNULL
00056 __attribute__((nonnull))
00057 #endif
00058 ;
00059
00060 inline static void irplib_data_set_double(void *, cpl_type, int, double)
00061 #ifdef CPL_HAVE_GNUC_NONNULL
00062 __attribute__((nonnull))
00063 #endif
00064 ;
00065
00066
00067 static
00068 void irplib_errorstate_dump_one_level(void (*)(const char *,
00069 const char *, ...)
00070 #ifdef __GNUC__
00071 __attribute__((format (printf, 2, 3)))
00072 #endif
00073 , unsigned, unsigned, unsigned);
00074 static double frame_get_exptime(const cpl_frame * pframe);
00075 static void quicksort(int* index, double* exptime, int left, int right);
00076
00077 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
00078 cpl_propertylist *,
00079 const cpl_parameterlist *,
00080 const cpl_frameset *,
00081 const cpl_frame *,
00082 const cpl_imagelist *,
00083 const cpl_image *,
00084 cpl_type,
00085 const cpl_table *,
00086 const cpl_propertylist *,
00087 const char *,
00088 const cpl_propertylist *,
00089 const char *,
00090 const char *,
00091 const char *);
00092
00093
00097
00101
00113
00114 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
00115 unsigned last)
00116 {
00117
00118 irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
00119
00120 }
00121
00122 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
00123 const cpl_vector * x_pos,
00124 const cpl_vector * values,
00125 int degree,
00126 double * mse,
00127 double * rechisq
00128 );
00129
00130
00140
00141 void irplib_errorstate_dump_info(unsigned self, unsigned first,
00142 unsigned last)
00143 {
00144
00145 irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
00146
00147 }
00148
00149
00150
00160
00161 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
00162 unsigned last)
00163 {
00164
00165 irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
00166
00167 }
00168
00169
00170
00191
00192 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
00193 const cpl_parameterlist * parlist,
00194 const cpl_frameset * usedframes,
00195 const cpl_image * image,
00196 cpl_type_bpp bpp,
00197 const char * recipe,
00198 const char * procat,
00199 const cpl_propertylist * applist,
00200 const char * remregexp,
00201 const char * pipe_id,
00202 const char * filename)
00203 {
00204 cpl_errorstate prestate = cpl_errorstate_get();
00205 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00206 : cpl_propertylist_new();
00207
00208 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00209
00210 irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
00211 bpp, recipe, prolist, remregexp, pipe_id, filename);
00212
00213 cpl_propertylist_delete(prolist);
00214
00215 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00216
00217 return CPL_ERROR_NONE;
00218
00219 }
00220
00221
00238
00239 cpl_error_code
00240 irplib_dfs_save_propertylist(cpl_frameset * allframes,
00241 const cpl_parameterlist * parlist,
00242 const cpl_frameset * usedframes,
00243 const char * recipe,
00244 const char * procat,
00245 const cpl_propertylist * applist,
00246 const char * remregexp,
00247 const char * pipe_id,
00248 const char * filename)
00249 {
00250 cpl_errorstate prestate = cpl_errorstate_get();
00251 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00252 : cpl_propertylist_new();
00253
00254 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00255
00256 cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00257 recipe, prolist, remregexp, pipe_id, filename);
00258
00259 cpl_propertylist_delete(prolist);
00260
00261 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00262
00263 return CPL_ERROR_NONE;
00264
00265 }
00266
00267
00286
00287 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
00288 const cpl_parameterlist * parlist,
00289 const cpl_frameset * usedframes,
00290 const cpl_imagelist * imagelist,
00291 cpl_type_bpp bpp,
00292 const char * recipe,
00293 const char * procat,
00294 const cpl_propertylist * applist,
00295 const char * remregexp,
00296 const char * pipe_id,
00297 const char * filename)
00298 {
00299 cpl_errorstate prestate = cpl_errorstate_get();
00300 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00301 : cpl_propertylist_new();
00302
00303 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00304
00305 cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00306 imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00307 filename);
00308
00309 cpl_propertylist_delete(prolist);
00310
00311 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00312
00313 return CPL_ERROR_NONE;
00314 }
00315
00316
00334
00335 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
00336 const cpl_parameterlist * parlist,
00337 const cpl_frameset * usedframes,
00338 const cpl_table * table,
00339 const cpl_propertylist * tablelist,
00340 const char * recipe,
00341 const char * procat,
00342 const cpl_propertylist * applist,
00343 const char * remregexp,
00344 const char * pipe_id,
00345 const char * filename)
00346 {
00347
00348 cpl_errorstate prestate = cpl_errorstate_get();
00349 cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
00350 : cpl_propertylist_new();
00351
00352 cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00353
00354 cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00355 table, tablelist, recipe, prolist, remregexp,
00356 pipe_id, filename);
00357
00358 cpl_propertylist_delete(prolist);
00359
00360 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00361
00362 return CPL_ERROR_NONE;
00363 }
00364
00365
00366
00367
00394
00395 cpl_error_code irplib_dfs_save_image_(cpl_frameset * allframes,
00396 cpl_propertylist * header,
00397 const cpl_parameterlist * parlist,
00398 const cpl_frameset * usedframes,
00399 const cpl_frame * inherit,
00400 const cpl_image * image,
00401 cpl_type type,
00402 const char * recipe,
00403 const cpl_propertylist * applist,
00404 const char * remregexp,
00405 const char * pipe_id,
00406 const char * filename)
00407 {
00408 return
00409 irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
00410 NULL, image, type, NULL, NULL, recipe,
00411 applist, remregexp, pipe_id, filename)
00412 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00413
00414 }
00415
00416
00417
00441
00442
00443 static
00444 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
00445 cpl_propertylist * header,
00446 const cpl_parameterlist * parlist,
00447 const cpl_frameset * usedframes,
00448 const cpl_frame * inherit,
00449 const cpl_imagelist * imagelist,
00450 const cpl_image * image,
00451 cpl_type type,
00452 const cpl_table * table,
00453 const cpl_propertylist * tablelist,
00454 const char * recipe,
00455 const cpl_propertylist * applist,
00456 const char * remregexp,
00457 const char * pipe_id,
00458 const char * filename) {
00459
00460 const char * procat;
00461 cpl_propertylist * plist;
00462 cpl_frame * product_frame;
00463
00464
00465
00466
00467
00468
00469 const unsigned pronum
00470 = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
00471 const char * proname[] = {"imagelist", "table", "image",
00472 "propertylist"};
00473
00474 const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
00475 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
00476 cpl_error_code error = CPL_ERROR_NONE;
00477
00478
00479
00480
00481 if (imagelist != NULL) {
00482 assert(pronum == 0);
00483 assert(image == NULL);
00484 assert(table == NULL);
00485 assert(tablelist == NULL);
00486 } else if (table != NULL) {
00487 assert(pronum == 1);
00488 assert(imagelist == NULL);
00489 assert(image == NULL);
00490 } else if (image != NULL) {
00491 assert(pronum == 2);
00492 assert(imagelist == NULL);
00493 assert(table == NULL);
00494 assert(tablelist == NULL);
00495 } else {
00496 assert(pronum == 3);
00497 assert(imagelist == NULL);
00498 assert(table == NULL);
00499 assert(tablelist == NULL);
00500 assert(image == NULL);
00501 }
00502
00503 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00504 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00505 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
00506 cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
00507 cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
00508 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00509 cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
00510
00511 procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
00512
00513 cpl_ensure_code(procat != NULL, cpl_error_get_code());
00514
00515 cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", proname[pronum],
00516 procat, filename);
00517
00518 product_frame = cpl_frame_new();
00519
00520
00521 error |= cpl_frame_set_filename(product_frame, filename);
00522 error |= cpl_frame_set_tag(product_frame, procat);
00523 error |= cpl_frame_set_type(product_frame, protype[pronum]);
00524 error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
00525 error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
00526
00527 if (error) {
00528 cpl_frame_delete(product_frame);
00529 return cpl_error_set_where(cpl_func);
00530 }
00531
00532 if (header != NULL) {
00533 cpl_propertylist_empty(header);
00534 plist = header;
00535 } else {
00536 plist = cpl_propertylist_new();
00537 }
00538
00539
00540 if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
00541 applist,
00542 ".", 0);
00543
00544
00545 if (!error)
00546 error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
00547 parlist, recipe, pipe_id,
00548 "PRO-1.16", inherit);
00549
00550 if (remregexp != NULL && !error) {
00551 cpl_errorstate prestate = cpl_errorstate_get();
00552 (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
00553 if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
00554 }
00555
00556 if (!error) {
00557 switch (pronum) {
00558 case 0:
00559 error = cpl_imagelist_save(imagelist, filename, type, plist,
00560 CPL_IO_CREATE);
00561 break;
00562 case 1:
00563 error = cpl_table_save(table, plist, tablelist, filename,
00564 CPL_IO_CREATE);
00565 break;
00566 case 2:
00567 error = cpl_image_save(image, filename, type, plist,
00568 CPL_IO_CREATE);
00569 break;
00570 default:
00571
00572 error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
00573 }
00574 }
00575
00576 if (!error) {
00577
00578 error = cpl_frameset_insert(allframes, product_frame);
00579
00580 } else {
00581 cpl_frame_delete(product_frame);
00582 }
00583
00584 if (plist != header) cpl_propertylist_delete(plist);
00585
00586 cpl_ensure_code(!error, error);
00587
00588 return CPL_ERROR_NONE;
00589
00590 }
00591
00592
00593
00648
00649 cpl_error_code irplib_image_split(const cpl_image * self,
00650 cpl_image * im_low,
00651 cpl_image * im_mid,
00652 cpl_image * im_high,
00653 double th_low,
00654 cpl_boolean isleq_low,
00655 double th_high,
00656 cpl_boolean isgeq_high,
00657 double alt_low,
00658 double alt_high,
00659 cpl_boolean isbad_low,
00660 cpl_boolean isbad_mid,
00661 cpl_boolean isbad_high)
00662 {
00663
00664 const void * selfdata = cpl_image_get_data_const(self);
00665
00666
00667
00668 const cpl_boolean hasbpm
00669 = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
00670 const cpl_binary * selfbpm = hasbpm
00671 ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
00672 const cpl_type selftype = cpl_image_get_type(self);
00673 const int nx = cpl_image_get_size_x(self);
00674 const int ny = cpl_image_get_size_y(self);
00675 const int npix = nx * ny;
00676 const cpl_boolean do_low = im_low != NULL;
00677 const cpl_boolean do_mid = im_mid != NULL;
00678 const cpl_boolean do_high = im_high != NULL;
00679 void * lowdata = NULL;
00680 void * middata = NULL;
00681 void * highdata = NULL;
00682 cpl_binary * lowbpm = NULL;
00683 cpl_binary * midbpm = NULL;
00684 cpl_binary * highbpm = NULL;
00685 const cpl_type lowtype
00686 = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
00687 const cpl_type midtype
00688 = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
00689 const cpl_type hightype
00690 = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
00691 int i;
00692
00693
00694 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00695 cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
00696 cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
00697
00698 if (do_low) {
00699 cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
00700 CPL_ERROR_INCOMPATIBLE_INPUT);
00701 cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
00702 CPL_ERROR_INCOMPATIBLE_INPUT);
00703 lowdata = cpl_image_get_data(im_low);
00704 }
00705
00706 if (do_mid) {
00707 cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
00708 CPL_ERROR_INCOMPATIBLE_INPUT);
00709 cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
00710 CPL_ERROR_INCOMPATIBLE_INPUT);
00711 middata = cpl_image_get_data(im_mid);
00712 }
00713
00714 if (do_high) {
00715 cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
00716 CPL_ERROR_INCOMPATIBLE_INPUT);
00717 cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
00718 CPL_ERROR_INCOMPATIBLE_INPUT);
00719 highdata = cpl_image_get_data(im_high);
00720 }
00721
00722
00723
00724 for (i = 0; i < npix; i++) {
00725 const double value = irplib_data_get_double(selfdata, selftype, i);
00726 cpl_boolean isalt_low = do_low;
00727 cpl_boolean isalt_mid = do_mid;
00728 cpl_boolean isalt_high = do_high;
00729 cpl_boolean setbad_low = do_low;
00730 cpl_boolean setbad_mid = do_mid;
00731 cpl_boolean setbad_high = do_high;
00732 const void * setdata = NULL;
00733 double alt_mid = 0.0;
00734
00735 if (isleq_low ? value <= th_low : value < th_low) {
00736 if (do_low) {
00737 isalt_low = CPL_FALSE;
00738 irplib_data_set_double(lowdata, lowtype, i, value);
00739 setbad_low = hasbpm && selfbpm[i];
00740 setdata = lowdata;
00741 }
00742 alt_mid = alt_low;
00743 } else if (isgeq_high ? value >= th_high : value > th_high) {
00744 if (do_high) {
00745 isalt_high = CPL_FALSE;
00746 irplib_data_set_double(highdata, hightype, i, value);
00747 setbad_high = hasbpm && selfbpm[i];
00748 setdata = highdata;
00749 }
00750 alt_mid = alt_high;
00751 } else if (do_mid) {
00752 isalt_mid = CPL_FALSE;
00753 irplib_data_set_double(middata, midtype, i, value);
00754 setbad_mid = hasbpm && selfbpm[i];
00755 setdata = middata;
00756 }
00757
00758 if (isalt_low && lowdata != setdata) {
00759 irplib_data_set_double(lowdata, lowtype, i, alt_low);
00760 setbad_low = isbad_low;
00761 }
00762 if (isalt_mid && middata != setdata) {
00763 irplib_data_set_double(middata, midtype, i, alt_mid);
00764 setbad_mid = isbad_mid;
00765 }
00766 if (isalt_high && highdata != setdata) {
00767 irplib_data_set_double(highdata, hightype, i, alt_high);
00768 setbad_high = isbad_high;
00769 }
00770
00771 if (setbad_low) {
00772 if (lowbpm == NULL) lowbpm
00773 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
00774 lowbpm[i] = CPL_BINARY_1;
00775 }
00776 if (setbad_mid) {
00777 if (midbpm == NULL) midbpm
00778 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
00779 midbpm[i] = CPL_BINARY_1;
00780 }
00781 if (setbad_high) {
00782 if (highbpm == NULL) highbpm
00783 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
00784 highbpm[i] = CPL_BINARY_1;
00785 }
00786 }
00787
00788 return CPL_ERROR_NONE;
00789
00790 }
00791
00792
00793
00841
00842
00843 cpl_error_code
00844 irplib_dfs_table_convert(cpl_table * self,
00845 cpl_frameset * allframes,
00846 const cpl_frameset * useframes,
00847 int maxlinelen,
00848 char commentchar,
00849 const char * product_name,
00850 const char * procatg,
00851 const cpl_parameterlist * parlist,
00852 const char * recipe_name,
00853 const cpl_propertylist * mainlist,
00854 const cpl_propertylist * extlist,
00855 const char * remregexp,
00856 const char * instrume,
00857 const char * pipe_id,
00858 cpl_boolean (*table_set_row)
00859 (cpl_table *, const char *, int,
00860 const cpl_frame *,
00861 const cpl_parameterlist *),
00862 cpl_error_code (*table_check)
00863 (cpl_table *,
00864 const cpl_frameset *,
00865 const cpl_parameterlist *))
00866 {
00867
00868 const char * filename;
00869 cpl_propertylist * applist = NULL;
00870 cpl_errorstate prestate = cpl_errorstate_get();
00871 cpl_error_code error;
00872 char * fallback_filename = NULL;
00873
00874 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00875 cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
00876 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00877 cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
00878 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00879 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00880 cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
00881 cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
00882
00883 cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00884 maxlinelen,
00885 commentchar,
00886 parlist,
00887 table_set_row),
00888 cpl_error_get_code());
00889
00890 if (table_check != NULL && (table_check(self, useframes, parlist) ||
00891 !cpl_errorstate_is_equal(prestate))) {
00892 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00893 "Consistency check of table failed");
00894 }
00895
00896 fallback_filename = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00897 filename = product_name != NULL ? product_name : fallback_filename;
00898
00899 applist = mainlist == NULL
00900 ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00901
00902 error = cpl_propertylist_update_string(applist, "INSTRUME", instrume);
00903
00904 if (!error)
00905 error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00906 extlist, recipe_name, procatg, applist,
00907 remregexp, pipe_id, filename);
00908
00909 cpl_propertylist_delete(applist);
00910 cpl_free(fallback_filename);
00911
00912
00913 cpl_ensure_code(!error, error);
00914
00915 return CPL_ERROR_NONE;
00916
00917 }
00918
00919
00920
00921
00970
00971
00972 cpl_error_code
00973 irplib_table_read_from_frameset(cpl_table * self,
00974 const cpl_frameset * useframes,
00975 int maxlinelen,
00976 char commentchar,
00977 const cpl_parameterlist * parlist,
00978 cpl_boolean (*table_set_row)
00979 (cpl_table *, const char *, int,
00980 const cpl_frame *,
00981 const cpl_parameterlist *))
00982 {
00983
00984 const cpl_frame * rawframe;
00985 char * linebuffer = NULL;
00986 FILE * stream = NULL;
00987 int nfiles = 0;
00988 int nrow = cpl_table_get_nrow(self);
00989 int irow = 0;
00990 cpl_errorstate prestate = cpl_errorstate_get();
00991 cpl_frameset_iterator * iterator = NULL;
00992
00993 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00994 cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
00995 cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
00996 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00997 cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
00998
00999 linebuffer = cpl_malloc(maxlinelen);
01000
01001 for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
01002 rawframe != NULL;
01003 rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
01004
01005 const char * rawfile = cpl_frame_get_filename(rawframe);
01006 const char * done;
01007 const int irowpre = irow;
01008 int iirow = 0;
01009 int ierror;
01010
01011 if (rawfile == NULL) break;
01012
01013 stream = fopen(rawfile, "r");
01014
01015 if (stream == NULL) {
01016 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01017 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01018 "open %s for reading", rawfile);
01019 #else
01020 cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01021 "open file for reading");
01022 #endif
01023 break;
01024 }
01025
01026 for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
01027
01028 if (linebuffer[0] != commentchar) {
01029 cpl_boolean didset;
01030 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01031 const int prerow = irow;
01032 #endif
01033
01034 if (irow == nrow) {
01035 nrow += nrow ? nrow : 1;
01036 if (cpl_table_set_size(self, nrow)) break;
01037 }
01038
01039 didset = table_set_row(self, linebuffer, irow, rawframe,
01040 parlist);
01041 if (didset) irow++;
01042
01043 if (!cpl_errorstate_is_equal(prestate)) {
01044 if (didset)
01045 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01046 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01047 "Failed to set table row %d "
01048 "using line %d from %d. file %s",
01049 1+prerow, iirow+1,
01050 nfiles+1, rawfile);
01051 else
01052 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01053 "Failure with line %d from %d. "
01054 "file %s", iirow+1,
01055 nfiles+1, rawfile);
01056 #else
01057 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01058 "Failed to set table row"
01059 "using catalogue line");
01060 else
01061 cpl_error_set_message(cpl_func, cpl_error_get_code(),
01062 "Failure with catalogue line");
01063 #endif
01064
01065 break;
01066 }
01067 }
01068 }
01069 if (done != NULL) break;
01070
01071 ierror = fclose(stream);
01072 stream = NULL;
01073 if (ierror) break;
01074
01075
01076 if (irow == irowpre)
01077 cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
01078 1+nfiles, rawfile);
01079 }
01080
01081 cpl_frameset_iterator_delete(iterator);
01082 cpl_free(linebuffer);
01083 if (stream != NULL) fclose(stream);
01084
01085
01086 cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
01087
01088 if (irow == 0) {
01089 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01090 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01091 "No usable lines in the %d input "
01092 "frame(s)", nfiles);
01093 #else
01094 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01095 "No usable lines in the input frame(s)");
01096 #endif
01097 }
01098
01099
01100 cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
01101
01102 return CPL_ERROR_NONE;
01103 }
01104
01105
01106
01107
01119
01120 void irplib_reset(void)
01121 {
01122 return;
01123 }
01124
01125
01132
01133 int irplib_compare_tags(
01134 cpl_frame * frame1,
01135 cpl_frame * frame2)
01136 {
01137 const char * v1 ;
01138 const char * v2 ;
01139
01140
01141 if (frame1==NULL || frame2==NULL) return -1 ;
01142
01143
01144 if ((v1 = cpl_frame_get_tag(frame1)) == NULL) return -1 ;
01145 if ((v2 = cpl_frame_get_tag(frame2)) == NULL) return -1 ;
01146
01147
01148 if (strcmp(v1, v2)) return 0 ;
01149 else return 1 ;
01150 }
01151
01152
01168
01169 const char * irplib_frameset_find_file(const cpl_frameset * self,
01170 const char * tag)
01171 {
01172 const cpl_frame * frame = cpl_frameset_find_const(self, tag);
01173
01174
01175 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01176
01177 if (frame == NULL) return NULL;
01178
01179 if (cpl_frameset_find_const(self, NULL))
01180 cpl_msg_warning(cpl_func,
01181 "Frameset has more than one file with tag: %s",
01182 tag);
01183
01184 return cpl_frame_get_filename(frame);
01185
01186 }
01187
01188
01198
01199 const
01200 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
01201 cpl_frame_group group)
01202 {
01203 const cpl_frame * frame;
01204 cpl_frameset_iterator * iterator = NULL;
01205
01206 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01207
01208 for (frame = irplib_frameset_get_first_const(&iterator, self);
01209 frame != NULL ;
01210 frame = irplib_frameset_get_next_const(iterator)) {
01211 if (cpl_frame_get_group(frame) == group) break;
01212 }
01213 cpl_frameset_iterator_delete(iterator);
01214 return frame;
01215 }
01216
01217
01236
01237 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01238 int * ind, int nfind)
01239 {
01240 const int nsize = cpl_apertures_get_size(self);
01241 int ifind;
01242
01243
01244 cpl_ensure_code(nsize > 0, cpl_error_get_code());
01245 cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
01246 cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
01247 cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01248
01249 for (ifind=0; ifind < nfind; ifind++) {
01250 double maxflux = -1;
01251 int maxind = -1;
01252 int i;
01253 for (i=1; i <= nsize; i++) {
01254 int k;
01255
01256
01257 for (k=0; k < ifind; k++) if (ind[k] == i) break;
01258
01259 if (k == ifind) {
01260
01261 const double flux = cpl_apertures_get_flux(self, i);
01262
01263 if (maxind < 0 || flux > maxflux) {
01264 maxind = i;
01265 maxflux = flux;
01266 }
01267 }
01268 }
01269 ind[ifind] = maxind;
01270 }
01271
01272 return CPL_ERROR_NONE;
01273
01274 }
01275
01280
01291
01292 inline static
01293 double irplib_data_get_double(const void * self, cpl_type type, int i)
01294 {
01295
01296 double value;
01297
01298
01299 switch (type) {
01300 case CPL_TYPE_FLOAT:
01301 {
01302 const float * pself = (const float*)self;
01303 value = (double)pself[i];
01304 break;
01305 }
01306 case CPL_TYPE_INT:
01307 {
01308 const int * pself = (const int*)self;
01309 value = (double)pself[i];
01310 break;
01311 }
01312 default:
01313 {
01314 const double * pself = (const double*)self;
01315 value = pself[i];
01316 break;
01317 }
01318 }
01319
01320 return value;
01321
01322 }
01323
01324
01325
01336
01337 inline static
01338 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01339 {
01340
01341 switch (type) {
01342 case CPL_TYPE_FLOAT:
01343 {
01344 float * pself = (float*)self;
01345 pself[i] = (float)value;
01346 break;
01347 }
01348 case CPL_TYPE_INT:
01349 {
01350 int * pself = (int*)self;
01351 pself[i] = (int)value;
01352 break;
01353 }
01354 default:
01355 {
01356 double * pself = (double*)self;
01357 pself[i] = value;
01358 break;
01359 }
01360 }
01361 }
01362
01363
01364
01365
01366
01367
01378
01379 static
01380 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01381 const char *, ...),
01382 unsigned self, unsigned first,
01383 unsigned last)
01384 {
01385
01386 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01387 const unsigned newest = is_reverse ? first : last;
01388 const unsigned oldest = is_reverse ? last : first;
01389 const char * revmsg = is_reverse ? " in reverse order" : "";
01390
01391
01392
01393
01394
01395
01396
01397
01398 if (newest == 0) {
01399 messenger(cpl_func, "No error(s) to dump");
01400
01401 } else {
01402
01403
01404
01405
01406 if (self == first) {
01407 if (oldest == 1) {
01408 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01409 revmsg);
01410 } else {
01411 messenger(cpl_func, "Dumping the %u most recent error(s) "
01412 "out of a total of %u errors%s:",
01413 newest - oldest + 1, newest, revmsg);
01414 }
01415 cpl_msg_indent_more();
01416 }
01417
01418 messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01419 cpl_error_get_message(), cpl_error_get_code(),
01420 cpl_error_get_where());
01421
01422 if (self == last) cpl_msg_indent_less();
01423 }
01424 }
01425
01426 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01427 const cpl_vector * x_pos,
01428 const cpl_vector * values,
01429 int degree,
01430 double * rechisq
01431 )
01432 {
01433 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01434 }
01435 cpl_polynomial * irplib_polynomial_fit_1d_create(
01436 const cpl_vector * x_pos,
01437 const cpl_vector * values,
01438 int degree,
01439 double * mse
01440 )
01441 {
01442
01443 return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01444 }
01445 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01446 const cpl_vector * x_pos,
01447 const cpl_vector * values,
01448 int degree,
01449 double * mse,
01450 double * rechisq
01451 )
01452 {
01453 cpl_polynomial * fit1d = NULL;
01454 cpl_size loc_degree = (cpl_size)degree ;
01455 int x_size = 0;
01456 fit1d = cpl_polynomial_new(1);
01457 x_size = cpl_vector_get_size(x_pos);
01458 if(fit1d != NULL && x_size > 1)
01459 {
01460 cpl_matrix * samppos = NULL;
01461 cpl_vector * fitresidual = NULL;
01462 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01463 samppos = cpl_matrix_wrap(1, x_size,
01464 (double*)cpl_vector_get_data_const(x_pos));
01465 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01466 fitresidual = cpl_vector_new(x_size);
01467 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01468 cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01469 CPL_FALSE, NULL, &loc_degree);
01470 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01471 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
01472 fit1d, samppos, rechisq);
01473 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01474 if (mse)
01475 {
01476 *mse = cpl_vector_product(fitresidual, fitresidual)
01477 / cpl_vector_get_size(fitresidual);
01478 }
01479 cpl_matrix_unwrap(samppos);
01480 cpl_vector_delete(fitresidual);
01481 }
01482 return fit1d;
01483 }
01484
01485 static void quicksort(int* iindex, double* exptime, int left, int right)
01486 {
01487 int i = left;
01488 int j = right;
01489 int pivot = (i + j) / 2;
01490 double index_value = exptime[pivot];
01491 do
01492 {
01493 while(exptime[i] < index_value) i++;
01494 while(exptime[j] > index_value) j--;
01495 if (i <= j)
01496 {
01497 if(i < j)
01498 {
01499 int tmp = iindex[i];
01500 double dtmp = exptime[i];
01501 iindex[i]=iindex[j];
01502 iindex[j]=tmp;
01503 exptime[i] = exptime[j];
01504 exptime[j] = dtmp;
01505 }
01506 i++;
01507 j--;
01508 }
01509 } while (i <= j);
01510
01511 if (i < right)
01512 {
01513 quicksort(iindex, exptime, i, right);
01514 }
01515 if (left < j)
01516 {
01517 quicksort(iindex, exptime,left, j);
01518 }
01519 }
01520 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
01521 {
01522 int i = 0;
01523 const cpl_frame* tmp_frame = 0;
01524 cpl_error_code error = CPL_ERROR_NONE;
01525 int sz = cpl_frameset_get_size(self);
01526 cpl_frameset_iterator* iterator = NULL;
01527
01528
01529 tmp_frame = irplib_frameset_get_first_const(&iterator, self);
01530 while(tmp_frame)
01531 {
01532 exptime[i] = frame_get_exptime(tmp_frame);
01533 iindex[i] = i;
01534 tmp_frame = irplib_frameset_get_next_const(iterator);
01535 i++;
01536 }
01537 cpl_frameset_iterator_delete(iterator);
01538
01539 quicksort(iindex, exptime, 0, sz - 1);
01540
01541 return error;
01542 }
01543
01544 static double frame_get_exptime(const cpl_frame * pframe)
01545 {
01546 double dval = 0;
01547 cpl_propertylist * plist =
01548 cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
01549 "EXPTIME", CPL_FALSE);
01550 if(plist) {
01551 dval = cpl_propertylist_get_double(plist, "EXPTIME");
01552 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01553 cpl_msg_error(cpl_func, "error during reading EXPTIME key from "
01554 "the frame [%s]", cpl_frame_get_filename(pframe));
01555 }
01556 }
01557
01558 cpl_propertylist_delete(plist);
01559 return dval;
01560 }
01561
01562
01563
01577
01578 void * irplib_aligned_malloc(size_t alignment, size_t size)
01579 {
01580 if (alignment == 0)
01581 alignment = 1;
01582
01583 if (alignment & (alignment - 1)) {
01584 errno = EINVAL;
01585 return NULL;
01586 }
01587
01588 if ((size % alignment) != 0) {
01589 size += alignment - (size % alignment);
01590 }
01591
01592 #if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
01593 return aligned_alloc(alignment, size);
01594 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
01595 {
01596 void *ptr;
01597 if (alignment == 1)
01598 return malloc (size);
01599 if (alignment == 2 || (sizeof (void *) == 8 && alignment == 4))
01600 alignment = sizeof (void *);
01601 if (posix_memalign (&ptr, alignment, size) == 0)
01602 return ptr;
01603 else
01604 return NULL;
01605 }
01606 #else
01607
01608 {
01609 void * malloc_ptr;
01610 void * aligned_ptr;
01611
01612 if (size == 0)
01613 return NULL;
01614
01615
01616
01617
01618
01619 if (alignment < 2 * sizeof (void *))
01620 alignment = 2 * sizeof (void *);
01621
01622 malloc_ptr = malloc (size + alignment);
01623 if (!malloc_ptr)
01624 return NULL;
01625
01626
01627 aligned_ptr = (void *) (((size_t) malloc_ptr + alignment)
01628 & ~((size_t) (alignment) - 1));
01629
01630
01631 *(((void **) aligned_ptr) - 1) = malloc_ptr;
01632
01633 return aligned_ptr;
01634 }
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 HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
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 }
01681
01682
01683
01696
01697 const cpl_frame *
01698 irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
01699 const cpl_frameset *frameset)
01700 {
01701 cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
01702 *iterator = cpl_frameset_iterator_new(frameset);
01703 return cpl_frameset_iterator_get_const(*iterator);
01704 }
01705
01706
01715
01716 const cpl_frame *
01717 irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
01718 {
01719 cpl_errorstate prestate = cpl_errorstate_get();
01720 cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
01721 if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
01722 cpl_errorstate_set(prestate);
01723 return NULL;
01724 } else if (error != CPL_ERROR_NONE) {
01725 return NULL;
01726 }
01727 return cpl_frameset_iterator_get_const(iterator);
01728 }