GIRAFFE Pipeline Reference Manual

irplib_utils.c

00001 /* $Id: irplib_utils.c,v 1.74 2010/12/17 09:19:01 kmirny 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: kmirny $
00023  * $Date: 2010/12/17 09:19:01 $
00024  * $Revision: 1.74 $
00025  * $Name:  $
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(cpl_size* index, double* exptime, cpl_size left,
00091                       cpl_size right);
00092 /*----------------------------------------------------------------------------*/
00096 /*----------------------------------------------------------------------------*/
00100 /*----------------------------------------------------------------------------*/
00112 /*----------------------------------------------------------------------------*/
00113 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
00114                                     unsigned last)
00115 {
00116 
00117     irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
00118 
00119 }
00120 
00121 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
00122         const cpl_vector    *   x_pos,
00123         const cpl_vector    *   values,
00124         cpl_size                degree,
00125         double              *   mse,
00126         double              *  rechisq
00127         );
00128 
00129 /*----------------------------------------------------------------------------*/
00139 /*----------------------------------------------------------------------------*/
00140 void irplib_errorstate_dump_info(unsigned self, unsigned first,
00141                                     unsigned last)
00142 {
00143 
00144     irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
00145 
00146 }
00147 
00148 
00149 /*----------------------------------------------------------------------------*/
00159 /*----------------------------------------------------------------------------*/
00160 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
00161                                     unsigned last)
00162 {
00163 
00164     irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
00165 
00166 }
00167 
00168 
00169 /*----------------------------------------------------------------------------*/
00190 /*----------------------------------------------------------------------------*/
00191 cpl_error_code irplib_dfs_save_image(cpl_frameset            * allframes,
00192                                      const cpl_parameterlist * parlist,
00193                                      const cpl_frameset      * usedframes,
00194                                      const cpl_image         * image,
00195                                      cpl_type_bpp              bpp,
00196                                      const char              * recipe,
00197                                      const char              * procat,
00198                                      const cpl_propertylist  * applist,
00199                                      const char              * remregexp,
00200                                      const char              * pipe_id,
00201                                      const char              * filename)
00202 {
00203     cpl_errorstate     prestate = cpl_errorstate_get();
00204     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00205         : cpl_propertylist_new();
00206 
00207     cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00208 
00209     cpl_dfs_save_image(allframes, NULL, parlist, usedframes, NULL, image, bpp,
00210                        recipe, prolist, remregexp, pipe_id, filename);
00211 
00212     cpl_propertylist_delete(prolist);
00213 
00214     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00215 
00216     return CPL_ERROR_NONE;
00217 
00218 }
00219 
00220 /*----------------------------------------------------------------------------*/
00237 /*----------------------------------------------------------------------------*/
00238 cpl_error_code
00239 irplib_dfs_save_propertylist(cpl_frameset            * allframes,
00240                              const cpl_parameterlist * parlist,
00241                              const cpl_frameset      * usedframes,
00242                              const char              * recipe,
00243                              const char              * procat,
00244                              const cpl_propertylist  * applist,
00245                              const char              * remregexp,
00246                              const char              * pipe_id,
00247                              const char              * filename)
00248 {
00249     cpl_errorstate     prestate = cpl_errorstate_get();
00250     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00251         : cpl_propertylist_new();
00252 
00253     cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00254 
00255     cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
00256                               recipe, prolist, remregexp, pipe_id, filename);
00257 
00258     cpl_propertylist_delete(prolist);
00259 
00260     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00261 
00262     return CPL_ERROR_NONE;
00263 
00264 }
00265 
00266 /*----------------------------------------------------------------------------*/
00285 /*----------------------------------------------------------------------------*/
00286 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset            * allframes,
00287                                          const cpl_parameterlist * parlist,
00288                                          const cpl_frameset      * usedframes,
00289                                          const cpl_imagelist     * imagelist,
00290                                          cpl_type_bpp              bpp,
00291                                          const char              * recipe,
00292                                          const char              * procat,
00293                                          const cpl_propertylist  * applist,
00294                                          const char              * remregexp,
00295                                          const char              * pipe_id,
00296                                          const char              * filename)
00297 {
00298     cpl_errorstate     prestate = cpl_errorstate_get();
00299     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00300         : cpl_propertylist_new();
00301 
00302     cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00303 
00304     cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
00305                            imagelist, bpp, recipe, prolist, remregexp, pipe_id,
00306                            filename);
00307 
00308     cpl_propertylist_delete(prolist);
00309 
00310     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00311 
00312     return CPL_ERROR_NONE;
00313 }
00314 
00315 /*----------------------------------------------------------------------------*/
00333 /*----------------------------------------------------------------------------*/
00334 cpl_error_code irplib_dfs_save_table(cpl_frameset            * allframes,
00335                                      const cpl_parameterlist * parlist,
00336                                      const cpl_frameset      * usedframes,
00337                                      const cpl_table         * table,
00338                                      const cpl_propertylist  * tablelist,
00339                                      const char              * recipe,
00340                                      const char              * procat,
00341                                      const cpl_propertylist  * applist,
00342                                      const char              * remregexp,
00343                                      const char              * pipe_id,
00344                                      const char              * filename)
00345 {
00346 
00347     cpl_errorstate     prestate = cpl_errorstate_get();
00348     cpl_propertylist * prolist  = applist ? cpl_propertylist_duplicate(applist)
00349         : cpl_propertylist_new();
00350 
00351     cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);
00352 
00353     cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
00354                            table, tablelist, recipe, prolist, remregexp,
00355                            pipe_id, filename);
00356 
00357     cpl_propertylist_delete(prolist);
00358 
00359     cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00360 
00361     return CPL_ERROR_NONE;
00362 }
00363 
00364 /*----------------------------------------------------------------------------*/
00419 /*----------------------------------------------------------------------------*/
00420 cpl_error_code irplib_image_split(const cpl_image * self,
00421                                   cpl_image * im_low,
00422                                   cpl_image * im_mid,
00423                                   cpl_image * im_high,
00424                                   double th_low,
00425                                   cpl_boolean isleq_low,
00426                                   double th_high,
00427                                   cpl_boolean isgeq_high,
00428                                   double alt_low,
00429                                   double alt_high,
00430                                   cpl_boolean isbad_low,
00431                                   cpl_boolean isbad_mid,
00432                                   cpl_boolean isbad_high)
00433 {
00434 
00435     const void       * selfdata = cpl_image_get_data_const(self);
00436     /* hasbpm reduces check-overhead if self does not have a bpm, and if
00437        self is also passed as an output image, that ends up with bad pixels */
00438     /* FIXME: Need a proper way to know if a bpm has been allocated :-((((((( */
00439     const cpl_boolean  hasbpm
00440         = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
00441     const cpl_binary * selfbpm = hasbpm
00442         ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
00443     const cpl_type     selftype = cpl_image_get_type(self);
00444     const int          nx = cpl_image_get_size_x(self);
00445     const int          ny = cpl_image_get_size_y(self);
00446     const int          npix = nx * ny;
00447     const cpl_boolean  do_low   = im_low  != NULL;
00448     const cpl_boolean  do_mid   = im_mid  != NULL;
00449     const cpl_boolean  do_high  = im_high != NULL;
00450     void             * lowdata  = NULL;
00451     void             * middata  = NULL;
00452     void             * highdata = NULL;
00453     cpl_binary       * lowbpm   = NULL;
00454     cpl_binary       * midbpm   = NULL;
00455     cpl_binary       * highbpm  = NULL;
00456     const cpl_type     lowtype
00457         = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
00458     const cpl_type     midtype
00459         = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
00460     const cpl_type     hightype
00461         = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
00462     int i;
00463 
00464 
00465     cpl_ensure_code(self != NULL,                CPL_ERROR_NULL_INPUT);
00466     cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
00467     cpl_ensure_code(th_low <= th_high,           CPL_ERROR_ILLEGAL_INPUT);
00468 
00469     if (do_low) {
00470         cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
00471                         CPL_ERROR_INCOMPATIBLE_INPUT);
00472         cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
00473                         CPL_ERROR_INCOMPATIBLE_INPUT);
00474         lowdata = cpl_image_get_data(im_low);
00475     }
00476 
00477     if (do_mid) {
00478         cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
00479                         CPL_ERROR_INCOMPATIBLE_INPUT);
00480         cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
00481                         CPL_ERROR_INCOMPATIBLE_INPUT);
00482         middata = cpl_image_get_data(im_mid);
00483     }
00484 
00485     if (do_high) {
00486         cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
00487                         CPL_ERROR_INCOMPATIBLE_INPUT);
00488         cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
00489                         CPL_ERROR_INCOMPATIBLE_INPUT);
00490         highdata = cpl_image_get_data(im_high);
00491     }
00492 
00493     /* From this point a failure would indicate a serious bug in CPL */
00494 
00495     for (i = 0; i < npix; i++) {
00496         const double value = irplib_data_get_double(selfdata, selftype, i);
00497         cpl_boolean  isalt_low   = do_low;
00498         cpl_boolean  isalt_mid   = do_mid;
00499         cpl_boolean  isalt_high  = do_high;
00500         cpl_boolean  setbad_low  = do_low;
00501         cpl_boolean  setbad_mid  = do_mid;
00502         cpl_boolean  setbad_high = do_high;
00503         const void * setdata     = NULL;
00504         double       alt_mid     = 0.0; /* Avoid (false) uninit warning */
00505 
00506         if (isleq_low ? value <= th_low : value < th_low) {
00507             if (do_low) {
00508                 isalt_low = CPL_FALSE;
00509                 irplib_data_set_double(lowdata, lowtype, i, value);
00510                 setbad_low = hasbpm && selfbpm[i];
00511                 setdata = lowdata;
00512             }
00513             alt_mid = alt_low;
00514         } else if (isgeq_high ? value >= th_high : value > th_high) {
00515             if (do_high) {
00516                 isalt_high = CPL_FALSE;
00517                 irplib_data_set_double(highdata, hightype, i, value);
00518                 setbad_high = hasbpm && selfbpm[i];
00519                 setdata = highdata;
00520             }
00521             alt_mid = alt_high;
00522         } else if (do_mid) {
00523             isalt_mid = CPL_FALSE;
00524             irplib_data_set_double(middata, midtype, i, value);
00525             setbad_mid = hasbpm && selfbpm[i];
00526             setdata = middata;
00527         }
00528 
00529         if (isalt_low && lowdata != setdata) {
00530             irplib_data_set_double(lowdata, lowtype, i, alt_low);
00531             setbad_low = isbad_low;
00532         }
00533         if (isalt_mid && middata != setdata) {
00534             irplib_data_set_double(middata, midtype, i, alt_mid);
00535             setbad_mid = isbad_mid;
00536         }
00537         if (isalt_high && highdata != setdata) {
00538             irplib_data_set_double(highdata, hightype, i, alt_high);
00539             setbad_high = isbad_high;
00540         }
00541 
00542         if (setbad_low) {
00543             if (lowbpm == NULL) lowbpm
00544                 = cpl_mask_get_data(cpl_image_get_bpm(im_low));
00545             lowbpm[i] = CPL_BINARY_1;
00546         }
00547         if (setbad_mid) {
00548             if (midbpm == NULL) midbpm
00549                 = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
00550             midbpm[i] = CPL_BINARY_1;
00551         }
00552         if (setbad_high) {
00553             if (highbpm == NULL) highbpm
00554                 = cpl_mask_get_data(cpl_image_get_bpm(im_high));
00555             highbpm[i] = CPL_BINARY_1;
00556         }
00557     }
00558 
00559     return CPL_ERROR_NONE;
00560 
00561 }
00562 
00563 
00564 /*----------------------------------------------------------------------------*/
00612 /*----------------------------------------------------------------------------*/
00613 
00614 cpl_error_code
00615 irplib_dfs_table_convert(cpl_table               * self,
00616                          cpl_frameset            * allframes,
00617                          const cpl_frameset      * useframes,
00618                          int                       maxlinelen,
00619                          char                      commentchar,
00620                          const char              * product_name,
00621                          const char              * procatg,
00622                          const cpl_parameterlist * parlist,
00623                          const char              * recipe_name,
00624                          const cpl_propertylist  * mainlist,
00625                          const cpl_propertylist  * extlist,
00626                          const char              * remregexp,
00627                          const char              * instrume,
00628                          const char              * pipe_id,
00629                          cpl_boolean (*table_set_row)
00630                          (cpl_table *, const char *, int,
00631                           const cpl_frame *,
00632                           const cpl_parameterlist *),
00633                          cpl_error_code (*table_check)
00634                          (cpl_table *,
00635                           const cpl_frameset *,
00636                           const cpl_parameterlist *))
00637 {
00638 
00639     const char       * filename;
00640     cpl_propertylist * applist    = NULL;
00641     cpl_errorstate     prestate   = cpl_errorstate_get();
00642     cpl_error_code     error;
00643 
00644     cpl_ensure_code(self         != NULL, CPL_ERROR_NULL_INPUT);
00645     cpl_ensure_code(allframes    != NULL, CPL_ERROR_NULL_INPUT);
00646     cpl_ensure_code(useframes    != NULL, CPL_ERROR_NULL_INPUT);
00647     cpl_ensure_code(procatg      != NULL, CPL_ERROR_NULL_INPUT);
00648     cpl_ensure_code(parlist      != NULL, CPL_ERROR_NULL_INPUT);
00649     cpl_ensure_code(recipe_name  != NULL, CPL_ERROR_NULL_INPUT);
00650     cpl_ensure_code(instrume     != NULL, CPL_ERROR_NULL_INPUT);
00651     cpl_ensure_code(pipe_id      != NULL, CPL_ERROR_NULL_INPUT);
00652 
00653     cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
00654                                                      maxlinelen,
00655                                                      commentchar,
00656                                                      parlist,
00657                                                      table_set_row),
00658                     cpl_error_get_code());
00659 
00660     if (table_check != NULL && (table_check(self, useframes, parlist) ||
00661                                 !cpl_errorstate_is_equal(prestate))) {
00662         return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00663                                      "Consistency check of table failed");
00664     }
00665 
00666     filename = product_name != NULL
00667         ? product_name : cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
00668 
00669     applist = mainlist == NULL
00670         ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
00671 
00672     error = cpl_propertylist_append_string(applist, "INSTRUME", instrume);
00673 
00674     if (!error)
00675         error = irplib_dfs_save_table(allframes, parlist, useframes, self,
00676                                       extlist, recipe_name, procatg, applist,
00677                                       remregexp, pipe_id, filename);
00678 
00679     cpl_propertylist_delete(applist);
00680     if (filename != product_name) cpl_free((char*)filename);
00681 
00682     /* Propagate the error, if any */
00683     cpl_ensure_code(!error, error);
00684 
00685     return CPL_ERROR_NONE;
00686 
00687 }
00688 
00689 
00690 
00691 /*----------------------------------------------------------------------------*/
00740 /*----------------------------------------------------------------------------*/
00741 
00742 cpl_error_code
00743 irplib_table_read_from_frameset(cpl_table               * self,
00744                                 const cpl_frameset      * useframes,
00745                                 int                       maxlinelen,
00746                                 char                      commentchar,
00747                                 const cpl_parameterlist * parlist,
00748                                 cpl_boolean (*table_set_row)
00749                                 (cpl_table *, const char *, int,
00750                                  const cpl_frame *,
00751                                  const cpl_parameterlist *))
00752 {
00753 
00754     const cpl_frame  * rawframe;
00755     char             * linebuffer = NULL;
00756     FILE             * stream     = NULL;
00757     int                nfiles     = 0;
00758     int                nrow       = cpl_table_get_nrow(self);
00759     int                irow       = 0;
00760     cpl_errorstate     prestate   = cpl_errorstate_get();
00761 
00762     cpl_ensure_code(self         != NULL, CPL_ERROR_NULL_INPUT);
00763     cpl_ensure_code(useframes    != NULL, CPL_ERROR_NULL_INPUT);
00764     cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
00765     cpl_ensure_code(parlist      != NULL, CPL_ERROR_NULL_INPUT);
00766     cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
00767 
00768     linebuffer = cpl_malloc(maxlinelen);
00769 
00770     for (rawframe = cpl_frameset_get_first_const(useframes);
00771          rawframe != NULL;
00772          rawframe = cpl_frameset_get_next_const(useframes), nfiles++) {
00773 
00774         const char * rawfile = cpl_frame_get_filename(rawframe);
00775         const char * done; /* Indicate when the reading is done */
00776         const int irowpre = irow;
00777         int iirow = 0;
00778         int ierror;
00779 
00780         if (rawfile == NULL) break; /* Should not happen... */
00781 
00782         stream = fopen(rawfile, "r");
00783 
00784         if (stream == NULL) {
00785 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00786             cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
00787                                   "open %s for reading", rawfile);
00788 #else
00789             cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
00790                                   "open file for reading");
00791 #endif
00792             break;
00793         }
00794 
00795         for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
00796 
00797             if (linebuffer[0] != commentchar) {
00798                 cpl_boolean didset;
00799 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00800                 const int prerow = irow;
00801 #endif
00802 
00803                 if (irow == nrow) {
00804                     nrow += nrow ? nrow : 1;
00805                     if (cpl_table_set_size(self, nrow)) break;
00806                 }
00807 
00808                 didset = table_set_row(self, linebuffer, irow, rawframe,
00809                                        parlist);
00810                 if (didset) irow++;
00811 
00812                 if (!cpl_errorstate_is_equal(prestate)) {
00813                     if (didset)
00814 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00815                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
00816                                               "Failed to set table row %d "
00817                                               "using line %d from %d. file %s",
00818                                               1+prerow, iirow+1,
00819                                               nfiles+1, rawfile);
00820                     else
00821                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
00822                                               "Failure with line %d from %d. "
00823                                               "file %s", iirow+1,
00824                                               nfiles+1, rawfile);
00825 #else
00826                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
00827                                               "Failed to set table row"
00828                                               "using catalogue line");
00829                     else
00830                         cpl_error_set_message(cpl_func, cpl_error_get_code(),
00831                                               "Failure with catalogue line");
00832 #endif
00833 
00834                     break;
00835                 }
00836             }
00837         }
00838         if (done != NULL) break;
00839 
00840         ierror = fclose(stream);
00841         stream = NULL;
00842         if (ierror) break;
00843 
00844 
00845         if (irow == irowpre)
00846             cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
00847                             1+nfiles, rawfile);
00848     }
00849 
00850     cpl_free(linebuffer);
00851     if (stream != NULL) fclose(stream);
00852 
00853     /* Check for premature end */
00854     cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
00855 
00856     if (irow == 0) {
00857 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00858         return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00859                                      "No usable lines in the %d input "
00860                                      "frame(s)", nfiles);
00861 #else
00862         return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00863                                      "No usable lines in the input frame(s)");
00864 #endif
00865     }
00866 
00867     /* Resize the table to the actual number of rows set */
00868     cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
00869 
00870     return CPL_ERROR_NONE;
00871 }
00872 
00873 
00874 
00875 /*----------------------------------------------------------------------------*/
00887 /*----------------------------------------------------------------------------*/
00888 void irplib_reset(void)
00889 {
00890     return;
00891 }
00892 
00893 /*----------------------------------------------------------------------------*/
00900 /*----------------------------------------------------------------------------*/
00901 int irplib_compare_tags(
00902         cpl_frame   *   frame1,
00903         cpl_frame   *   frame2)
00904 {
00905     char            *   v1 ;
00906     char            *   v2 ;
00907 
00908     /* Test entries */
00909     if (frame1==NULL || frame2==NULL) return -1 ;
00910 
00911     /* Get the tags */
00912     if ((v1 = (char*)cpl_frame_get_tag(frame1)) == NULL) return -1 ;
00913     if ((v2 = (char*)cpl_frame_get_tag(frame2)) == NULL) return -1 ;
00914 
00915     /* Compare the tags */
00916     if (strcmp(v1, v2)) return 0 ;
00917     else return 1 ;
00918 }
00919 
00920 /*----------------------------------------------------------------------------*/
00936 /*----------------------------------------------------------------------------*/
00937 const char * irplib_frameset_find_file(const cpl_frameset * self,
00938                                       const char * tag)
00939 {
00940     const cpl_frame * frame = cpl_frameset_find_const(self, tag);
00941 
00942 
00943     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00944 
00945     if (frame == NULL) return NULL;
00946 
00947     if (cpl_frameset_find_const(self, NULL))
00948         cpl_msg_warning(cpl_func,
00949             "Frameset has more than one file with tag: %s",
00950                         tag);
00951 
00952     return cpl_frame_get_filename(frame);
00953 
00954 }
00955 
00956 /*----------------------------------------------------------------------------*/
00966 /*----------------------------------------------------------------------------*/
00967 const
00968 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
00969                                                  cpl_frame_group      group)
00970 {
00971     const cpl_frame * frame;
00972 
00973     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00974 
00975     for (frame = cpl_frameset_get_first_const(self); frame != NULL ;
00976          frame = cpl_frameset_get_next_const(self)) {
00977         if (cpl_frame_get_group(frame) == group) break;
00978     }
00979     return frame;
00980 }
00981 
00982 /*----------------------------------------------------------------------------*/
01001 /*----------------------------------------------------------------------------*/
01002 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
01003                                               int * ind, int nfind)
01004 {
01005     const int    nsize = cpl_apertures_get_size(self);
01006     int          ifind;
01007 
01008 
01009     cpl_ensure_code(nsize > 0,      cpl_error_get_code());
01010     cpl_ensure_code(ind,          CPL_ERROR_NULL_INPUT);
01011     cpl_ensure_code(nfind > 0,      CPL_ERROR_ILLEGAL_INPUT);
01012     cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
01013 
01014     for (ifind=0; ifind < nfind; ifind++) {
01015         double maxflux = -1;
01016         int maxind = -1;
01017         int i;
01018         for (i=1; i <= nsize; i++) {
01019             int k;
01020 
01021             /* The flux has to be the highest among those not already found */
01022             for (k=0; k < ifind; k++) if (ind[k] == i) break;
01023 
01024             if (k == ifind) {
01025                 /* i has not been inserted into ind */
01026                 const double flux = cpl_apertures_get_flux(self, i);
01027 
01028                 if (maxind < 0 || flux > maxflux) {
01029                     maxind = i;
01030                     maxflux = flux;
01031                 }
01032             }
01033         }
01034         ind[ifind] = maxind;
01035     }
01036 
01037     return CPL_ERROR_NONE;
01038 
01039 }
01040 
01041 /*----------------------------------------------------------------------------*/
01045 /*----------------------------------------------------------------------------*/
01046 int irplib_isinf(double value)
01047 {
01048 #if defined HAVE_ISINF && HAVE_ISINF
01049     return isinf(value);
01050 #else
01051     return value != 0 && value == 2 * value;
01052 #endif
01053 }
01054 
01055 /*----------------------------------------------------------------------------*/
01059 /*----------------------------------------------------------------------------*/
01060 int irplib_isnan(double value)
01061 {
01062 #if defined HAVE_ISNAN && HAVE_ISNAN
01063     return isnan(value);
01064 #else
01065     return value != value;
01066 #endif
01067 }
01068 
01069 
01070 
01071 /*----------------------------------------------------------------------------*/
01082 /*----------------------------------------------------------------------------*/
01083 void irplib_errorstate_warning(unsigned self, unsigned first, unsigned last)
01084 {
01085 
01086     const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01087     const unsigned    newest     = is_reverse ? first : last;
01088     const unsigned    oldest     = is_reverse ? last : first;
01089     const char      * revmsg     = is_reverse ? " in reverse order" : "";
01090 
01091 
01092     assert( oldest <= self );
01093     assert( newest >= self );
01094 
01095     if (newest == 0) {
01096         cpl_msg_info(cpl_func, "No error(s) to dump");
01097         assert( oldest == 0);
01098     } else {
01099         assert( oldest > 0);
01100         assert( newest >= oldest);
01101         if (self == first) {
01102             if (oldest == 1) {
01103                 cpl_msg_warning(cpl_func, "Dumping all %u error(s)%s:", newest,
01104                               revmsg);
01105             } else {
01106                 cpl_msg_warning(cpl_func, "Dumping the %u most recent error(s) "
01107                               "out of a total of %u errors%s:",
01108                               newest - oldest + 1, newest, revmsg);
01109             }
01110             cpl_msg_indent_more();
01111         }
01112 
01113         cpl_msg_warning(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01114                       cpl_error_get_message(), cpl_error_get_code(),
01115                       cpl_error_get_where());
01116 
01117         if (self == last) cpl_msg_indent_less();
01118     }
01119 }
01120 
01121 
01124 /*----------------------------------------------------------------------------*/
01135 /*----------------------------------------------------------------------------*/
01136 inline static
01137 double irplib_data_get_double(const void * self, cpl_type type, int i)
01138 {
01139 
01140     double value;
01141 
01142 
01143     switch (type) {
01144     case CPL_TYPE_FLOAT:
01145         {
01146             const float * pself = (const float*)self;
01147             value = (double)pself[i];
01148             break;
01149         }
01150     case CPL_TYPE_INT:
01151         {
01152             const int * pself = (const int*)self;
01153             value = (double)pself[i];
01154             break;
01155         }
01156     default: /* case CPL_TYPE_DOUBLE */
01157         {
01158             const double * pself = (const double*)self;
01159             value = pself[i];
01160             break;
01161         }
01162     }
01163 
01164     return value;
01165 
01166 }
01167 
01168 
01169 /*----------------------------------------------------------------------------*/
01180 /*----------------------------------------------------------------------------*/
01181 inline static
01182 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
01183 {
01184 
01185     switch (type) {
01186     case CPL_TYPE_FLOAT:
01187         {
01188             float * pself = (float*)self;
01189             pself[i] = (float)value;
01190             break;
01191         }
01192     case CPL_TYPE_INT:
01193         {
01194             int * pself = (int*)self;
01195             pself[i] = (int)value;
01196             break;
01197         }
01198     default: /* case CPL_TYPE_DOUBLE */
01199         {
01200             double * pself = (double*)self;
01201             pself[i] = value;
01202             break;
01203         }
01204     }
01205 }
01206 
01207 
01208 
01209 
01210 
01211 /*----------------------------------------------------------------------------*/
01222 /*----------------------------------------------------------------------------*/
01223 static
01224 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
01225                                                         const char *, ...),
01226                                       unsigned self, unsigned first,
01227                                       unsigned last)
01228 {
01229 
01230     const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
01231     const unsigned    newest     = is_reverse ? first : last;
01232     const unsigned    oldest     = is_reverse ? last : first;
01233     const char      * revmsg     = is_reverse ? " in reverse order" : "";
01234 
01235 
01236     /*
01237     cx_assert( messenger != NULL );
01238     cx_assert( oldest <= self );
01239     cx_assert( newest >= self );
01240     */
01241 
01242     if (newest == 0) {
01243         messenger(cpl_func, "No error(s) to dump");
01244         /* cx_assert( oldest == 0); */
01245     } else {
01246         /*
01247           cx_assert( oldest > 0);
01248           cx_assert( newest >= oldest);
01249         */
01250         if (self == first) {
01251             if (oldest == 1) {
01252                 messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
01253                           revmsg);
01254             } else {
01255                 messenger(cpl_func, "Dumping the %u most recent error(s) "
01256                           "out of a total of %u errors%s:",
01257                           newest - oldest + 1, newest, revmsg);
01258             }
01259             cpl_msg_indent_more();
01260         }
01261 
01262         messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
01263                   cpl_error_get_message(), cpl_error_get_code(),
01264                   cpl_error_get_where());
01265 
01266         if (self == last) cpl_msg_indent_less();
01267     }
01268 }
01269 
01270 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
01271         const cpl_vector    *   x_pos,
01272         const cpl_vector    *   values,
01273         int                     degree,
01274         double              *   rechisq
01275         )
01276  {
01277     return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
01278  }
01279 cpl_polynomial * irplib_polynomial_fit_1d_create(
01280         const cpl_vector    *   x_pos,
01281         const cpl_vector    *   values,
01282         int                     degree,
01283         double              *   mse
01284         )
01285 {
01286 
01287     return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
01288 }
01289 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
01290         const cpl_vector    *   x_pos,
01291         const cpl_vector    *   values,
01292         cpl_size                degree,
01293         double              *   mse,
01294         double              *  rechisq
01295         )
01296 {
01297     cpl_polynomial * fit1d = NULL;
01298     int x_size = 0;
01299     fit1d = cpl_polynomial_new(1);
01300     x_size = cpl_vector_get_size(x_pos);    
01301     if(fit1d != NULL && x_size > 1)
01302     {
01303       cpl_matrix     * samppos = NULL;
01304       cpl_vector     * fitresidual = NULL;
01305         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01306         samppos = cpl_matrix_wrap(1, x_size,
01307                                                    (double*)cpl_vector_get_data_const(x_pos));
01308         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01309         fitresidual = cpl_vector_new(x_size);
01310         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01311         cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
01312                            CPL_FALSE, NULL, &degree);
01313         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01314         cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, fit1d,
01315                                                 samppos, rechisq);
01316         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
01317         if (mse)
01318         {
01319             *mse = cpl_vector_product(fitresidual, fitresidual)
01320                 / cpl_vector_get_size(fitresidual);
01321         }
01322         cpl_matrix_unwrap(samppos);
01323         cpl_vector_delete(fitresidual);
01324     }
01325     return fit1d;
01326 }
01327 
01328 static void quicksort(cpl_size* iindex, double* exptime,
01329                       cpl_size left, cpl_size right)
01330 {
01331     cpl_size i = left;
01332     cpl_size j = right;
01333     cpl_size pivot = (i + j) / 2;
01334     double index_value = exptime[pivot];
01335     do
01336     {
01337         while(exptime[i] < index_value) i++;
01338         while(exptime[j] > index_value) j--;
01339         if (i <= j)
01340         {
01341             if(i < j)
01342             {
01343                 int tmp = iindex[i];
01344                 double dtmp = exptime[i];
01345                 iindex[i]=iindex[j];
01346                 iindex[j]=tmp;
01347                 exptime[i] = exptime[j];
01348                 exptime[j] = dtmp;
01349             }
01350             i++;
01351             j--;
01352         }
01353     } while (i <= j);
01354 
01355     if (i < right)
01356     {
01357         quicksort(iindex, exptime, i, right);
01358     }
01359     if (left < j)
01360     {
01361         quicksort(iindex, exptime,left, j);
01362     }
01363 }
01364 cpl_error_code irplib_frameset_sort(const cpl_frameset *  self,
01365                                     cpl_size* iindex, double* exptime)
01366 {
01367     cpl_size sz = 0;
01368     cpl_size i = 0;
01369     const cpl_frame* tmp_frame = 0;
01370     cpl_error_code error = CPL_ERROR_NONE;
01371     sz = cpl_frameset_get_size(self);
01372 
01373     /* 1. get an array of frames */
01374     tmp_frame = cpl_frameset_get_first_const(self);
01375     while(tmp_frame)
01376     {
01377         exptime[i] = frame_get_exptime(tmp_frame);
01378         iindex[i] = i;
01379         tmp_frame = cpl_frameset_get_next_const(self);
01380         i++;
01381     }
01382     /* 2.sort */
01383     quicksort(iindex, exptime, 0, sz - 1);
01384 
01385     return error;
01386 }
01387 
01388 static double frame_get_exptime(const cpl_frame * pframe)
01389 {
01390     cpl_propertylist       *plist = 0;
01391     double                  dval = 0;
01392 
01393     plist = cpl_propertylist_load(cpl_frame_get_filename(pframe),0);
01394     if(plist)
01395     {
01396       cpl_error_code err = CPL_ERROR_NONE;  
01397         dval = cpl_propertylist_get_double(plist, "EXPTIME");
01398        err = cpl_error_get_code();
01399        if (err != CPL_ERROR_NONE)
01400        {
01401          cpl_msg_error(cpl_func, "error during reading EXPTIME key from the frame [%s]", cpl_frame_get_filename(pframe));
01402        }
01403     }
01404     /* Free and return */
01405     cpl_propertylist_delete(plist);
01406     return dval;
01407 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.9.0.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Jan 26 14:20:29 2012 by doxygen 1.6.3 written by Dimitri van Heesch, © 1997-2004