HAWKI Pipeline Reference Manual 1.8.12
hawki_utils.c
00001 /* $Id: hawki_utils.c,v 1.54 2012/12/06 16:55:32 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2012/12/06 16:55:32 $
00024  * $Revision: 1.54 $
00025  * $Name: hawki-1_8_12 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <float.h>
00037 #include <string.h>
00038 #include <math.h>
00039 #include <cpl.h>
00040 
00041 #include "irplib_cat.h"  
00042 #include "irplib_wcs.h"  
00043 
00044 #include "hawki_utils.h"
00045 #include "hawki_pfits.h"
00046 #include "hawki_load.h"
00047 
00048 /*----------------------------------------------------------------------------*/
00052 /*----------------------------------------------------------------------------*/
00053 
00056 /*----------------------------------------------------------------------------*/
00064 /*----------------------------------------------------------------------------*/
00065 const char * hawki_get_license(void)
00066 {
00067     const char  *   hawki_license = 
00068         "This file is part of the HAWKI Instrument Pipeline\n"
00069         "Copyright (C) 2002,2011 European Southern Observatory\n"
00070         "\n"
00071         "This program is free software; you can redistribute it and/or modify\n"
00072         "it under the terms of the GNU General Public License as published by\n"
00073         "the Free Software Foundation; either version 2 of the License, or\n"
00074         "(at your option) any later version.\n"
00075         "\n"
00076         "This program is distributed in the hope that it will be useful,\n"
00077         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00078         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00079         "GNU General Public License for more details.\n"
00080         "\n"
00081         "You should have received a copy of the GNU General Public License\n"
00082         "along with this program; if not, write to the Free Software\n"
00083         "Foundation, Inc., 59 Temple Place, Suite 330, Boston, \n"
00084         "MA  02111-1307  USA" ;
00085     return hawki_license ;
00086 }
00087 
00088 /*----------------------------------------------------------------------------*/
00092 /*----------------------------------------------------------------------------*/
00093 void hawki_print_banner(void)
00094 {
00095     cpl_msg_info(__func__, "*****************************************");
00096     cpl_msg_info(__func__, "Welcome to HAWK-I Pipeline release %s",
00097                  hawki_get_version());
00098     cpl_msg_info(__func__, "*****************************************");
00099 }
00100 
00101 /*----------------------------------------------------------------------------*/
00105 /*----------------------------------------------------------------------------*/
00106 const char * hawki_get_version(void)
00107 {
00108     return PACKAGE_VERSION;
00109 }
00110 
00111 /*----------------------------------------------------------------------------*/
00118 /*----------------------------------------------------------------------------*/
00119 cpl_image * hawki_compute_darkbpm(
00120         const cpl_image     *   in,
00121         double                  sigma)
00122 {
00123     double                  med, stdev, threshold ;
00124     cpl_image           *   bpm ;
00125     cpl_image           *   bpm_int ;
00126 
00127     /* Test entries */
00128     if (in == NULL) return NULL ;
00129     if (sigma <= 0) return NULL ;
00130 
00131     bpm = cpl_image_duplicate(in);
00132 
00133     /* Compute the threshold */
00134     med = cpl_image_get_median_dev(bpm, &stdev) ;
00135     threshold = med + sigma*stdev ;
00136     cpl_msg_info(__func__, "Threshold : %g = %g + %g * %g", 
00137             threshold, med, sigma, stdev) ;
00138 
00139     /* Compute the bpm */
00140     cpl_image_threshold(bpm, threshold, threshold, 0.0, 1.0) ;
00141     
00142     /* Convert */
00143     bpm_int = cpl_image_cast(bpm, CPL_TYPE_INT) ;
00144     cpl_image_delete(bpm) ;
00145     
00146     return bpm_int ;
00147 }
00148 
00149 /*----------------------------------------------------------------------------*/
00162 /*----------------------------------------------------------------------------*/
00163 cpl_image * hawki_compute_flatbpm
00164 (const cpl_image *   in,
00165  double              sigma,
00166  double              lowval,
00167  double              highval)
00168 {
00169     cpl_mask            *   kernel ;
00170     cpl_image           *   filtered ;
00171     double                  med, stdev, threshold ;
00172     cpl_image           *   bpm_sigma;
00173     cpl_image           *   bpm_lowhigh;
00174     cpl_image           *   bpm;
00175     cpl_image           *   bpm_int ;
00176 
00177     /* Test entries */
00178     if (in == NULL) return NULL ;
00179     if (sigma <= 0) return NULL ;
00180 
00181     /* Filter the input image */
00182     kernel = cpl_mask_new(3, 3) ;
00183     cpl_mask_not(kernel) ;
00184     filtered = cpl_image_new(cpl_image_get_size_x(in), cpl_image_get_size_y(in),
00185                              cpl_image_get_type(in));
00186     cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN, 
00187                           CPL_BORDER_FILTER);
00188     cpl_mask_delete(kernel) ;
00189 
00190     /* Remove the low freq signal */
00191     bpm_sigma = cpl_image_subtract_create(in, filtered) ;
00192     cpl_image_delete(filtered) ;
00193 
00194     /* Compute the threshold */
00195     med = cpl_image_get_median_dev(bpm_sigma, &stdev) ;
00196     threshold = med + sigma*stdev ;
00197     cpl_msg_info(__func__, "Threshold : %g = %g + %g * %g", 
00198             threshold, med, sigma, stdev) ;
00199 
00200     /* Compute the bpm with the sigma values */
00201     cpl_image_threshold(bpm_sigma, threshold, threshold, 0.0, 1.0) ;
00202     
00203     /* Count the pixels below and above the lowval and highval */
00204     bpm_lowhigh = cpl_image_duplicate(in);
00205     hawki_image_inverse_threshold(bpm_lowhigh, lowval, highval, 0.0, 1.0);
00206     
00207     /* Merge both masks */
00208     bpm = cpl_image_add_create(bpm_sigma, bpm_lowhigh);
00209     cpl_image_threshold(bpm, 0.0, 1.0, 0.0, 1.0);
00210     
00211     /* Convert */
00212     bpm_int = cpl_image_cast(bpm, CPL_TYPE_INT) ;
00213     cpl_image_delete(bpm) ;
00214     cpl_image_delete(bpm_sigma);
00215     cpl_image_delete(bpm_lowhigh);
00216     
00217     return bpm_int ;
00218 }
00219 
00220 /*----------------------------------------------------------------------------*/
00239 /*----------------------------------------------------------------------------*/
00240 cpl_error_code hawki_image_inverse_threshold
00241 (cpl_image *    image_in,
00242  double         lo_valid,
00243  double         hi_valid,
00244  double         assign_in_range,
00245  double         assign_out_range)
00246 {
00247     int   i;
00248     int   npix;
00249 
00250     cpl_ensure_code(image_in != NULL, CPL_ERROR_NULL_INPUT);
00251     cpl_ensure_code(lo_valid <= hi_valid, CPL_ERROR_ILLEGAL_INPUT);
00252 
00253     /* Get number of pixels of image */
00254     npix = cpl_image_get_size_x(image_in) *  cpl_image_get_size_y(image_in);
00255     
00256     /* Switch on image type */
00257     switch (cpl_image_get_type(image_in)) 
00258     {
00259         case CPL_TYPE_DOUBLE: {
00260             double * pdi = cpl_image_get_data_double(image_in);
00261             for (i=0; i<npix; i++) {
00262                 if ((pdi[i]>lo_valid) && (pdi[i]<hi_valid))
00263                     pdi[i] = (double)assign_in_range;
00264                 else
00265                     pdi[i] = (double)assign_out_range;
00266             }
00267             break;
00268         }
00269         case CPL_TYPE_FLOAT: {
00270             float * pdi = cpl_image_get_data_float(image_in);
00271             for (i=0; i<npix; i++) {
00272                 if ((pdi[i]>lo_valid) && (pdi[i]<hi_valid))
00273                     pdi[i] = (float)assign_in_range;
00274                 else
00275                     pdi[i] = (float)assign_out_range;
00276             }
00277             break;
00278         }
00279         case CPL_TYPE_INT: {
00280             int * pdi = cpl_image_get_data_int(image_in);
00281             for (i=0; i<npix; i++) {
00282                 if (((double)pdi[i]>lo_valid) && ((double)pdi[i]<hi_valid))
00283                     pdi[i] = (int)assign_in_range;
00284                 else
00285                     pdi[i] = (int)assign_out_range;
00286             }
00287             break;
00288         }
00289         default:
00290           cpl_ensure_code(0, CPL_ERROR_INVALID_TYPE);
00291     }
00292     return CPL_ERROR_NONE;
00293 }
00294 
00295 /*----------------------------------------------------------------------------*/
00303 /*----------------------------------------------------------------------------*/
00304 cpl_image * hawki_images_stitch
00305 (cpl_image   ** ima,
00306  double      *  x,
00307  double      *  y)
00308 {
00309     int                     lx, ly ;
00310     cpl_image           *   ima_ext[HAWKI_NB_DETECTORS] ;
00311     cpl_imagelist       *   in ;
00312     cpl_bivector        *   offsets ;
00313     double              *   offsets_x ;
00314     double              *   offsets_y ;
00315     cpl_image           **  combined ;
00316     cpl_image           *   stitched ;
00317     int                     i ;
00318 
00319     /* Test entries */
00320     if (ima == NULL) return NULL ;
00321     if (x   == NULL) return NULL ;
00322     if (y   == NULL) return NULL ;
00323 
00324     /* Take the smallest size */
00325     lx = cpl_image_get_size_x(ima[0]) ;
00326     ly = cpl_image_get_size_y(ima[0]) ;
00327     for (i=1 ; i<HAWKI_NB_DETECTORS ; i++) {
00328         if (lx > cpl_image_get_size_x(ima[i]))
00329             lx = cpl_image_get_size_x(ima[i]) ;
00330         if (ly > cpl_image_get_size_y(ima[i]))
00331             ly = cpl_image_get_size_y(ima[i]) ;
00332     }
00333 
00334     /* Create the image list */
00335     in = cpl_imagelist_new() ;
00336     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00337         ima_ext[i] = cpl_image_extract(ima[i], 1, 1, lx, ly) ;
00338         cpl_imagelist_set(in, ima_ext[i], i) ;
00339     }
00340 
00341     /* Create the offsets */
00342     offsets = cpl_bivector_new(HAWKI_NB_DETECTORS) ;
00343     offsets_x = cpl_bivector_get_x_data(offsets) ;
00344     offsets_y = cpl_bivector_get_y_data(offsets) ;
00345     offsets_x[0] = HAWKI_DET1_POSX ;
00346     offsets_y[0] = HAWKI_DET1_POSY ;
00347     offsets_x[1] = x[0] - x[1] + HAWKI_DET2_POSX ;
00348     offsets_y[1] = y[0] - y[1] + HAWKI_DET2_POSY ;
00349     offsets_x[2] = x[0] - x[2] + HAWKI_DET3_POSX ;
00350     offsets_y[2] = y[0] - y[2] + HAWKI_DET3_POSY ;
00351     offsets_x[3] = x[0] - x[3] + HAWKI_DET4_POSX ;
00352     offsets_y[3] = y[0] - y[3] + HAWKI_DET4_POSY ;
00353 
00354     /* Recombine the images */
00355     if ((combined = cpl_geom_img_offset_saa(in, offsets,
00356             CPL_KERNEL_DEFAULT, 0, 0, CPL_GEOM_UNION, NULL, NULL)) == NULL) 
00357     {
00358         cpl_msg_error(__func__, "Cannot recombine the images") ;
00359         cpl_bivector_delete(offsets) ;
00360         cpl_imagelist_delete(in) ;
00361         return NULL ;
00362     }
00363     cpl_bivector_delete(offsets) ;
00364     cpl_imagelist_delete(in) ;
00365 
00366     /* Return  */
00367     stitched = combined[0] ;
00368     cpl_image_delete(combined[1]) ;
00369     cpl_free(combined) ;
00370     return stitched ;
00371 }
00372 
00373 /*----------------------------------------------------------------------------*/
00383 /*----------------------------------------------------------------------------*/
00384 int hawki_apply_harmonization(
00385         cpl_imagelist   *   in,
00386         double              h1,
00387         double              h2,
00388         double              h3,
00389         double              h4)
00390 {
00391     /* Test entries */
00392     if (in == NULL) return -1 ;
00393 
00394     cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 0), h1) ;
00395     cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 1), h2) ;
00396     cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 2), h3) ;
00397     cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 3), h4) ;
00398 
00399     return 0 ;
00400 }
00401 
00402 /*----------------------------------------------------------------------------*/
00421 /*----------------------------------------------------------------------------*/
00422 int hawki_compute_harmonization(
00423         const cpl_imagelist *   in,
00424         double              *   h1,
00425         double              *   h2,
00426         double              *   h3,
00427         double              *   h4,
00428         double              *   h)
00429 {
00430     int                 width = 64 ;
00431     int                 nx, ny ;
00432     const cpl_image *   ima ;
00433     double              avg1, avg2, avg3, avg4 ;
00434     double              val1, val2 ;
00435     int                 llx, lly, urx, ury ;
00436 
00437     /* Test entries */
00438     if (in == NULL) return -1 ;
00439     if (h1==NULL || h2==NULL || h3==NULL || h4==NULL || h==NULL) return -1 ;
00440 
00441     /* Compute the avg1 */
00442     ima = cpl_imagelist_get_const(in, 0) ;
00443     nx = cpl_image_get_size_x(ima) ;
00444     ny = cpl_image_get_size_y(ima) ;
00445     llx = 1 ; lly = ny - width + 1 ; urx = nx ; ury = ny ;
00446     val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00447     if (cpl_error_get_code()) {
00448         cpl_msg_error(__func__, "Cannot get statistics from chip 1") ;
00449         return -1 ;
00450     }
00451     llx = nx - width + 1 ; lly = 1 ; urx = nx ; ury = ny ;
00452     val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00453     if (cpl_error_get_code()) {
00454         cpl_msg_error(__func__, "Cannot get statistics from chip 1") ;
00455         return -1 ;
00456     }
00457     avg1 = (val1 + val2) / 2.0 ;
00458 
00459     /* Compute the avg2 */
00460     ima = cpl_imagelist_get_const(in, 1) ;
00461     nx = cpl_image_get_size_x(ima) ;
00462     ny = cpl_image_get_size_y(ima) ;
00463     llx = 1 ; lly = 1 ; urx = width ; ury = ny ;
00464     val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00465     if (cpl_error_get_code()) {
00466         cpl_msg_error(__func__, "Cannot get statistics from chip 2") ;
00467         return -1 ;
00468     }
00469     llx = 1 ; lly = ny - width + 1 ; urx = nx ; ury = ny ;
00470     val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00471     if (cpl_error_get_code()) {
00472         cpl_msg_error(__func__, "Cannot get statistics from chip 2") ;
00473         return -1 ;
00474     }
00475     avg2 = (val1 + val2) / 2.0 ;
00476 
00477     /* Compute the avg3 */
00478     ima = cpl_imagelist_get_const(in, 2) ;
00479     nx = cpl_image_get_size_x(ima) ;
00480     ny = cpl_image_get_size_y(ima) ;
00481     llx = 1 ; lly = 1 ; urx = nx ; ury = width ;
00482     val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00483     if (cpl_error_get_code()) {
00484         cpl_msg_error(__func__, "Cannot get statistics from chip 3") ;
00485         return -1 ;
00486     }
00487     llx = nx - width + 1 ; lly = 1 ; urx = nx ; ury = ny ;
00488     val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00489     if (cpl_error_get_code()) {
00490         cpl_msg_error(__func__, "Cannot get statistics from chip 3") ;
00491         return -1 ;
00492     }
00493     avg3 = (val1 + val2) / 2.0 ;
00494 
00495     /* Compute the avg4 */
00496     ima = cpl_imagelist_get_const(in, 3) ;
00497     nx = cpl_image_get_size_x(ima) ;
00498     ny = cpl_image_get_size_y(ima) ;
00499     llx = 1 ; lly = 1 ; urx = width ; ury = ny ;
00500     val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00501     if (cpl_error_get_code()) {
00502         cpl_msg_error(__func__, "Cannot get statistics from chip 4") ;
00503         return -1 ;
00504     }
00505     llx = 1 ; lly = 1 ; urx = nx ; ury = width ;
00506     val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
00507     if (cpl_error_get_code()) {
00508         cpl_msg_error(__func__, "Cannot get statistics from chip 4") ;
00509         return -1 ;
00510     }
00511     avg4 = (val1 + val2) / 2.0 ;
00512 
00513     /* Compute h */
00514     *h = (avg1 + avg2 + avg3 + avg4) / 4.0 ;
00515 
00516     *h1 = *h / avg1 ;
00517     *h2 = *h / avg2 ;
00518     *h3 = *h / avg3 ;
00519     *h4 = *h / avg4 ;
00520 
00521     return 0 ;
00522 }
00523 
00524 /*----------------------------------------------------------------------------*/
00530 /*----------------------------------------------------------------------------*/
00531 cpl_image * hawki_compute_lsbg(const cpl_image * in)
00532 {
00533     cpl_image       *   out ;
00534     cpl_image       *   tmp ;
00535     cpl_image       *   filtered ;
00536     cpl_image       *   subsampled ;
00537     cpl_mask        *   kernel ;
00538     int                 nscales ;
00539     cpl_polynomial  *   poly ;
00540     cpl_bivector    *   xy_pos ;
00541     cpl_vector      *   vals ;
00542     int                 quad_sz, nbpoints, lx, ly, nx, ny ;
00543     double          *   pxy_pos_x ;
00544     double          *   pxy_pos_y ;
00545     double          *   pvals ;
00546     float           *   pima ;
00547     int                 i, j ;
00548 
00549     /* Check entries */
00550     if (in == NULL) return NULL ;
00551     nx = cpl_image_get_size_x(in) ;
00552     ny = cpl_image_get_size_y(in) ;
00553     
00554     /* Initialise */
00555     nscales = 7 ;
00556     tmp = (cpl_image *)in ;
00557     subsampled = NULL ;
00558     
00559     /* Check entries */
00560     quad_sz = pow(2, (double)nscales) ;
00561     lx = nx / quad_sz ;
00562     ly = ny / quad_sz ;
00563     nbpoints = lx * ly ;
00564     if (quad_sz >= nx || quad_sz >= ny) return NULL ;
00565 
00566     /* Create filter kernel */
00567     kernel = cpl_mask_new(3, 3) ;
00568     cpl_mask_not(kernel) ;
00569 
00570     /* Loop nscales times */
00571     for (i=0 ; i<nscales ; i++) {
00572 
00573         /* Filter the image */
00574         filtered = cpl_image_new(cpl_image_get_size_x(tmp),
00575                                  cpl_image_get_size_y(tmp),
00576                                  cpl_image_get_type(tmp));
00577         cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN, 
00578                               CPL_BORDER_FILTER);
00579         if (i>0) cpl_image_delete(tmp) ;
00580 
00581         /* Subsample the image */
00582         subsampled = cpl_image_extract_subsample(filtered, 2, 2) ;
00583         cpl_image_delete(filtered) ;
00584     
00585         tmp = subsampled ;
00586     }
00587     cpl_mask_delete(kernel) ;
00588 
00589     /* Check nbpoints */
00590     if (nbpoints != 
00591             cpl_image_get_size_x(subsampled)*cpl_image_get_size_y(subsampled)) {
00592         cpl_msg_error(__func__, "Invalid size") ;
00593         cpl_image_delete(subsampled) ;
00594         return NULL ;
00595     }
00596     
00597     /* Create anchor points for the fit */
00598     xy_pos = cpl_bivector_new(nbpoints) ;
00599     vals = cpl_vector_new(nbpoints) ;
00600     pxy_pos_x = cpl_bivector_get_x_data(xy_pos) ;
00601     pxy_pos_y = cpl_bivector_get_y_data(xy_pos) ;
00602     pvals = cpl_vector_get_data(vals) ;
00603     pima = cpl_image_get_data_float(subsampled) ;
00604     for (j=0 ; j<ly ; j++) {
00605         for (i=0 ; i<lx ; i++) {
00606             pxy_pos_x[i+j*lx] = i * quad_sz + quad_sz/2 ;
00607             pxy_pos_y[i+j*lx] = j * quad_sz + quad_sz/2 ;
00608             pvals[i+j*lx] = (double)pima[i+j*lx];
00609         }
00610     }
00611     cpl_image_delete(subsampled) ;
00612 
00613     /* Fit the polynomial */
00614     if ((poly = cpl_polynomial_fit_2d_create(xy_pos, vals, 3, NULL)) == NULL) {
00615         cpl_msg_error(__func__, "Cannot fit the polynomial") ;
00616         cpl_bivector_delete(xy_pos) ;
00617         cpl_vector_delete(vals) ;
00618         return NULL ;
00619     }
00620     cpl_bivector_delete(xy_pos) ;
00621     cpl_vector_delete(vals) ;
00622 
00623     /* Regenerate the big bgd image */
00624     out = cpl_image_duplicate(in) ;
00625     cpl_image_fill_polynomial(out, poly, 1.0, 1.0, 1.0, 1.0) ;
00626     cpl_polynomial_delete(poly) ;
00627     
00628     return out ;
00629 }
00630 
00631 /*----------------------------------------------------------------------------*/
00638 /*----------------------------------------------------------------------------*/
00639 const char * hawki_extract_first_filename(
00640         const cpl_frameset  *   in,
00641         const char          *   tag)
00642 {
00643     const cpl_frame     *   cur_frame ;
00644 
00645     /* Get the frame  */
00646     if ((cur_frame = cpl_frameset_find_const(in, tag)) == NULL) return NULL ;
00647     return cpl_frame_get_filename(cur_frame) ;
00648 }
00649 
00650 /*----------------------------------------------------------------------------*/
00656 /*----------------------------------------------------------------------------*/
00657 hawki_band hawki_get_band(const char * f)
00658 {
00659     if (!strcmp(f, "J"))            return HAWKI_BAND_J ;
00660     if (!strcmp(f, "H"))            return HAWKI_BAND_H ;
00661     if (!strcmp(f, "K"))            return HAWKI_BAND_K ;
00662     if (!strcmp(f, "Ks"))           return HAWKI_BAND_K ;
00663     if (!strcmp(f, "Y"))            return HAWKI_BAND_Y ;
00664     return HAWKI_BAND_UNKNOWN ;
00665 }
00666 
00667 /*-------------------------------------------------------------------------*/
00673 /*--------------------------------------------------------------------------*/
00674 const char * hawki_std_band_name(hawki_band band)
00675 {
00676     switch (band) {
00677         case HAWKI_BAND_J:        return "J" ;
00678         case HAWKI_BAND_H:        return "H" ;
00679         case HAWKI_BAND_K:        return "K" ;
00680         case HAWKI_BAND_Y:        return "Y" ;
00681         default:            return "Unknown" ;
00682     } 
00683 }
00684 
00685 /*----------------------------------------------------------------------------*/
00694 /*----------------------------------------------------------------------------*/
00695 cpl_bivector * hawki_get_header_tel_offsets(const cpl_frameset * fset)
00696 {
00697     cpl_bivector        *   offsets ;
00698     double              *   offsets_x ;
00699     double              *   offsets_y ;
00700     const cpl_frame     *   frame ;
00701     cpl_propertylist    *   plist ;
00702     int                     nfiles ;
00703     int                     i ;
00704     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00705     
00706 
00707     /* Test entries */
00708     if (fset == NULL) return NULL ;
00709 
00710     /* Create the offsets bi vector */
00711     nfiles = cpl_frameset_get_size(fset) ;
00712     offsets = cpl_bivector_new(nfiles) ;
00713     offsets_x = cpl_bivector_get_x_data(offsets) ;
00714     offsets_y = cpl_bivector_get_y_data(offsets) ;
00715     for (i=0 ; i<nfiles ; i++) {
00716 
00717         /* X and Y offsets */
00718         frame = cpl_frameset_get_frame_const(fset, i) ;
00719         plist=cpl_propertylist_load(cpl_frame_get_filename(frame),0);
00720         offsets_x[i] = hawki_pfits_get_cumoffsetx(plist) ;
00721         offsets_y[i] = hawki_pfits_get_cumoffsety(plist) ;
00722         cpl_propertylist_delete(plist) ;
00723         if(!cpl_errorstate_is_equal(error_prevstate ))
00724         {
00725             cpl_msg_error(__func__, "Cannot get offsets from header") ;
00726             cpl_bivector_delete(offsets) ;
00727             return NULL ;
00728         }
00729     }
00730     return offsets ;
00731 }
00732 
00733 /*----------------------------------------------------------------------------*/
00739 /*----------------------------------------------------------------------------*/
00740 double hawki_get_mean_airmass(cpl_frameset *   set)
00741 {
00742     int                     nframes;
00743     cpl_frame           *   cur_frame;
00744     cpl_propertylist    *   plist;
00745     int                     iframe;
00746     double                  mean_airmass = 0.0;
00747 
00748     /* Test inputs  */
00749     if (set == NULL) return -1;
00750 
00751     /* Initialize */
00752     nframes = cpl_frameset_get_size(set);
00753 
00754     for (iframe=0 ; iframe<nframes ; iframe++) 
00755     {
00756         cur_frame = cpl_frameset_get_frame(set, iframe);
00757         plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
00758         mean_airmass +=   hawki_pfits_get_airmass_start(plist) +
00759                           hawki_pfits_get_airmass_end(plist); 
00760         cpl_propertylist_delete(plist);
00761     }
00762     mean_airmass /= 2. * nframes;
00763 
00764     /* Free and return */
00765     return mean_airmass;
00766 }
00767 
00768 /*----------------------------------------------------------------------------*/
00780 /*----------------------------------------------------------------------------*/
00781 int * hawki_detectors_labelise
00782 (const cpl_frameset * in)
00783 {
00784     int             *   labels ;
00785     cpl_bivector    *   offsets ;
00786     int                 nframes ;
00787     double          *   poff_x ;
00788     double          *   poff_y ;
00789     double              off_x_mean;
00790     double              off_y_mean;
00791     int                 i ;
00792 
00793     /* Check entries */
00794     if (in == NULL) return NULL ;
00795 
00796     /* Initialise */
00797     nframes = cpl_frameset_get_size(in) ;
00798 
00799     /* Get the offsets */
00800     if ((offsets = hawki_get_header_tel_offsets((cpl_frameset *)in)) == NULL) {
00801         cpl_msg_error(__func__, "Cannot read the offsets") ;
00802         return NULL ;
00803     }
00804     poff_x = cpl_bivector_get_x_data(offsets) ;
00805     poff_y = cpl_bivector_get_y_data(offsets) ;
00806 
00807     /* Get the mean offsets */
00808     off_x_mean = cpl_vector_get_mean(cpl_bivector_get_x(offsets));
00809     off_y_mean = cpl_vector_get_mean(cpl_bivector_get_y(offsets));
00810     
00811     /* Allocate labels */
00812     labels = cpl_malloc(nframes * sizeof(int)) ;
00813     for (i=0 ; i<nframes ; i++) {
00814         if (poff_x[i] - off_x_mean <= 0 && poff_y[i] - off_y_mean <= 0)
00815             labels[i] = 1 ;
00816         else if (poff_x[i] - off_x_mean >= 0 && poff_y[i] - off_y_mean <= 0) 
00817             labels[i] = 2 ;
00818         else if (poff_x[i] - off_x_mean >= 0 && poff_y[i] - off_y_mean >= 0) 
00819             labels[i] = 3 ;
00820         else if (poff_x[i] - off_x_mean <= 0 && poff_y[i] - off_y_mean >= 0) 
00821             labels[i] = 4 ;
00822         else labels[i] = 0 ;
00823     }
00824     cpl_bivector_delete(offsets) ;
00825     return labels ;
00826 }
00827 
00828 /*----------------------------------------------------------------------------*/
00835 /*----------------------------------------------------------------------------*/
00836 int hawki_detectors_locate_star
00837 (const cpl_frameset * in,
00838  double               star_ra,
00839  double               star_dec,
00840  int                * labels)
00841 {
00842     int     nframes;
00843     int     idet, iframe;
00844 
00845     /* Check entries */
00846     if (in == NULL) return -1;
00847 
00848     /* Initialise */
00849     nframes = cpl_frameset_get_size(in) ;
00850 
00851     /* Allocate labels */
00852     for (iframe=0 ; iframe<nframes ; iframe++) 
00853     {
00854         const char * filename;
00855         filename = cpl_frame_get_filename
00856             (cpl_frameset_get_frame_const(in, iframe));
00857         
00858         for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00859         {
00860             cpl_propertylist * main_header;
00861             cpl_propertylist * ext_header;
00862             cpl_wcs          * wcs;
00863             double             naxis1, naxis2;
00864             double             star_x, star_y;
00865         
00866             /* Get the headers */
00867             main_header = cpl_propertylist_load(filename, 0);
00868             ext_header  = cpl_propertylist_load
00869                 (filename, hawki_get_ext_from_detector(filename,idet + 1));
00870             
00871             /* Get the position of the star in pixels */
00872             wcs = cpl_wcs_new_from_propertylist(ext_header);
00873             if(wcs == NULL)
00874             {
00875                 cpl_msg_error(__func__, "Could not get WCS info");
00876                 cpl_propertylist_delete(ext_header);
00877                 cpl_propertylist_delete(main_header);
00878                 return -1;
00879             }
00880             if(irplib_wcs_radectoxy(wcs, star_ra, star_dec, &star_x, &star_y)
00881                     != CPL_ERROR_NONE)
00882             {
00883                 cpl_errorstate_set(CPL_ERROR_NONE);
00884             }
00885             
00886             /* Check for the limits */
00887             naxis1 = (double)hawki_pfits_get_naxis1(ext_header);
00888             naxis2 = (double)hawki_pfits_get_naxis2(ext_header);
00889             if(star_x > 0 && star_x < naxis1 && star_y > 0 && star_y < naxis2)
00890             {
00891                 labels[iframe] = idet + 1;
00892             }
00893             
00894             /* Free */
00895             cpl_propertylist_delete(ext_header);
00896             cpl_propertylist_delete(main_header);
00897             cpl_wcs_delete(wcs);
00898         }
00899         if(labels[iframe] == 0)
00900         {
00901             cpl_msg_error(__func__,"Frame %d does not contain the star in any "
00902                           "detector", iframe + 1);
00903         }
00904     }
00905     return 0;
00906 }
00907 
00908 /*----------------------------------------------------------------------------*/
00916 /*----------------------------------------------------------------------------*/
00917 double hawki_vector_get_max_select
00918 (const cpl_vector * self, const cpl_vector * valid)
00919 {
00920     double max_val = DBL_MIN;
00921     int    initialized = 0;
00922     int    ival;
00923     int    nvals;
00924     
00925     nvals = cpl_vector_get_size(self);
00926     for(ival = 0; ival < nvals; ++ival)
00927     {
00928         if(cpl_vector_get(valid, ival) >= -0.5) 
00929         {
00930             if(!initialized)
00931             {
00932                 max_val = cpl_vector_get(self, ival);
00933                 initialized = 1;
00934             }
00935             if(cpl_vector_get(self, ival) > max_val)
00936                 max_val = cpl_vector_get(self, ival);
00937         }
00938     }
00939     return max_val;
00940 }
00941 
00942 /*----------------------------------------------------------------------------*/
00950 /*----------------------------------------------------------------------------*/
00951 double hawki_vector_get_min_select
00952 (const cpl_vector * self, const cpl_vector * valid)
00953 {
00954     double min_val = DBL_MAX;
00955     int    initialized = 0;
00956     int    ival;
00957     int    nvals;
00958     
00959     nvals = cpl_vector_get_size(self);
00960     for(ival = 0; ival < nvals; ++ival)
00961     {
00962         if(cpl_vector_get(valid, ival) >= -0.5) 
00963         {
00964             if(!initialized)
00965             {
00966                 min_val = cpl_vector_get(self, ival);
00967                 initialized = 1;
00968             }
00969             if(cpl_vector_get(self, ival) < min_val)
00970                 min_val = cpl_vector_get(self, ival);
00971         }
00972     }
00973     return min_val;
00974 }
00975 
00976 /*----------------------------------------------------------------------------*/
00982 /*----------------------------------------------------------------------------*/
00983 double hawki_vector_get_mode(cpl_vector * vec)
00984 {
00985     int                 nb ;
00986     int                 nbins ;
00987     double              min, max ;
00988     double              bin_size ;
00989     cpl_bivector    *   hist ;
00990     cpl_vector      *   hist_x ;
00991     cpl_vector      *   hist_y ;
00992     double              cur_val ;
00993     int                 cur_bin ;
00994     double              max_val ;
00995     int                 max_bin ;
00996     double              mode ;
00997     int                 i ;
00998 
00999     /* Test entries  */
01000     if (vec == NULL) return -1.0 ;
01001     
01002     /* Initialise */
01003     nb = cpl_vector_get_size(vec) ;
01004 
01005     /* Create the histogram */
01006     nbins = 10 ;
01007     min = cpl_vector_get_min(vec) ;
01008     max = cpl_vector_get_max(vec) ;
01009     bin_size = (max-min)/nbins ;
01010     hist = cpl_bivector_new(nbins) ;
01011     hist_x = cpl_bivector_get_x(hist) ;
01012     hist_y = cpl_bivector_get_y(hist) ;
01013     cpl_vector_fill(hist_x, 0.0) ;
01014     cpl_vector_fill(hist_y, 0.0) ;
01015     for (i=0 ; i<nbins ; i++) {
01016         cpl_vector_set(hist_x, i, min + i * bin_size) ;
01017     }
01018     for (i=0 ; i<nb ; i++) {
01019         cur_val = cpl_vector_get(vec, i) ;
01020         cur_bin = (int)((cur_val - min) / bin_size) ;
01021         if (cur_bin >= nbins) cur_bin -= 1.0 ;
01022         cur_val = cpl_vector_get(hist_y, cur_bin) ;
01023         cur_val += 1.0 ;
01024         cpl_vector_set(hist_y, cur_bin, cur_val) ;
01025     }
01026     
01027     /* Get the mode of the histogram */
01028     max_val = cpl_vector_get(hist_y, 0) ;
01029     max_bin = 0 ;
01030     for (i=0 ; i<nbins ; i++) {
01031         cur_val = cpl_vector_get(hist_y, i) ;
01032         if (cur_val > max_val) {
01033             max_val = cur_val ;
01034             max_bin = i ;
01035         }
01036     }
01037     mode = cpl_vector_get(hist_x, max_bin) ;
01038     cpl_bivector_delete(hist) ;
01039     return mode ;
01040 }
01041 
01042 /*----------------------------------------------------------------------------*/
01050 /*----------------------------------------------------------------------------*/
01051 int hawki_utils_check_equal_double_keys
01052 (cpl_frameset * frames, double (*func)(const cpl_propertylist *))
01053 {
01054     int                iframe;
01055     double             value = 0;
01056     
01057     if(cpl_frameset_get_size(frames) < 2)
01058        return 1;
01059 
01060     for(iframe = 0; iframe < cpl_frameset_get_size(frames); ++iframe)
01061     {
01062         cpl_propertylist * header;
01063         header = cpl_propertylist_load(
01064                      cpl_frame_get_filename(
01065                      cpl_frameset_get_frame_const(frames, iframe)),0);
01066         if(iframe == 0)
01067             value = (func)(header);
01068         else
01069             if(value != (func)(header))
01070             {
01071                 cpl_propertylist_delete(header);
01072                 return 0;
01073             }
01074         cpl_propertylist_delete(header);
01075     }
01076     return 1;
01077 }
01078 
01079 /*----------------------------------------------------------------------------*/
01087 /*----------------------------------------------------------------------------*/
01088 int hawki_utils_check_equal_int_keys
01089 (cpl_frameset * frames, int (*func)(const cpl_propertylist *))
01090 {
01091     int                iframe;
01092     int                value = 0;
01093     
01094     if(cpl_frameset_get_size(frames) < 2)
01095        return 1;
01096 
01097     for(iframe = 0; iframe < cpl_frameset_get_size(frames); ++iframe)
01098     {
01099         cpl_propertylist * header;
01100         header = cpl_propertylist_load(
01101                      cpl_frame_get_filename(
01102                      cpl_frameset_get_frame_const(frames, iframe)),0);
01103         if(iframe == 0)
01104             value = (func)(header);
01105         else
01106             if(value != (func)(header))
01107             {
01108                 cpl_propertylist_delete(header);
01109                 return 0;
01110             }
01111         cpl_propertylist_delete(header);
01112     }
01113     return 1;
01114 }
01115 
01116 /*----------------------------------------------------------------------------*/
01126 /*----------------------------------------------------------------------------*/
01127 void hawki_utils_ra2str(char * str, int length_str, double ra)
01128 {
01129     double a,b;
01130     double seconds;
01131     char tstring[64];
01132     int hours;
01133     int minutes;
01134     int ltstr;
01135     double dsgn;
01136 
01137     /* Keep RA between 0 and 360 */
01138     if (ra < 0.0 ) 
01139     {
01140         ra = -ra;
01141         dsgn = -1.0;
01142     }
01143     else
01144         dsgn = 1.0;
01145     ra = fmod(ra, 360.0);
01146     ra *= dsgn;
01147     if (ra < 0.0)
01148         ra = ra + 360.0;
01149 
01150     a = ra / 15.0;
01151 
01152     /* Convert to hours */
01153     hours = (int) a;
01154 
01155     /* Compute minutes */
01156     b =  (a - (double)hours) * 60.0;
01157     minutes = (int) b;
01158 
01159     /* Compute seconds */
01160     seconds = (b - (double)minutes) * 60.0;
01161 
01162     if (seconds > 59.99) 
01163     {
01164         seconds = 0.0;
01165         minutes = minutes + 1;
01166     }
01167     if (minutes > 59) 
01168     {
01169         minutes = 0;
01170         hours = hours + 1;
01171     }
01172     hours = hours % 24;
01173     (void) sprintf (tstring,"%02d:%02d:%05.2f",hours,minutes,seconds);
01174 
01175     /* Move formatted string to returned string */
01176     ltstr = (int) strlen (tstring);
01177     if (ltstr < length_str-1)
01178         strcpy (str, tstring);
01179     else 
01180     {
01181         strncpy (str, tstring, length_str-1);
01182         str[length_str-1] = 0;
01183     }
01184     return;
01185 }
01186 
01187 /*----------------------------------------------------------------------------*/
01197 /*----------------------------------------------------------------------------*/
01198 void hawki_utils_dec2str(char * str, int length_str, double dec)
01199 {
01200     double a, b, dsgn, deg1;
01201     double seconds;
01202     char sign;
01203     int degrees;
01204     int minutes;
01205     int ltstr;
01206     char tstring[64];
01207 
01208     /* Keep angle between -180 and 360 degrees */
01209     deg1 = dec;
01210     if (deg1 < 0.0 ) 
01211     {
01212         deg1 = -deg1;
01213         dsgn = -1.0;
01214     }
01215     else
01216         dsgn = 1.0;
01217     deg1 = fmod(deg1, 360.0);
01218     deg1 *= dsgn;
01219     if (deg1 <= -180.0)
01220         deg1 = deg1 + 360.0;
01221 
01222     a = deg1;
01223 
01224     /* Set sign and do all the rest with a positive */
01225     if (a < 0) 
01226     {
01227         sign = '-';
01228         a = -a;
01229     }
01230     else
01231         sign = '+';
01232 
01233     /* Convert to degrees */
01234     degrees = (int) a;
01235 
01236     /* Compute minutes */
01237     b =  (a - (double)degrees) * 60.0;
01238     minutes = (int) b;
01239 
01240     /* Compute seconds */
01241     seconds = (b - (double)minutes) * 60.0;
01242 
01243     if (seconds > 59.99) 
01244     {
01245         seconds = 0.0;
01246         minutes = minutes + 1;
01247     }
01248     if (minutes > 59) 
01249     {
01250         minutes = 0;
01251         degrees = degrees + 1;
01252     }
01253     (void) sprintf (tstring,"%c%02d:%02d:%05.2f",sign,degrees,minutes,seconds);
01254 
01255     /* Move formatted string to returned string */
01256     ltstr = (int) strlen (tstring);
01257     if (ltstr < length_str-1)
01258         strcpy (str, tstring);
01259     else 
01260     {
01261         strncpy (str, tstring, length_str-1);
01262         str[length_str-1] = 0;
01263     }
01264     return;
01265 }
01266 
01275 cpl_error_code
01276 hawki_frameset_append(cpl_frameset *self, const cpl_frameset *other)
01277 {
01278     cpl_size iframe;
01279     cpl_size nframes;
01280 
01281     nframes = cpl_frameset_get_size(other);
01282 
01283     for(iframe = 0; iframe<nframes; ++iframe)
01284     {
01285         cpl_frame * newframe;
01286         newframe = cpl_frame_duplicate
01287             (cpl_frameset_get_frame_const(other, iframe));
01288         if(cpl_frameset_insert(self, newframe) != CPL_ERROR_NONE)
01289         {
01290             cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
01291             return CPL_ERROR_ILLEGAL_INPUT;
01292         }
01293     }
01294     return CPL_ERROR_NONE;
01295 }
01296