MIDI Pipeline Reference Manual  2.8.3
midi_acq.c
1 /* $Id: midi_acq.c,v 1.23 2011-11-21 09:40:20 agabasch Exp $
2  *
3  * This file is part of the MIDI 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: agabasch $
23  * $Date: 2011-11-21 09:40:20 $
24  * $Revision: 1.23 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <cpl.h>
37 #include <stdio.h>
38 #include "midi_utils.h"
39 #include "midi_pfits.h"
40 #include "midi_dfs.h"
41 #include "midiControl.h"
42 #include "midiGlobal.h"
43 #include "midiAppendPropertylist.h"
44 #include <string.h>
45 #include "midi_cplupgrade.h"
46 
47 /*-----------------------------------------------------------------------------
48  Functions prototypes
49  -----------------------------------------------------------------------------*/
50 
51 static int midi_acq_create(cpl_plugin *) ;
52 static int midi_acq_exec(cpl_plugin *) ;
53 static int midi_acq_destroy(cpl_plugin *) ;
54 static int midi_acq(cpl_parameterlist *, cpl_frameset *) ;
55 static int table_to_imglst(const char * columname,
56  const char * columntype,
57  cpl_imagelist * imglst_target,
58  const char * columnentry,
59  cpl_table * table);
60 static cpl_error_code midi_qc_acq(const cpl_image * image,
61  cpl_propertylist * pro_list);
62 static cpl_error_code midi_image_get_fwhm(
63  const cpl_image * in,
64  int xpos,
65  int ypos,
66  double * fwhm_x,
67  double * fwhm_y);
68 static double midi_vector_get_fwhm(
69  const cpl_vector * vec,
70  int pos,
71  double half_max);
72 static int midi_isnan(double value);
73 
74 
75 /*-----------------------------------------------------------------------------
76  Static variables
77  -----------------------------------------------------------------------------*/
78 
79 static char midi_acq_description[] =
80  "The purpose of this recipe is to assess the position, size and the flux\n"
81  "intensity of the target.\n\n"
82  "Input files:\n\n"
83  " DO category: Type: Explanation: Required:\n"
84  " ACQ Raw Raw data frame Y\n\n"
85  "Output files:\n\n"
86  " DO category: Data type: Explanation:\n"
87  " IMAGE_QUALITY FITS image Image of the beam\n\n";
88 
89 /*-----------------------------------------------------------------------------
90  Functions code
91  -----------------------------------------------------------------------------*/
92 
93 /*----------------------------------------------------------------------------*/
102 /*----------------------------------------------------------------------------*/
103 int cpl_plugin_get_info(cpl_pluginlist * list)
104 {
105  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe ) ;
106  cpl_plugin * plugin = &recipe->interface ;
107 
108  cpl_plugin_init(plugin,
109  CPL_PLUGIN_API,
110  MIDI_BINARY_VERSION,
111  CPL_PLUGIN_TYPE_RECIPE,
112  "midi_acq",
113  "Image quality assessment",
114  midi_acq_description,
115  "Coorosh Sabet",
116  PACKAGE_BUGREPORT,
118  midi_acq_create,
119  midi_acq_exec,
120  midi_acq_destroy) ;
121 
122  cpl_pluginlist_append(list, plugin) ;
123 
124  return 0;
125 }
126 
127 /*----------------------------------------------------------------------------*/
135 /*----------------------------------------------------------------------------*/
136 static int midi_acq_create(cpl_plugin * plugin)
137 {
138  cpl_recipe * recipe ;
139  /* cpl_parameter * p ;*/
140 
141  /* Check that the plugin is part of a valid recipe */
142  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
143  recipe = (cpl_recipe *)plugin ;
144  else return -1 ;
145 
146  /* Create the parameters list in the cpl_recipe object */
147  recipe->parameters = cpl_parameterlist_new() ;
148 
149 
150  /* Return */
151  return 0;
152 }
153 
154 /*----------------------------------------------------------------------------*/
160 /*----------------------------------------------------------------------------*/
161 static int midi_acq_exec(cpl_plugin * plugin)
162 {
163  cpl_recipe * recipe ;
164 
165  /* Get the recipe out of the plugin */
166  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
167  recipe = (cpl_recipe *)plugin ;
168  else return -1 ;
169 
170  batchNumber=0;
171  return midi_acq(recipe->parameters, recipe->frames) ;
172 }
173 
174 /*----------------------------------------------------------------------------*/
180 /*----------------------------------------------------------------------------*/
181 static int midi_acq_destroy(cpl_plugin * plugin)
182 {
183  cpl_recipe * recipe ;
184 
185  /* Get the recipe out of the plugin */
186  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
187  recipe = (cpl_recipe *)plugin ;
188  else return -1 ;
189 
190  cpl_parameterlist_delete(recipe->parameters) ;
191  return 0 ;
192 }
193 
194 /*----------------------------------------------------------------------------*/
201 /*----------------------------------------------------------------------------*/
202 static int midi_acq(
203  cpl_parameterlist *parlist,
204  cpl_frameset *frameset)
205 {
206 
207  cpl_frame * current_frame;
208  int error=0;
209  FILE * sofPtr=NULL;
210  int plotDuration;
211  cpl_propertylist * header=NULL;
212 
213  cpl_frame * cur_frame=NULL;
214  cpl_table * table=NULL;
215  cpl_imagelist * imglst_data1;
216  cpl_imagelist * imglst_data2;
217  cpl_image * image_data1, * image_data2;
218  cpl_image * image_data1_mask, * image_data2_mask;
219  cpl_mask * mask_data1, * mask_data2;
220  cpl_matrix * filter;
221  cpl_errorstate prestate = cpl_errorstate_get();
222  int ext_imaging_data=0;
223  double median_data1, median_data2;
224  cpl_propertylist * qclist_data1=NULL;
225  cpl_propertylist * qclist_data2=NULL;
226  char station[]= "AT";
227  plotDuration=0;
228 
229  current_frame = cpl_frameset_get_first(frameset);
230  sofPtr = fopen ("MIDI_sof.log", "w");
231  while ( current_frame && sofPtr )
232  {
233  fprintf (sofPtr,"%s \n", (char *)cpl_frame_get_filename(current_frame));
234  current_frame = cpl_frameset_get_next( frameset );
235  } /* All frames from frameset */
236  fclose (sofPtr);
237 
238  /* NOW PERFORMING THE DATA REDUCTION */
239  executeDataReduction ("", "","./", plotDuration,"MIDI_sof.log",&error,
240  parlist,frameset);
241  if (error) return -1;
242  remove ("MIDI_sof.log");
243 
244  if (CPL_ERROR_NONE != appendPropertylist("MIDI_b1_acq_DATA1.pro.fits",
245  CPL_FRAME_TYPE_IMAGE, "IMAGE_QUALITY",frameset,parlist))
246  {
247  cpl_msg_error(cpl_func,"Error in appendPropertylist");
248  }
249 
250  if (CPL_ERROR_NONE != appendPropertylist("MIDI_b1_acq_DATA2.pro.fits",
251  CPL_FRAME_TYPE_IMAGE, "IMAGE_QUALITY",frameset,parlist))
252  {
253  cpl_msg_error(cpl_func,"Error in appendPropertylist");
254  }
255 
256 
257  /*------------------------------------------------------------------------*/
258 
259 
260 
261  imglst_data1=cpl_imagelist_new();
262  imglst_data2=cpl_imagelist_new();
263 
264 
265  cur_frame=cpl_frameset_find(frameset,MIDI_ACQ);
266  if (cur_frame == NULL) {
267  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
268  "SOF does not have any file");
269  }
270  /* Append the images from the tables to the imagelists */
271 
272  cpl_msg_info(cpl_func,"Processing file %s",
273  cpl_frame_get_filename(cur_frame));
274 
275  header = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
276 
277 
278  /* Checking if UT or AT */
279  strcpy(station,"AT");
280 
281  if (cpl_propertylist_has(header, "ESO ISS CONF STATION1") == 1)
282  {
283  if(strcmp(cpl_propertylist_get_string(header,
284  "ESO ISS CONF STATION1"),"U1")==0 ||
285  strcmp(cpl_propertylist_get_string(header,
286  "ESO ISS CONF STATION1"),"U2")==0 ||
287  strcmp(cpl_propertylist_get_string(header,
288  "ESO ISS CONF STATION1"),"U3")==0 ||
289  strcmp(cpl_propertylist_get_string(header,
290  "ESO ISS CONF STATION1"),"U4")==0){
291  strcpy(station,"UT");
292  }
293  }
294 
295 
296  /* Load extension Imaging Data */
297  ext_imaging_data=cpl_fits_find_extension(cpl_frame_get_filename(cur_frame),
298  "IMAGING_DATA");
299  table =cpl_table_load(cpl_frame_get_filename(cur_frame),ext_imaging_data,1);
300  if (table == NULL) {
301  cpl_imagelist_delete(imglst_data1);
302  cpl_imagelist_delete(imglst_data2);
303  cpl_propertylist_delete(header);
304  return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
305  "Could not load the table");
306  }
307  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
308 
309  cpl_msg_indent_more();
310  cpl_msg_info(cpl_func,"Reading DATA1 and DATA2 frames into imagelists ...");
311  /* Adding the data1/data2 sky and target images to the imagelist*/
312  if (cpl_table_has_column(table,"DATA1")){
313  table_to_imglst("DATA1","TARTYP1",imglst_data1,"S",table);
314  table_to_imglst("DATA1","TARTYP1",imglst_data1,"T",table);
315  }
316  if (cpl_table_has_column(table,"DATA2")){
317  table_to_imglst("DATA2","TARTYP2",imglst_data2,"S",table);
318  table_to_imglst("DATA2","TARTYP2",imglst_data2,"T",table);
319 
320  }
321 
322  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
323  cpl_msg_info(cpl_func, "Processed DATA1 frames: % " CPL_SIZE_FORMAT "",
324  cpl_imagelist_get_size(imglst_data1));
325  cpl_msg_info(cpl_func, "Processed DATA2 frames: % " CPL_SIZE_FORMAT "",
326  cpl_imagelist_get_size(imglst_data2));
327  cpl_imagelist_save(imglst_data1,"imglst_data1.fits", CPL_BPP_IEEE_FLOAT,
328  NULL, CPL_IO_CREATE);
329  cpl_imagelist_save(imglst_data2,"imglst_data2.fits", CPL_BPP_IEEE_FLOAT,
330  NULL, CPL_IO_CREATE);
331  }
332 
333  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
334  cpl_table_delete(table);
335 
336 
337  /*Average the imagelist to get an cpl_image*/
338  cpl_msg_info(cpl_func, "Averaging the imagelists ...");
339  image_data1=cpl_imagelist_collapse_create(imglst_data1);
340  image_data2=cpl_imagelist_collapse_create(imglst_data2);
341 
342  cpl_msg_info(cpl_func, "Calculating the median ...");
343  median_data1=cpl_image_get_median(image_data1);
344  median_data2=cpl_image_get_median(image_data2);
345  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
346  cpl_msg_info(cpl_func,"First median DATA1: %f DATA12:%f", median_data1,
347  median_data2);
348  }
349 
350 
351  /* Create a bad pixel mask and connect it with the image*/
352  cpl_msg_info(cpl_func, "Creating a mask by using the median ...");
353  mask_data1=cpl_mask_threshold_image_create(image_data1,0., median_data1);
354  cpl_image_reject_from_mask(image_data1, mask_data1) ;
355  mask_data2=cpl_mask_threshold_image_create(image_data2,0., median_data2);
356  cpl_image_reject_from_mask(image_data2, mask_data2) ;
357 
358  /*Threshold the images */
359  cpl_msg_info(cpl_func, "Thresholding the images by using the median ...");
360  cpl_image_threshold(image_data1,median_data1,FLT_MAX,0.,FLT_MAX);
361  cpl_image_threshold(image_data2,median_data2,FLT_MAX,0.,FLT_MAX);
362 
363  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
364  cpl_image_save(image_data1, "image_data1.fits", CPL_BPP_IEEE_FLOAT,
365  NULL, CPL_IO_CREATE);
366  cpl_image_save(image_data2, "image_data2.fits", CPL_BPP_IEEE_FLOAT,
367  NULL, CPL_IO_CREATE);
368  }
369 
370 
371  /* Re Calculate the median deviation using the mask file*/
372 
373  cpl_msg_info(cpl_func, "Re-calculating the median after thresholding ...");
374  median_data1=cpl_image_get_median(image_data1);
375  median_data2=cpl_image_get_median(image_data2);
376 
377  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
378  cpl_msg_info(cpl_func,"Second median DATA1: %f DATA2:%f", median_data1,
379  median_data2);
380  }
381 
382 
383  /* Apply dilatation to decrease the good pixel area */
384  cpl_msg_info(cpl_func, "Dilate the mask ...");
385  filter = cpl_matrix_new(7, 7);
386  cpl_matrix_fill(filter, 1.0);
387  cpl_mask_dilation(mask_data1, filter);
388  cpl_mask_dilation(mask_data2, filter);
389  cpl_matrix_delete(filter);
390 
391  cpl_mask_not(mask_data1);
392  cpl_mask_not(mask_data2);
393 
394  /*convert the mask to a cpl_image*/
395  image_data1_mask=cpl_image_new_from_mask(mask_data1);
396  image_data2_mask=cpl_image_new_from_mask(mask_data2);
397 
398  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
399  cpl_image_save(image_data1_mask, "image_data1_mask.fits",
400  CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_CREATE);
401  cpl_image_save(image_data2_mask, "image_data2_mask.fits",
402  CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_CREATE);
403  }
404 
405 
406 
407 
408  /* multiply mask and image */
409  cpl_msg_info(cpl_func, "Multiply the dilated mask and the image ...");
410  cpl_image_multiply(image_data1,image_data1_mask);
411  cpl_image_multiply(image_data2,image_data2_mask);
412 
413  cpl_msg_indent_less();
414  if (strcmp(station,"AT")==0)
415  {
416 
417  cpl_image_subtract_scalar(image_data1,median_data1);
418  cpl_image_subtract_scalar(image_data2,median_data2);
419 
420  /*Threshold the images */
421  cpl_image_threshold(image_data1, (median_data1*(-1.))+1., FLT_MAX,
422  0., FLT_MAX);
423  cpl_image_threshold(image_data2, (median_data2*(-1.))+1. ,FLT_MAX,
424  0., FLT_MAX);
425 
426  cpl_image_multiply_scalar(image_data1,-1.);
427  cpl_image_multiply_scalar(image_data2,-1.);
428  }
429 
430 
431  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
432  cpl_image_save(image_data1,"image_data1_final.fits", CPL_BPP_IEEE_FLOAT,
433  NULL, CPL_IO_CREATE);
434  cpl_image_save(image_data2,"image_data2_final.fits", CPL_BPP_IEEE_FLOAT,
435  NULL, CPL_IO_CREATE);
436  }
437 
438  qclist_data1=cpl_propertylist_new();
439  qclist_data2=cpl_propertylist_new();
440 
441 
442  /*Derive QC parameters*/
443 
444  prestate = cpl_errorstate_get();
445 
446  midi_qc_acq(image_data1,qclist_data1);
447  midi_qc_acq(image_data2,qclist_data2);
448 
449 
450  if (!cpl_errorstate_is_equal(prestate)) {
451  /*An error happened*/
452  cpl_msg_warning(cpl_func, "An error occurred! ");
453  cpl_msg_indent_more();
454  cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
455  cpl_msg_indent_less();
456  }
457 
458  cpl_msg_warning(cpl_func, "Trying to recover ... ");
459 
460  cpl_errorstate_set(prestate);
461 
462 
463 
464 
465  cpl_propertylist_update_string(qclist_data1, CPL_DFS_PRO_CATG,
466  "MIDI_ACQ_FOV_DATA1");
467  if (cpl_dfs_save_image(frameset, header, parlist, frameset, NULL,
468  image_data1, CPL_BPP_IEEE_FLOAT, "midi_acq", qclist_data1, NULL,
469  PACKAGE "/" PACKAGE_VERSION, "midi_acq_fov_data1.fits")) {
470  /* Propagate the error */
471  (void)cpl_error_set_where(cpl_func);
472  }
473 
474  cpl_propertylist_update_string(qclist_data2, CPL_DFS_PRO_CATG,
475  "MIDI_ACQ_FOV_DATA2");
476  if (cpl_dfs_save_image(frameset, header, parlist, frameset, NULL,
477  image_data2, CPL_BPP_IEEE_FLOAT, "midi_acq", qclist_data2, NULL,
478  PACKAGE "/" PACKAGE_VERSION, "midi_acq_fov_data2.fits")) {
479  /* Propagate the error */
480  (void)cpl_error_set_where(cpl_func);
481  }
482  /*
483  cpl_image_save(image_data1, "armin1_delayline.fits", CPL_BPP_IEEE_FLOAT,
484  qclist_data1, CPL_IO_CREATE);
485  cpl_image_save(image_data2, "armin2_delayline.fits", CPL_BPP_IEEE_FLOAT,
486  qclist_data2, CPL_IO_CREATE);
487  */
488 
489  if (cpl_error_get_code() != CPL_ERROR_NONE) {
490  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
491  cpl_func, __LINE__, cpl_error_get_message());
492 
493  cpl_msg_error(cpl_func,"%s %s",cpl_error_get_message(),
494  cpl_error_get_where());
495  }
496  /* un-connect the mask and free the memory*/
497  cpl_image_accept_all(image_data1) ;
498  cpl_mask_delete(mask_data1);
499  cpl_image_accept_all(image_data2) ;
500  cpl_mask_delete(mask_data2);
501 
502  /* Free the memory */
503 
504  cpl_imagelist_delete(imglst_data1);
505  cpl_imagelist_delete(imglst_data2);
506  cpl_image_delete(image_data1);
507  cpl_image_delete(image_data2);
508  cpl_image_delete(image_data1_mask);
509  cpl_image_delete(image_data2_mask);
510  cpl_propertylist_delete(header);
511  cpl_propertylist_delete(qclist_data1);
512  cpl_propertylist_delete(qclist_data2);
513 
514 
515  /*---------------------------------------------------------------------*/
516 
517 
518 
519  /* Return */
520  if (cpl_error_get_code())
521  return -1 ;
522  else
523  return 0 ;
524 }
525 
526 static int table_to_imglst(const char * columname,
527  const char * columntype,
528  cpl_imagelist * imglst_target,
529  const char * columnentry,
530  cpl_table * table)
531 {
532 
533  int dimenDATA;
534  int i, ctarget=0;
535  cpl_array * array_data=NULL;
536  cpl_image * image_data=NULL;
537  cpl_errorstate prestate = cpl_errorstate_get();
538  char ** target_type;
539  cpl_type ctype;
540 
541  /* Load extension Imaging Data */
542 
543  dimenDATA=cpl_table_get_column_dimensions(table, columname);
544  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
545  if (dimenDATA != 2) {
546  return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
547  "DATA has a wrong dimension");
548  }
549  /* Read target type columnentry and store them in the image list */
550  /* Loop over all "images" stored in DATA and add them to the imagelist */
551 
552  if (cpl_table_has_column(table, columntype))
553  {
554  target_type=cpl_table_get_data_string(table, columntype);
555 
556  }
557  else
558  {
559  return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
560  "TYPE of the Column not found");
561  }
562 
563  ctype=cpl_table_get_column_type(table, columname);
564  /* cpl_msg_info(cpl_func, "Type of the table column: %d",ctype); */
565 
566  ctarget=cpl_imagelist_get_size(imglst_target);
567 
568  for (i=0; i<cpl_table_get_nrow(table);i++)
569  {
570 
571  array_data=(cpl_array *)cpl_table_get_array(table,columname, i);
572  if(ctype&CPL_TYPE_INT){
573  image_data=cpl_image_wrap_int(
574  cpl_table_get_column_dimension(table,columname,0 ),
575  cpl_table_get_column_dimension(table,columname,1 ),
576  cpl_array_get_data_int(array_data) );
577  }
578  if(ctype&CPL_TYPE_FLOAT){
579  image_data=cpl_image_wrap_float(
580  cpl_table_get_column_dimension(table,columname,0 ),
581  cpl_table_get_column_dimension(table,columname,1 ),
582  cpl_array_get_data_float(array_data) );
583  }
584  /* Cast the image to float */
585  /* image_data=cpl_image_cast(image_data, CPL_TYPE_FLOAT); */
586 
587  /* Append the image to the imagelists */
588 
589 
590  if(strcmp(target_type[i],columnentry)== 0){
591  cpl_imagelist_set(imglst_target,
592  cpl_image_cast(image_data, CPL_TYPE_FLOAT),ctarget++);
593  cpl_image_unwrap(image_data);
594  continue;
595  }
596 
597  /*Unwrap processed image manualy if nor Target nor Sky*/
598  if(image_data!=NULL){
599  cpl_image_unwrap(image_data);
600  }
601 
602  }
603 
604  return (int)cpl_error_get_code();
605 }
606 
607 static cpl_error_code midi_qc_acq(const cpl_image * image,
608  cpl_propertylist * pro_list)
609 {
610 
611  cpl_array *parameters = NULL;
612  cpl_array *err_params = NULL;
613  cpl_array *fit_params = NULL;
614  double major=0.0,minor=0.0,angle=0.0,rms=0.0;
615  double centroid_x=0.0, centroid_y=0.0;
616  double centroid_fwhm_x=0.0, centroid_fwhm_y=0.0;
617  double gauss_x=0.0, gauss_y=0.0;
618  double gauss_sigma_x=0.0, gauss_sigma_y=0.0;
619  double gauss_fwhm_x=0.0, gauss_fwhm_y=0.0;
620  double dummy=0.;
621  int i=0;
622 
623 
624 
625  const char *p[7] = { /* Parameter names */
626  "Background ",
627  "Normalisation ",
628  "Correlation ",
629  "Center position x",
630  "Center position y",
631  "Sigma x ",
632  "Sigma y "};
633 
634  parameters = cpl_array_new(7, CPL_TYPE_DOUBLE);
635  err_params = cpl_array_new(7, CPL_TYPE_DOUBLE);
636  fit_params = cpl_array_new(7, CPL_TYPE_INT);
637 
638  /*All parameter should be fitted*/
639  for (i = 0; i < 7; i++)
640  cpl_array_set(fit_params, i, 1);
641 
642 
643  /*Freez the background to a value of zero*/
644  //cpl_array_set(fit_params, 0, 0);
645  //cpl_array_set(parameters, 0,0.);
646 
647  /*Fit a gaussian*/
648  if(cpl_fit_image_gaussian(image, NULL, 30, 30, 20, 20, parameters, NULL,
649  fit_params, &rms, NULL, NULL, &major, &minor, &angle, NULL)
650  == CPL_ERROR_NONE &&
651  !midi_isnan(cpl_array_get(parameters,0,NULL)) &&
652  !midi_isnan(cpl_array_get(parameters,1,NULL)) &&
653  !midi_isnan(cpl_array_get(parameters,2,NULL)) &&
654  !midi_isnan(cpl_array_get(parameters,3,NULL)) &&
655  !midi_isnan(cpl_array_get(parameters,4,NULL)) &&
656  !midi_isnan(cpl_array_get(parameters,5,NULL)) &&
657  !midi_isnan(cpl_array_get(parameters,6,NULL)))
658  {
659 
660 
661  for (i = 0; i < 7; i++){
662  cpl_msg_info(cpl_func,"%s: %f",
663  p[i], cpl_array_get(parameters,i,NULL));
664  }
665 
666  gauss_x=cpl_array_get(parameters,3,NULL);
667  gauss_y=cpl_array_get(parameters,4,NULL);
668  gauss_sigma_x=cpl_array_get(parameters,5,NULL);
669  gauss_sigma_y=cpl_array_get(parameters,6,NULL);
670 
671  /*Get the FWHM at the center of the gaussian fit*/
672  cpl_image_get_fwhm(image, gauss_x, gauss_y, &gauss_fwhm_x,
673  &gauss_fwhm_y);
674 
675  if(gauss_fwhm_x<0){
676  midi_image_get_fwhm(image, gauss_x, gauss_y, &gauss_fwhm_x,
677  &dummy);
678  }
679  if(gauss_fwhm_y<0){
680  midi_image_get_fwhm(image, gauss_x, gauss_y, &dummy, &gauss_fwhm_y);
681 
682  }
683 
684  }
685  /*Get the centroid of the image*/
686  centroid_x=cpl_image_get_centroid_x(image);
687  centroid_y=cpl_image_get_centroid_y(image);
688  /*Get the FWHM at the centroid position*/
689  cpl_image_get_fwhm(image, centroid_x, centroid_y, &centroid_fwhm_x,
690  &centroid_fwhm_y);
691 
692 
693  if(centroid_fwhm_x<0){
694  midi_image_get_fwhm(image, centroid_x, centroid_y, &centroid_fwhm_x,
695  &dummy);
696  }
697  if(centroid_fwhm_y<0){
698  midi_image_get_fwhm(image, centroid_x, centroid_y, &dummy,
699  &centroid_fwhm_y);
700  }
701 
702 
703 
704  cpl_propertylist_update_float(pro_list,
705  "ESO QC GAUSS FIT X", (float)gauss_x);
706  cpl_propertylist_update_float(pro_list,
707  "ESO QC GAUSS FIT Y", (float)gauss_y);
708  cpl_propertylist_update_float(pro_list,
709  "ESO QC GAUSS FIT SIGMA X", (float)gauss_sigma_x);
710  cpl_propertylist_update_float(pro_list,
711  "ESO QC GAUSS FIT SIGMA Y", (float)gauss_sigma_y);
712  cpl_propertylist_update_float(pro_list,
713  "ESO QC GAUSS MEASURED FWHM AT X", (float)gauss_fwhm_x);
714  cpl_propertylist_update_float(pro_list,
715  "ESO QC GAUSS MEASURED FWHM AT Y", (float)gauss_fwhm_y);
716 
717  cpl_propertylist_update_float(pro_list,
718  "ESO QC CENTROID X", (float)centroid_x);
719  cpl_propertylist_update_float(pro_list,
720  "ESO QC CENTROID Y", (float)centroid_y);
721  cpl_propertylist_update_float(pro_list,
722  "ESO QC CENTROID MEASURED FWHM AT X", (float)centroid_fwhm_x);
723  cpl_propertylist_update_float(pro_list,
724  "ESO QC CENTROID MEASURED FWHM AT Y", (float)centroid_fwhm_y);
725 
726  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
727  cpl_msg_info(cpl_func,"centroid_x: %f centroid_y: %f", centroid_x,
728  centroid_y);
729  cpl_msg_info(cpl_func,"centroid_fwhm_x: %f centroid_fwhm_y: %f",
730  centroid_fwhm_x, centroid_fwhm_y);
731  }
732 
733  /*Free the memory*/
734  cpl_array_delete(parameters);
735  cpl_array_delete(err_params);
736  cpl_array_delete(fit_params);
737 
738  return cpl_error_get_code();
739 }
740 
741 /*----------------------------------------------------------------------------*/
769 /*----------------------------------------------------------------------------*/
770 static cpl_error_code midi_image_get_fwhm(
771  const cpl_image * in,
772  int xpos,
773  int ypos,
774  double * fwhm_x,
775  double * fwhm_y)
776 {
777  double half_max;
778  const int minimum_size = 5;
779  int is_rejected;
780 
781 
782  /* Check entries - and initialize *fwhm_{x,y} */
783  if (fwhm_y != NULL) *fwhm_y = -1;
784  cpl_ensure_code(fwhm_x, CPL_ERROR_NULL_INPUT);
785  *fwhm_x = -1;
786  cpl_ensure_code(fwhm_y, CPL_ERROR_NULL_INPUT);
787 
788  /* This call will check the validity of image, xpos and ypos */
789  half_max = 0.5 * cpl_image_get(in, xpos, ypos, &is_rejected);
790 
791  cpl_ensure_code(is_rejected >= 0, cpl_error_get_code());
792  cpl_ensure_code(!is_rejected, CPL_ERROR_DATA_NOT_FOUND);
793 
794  cpl_ensure_code(half_max > 0, CPL_ERROR_DATA_NOT_FOUND);
795 
796  /* FWHM in x */
797  if (cpl_image_get_size_x(in) >= minimum_size) {
798  cpl_errorstate pstate;
799 
800  /* Extract the vector centered on the maximum */
801  cpl_vector * row = cpl_vector_new_from_image_row(in, ypos);
802 
803  /* If an error happened, update its location */
804  cpl_ensure_code(row, cpl_error_get_code());
805 
806  pstate = cpl_errorstate_get();
807 
808 
809  /* Compute the FWHM */
810  if (cpl_errorstate_is_equal(pstate))
811  *fwhm_x = midi_vector_get_fwhm(row, xpos, half_max);
812 
813  cpl_vector_delete(row);
814 
815  /* Propagate the error, if any */
816  cpl_ensure_code(cpl_errorstate_is_equal(pstate), cpl_error_get_code());
817 
818  }
819 
820  /* FWHM in y */
821  if (cpl_image_get_size_y(in)>= minimum_size) {
822  cpl_errorstate pstate;
823 
824  /* Extract the vector centered on the maximum */
825  cpl_vector * col = cpl_vector_new_from_image_column(in, xpos);
826 
827  /* If an error happened, update its location */
828  cpl_ensure_code(col, cpl_error_get_code());
829 
830  pstate = cpl_errorstate_get();
831 
832 
833 
834  /* Compute the FWHM */
835  if (cpl_errorstate_is_equal(pstate))
836  *fwhm_y = midi_vector_get_fwhm(col, ypos, half_max);
837 
838  cpl_vector_delete(col);
839 
840  /* Propagate the error, if any */
841  cpl_ensure_code(cpl_errorstate_is_equal(pstate), cpl_error_get_code());
842  }
843 
844  return CPL_ERROR_NONE;
845 }
846 /*----------------------------------------------------------------------------*/
859 /*----------------------------------------------------------------------------*/
860 static double midi_vector_get_fwhm(
861  const cpl_vector * vec,
862  int pos,
863  double half_max)
864 {
865  const double * vec_data;
866  int nelem;
867  double x_left, x_right;
868  double y_1, y_2;
869  int i;
870 
871  /* Check entries */
872  cpl_ensure(vec, CPL_ERROR_NULL_INPUT, -1.0);
873  nelem = cpl_vector_get_size(vec);
874  cpl_ensure(pos >= 1, CPL_ERROR_ILLEGAL_INPUT, -1.0);
875  cpl_ensure(pos <= nelem, CPL_ERROR_ILLEGAL_INPUT, -1.0);
876 
877  vec_data = cpl_vector_get_data_const(vec);
878 
879  /* Object may be too noisy - or strange in some other way */
880  if (vec_data[pos - 1] <= half_max) return -1.0;
881 
882  /* Find first pair of values, y(i) <= half_max < y(i+1)
883  on the left of the maximum */
884  i = pos - 1;
885 
886  while ((vec_data[i] > half_max) && (i > 0)) i--;
887  if (vec_data[i] > half_max) return -1.0; /* y_1 could not be found */
888 
889  y_1 = vec_data[i];
890  y_2 = vec_data[i+1];
891 
892  /* assert ( y_1 <= half_max && half_max < y_2 ); */
893 
894  /* Assume linearity between y_1 and y_2 */
895  x_left = i + (half_max-y_1) / (y_2-y_1);
896 
897  /* assert( x_left >= i ); */
898 
899  /* Find first pair of values, y(i-1) > half_max >= y(i)
900  on the right of the maximum */
901  i = pos - 1;
902 
903  while ((vec_data[i] > half_max) && (i < nelem-1)) i++;
904  if (vec_data[i] > half_max) return -1.0; /* y_2 could not be found */
905 
906  y_1 = vec_data[i-1];
907  y_2 = vec_data[i];
908 
909  /* assert( y_1 > half_max && half_max >= y_2 ); */
910 
911  /* Assume linearity between y_1 and y_2 */
912  x_right = i + (half_max-y_2) / (y_2-y_1);
913 
914  /* assert( x_right < i ); */
915 
916  if (x_right < x_left || x_right - x_left > FLT_MAX) return -1;
917 
918  return x_right - x_left;
919 }
920 /*----------------------------------------------------------------------------*/
924 /*----------------------------------------------------------------------------*/
925 static int midi_isnan(double value)
926 {
927 #if defined HAVE_ISNAN && HAVE_ISNAN
928  return isnan(value);
929 #else
930  return value != value;
931 #endif
932 }