visir_utils.c

00001 /* $Id: visir_utils.c,v 1.138 2009/03/06 08:35:40 llundin Exp $
00002  *
00003  * This file is part of the VISIR Pipeline
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: 2009/03/06 08:35:40 $
00024  * $Revision: 1.138 $
00025  * $Name: visir-3_2_2 $
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 <assert.h>
00039 #include <cpl.h>
00040 
00041 #include "irplib_utils.h"
00042 #include "irplib_filter.h"
00043 
00044 #include "visir_inputs.h"
00045 #include "visir_utils.h"
00046 #include "visir_pfits.h"
00047 #include "visir_spc_distortion.h"
00048 
00049 /*-----------------------------------------------------------------------------
00050                                    Define
00051  -----------------------------------------------------------------------------*/
00052 
00053 #define VISIR_BACKGD_START  76
00054 #define VISIR_BACKGD_STOP   172
00055 
00056 /*----------------------------------------------------------------------------*/
00062 /*----------------------------------------------------------------------------*/
00063 
00064 /*-----------------------------------------------------------------------------
00065                         Private function prototypes
00066  -----------------------------------------------------------------------------*/
00067 
00068 
00069 static double visir_great_circle_dist(double, double, double, double);
00070 static double ra_hms2deg(int, int, double);
00071 static double dec_hms2deg(int, int, double);
00072 
00073 static const char * visir_get_capa(const cpl_propertylist *);
00074 static double visir_hcycle_background(const irplib_framelist *, int, int);
00075 
00076 #ifdef VISIR_MASK_HAS
00077 static cpl_boolean visir_mask_has(const cpl_mask *, cpl_binary, int);
00078 #endif
00079 
00080 
00083 /*----------------------------------------------------------------------------*/
00092 /*----------------------------------------------------------------------------*/
00093 double * visir_utils_get_wls(const irplib_framelist * self)
00094 {
00095     /* Get the number of files */
00096     const int   size = irplib_framelist_get_size(self);
00097     double    * wls = NULL;
00098     int         i;
00099 
00100 
00101     skip_if (0);
00102 
00103     skip_if(irplib_framelist_contains(self, VISIR_PFITS_DOUBLE_MONOC_POS,
00104                                       CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00105 
00106     /* Allocate the output array */
00107     wls = cpl_malloc(size * sizeof(double));
00108 
00109     /* Get the wavelengths */
00110     for (i=0; i < size; i++) {
00111         const cpl_propertylist * plist
00112             = irplib_framelist_get_propertylist_const(self, i);
00113 
00114         wls[i] = visir_pfits_get_monoc_pos(plist);
00115 
00116         skip_if (0);
00117     }
00118 
00119     end_skip;
00120 
00121     if (cpl_error_get_code()) {
00122         cpl_free(wls);
00123         wls = NULL;
00124     }
00125 
00126     return wls;
00127 }
00128 
00129 /*----------------------------------------------------------------------------*/
00139 /*----------------------------------------------------------------------------*/
00140 cpl_image * visir_create_disk_intimage(
00141         int     nx, 
00142         int     ny, 
00143         int     x_pos, 
00144         int     y_pos, 
00145         int     radius) 
00146 {
00147     cpl_image   *   intima;
00148     int         *   pintima;
00149     double          dist;
00150     int             i, j;
00151 
00152     /* Create the empty output image */
00153     intima = cpl_image_new(nx, ny, CPL_TYPE_INT);
00154     pintima = cpl_image_get_data_int(intima);
00155 
00156     /* Loop on the pixels */
00157     for (j=0;j<ny ; j++) {
00158         for (i=0;i<nx ; i++) {
00159             dist = (i+1-x_pos)*(i+1-x_pos)+(j+1-y_pos)*(j+1-y_pos);
00160             if (dist < radius*radius) {
00161                 pintima[i+j*nx] = 1;
00162             } else {
00163                 pintima[i+j*nx] = 0;
00164             }
00165         }
00166     }
00167     return intima;
00168 }
00169 
00170 /*----------------------------------------------------------------------------*/
00181 /*----------------------------------------------------------------------------*/
00182 cpl_image * visir_create_ring_intimage(
00183         int     nx, 
00184         int     ny, 
00185         int     x_pos, 
00186         int     y_pos, 
00187         int     radius1, 
00188         int     radius2)
00189 {
00190     cpl_image   *   intima;
00191     int         *   pintima;
00192     double          dist;
00193     int             i, j;
00194 
00195     /* Create the empty output image */
00196     intima = cpl_image_new(nx, ny, CPL_TYPE_INT);
00197     pintima = cpl_image_get_data_int(intima);
00198 
00199     /* Loop on the pixels */
00200     for (j=0;j<ny ; j++) {
00201         for (i=0;i<nx ; i++) {
00202             dist = (i+1-x_pos)*(i+1-x_pos)+(j+1-y_pos)*(j+1-y_pos);
00203             if ((dist < radius2*radius2) && (dist > radius1*radius1)) {
00204                 pintima[i+j*nx] = 1;
00205             } else {
00206                 pintima[i+j*nx] = 0;
00207             }
00208         }
00209     }
00210     return intima;
00211 }
00212 
00213 /*----------------------------------------------------------------------------*/
00224 /*----------------------------------------------------------------------------*/
00225 double visir_image_sigma_clip(const cpl_image * self, double * pstdev)
00226 {
00227     const int      dimx = cpl_image_get_size_x(self);
00228     const int      dimy = cpl_image_get_size_y(self);
00229     const cpl_type type = cpl_image_get_type(self);
00230     /* Apply a 3x3 median filter to the input image  */
00231     /* FIXME: A wrap (around float/double) would be sufficient */
00232     cpl_image    * noise = cpl_image_new(dimx, dimy, type);
00233     cpl_mask     * bpm = NULL;
00234     const int      niterations = 5;
00235     const double   sigma = 3.0;
00236     const double   median_corr = 0.94;
00237     double         bgnoise = -1;
00238     int            i = -1;
00239 
00240 
00241     bug_if (0);
00242 
00243     bug_if(irplib_image_filter(noise, self, 1, 1, IRPLIB_FILTER_MEDIAN
00244                                | IRPLIB_FILTER_BORDER_FILTER));
00245 
00246     /* (Inverted) Noise image */
00247     bug_if (cpl_image_subtract(noise, self));
00248 
00249     for (i=0; i < niterations ; i++) {
00250         /* Compute mean and stdev */
00251         cpl_stats * stats =
00252             cpl_stats_new_from_image(noise, CPL_STATS_MEAN | CPL_STATS_STDEV);
00253 
00254         const double mean  = cpl_stats_get_mean(stats);
00255         const double stdev = cpl_stats_get_stdev(stats);
00256 
00257         /* Set the thresholds */
00258         const double low_thresh  = mean - sigma * stdev;
00259         const double high_thresh = mean + sigma * stdev;
00260 
00261 
00262         cpl_stats_delete(stats); /* :-( */
00263 
00264         /* The previous thresholding may have left too few good pixels */
00265         skip_if (0);
00266 
00267         /* Identify where mean-sigma*stdev < noise < mean+sigma*stdev */
00268         bpm = cpl_mask_threshold_image_create(noise, low_thresh, high_thresh);
00269 
00270         bug_if (0);
00271 
00272         bug_if (cpl_mask_not(bpm));
00273 
00274         bug_if (cpl_image_reject_from_mask(noise, bpm));
00275 
00276         cpl_mask_delete(bpm);  /* :-( */
00277         bpm = NULL;
00278 
00279     }
00280 
00281     if (pstdev != NULL) {
00282         /* Compute the stdev of the noise and the background */
00283 
00284         cpl_stats * stats =
00285             cpl_stats_new_from_image(noise, CPL_STATS_MEAN | CPL_STATS_STDEV);
00286 
00287         /* Compute mean and stdev */
00288         bgnoise = cpl_stats_get_stdev(stats);
00289         *pstdev = cpl_image_get_median(self) - cpl_stats_get_mean(stats);
00290 
00291         cpl_stats_delete(stats);
00292     } else {
00293         /* Compute the stdev */
00294         bgnoise = cpl_image_get_stdev(noise);
00295     }
00296 
00297     bug_if(0);
00298 
00299     bgnoise /= median_corr;
00300 
00301     end_skip;
00302 
00303     if (cpl_error_get_code()) 
00304         cpl_msg_error(cpl_func, "Computation of background noise using sigma=%g"
00305                       " failed in iteration %d of %d", sigma, i+1, niterations);
00306 
00307     cpl_mask_delete(bpm);
00308     cpl_image_delete(noise);
00309 
00310     return bgnoise;
00311 }
00312 
00313 /*----------------------------------------------------------------------------*/
00323 /*----------------------------------------------------------------------------*/
00324 double visir_img_phot_sigma_clip(const cpl_image * self)
00325 {
00326 
00327     const double noise = visir_image_sigma_clip(self, NULL);
00328 
00329     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), noise);
00330 
00331     return noise;
00332 
00333 }
00334 
00335 /*----------------------------------------------------------------------------*/
00353 /*----------------------------------------------------------------------------*/
00354 int visir_star_find(const cpl_vector * v_ra, const cpl_vector * v_dec,
00355                     double ra, double dec, double maxdist, double * pdist)
00356 {
00357     const int    nra   = cpl_vector_get_size(v_ra);
00358     const int    ndec  = cpl_vector_get_size(v_dec);
00359     double       dmin = 0.0;  /* Avoid (false) uninit warning */
00360     int          minind = 0;
00361     int          i;
00362 
00363 
00364     /* Catch NULL input */
00365     cpl_ensure(nra  > 0,     cpl_error_get_code(), -2);
00366     cpl_ensure(ndec > 0,     cpl_error_get_code(), -3);
00367 
00368     /* It would be natural to use a cpl_bivector for the positions,
00369        but since CPL cannot ensure that a bivector comprises two vectors
00370        of the same length this would be pointless :-( */
00371     cpl_ensure(nra == ndec,  CPL_ERROR_INCOMPATIBLE_INPUT, -4);
00372 
00373     cpl_ensure(maxdist >= 0, CPL_ERROR_ILLEGAL_INPUT, -5);
00374 
00375     /* Find the index of the star closest to the given coordinate */
00376     for (i=0 ; i < nra ; i++) {
00377         const double rai  = cpl_vector_get(v_ra,  i);
00378         const double deci = cpl_vector_get(v_dec, i);
00379         const double gdist = visir_great_circle_dist(rai, deci, ra, dec);
00380 
00381         cpl_msg_debug(cpl_func, "DISTANCE (RAi,DECi)=(%g,%g) <=> "
00382                       "(RA,DEC)=(%g,%g): %g", rai, deci, ra, dec, gdist);
00383 
00384         if (i == 0 || gdist < dmin) {
00385             minind = i;
00386             dmin = gdist;
00387         }
00388     }
00389 
00390     if (pdist != NULL) *pdist = dmin;
00391 
00392     /* Check that it is close enough */
00393     if (dmin > maxdist) {
00394         cpl_msg_error(cpl_func, "Nearest standard star (%d of %d) at (RA,DEC)="
00395                       "(%g,%g) is too distant from (RA,DEC)=(%g, %g): %g > %g",
00396                       1+minind, nra, cpl_vector_get(v_ra,  minind),
00397                       cpl_vector_get(v_dec,  minind), ra, dec, dmin, maxdist);
00398         cpl_ensure(0, CPL_ERROR_DATA_NOT_FOUND, -1);
00399     }
00400 
00401     return minind;
00402 }
00403 
00404 /*----------------------------------------------------------------------------*/
00423 /*----------------------------------------------------------------------------*/
00424 cpl_error_code visir_star_convert(const char * line, int ra_hh, int ra_mm,
00425                                   double ra_ss, char isign, int dec_hh,
00426                                   int dec_mm, double dec_ss,
00427                                   const double * jys, int njys,
00428                                   double * pra, double * pdec)
00429 {
00430 
00431     double sign;
00432     int i;
00433 
00434     assert( line );
00435     assert( pra );
00436     assert( pdec );
00437     assert( jys );
00438     assert( njys > 0 );
00439 
00440 
00441     if (isign == '+')
00442       sign = 1.0;
00443     else if (isign == '-')
00444       sign = -1.0;
00445     else {
00446         cpl_msg_error(cpl_func, "Line has illegal declination-sign character "
00447                       "(%c): %s", isign, line);
00448         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00449     }
00450 
00451     if (ra_hh < 0) {
00452         cpl_msg_error(cpl_func, "Line has negative RA hh (%d): %s",
00453                       ra_hh, line);
00454         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00455     }
00456     if (ra_mm < 0) {
00457         cpl_msg_error(cpl_func, "Line has negative RA mm (%d): %s",
00458                       ra_hh, line);
00459         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00460     }
00461     if (ra_mm >= 60) {
00462         cpl_msg_error(cpl_func, "Line has too large RA mm (%d): %s ",
00463                       ra_mm, line);
00464         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00465     }
00466     if (ra_ss < 0) {
00467         cpl_msg_error(cpl_func, "Line has negative RA ss (%g): %s",
00468                       ra_ss, line);
00469         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00470     }
00471     if (ra_ss >= 60) {
00472         cpl_msg_error(cpl_func, "Line has too large RA ss (%g): %s ",
00473                       ra_ss, line);
00474         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00475     }
00476 
00477     if (dec_hh < 0) {
00478         cpl_msg_error(cpl_func, "Line has negative DEC hh (%d): %s",
00479                       dec_hh, line);
00480         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00481     }
00482     if (dec_mm < 0) {
00483         cpl_msg_error(cpl_func, "Line has negative DEC mm (%d): %s",
00484                       dec_hh, line);
00485         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00486     }
00487     if (dec_mm >= 60) {
00488         cpl_msg_error(cpl_func, "Line has too large DEC mm (%d): %s ",
00489                       dec_mm, line);
00490         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00491     }
00492     if (dec_ss < 0) {
00493         cpl_msg_error(cpl_func, "Line has negative DEC ss (%g): %s",
00494                       dec_ss, line);
00495         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00496     }
00497     if (dec_ss >= 60) {
00498         cpl_msg_error(cpl_func, "Line has too large DEC ss (%g): %s ",
00499                       dec_ss, line);
00500         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00501     }
00502 
00503     *pra = ra_hms2deg(ra_hh, ra_mm, ra_ss);
00504     if (*pra >= 360.0) {
00505         cpl_msg_error(cpl_func, "Line has too large RA (%g): %s ",
00506                       *pra, line);
00507         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00508     }
00509 
00510     *pdec = sign * dec_hms2deg(dec_hh, dec_mm, dec_ss);
00511     if (*pdec > 90.0) {
00512         cpl_msg_error(cpl_func, "Line has too large RA (%g): %s ",
00513                       *pdec, line);
00514         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00515     }
00516     if (*pdec < -90.0) {
00517         cpl_msg_error(cpl_func, "Line has too small RA (%g): %s ",
00518                       *pdec, line);
00519         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00520     }
00521 
00522     for (i=0; i < njys; i++) if (jys[i] <= 0.0) {
00523         cpl_msg_error(cpl_func,"Line has non-positive Jy value (%g) at %d: %s ",
00524                       jys[i], i+1, line);
00525         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00526     }
00527 
00528     return CPL_ERROR_NONE;
00529 
00530 }
00531 
00532 /*----------------------------------------------------------------------------*/
00545 /*----------------------------------------------------------------------------*/
00546 cpl_table * visir_table_new_xypos(const cpl_imagelist * images,
00547                                   const char * label)
00548 {
00549     cpl_errorstate cleanstate = cpl_errorstate_get();
00550     const int    nsize = cpl_imagelist_get_size(images);
00551     double       psigmas[] = {5, 2, 1, 0.5}; /* Actually not modified */
00552     cpl_vector * sigmas = NULL;
00553     cpl_table  * self  = NULL;
00554     const int           nsigmas = sizeof(psigmas)/sizeof(double);
00555     int                 isigma;
00556     int isflux = 0;
00557     int nfail, i;
00558 
00559     cpl_ensure(nsize > 0, cpl_error_get_code(), NULL);
00560     cpl_ensure(label,     CPL_ERROR_NULL_INPUT, NULL);
00561     cpl_ensure(!strcmp(label, "FLUX") || !strcmp(label, "FWHM"),
00562                CPL_ERROR_UNSUPPORTED_MODE, NULL);
00563 
00564     self = cpl_table_new(nsize);
00565 
00566     skip_if (cpl_table_new_column(self, "X_POS", CPL_TYPE_DOUBLE));
00567     skip_if (cpl_table_new_column(self, "Y_POS", CPL_TYPE_DOUBLE));
00568 
00569     if (!strcmp(label,"FLUX")) {
00570         isflux = 1;
00571         skip_if (cpl_table_new_column(self, label,    CPL_TYPE_DOUBLE));
00572     } else {
00573         skip_if (cpl_table_new_column(self, "X_FWHM", CPL_TYPE_DOUBLE));
00574         skip_if (cpl_table_new_column(self, "Y_FWHM", CPL_TYPE_DOUBLE));
00575     }
00576 
00577     sigmas = cpl_vector_wrap(4, psigmas);
00578     skip_if (sigmas == NULL);
00579 
00580     cpl_msg_info(cpl_func, "Detecting apertures using %d sigma-levels "
00581                  "ranging from %g down to %g", nsigmas, psigmas[0],
00582                  psigmas[nsigmas-1]);
00583 
00584     /* Object detection */
00585     nfail = 0;
00586     for (i=0 ; i < nsize ; i++) {
00587         const cpl_image * image = cpl_imagelist_get_const(images, i);
00588         cpl_apertures * apert;
00589 
00590         double posx  = -1;
00591         double posy  = -1;
00592         double fwhmx = -1;
00593         double fwhmy = -1;
00594         double flux  = -1;
00595         int iflux;
00596 
00597         skip_if (0);
00598 
00599         /* Find any apertures in each image */
00600         apert = cpl_apertures_extract(image, sigmas, &isigma);
00601 
00602         if (apert != NULL && cpl_error_get_code()) {
00603             /* FIX for DFS 2616 */
00604             cpl_msg_error(cpl_func, "cpl_apertures_extract() returned non-NULL "
00605                           "while setting the CPL error-state to '%s' at '%s'",
00606                           cpl_error_get_message(), cpl_error_get_where());
00607             cpl_msg_debug(cpl_func, "Deleting the spurious aperture list at %p:",
00608                           (void*)apert);
00609             if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00610                 cpl_apertures_dump(apert, stdout);
00611             cpl_apertures_delete(apert);
00612             apert = NULL;
00613         }
00614 
00615         if (apert != NULL &&
00616             !irplib_apertures_find_max_flux(apert, &iflux, 1) &&
00617             cpl_apertures_get_flux(apert, iflux) > 0) {
00618 
00619             posx = cpl_apertures_get_centroid_x(apert, iflux);
00620             posy = cpl_apertures_get_centroid_y(apert, iflux);
00621             flux = cpl_apertures_get_flux(apert, iflux);
00622             if (!isflux)
00623                 cpl_image_get_fwhm(image, (int)posx, (int)posy, &fwhmx, &fwhmy);
00624 
00625             cpl_msg_info(cpl_func, "Detected an aperture with flux=%g at "
00626                          "sigma=%g, at position: %g %g", flux,
00627                          psigmas[isigma], posx, posy);
00628     
00629         }
00630 
00631         if (cpl_error_get_code()) {
00632             visir_error_reset("Aperture detection in image %d of %d failed",
00633                              i+1, nsize);
00634             nfail++;
00635         } else if (flux <= 0) {
00636             cpl_msg_warning(cpl_func, "Ignoring %d-pixel aperture %d (out of %d) "
00637                             "in file %d of %d with non-positive flux: %g",
00638                             cpl_apertures_get_npix(apert, iflux), iflux,
00639                             cpl_apertures_get_size(apert), i+1, nsize, flux);
00640             nfail++;
00641         }
00642 
00643         cpl_apertures_delete(apert);
00644         apert = NULL;
00645 
00646         skip_if (cpl_table_set_double(self, "X_POS", i, posx));
00647         skip_if (cpl_table_set_double(self, "Y_POS", i, posy));
00648 
00649         if (isflux)
00650             skip_if (cpl_table_set_double(self, "FLUX",  i, flux));
00651         else {
00652             skip_if (cpl_table_set_double(self, "X_FWHM", i, fwhmx));
00653             skip_if (cpl_table_set_double(self, "Y_FWHM", i, fwhmy));
00654         }
00655 
00656     }
00657 
00658     /* Check if some detections were successful */
00659     if (nfail == nsize) {
00660         cpl_msg_error(cpl_func, "Aperture detection failed in all %d images",
00661                       nsize);
00662         visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00663         skip_if(1);
00664     }
00665 
00666     end_skip;
00667 
00668     cpl_vector_unwrap(sigmas);
00669 
00670     if (self && cpl_error_get_code()) {
00671         cpl_table_delete(self);
00672         self = NULL;
00673     }
00674 
00675     return self;
00676 }
00677 
00678 /*----------------------------------------------------------------------------*/
00685 /*----------------------------------------------------------------------------*/
00686 int visir_vector_minpos(const cpl_vector * v)
00687 {
00688     const double * x     = cpl_vector_get_data_const(v);
00689     const int      n     = cpl_vector_get_size(v);
00690     int minpos = 0;
00691     int i;
00692 
00693     cpl_ensure(x, CPL_ERROR_NULL_INPUT, -1);
00694 
00695     for (i = 1; i < n; i++) if (x[i] < x[minpos]) minpos = i;
00696 
00697     return minpos;
00698 }
00699 
00700 /*----------------------------------------------------------------------------*/
00715 /*----------------------------------------------------------------------------*/
00716 cpl_error_code visir_bivector_load(cpl_bivector * self, FILE * stream)
00717 {
00718     cpl_vector * v1;
00719     cpl_vector * v2;
00720     int          np = 0;
00721     int          xsize, ysize;
00722     char         line[1024];
00723 
00724     cpl_ensure_code(self,   CPL_ERROR_NULL_INPUT);
00725     cpl_ensure_code(stream, CPL_ERROR_NULL_INPUT);
00726 
00727     /* Create and fill the vectors */
00728     v1 = cpl_bivector_get_x(self);
00729     v2 = cpl_bivector_get_y(self);
00730 
00731     xsize = cpl_vector_get_size(v1);
00732     ysize = cpl_vector_get_size(v2);
00733 
00734     while (fgets(line, 1024, stream) != NULL) {
00735         double x, y;
00736         if (line[0] != '#' && sscanf(line, "%lg %lg", &x, &y) == 2) {
00737             /* Found new element-pair
00738                - increase vector sizes if necessary,
00739                - insert element at end and
00740                - increment size counter */
00741             if (np == xsize) {
00742                 xsize *= 2;
00743                 cpl_vector_set_size(v1, xsize);
00744             }
00745             if (np == ysize) {
00746                 ysize *= 2;
00747                 cpl_vector_set_size(v2, ysize);
00748             }
00749             cpl_vector_set(v1, np, x);
00750             cpl_vector_set(v2, np, y);
00751             np++;
00752         }
00753     }
00754 
00755     /* Check that the loop ended due to eof and not an error */
00756     cpl_ensure_code(!ferror(stream), CPL_ERROR_FILE_IO);
00757 
00758     /* Check that the file was not empty and set the size to its true value */
00759     if (np == 0 || cpl_vector_set_size(v1, np) || cpl_vector_set_size(v2, np)) {
00760         cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00761     }
00762 
00763     return CPL_ERROR_NONE;
00764 
00765 }
00766 
00767 /*----------------------------------------------------------------------------*/
00780 /*----------------------------------------------------------------------------*/
00781 double visir_star_dist_min(const double * pras, const double * pdecs, int nloc,
00782                            int * piloc1, int * piloc2)
00783 {
00784 
00785     int i, j;
00786     double dmin = 180;
00787 
00788 
00789     assert( pras != NULL);
00790     assert( pdecs != NULL);
00791     assert( piloc1 != NULL);
00792     assert( piloc2 != NULL);
00793     assert( nloc > 0 );
00794 
00795     for (j = 0; j < nloc; j++) {
00796         for (i = 0; i < j; i++) {
00797             const double dist = visir_great_circle_dist(pras[i], pdecs[i],
00798                                                         pras[j], pdecs[j]);
00799             if (dist < dmin) {
00800                 dmin = dist;
00801                 *piloc1 = i;
00802                 *piloc2 = j;
00803             }
00804             if (dist < VISIR_STAR_MAX_RADIUS)
00805                 cpl_msg_warning(cpl_func,"The two stars (%d,%d) have a distance"
00806                                 ": %g < %g", i, j, dist, VISIR_STAR_MAX_RADIUS);
00807         }
00808     }
00809 
00810     return dmin;
00811 }
00812 
00813 
00814 /*----------------------------------------------------------------------------*/
00828 /*----------------------------------------------------------------------------*/
00829 const char ** visir_framelist_set_tag(irplib_framelist * self,
00830                                       char * (*pftag)(const cpl_frame *,
00831                                                       const cpl_propertylist *,
00832                                                       int),
00833                                       int *pntags)
00834 {
00835 
00836     /* FIXME: Copied from NACO - move to irplib */
00837 
00838     const char ** taglist = NULL; /* Must be initialized due to realloc call */
00839     int iframe, size;
00840 
00841     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00842     cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
00843     cpl_ensure(pftag  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00844     cpl_ensure(pntags != NULL, CPL_ERROR_NULL_INPUT, NULL);
00845 
00846     size = irplib_framelist_get_size(self);
00847 
00848     cpl_ensure(size > 0, CPL_ERROR_DATA_NOT_FOUND, NULL);
00849 
00850     *pntags = 0;
00851 
00852     for (iframe = 0; iframe < size ; iframe++) {
00853         cpl_frame  * frame = irplib_framelist_get(self, iframe);
00854         const cpl_propertylist * plist
00855             = irplib_framelist_get_propertylist_const(self, iframe);
00856         char       * tag;
00857         const char * newtag;
00858         int          i;
00859 
00860 
00861         /* This should really be an assert() */
00862         cpl_ensure(frame != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
00863         cpl_ensure(plist != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
00864 
00865         tag = (*pftag)(frame, plist, iframe);
00866 
00867         cpl_ensure(tag != NULL, cpl_error_get_code(), NULL);
00868 
00869         /* From this point on failures should not really happen */
00870 
00871         (void)cpl_frame_set_tag(frame, tag);
00872         cpl_free(tag);
00873 
00874         newtag = cpl_frame_get_tag(frame);
00875 
00876         cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00877 
00878         /* Compare the new tags with those of previous frames */
00879         for (i=0; i < *pntags; i++)
00880             if (strcmp(newtag, taglist[i]) == 0) break;
00881 
00882         if (i == *pntags) {
00883             /* The new tag is different from the previous ones
00884                - add it to the list */
00885             (*pntags)++;
00886             taglist = (const char **)cpl_realloc(taglist, *pntags *
00887                                                  sizeof(const char *));
00888             taglist[i] = newtag;
00889         }
00890 
00891     }
00892 
00893     return taglist;
00894 
00895 }
00896 
00897 /*----------------------------------------------------------------------------*/
00907 /*----------------------------------------------------------------------------*/
00908 cpl_error_code visir_qc_append_background(cpl_propertylist * self,
00909                                           const irplib_framelist * rawframes,
00910                                           int icol1, int icol2)
00911 {
00912 
00913     /* Compute the background values of the HCYCLE frames */
00914     const double bg_mean = visir_hcycle_background(rawframes, icol1, icol2);
00915 
00916     skip_if (0);
00917 
00918     bug_if (cpl_propertylist_append_double(self, "ESO QC BACKGD MEAN",
00919                                            bg_mean));
00920 
00921     end_skip;
00922 
00923     return cpl_error_get_code();
00924 
00925 }
00926 
00927 
00928 /*----------------------------------------------------------------------------*/
00937 /*----------------------------------------------------------------------------*/
00938 cpl_error_code visir_qc_append_capa(cpl_propertylist * self,
00939                                     const irplib_framelist * rawframes)
00940 {
00941 
00942     cpl_errorstate cleanstate = cpl_errorstate_get();
00943     const cpl_propertylist * plist
00944         = irplib_framelist_get_propertylist_const(rawframes, 0);
00945     const char             * capa;
00946 
00947 
00948     bug_if (0);
00949 
00950     capa = visir_get_capa(plist);
00951 
00952     if (cpl_error_get_code()) {
00953         visir_error_reset("Could not determine capa");
00954     } else {
00955         bug_if (cpl_propertylist_append_string(self, "ESO QC CAPA", capa));
00956     }
00957 
00958     end_skip;
00959 
00960     return cpl_error_get_code();
00961 
00962 }
00963 
00964 /*----------------------------------------------------------------------------*/
00972 /*----------------------------------------------------------------------------*/
00973 cpl_error_code visir_qc_append_filter(cpl_propertylist * self,
00974                                       const irplib_framelist * rawframes)
00975 {
00976 
00977     const cpl_propertylist * plist
00978         = irplib_framelist_get_propertylist_const(rawframes, 0);
00979     const char             * value = visir_pfits_get_filter(plist);
00980 
00981 
00982     skip_if (0);
00983  
00984     bug_if (cpl_propertylist_append_string(self, "ESO QC FILTER", value));
00985 
00986     end_skip;
00987 
00988     return cpl_error_get_code();
00989 
00990 }
00991 
00992 /*----------------------------------------------------------------------------*/
01000 /*----------------------------------------------------------------------------*/
01001 cpl_error_code visir_qc_append_exptime(cpl_propertylist * self,
01002                                        const irplib_framelist * rawframes)
01003 {
01004 
01005     const cpl_propertylist * plist
01006         = irplib_framelist_get_propertylist_const(rawframes, 0);
01007 
01008     /* Get the total exposure time */
01009     /* DIT */
01010     const double dit = visir_pfits_get_dit(plist);
01011     /* NDIT */
01012     const int ndit = visir_pfits_get_ndit(plist);
01013     /* NNOD */
01014     const int nnod = irplib_framelist_get_size(rawframes);
01015     /* Number of chopping cycles */
01016     const int ncycles = visir_pfits_get_chop_ncycles(plist);
01017 
01018     /* Exptime * 2 because of chopping */
01019     const double value = 2 * dit * ndit * nnod * ncycles;
01020 
01021 
01022     skip_if (0);
01023     
01024     if (value <= 0) {
01025         cpl_msg_error(cpl_func, "Illegal exposure time "
01026                       "(dit=%g:ndit=%d:ncycles=%d:nnod=%d): %g",
01027                       dit, ndit, ncycles, nnod, value);
01028         skip_if(1);
01029     }
01030 
01031     bug_if (cpl_propertylist_append_double(self, "ESO QC EXPTIME", value));
01032 
01033     end_skip;
01034 
01035     return cpl_error_get_code();
01036 
01037 }
01038 
01041 /*----------------------------------------------------------------------------*/
01052 /*----------------------------------------------------------------------------*/
01053 static double visir_great_circle_dist(double ra1, double dec1,
01054                                       double ra2, double dec2)
01055 {
01056 
01057   /* Convert all input from degrees to radian - and back for the result */
01058   const double dra  = sin( CPL_MATH_RAD_DEG * (ra2  - ra1 )/2.0 );
01059   const double ddec = sin( CPL_MATH_RAD_DEG * (dec2 - dec1)/2.0 );
01060 
01061   dec1 *= CPL_MATH_RAD_DEG;
01062   dec2 *= CPL_MATH_RAD_DEG;
01063 
01064   return 2.0 * asin(sqrt( ddec*ddec + cos(dec1)*cos(dec2)*dra*dra))
01065       * CPL_MATH_DEG_RAD;
01066 
01067 }
01068 
01069 /*----------------------------------------------------------------------------*/
01082 /*----------------------------------------------------------------------------*/
01083 static double ra_hms2deg(int hh, int mm, double ss)
01084 {
01085     return 15.0 * dec_hms2deg(hh, mm, ss);
01086 }
01087 
01088 /*----------------------------------------------------------------------------*/
01100 /*----------------------------------------------------------------------------*/
01101 static double dec_hms2deg(int dd, int mm, double ss)
01102 {
01103     return ((double)ss/60.0 + (double)mm)/60.0 + dd;
01104 }
01105 
01106 /*----------------------------------------------------------------------------*/
01119 /*----------------------------------------------------------------------------*/
01120 static double visir_hcycle_background(const irplib_framelist * rawframes,
01121                                int icol1, int icol2)
01122 {
01123     cpl_imagelist * iset = NULL;
01124     /* Get the number of files */
01125     const int       nfiles = irplib_framelist_get_size(rawframes);
01126     double          bgsum  = 0;
01127     double          bgmean = -1;
01128     int             nsum  = 0;
01129     int             i, j;
01130 
01131     
01132     skip_if (nfiles < 1);
01133 
01134     if (icol1 == 0) icol1 = VISIR_BACKGD_START;
01135     if (icol2 == 0) icol2 = VISIR_BACKGD_STOP;
01136 
01137     cpl_msg_info(cpl_func, "Computing Half-cycle background level from column %d "
01138                  "through %d", icol1, icol2);
01139 
01140     /* Loop on the hcycles images */
01141     for (i=0; i < nfiles; i++) {
01142 
01143         iset = visir_load_hcycle(rawframes, i);
01144 
01145         skip_if (0);
01146 
01147         for (j = 0; j < cpl_imagelist_get_size(iset) ; j++) {
01148             const double median =
01149                 cpl_image_get_median_window(cpl_imagelist_get(iset, j),
01150                                             VISIR_BACKGD_START, icol1,
01151                                             VISIR_BACKGD_STOP, icol2);
01152 
01153             skip_if (0);
01154 
01155             if (median != median) {
01156                 const cpl_frame * frame = irplib_framelist_get_const(rawframes,
01157                                                                      i);
01158                 /* Some Comm. I data contains NaNs */
01159                 cpl_msg_error(cpl_func, "Image window (%d, %d, %d, %d) "
01160                               "(image %d of %d) in %s (frame %d of %d) "
01161                               "has NaN median",
01162                               VISIR_BACKGD_START, icol1,
01163                               VISIR_BACKGD_STOP, icol2,
01164                               j+1, cpl_imagelist_get_size(iset),
01165                               cpl_frame_get_filename(frame), i+1, nfiles);
01166                 visir_error_set(CPL_ERROR_BAD_FILE_FORMAT);
01167                 skip_if(1);
01168             }
01169             bgsum += median;
01170         }
01171         nsum += j;
01172         cpl_imagelist_delete(iset);
01173         iset = NULL;
01174     }
01175 
01176     /* Test if there are some HCYCLE frames */
01177     skip_if (nsum < 1);
01178 
01179     bgmean = bgsum / nsum;
01180 
01181     end_skip;
01182 
01183     cpl_imagelist_delete(iset);
01184 
01185     /* The background was requested to not include the offset correction */
01186     return bgmean - VISIR_HCYCLE_OFFSET;
01187 }
01188 
01189 /*----------------------------------------------------------------------------*/
01195 /*----------------------------------------------------------------------------*/
01196 static const char * visir_get_capa(const cpl_propertylist * plist)
01197 {
01198     const char  * capa = "Pb with Capa";
01199     const char  * sval;
01200     double        mean;
01201 
01202 
01203     skip_if (0);
01204 
01205 
01206     /* Get the instrument mode */
01207     sval = visir_pfits_get_insmode(plist);
01208     skip_if (0);
01209 
01210     /* Identify the mode */
01211     if (!strcmp(sval, "IMG")) {
01212         /* Imaging mode */
01213         mean  = visir_pfits_get_volt1dcta9(plist);
01214         mean += visir_pfits_get_volt1dctb9(plist);
01215     } else if (!strcmp(sval, "SPC") || !strcmp(sval, "SPCIMG")) {
01216         /* Spectro mode */
01217         mean  = visir_pfits_get_volt2dcta9(plist);
01218         mean += visir_pfits_get_volt2dctb9(plist);
01219     } else
01220         skip_if (1);
01221 
01222     skip_if (0);
01223 
01224     mean *= 0.5;
01225 
01226     /* Compute Capa value */
01227     if (mean < 1.0) {
01228         capa = "Large Capa";
01229     } else if (mean > 4.5) {
01230         capa = "Small Capa";
01231     }
01232 
01233     end_skip;    
01234 
01235     return capa;
01236 }
01237 
01238 #ifdef VISIR_MASK_HAS
01239 /*----------------------------------------------------------------------------*/
01259 /*----------------------------------------------------------------------------*/
01260 static cpl_boolean visir_mask_has(const cpl_mask * self, cpl_binary value,
01261                                   int ngood)
01262 {
01263     const cpl_binary * pself = cpl_mask_get_data_const(self);
01264     int                size  = cpl_mask_get_size_x(self)
01265                              * cpl_mask_get_size_y(self);
01266     int i;
01267 
01268     cpl_ensure(self,          CPL_ERROR_NULL_INPUT,          CPL_FALSE);
01269     cpl_ensure(ngood >= 0,    CPL_ERROR_ILLEGAL_INPUT,       CPL_FALSE);
01270     cpl_ensure(ngood <= size, CPL_ERROR_ACCESS_OUT_OF_RANGE, CPL_FALSE);
01271     cpl_ensure(value == CPL_BINARY_0 || value == CPL_BINARY_1,
01272                CPL_ERROR_INCOMPATIBLE_INPUT, CPL_FALSE);
01273 
01274     for (i = 0; i < ngood; i++) {
01275         /* Assume NULL is returned if size == 0 */
01276         const cpl_binary * ppos = memchr(pself, value, (size_t)size);
01277         if (ppos == NULL) break;
01278 
01279         size -= 1 + (int)(ppos - pself);
01280         pself = 1 + ppos;
01281     }
01282 
01283     return i == ngood ? CPL_TRUE : CPL_FALSE;
01284 }
01285 #endif

Generated on Fri Jul 3 11:15:24 2009 for VISIR Pipeline Reference Manual by  doxygen 1.5.8