irplib_std.c

00001 /* $Id: irplib_std.c,v 1.23 2007/05/24 07:46:07 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: 2007/05/24 07:46:07 $
00024  * $Revision: 1.23 $
00025  * $Name: uves-3_3_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <string.h>
00037 #include <math.h>
00038 #include <float.h>
00039 
00040 #include <cpl.h>
00041 
00042 #include "irplib_std.h"
00043 #include "irplib_irlist.h"
00044 
00045 /*----------------------------------------------------------------------------*/
00049 /*----------------------------------------------------------------------------*/
00052 #ifndef IRPLIB_STD_MAXRADIUS
00053   /* 2 arcminutes */
00054 #define IRPLIB_STD_MAXRADIUS 2.0
00055 #endif
00056 
00057 /*-----------------------------------------------------------------------------
00058                         Private function prototypes
00059  -----------------------------------------------------------------------------*/
00060 
00061 
00062 static double irplib_great_circle_dist(double, double, double, double);
00063 static int irplib_std_setactive(const char *) ;
00064 static const irplib_irstd * irplib_std_get_closest_star(double, double) ;
00065 
00066 /*-----------------------------------------------------------------------------
00067                                    Functions code
00068  -----------------------------------------------------------------------------*/
00069 
00070 /*----------------------------------------------------------------------------*/
00081 /*----------------------------------------------------------------------------*/
00082 irplib_irstd * irplib_std_get_mag_one_cat(
00083         double          ra,
00084         double          dec,
00085         irplib_band     band,
00086         const char  *   cat,
00087         double      *   mag)
00088 {
00089     const irplib_irstd      *   refstar ;
00090 
00091     /* Test entries */
00092     if (cat == NULL) return NULL ;
00093     if (!strcmp(cat, "all")) return NULL ;
00094 
00095     /* Search closest star */
00096     irplib_std_setactive("none");
00097     irplib_std_setactive(cat) ;
00098     refstar = irplib_std_get_closest_star(ra, dec) ;
00099 
00100     /* Star not found */
00101     if (refstar == NULL) return NULL ;
00102 
00103     cpl_msg_info(cpl_func, "Looking for magnitude (in band %d of %d) for "
00104                  "closest star '%s' at (RA,DEC)=(%g,%g)", band, BAND_UNKNOWN,
00105                  refstar->name ? refstar->name : "<NULL>", refstar->ra,
00106                  refstar->dec);
00107 
00108     /* Keep the star if magnitude is known */
00109     switch (band) {
00110         case BAND_J:
00111             if (refstar->mag_J < 98.0) {
00112                 *mag = (double)(refstar->mag_J) ;
00113                 return (irplib_irstd*)refstar ;
00114             } else return NULL ;
00115         case BAND_H:
00116             if (refstar->mag_H < 98.0) {
00117                 *mag = (double)(refstar->mag_H) ;
00118                 return (irplib_irstd*)refstar ;
00119             } else return NULL ;
00120         case BAND_K:
00121             if (refstar->mag_K < 98.0) {
00122                 *mag = (double)(refstar->mag_K) ;
00123                 return (irplib_irstd*)refstar ;
00124             } else return NULL ;
00125         case BAND_KS:
00126             if (refstar->mag_Ks < 98.0) {
00127                 *mag = (double)(refstar->mag_Ks) ;
00128                 return (irplib_irstd*)refstar ;
00129             } else return NULL ;
00130         case BAND_L:
00131             if (refstar->mag_L < 98.0) {
00132                 *mag = (double)(refstar->mag_L) ;
00133                 return (irplib_irstd*)refstar ;
00134             } else return NULL ;
00135         case BAND_M:
00136             if (refstar->mag_M < 98.0) {
00137                 *mag = (double)(refstar->mag_M) ;
00138                 return (irplib_irstd*)refstar ;
00139             } else return NULL ;
00140         case BAND_LP:
00141             if (refstar->mag_Lp < 98.0) {
00142                 *mag = (double)(refstar->mag_Lp) ;
00143                 return (irplib_irstd*)refstar ;
00144             } else return NULL ;
00145         case BAND_MP:
00146             if (refstar->mag_Mp < 98.0) {
00147                 *mag = (double)(refstar->mag_Mp) ;
00148                 return (irplib_irstd*)refstar ;
00149             } else return NULL ;
00150         default:
00151             return NULL ;
00152     }
00153 }
00154 
00155 /*----------------------------------------------------------------------------*/
00168 /*----------------------------------------------------------------------------*/
00169 cpl_vector * irplib_std_get_conversion(
00170         const cpl_bivector  *   spec,
00171         double                  dit,
00172         double                  surface,
00173         double                  gain,
00174         double                  mag)
00175 {
00176     double                  h = 6.62e-27 ;
00177     double                  c = 3e18 ;
00178     cpl_vector      *       wave ;
00179     cpl_vector      *       extr ;
00180     cpl_vector      *       out ;
00181     double                  factor ;
00182 
00183     /* Test entries */
00184     if (spec == NULL) return NULL ;
00185     if (dit <= 0.0) return NULL ;
00186     
00187     /* Get the extracted spectrum */
00188     wave = cpl_bivector_get_x(spec) ;
00189     extr = cpl_bivector_get_y(spec) ;
00190 
00191     /* Get the spectrum */
00192     out = cpl_vector_duplicate(extr) ;
00193     
00194     /* Divide by DIT */
00195     cpl_vector_divide_scalar(out, dit) ;
00196 
00197     /* Divide by the surface */
00198     cpl_vector_divide_scalar(out, surface) ;
00199 
00200     /* Multiply by the gain */
00201     cpl_vector_multiply_scalar(out, gain) ;
00202 
00203     /* Multiply by the difference magnitude */
00204     factor = pow(10, mag/2.5) ;
00205     cpl_vector_multiply_scalar(out, factor) ;
00206     
00207     /* Divide by the dispersion */
00208     factor = (cpl_vector_get(wave, cpl_vector_get_size(wave)-1) -
00209             cpl_vector_get(wave, 0)) / cpl_vector_get_size(wave) ;
00210     cpl_vector_divide_scalar(out, factor) ;
00211     
00212     /* Multiply by the energy of the photon */
00213     cpl_vector_multiply_scalar(out, h*c) ;
00214     cpl_vector_divide(out, wave) ;
00215     
00216     return out ;
00217 }
00218 
00219 /*----------------------------------------------------------------------------*/
00227 /*----------------------------------------------------------------------------*/
00228 cpl_vector * irplib_std_get_mag_zero(
00229         const cpl_bivector  *   sed,
00230         const cpl_vector    *   waves,
00231         double                  cent_wl)
00232 {
00233     double              wmin, wmax, wstep ;
00234     int                 nb_sed ;
00235     double          *   sed_x ;
00236     double          *   sed_y ;
00237     cpl_bivector    *   sed_loc ;
00238     double          *   sed_loc_x ;
00239     double          *   sed_loc_y ;
00240     cpl_vector      *   out ;
00241     cpl_bivector    *   out_biv ;
00242     double              f0_jan, f0_erg, cent_val ;
00243     int                 i ;
00244 
00245     /* Test entries */
00246     if (sed == NULL) return NULL ;
00247     if (waves == NULL) return NULL ;
00248 
00249     /* Initialise */
00250     nb_sed = cpl_bivector_get_size(sed) ;
00251     sed_x = cpl_bivector_get_x_data(sed) ;
00252     sed_y = cpl_bivector_get_y_data(sed) ;
00253     wstep = sed_x[1] - sed_x[0] ;
00254     wmin = cpl_vector_get(waves, 0) ;
00255     wmax = cpl_vector_get(waves, cpl_vector_get_size(waves)-1) ;
00256     
00257     /* Expand sed with 0 to have it bigger than the required wavelengths */
00258     sed_loc = cpl_bivector_new(nb_sed + 4) ;
00259     sed_loc_x = cpl_bivector_get_x_data(sed_loc) ;
00260     sed_loc_y = cpl_bivector_get_y_data(sed_loc) ;
00261     for (i=0 ; i<nb_sed ; i++) {
00262         sed_loc_x[i+2] = sed_x[i] ;
00263         sed_loc_y[i+2] = sed_y[i] ;
00264     }
00265 
00266     /* Low bound */
00267     sed_loc_x[1] = sed_loc_x[2] - wstep ;
00268     if (sed_loc_x[2] < wmin) {
00269         sed_loc_x[0] = sed_loc_x[1] - wstep ;
00270     } else {
00271         sed_loc_x[0] = wmin - wstep ;
00272     }
00273     sed_loc_y[0] = 1e20 ; 
00274     sed_loc_y[1] = 1e20 ; 
00275         
00276     /* High bound */
00277     sed_loc_x[nb_sed+2] = sed_loc_x[nb_sed+1] + wstep ;
00278     if (sed_loc_x[nb_sed+1] > wmax) {
00279         sed_loc_x[nb_sed+3] = sed_loc_x[nb_sed+2] + wstep ; 
00280     } else {
00281         sed_loc_x[nb_sed+3] = wmax + wstep ; 
00282     }
00283     sed_loc_y[nb_sed+2] = 1e20 ; 
00284     sed_loc_y[nb_sed+3] = 1e20 ; 
00285 
00286     /* Create the output bivector */
00287     out = cpl_vector_duplicate(waves) ;
00288     out_biv = cpl_bivector_wrap_vectors((cpl_vector*)waves, out) ;
00289  
00290     /* Interpolate */
00291     if (cpl_bivector_interpolate_linear(out_biv, sed_loc) != CPL_ERROR_NONE) {
00292         cpl_msg_error(cpl_func, "Cannot interpolate the wavelength") ;
00293         cpl_bivector_unwrap_vectors(out_biv) ;
00294         cpl_vector_delete(out) ;
00295         cpl_bivector_delete(sed_loc) ;
00296         return NULL ;
00297     }
00298     cpl_bivector_unwrap_vectors(out_biv) ;
00299     cpl_bivector_delete(sed_loc) ;
00300 
00301     /* Compute f0_jan */
00302     f0_jan = 5513.15 / ( pow(cent_wl,3) * (exp(1.2848/cent_wl)-1) ) ;
00303 
00304     /* Convert f0 Jansky -> ergs/s/cm^2/Angstrom */
00305     f0_erg = f0_jan * 1e-26 * 1e7 * 3e18 / (1e4 * cent_wl*cent_wl*1e4*1e4) ;
00306     
00307     /* Scale out so that the central value is f0 */
00308     cent_val = cpl_vector_get(out, cpl_vector_get_size(out)/2) ;
00309     if (cent_val <= 0.0) {
00310         cpl_msg_error(cpl_func, "Negative or 0 central value") ;
00311         cpl_vector_delete(out) ;
00312         return NULL ;
00313     }
00314     cpl_vector_multiply_scalar(out, f0_erg/cent_val) ;
00315     
00316     /* Return */
00317     return out ;
00318 }
00319 
00320 /*----------------------------------------------------------------------------*/
00330 /*----------------------------------------------------------------------------*/
00331 cpl_bivector * irplib_std_get_sed(
00332         const char  *   seds_file,
00333         const char  *   sptype)
00334 {
00335     cpl_table           *   seds ;
00336     cpl_bivector        *   out ;
00337     cpl_vector          *   wave ;
00338     cpl_vector          *   sed ;
00339     cpl_bivector        *   tmp ;
00340     int                     nlines ;
00341   
00342     /* Test entries */
00343     if (seds_file == NULL) return NULL ;
00344     if (sptype == NULL) return NULL ;
00345     
00346     /* Load the table */
00347     if ((seds = cpl_table_load(seds_file, 1, 0)) == NULL) {
00348         cpl_msg_error(cpl_func, "Cannot load the table") ;
00349         return NULL ;
00350     }
00351    
00352     /* Check if the column is there */
00353     if (!cpl_table_has_column(seds, sptype)) {
00354         cpl_msg_error(cpl_func, "SED of the requested star not available") ;
00355         cpl_table_delete(seds) ;
00356         return NULL ;
00357     }
00358     
00359     /* Get the nb lines */
00360     nlines = cpl_table_get_nrow(seds) ;
00361 
00362     /* Get the wavelength as a vector */
00363     if ((wave = cpl_vector_wrap(nlines, 
00364             cpl_table_get_data_double(seds, "Wavelength"))) == NULL) {
00365         cpl_msg_error(cpl_func, "Cannot get the Wavelength column") ;
00366         cpl_table_delete(seds) ;
00367         return NULL ;
00368     }
00369  
00370     /* Get the SED as a vector */
00371     if ((sed = cpl_vector_wrap(nlines, 
00372             cpl_table_get_data_double(seds, sptype))) == NULL) {
00373         cpl_msg_error(cpl_func, "Cannot get the SED column") ;
00374         cpl_table_delete(seds) ;
00375         cpl_vector_unwrap(wave) ;
00376         return NULL ;
00377     }
00378     tmp = cpl_bivector_wrap_vectors(wave, sed) ;
00379 
00380     /* Create the output bivector */
00381     out = cpl_bivector_duplicate(tmp) ;
00382 
00383     /* Free */
00384     cpl_bivector_unwrap_vectors(tmp) ;
00385     cpl_vector_unwrap(wave) ;
00386     cpl_vector_unwrap(sed) ;
00387     cpl_table_delete(seds) ;
00388     
00389     /* Return  */
00390     return out ;
00391 }
00392 
00393 /*----------------------------------------------------------------------------*/
00401 /*----------------------------------------------------------------------------*/
00402 irplib_irstd * irplib_std_get_type(
00403         double          ra,
00404         double          dec)
00405 {
00406     char            **  catalog_names ;
00407     const irplib_irstd * refstar ;
00408     int                 nfound ;
00409     const irplib_irstd ** refstars ;
00410     int                 i, j ;
00411 
00412     /* Initialise */
00413     catalog_names = (char**)irplib_irlist_catalogs ;
00414     nfound = 0 ;
00415 
00416     /* Loop on the catalogs and get the closest stars */
00417     for (i=0 ; catalog_names[i] ; i++) {
00418         irplib_std_setactive("none");
00419         irplib_std_setactive(catalog_names[i]) ;
00420         refstar = irplib_std_get_closest_star(ra, dec) ;
00421         if (refstar != NULL) nfound ++ ;
00422     }
00423     refstars = cpl_malloc(nfound*sizeof(irplib_irstd*)) ;
00424     j = 0 ;
00425     for (i=0 ; catalog_names[i] ; i++) {
00426         irplib_std_setactive("none");
00427         irplib_std_setactive(catalog_names[i]) ;
00428         refstar = irplib_std_get_closest_star(ra, dec) ;
00429         if (refstar != NULL) {
00430             refstars[j] = refstar ;
00431             j++ ;
00432         }
00433     }
00434 
00435     /* Keep the first one whose type is known */
00436     refstar = NULL ;
00437     for (i=0 ; i<nfound ; i++) {
00438         if (strcmp(refstars[i]->sptype, "--")) {
00439             refstar = refstars[i] ;
00440             break ;
00441         }
00442     }
00443     /* Free and return */
00444     cpl_free(refstars) ;
00445     return (irplib_irstd*)refstar ;
00446 }
00447 
00448 /*----------------------------------------------------------------------------*/
00458 /*----------------------------------------------------------------------------*/
00459 irplib_irstd * irplib_std_get_mag(
00460         double          ra,
00461         double          dec,
00462         irplib_band       band,
00463         double      *   mag)
00464 {
00465     char        **  catalog_names ;
00466     const irplib_irstd * refstar ;
00467     int             nfound ;
00468     const irplib_irstd ** refstars ;
00469     int             i, j ;
00470 
00471     /* Initialise */
00472     catalog_names = (char**)irplib_irlist_catalogs ;
00473     nfound = 0 ;
00474 
00475     /* Loop on the catalogs and get the closest stars */
00476     for (i=0 ; catalog_names[i] ; i++) {
00477         irplib_std_setactive("none");
00478         irplib_std_setactive(catalog_names[i]) ;
00479         refstar = irplib_std_get_closest_star(ra, dec) ;
00480         if (refstar != NULL) nfound ++ ;
00481     }
00482     refstars = cpl_malloc(nfound*sizeof(irplib_irstd*)) ;
00483     j = 0 ;
00484     for (i=0 ; catalog_names[i] ; i++) {
00485         irplib_std_setactive("none");
00486         irplib_std_setactive(catalog_names[i]) ;
00487         refstar = irplib_std_get_closest_star(ra, dec) ;
00488         if (refstar != NULL) {
00489             refstars[j] = refstar ;
00490             j++ ;
00491         }
00492     }
00493 
00494     /* Keep the first one whose magnitude is known */
00495     refstar = NULL ;
00496     switch (band) {
00497         case BAND_J:
00498             for (i=0 ; i<nfound ; i++) {
00499                 if (refstars[i]->mag_J < 98.0) {
00500                     refstar = refstars[i] ;
00501                     *mag = (double)(refstar->mag_J) ;
00502                     break ;
00503                 }
00504             }
00505             break ;
00506         case BAND_H:
00507             for (i=0 ; i<nfound ; i++) {
00508                 if (refstars[i]->mag_H < 98.0) {
00509                     refstar = refstars[i] ;
00510                     *mag = (double)(refstar->mag_H) ;
00511                     break ;
00512                 }
00513             }
00514             break ;
00515         case BAND_K:
00516             for (i=0 ; i<nfound ; i++) {
00517                 if (refstars[i]->mag_K < 98.0) {
00518                     refstar = refstars[i] ;
00519                     *mag = (double)(refstar->mag_K) ;
00520                     break ;
00521                 }
00522             }
00523             break ;
00524         case BAND_KS:
00525             for (i=0 ; i<nfound ; i++) {
00526                 if (refstars[i]->mag_Ks < 98.0) {
00527                     refstar = refstars[i] ;
00528                     *mag = (double)(refstar->mag_Ks) ;
00529                     break ;
00530                 }
00531             }
00532             break ;
00533         case BAND_L:
00534             for (i=0 ; i<nfound ; i++) {
00535                 if (refstars[i]->mag_L < 98.0) {
00536                     refstar = refstars[i] ;
00537                     *mag = (double)(refstar->mag_L) ;
00538                     break ;
00539                 }
00540             }
00541             break ;
00542         case BAND_M:
00543             for (i=0 ; i<nfound ; i++) {
00544                 if (refstars[i]->mag_M < 98.0) {
00545                     refstar = refstars[i] ;
00546                     *mag = (double)(refstar->mag_M) ;
00547                     break ;
00548                 }
00549             }
00550             break ;
00551         case BAND_LP:
00552             for (i=0 ; i<nfound ; i++) {
00553                 if (refstars[i]->mag_Lp < 98.0) {
00554                     refstar = refstars[i] ;
00555                     *mag = (double)(refstar->mag_Lp) ;
00556                     break ;
00557                 }
00558             }
00559             break ;
00560         case BAND_MP:
00561             for (i=0 ; i<nfound ; i++) {
00562                 if (refstars[i]->mag_Mp < 98.0) {
00563                     refstar = refstars[i] ;
00564                     *mag = (double)(refstar->mag_Mp) ;
00565                     break ;
00566                 }
00567             }
00568             break ;
00569         default:
00570             break ;
00571     }
00572 
00573 
00574     /* Free and return */
00575     cpl_free(refstars) ;
00576     return (irplib_irstd*)refstar ;
00577 }
00578 
00579 /*-------------------------------------------------------------------------*/
00585 /*--------------------------------------------------------------------------*/
00586 const char * irplib_std_band_name(irplib_band band)
00587 {
00588     switch (band) {
00589         case BAND_J:        return "J" ; 
00590         case BAND_JS:       return "Js" ;
00591         case BAND_JBLOCK:   return "J+Block" ;
00592         case BAND_H:        return "H" ;
00593         case BAND_K:        return "K" ;
00594         case BAND_KS:       return "Ks" ;
00595         case BAND_L:        return "L" ;
00596         case BAND_M:        return "M" ;
00597         case BAND_LP:       return "Lp" ;
00598         case BAND_MP:       return "Mp" ;
00599         case BAND_Z:        return "Z" ;
00600         case BAND_SZ:       return "SZ" ;
00601         case BAND_SH:       return "SH" ;
00602         case BAND_SK:       return "SK" ;
00603         case BAND_SL:       return "SL" ;
00604         default:            return "Unknown" ;
00605     } 
00606 }
00607 
00608 /*-------------------------------------------------------------------------*/
00618 /*--------------------------------------------------------------------------*/
00619 const char * irplib_std_catalog_name(int cat_id)
00620 {
00621     return irplib_irlist_catalogs[cat_id] ;
00622 }
00623 
00624 
00625 /*-------------------------------------------------------------------------*/
00632 /*--------------------------------------------------------------------------*/
00633 const char * irplib_std_get_name(const irplib_irstd * self)
00634 {
00635 
00636     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00637 
00638     return self->name;
00639 }
00640 
00641 /*-------------------------------------------------------------------------*/
00648 /*--------------------------------------------------------------------------*/
00649 const char * irplib_std_get_type_spectral(const irplib_irstd * self)
00650 {
00651 
00652     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00653 
00654     return self->sptype;
00655 }
00656 
00657 
00658 /*-------------------------------------------------------------------------*/
00665 /*--------------------------------------------------------------------------*/
00666 const char * irplib_std_get_catalog(const irplib_irstd * self)
00667 {
00668 
00669     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00670 
00671     return irplib_irlist_catalogs[self->source];
00672 }
00673 
00674 
00677 /*----------------------------------------------------------------------------*/
00691 /*----------------------------------------------------------------------------*/
00692 static int irplib_std_setactive(const char * catalog)
00693 {
00694     int     i ;
00695     int     found ;
00696     int     active ;
00697 
00698     /* NULL: Compute number of active stars in list */
00699     if (catalog==NULL) {
00700         found=0 ;
00701         i=0 ;
00702         while (irplib_irstd_list[i].name != NULL) {
00703             if (irplib_irstd_list[i].select) found++ ;
00704             i++ ;
00705         }
00706         return found ;
00707     }
00708 
00709     /* "none": disable all stars */
00710     if (!strcmp(catalog, "none")) {
00711         i=0 ;
00712         while (irplib_irstd_list[i].name!=NULL) {
00713             irplib_irstd_list[i].select=0 ;
00714             i++;
00715         }
00716         return 0 ;
00717     }
00718 
00719     /* "all": enable all stars */
00720     if (!strcmp(catalog, "all")) {
00721         i=0 ;
00722         while (irplib_irstd_list[i].name!=NULL) {
00723             irplib_irstd_list[i].select=1 ;
00724             i++;
00725         }
00726         return i ;
00727     }
00728 
00729     /* General case: activate only required catalog */
00730     i=0 ;
00731     active=0 ;
00732     found=0 ;
00733     while (irplib_irstd_list[i].name!=NULL) {
00734         if (!strcmp(catalog, irplib_irlist_catalogs[irplib_irstd_list[i].source])) {
00735             found=1 ;
00736             irplib_irstd_list[i].select=1 ;
00737         }
00738         if (irplib_irstd_list[i].select) {
00739             active++ ;
00740         }
00741         i++ ;
00742     }
00743     if (found<1) return -1 ;
00744     return active ;
00745 }
00746 
00747 /*-------------------------------------------------------------------------*/
00760 /*--------------------------------------------------------------------------*/
00761 static const irplib_irstd * irplib_std_get_closest_star(double ra_d,
00762                                                         double dec_d)
00763 {
00764     const irplib_irstd * self = NULL;
00765     const double         max_dist = (IRPLIB_STD_MAXRADIUS)/60.0; /* degrees */
00766     double               min_dist = DBL_MAX;  /* Avoid (false) uninit warning */
00767     int                  min_index;
00768     int                  i;
00769 
00770 
00771     /* Look for minimum distance star */
00772     min_index = -1; /* None found yet */
00773     for (i = 0; irplib_irstd_list[i].name != NULL; i++) {
00774         if (irplib_irstd_list[i].select) {
00775             const double ra  = irplib_irstd_list[i].ra;
00776             const double dec = irplib_irstd_list[i].dec;
00777             const double dist = irplib_great_circle_dist(ra_d, dec_d, ra, dec);
00778 
00779             if (min_index < 0 || dist < min_dist) {
00780                 min_dist = dist;
00781                 min_index = i;
00782             }
00783         }
00784     }
00785 
00786     if (min_index < 0) {
00787         cpl_msg_debug(cpl_func, "No standard stars found in catalogue: %d", i);
00788     } else if (min_dist > max_dist) {
00789         /* The closest star is too distant (more than 2 arcminutes away) */
00790         /* FIXME: This message should appear as an error message,
00791            prior to causing a recipe failure */
00792         cpl_msg_debug(cpl_func, "The distance between the star at (RA,DEC)="
00793                       "(%g,%g) and the closest catalogue star at (RA,DEC)="
00794                       "(%g, %g) exceeds %g degrees [degrees]: %g (%d)",
00795                       ra_d, dec_d, irplib_irstd_list[min_index].ra,
00796                       irplib_irstd_list[min_index].dec, max_dist, min_dist,
00797                       min_index);
00798     } else {
00799         self = &(irplib_irstd_list[min_index]);
00800     }
00801 
00802     return self;
00803 }
00804 
00805 
00806 /*----------------------------------------------------------------------------*/
00818 /*----------------------------------------------------------------------------*/
00819 static double irplib_great_circle_dist(double ra1, double dec1,
00820                                        double ra2, double dec2)
00821 {
00822 
00823   /* Convert all input from degrees to radian - and back for the result */
00824   const double dra  = sin( atan(1.0)/45.0 * (ra2  - ra1 )/2.0 );
00825   const double ddec = sin( atan(1.0)/45.0 * (dec2 - dec1)/2.0 );
00826 
00827   dec1 *= atan(1.0)/45.0; 
00828   dec2 *= atan(1.0)/45.0; 
00829 
00830   return 2.0 * asin(sqrt( ddec*ddec + cos(dec1)*cos(dec2)*dra*dra))
00831       * 45.0/atan(1.0);
00832 
00833 }

Generated on Tue Jun 19 14:39:14 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6