irplib_utils.c

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

Generated on Mon Feb 6 14:42:07 2012 for NACO Pipeline Reference Manual by  doxygen 1.5.8