irplib_utils.c

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

Generated on Thu May 12 12:12:19 2011 for VISIR Pipeline Reference Manual by  doxygen 1.4.7