FORS Pipeline Reference Manual 4.9.9
fors_utils.c
00001 /* $Id: fors_utils.c,v 1.31 2011/10/13 14:26:54 cgarcia Exp $
00002  *
00003  * This file is part of the FORS Library
00004  * Copyright (C) 2002-2010 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  02110-1301 USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2011/10/13 14:26:54 $
00024  * $Revision: 1.31 $
00025  * $Name: fors-4_9_9 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_utils.h>
00033 
00034 #include <fors_pfits.h>
00035 
00036 #include <math.h>
00037 #include <stdbool.h>
00038 
00039 /*----------------------------------------------------------------------------*/
00043 /*----------------------------------------------------------------------------*/
00044 
00047 /* Required CPL version */
00048 #define REQ_CPL_MAJOR 4
00049 #define REQ_CPL_MINOR 0
00050 #define REQ_CPL_MICRO 0
00051 
00052 const double STDEV_PR_MAD = 1/0.6744897;  /* standard deviations per median
00053                                              absolute deviation,
00054                                              assuming a normal distribution */
00055 
00056 /*----------------------------------------------------------------------------*/
00064 /*----------------------------------------------------------------------------*/
00065 const char * fors_get_license(void)
00066 {
00067     const char *const fors_license = 
00068         "This file is currently part of the FORS Instrument Pipeline\n"
00069         "Copyright (C) 2002-2011 European Southern Observatory\n"
00070         "\n"
00071         "This program is free software; you can redistribute it and/or modify\n"
00072         "it under the terms of the GNU General Public License as published by\n"
00073         "the Free Software Foundation; either version 2 of the License, or\n"
00074         "(at your option) any later version.\n"
00075         "\n"
00076         "This program is distributed in the hope that it will be useful,\n"
00077         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00078         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00079         "GNU General Public License for more details.\n"
00080         "\n"
00081         "You should have received a copy of the GNU General Public License\n"
00082         "along with this program; if not, write to the Free Software Foundation,\n"
00083         "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n";
00084     return fors_license ;
00085 }
00086 
00087 /*----------------------------------------------------------------------------*/
00091 /*----------------------------------------------------------------------------*/
00092 void fors_print_banner(void)
00093 {
00094     cpl_msg_info(__func__, "*****************************************");
00095     cpl_msg_info(__func__, "Welcome to FORS Pipeline release %s",
00096                  PACKAGE_VERSION);
00097     cpl_msg_info(__func__, "*****************************************");
00098 }
00099 
00100 /*----------------------------------------------------------------------------*/
00105 /*----------------------------------------------------------------------------*/
00106 int
00107 fors_get_version_binary(void)
00108 {
00109     /*
00110       This is a good opportunity to verify that the compile time
00111       and runtime CPL versions are recent enough, and consistent 
00112     */
00113 
00114 #ifdef CPL_VERSION_CODE
00115 #if CPL_VERSION_CODE >= CPL_VERSION(REQ_CPL_MAJOR, REQ_CPL_MINOR, REQ_CPL_MICRO)
00116     cpl_msg_debug(cpl_func, 
00117                   "Compile time CPL version code was %d. "
00118                   "Required is version %d.%d.%d, code %d",
00119                   CPL_VERSION_CODE, REQ_CPL_MAJOR, REQ_CPL_MINOR, REQ_CPL_MICRO,
00120                   CPL_VERSION(REQ_CPL_MAJOR, REQ_CPL_MINOR, REQ_CPL_MICRO));
00121 #else
00122 #error CPL version too old
00123 #endif
00124 #else  /* ifdef CPL_VERSION_CODE */
00125 #error CPL_VERSION_CODE not defined. CPL version too old
00126 #endif
00127 
00128     if (cpl_version_get_major() < REQ_CPL_MAJOR ||
00129         (cpl_version_get_major() == REQ_CPL_MAJOR && 
00130          (int) cpl_version_get_minor() < REQ_CPL_MINOR) ||
00131         
00132         (cpl_version_get_major() == REQ_CPL_MAJOR &&
00133          cpl_version_get_minor() == REQ_CPL_MINOR && 
00134          (int) cpl_version_get_micro() < REQ_CPL_MICRO)
00135         ) {
00136         /* cast suppresses warning about comparing unsigned with 0 */
00137 
00138         cpl_msg_warning(cpl_func, 
00139                         "Runtime CPL version %s (%d.%d.%d) "
00140                         "is not supported. "
00141                         "Please update to CPL version %d.%d.%d or later", 
00142                         cpl_version_get_version(),
00143                         cpl_version_get_major(),
00144                         cpl_version_get_minor(),
00145                         cpl_version_get_micro(),
00146                         REQ_CPL_MAJOR,
00147                         REQ_CPL_MINOR,
00148                         REQ_CPL_MICRO);
00149     }
00150     else {
00151         cpl_msg_debug(cpl_func,
00152                       "Runtime CPL version %s (%d.%d.%d) detected, "
00153                       "%d.%d.%d or later required",
00154                       cpl_version_get_version(),
00155                       cpl_version_get_major(),
00156                       cpl_version_get_minor(),
00157                       cpl_version_get_micro(),
00158                       REQ_CPL_MAJOR,
00159                       REQ_CPL_MINOR,
00160                       REQ_CPL_MICRO);
00161     }
00162 
00163     /* Fixme: Test that compile and runtime versions compare equal.
00164        This requires CPL to provide the major/minor/micro version numbers
00165        as preprocessor symbols, not just a code. */
00166     
00167     /* As defined in config.h */
00168     return FORS_BINARY_VERSION;
00169 }
00170 
00171 
00172 /*----------------------------------------------------------------------------*/
00180 /*----------------------------------------------------------------------------*/
00181 double fors_rand_gauss(void)
00182 {
00183     static double V1, V2, S;
00184     static int phase = 0;
00185     double X;
00186     
00187     if(phase == 0) {
00188     do {
00189         double U1 = (double)rand() / RAND_MAX;
00190         double U2 = (double)rand() / RAND_MAX;
00191         
00192         V1 = 2 * U1 - 1;
00193         V2 = 2 * U2 - 1;
00194         S = V1 * V1 + V2 * V2;
00195     } while(S >= 1 || S == 0);
00196     
00197     X = V1 * sqrt(-2 * log(S) / S);
00198     } else
00199     X = V2 * sqrt(-2 * log(S) / S);
00200     
00201     phase = 1 - phase;
00202     
00203     return X;
00204 }
00205 
00206 /*----------------------------------------------------------------------------*/
00210 /*----------------------------------------------------------------------------*/
00211 double fors_tools_get_kth_double(
00212     double  *   a,
00213     int         n,
00214     int         k)
00215 {
00216     double x ;
00217     int    i, j, l, m ;
00218 
00219     cpl_ensure(a, CPL_ERROR_NULL_INPUT, 0.00) ;
00220 
00221     l=0 ; m=n-1 ;
00222     while (l<m) {
00223         x=a[k] ;
00224         i=l ;
00225         j=m ;
00226         do {
00227             while (a[i]<x) i++ ;
00228             while (x<a[j]) j-- ;
00229             if (i<=j) {
00230                 //CPL_DOUBLE_SWAP(a[i],a[j]) ;
00231                 double temp = a[i];
00232                 a[i] = a[j];
00233                 a[j] = temp;
00234                 i++ ; j-- ;
00235             }
00236         } while (i<=j) ;
00237         if (j<k) l=i ;
00238         if (k<i) m=j ;
00239     }
00240     return a[k] ;
00241 }
00242 
00243 #undef cleanup
00244 #define cleanup
00245 /*----------------------------------------------------------------------------*/
00249 /*----------------------------------------------------------------------------*/
00250 float fors_tools_get_median_float(float *a, int n)
00251 {
00252     return (n % 2 == 0) ?
00253         (fors_tools_get_kth_float(a, n, (n-1)/2) +
00254          fors_tools_get_kth_float(a, n, (n/2))) / 2.0
00255         : fors_tools_get_kth_float(a, n, n/2);
00256 }
00257 
00258 #undef cleanup
00259 #define cleanup
00260 /*----------------------------------------------------------------------------*/
00264 /*----------------------------------------------------------------------------*/
00265 float fors_tools_get_median_fast_float(float *a, int n)
00266 {
00267     return fors_tools_get_kth_float(a, n, n/2);
00268 }
00269 
00270 #undef cleanup
00271 #define cleanup
00272 /*----------------------------------------------------------------------------*/
00276 /*----------------------------------------------------------------------------*/
00277 float fors_tools_get_kth_float(
00278     float  *   a,
00279     int         n,
00280     int         k)
00281 {
00282     float x ;
00283     int    i, j, l, m ;
00284 
00285     cpl_ensure(a, CPL_ERROR_NULL_INPUT, 0.00) ;
00286 
00287     l=0 ; m=n-1 ;
00288     while (l<m) {
00289         x=a[k] ;
00290         i=l ;
00291         j=m ;
00292         do {
00293             while (a[i]<x) i++ ;
00294             while (x<a[j]) j-- ;
00295             if (i<=j) {
00296                 //CPL_FLOAT_SWAP(a[i],a[j]) ;
00297                 float temp = a[i];
00298                 a[i] = a[j];
00299                 a[j] = temp;
00300                 i++ ; j-- ;
00301             }
00302         } while (i<=j) ;
00303         if (j<k) l=i ;
00304         if (k<i) m=j ;
00305     }
00306     return a[k] ;
00307 }
00308 
00309 #undef cleanup
00310 #define cleanup
00311 /*----------------------------------------------------------------------------*/
00317 /*----------------------------------------------------------------------------*/
00318 const char *
00319 fors_frame_get_type_string(const cpl_frame *f)
00320 {
00321     assure( f != NULL, return NULL, "Null frame" );
00322 
00323     switch (cpl_frame_get_type(f)) {
00324     case CPL_FRAME_TYPE_NONE:   return "NONE";      break;
00325     case CPL_FRAME_TYPE_IMAGE:  return "IMAGE";     break;
00326     case CPL_FRAME_TYPE_MATRIX: return "MATRIX";    break;
00327     case CPL_FRAME_TYPE_TABLE:  return "TABLE";     break;
00328     default: 
00329         return "unrecognized frame type";      
00330         break;
00331     }
00332 }
00333 
00334 #undef cleanup
00335 #define cleanup
00336 /*----------------------------------------------------------------------------*/
00342 /*----------------------------------------------------------------------------*/
00343 const char *
00344 fors_frame_get_group_string(const cpl_frame *f)
00345 {
00346     assure( f != NULL, return NULL, "Null frame" );
00347     
00348     switch (cpl_frame_get_group(f)) {
00349     case CPL_FRAME_GROUP_NONE:    return "NONE";                     break;
00350     case CPL_FRAME_GROUP_RAW:     return CPL_FRAME_GROUP_RAW_ID;     break;
00351     case CPL_FRAME_GROUP_CALIB:   return CPL_FRAME_GROUP_CALIB_ID;   break;
00352     case CPL_FRAME_GROUP_PRODUCT: return CPL_FRAME_GROUP_PRODUCT_ID; break;
00353     default:
00354         return "unrecognized frame group";
00355         break;
00356     }
00357 }
00358 
00359 #undef cleanup
00360 #define cleanup
00361 /*----------------------------------------------------------------------------*/
00367 /*----------------------------------------------------------------------------*/
00368 const char *
00369 fors_frame_get_level_string(const cpl_frame *f)
00370 {
00371     assure( f != NULL, return NULL, "Null frame" );
00372     
00373     switch (cpl_frame_get_level(f)) {
00374     case CPL_FRAME_LEVEL_NONE:        return "NONE";         break;
00375     case CPL_FRAME_LEVEL_TEMPORARY:   return "TEMPORARY";    break;
00376     case CPL_FRAME_LEVEL_INTERMEDIATE:return "INTERMEDIATE"; break;
00377     case CPL_FRAME_LEVEL_FINAL:       return "FINAL";        break;
00378     default: 
00379         return "unrecognized frame level";
00380         break;
00381     }
00382 }
00383 
00384 /*----------------------------------------------------------------------------*/
00391 /*----------------------------------------------------------------------------*/
00392 void
00393 fors_frameset_print(const cpl_frameset *frames)
00394 {
00395     /* Two special cases: a NULL frame set and an empty frame set */
00396 
00397     if (frames == NULL) {
00398         cpl_msg_info(cpl_func, "NULL");
00399     }
00400     else {
00401         const cpl_frame *f = NULL;
00402         f = cpl_frameset_get_first_const(frames);
00403         
00404         if (f == NULL) {
00405             cpl_msg_info(cpl_func, "[Empty frame set]");
00406         }
00407         else {
00408             while(f != NULL) {
00409                 fors_frame_print(f);
00410                 f = cpl_frameset_get_next_const(frames);
00411             }
00412         }
00413     }
00414     
00415     return;
00416 }
00417 
00418 /*----------------------------------------------------------------------------*/
00425 /*----------------------------------------------------------------------------*/
00426 void
00427 fors_frame_print(const cpl_frame *f)
00428 {
00429     if (f == NULL) {
00430         cpl_msg_info(cpl_func, "NULL");
00431     }
00432     else {
00433         const char *filename = cpl_frame_get_filename(f);
00434         const char *tag = cpl_frame_get_tag(f);
00435         
00436         if (filename == NULL) {
00437             filename = "NULL";
00438         }
00439         if (tag == NULL) {
00440             tag = "NULL";
00441         }
00442         
00443         cpl_msg_info(cpl_func, "%-7s %-20s %s", 
00444                      fors_frame_get_group_string(f),
00445                      tag,
00446                      filename);
00447         
00448         cpl_msg_debug(cpl_func, "type \t= %s",  fors_frame_get_type_string(f));
00449         cpl_msg_debug(cpl_func, "group \t= %s", fors_frame_get_group_string(f));
00450         cpl_msg_debug(cpl_func, "level \t= %s", fors_frame_get_level_string(f));
00451     }
00452     
00453     return;
00454 }
00455 
00456 
00457 #undef cleanup
00458 #define cleanup
00459 /*----------------------------------------------------------------------------*/
00466 /*----------------------------------------------------------------------------*/
00467 cpl_frameset *
00468 fors_frameset_extract(const cpl_frameset *frames,
00469                       const char *tag)
00470 {
00471     cpl_frameset *subset = NULL;
00472     const cpl_frame *f;
00473 
00474     assure( frames != NULL, return NULL, "Null frameset" );
00475     assure( tag    != NULL, return NULL, "Null tag" );
00476     
00477     subset = cpl_frameset_new();
00478 
00479     for (f = cpl_frameset_find_const(frames, tag);
00480          f != NULL;
00481          f = cpl_frameset_find_const(frames, NULL)) {
00482 
00483         cpl_frameset_insert(subset, cpl_frame_duplicate(f));
00484     }
00485 
00486     return subset;
00487 }
00488 
00489 /*----------------------------------------------------------------------------*/
00495 /*----------------------------------------------------------------------------*/
00496 const char *fors_type_get_string(cpl_type t)
00497 {
00498     /* Note that CPL_TYPE_STRING is shorthand
00499        for CPL_TYPE_CHAR | CPL_TYPE_FLAG_ARRAY . */
00500     
00501     if (!(t & CPL_TYPE_FLAG_ARRAY))
00502         switch(t & (~CPL_TYPE_FLAG_ARRAY)) {
00503         case CPL_TYPE_CHAR:       return "char";    break;
00504         case CPL_TYPE_UCHAR:      return "uchar";   break;
00505         case CPL_TYPE_BOOL:       return "boolean"; break;
00506         case CPL_TYPE_INT:        return "int";     break;
00507         case CPL_TYPE_UINT:       return "uint";    break;
00508         case CPL_TYPE_LONG:       return "long";    break;
00509         case CPL_TYPE_ULONG:      return "ulong";   break;
00510         case CPL_TYPE_FLOAT:      return "float";   break;
00511         case CPL_TYPE_DOUBLE:     return "double";  break;
00512         case CPL_TYPE_POINTER:    return "pointer"; break;
00513         case CPL_TYPE_INVALID:    return "invalid"; break;
00514         default:
00515             return "unrecognized type";
00516         }
00517     else
00518         switch(t & (~CPL_TYPE_FLAG_ARRAY)) {
00519         case CPL_TYPE_CHAR:       return "string (char array)"; break;
00520         case CPL_TYPE_UCHAR:      return "uchar array";         break;
00521         case CPL_TYPE_BOOL:       return "boolean array";       break;
00522         case CPL_TYPE_INT:        return "int array";           break;
00523         case CPL_TYPE_UINT:       return "uint array";          break;
00524         case CPL_TYPE_LONG:       return "long array";          break;
00525         case CPL_TYPE_ULONG:      return "ulong array";         break;
00526         case CPL_TYPE_FLOAT:      return "float array";         break;
00527         case CPL_TYPE_DOUBLE:     return "double array";        break;
00528         case CPL_TYPE_POINTER:    return "pointer array";       break;
00529         case CPL_TYPE_INVALID:    return "invalid (array)";     break;
00530         default:
00531             return "unrecognized type";
00532         }
00533 }
00534 
00535 /*----------------------------------------------------------------------------*/
00543 /*----------------------------------------------------------------------------*/
00544 void
00545 fors_parameterlist_set_defaults(cpl_parameterlist *parlist)
00546 {
00547     cpl_parameter *p = NULL;
00548     bool parameter_is_set;
00549 
00550     p = cpl_parameterlist_get_first(parlist);
00551     while (p != NULL) {
00552 
00553         /*   EsoRex bug: (well, it's an undocumented-feature 
00554              that EsoRex, unlike Gasgano, reads the default flag):
00555         */
00556         parameter_is_set = cpl_parameter_get_default_flag(p);
00557         
00558         if (!parameter_is_set) {
00559             cpl_type ptype = cpl_parameter_get_type(p);
00560             switch (ptype) {
00561             case CPL_TYPE_BOOL:
00562                 cpl_parameter_set_bool(p, cpl_parameter_get_default_bool(p));
00563                 break;
00564             case CPL_TYPE_INT:
00565                 cpl_parameter_set_int(p, cpl_parameter_get_default_int(p));
00566                 break;
00567             case CPL_TYPE_DOUBLE:
00568                 cpl_parameter_set_double(p, cpl_parameter_get_default_double(p));
00569                 break;
00570             case CPL_TYPE_STRING:
00571                 cpl_parameter_set_string(p, cpl_parameter_get_default_string(p));
00572                 break;
00573             default:
00574                 assure( false, return, "Unknown type of parameter '%s'", 
00575                         cpl_parameter_get_name(p));
00576             }
00577         }
00578         p = cpl_parameterlist_get_next(parlist);
00579     }
00580     
00581     return;
00582 }
00583 
00584 #ifdef CPL_IS_NOT_CRAP
00585 #else
00586 
00597 cpl_image *fors_imagelist_collapse_create(const cpl_imagelist *ilist)
00598 {
00599     cpl_image *result = cpl_imagelist_collapse_create(ilist);
00600     
00601     if (result != NULL && cpl_image_count_rejected(result) == 0) {
00602         cpl_image_accept_all(result);
00603     }
00604     
00605     return result;
00606 }
00607 
00608 
00616 cpl_image *fors_imagelist_collapse_median_create(const cpl_imagelist *ilist)
00617 {
00618     cpl_image *result = cpl_imagelist_collapse_median_create(ilist);
00619     
00620     if (result != NULL && cpl_image_count_rejected(result) == 0) {
00621         cpl_image_accept_all(result);
00622     }
00623     
00624     return result;
00625 }
00626 #endif
00627 
00628 #undef cleanup
00629 #define cleanup
00630 
00636 double fors_angle_diff(const double *a1, const double *a2)
00637 {
00638     assure( a1 != NULL, return -1, NULL );
00639     assure( a2 != NULL, return -1, NULL );
00640 
00641     double d = *a1 - *a2;
00642 
00643     while (d < -M_PI) d += 2*M_PI;
00644     while (d >  M_PI) d -= 2*M_PI;
00645     
00646     return fabs(d);
00647 }
00648 
00649 #define MAX_MESSAGE_LENGTH 1024
00650 #undef cleanup
00651 #define cleanup
00652 
00660 void fors_msg_macro(cpl_msg_severity level, const char *fct, const char *format, ...)
00661 {
00662     char message[MAX_MESSAGE_LENGTH];
00663     va_list al;
00664     
00665     va_start(al, format);
00666     vsnprintf(message, MAX_MESSAGE_LENGTH - 1, format, al);
00667     va_end(al);
00668     
00669     message[MAX_MESSAGE_LENGTH - 1] = '\0';
00670 
00671     switch(level) {
00672     case CPL_MSG_DEBUG:   cpl_msg_debug  (fct, "%s", message); break;
00673     case CPL_MSG_INFO:    cpl_msg_info   (fct, "%s", message); break;
00674     case CPL_MSG_WARNING: cpl_msg_warning(fct, "%s", message); break;
00675     case CPL_MSG_ERROR:   cpl_msg_error  (fct, "%s", message); break;
00676     default: 
00677         cpl_msg_error(fct, "Unknown message level: %d", level);
00678         cpl_msg_error(fct, message);
00679         break;
00680     }
00681     return;
00682 }
00683 
00684 
00685 #undef cleanup
00686 #define cleanup
00687 
00696 double fors_utils_median_corr(int n)
00697 {
00698     assure( n > 0, return -1, "Illegal number: %d", n);
00699 
00700     const double c[] = {
00701     /* Format:  n, corr(n), error
00702        Numbers computed by numerical experiment 
00703        (i.e. generate n normal distributed numbers, 
00704        get the median (if n is even, mean of middle elements),
00705        measure the median error and median's error error)
00706     */
00707     1, 0.999892, 0.000405,
00708     2, 0.999868, 0.000413,
00709     3, 1.159685, 0.000467,
00710     4, 1.091738, 0.000431,
00711     5, 1.197186, 0.000473,
00712     6, 1.134358, 0.000454,
00713     7, 1.213364, 0.000481,
00714     8, 1.159116, 0.000466,
00715     9, 1.223264, 0.000487,
00716     10, 1.176252, 0.000468,
00717     11, 1.228136, 0.000491,
00718     12, 1.187431, 0.000476,
00719     13, 1.231643, 0.000498,
00720     14, 1.195670, 0.000488,
00721     15, 1.235724, 0.000491,
00722     16, 1.201223, 0.000482,
00723     17, 1.237393, 0.000487,
00724     18, 1.207451, 0.000487,
00725     19, 1.239745, 0.000502,
00726     20, 1.212639, 0.000490,
00727     21, 1.241837, 0.000498,
00728     22, 1.216330, 0.000492,
00729     23, 1.244426, 0.000508,
00730     24, 1.221290, 0.000493,
00731     25, 1.246456, 0.000507,
00732     26, 1.224591, 0.000498,
00733     27, 1.248254, 0.000500,
00734     28, 1.227300, 0.000498,
00735     29, 1.248467, 0.000503,
00736     30, 1.229101, 0.000485,
00737     31, 1.248270, 0.000498,
00738     32, 1.231945, 0.000493,
00739     33, 1.249087, 0.000509,
00740     34, 1.231960, 0.000486,
00741     35, 1.249525, 0.000500,
00742     36, 1.231679, 0.000496,
00743     37, 1.249156, 0.000510,
00744     38, 1.233630, 0.000494,
00745     39, 1.249173, 0.000483,
00746     40, 1.233669, 0.000492,
00747     41, 1.248756, 0.000510,
00748     42, 1.235170, 0.000493,
00749     43, 1.248498, 0.000497,
00750     44, 1.235864, 0.000501,
00751     45, 1.248986, 0.000487,
00752     46, 1.236148, 0.000495,
00753     47, 1.248720, 0.000507,
00754     48, 1.236461, 0.000499,
00755     49, 1.248677, 0.000500,
00756     50, 1.236832, 0.000499,
00757     51, 1.249143, 0.000510,
00758     52, 1.237251, 0.000497,
00759     53, 1.248619, 0.000510,
00760     54, 1.237826, 0.000490,
00761     55, 1.249292, 0.000499,
00762     56, 1.238721, 0.000492,
00763     57, 1.248719, 0.000502,
00764     58, 1.238830, 0.000482,
00765     59, 1.248869, 0.000491,
00766     60, 1.239892, 0.000501,
00767     61, 1.248980, 0.000505,
00768     62, 1.239435, 0.000506,
00769     63, 1.249534, 0.000506,
00770     64, 1.240748, 0.000507,
00771     65, 1.249158, 0.000501,
00772     66, 1.240053, 0.000503,
00773     67, 1.248843, 0.000500,
00774     68, 1.241417, 0.000499,
00775     69, 1.249386, 0.000506,
00776     70, 1.241106, 0.000499,
00777     71, 1.249540, 0.000509,
00778     72, 1.240998, 0.000491,
00779     73, 1.250202, 0.000502,
00780     74, 1.241989, 0.000491,
00781     75, 1.249485, 0.000497,
00782     76, 1.242218, 0.000503,
00783     77, 1.249733, 0.000506,
00784     78, 1.240815, 0.000517,
00785     79, 1.250652, 0.000494,
00786     80, 1.241356, 0.000501,
00787     81, 1.250115, 0.000511,
00788     82, 1.241610, 0.000506,
00789     83, 1.249751, 0.000504,
00790     84, 1.242905, 0.000485,
00791     85, 1.249906, 0.000512,
00792     86, 1.243211, 0.000502,
00793     87, 1.250671, 0.000503,
00794     88, 1.242750, 0.000489,
00795     89, 1.249779, 0.000502,
00796     90, 1.243191, 0.000507,
00797     91, 1.250325, 0.000494,
00798     92, 1.243411, 0.000493,
00799     93, 1.250774, 0.000508,
00800     94, 1.244007, 0.000492,
00801     95, 1.249777, 0.000503,
00802     96, 1.243910, 0.000507,
00803     97, 1.250147, 0.000503,
00804     98, 1.243634, 0.000501,
00805     99, 1.250931, 0.000504,
00806     100, 1.243948, 0.000504};
00807 
00808     if (n <= 100) {
00809     return c[(n-1)*3 + 1];
00810     }
00811     else {
00812         return sqrt(M_PI/2);
00813     }
00814 }
00815