SINFONI Pipeline Reference Manual  2.6.0
sinfo_new_nst.c
1 /*
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 /*----------------------------------------------------------------------------
20 
21  File name : spiffi_north_south_test.c
22  Author : A. Modigliani
23  Created on : Sep 17, 2003
24  Description :
25 
26  * nsh.h
27  * Result of a north-south test exposure are 32 continuum spectra of a
28  * pinhole that means one spectrum in each slitlet at the same spatial
29  * position.
30  * Each spectrum is fitted in sp[atial direction by a Gaussian to get the
31  * sub-pixel positions for each row.
32  *
33  * Then the distances are determined in each row and averaged
34  *
35  * Result: are distances of each slitlet from each other => 31 values stored
36  * in an ASCII file this Python script needs a frame of a pinhole source with
37  * a continuous spectrum, that is shifted exactly perpendicular to the
38  * slitlets. It fits the spectra in spatial direction by a Gaussian fit
39  * function and therefore determines the sub-pixel position of the source.
40  *
41  * Then the distances of the slitlets from each other are determined and
42  * saved in an ASCII list.
43  *
44 
45 
46  ---------------------------------------------------------------------------*/
47 
48 #ifdef HAVE_CONFIG_H
49 # include <config.h>
50 #endif
51 /*----------------------------------------------------------------------------
52  Includes
53  ---------------------------------------------------------------------------*/
54 #include "sinfo_new_nst.h"
55 #include "sinfo_pro_save.h"
56 #include "sinfo_pro_types.h"
57 #include "sinfo_functions.h"
58 #include "sinfo_ns_ini_by_cpl.h"
59 #include "sinfo_cube_construct.h"
60 #include "sinfo_utilities.h"
61 #include "sinfo_utils_wrappers.h"
62 #include "sinfo_error.h"
63 #include "sinfo_globals.h"
64 
65 /*----------------------------------------------------------------------------
66  Defines
67  ---------------------------------------------------------------------------*/
68 
76 /*----------------------------------------------------------------------------
77  Function Definitions
78  ---------------------------------------------------------------------------*/
79 
80 /*----------------------------------------------------------------------------
81  Function : north_south_test()
82  In : ini_file: file name of according .ini file
83  Out : integer (0 if it worked, -1 if it doesn't)
84  Job : Result of a north-south test exposure are 32 continuum
85  spectra of a pinhole that means one spectrum in each
86  slitlet at the same spatial position.
87 
88  Each spectrum is fitted in sp[atial direction by a Gaussian
89  to get the sub-pixel positions for each row.
90 
91  Then the distances are determined in each row and averaged
92 
93  Result: are distances of each slitlet from each other =>
94  31 values stored in an ASCII file
95 
96 
97  ---------------------------------------------------------------------------*/
98 int
99 sinfo_new_nst(const char* plugin_id,
100  cpl_parameterlist* config,
101  cpl_frameset* sof,
102  cpl_frameset* ref_set)
103 {
104  ns_config * cfg=NULL ;
105  cpl_imagelist * list_object=NULL ;
106  cpl_imagelist * list_off=NULL;
107  cpl_image * im_on=NULL;
108  cpl_image * im_on_sub=NULL ;
109  cpl_image * im_on_ind=NULL ;
110  cpl_image * im_on_gauss=NULL ;
111  cpl_image * im_mask=NULL ;
112  cpl_image * im_off=NULL ;
113 
114  char* name=NULL;
115  char tbl_name[MAX_NAME_SIZE];
116  int typ=0;
117  int i = 0;
118 
119  int nob =0;
120  int nof =0;
121 
122  float* distances=NULL;
123  cpl_table* tbl_dist=NULL;
124 
125  cpl_vector* qc_dist=NULL;
126 
127  //double qc_dist_mean=0;
128  double qc_dist_stdev=0;
129  cpl_frameset* raw=NULL;
130 
131  cpl_table* qclog_tbl=NULL;
132  char key_value[MAX_NAME_SIZE];
133  char key_name[MAX_NAME_SIZE];
134  int no=0;
135  double lo_cut=0.;
136  double hi_cut=0.;
137  int pdensity=0;
138 
139  /*
140  -----------------------------------------------------------------
141  1) parse the file names and parameters to the ns_config data
142  structure cfg
143  -----------------------------------------------------------------
144  */
145 
146  /*
147  parse the file names and parameters to the ns_config data structure cfg
148  */
149 
150  sinfo_msg("Parse cpl input");
151  check_nomsg(raw=cpl_frameset_new());
152  cknull(cfg = sinfo_parse_cpl_input_ns(config,sof,&raw),
153  "could not parse cpl input!") ;
154 
155  if (cfg->maskInd == 1) {
156  if(sinfo_is_fits_file(cfg->mask) != 1) {
157  sinfo_msg_error("Input file %s is not FITS",cfg->mask);
158  goto cleanup;
159  }
160  }
161  /*
162  --------------------------------------------------------------------
163  stack the frames in data cubes and take the clean mean of all frames
164  --------------------------------------------------------------------
165  */
166  /* allocate memory for lists of object and off-frames */
167  sinfo_msg("stack the frames in data cubes");
168  check(list_object = cpl_imagelist_new(),
169  "could not allocate memory");
170 
171  if (cfg->noff > 0 ) {
172  check(list_off = cpl_imagelist_new(),
173  "could not allocate memory");
174  }
175 
176  /*
177  #build different image lists for the different cases----
178  */
179  sinfo_msg("build different image lists for the different cases");
180  nob = 0;
181  nof = 0;
182 
183  for (i=0; i< cfg->nframes; i++){
184  name = cfg->framelist[i];
185  if(sinfo_is_fits_file(name) != 1) {
186  sinfo_msg_error("Input file %s is not FITS",name);
187  goto cleanup;
188  } else {
189  typ = sinfo_new_intarray_get_value( cfg->frametype, i );
190  if (typ == 1) {
191  cpl_imagelist_set(list_object,
192  cpl_image_load(name,CPL_TYPE_FLOAT,0,0),nob);
193  nob = nob + 1;
194  } else {
195  cpl_imagelist_set(list_off,
196  cpl_image_load(name,CPL_TYPE_FLOAT,0,0),nof);
197  nof = nof + 1;
198  }
199  }
200  }
201 
202  if (cfg->noff != nof || cfg->nobj != nob ){
203  sinfo_msg_error("something wrong with the number of the "
204  "different types of frames");
205  goto cleanup;
206  }
207 
208  /*
209  #---take the average of the different cubes -------------
210  */
211  sinfo_msg("take the average of the different cubes");
212 
213  check_nomsg(no=cpl_imagelist_get_size(list_object));
214  lo_cut=(floor)(cfg->loReject*no+0.5);
215  hi_cut=(floor)(cfg->hiReject*no+0.5);
216  check(im_on=cpl_imagelist_collapse_minmax_create(list_object,lo_cut,hi_cut),
217  "sinfo_average_with_rejection failed" );
218 
219  if (cfg->noff != 0) {
220  /*
221  im_off = sinfo_average_with_rejection( cube_off,
222  cfg->loReject, cfg->hiReject );
223  */
224  check_nomsg(no=cpl_imagelist_get_size(list_off));
225  lo_cut=(floor)(cfg->loReject*no+0.5);
226  hi_cut=(floor)(cfg->hiReject*no+0.5);
227  check(im_off=cpl_imagelist_collapse_minmax_create(list_off,lo_cut,hi_cut),
228  "sinfo_average_with_rejection failed" );
229  sinfo_free_imagelist(&list_off);
230  }
231  sinfo_free_imagelist(&list_object);
232 
233  /*
234  #finally, subtract off from on frames and store the result in the object cube
235  */
236 
237  if (cfg->noff != 0) {
238  sinfo_msg("subtract off from on frames");
239  check(im_on_sub = cpl_image_subtract_create(im_on, im_off),
240  "sinfo_sub_image failed" );
241 
242  sinfo_free_image(&im_on);
243  sinfo_free_image(&im_off);
244  } else {
245  check_nomsg(im_on_sub = cpl_image_duplicate(im_on));
246  sinfo_free_image(&im_on);
247  }
248 
249  /*
250  #---------------------------------------------------------
251  # convolution with Gaussian if recommended
252  #---------------------------------------------------------
253  */
254  if (cfg->gaussInd == 1) {
255  sinfo_msg("convolution with Gaussian");
256  cknull(im_on_gauss = sinfo_new_convolve_ns_image_by_gauss(im_on_sub,
257  cfg->hw),
258  "could not carry out sinfo_convolveNSImageByGauss" );
259 
260  sinfo_free_image(&im_on_sub);
261  check_nomsg(im_on_sub = cpl_image_duplicate(im_on_gauss));
262  sinfo_free_image(&im_on_gauss);
263  }
264 
265  /*
266  #---------------------------------------------------------
267  # static bad pixel indication
268  #---------------------------------------------------------
269  */
270 
271  if (cfg->maskInd == 1) {
272  sinfo_msg("static bad pixel indication");
273  check(im_mask = cpl_image_load(cfg->mask,CPL_TYPE_FLOAT,0,0),
274  "could not load static bad pixel mask" );
275  cknull(im_on_ind = sinfo_new_mult_image_by_mask(im_on_sub, im_mask),
276  "could not carry out sinfo_multImageByMask" );
277  sinfo_free_image(&im_mask);
278  sinfo_free_image(&im_on_sub);
279 
280  } else {
281  check_nomsg(im_on_ind = cpl_image_duplicate(im_on_sub));
282  sinfo_free_image(&im_on_sub);
283  }
284 
285  if(pdensity > 1 && strcmp(plugin_id,"sinfo_rec_distortion")!=0) {
286  ck0(sinfo_pro_save_ima(im_on_ind,ref_set,sof,cfg->fitsname,
287  PRO_MASTER_SLIT,NULL,plugin_id,config),
288  "cannot save ima %s", cfg->fitsname);
289  }
290 
291  /*
292  #---------------------------------------------------------
293  # do the north - south - test
294  #---------------------------------------------------------
295  */
296  sinfo_msg("Do the north - south - test");
297 
298  cknull(distances = sinfo_north_south_test(im_on_ind,
299  cfg->nslits,
300  cfg->halfWidth,
301  cfg->fwhm ,
302  cfg->minDiff,
303  cfg->estimated_dist,
304  cfg->devtol,
305  IMA_PIX_START,
306  IMA_PIX_END ),
307  "North South Test distance determination failed");
308  sinfo_free_image(&im_on_ind);
309  /*
310  sinfo_new_parameter_to_ascii(distances, cfg->nslits - 1, cfg->outName);
311  */
312  check_nomsg(tbl_dist = cpl_table_new(cfg->nslits - 1));
313  check_nomsg(cpl_table_new_column(tbl_dist,"slitlet_distance",
314  CPL_TYPE_FLOAT));
315  check_nomsg(cpl_table_copy_data_float(tbl_dist,"slitlet_distance",
316  distances));
317 
318  strcpy(tbl_name,cfg->outName);
319 
320  check_nomsg(qclog_tbl = cpl_table_new(cfg->nslits + 1));
321  check_nomsg(cpl_table_new_column(qclog_tbl,"key_name", CPL_TYPE_STRING));
322  check_nomsg(cpl_table_new_column(qclog_tbl,"key_type", CPL_TYPE_STRING));
323  check_nomsg(cpl_table_new_column(qclog_tbl,"key_value", CPL_TYPE_STRING));
324  check_nomsg(cpl_table_new_column(qclog_tbl,"key_help", CPL_TYPE_STRING));
325 
326  check_nomsg(qc_dist=cpl_vector_new(cfg->nslits - 1));
327 
328  for(i=0;i<cfg->nslits - 1;i++) {
329  snprintf(key_name,MAX_NAME_SIZE-1,"%s%i","QC SL DIST",i);
330  cpl_table_set_string(qclog_tbl,"key_name",i,key_name);
331  cpl_table_set_string(qclog_tbl,"key_type",i,"CPL_TYPE_DOUBLE");
332  snprintf(key_value,MAX_NAME_SIZE-1,"%g",distances[i]);
333  cpl_table_set_string(qclog_tbl,"key_value",i,key_value);
334  cpl_table_set_string(qclog_tbl,"key_help",i,"Slitlet distance");
335 
336  cpl_vector_set(qc_dist,i,distances[i]);
337  }
338  //check_nomsg(qc_dist_mean=cpl_vector_get_mean(qc_dist));
339  check_nomsg(qc_dist_stdev=cpl_vector_get_stdev(qc_dist));
340 
341  cpl_table_set_string(qclog_tbl,"key_name",cfg->nslits-1,"QC SL DISTAVG");
342  cpl_table_set_string(qclog_tbl,"key_type",cfg->nslits-1,"CPL_TYPE_DOUBLE");
343  snprintf(key_value,MAX_NAME_SIZE-1,"%g",cpl_vector_get_mean(qc_dist));
344  cpl_table_set_string(qclog_tbl,"key_value",cfg->nslits-1,key_value);
345  cpl_table_set_string(qclog_tbl,"key_help",cfg->nslits-1,
346  "Average Slitlet distance");
347 
348  cpl_table_set_string(qclog_tbl,"key_name",cfg->nslits,"QC SL DISTRMS");
349  cpl_table_set_string(qclog_tbl,"key_type",cfg->nslits,"CPL_TYPE_DOUBLE");
350  snprintf(key_value,MAX_NAME_SIZE-1,"%g",qc_dist_stdev);
351  cpl_table_set_string(qclog_tbl,"key_value",cfg->nslits,key_value);
352  cpl_table_set_string(qclog_tbl,"key_help",cfg->nslits,
353  "RMS Slitlet distance");
354 
355  ck0(sinfo_pro_save_tbl(tbl_dist,ref_set,sof,tbl_name,
356  PRO_SLITLETS_DISTANCE,qclog_tbl,plugin_id,config),
357  "cannot dump tbl %s", tbl_name);
358 
359  sinfo_free_my_vector(&qc_dist);
360  sinfo_free_table(&tbl_dist);
361  sinfo_free_table(&qclog_tbl);
362  sinfo_free_float(&distances);
363  sinfo_ns_free (&cfg);
364  sinfo_free_frameset(&raw);
365 
366  return 0;
367 
368  cleanup:
369  sinfo_free_my_vector(&qc_dist);
370  sinfo_free_table(&tbl_dist);
371  sinfo_free_table(&qclog_tbl);
372  sinfo_free_float(&distances);
373  sinfo_free_table(&tbl_dist);
374  sinfo_free_table(&qclog_tbl);
375  sinfo_free_imagelist(&list_object);
376  sinfo_free_imagelist(&list_off);
377  sinfo_free_image(&im_on);
378  sinfo_free_image(&im_mask);
379  sinfo_free_image(&im_on_gauss);
380  sinfo_free_image(&im_on_sub);
381  sinfo_free_image(&im_off);
382  sinfo_free_image(&im_on_ind);
383  sinfo_ns_free (&cfg);
384  sinfo_free_frameset(&raw);
385  return -1;
386 
387 
388 }
389 
#define sinfo_msg_error(...)
Print an error message.
Definition: sinfo_msg.h:69