visir_utils.c

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

Generated on Thu Mar 24 11:59:40 2011 for VISIR Pipeline Reference Manual by  doxygen 1.5.8