irplib_utils.h

00001 /* $Id: irplib_utils.h,v 1.55 2011/06/01 06:47:56 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/06/01 06:47:56 $
00024  * $Revision: 1.55 $
00025  * $Name: naco-4_3_0 $
00026  * $Log: irplib_utils.h,v $
00027  * Revision 1.55  2011/06/01 06:47:56  llundin
00028  * skip_if_lt(): Fix previous edits switch of A and B in error message
00029  *
00030  * Revision 1.54  2011/05/26 08:08:56  llundin
00031  * skip_if_lt(): Support printf-style error message, name-space protect temporary variables
00032  *
00033  * Revision 1.53  2011/05/09 07:51:18  llundin
00034  * irplib_dfs_save_image_(): Modified from cpl_dfs_save_image(). irplib_dfs_save_image(): Use irplib_dfs_save_image_()
00035  *
00036  * Revision 1.52  2010/03/23 07:57:59  kmirny
00037  * DFS08552, Documentation for irplib_frameset_sort
00038  *
00039  * Revision 1.51  2009/12/16 14:59:30  cgarcia
00040  * Avoid name clash with index function
00041  *
00042  * Revision 1.50  2009/08/17 15:10:16  kmirny
00043  *
00044  * DFS07454 DFS07437
00045  *
00046  */
00047 
00048 #ifndef IRPLIB_UTILS_H
00049 #define IRPLIB_UTILS_H
00050 
00051 /*-----------------------------------------------------------------------------
00052                                    Includes
00053  -----------------------------------------------------------------------------*/
00054 
00055 #include <stdarg.h>
00056 
00057 #include <cpl.h>
00058 
00059 /*-----------------------------------------------------------------------------
00060                                    Define
00061  -----------------------------------------------------------------------------*/
00062 
00063 #define IRPLIB_XSTRINGIFY(TOSTRING) #TOSTRING
00064 #define IRPLIB_STRINGIFY(TOSTRING) IRPLIB_XSTRINGIFY(TOSTRING)
00065 
00066 /* FIXME: Remove when no longer used by any irplib-based pipelines */
00067 /* Useful for debugging */
00068 #define irplib_trace()  do if (cpl_error_get_code()) { \
00069     cpl_msg_debug(cpl_func, __FILE__ " at line %d: ERROR '%s' at %s", \
00070          __LINE__, cpl_error_get_message(), cpl_error_get_where()); \
00071   } else { \
00072     cpl_msg_debug(cpl_func, __FILE__ " at line %d: OK", __LINE__); \
00073   } while (0)
00074 
00075 #define irplib_error_recover(ESTATE, ...)                                      \
00076     do if (!cpl_errorstate_is_equal(ESTATE)) {                                 \
00077         cpl_msg_warning(cpl_func, __VA_ARGS__);                                \
00078         cpl_msg_indent_more();                                                 \
00079         cpl_errorstate_dump(ESTATE, CPL_FALSE, irplib_errorstate_warning);     \
00080         cpl_msg_indent_less();                                                 \
00081         cpl_errorstate_set(ESTATE);                                            \
00082     } while (0)
00083 
00084 
00085 
00086 /*----------------------------------------------------------------------------*/
00087 /*
00088   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00089   @param  table_set_row    The name of the function to declare
00090   @see irplib_dfs_table_convert(), irplib_table_read_from_frameset()
00091 
00092 */
00093 /*----------------------------------------------------------------------------*/
00094 #define IRPLIB_UTIL_SET_ROW(table_set_row)                      \
00095     cpl_boolean table_set_row(cpl_table *,                      \
00096                               const char *,                     \
00097                               int,                              \
00098                               const cpl_frame *,                \
00099                               const cpl_parameterlist *)
00100 
00101 
00102 /*----------------------------------------------------------------------------*/
00103 /*
00104   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00105   @param  table_check    The name of the function to declare
00106   @see irplib_dfs_table_convert()
00107 
00108 */
00109 /*----------------------------------------------------------------------------*/
00110 #define IRPLIB_UTIL_CHECK(table_check)                          \
00111     cpl_error_code table_check(cpl_table *,                     \
00112                                const cpl_frameset *,            \
00113                                const cpl_parameterlist *)
00114 
00115 
00116 /*----------------------------------------------------------------------------*/
00117 /*
00118   @brief   Conditional skip to the (unqiue) return point of the function
00119   @param   CONDITION    The condition to check
00120   @see cpl_error_ensure()
00121 
00122   skip_if() takes one argument, which is a logical expression.
00123   If the logical expression is false skip_if() takes no action and
00124   program execution continues.
00125   If the logical expression is true this indicates an error. In this case
00126   skip_if() will set the location of the error to the point where it
00127   was invoked in the recipe code (unless the error location is already in the
00128   recipe code). If no error code had been set, then skip_if() will set one.
00129   Finally, skip_if() causes program execution to skip to the macro 'end_skip'.
00130   The macro end_skip is located towards the end of the function, after
00131   which all resource deallocation and the function return is located.
00132 
00133   The use of skip_if() assumes the following coding practice:
00134   1) Pointers used for dynamically allocated memory that they "own" shall always
00135      point to either NULL or to allocated memory (including CPL-objects).
00136   2) Such pointers may not be reused to point to memory whose deallocation
00137      requires calls to different functions.
00138   3) Pointers of type FILE should be set NULL when not pointing to an open
00139      stream and their closing calls (fclose(), freopen(), etc.) following the
00140      'end_skip' should be guarded against such NULL pointers.
00141 
00142   Error checking with skip_if() is encouraged due to the following advantages:
00143   1) It ensures that a CPL-error code is set.
00144   2) It ensures that the location of the error in the _recipe_ code is noted.
00145   3) The error checking may be confined to a single concise line.
00146   4) It is not necessary to replicate memory deallocation for every error
00147      condition.
00148   5) If more extensive error reporting/handling is required it is not precluded
00149      by the use of skip_if().
00150   6) It allows for a single point of function return.
00151   7) It allows for optional, uniformly formatted debugging/tracing information
00152      at each macro invocation.
00153 
00154   The implementation of skip_if() uses a goto/label construction.
00155   According to Kerningham & Ritchie, The C Programming Language, 2nd edition,
00156   Section 3.8:
00157   "This organization is handy if the error-handling code is non-trivial,
00158   and if errors can occur in several places."
00159 
00160   The use of goto for any other purpose should be avoided.
00161 
00162 */
00163 /*----------------------------------------------------------------------------*/
00164 #define skip_if(CONDITION)                                                     \
00165     do {                                                                       \
00166         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00167                          goto cleanup, "Propagating a pre-existing error");    \
00168         cpl_error_ensure(!(CONDITION), cpl_error_get_code(),                   \
00169                          goto cleanup, "Propagating error");\
00170     } while (0)
00171 
00172 /*----------------------------------------------------------------------------*/
00173 /*
00174   @brief   Skip if A < B
00175   @param   A   The 1st double to compare
00176   @param   B   The 2nd double to compare
00177   @param   MSG A printf-style error message, 1st arg should be a string literal
00178   @see skip_if()
00179   @note A and B are evaluated exactly once
00180 
00181   If no CPL error is set, sets CPL_ERROR_DATA_NOT_FOUND on failure
00182 */
00183 /*----------------------------------------------------------------------------*/
00184 #define skip_if_lt(A, B, ...)                                                  \
00185     do {                                                                       \
00186         /* Name-space protected one-time only evaluation */                    \
00187         const double irplib_utils_a = (double)(A);                             \
00188         const double irplib_utils_b = (double)(B);                             \
00189                                                                                \
00190         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00191                          goto cleanup, "Propagating a pre-existing error");    \
00192         if (irplib_utils_a < irplib_utils_b) {                                 \
00193             char * irplib_utils_msg = cpl_sprintf(__VA_ARGS__);                \
00194             (void)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,    \
00195                                         "Need at least %g (not %g) %s",        \
00196                                         irplib_utils_b, irplib_utils_a,        \
00197                                         irplib_utils_msg);                     \
00198             cpl_free(irplib_utils_msg);                                        \
00199             goto cleanup;                                                      \
00200         }                                                                      \
00201     } while (0)
00202 
00203 /*----------------------------------------------------------------------------*/
00204 /*
00205   @brief   Conditional skip on coding bug
00206   @param   CONDITION    The condition to check
00207   @see skip_if()
00208   @note unlike assert() this check cannot be disabled
00209  */
00210 /*----------------------------------------------------------------------------*/
00211 #define bug_if(CONDITION)                                                      \
00212     do {                                                                       \
00213         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00214                          goto cleanup, "Propagating an unexpected error, "     \
00215                          "please report to " PACKAGE_BUGREPORT);               \
00216         cpl_error_ensure(!(CONDITION), CPL_ERROR_UNSPECIFIED,                  \
00217                          goto cleanup, "Internal error, please report to "     \
00218                          PACKAGE_BUGREPORT);                                   \
00219     } while (0)
00220 
00221 /*----------------------------------------------------------------------------*/
00222 /*
00223   @brief   Conditional skip with error creation
00224   @param   CONDITION    The condition to check
00225   @param   ERROR        The error code to set
00226   @param   MSG          A printf-style error message. As a matter of
00227                         user-friendliness the message should mention any
00228                         value that caused the @em CONDITION to fail.
00229   @see skip_if()
00230   @note unlike assert() this check cannot be disabled
00231  */
00232 /*----------------------------------------------------------------------------*/
00233 #define error_if(CONDITION, ERROR, ...)                                 \
00234     cpl_error_ensure(cpl_error_get_code() == CPL_ERROR_NONE &&          \
00235                      !(CONDITION), ERROR, goto cleanup,  __VA_ARGS__)
00236 
00237 /*----------------------------------------------------------------------------*/
00238 /*
00239   @brief   Propagate a preexisting error, if any
00240   @param   MSG          A printf-style error message.
00241   @see skip_if()
00242  */
00243 /*----------------------------------------------------------------------------*/
00244 #define any_if(...)                                                     \
00245     cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),       \
00246                      goto cleanup,  __VA_ARGS__)
00247 
00248 /*----------------------------------------------------------------------------*/
00249 /*
00250   @brief   Define the single point of resource deallocation and return
00251   @see skip_if()
00252   @note end_skip should be used exactly once in functions that use skip_if() etc
00253 */
00254 /*----------------------------------------------------------------------------*/
00255 #define end_skip \
00256     do {                                                                     \
00257         cleanup:                                                             \
00258         if (cpl_error_get_code())                                            \
00259             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u with "  \
00260                           "error '%s' at %s", __LINE__,                      \
00261                           cpl_error_get_message(), cpl_error_get_where());   \
00262         else                                                                 \
00263             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u",       \
00264                           __LINE__);                                         \
00265     } while (0)
00266 
00267 
00268 /*----------------------------------------------------------------------------*/
00280 /*----------------------------------------------------------------------------*/
00281 #define irplib_ensure(CONDITION, ec, ...)                                      \
00282     cpl_error_ensure(CONDITION, ec, goto cleanup,  __VA_ARGS__)
00283 
00284 /*----------------------------------------------------------------------------*/
00314 /*----------------------------------------------------------------------------*/
00315 
00316 #define irplib_check(COMMAND, ...)                                             \
00317   do {                                                                         \
00318     cpl_errorstate irplib_check_prestate = cpl_errorstate_get();               \
00319     skip_if(0);                                                                \
00320     COMMAND;                                                                   \
00321         irplib_trace(); \
00322     irplib_ensure(cpl_errorstate_is_equal(irplib_check_prestate),              \
00323                   cpl_error_get_code(), __VA_ARGS__);                          \
00324         irplib_trace(); \
00325   } while (0)
00326 
00327 /*-----------------------------------------------------------------------------
00328                                    Function prototypes
00329  -----------------------------------------------------------------------------*/
00330 
00331 cpl_error_code irplib_dfs_save_image(cpl_frameset            *,
00332                                      const cpl_parameterlist *,
00333                                      const cpl_frameset      *,
00334                                      const cpl_image         *,
00335                                      cpl_type_bpp             ,
00336                                      const char              *,
00337                                      const char              *,
00338                                      const cpl_propertylist  *,
00339                                      const char              *,
00340                                      const char              *,
00341                                      const char              *);
00342 
00343 
00344 cpl_error_code irplib_dfs_save_propertylist(cpl_frameset            *,
00345                                             const cpl_parameterlist *,
00346                                             const cpl_frameset      *,
00347                                             const char              *,
00348                                             const char              *,
00349                                             const cpl_propertylist  *,
00350                                             const char              *,
00351                                             const char              *,
00352                                             const char              *);
00353 
00354 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset            *,
00355                                          const cpl_parameterlist *,
00356                                          const cpl_frameset      *,
00357                                          const cpl_imagelist     *,
00358                                          cpl_type_bpp             ,
00359                                          const char              *,
00360                                          const char              *,
00361                                          const cpl_propertylist  *,
00362                                          const char              *,
00363                                          const char              *,
00364                                          const char              *);
00365 
00366 cpl_error_code irplib_dfs_save_table(cpl_frameset            *,
00367                                      const cpl_parameterlist *,
00368                                      const cpl_frameset      *,
00369                                      const cpl_table         *,
00370                                      const cpl_propertylist  *,
00371                                      const char              *,
00372                                      const char              *,
00373                                      const cpl_propertylist  *,
00374                                      const char              *,
00375                                      const char              *,
00376                                      const char              *);
00377 
00378 cpl_error_code irplib_dfs_save_image_(cpl_frameset            *,
00379                                       cpl_propertylist        *,
00380                                       const cpl_parameterlist *,
00381                                       const cpl_frameset      *,
00382                                       const cpl_frame         *,
00383                                       const cpl_image         *,
00384                                       cpl_type                 ,
00385                                       const char              *,
00386                                       const cpl_propertylist  *,
00387                                       const char              *,
00388                                       const char              *,
00389                                       const char              *);
00390 
00391 void irplib_reset(void);
00392 int irplib_compare_tags(cpl_frame *, cpl_frame *);
00393 const char * irplib_frameset_find_file(const cpl_frameset *, const char *);
00394 const cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset *,
00395                                                        cpl_frame_group);
00396 
00397 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *, int *,
00398                                               int);
00399 
00400 int irplib_isinf(double value);
00401 int irplib_isnan(double value);
00402 
00403 void irplib_errorstate_warning(unsigned, unsigned, unsigned);
00404 
00405 cpl_error_code
00406 irplib_dfs_table_convert(cpl_table *, cpl_frameset *, const cpl_frameset *,
00407                          int, char, const char *, const char *,
00408                          const cpl_parameterlist *, const char *,
00409                          const cpl_propertylist *, const cpl_propertylist *,
00410                          const char *, const char *, const char *,
00411                          cpl_boolean (*)(cpl_table *, const char *, int,
00412                                             const cpl_frame *,
00413                                             const cpl_parameterlist *),
00414                          cpl_error_code (*)(cpl_table *,
00415                                             const cpl_frameset *,
00416                                             const cpl_parameterlist *));
00417 
00418 cpl_error_code irplib_table_read_from_frameset(cpl_table *,
00419                                                const cpl_frameset *,
00420                                                int,
00421                                                char,
00422                                                const cpl_parameterlist *,
00423                                                cpl_boolean (*)
00424                                                (cpl_table *, const char *,
00425                                                 int, const cpl_frame *,
00426                                                 const cpl_parameterlist *));
00427 
00428 cpl_error_code irplib_image_split(const cpl_image *,
00429                                   cpl_image *, cpl_image *, cpl_image *,
00430                                   double, cpl_boolean,
00431                                   double, cpl_boolean,
00432                                   double, double,
00433                                   cpl_boolean, cpl_boolean, cpl_boolean);
00434 
00435 void irplib_errorstate_dump_warning(unsigned, unsigned, unsigned);
00436 void irplib_errorstate_dump_info(unsigned, unsigned, unsigned);
00437 void irplib_errorstate_dump_debug(unsigned, unsigned, unsigned);
00438 /* wrapper for replace deprecated function cpl_polynomial_fit_1d_create*/
00439 cpl_polynomial * irplib_polynomial_fit_1d_create(
00440         const cpl_vector    *   x_pos,
00441         const cpl_vector    *   values,
00442         int                     degree,
00443         double              *   mse
00444         );
00445 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
00446         const cpl_vector    *   x_pos,
00447         const cpl_vector    *   values,
00448         int                     degree,
00449         double              *   rechiq
00450         );
00451 /*----------------------------------------------------------------------------*/
00459 cpl_error_code irplib_frameset_sort(
00460         const cpl_frameset *  self,
00461         int* iindex,
00462         double* exptime);
00463 
00464 #endif

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