HAWKI Pipeline Reference Manual  1.8.12
hawki_utils.c
1 /* $Id: hawki_utils.c,v 1.54 2012/12/06 16:55:32 cgarcia Exp $
2  *
3  * This file is part of the HAWKI Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: cgarcia $
23  * $Date: 2012/12/06 16:55:32 $
24  * $Revision: 1.54 $
25  * $Name: hawki-1_8_12 $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <float.h>
37 #include <string.h>
38 #include <math.h>
39 #include <cpl.h>
40 
41 #include "irplib_cat.h"
42 #include "irplib_wcs.h"
43 
44 #include "hawki_utils.h"
45 #include "hawki_pfits.h"
46 #include "hawki_load.h"
47 
48 /*----------------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------------*/
53 
56 /*----------------------------------------------------------------------------*/
64 /*----------------------------------------------------------------------------*/
65 const char * hawki_get_license(void)
66 {
67  const char * hawki_license =
68  "This file is part of the HAWKI Instrument Pipeline\n"
69  "Copyright (C) 2002,2011 European Southern Observatory\n"
70  "\n"
71  "This program is free software; you can redistribute it and/or modify\n"
72  "it under the terms of the GNU General Public License as published by\n"
73  "the Free Software Foundation; either version 2 of the License, or\n"
74  "(at your option) any later version.\n"
75  "\n"
76  "This program is distributed in the hope that it will be useful,\n"
77  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
78  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
79  "GNU General Public License for more details.\n"
80  "\n"
81  "You should have received a copy of the GNU General Public License\n"
82  "along with this program; if not, write to the Free Software\n"
83  "Foundation, Inc., 59 Temple Place, Suite 330, Boston, \n"
84  "MA 02111-1307 USA" ;
85  return hawki_license ;
86 }
87 
88 /*----------------------------------------------------------------------------*/
92 /*----------------------------------------------------------------------------*/
94 {
95  cpl_msg_info(__func__, "*****************************************");
96  cpl_msg_info(__func__, "Welcome to HAWK-I Pipeline release %s",
98  cpl_msg_info(__func__, "*****************************************");
99 }
100 
101 /*----------------------------------------------------------------------------*/
105 /*----------------------------------------------------------------------------*/
106 const char * hawki_get_version(void)
107 {
108  return PACKAGE_VERSION;
109 }
110 
111 /*----------------------------------------------------------------------------*/
118 /*----------------------------------------------------------------------------*/
120  const cpl_image * in,
121  double sigma)
122 {
123  double med, stdev, threshold ;
124  cpl_image * bpm ;
125  cpl_image * bpm_int ;
126 
127  /* Test entries */
128  if (in == NULL) return NULL ;
129  if (sigma <= 0) return NULL ;
130 
131  bpm = cpl_image_duplicate(in);
132 
133  /* Compute the threshold */
134  med = cpl_image_get_median_dev(bpm, &stdev) ;
135  threshold = med + sigma*stdev ;
136  cpl_msg_info(__func__, "Threshold : %g = %g + %g * %g",
137  threshold, med, sigma, stdev) ;
138 
139  /* Compute the bpm */
140  cpl_image_threshold(bpm, threshold, threshold, 0.0, 1.0) ;
141 
142  /* Convert */
143  bpm_int = cpl_image_cast(bpm, CPL_TYPE_INT) ;
144  cpl_image_delete(bpm) ;
145 
146  return bpm_int ;
147 }
148 
149 /*----------------------------------------------------------------------------*/
162 /*----------------------------------------------------------------------------*/
163 cpl_image * hawki_compute_flatbpm
164 (const cpl_image * in,
165  double sigma,
166  double lowval,
167  double highval)
168 {
169  cpl_mask * kernel ;
170  cpl_image * filtered ;
171  double med, stdev, threshold ;
172  cpl_image * bpm_sigma;
173  cpl_image * bpm_lowhigh;
174  cpl_image * bpm;
175  cpl_image * bpm_int ;
176 
177  /* Test entries */
178  if (in == NULL) return NULL ;
179  if (sigma <= 0) return NULL ;
180 
181  /* Filter the input image */
182  kernel = cpl_mask_new(3, 3) ;
183  cpl_mask_not(kernel) ;
184  filtered = cpl_image_new(cpl_image_get_size_x(in), cpl_image_get_size_y(in),
185  cpl_image_get_type(in));
186  cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN,
187  CPL_BORDER_FILTER);
188  cpl_mask_delete(kernel) ;
189 
190  /* Remove the low freq signal */
191  bpm_sigma = cpl_image_subtract_create(in, filtered) ;
192  cpl_image_delete(filtered) ;
193 
194  /* Compute the threshold */
195  med = cpl_image_get_median_dev(bpm_sigma, &stdev) ;
196  threshold = med + sigma*stdev ;
197  cpl_msg_info(__func__, "Threshold : %g = %g + %g * %g",
198  threshold, med, sigma, stdev) ;
199 
200  /* Compute the bpm with the sigma values */
201  cpl_image_threshold(bpm_sigma, threshold, threshold, 0.0, 1.0) ;
202 
203  /* Count the pixels below and above the lowval and highval */
204  bpm_lowhigh = cpl_image_duplicate(in);
205  hawki_image_inverse_threshold(bpm_lowhigh, lowval, highval, 0.0, 1.0);
206 
207  /* Merge both masks */
208  bpm = cpl_image_add_create(bpm_sigma, bpm_lowhigh);
209  cpl_image_threshold(bpm, 0.0, 1.0, 0.0, 1.0);
210 
211  /* Convert */
212  bpm_int = cpl_image_cast(bpm, CPL_TYPE_INT) ;
213  cpl_image_delete(bpm) ;
214  cpl_image_delete(bpm_sigma);
215  cpl_image_delete(bpm_lowhigh);
216 
217  return bpm_int ;
218 }
219 
220 /*----------------------------------------------------------------------------*/
239 /*----------------------------------------------------------------------------*/
240 cpl_error_code hawki_image_inverse_threshold
241 (cpl_image * image_in,
242  double lo_valid,
243  double hi_valid,
244  double assign_in_range,
245  double assign_out_range)
246 {
247  int i;
248  int npix;
249 
250  cpl_ensure_code(image_in != NULL, CPL_ERROR_NULL_INPUT);
251  cpl_ensure_code(lo_valid <= hi_valid, CPL_ERROR_ILLEGAL_INPUT);
252 
253  /* Get number of pixels of image */
254  npix = cpl_image_get_size_x(image_in) * cpl_image_get_size_y(image_in);
255 
256  /* Switch on image type */
257  switch (cpl_image_get_type(image_in))
258  {
259  case CPL_TYPE_DOUBLE: {
260  double * pdi = cpl_image_get_data_double(image_in);
261  for (i=0; i<npix; i++) {
262  if ((pdi[i]>lo_valid) && (pdi[i]<hi_valid))
263  pdi[i] = (double)assign_in_range;
264  else
265  pdi[i] = (double)assign_out_range;
266  }
267  break;
268  }
269  case CPL_TYPE_FLOAT: {
270  float * pdi = cpl_image_get_data_float(image_in);
271  for (i=0; i<npix; i++) {
272  if ((pdi[i]>lo_valid) && (pdi[i]<hi_valid))
273  pdi[i] = (float)assign_in_range;
274  else
275  pdi[i] = (float)assign_out_range;
276  }
277  break;
278  }
279  case CPL_TYPE_INT: {
280  int * pdi = cpl_image_get_data_int(image_in);
281  for (i=0; i<npix; i++) {
282  if (((double)pdi[i]>lo_valid) && ((double)pdi[i]<hi_valid))
283  pdi[i] = (int)assign_in_range;
284  else
285  pdi[i] = (int)assign_out_range;
286  }
287  break;
288  }
289  default:
290  cpl_ensure_code(0, CPL_ERROR_INVALID_TYPE);
291  }
292  return CPL_ERROR_NONE;
293 }
294 
295 /*----------------------------------------------------------------------------*/
303 /*----------------------------------------------------------------------------*/
304 cpl_image * hawki_images_stitch
305 (cpl_image ** ima,
306  double * x,
307  double * y)
308 {
309  int lx, ly ;
310  cpl_image * ima_ext[HAWKI_NB_DETECTORS] ;
311  cpl_imagelist * in ;
312  cpl_bivector * offsets ;
313  double * offsets_x ;
314  double * offsets_y ;
315  cpl_image ** combined ;
316  cpl_image * stitched ;
317  int i ;
318 
319  /* Test entries */
320  if (ima == NULL) return NULL ;
321  if (x == NULL) return NULL ;
322  if (y == NULL) return NULL ;
323 
324  /* Take the smallest size */
325  lx = cpl_image_get_size_x(ima[0]) ;
326  ly = cpl_image_get_size_y(ima[0]) ;
327  for (i=1 ; i<HAWKI_NB_DETECTORS ; i++) {
328  if (lx > cpl_image_get_size_x(ima[i]))
329  lx = cpl_image_get_size_x(ima[i]) ;
330  if (ly > cpl_image_get_size_y(ima[i]))
331  ly = cpl_image_get_size_y(ima[i]) ;
332  }
333 
334  /* Create the image list */
335  in = cpl_imagelist_new() ;
336  for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
337  ima_ext[i] = cpl_image_extract(ima[i], 1, 1, lx, ly) ;
338  cpl_imagelist_set(in, ima_ext[i], i) ;
339  }
340 
341  /* Create the offsets */
342  offsets = cpl_bivector_new(HAWKI_NB_DETECTORS) ;
343  offsets_x = cpl_bivector_get_x_data(offsets) ;
344  offsets_y = cpl_bivector_get_y_data(offsets) ;
345  offsets_x[0] = HAWKI_DET1_POSX ;
346  offsets_y[0] = HAWKI_DET1_POSY ;
347  offsets_x[1] = x[0] - x[1] + HAWKI_DET2_POSX ;
348  offsets_y[1] = y[0] - y[1] + HAWKI_DET2_POSY ;
349  offsets_x[2] = x[0] - x[2] + HAWKI_DET3_POSX ;
350  offsets_y[2] = y[0] - y[2] + HAWKI_DET3_POSY ;
351  offsets_x[3] = x[0] - x[3] + HAWKI_DET4_POSX ;
352  offsets_y[3] = y[0] - y[3] + HAWKI_DET4_POSY ;
353 
354  /* Recombine the images */
355  if ((combined = cpl_geom_img_offset_saa(in, offsets,
356  CPL_KERNEL_DEFAULT, 0, 0, CPL_GEOM_UNION, NULL, NULL)) == NULL)
357  {
358  cpl_msg_error(__func__, "Cannot recombine the images") ;
359  cpl_bivector_delete(offsets) ;
360  cpl_imagelist_delete(in) ;
361  return NULL ;
362  }
363  cpl_bivector_delete(offsets) ;
364  cpl_imagelist_delete(in) ;
365 
366  /* Return */
367  stitched = combined[0] ;
368  cpl_image_delete(combined[1]) ;
369  cpl_free(combined) ;
370  return stitched ;
371 }
372 
373 /*----------------------------------------------------------------------------*/
383 /*----------------------------------------------------------------------------*/
385  cpl_imagelist * in,
386  double h1,
387  double h2,
388  double h3,
389  double h4)
390 {
391  /* Test entries */
392  if (in == NULL) return -1 ;
393 
394  cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 0), h1) ;
395  cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 1), h2) ;
396  cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 2), h3) ;
397  cpl_image_multiply_scalar((cpl_image *)cpl_imagelist_get(in, 3), h4) ;
398 
399  return 0 ;
400 }
401 
402 /*----------------------------------------------------------------------------*/
421 /*----------------------------------------------------------------------------*/
423  const cpl_imagelist * in,
424  double * h1,
425  double * h2,
426  double * h3,
427  double * h4,
428  double * h)
429 {
430  int width = 64 ;
431  int nx, ny ;
432  const cpl_image * ima ;
433  double avg1, avg2, avg3, avg4 ;
434  double val1, val2 ;
435  int llx, lly, urx, ury ;
436 
437  /* Test entries */
438  if (in == NULL) return -1 ;
439  if (h1==NULL || h2==NULL || h3==NULL || h4==NULL || h==NULL) return -1 ;
440 
441  /* Compute the avg1 */
442  ima = cpl_imagelist_get_const(in, 0) ;
443  nx = cpl_image_get_size_x(ima) ;
444  ny = cpl_image_get_size_y(ima) ;
445  llx = 1 ; lly = ny - width + 1 ; urx = nx ; ury = ny ;
446  val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
447  if (cpl_error_get_code()) {
448  cpl_msg_error(__func__, "Cannot get statistics from chip 1") ;
449  return -1 ;
450  }
451  llx = nx - width + 1 ; lly = 1 ; urx = nx ; ury = ny ;
452  val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
453  if (cpl_error_get_code()) {
454  cpl_msg_error(__func__, "Cannot get statistics from chip 1") ;
455  return -1 ;
456  }
457  avg1 = (val1 + val2) / 2.0 ;
458 
459  /* Compute the avg2 */
460  ima = cpl_imagelist_get_const(in, 1) ;
461  nx = cpl_image_get_size_x(ima) ;
462  ny = cpl_image_get_size_y(ima) ;
463  llx = 1 ; lly = 1 ; urx = width ; ury = ny ;
464  val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
465  if (cpl_error_get_code()) {
466  cpl_msg_error(__func__, "Cannot get statistics from chip 2") ;
467  return -1 ;
468  }
469  llx = 1 ; lly = ny - width + 1 ; urx = nx ; ury = ny ;
470  val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
471  if (cpl_error_get_code()) {
472  cpl_msg_error(__func__, "Cannot get statistics from chip 2") ;
473  return -1 ;
474  }
475  avg2 = (val1 + val2) / 2.0 ;
476 
477  /* Compute the avg3 */
478  ima = cpl_imagelist_get_const(in, 2) ;
479  nx = cpl_image_get_size_x(ima) ;
480  ny = cpl_image_get_size_y(ima) ;
481  llx = 1 ; lly = 1 ; urx = nx ; ury = width ;
482  val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
483  if (cpl_error_get_code()) {
484  cpl_msg_error(__func__, "Cannot get statistics from chip 3") ;
485  return -1 ;
486  }
487  llx = nx - width + 1 ; lly = 1 ; urx = nx ; ury = ny ;
488  val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
489  if (cpl_error_get_code()) {
490  cpl_msg_error(__func__, "Cannot get statistics from chip 3") ;
491  return -1 ;
492  }
493  avg3 = (val1 + val2) / 2.0 ;
494 
495  /* Compute the avg4 */
496  ima = cpl_imagelist_get_const(in, 3) ;
497  nx = cpl_image_get_size_x(ima) ;
498  ny = cpl_image_get_size_y(ima) ;
499  llx = 1 ; lly = 1 ; urx = width ; ury = ny ;
500  val1 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
501  if (cpl_error_get_code()) {
502  cpl_msg_error(__func__, "Cannot get statistics from chip 4") ;
503  return -1 ;
504  }
505  llx = 1 ; lly = 1 ; urx = nx ; ury = width ;
506  val2 = cpl_image_get_mean_window(ima, llx, lly, urx, ury) ;
507  if (cpl_error_get_code()) {
508  cpl_msg_error(__func__, "Cannot get statistics from chip 4") ;
509  return -1 ;
510  }
511  avg4 = (val1 + val2) / 2.0 ;
512 
513  /* Compute h */
514  *h = (avg1 + avg2 + avg3 + avg4) / 4.0 ;
515 
516  *h1 = *h / avg1 ;
517  *h2 = *h / avg2 ;
518  *h3 = *h / avg3 ;
519  *h4 = *h / avg4 ;
520 
521  return 0 ;
522 }
523 
524 /*----------------------------------------------------------------------------*/
530 /*----------------------------------------------------------------------------*/
531 cpl_image * hawki_compute_lsbg(const cpl_image * in)
532 {
533  cpl_image * out ;
534  cpl_image * tmp ;
535  cpl_image * filtered ;
536  cpl_image * subsampled ;
537  cpl_mask * kernel ;
538  int nscales ;
539  cpl_polynomial * poly ;
540  cpl_bivector * xy_pos ;
541  cpl_vector * vals ;
542  int quad_sz, nbpoints, lx, ly, nx, ny ;
543  double * pxy_pos_x ;
544  double * pxy_pos_y ;
545  double * pvals ;
546  float * pima ;
547  int i, j ;
548 
549  /* Check entries */
550  if (in == NULL) return NULL ;
551  nx = cpl_image_get_size_x(in) ;
552  ny = cpl_image_get_size_y(in) ;
553 
554  /* Initialise */
555  nscales = 7 ;
556  tmp = (cpl_image *)in ;
557  subsampled = NULL ;
558 
559  /* Check entries */
560  quad_sz = pow(2, (double)nscales) ;
561  lx = nx / quad_sz ;
562  ly = ny / quad_sz ;
563  nbpoints = lx * ly ;
564  if (quad_sz >= nx || quad_sz >= ny) return NULL ;
565 
566  /* Create filter kernel */
567  kernel = cpl_mask_new(3, 3) ;
568  cpl_mask_not(kernel) ;
569 
570  /* Loop nscales times */
571  for (i=0 ; i<nscales ; i++) {
572 
573  /* Filter the image */
574  filtered = cpl_image_new(cpl_image_get_size_x(tmp),
575  cpl_image_get_size_y(tmp),
576  cpl_image_get_type(tmp));
577  cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN,
578  CPL_BORDER_FILTER);
579  if (i>0) cpl_image_delete(tmp) ;
580 
581  /* Subsample the image */
582  subsampled = cpl_image_extract_subsample(filtered, 2, 2) ;
583  cpl_image_delete(filtered) ;
584 
585  tmp = subsampled ;
586  }
587  cpl_mask_delete(kernel) ;
588 
589  /* Check nbpoints */
590  if (nbpoints !=
591  cpl_image_get_size_x(subsampled)*cpl_image_get_size_y(subsampled)) {
592  cpl_msg_error(__func__, "Invalid size") ;
593  cpl_image_delete(subsampled) ;
594  return NULL ;
595  }
596 
597  /* Create anchor points for the fit */
598  xy_pos = cpl_bivector_new(nbpoints) ;
599  vals = cpl_vector_new(nbpoints) ;
600  pxy_pos_x = cpl_bivector_get_x_data(xy_pos) ;
601  pxy_pos_y = cpl_bivector_get_y_data(xy_pos) ;
602  pvals = cpl_vector_get_data(vals) ;
603  pima = cpl_image_get_data_float(subsampled) ;
604  for (j=0 ; j<ly ; j++) {
605  for (i=0 ; i<lx ; i++) {
606  pxy_pos_x[i+j*lx] = i * quad_sz + quad_sz/2 ;
607  pxy_pos_y[i+j*lx] = j * quad_sz + quad_sz/2 ;
608  pvals[i+j*lx] = (double)pima[i+j*lx];
609  }
610  }
611  cpl_image_delete(subsampled) ;
612 
613  /* Fit the polynomial */
614  if ((poly = cpl_polynomial_fit_2d_create(xy_pos, vals, 3, NULL)) == NULL) {
615  cpl_msg_error(__func__, "Cannot fit the polynomial") ;
616  cpl_bivector_delete(xy_pos) ;
617  cpl_vector_delete(vals) ;
618  return NULL ;
619  }
620  cpl_bivector_delete(xy_pos) ;
621  cpl_vector_delete(vals) ;
622 
623  /* Regenerate the big bgd image */
624  out = cpl_image_duplicate(in) ;
625  cpl_image_fill_polynomial(out, poly, 1.0, 1.0, 1.0, 1.0) ;
626  cpl_polynomial_delete(poly) ;
627 
628  return out ;
629 }
630 
631 /*----------------------------------------------------------------------------*/
638 /*----------------------------------------------------------------------------*/
640  const cpl_frameset * in,
641  const char * tag)
642 {
643  const cpl_frame * cur_frame ;
644 
645  /* Get the frame */
646  if ((cur_frame = cpl_frameset_find_const(in, tag)) == NULL) return NULL ;
647  return cpl_frame_get_filename(cur_frame) ;
648 }
649 
650 /*----------------------------------------------------------------------------*/
656 /*----------------------------------------------------------------------------*/
657 hawki_band hawki_get_band(const char * f)
658 {
659  if (!strcmp(f, "J")) return HAWKI_BAND_J ;
660  if (!strcmp(f, "H")) return HAWKI_BAND_H ;
661  if (!strcmp(f, "K")) return HAWKI_BAND_K ;
662  if (!strcmp(f, "Ks")) return HAWKI_BAND_K ;
663  if (!strcmp(f, "Y")) return HAWKI_BAND_Y ;
664  return HAWKI_BAND_UNKNOWN ;
665 }
666 
667 /*-------------------------------------------------------------------------*/
673 /*--------------------------------------------------------------------------*/
674 const char * hawki_std_band_name(hawki_band band)
675 {
676  switch (band) {
677  case HAWKI_BAND_J: return "J" ;
678  case HAWKI_BAND_H: return "H" ;
679  case HAWKI_BAND_K: return "K" ;
680  case HAWKI_BAND_Y: return "Y" ;
681  default: return "Unknown" ;
682  }
683 }
684 
685 /*----------------------------------------------------------------------------*/
694 /*----------------------------------------------------------------------------*/
695 cpl_bivector * hawki_get_header_tel_offsets(const cpl_frameset * fset)
696 {
697  cpl_bivector * offsets ;
698  double * offsets_x ;
699  double * offsets_y ;
700  const cpl_frame * frame ;
701  cpl_propertylist * plist ;
702  int nfiles ;
703  int i ;
704  cpl_errorstate error_prevstate = cpl_errorstate_get();
705 
706 
707  /* Test entries */
708  if (fset == NULL) return NULL ;
709 
710  /* Create the offsets bi vector */
711  nfiles = cpl_frameset_get_size(fset) ;
712  offsets = cpl_bivector_new(nfiles) ;
713  offsets_x = cpl_bivector_get_x_data(offsets) ;
714  offsets_y = cpl_bivector_get_y_data(offsets) ;
715  for (i=0 ; i<nfiles ; i++) {
716 
717  /* X and Y offsets */
718  frame = cpl_frameset_get_frame_const(fset, i) ;
719  plist=cpl_propertylist_load(cpl_frame_get_filename(frame),0);
720  offsets_x[i] = hawki_pfits_get_cumoffsetx(plist) ;
721  offsets_y[i] = hawki_pfits_get_cumoffsety(plist) ;
722  cpl_propertylist_delete(plist) ;
723  if(!cpl_errorstate_is_equal(error_prevstate ))
724  {
725  cpl_msg_error(__func__, "Cannot get offsets from header") ;
726  cpl_bivector_delete(offsets) ;
727  return NULL ;
728  }
729  }
730  return offsets ;
731 }
732 
733 /*----------------------------------------------------------------------------*/
739 /*----------------------------------------------------------------------------*/
740 double hawki_get_mean_airmass(cpl_frameset * set)
741 {
742  int nframes;
743  cpl_frame * cur_frame;
744  cpl_propertylist * plist;
745  int iframe;
746  double mean_airmass = 0.0;
747 
748  /* Test inputs */
749  if (set == NULL) return -1;
750 
751  /* Initialize */
752  nframes = cpl_frameset_get_size(set);
753 
754  for (iframe=0 ; iframe<nframes ; iframe++)
755  {
756  cur_frame = cpl_frameset_get_frame(set, iframe);
757  plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
758  mean_airmass += hawki_pfits_get_airmass_start(plist) +
760  cpl_propertylist_delete(plist);
761  }
762  mean_airmass /= 2. * nframes;
763 
764  /* Free and return */
765  return mean_airmass;
766 }
767 
768 /*----------------------------------------------------------------------------*/
780 /*----------------------------------------------------------------------------*/
782 (const cpl_frameset * in)
783 {
784  int * labels ;
785  cpl_bivector * offsets ;
786  int nframes ;
787  double * poff_x ;
788  double * poff_y ;
789  double off_x_mean;
790  double off_y_mean;
791  int i ;
792 
793  /* Check entries */
794  if (in == NULL) return NULL ;
795 
796  /* Initialise */
797  nframes = cpl_frameset_get_size(in) ;
798 
799  /* Get the offsets */
800  if ((offsets = hawki_get_header_tel_offsets((cpl_frameset *)in)) == NULL) {
801  cpl_msg_error(__func__, "Cannot read the offsets") ;
802  return NULL ;
803  }
804  poff_x = cpl_bivector_get_x_data(offsets) ;
805  poff_y = cpl_bivector_get_y_data(offsets) ;
806 
807  /* Get the mean offsets */
808  off_x_mean = cpl_vector_get_mean(cpl_bivector_get_x(offsets));
809  off_y_mean = cpl_vector_get_mean(cpl_bivector_get_y(offsets));
810 
811  /* Allocate labels */
812  labels = cpl_malloc(nframes * sizeof(int)) ;
813  for (i=0 ; i<nframes ; i++) {
814  if (poff_x[i] - off_x_mean <= 0 && poff_y[i] - off_y_mean <= 0)
815  labels[i] = 1 ;
816  else if (poff_x[i] - off_x_mean >= 0 && poff_y[i] - off_y_mean <= 0)
817  labels[i] = 2 ;
818  else if (poff_x[i] - off_x_mean >= 0 && poff_y[i] - off_y_mean >= 0)
819  labels[i] = 3 ;
820  else if (poff_x[i] - off_x_mean <= 0 && poff_y[i] - off_y_mean >= 0)
821  labels[i] = 4 ;
822  else labels[i] = 0 ;
823  }
824  cpl_bivector_delete(offsets) ;
825  return labels ;
826 }
827 
828 /*----------------------------------------------------------------------------*/
835 /*----------------------------------------------------------------------------*/
837 (const cpl_frameset * in,
838  double star_ra,
839  double star_dec,
840  int * labels)
841 {
842  int nframes;
843  int idet, iframe;
844 
845  /* Check entries */
846  if (in == NULL) return -1;
847 
848  /* Initialise */
849  nframes = cpl_frameset_get_size(in) ;
850 
851  /* Allocate labels */
852  for (iframe=0 ; iframe<nframes ; iframe++)
853  {
854  const char * filename;
855  filename = cpl_frame_get_filename
856  (cpl_frameset_get_frame_const(in, iframe));
857 
858  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
859  {
860  cpl_propertylist * main_header;
861  cpl_propertylist * ext_header;
862  cpl_wcs * wcs;
863  double naxis1, naxis2;
864  double star_x, star_y;
865 
866  /* Get the headers */
867  main_header = cpl_propertylist_load(filename, 0);
868  ext_header = cpl_propertylist_load
869  (filename, hawki_get_ext_from_detector(filename,idet + 1));
870 
871  /* Get the position of the star in pixels */
872  wcs = cpl_wcs_new_from_propertylist(ext_header);
873  if(wcs == NULL)
874  {
875  cpl_msg_error(__func__, "Could not get WCS info");
876  cpl_propertylist_delete(ext_header);
877  cpl_propertylist_delete(main_header);
878  return -1;
879  }
880  if(irplib_wcs_radectoxy(wcs, star_ra, star_dec, &star_x, &star_y)
881  != CPL_ERROR_NONE)
882  {
883  cpl_errorstate_set(CPL_ERROR_NONE);
884  }
885 
886  /* Check for the limits */
887  naxis1 = (double)hawki_pfits_get_naxis1(ext_header);
888  naxis2 = (double)hawki_pfits_get_naxis2(ext_header);
889  if(star_x > 0 && star_x < naxis1 && star_y > 0 && star_y < naxis2)
890  {
891  labels[iframe] = idet + 1;
892  }
893 
894  /* Free */
895  cpl_propertylist_delete(ext_header);
896  cpl_propertylist_delete(main_header);
897  cpl_wcs_delete(wcs);
898  }
899  if(labels[iframe] == 0)
900  {
901  cpl_msg_error(__func__,"Frame %d does not contain the star in any "
902  "detector", iframe + 1);
903  }
904  }
905  return 0;
906 }
907 
908 /*----------------------------------------------------------------------------*/
916 /*----------------------------------------------------------------------------*/
918 (const cpl_vector * self, const cpl_vector * valid)
919 {
920  double max_val = DBL_MIN;
921  int initialized = 0;
922  int ival;
923  int nvals;
924 
925  nvals = cpl_vector_get_size(self);
926  for(ival = 0; ival < nvals; ++ival)
927  {
928  if(cpl_vector_get(valid, ival) >= -0.5)
929  {
930  if(!initialized)
931  {
932  max_val = cpl_vector_get(self, ival);
933  initialized = 1;
934  }
935  if(cpl_vector_get(self, ival) > max_val)
936  max_val = cpl_vector_get(self, ival);
937  }
938  }
939  return max_val;
940 }
941 
942 /*----------------------------------------------------------------------------*/
950 /*----------------------------------------------------------------------------*/
952 (const cpl_vector * self, const cpl_vector * valid)
953 {
954  double min_val = DBL_MAX;
955  int initialized = 0;
956  int ival;
957  int nvals;
958 
959  nvals = cpl_vector_get_size(self);
960  for(ival = 0; ival < nvals; ++ival)
961  {
962  if(cpl_vector_get(valid, ival) >= -0.5)
963  {
964  if(!initialized)
965  {
966  min_val = cpl_vector_get(self, ival);
967  initialized = 1;
968  }
969  if(cpl_vector_get(self, ival) < min_val)
970  min_val = cpl_vector_get(self, ival);
971  }
972  }
973  return min_val;
974 }
975 
976 /*----------------------------------------------------------------------------*/
982 /*----------------------------------------------------------------------------*/
983 double hawki_vector_get_mode(cpl_vector * vec)
984 {
985  int nb ;
986  int nbins ;
987  double min, max ;
988  double bin_size ;
989  cpl_bivector * hist ;
990  cpl_vector * hist_x ;
991  cpl_vector * hist_y ;
992  double cur_val ;
993  int cur_bin ;
994  double max_val ;
995  int max_bin ;
996  double mode ;
997  int i ;
998 
999  /* Test entries */
1000  if (vec == NULL) return -1.0 ;
1001 
1002  /* Initialise */
1003  nb = cpl_vector_get_size(vec) ;
1004 
1005  /* Create the histogram */
1006  nbins = 10 ;
1007  min = cpl_vector_get_min(vec) ;
1008  max = cpl_vector_get_max(vec) ;
1009  bin_size = (max-min)/nbins ;
1010  hist = cpl_bivector_new(nbins) ;
1011  hist_x = cpl_bivector_get_x(hist) ;
1012  hist_y = cpl_bivector_get_y(hist) ;
1013  cpl_vector_fill(hist_x, 0.0) ;
1014  cpl_vector_fill(hist_y, 0.0) ;
1015  for (i=0 ; i<nbins ; i++) {
1016  cpl_vector_set(hist_x, i, min + i * bin_size) ;
1017  }
1018  for (i=0 ; i<nb ; i++) {
1019  cur_val = cpl_vector_get(vec, i) ;
1020  cur_bin = (int)((cur_val - min) / bin_size) ;
1021  if (cur_bin >= nbins) cur_bin -= 1.0 ;
1022  cur_val = cpl_vector_get(hist_y, cur_bin) ;
1023  cur_val += 1.0 ;
1024  cpl_vector_set(hist_y, cur_bin, cur_val) ;
1025  }
1026 
1027  /* Get the mode of the histogram */
1028  max_val = cpl_vector_get(hist_y, 0) ;
1029  max_bin = 0 ;
1030  for (i=0 ; i<nbins ; i++) {
1031  cur_val = cpl_vector_get(hist_y, i) ;
1032  if (cur_val > max_val) {
1033  max_val = cur_val ;
1034  max_bin = i ;
1035  }
1036  }
1037  mode = cpl_vector_get(hist_x, max_bin) ;
1038  cpl_bivector_delete(hist) ;
1039  return mode ;
1040 }
1041 
1042 /*----------------------------------------------------------------------------*/
1050 /*----------------------------------------------------------------------------*/
1052 (cpl_frameset * frames, double (*func)(const cpl_propertylist *))
1053 {
1054  int iframe;
1055  double value = 0;
1056 
1057  if(cpl_frameset_get_size(frames) < 2)
1058  return 1;
1059 
1060  for(iframe = 0; iframe < cpl_frameset_get_size(frames); ++iframe)
1061  {
1062  cpl_propertylist * header;
1063  header = cpl_propertylist_load(
1064  cpl_frame_get_filename(
1065  cpl_frameset_get_frame_const(frames, iframe)),0);
1066  if(iframe == 0)
1067  value = (func)(header);
1068  else
1069  if(value != (func)(header))
1070  {
1071  cpl_propertylist_delete(header);
1072  return 0;
1073  }
1074  cpl_propertylist_delete(header);
1075  }
1076  return 1;
1077 }
1078 
1079 /*----------------------------------------------------------------------------*/
1087 /*----------------------------------------------------------------------------*/
1089 (cpl_frameset * frames, int (*func)(const cpl_propertylist *))
1090 {
1091  int iframe;
1092  int value = 0;
1093 
1094  if(cpl_frameset_get_size(frames) < 2)
1095  return 1;
1096 
1097  for(iframe = 0; iframe < cpl_frameset_get_size(frames); ++iframe)
1098  {
1099  cpl_propertylist * header;
1100  header = cpl_propertylist_load(
1101  cpl_frame_get_filename(
1102  cpl_frameset_get_frame_const(frames, iframe)),0);
1103  if(iframe == 0)
1104  value = (func)(header);
1105  else
1106  if(value != (func)(header))
1107  {
1108  cpl_propertylist_delete(header);
1109  return 0;
1110  }
1111  cpl_propertylist_delete(header);
1112  }
1113  return 1;
1114 }
1115 
1116 /*----------------------------------------------------------------------------*/
1126 /*----------------------------------------------------------------------------*/
1127 void hawki_utils_ra2str(char * str, int length_str, double ra)
1128 {
1129  double a,b;
1130  double seconds;
1131  char tstring[64];
1132  int hours;
1133  int minutes;
1134  int ltstr;
1135  double dsgn;
1136 
1137  /* Keep RA between 0 and 360 */
1138  if (ra < 0.0 )
1139  {
1140  ra = -ra;
1141  dsgn = -1.0;
1142  }
1143  else
1144  dsgn = 1.0;
1145  ra = fmod(ra, 360.0);
1146  ra *= dsgn;
1147  if (ra < 0.0)
1148  ra = ra + 360.0;
1149 
1150  a = ra / 15.0;
1151 
1152  /* Convert to hours */
1153  hours = (int) a;
1154 
1155  /* Compute minutes */
1156  b = (a - (double)hours) * 60.0;
1157  minutes = (int) b;
1158 
1159  /* Compute seconds */
1160  seconds = (b - (double)minutes) * 60.0;
1161 
1162  if (seconds > 59.99)
1163  {
1164  seconds = 0.0;
1165  minutes = minutes + 1;
1166  }
1167  if (minutes > 59)
1168  {
1169  minutes = 0;
1170  hours = hours + 1;
1171  }
1172  hours = hours % 24;
1173  (void) sprintf (tstring,"%02d:%02d:%05.2f",hours,minutes,seconds);
1174 
1175  /* Move formatted string to returned string */
1176  ltstr = (int) strlen (tstring);
1177  if (ltstr < length_str-1)
1178  strcpy (str, tstring);
1179  else
1180  {
1181  strncpy (str, tstring, length_str-1);
1182  str[length_str-1] = 0;
1183  }
1184  return;
1185 }
1186 
1187 /*----------------------------------------------------------------------------*/
1197 /*----------------------------------------------------------------------------*/
1198 void hawki_utils_dec2str(char * str, int length_str, double dec)
1199 {
1200  double a, b, dsgn, deg1;
1201  double seconds;
1202  char sign;
1203  int degrees;
1204  int minutes;
1205  int ltstr;
1206  char tstring[64];
1207 
1208  /* Keep angle between -180 and 360 degrees */
1209  deg1 = dec;
1210  if (deg1 < 0.0 )
1211  {
1212  deg1 = -deg1;
1213  dsgn = -1.0;
1214  }
1215  else
1216  dsgn = 1.0;
1217  deg1 = fmod(deg1, 360.0);
1218  deg1 *= dsgn;
1219  if (deg1 <= -180.0)
1220  deg1 = deg1 + 360.0;
1221 
1222  a = deg1;
1223 
1224  /* Set sign and do all the rest with a positive */
1225  if (a < 0)
1226  {
1227  sign = '-';
1228  a = -a;
1229  }
1230  else
1231  sign = '+';
1232 
1233  /* Convert to degrees */
1234  degrees = (int) a;
1235 
1236  /* Compute minutes */
1237  b = (a - (double)degrees) * 60.0;
1238  minutes = (int) b;
1239 
1240  /* Compute seconds */
1241  seconds = (b - (double)minutes) * 60.0;
1242 
1243  if (seconds > 59.99)
1244  {
1245  seconds = 0.0;
1246  minutes = minutes + 1;
1247  }
1248  if (minutes > 59)
1249  {
1250  minutes = 0;
1251  degrees = degrees + 1;
1252  }
1253  (void) sprintf (tstring,"%c%02d:%02d:%05.2f",sign,degrees,minutes,seconds);
1254 
1255  /* Move formatted string to returned string */
1256  ltstr = (int) strlen (tstring);
1257  if (ltstr < length_str-1)
1258  strcpy (str, tstring);
1259  else
1260  {
1261  strncpy (str, tstring, length_str-1);
1262  str[length_str-1] = 0;
1263  }
1264  return;
1265 }
1266 
1275 cpl_error_code
1276 hawki_frameset_append(cpl_frameset *self, const cpl_frameset *other)
1277 {
1278  cpl_size iframe;
1279  cpl_size nframes;
1280 
1281  nframes = cpl_frameset_get_size(other);
1282 
1283  for(iframe = 0; iframe<nframes; ++iframe)
1284  {
1285  cpl_frame * newframe;
1286  newframe = cpl_frame_duplicate
1287  (cpl_frameset_get_frame_const(other, iframe));
1288  if(cpl_frameset_insert(self, newframe) != CPL_ERROR_NONE)
1289  {
1290  cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1291  return CPL_ERROR_ILLEGAL_INPUT;
1292  }
1293  }
1294  return CPL_ERROR_NONE;
1295 }
1296