HAWKI Pipeline Reference Manual 1.8.12
|
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