irplib_utils.h

00001 /* $Id: irplib_utils.h,v 1.60 2013-08-21 14:55:14 cgarcia 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: cgarcia $
00023  * $Date: 2013-08-21 14:55:14 $
00024  * $Revision: 1.60 $
00025  * $Name: not supported by cvs2svn $
00026  * $Log: not supported by cvs2svn $
00027  * Revision 1.59  2013/03/15 09:06:06  jtaylor
00028  * add irplib_aligned_{[mc]alloc,free}
00029  *
00030  * allow portable allocation of aligned memory for vectorization
00031  *
00032  * Revision 1.58  2013/03/15 09:05:28  jtaylor
00033  * move isnan and isinf to header so it is inlineable and use gcc builtin for better performance
00034  *
00035  * Revision 1.57  2013/02/27 16:02:02  jtaylor
00036  * add diagnostic pragma macros
00037  *
00038  * Revision 1.56  2012/08/06 06:14:18  llundin
00039  * irplib_errorstate_warning(): Replaced by cpl_errorstate_dump_one_warning() from CPL 6.X
00040  *
00041  * Revision 1.55  2011/06/01 06:47:56  llundin
00042  * skip_if_lt(): Fix previous edits switch of A and B in error message
00043  *
00044  * Revision 1.54  2011/05/26 08:08:56  llundin
00045  * skip_if_lt(): Support printf-style error message, name-space protect temporary variables
00046  *
00047  * Revision 1.53  2011/05/09 07:51:18  llundin
00048  * irplib_dfs_save_image_(): Modified from cpl_dfs_save_image(). irplib_dfs_save_image(): Use irplib_dfs_save_image_()
00049  *
00050  * Revision 1.52  2010/03/23 07:57:59  kmirny
00051  * DFS08552, Documentation for irplib_frameset_sort
00052  *
00053  * Revision 1.51  2009/12/16 14:59:30  cgarcia
00054  * Avoid name clash with index function
00055  *
00056  * Revision 1.50  2009/08/17 15:10:16  kmirny
00057  *
00058  * DFS07454 DFS07437
00059  *
00060  */
00061 
00062 #ifndef IRPLIB_UTILS_H
00063 #define IRPLIB_UTILS_H
00064 
00065 /*-----------------------------------------------------------------------------
00066                                    Includes
00067  -----------------------------------------------------------------------------*/
00068 
00069 #include <cpl.h>
00070 #include <math.h>
00071 #include <stdarg.h>
00072 
00073 /*-----------------------------------------------------------------------------
00074                                    Define
00075  -----------------------------------------------------------------------------*/
00076 
00077 #define IRPLIB_XSTRINGIFY(TOSTRING) #TOSTRING
00078 #define IRPLIB_STRINGIFY(TOSTRING) IRPLIB_XSTRINGIFY(TOSTRING)
00079 
00080 #if !defined __GNUC__ && !defined __inline__
00081 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
00082 #define __inline__ inline
00083 #else
00084 #define __inline__
00085 #endif
00086 #endif
00087 
00088 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
00089 #define IRPLIB_DIAG_PRAGMA_PUSH_IGN(x)        \
00090     _Pragma("GCC diagnostic push") \
00091     _Pragma(IRPLIB_STRINGIFY(GCC diagnostic ignored #x))
00092 #define IRPLIB_DIAG_PRAGMA_PUSH_ERR(x)        \
00093     _Pragma("GCC diagnostic push") \
00094     _Pragma(IRPLIB_STRINGIFY(GCC diagnostic error #x))
00095 #define IRPLIB_DIAG_PRAGMA_POP \
00096     _Pragma("GCC diagnostic pop")
00097 #else
00098 #define IRPLIB_DIAG_PRAGMA_PUSH_IGN(x)
00099 #define IRPLIB_DIAG_PRAGMA_PUSH_ERR(x)
00100 #define IRPLIB_DIAG_PRAGMA_POP
00101 #endif
00102 
00103 
00104 /* FIXME: Remove when no longer used by any irplib-based pipelines */
00105 /* Useful for debugging */
00106 #define irplib_trace()  do if (cpl_error_get_code()) { \
00107     cpl_msg_debug(cpl_func, __FILE__ " at line %d: ERROR '%s' at %s", \
00108          __LINE__, cpl_error_get_message(), cpl_error_get_where()); \
00109   } else { \
00110     cpl_msg_debug(cpl_func, __FILE__ " at line %d: OK", __LINE__); \
00111   } while (0)
00112 
00113 #define irplib_error_recover(ESTATE, ...)                       \
00114     do if (!cpl_errorstate_is_equal(ESTATE)) {                  \
00115         cpl_msg_warning(cpl_func, __VA_ARGS__);                 \
00116         cpl_msg_indent_more();                                  \
00117         cpl_errorstate_dump(ESTATE, CPL_FALSE,                  \
00118                             cpl_errorstate_dump_one_warning);   \
00119         cpl_msg_indent_less();                                  \
00120         cpl_errorstate_set(ESTATE);                             \
00121     } while (0)
00122 
00123 
00124 
00125 /*----------------------------------------------------------------------------*/
00126 /*
00127   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00128   @param  table_set_row    The name of the function to declare
00129   @see irplib_dfs_table_convert(), irplib_table_read_from_frameset()
00130 
00131 */
00132 /*----------------------------------------------------------------------------*/
00133 #define IRPLIB_UTIL_SET_ROW(table_set_row)                      \
00134     cpl_boolean table_set_row(cpl_table *,                      \
00135                               const char *,                     \
00136                               int,                              \
00137                               const cpl_frame *,                \
00138                               const cpl_parameterlist *)
00139 
00140 
00141 /*----------------------------------------------------------------------------*/
00142 /*
00143   @brief Declare a function suitable for use with irplib_dfs_table_convert()
00144   @param  table_check    The name of the function to declare
00145   @see irplib_dfs_table_convert()
00146 
00147 */
00148 /*----------------------------------------------------------------------------*/
00149 #define IRPLIB_UTIL_CHECK(table_check)                          \
00150     cpl_error_code table_check(cpl_table *,                     \
00151                                const cpl_frameset *,            \
00152                                const cpl_parameterlist *)
00153 
00154 
00155 /*----------------------------------------------------------------------------*/
00156 /*
00157   @brief   Conditional skip to the (unqiue) return point of the function
00158   @param   CONDITION    The condition to check
00159   @see cpl_error_ensure()
00160 
00161   skip_if() takes one argument, which is a logical expression.
00162   If the logical expression is false skip_if() takes no action and
00163   program execution continues.
00164   If the logical expression is true this indicates an error. In this case
00165   skip_if() will set the location of the error to the point where it
00166   was invoked in the recipe code (unless the error location is already in the
00167   recipe code). If no error code had been set, then skip_if() will set one.
00168   Finally, skip_if() causes program execution to skip to the macro 'end_skip'.
00169   The macro end_skip is located towards the end of the function, after
00170   which all resource deallocation and the function return is located.
00171 
00172   The use of skip_if() assumes the following coding practice:
00173   1) Pointers used for dynamically allocated memory that they "own" shall always
00174      point to either NULL or to allocated memory (including CPL-objects).
00175   2) Such pointers may not be reused to point to memory whose deallocation
00176      requires calls to different functions.
00177   3) Pointers of type FILE should be set NULL when not pointing to an open
00178      stream and their closing calls (fclose(), freopen(), etc.) following the
00179      'end_skip' should be guarded against such NULL pointers.
00180 
00181   Error checking with skip_if() is encouraged due to the following advantages:
00182   1) It ensures that a CPL-error code is set.
00183   2) It ensures that the location of the error in the _recipe_ code is noted.
00184   3) The error checking may be confined to a single concise line.
00185   4) It is not necessary to replicate memory deallocation for every error
00186      condition.
00187   5) If more extensive error reporting/handling is required it is not precluded
00188      by the use of skip_if().
00189   6) It allows for a single point of function return.
00190   7) It allows for optional, uniformly formatted debugging/tracing information
00191      at each macro invocation.
00192 
00193   The implementation of skip_if() uses a goto/label construction.
00194   According to Kerningham & Ritchie, The C Programming Language, 2nd edition,
00195   Section 3.8:
00196   "This organization is handy if the error-handling code is non-trivial,
00197   and if errors can occur in several places."
00198 
00199   The use of goto for any other purpose should be avoided.
00200 
00201 */
00202 /*----------------------------------------------------------------------------*/
00203 #define skip_if(CONDITION)                                                     \
00204     do {                                                                       \
00205         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00206                          goto cleanup, "Propagating a pre-existing error");    \
00207         cpl_error_ensure(!(CONDITION), cpl_error_get_code(),                   \
00208                          goto cleanup, "Propagating error");\
00209     } while (0)
00210 
00211 /*----------------------------------------------------------------------------*/
00212 /*
00213   @brief   Skip if A < B
00214   @param   A   The 1st double to compare
00215   @param   B   The 2nd double to compare
00216   @param   MSG A printf-style error message, 1st arg should be a string literal
00217   @see skip_if()
00218   @note A and B are evaluated exactly once
00219 
00220   If no CPL error is set, sets CPL_ERROR_DATA_NOT_FOUND on failure
00221 */
00222 /*----------------------------------------------------------------------------*/
00223 #define skip_if_lt(A, B, ...)                                                  \
00224     do {                                                                       \
00225         /* Name-space protected one-time only evaluation */                    \
00226         const double irplib_utils_a = (double)(A);                             \
00227         const double irplib_utils_b = (double)(B);                             \
00228                                                                                \
00229         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00230                          goto cleanup, "Propagating a pre-existing error");    \
00231         if (irplib_utils_a < irplib_utils_b) {                                 \
00232             char * irplib_utils_msg = cpl_sprintf(__VA_ARGS__);                \
00233             (void)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,    \
00234                                         "Need at least %g (not %g) %s",        \
00235                                         irplib_utils_b, irplib_utils_a,        \
00236                                         irplib_utils_msg);                     \
00237             cpl_free(irplib_utils_msg);                                        \
00238             goto cleanup;                                                      \
00239         }                                                                      \
00240     } while (0)
00241 
00242 /*----------------------------------------------------------------------------*/
00243 /*
00244   @brief   Conditional skip on coding bug
00245   @param   CONDITION    The condition to check
00246   @see skip_if()
00247   @note unlike assert() this check cannot be disabled
00248  */
00249 /*----------------------------------------------------------------------------*/
00250 #define bug_if(CONDITION)                                                      \
00251     do {                                                                       \
00252         cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),          \
00253                          goto cleanup, "Propagating an unexpected error, "     \
00254                          "please report to " PACKAGE_BUGREPORT);               \
00255         cpl_error_ensure(!(CONDITION), CPL_ERROR_UNSPECIFIED,                  \
00256                          goto cleanup, "Internal error, please report to "     \
00257                          PACKAGE_BUGREPORT);                                   \
00258     } while (0)
00259 
00260 /*----------------------------------------------------------------------------*/
00261 /*
00262   @brief   Conditional skip with error creation
00263   @param   CONDITION    The condition to check
00264   @param   ERROR        The error code to set
00265   @param   MSG          A printf-style error message. As a matter of
00266                         user-friendliness the message should mention any
00267                         value that caused the @em CONDITION to fail.
00268   @see skip_if()
00269   @note unlike assert() this check cannot be disabled
00270  */
00271 /*----------------------------------------------------------------------------*/
00272 #define error_if(CONDITION, ERROR, ...)                                 \
00273     cpl_error_ensure(cpl_error_get_code() == CPL_ERROR_NONE &&          \
00274                      !(CONDITION), ERROR, goto cleanup,  __VA_ARGS__)
00275 
00276 /*----------------------------------------------------------------------------*/
00277 /*
00278   @brief   Propagate a preexisting error, if any
00279   @param   MSG          A printf-style error message.
00280   @see skip_if()
00281  */
00282 /*----------------------------------------------------------------------------*/
00283 #define any_if(...)                                                     \
00284     cpl_error_ensure(!cpl_error_get_code(), cpl_error_get_code(),       \
00285                      goto cleanup,  __VA_ARGS__)
00286 
00287 /*----------------------------------------------------------------------------*/
00288 /*
00289   @brief   Define the single point of resource deallocation and return
00290   @see skip_if()
00291   @note end_skip should be used exactly once in functions that use skip_if() etc
00292 */
00293 /*----------------------------------------------------------------------------*/
00294 #define end_skip \
00295     do {                                                                     \
00296         cleanup:                                                             \
00297         if (cpl_error_get_code())                                            \
00298             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u with "  \
00299                           "error '%s' at %s", __LINE__,                      \
00300                           cpl_error_get_message(), cpl_error_get_where());   \
00301         else                                                                 \
00302             cpl_msg_debug(cpl_func, "Cleanup in " __FILE__ " line %u",       \
00303                           __LINE__);                                         \
00304     } while (0)
00305 
00306 
00307 /*----------------------------------------------------------------------------*/
00319 /*----------------------------------------------------------------------------*/
00320 #define irplib_ensure(CONDITION, ec, ...)                                      \
00321     cpl_error_ensure(CONDITION, ec, goto cleanup,  __VA_ARGS__)
00322 
00323 /*----------------------------------------------------------------------------*/
00353 /*----------------------------------------------------------------------------*/
00354 
00355 #define irplib_check(COMMAND, ...)                                             \
00356   do {                                                                         \
00357     cpl_errorstate irplib_check_prestate = cpl_errorstate_get();               \
00358     skip_if(0);                                                                \
00359     COMMAND;                                                                   \
00360         irplib_trace(); \
00361     irplib_ensure(cpl_errorstate_is_equal(irplib_check_prestate),              \
00362                   cpl_error_get_code(), __VA_ARGS__);                          \
00363         irplib_trace(); \
00364   } while (0)
00365 
00366 /*-----------------------------------------------------------------------------
00367                                    Function prototypes
00368  -----------------------------------------------------------------------------*/
00369 
00370 cpl_error_code irplib_dfs_save_image(cpl_frameset            *,
00371                                      const cpl_parameterlist *,
00372                                      const cpl_frameset      *,
00373                                      const cpl_image         *,
00374                                      cpl_type_bpp             ,
00375                                      const char              *,
00376                                      const char              *,
00377                                      const cpl_propertylist  *,
00378                                      const char              *,
00379                                      const char              *,
00380                                      const char              *);
00381 
00382 
00383 cpl_error_code irplib_dfs_save_propertylist(cpl_frameset            *,
00384                                             const cpl_parameterlist *,
00385                                             const cpl_frameset      *,
00386                                             const char              *,
00387                                             const char              *,
00388                                             const cpl_propertylist  *,
00389                                             const char              *,
00390                                             const char              *,
00391                                             const char              *);
00392 
00393 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset            *,
00394                                          const cpl_parameterlist *,
00395                                          const cpl_frameset      *,
00396                                          const cpl_imagelist     *,
00397                                          cpl_type_bpp             ,
00398                                          const char              *,
00399                                          const char              *,
00400                                          const cpl_propertylist  *,
00401                                          const char              *,
00402                                          const char              *,
00403                                          const char              *);
00404 
00405 cpl_error_code irplib_dfs_save_table(cpl_frameset            *,
00406                                      const cpl_parameterlist *,
00407                                      const cpl_frameset      *,
00408                                      const cpl_table         *,
00409                                      const cpl_propertylist  *,
00410                                      const char              *,
00411                                      const char              *,
00412                                      const cpl_propertylist  *,
00413                                      const char              *,
00414                                      const char              *,
00415                                      const char              *);
00416 
00417 cpl_error_code irplib_dfs_save_image_(cpl_frameset            *,
00418                                       cpl_propertylist        *,
00419                                       const cpl_parameterlist *,
00420                                       const cpl_frameset      *,
00421                                       const cpl_frame         *,
00422                                       const cpl_image         *,
00423                                       cpl_type                 ,
00424                                       const char              *,
00425                                       const cpl_propertylist  *,
00426                                       const char              *,
00427                                       const char              *,
00428                                       const char              *);
00429 
00430 void irplib_reset(void);
00431 int irplib_compare_tags(cpl_frame *, cpl_frame *);
00432 const char * irplib_frameset_find_file(const cpl_frameset *, const char *);
00433 const cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset *,
00434                                                        cpl_frame_group);
00435 
00436 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *, int *,
00437                                               int);
00438 
00439 #if defined HAVE_ISNAN && HAVE_ISNAN != 0
00440 #if !defined isnan && defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 0
00441 /* HP-UX and Solaris may have isnan() available at link-time
00442    without the prototype */
00443 int isnan(double);
00444 #endif
00445 #endif
00446 
00447 cpl_error_code
00448 irplib_dfs_table_convert(cpl_table *, cpl_frameset *, const cpl_frameset *,
00449                          int, char, const char *, const char *,
00450                          const cpl_parameterlist *, const char *,
00451                          const cpl_propertylist *, const cpl_propertylist *,
00452                          const char *, const char *, const char *,
00453                          cpl_boolean (*)(cpl_table *, const char *, int,
00454                                             const cpl_frame *,
00455                                             const cpl_parameterlist *),
00456                          cpl_error_code (*)(cpl_table *,
00457                                             const cpl_frameset *,
00458                                             const cpl_parameterlist *));
00459 
00460 cpl_error_code irplib_table_read_from_frameset(cpl_table *,
00461                                                const cpl_frameset *,
00462                                                int,
00463                                                char,
00464                                                const cpl_parameterlist *,
00465                                                cpl_boolean (*)
00466                                                (cpl_table *, const char *,
00467                                                 int, const cpl_frame *,
00468                                                 const cpl_parameterlist *));
00469 
00470 cpl_error_code irplib_image_split(const cpl_image *,
00471                                   cpl_image *, cpl_image *, cpl_image *,
00472                                   double, cpl_boolean,
00473                                   double, cpl_boolean,
00474                                   double, double,
00475                                   cpl_boolean, cpl_boolean, cpl_boolean);
00476 
00477 void irplib_errorstate_dump_warning(unsigned, unsigned, unsigned);
00478 void irplib_errorstate_dump_info(unsigned, unsigned, unsigned);
00479 void irplib_errorstate_dump_debug(unsigned, unsigned, unsigned);
00480 /* wrapper for replace deprecated function cpl_polynomial_fit_1d_create*/
00481 cpl_polynomial * irplib_polynomial_fit_1d_create(
00482         const cpl_vector    *   x_pos,
00483         const cpl_vector    *   values,
00484         int                     degree,
00485         double              *   mse
00486         );
00487 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
00488         const cpl_vector    *   x_pos,
00489         const cpl_vector    *   values,
00490         int                     degree,
00491         double              *   rechiq
00492         );
00493 /*----------------------------------------------------------------------------*/
00501 cpl_error_code irplib_frameset_sort(
00502         const cpl_frameset *  self,
00503         int* iindex,
00504         double* exptime);
00505 
00506 
00507 /* FIXME: add alloc_size(2) */
00508 void * irplib_aligned_malloc(size_t alignment, size_t size) CPL_ATTR_ALLOC;
00509 void * irplib_aligned_calloc(size_t alignment,
00510                              size_t nelem, size_t nbytes) CPL_ATTR_ALLOC;
00511 void irplib_aligned_free (void * aligned_ptr);
00512 
00513 
00514 /*-----------------------------------------------------------------------------
00515                                    Function inlines
00516  -----------------------------------------------------------------------------*/
00517 
00518 
00519 /*----------------------------------------------------------------------------*/
00523 /*----------------------------------------------------------------------------*/
00524 static __inline__ int irplib_isinf(double value)
00525 {
00526 /* documented only on 4.4, but available in at least 4.2 */
00527 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
00528     return __builtin_isinf(value);
00529 #elif defined HAVE_ISINF && HAVE_ISINF
00530     return isinf(value);
00531 #else
00532     return value != 0 && value == 2 * value;
00533 #endif
00534 }
00535 
00536 
00537 /*----------------------------------------------------------------------------*/
00541 /*----------------------------------------------------------------------------*/
00542 static __inline__ int irplib_isnan(double value)
00543 {
00544 /* documented only on 4.4, but available in at least 4.2 */
00545 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
00546     return __builtin_isnan(value);
00547 #elif defined HAVE_ISNAN && HAVE_ISNAN
00548     return isnan(value);
00549 #else
00550     return value != value;
00551 #endif
00552 }
00553 
00554 #endif
Generated on Mon Feb 17 15:01:44 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3