irplib_utils.c

00001 /* $Id: irplib_utils.c,v 1.82 2013/02/27 16:00:29 jtaylor 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: jtaylor $
00023  * $Date: 2013/02/27 16:00:29 $
00024  * $Revision: 1.82 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 #include "irplib_utils.h"
00036 
00037 #include <math.h>
00038 
00039 #include <string.h>
00040 #include <assert.h>
00041 
00042 #include <cpl.h>
00043 
00044 
00045 /*-----------------------------------------------------------------------------
00046                            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_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00231 
00232     irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
00233                            bpp, recipe, prolist, remregexp, pipe_id, filename);
00234 
00235     cpl_propertylist_delete(prolist);
00236 
00237     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00238 
00239     return CPL_ERROR_NONE;
00240 
00241 }
00242 
00243 /*----------------------------------------------------------------------------*/
00260 /*----------------------------------------------------------------------------*/
00261 cpl_error_code
00262 irplib_dfs_save_propertylist(cpl_frameset            * allframes,
00263                              const cpl_parameterlist * parlist,
00264                              const cpl_frameset      * usedframes,
00265                              const char              * recipe,
00266                              const char              * procat,
00267                              const cpl_propertylist  * applist,
00268                              const char              * remregexp,
00269                              const char              * pipe_id,
00270                              const char              * filename)
00271 {
00272     cpl_errorstate     prestate = cpl_errorstate_get();
00273     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00274         : cpl_propertylist_new();
00275 
00276     cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00277 
00278     cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00279                               recipe, prolist, remregexp, pipe_id, filename);
00280 
00281     cpl_propertylist_delete(prolist);
00282 
00283     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00284 
00285     return CPL_ERROR_NONE;
00286 
00287 }
00288 
00289 /*----------------------------------------------------------------------------*/
00308 /*----------------------------------------------------------------------------*/
00309 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset            * allframes,
00310                                          const cpl_parameterlist * parlist,
00311                                          const cpl_frameset      * usedframes,
00312                                          const cpl_imagelist     * imagelist,
00313                                          cpl_type_bpp              bpp,
00314                                          const char              * recipe,
00315                                          const char              * procat,
00316                                          const cpl_propertylist  * applist,
00317                                          const char              * remregexp,
00318                                          const char              * pipe_id,
00319                                          const char              * filename)
00320 {
00321     cpl_errorstate     prestate = cpl_errorstate_get();
00322     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00323         : cpl_propertylist_new();
00324 
00325     cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00326 
00327     cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00328                            imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00329                            filename);
00330 
00331     cpl_propertylist_delete(prolist);
00332 
00333     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00334 
00335     return CPL_ERROR_NONE;
00336 }
00337 
00338 /*----------------------------------------------------------------------------*/
00356 /*----------------------------------------------------------------------------*/
00357 cpl_error_code irplib_dfs_save_table(cpl_frameset            * allframes,
00358                                      const cpl_parameterlist * parlist,
00359                                      const cpl_frameset      * usedframes,
00360                                      const cpl_table         * table,
00361                                      const cpl_propertylist  * tablelist,
00362                                      const char              * recipe,
00363                                      const char              * procat,
00364                                      const cpl_propertylist  * applist,
00365                                      const char              * remregexp,
00366                                      const char              * pipe_id,
00367                                      const char              * filename)
00368 {
00369 
00370     cpl_errorstate     prestate = cpl_errorstate_get();
00371     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00372         : cpl_propertylist_new();
00373 
00374     cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
00375 
00376     cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00377                            table, tablelist, recipe, prolist, remregexp,
00378                            pipe_id, filename);
00379 
00380     cpl_propertylist_delete(prolist);
00381 
00382     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00383 
00384     return CPL_ERROR_NONE;
00385 }
00386 
00387 
00388 
00389 /*----------------------------------------------------------------------------*/
00416 /*----------------------------------------------------------------------------*/
00417 cpl_error_code irplib_dfs_save_image_(cpl_frameset            * allframes,
00418                                       cpl_propertylist        * header,
00419                                       const cpl_parameterlist * parlist,
00420                                       const cpl_frameset      * usedframes,
00421                                       const cpl_frame         * inherit,
00422                                       const cpl_image         * image,
00423                                       cpl_type                  type,
00424                                       const char              * recipe,
00425                                       const cpl_propertylist  * applist,
00426                                       const char              * remregexp,
00427                                       const char              * pipe_id,
00428                                       const char              * filename)
00429 {
00430     return
00431         irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
00432                                 NULL, image, type, NULL, NULL, recipe,
00433                                 applist, remregexp, pipe_id, filename)
00434         ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00435 
00436 }
00437 
00438 
00439 /*----------------------------------------------------------------------------*/
00463 /*----------------------------------------------------------------------------*/
00464 
00465 static
00466 cpl_error_code irplib_dfs_product_save(cpl_frameset            * allframes,
00467                                        cpl_propertylist        * header,
00468                                        const cpl_parameterlist * parlist,
00469                                        const cpl_frameset      * usedframes,
00470                                        const cpl_frame         * inherit,
00471                                        const cpl_imagelist     * imagelist,
00472                                        const cpl_image         * image,
00473                                        cpl_type                  type,
00474                                        const cpl_table         * table,
00475                                        const cpl_propertylist  * tablelist,
00476                                        const char              * recipe,
00477                                        const cpl_propertylist  * applist,
00478                                        const char              * remregexp,
00479                                        const char              * pipe_id,
00480                                        const char              * filename) {
00481 
00482     const char       * procat;
00483     cpl_propertylist * plist;
00484     cpl_frame        * product_frame;
00485     /* 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     char             * fallback_filename = NULL;
00895 
00896     cpl_ensure_code(self         != NULL, CPL_ERROR_NULL_INPUT);
00897     cpl_ensure_code(allframes    != NULL, CPL_ERROR_NULL_INPUT);
00898     cpl_ensure_code(useframes    != NULL, CPL_ERROR_NULL_INPUT);
00899     cpl_ensure_code(procatg      != NULL, CPL_ERROR_NULL_INPUT);
00900     cpl_ensure_code(parlist      != NULL, CPL_ERROR_NULL_INPUT);
00901     cpl_ensure_code(recipe_name  != NULL, CPL_ERROR_NULL_INPUT);
00902     cpl_ensure_code(instrume     != NULL, CPL_ERROR_NULL_INPUT);
00903     cpl_ensure_code(pipe_id      != NULL, CPL_ERROR_NULL_INPUT);
00904 
00905     cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00906                                                      maxlinelen,
00907                                                      commentchar,
00908                                                      parlist,
00909                                                      table_set_row),
00910                     cpl_error_get_code());
00911 
00912     if (table_check != NULL && (table_check(self, useframes, parlist) ||
00913                                 !cpl_errorstate_is_equal(prestate))) {
00914         return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00915                                      "Consistency check of table failed");
00916     }
00917 
00918     fallback_filename = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00919     filename = product_name != NULL ? product_name : fallback_filename;
00920 
00921     applist = mainlist == NULL
00922         ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00923 
00924     error = cpl_propertylist_update_string(applist, "INSTRUME", instrume);
00925 
00926     if (!error)
00927         error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00928                                       extlist, recipe_name, procatg, applist,
00929                                       remregexp, pipe_id, filename);
00930 
00931     cpl_propertylist_delete(applist);
00932     cpl_free(fallback_filename);
00933 
00934     /* Propagate the error, if any */
00935     cpl_ensure_code(!error, error);
00936 
00937     return CPL_ERROR_NONE;
00938 
00939 }
00940 
00941 
00942 
00943 /*----------------------------------------------------------------------------*/
00992 /*----------------------------------------------------------------------------*/
00993 
00994 cpl_error_code
00995 irplib_table_read_from_frameset(cpl_table               * self,
00996                                 const cpl_frameset      * useframes,
00997                                 int                       maxlinelen,
00998                                 char                      commentchar,
00999                                 const cpl_parameterlist * parlist,
01000                                 cpl_boolean (*table_set_row)
01001                                 (cpl_table *, const char *, int,
01002                                  const cpl_frame *,
01003                                  const cpl_parameterlist *))
01004 {
01005 
01006     const cpl_frame  * rawframe;
01007     char             * linebuffer = NULL;
01008     FILE             * stream     = NULL;
01009     int                nfiles     = 0;
01010     int                nrow       = cpl_table_get_nrow(self);
01011     int                irow       = 0;
01012     cpl_errorstate     prestate   = cpl_errorstate_get();
01013 
01014     cpl_ensure_code(self         != NULL, CPL_ERROR_NULL_INPUT);
01015     cpl_ensure_code(useframes    != NULL, CPL_ERROR_NULL_INPUT);
01016     cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
01017     cpl_ensure_code(parlist      != NULL, CPL_ERROR_NULL_INPUT);
01018     cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
01019 
01020     linebuffer = cpl_malloc(maxlinelen);
01021 
01022     for (rawframe = cpl_frameset_get_first_const(useframes);
01023          rawframe != NULL;
01024          rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
01025 
01026         const char * rawfile = cpl_frame_get_filename(rawframe);
01027         const char * done; /* Indicate when the reading is done */
01028         const int irowpre = irow;
01029         int iirow = 0;
01030         int ierror;
01031 
01032         if (rawfile == NULL) break; /* Should not happen... */
01033 
01034         stream = fopen(rawfile, "r");
01035 
01036         if (stream == NULL) {
01037 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01038             cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01039                                   "open %s for reading", rawfile);
01040 #else
01041             cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
01042                                   "open file for reading");
01043 #endif
01044             break;
01045         }
01046 
01047         for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
01048 
01049             if (linebuffer[0] != commentchar) {
01050                 cpl_boolean didset;
01051 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01052                 const int prerow = irow;
01053 #endif
01054 
01055                 if (irow == nrow) {
01056                     nrow += nrow ? nrow : 1;
01057                     if (cpl_table_set_size(self, nrow)) break;
01058                 }
01059 
01060                 didset = table_set_row(self, linebuffer, irow, rawframe,
01061                                        parlist);
01062                 if (didset) irow++;
01063 
01064                 if (!cpl_errorstate_is_equal(prestate)) {
01065                     if (didset)
01066 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01067                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
01068                                               "Failed to set table row %d "
01069                                               "using line %d from %d. file %s",
01070                                               1+prerow, iirow+1,
01071                                               nfiles+1, rawfile);
01072                     else
01073                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
01074                                               "Failure with line %d from %d. "
01075                                               "file %s", iirow+1,
01076                                               nfiles+1, rawfile);
01077 #else
01078                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
01079                                               "Failed to set table row"
01080                                               "using catalogue line");
01081                     else
01082                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
01083                                               "Failure with catalogue line");
01084 #endif
01085 
01086                     break;
01087                 }
01088             }
01089         }
01090         if (done != NULL) break;
01091 
01092         ierror = fclose(stream);
01093         stream = NULL;
01094         if (ierror) break;
01095 
01096 
01097         if (irow == irowpre)
01098             cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
01099                             1+nfiles, rawfile);
01100     }
01101 
01102     cpl_free(linebuffer);
01103     if (stream != NULL) fclose(stream);
01104 
01105     /* Check for premature end */
01106     cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
01107 
01108     if (irow == 0) {
01109 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01110         return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01111                                      "No usable lines in the %d input "
01112                                      "frame(s)", nfiles);
01113 #else
01114         return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
01115                                      "No usable lines in the input frame(s)");
01116 #endif
01117     }
01118 
01119     /* Resize the table to the actual number of rows set */
01120     cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
01121 
01122     return CPL_ERROR_NONE;
01123 }
01124 
01125 
01126 
01127 /*----------------------------------------------------------------------------*/
01139 /*----------------------------------------------------------------------------*/
01140 void irplib_reset(void)
01141 {
01142     return;
01143 }
01144 
01145 /*----------------------------------------------------------------------------*/
01152 /*----------------------------------------------------------------------------*/
01153 int irplib_compare_tags(
01154         cpl_frame   *   frame1,
01155         cpl_frame   *   frame2)
01156 {
01157     const char            *   v1 ;
01158     const char            *   v2 ;
01159 
01160     /* Test entries */
01161     if (frame1==NULL || frame2==NULL) return -1 ;
01162 
01163     /* Get the tags */
01164     if ((v1 = cpl_frame_get_tag(frame1)) == NULL) return -1 ;
01165     if ((v2 = cpl_frame_get_tag(frame2)) == NULL) return -1 ;
01166 
01167     /* Compare the tags */
01168     if (strcmp(v1, v2)) return 0 ;
01169     else return 1 ;
01170 }
01171 
01172 /*----------------------------------------------------------------------------*/
01188 /*----------------------------------------------------------------------------*/
01189 const char * irplib_frameset_find_file(const cpl_frameset * self,
01190                                       const char * tag)
01191 {
01192     const cpl_frame * frame = cpl_frameset_find_const(self, tag);
01193 
01194 
01195     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01196 
01197     if (frame == NULL) return NULL;
01198 
01199     if (cpl_frameset_find_const(self, NULL))
01200         cpl_msg_warning(cpl_func,
01201             "Frameset has more than one file with tag: %s",
01202                         tag);
01203 
01204     return cpl_frame_get_filename(frame);
01205 
01206 }
01207 
01208 /*----------------------------------------------------------------------------*/
01218 /*----------------------------------------------------------------------------*/
01219 const
01220 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
01221                                                  cpl_frame_group      group)
01222 {
01223     const cpl_frame * frame;
01224 
01225     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01226 
01227     for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
01228          frame = cpl_frameset_get_next_const(self)) {
01229         if (cpl_frame_get_group(frame) == group) break;
01230     }
01231     return frame;
01232 }
01233 
01234 /*----------------------------------------------------------------------------*/
01253 /*----------------------------------------------------------------------------*/
01254 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01255                                               int * ind, int nfind)
01256 {
01257     const int    nsize = cpl_apertures_get_size(self);
01258     int          ifind;
01259 
01260 
01261     cpl_ensure_code(nsize > 0,      cpl_error_get_code());
01262     cpl_ensure_code(ind,          CPL_ERROR_NULL_INPUT);
01263     cpl_ensure_code(nfind > 0,      CPL_ERROR_ILLEGAL_INPUT);
01264     cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01265 
01266     for (ifind=0; ifind < nfind; ifind++) {
01267         double maxflux = -1;
01268         int maxind = -1;
01269         int i;
01270         for (i=1; i <= nsize; i++) {
01271             int k;
01272 
01273             /* The flux has to be the highest among those not already found */
01274             for (k=0; k < ifind; k++) if (ind[k] == i) break;
01275 
01276             if (k == ifind) {
01277                 /* i has not been inserted into ind */
01278                 const double flux = cpl_apertures_get_flux(self, i);
01279 
01280                 if (maxind < 0 || flux > maxflux) {
01281                     maxind = i;
01282                     maxflux = flux;
01283                 }
01284             }
01285         }
01286         ind[ifind] = maxind;
01287     }
01288 
01289     return CPL_ERROR_NONE;
01290 
01291 }
01292 
01293 /*----------------------------------------------------------------------------*/
01297 /*----------------------------------------------------------------------------*/
01298 int irplib_isinf(double value)
01299 {
01300 #if defined HAVE_ISINF && HAVE_ISINF
01301     return isinf(value);
01302 #else
01303     return value != 0 && value == 2 * value;
01304 #endif
01305 }
01306 
01307 /*----------------------------------------------------------------------------*/
01311 /*----------------------------------------------------------------------------*/
01312 int irplib_isnan(double value)
01313 {
01314 #if defined HAVE_ISNAN && HAVE_ISNAN
01315     return isnan(value);
01316 #else
01317     return value != value;
01318 #endif
01319 }
01320 
01325 /*----------------------------------------------------------------------------*/
01336 /*----------------------------------------------------------------------------*/
01337 inline static
01338 double irplib_data_get_double(const void * self, cpl_type type, int i)
01339 {
01340 
01341     double value;
01342 
01343 
01344     switch (type) {
01345     case CPL_TYPE_FLOAT:
01346         {
01347             const float * pself = (const float*)self;
01348             value = (double)pself[i];
01349             break;
01350         }
01351     case CPL_TYPE_INT:
01352         {
01353             const int * pself = (const int*)self;
01354             value = (double)pself[i];
01355             break;
01356         }
01357     default: /* case CPL_TYPE_DOUBLE */
01358         {
01359             const double * pself = (const double*)self;
01360             value = pself[i];
01361             break;
01362         }
01363     }
01364 
01365     return value;
01366 
01367 }
01368 
01369 
01370 /*----------------------------------------------------------------------------*/
01381 /*----------------------------------------------------------------------------*/
01382 inline static
01383 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01384 {
01385 
01386     switch (type) {
01387     case CPL_TYPE_FLOAT:
01388         {
01389             float * pself = (float*)self;
01390             pself[i] = (float)value;
01391             break;
01392         }
01393     case CPL_TYPE_INT:
01394         {
01395             int * pself = (int*)self;
01396             pself[i] = (int)value;
01397             break;
01398         }
01399     default: /* case CPL_TYPE_DOUBLE */
01400         {
01401             double * pself = (double*)self;
01402             pself[i] = value;
01403             break;
01404         }
01405     }
01406 }
01407 
01408 
01409 
01410 
01411 
01412 /*----------------------------------------------------------------------------*/
01423 /*----------------------------------------------------------------------------*/
01424 static
01425 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01426                                                         const char *, ...),
01427                                       unsigned self, unsigned first,
01428                                       unsigned last)
01429 {
01430 
01431     const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01432     const unsigned    newest     = is_reverse ? first : last;
01433     const unsigned    oldest     = is_reverse ? last : first;
01434     const char      * revmsg     = is_reverse ? " in reverse order" : "";
01435 
01436 
01437     /*
01438     cx_assert( messenger != NULL );
01439     cx_assert( oldest <= self );
01440     cx_assert( newest >= self );
01441     */
01442 
01443     if (newest == 0) {
01444         messenger(cpl_func, "No error(s) to dump");
01445         /* cx_assert( oldest == 0); */
01446     } else {
01447         /*
01448           cx_assert( oldest > 0);
01449           cx_assert( newest >= oldest);
01450         */
01451         if (self == first) {
01452             if (oldest == 1) {
01453                 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01454                           revmsg);
01455             } else {
01456                 messenger(cpl_func, "Dumping the %u most recent error(s) "
01457                           "out of a total of %u errors%s:",
01458                           newest - oldest + 1, newest, revmsg);
01459             }
01460             cpl_msg_indent_more();
01461         }
01462 
01463         messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01464                   cpl_error_get_message(), cpl_error_get_code(),
01465                   cpl_error_get_where());
01466 
01467         if (self == last) cpl_msg_indent_less();
01468     }
01469 }
01470 
01471 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01472         const cpl_vector    *   x_pos,
01473         const cpl_vector    *   values,
01474         int                     degree,
01475         double              *   rechisq
01476         )
01477  {
01478     return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01479  }
01480 cpl_polynomial * irplib_polynomial_fit_1d_create(
01481         const cpl_vector    *   x_pos,
01482         const cpl_vector    *   values,
01483         int                     degree,
01484         double              *   mse
01485         )
01486 {
01487 
01488     return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01489 }
01490 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01491         const cpl_vector    *   x_pos,
01492         const cpl_vector    *   values,
01493         int                     degree,
01494         double              *   mse,
01495         double              *  rechisq
01496         )
01497 {
01498     cpl_polynomial * fit1d = NULL;
01499     cpl_size loc_degree = (cpl_size)degree ;
01500     int x_size = 0;
01501     fit1d = cpl_polynomial_new(1);
01502     x_size = cpl_vector_get_size(x_pos);    
01503     if(fit1d != NULL && x_size > 1)
01504     {
01505         cpl_matrix     * samppos = NULL;
01506         cpl_vector     * fitresidual = NULL;
01507         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01508         samppos = cpl_matrix_wrap(1, x_size,
01509                                   (double*)cpl_vector_get_data_const(x_pos));
01510         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01511         fitresidual = cpl_vector_new(x_size);
01512         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01513         cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01514                            CPL_FALSE, NULL, &loc_degree);
01515         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01516         cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
01517                                                 fit1d, samppos, rechisq);
01518         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01519         if (mse)
01520         {
01521             *mse = cpl_vector_product(fitresidual, fitresidual)
01522                 / cpl_vector_get_size(fitresidual);
01523         }
01524         cpl_matrix_unwrap(samppos);
01525         cpl_vector_delete(fitresidual);
01526     }
01527     return fit1d;
01528 }
01529 
01530 static void quicksort(int* iindex, double* exptime, int left, int right)
01531 {
01532     int i = left;
01533     int j = right;
01534     int pivot = (i + j) / 2;
01535     double index_value = exptime[pivot];
01536     do
01537     {
01538         while(exptime[i] < index_value) i++;
01539         while(exptime[j] > index_value) j--;
01540         if (i <= j)
01541         {
01542             if(i < j)
01543             {
01544                 int tmp = iindex[i];
01545                 double dtmp = exptime[i];
01546                 iindex[i]=iindex[j];
01547                 iindex[j]=tmp;
01548                 exptime[i] = exptime[j];
01549                 exptime[j] = dtmp;
01550             }
01551             i++;
01552             j--;
01553         }
01554     } while (i <= j);
01555 
01556     if (i < right)
01557     {
01558         quicksort(iindex, exptime, i, right);
01559     }
01560     if (left < j)
01561     {
01562         quicksort(iindex, exptime,left, j);
01563     }
01564 }
01565 cpl_error_code irplib_frameset_sort(const cpl_frameset *  self, int* iindex, double* exptime)
01566 {
01567     int sz = 0;
01568     int i = 0;
01569     const cpl_frame* tmp_frame = 0;
01570     cpl_error_code error = CPL_ERROR_NONE;
01571     sz = cpl_frameset_get_size(self);
01572 
01573     /* 1. get an array of frames */
01574     tmp_frame = cpl_frameset_get_first_const(self);
01575     while(tmp_frame)
01576     {
01577         exptime[i] = frame_get_exptime(tmp_frame);
01578         iindex[i] = i;
01579         tmp_frame = cpl_frameset_get_next_const(self);
01580         i++;
01581     }
01582     /* 2.sort */
01583     quicksort(iindex, exptime, 0, sz - 1);
01584 
01585     return error;
01586 }
01587 
01588 static double frame_get_exptime(const cpl_frame * pframe)
01589 {
01590     cpl_propertylist       *plist = 0;
01591     double                  dval = 0;
01592 
01593     plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01594     if(plist)
01595     {
01596       cpl_error_code err = CPL_ERROR_NONE;  
01597         dval = cpl_propertylist_get_double(plist, "EXPTIME");
01598        err = cpl_error_get_code();
01599        if (err != CPL_ERROR_NONE)
01600        {
01601          cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01602        }
01603     }
01604     /* Free and return */
01605     cpl_propertylist_delete(plist);
01606     return dval;
01607 }

Generated on 3 Mar 2013 for DETMON Pipeline Reference Manual by  doxygen 1.6.1