SINFONI Pipeline Reference Manual  2.5.2
sinfo_new_cubes_build.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 : sinfo_new_cubes_build.c
22  Author : J. Schreiber
23  Created on : December 3, 2003
24  Description : Creates data cubes or merges data cubes
25  out of jittered object-sky
26  nodding observations
27  ---------------------------------------------------------------------------*/
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 /*----------------------------------------------------------------------------
33  Includes
34  ---------------------------------------------------------------------------*/
35 #include "sinfo_new_cubes_build.h"
36 #include "sinfo_pfits.h"
37 #include "sinfo_msg.h"
38 #include "sinfo_pro_save.h"
39 #include "sinfo_objnod_ini_by_cpl.h"
40 #include "sinfo_functions.h"
41 #include "sinfo_hidden.h"
42 #include "sinfo_utilities_scired.h"
43 #include "sinfo_wave_calibration.h"
44 #include "sinfo_cube_construct.h"
45 #include "sinfo_skycor.h"
46 #include "sinfo_product_config.h"
47 #include "sinfo_error.h"
48 #include "sinfo_utils_wrappers.h"
49 #include "sinfo_atmo_disp.h"
50 /*----------------------------------------------------------------------------
51  Defines
52  ---------------------------------------------------------------------------*/
53 #define PI_NUMB (3.1415926535897932384626433832795) /* pi */
54 
55 static void
56 sinfo_atm_correction(cpl_imagelist** ppCube, cpl_frameset* sof,
57  const char* polyshiftname, double dis_cube,
58  double centralLambda_cube, int centralpix_cube);
59 
60 /*----------------------------------------------------------------------------
61  Function Definitions
62  ---------------------------------------------------------------------------*/
63 /* Temporally commented out as not used
64  static cpl_image*
65  sinfo_flux_corr(const cpl_image* inp,const cpl_image* wav,const double dis);
66  */
74 /*----------------------------------------------------------------------------
75  Function : sinfo_new_cubes_build()
76  In : ini_file: file name of according .ini file
77  Out : integer (0 if it worked, -1 if it doesn't)
78  Job : this routine carries through the data cube creation of an
79  object science observation using object-sky nodding
80  and jittering. This script expects jittered frames that
81  were already sky-subtracted
82  averaged, flatfielded, spectral tilt corrected and
83  interleaved if necessary
84  ---------------------------------------------------------------------------*/
85 int
86 sinfo_new_cubes_build(const char* plugin_id, cpl_parameterlist* config,
87  cpl_frameset* sof, const char* procatg,
88  const int frame_index)
89 {
90 
91  object_config * cfg = NULL;
92  cpl_image * im = NULL;
93  cpl_image * wavemapim = NULL;
94  cpl_image * wim = NULL;
95  cpl_image * res_obj = NULL;
96  cpl_image * calim = NULL;
97  cpl_image * halospec = NULL;
98  cpl_image * sky_im = NULL;
99  cpl_image* res_ima = NULL;
100  cpl_image* res_wim = NULL;
101  cpl_image* res_flat = NULL;
102  cpl_image* res_sky = NULL;
103  cpl_image* flat_im = NULL;
104  cpl_image* eima_avg = NULL;
105  cpl_image* eima_med = NULL;
106  cpl_imagelist * cube = NULL;
107  cpl_imagelist * outcube = NULL;
108  cpl_imagelist * outcube2 = NULL;
109  cpl_imagelist* cflat = NULL;
110  cpl_imagelist* cflat2 = NULL;
111  cpl_imagelist* csky = NULL;
112  cpl_imagelist* csky2 = NULL;
113  cpl_propertylist* plist = NULL;
114  cpl_frame* obj_frm = NULL;
115  cpl_frame* sky_frm = NULL;
116  cpl_imagelist* obj_cor = NULL;
117 
118  int sky_cor = 0;
119  int flux_cor = 0;
120  int n = 0;
121  int cpix = 0;
122  float mi = 0;
123  float ma = 0;
124  float fcol = 0;
125  float center_x = 0;
126  float center_y = 0;
127  float * correct_dist = NULL;
128  float * distances = NULL;
129  float ** slit_edges = NULL;
130  int nx = 0;
131  int ny = 0;
132  cpl_image* dif = NULL;
133  float* pd = NULL;
134  float* pw = NULL;
135  int i = 0;
136  int j = 0;
137 
138  double dis = 0;
139  double cwav = 0;
140 
141  char pro_mjit[MAX_NAME_SIZE];
142  char pro_obs[MAX_NAME_SIZE];
143  char pro_med[MAX_NAME_SIZE];
144 
145  char * name = NULL;
146  char file_name[FILE_NAME_SZ];
147 
148  cpl_table* qclog_tbl = NULL;
149  cpl_frameset* stk = NULL;
150  cpl_parameter* p = NULL;
151  int pdensity = 0;
152  sinfo_skycor_qc* sqc = NULL;
153  cpl_table* int_obj = NULL;
154 
155  check_nomsg(p = cpl_parameterlist_find(config, "sinfoni.product.density"));
156  check_nomsg(pdensity = cpl_parameter_get_int(p));
157 
158  if (strcmp(procatg, PRO_COADD_STD) == 0) {
159  strcpy(pro_mjit, PRO_MASK_COADD_STD);
160  strcpy(pro_obs, PRO_OBS_STD);
161  strcpy(pro_med, PRO_MED_COADD_STD);
162 
163  }
164  else if (strcmp(procatg, PRO_COADD_PSF) == 0) {
165  strcpy(pro_mjit, PRO_MASK_COADD_PSF);
166  strcpy(pro_obs, PRO_OBS_PSF);
167  strcpy(pro_med, PRO_MED_COADD_PSF);
168  }
169  else {
170  strcpy(pro_mjit, PRO_MASK_COADD_OBJ);
171  strcpy(pro_obs, PRO_OBS_OBJ);
172  strcpy(pro_med, PRO_MED_COADD_OBJ);
173  }
174 
175  /*----parse input data and parameters to set cube_config cfg---*/
176  check_nomsg(stk = cpl_frameset_new());
177 
178  cknull(cfg = sinfo_parse_cpl_input_objnod(config, sof, &stk),
179  "Error setting parameter configuration");
180 
181  ck0(sinfo_check_input_data(cfg), "error checking input");
182 
183  check_nomsg(p = cpl_parameterlist_find(config, "sinfoni.objnod.fcol"));
184  check_nomsg(fcol = (float )cpl_parameter_get_double(p));
185 
186  for (n = 0; n < cfg->nframes; n++) {
187 
188  sinfo_msg_debug("Read FITS information");
189  name = cfg->framelist[n];
190  if (sinfo_is_fits_file(name) != 1) {
191  sinfo_msg_error("Input file %s is not FITS", name);
192  goto cleanup;
193  }
194 
195  sinfo_msg_debug("frame no.: %d, name: %s\n", n, name);
196  cknull(im = cpl_image_load(name,CPL_TYPE_FLOAT,0,0),
197  " could not load frame %s!",name);
198 
199  /*
200  *--------------------------------------------------------------
201  *---------------------RESAMPLING-------------------------------
202  *--------------------------------------------------------------
203  */
204  sinfo_msg("Resampling object");
205  cknull(wavemapim = cpl_image_load(cfg->wavemap, CPL_TYPE_FLOAT, 0, 0),
206  "could not load wavemap");
207  check_nomsg(wim = cpl_image_duplicate(wavemapim));
208 
209  check_nomsg(
210  p = cpl_parameterlist_find(config,
211  "sinfoni.objnod.flux_cor"));
212  check_nomsg(flux_cor = cpl_parameter_get_bool(p));
213 
214  nx = cpl_image_get_size_x(wim);
215  ny = cpl_image_get_size_y(wim);
216  /*
217  check_nomsg(pd=cpl_image_get_data(im));
218  //To compare statistics we make sure that the input image has all 1s
219 
220  for(i=0;i<nx;i++) {
221  for(j=0;j<ny;j++) {
222  pd[nx*j+i]=1.;
223  }
224  }
225  cpl_image_save(im,"im.fits", CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
226  */
227 
228  cknull(res_ima = sinfo_new_defined_resampling(im,
229  wim,
230  cfg->ncoeffs,
231  &cfg->nrows,
232  &dis,
233  &mi,
234  &ma,
235  &cwav,
236  &cpix),
237  " sinfo_definedResampling() failed" );
238 
239  //cpl_image_save(res_ima,"res_im.fits",
240  //CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
241 
242  //We create an image with the derivatives
243  check_nomsg(dif = cpl_image_new(nx, ny, CPL_TYPE_FLOAT));
244  pw = cpl_image_get_data(wim);
245  pd = cpl_image_get_data(dif);
246 
247  for (i = 1; i < nx - 1; i++) {
248  for (j = 1; j < ny - 1; j++) {
249  if (!isnan(pd[nx*j+i])) {
250  pd[nx * j + i] = 2.0 * dis
251  / (pw[nx * (j + 1) + i]
252  - pw[nx * (j - 1) + i]);
253  }
254  }
255  if (!isnan(pd[i])) {
256  pd[i] = dis / (pw[nx + i] - pw[i]);
257  }
258  if (!isnan(pd[nx*(ny-1)+i])) {
259  pd[nx * (ny - 1) + i] =
260  dis
261  / (pw[nx * (ny - 1) + i]
262  - pw[nx
263  * (ny
264  - 2)
265  + i]);
266  }
267  }
268 
269  //cpl_image_save(dif,"diff.fits",
270  //CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
271 
272  cknull(res_wim = sinfo_new_defined_resampling(dif,
273  wim,
274  cfg->ncoeffs,
275  &cfg->nrows,
276  &dis,
277  &mi,
278  &ma,
279  &cwav,
280  &cpix),
281  " sinfo_definedResampling() failed" );
282 
283  cpl_image_delete(dif);
284  //cpl_image_save(res_wim,"res_diff.fits",
285  //CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
286 
287  //To rescale in flux we divide the resampled image and
288  //the resampled derivatives. At this point res_obj should have same
289  //flux as input image (im.diff)
290 
291  res_obj = cpl_image_duplicate(res_ima);
292  sinfo_free_image(&res_ima);
293  if (flux_cor) {
294  sinfo_msg("Apply flux correction");
295  cpl_image_divide(res_obj, res_wim);
296  }
297  //cpl_image_save(res_obj,"res_obj.fits",
298  //CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
299 
300  sinfo_free_image(&wim);
301 
302  if ((pdensity == 3) || (pdensity == 2 && frame_index == 0)) {
303  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%d%s",
304  RESAMPLED_OUT_OBJ_FILENAME, frame_index, ".fits");
305  ck0(
306  sinfo_pro_save_ima(res_obj,sof,sof,file_name, PRO_RESAMPLED_OBJ, qclog_tbl,plugin_id,config),
307  "cannot save image %s", file_name);
308  }
309 
310  if (strcmp(cfg->sky_dist, "no_sky") != 0) {
311  sinfo_msg("Resampling sky");
312  check_nomsg(
313  sky_im = cpl_image_load(cfg->sky_dist,
314  CPL_TYPE_FLOAT, 0, 0));
315  check_nomsg(wim = cpl_image_duplicate(wavemapim));
316  cknull(
317  res_ima = sinfo_new_defined_resampling(sky_im, wim,
318  cfg->ncoeffs, &cfg->nrows, &dis,
319  &mi, &ma, &cwav, &cpix),
320  " sinfo_definedResampling() failed");
321  res_sky = cpl_image_duplicate(res_ima);
322  sinfo_free_image(&res_ima);
323  if (flux_cor) {
324  sinfo_msg("Apply flux correction");
325  cpl_image_divide(res_sky, res_wim);
326  }
327 
328  sinfo_free_image(&wim);
329  sinfo_free_image(&sky_im);
330  if ((pdensity == 3) || (pdensity == 2 && frame_index == 0)) {
331 
332  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%d%s",
333  RESAMPLED_OUT_SKY_FILENAME, frame_index,
334  ".fits");
335  ck0(
336  sinfo_pro_save_ima(res_sky,sof,sof,file_name, PRO_RESAMPLED_SKY, qclog_tbl,plugin_id,config),
337  "cannot save image %s", file_name);
338  }
339 
340  }
341 
342  if (n == 0) {
343  if (strcmp(cfg->mflat_dist, "not_found") != 0) {
344  sinfo_msg("Resampling master flat");
345  cknull(
346  flat_im = cpl_image_load(cfg->mflat_dist,
347  CPL_TYPE_FLOAT, 0, 0),
348  "Distorted master flat field not found\n"
349  "You may have set --stack-flat_ind=FALSE\n"
350  "Flat field resampling skipped");
351  check_nomsg(wim = cpl_image_duplicate(wavemapim));
352  cknull(res_ima = sinfo_new_defined_resampling(flat_im,
353  wim,
354  cfg->ncoeffs,
355  &cfg->nrows,
356  &dis,
357  &mi,
358  &ma,
359  &cwav,
360  &cpix),
361  " sinfo_definedResampling() failed" );
362 
363  res_flat = cpl_image_duplicate(res_ima);
364  sinfo_free_image(&res_ima);
365  if (flux_cor) {
366  sinfo_msg("Apply flux correction");
367  cpl_image_divide(res_flat, res_wim);
368  }
369  sinfo_free_image(&wim);
370  sinfo_free_image(&flat_im);
371  if ((pdensity == 3) || (pdensity == 2 && frame_index == 0)) {
372  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%d%s",
373  RESAMPLED_OUT_FLAT_FILENAME, frame_index,
374  ".fits");
375  ck0(
376  sinfo_pro_save_ima(res_flat,sof,sof,file_name, PRO_RESAMPLED_FLAT_LAMP, qclog_tbl,plugin_id,config),
377  "cannot save image %s", file_name);
378  }
379 
380  }
381 
382  }
383 
384  sinfo_msg("wmin %f wmax %f wcent %f wstep %f cpix %d", mi, ma, cwav,
385  dis, cpix);
386  sinfo_free_image(&res_wim);
387  sinfo_free_image(&im);
388  sinfo_free_image(&wavemapim);
389 
390  /*
391  *-------------------------------------------------------------------
392  *----------------Calibration----------------------------------------
393  *-------------------------------------------------------------------
394  */
395  /*----Multiply with calibrated halogen lamp spectrum----*/
396  if (cfg->halocorrectInd == 1) {
397  sinfo_msg("Calibration");
398  check_nomsg(halospec = cpl_image_load(cfg->halospectrum,
399  CPL_TYPE_FLOAT,0,0));
400 
401  cknull(calim = sinfo_new_multiply_image_with_spectrum(res_obj,
402  halospec),
403  " sinfo_new_multiply_image_with_spectrum() failed" );
404 
405  sinfo_free_image(&halospec);
406  sinfo_free_image(&res_obj);
407  res_obj = cpl_image_duplicate(calim);
408  sinfo_free_image(&calim);
409  }
410 
411  /*
412  *-------------------------------------------------------------------
413  *------------------CUBECREATION-------------------------------------
414  *-------------------------------------------------------------------
415  */
416  sinfo_msg("Cube creation");
417  /*---select north-south-test or fitting of slitlet edges--*/
418  if (cfg->northsouthInd == 0) {
419  sinfo_msg("cfg->northsouthInd == 0");
420  cknull(
421  slit_edges = sinfo_read_slitlets_edges(cfg->nslits,
422  cfg->poslist),
423  "error reading slitlets edges");
424  }
425  else {
426  sinfo_msg("cfg->northsouthInd != 0");
427  cknull(distances = sinfo_read_distances(cfg->nslits, cfg->distlist),
428  "error reading distances");
429  }
430 
431  cknull(correct_dist = (float*) cpl_calloc(cfg->nslits, sizeof (float)),
432  " could not allocate memory!");
433 
434  sinfo_msg("Create cube object");
435  if (cfg->northsouthInd == 0) {
436 
437  cknull(cube = sinfo_new_make_cube_spi(res_obj,slit_edges,
438  correct_dist),
439  "could not construct data cube!");
440 
441  }
442  else {
443  cknull(cube = sinfo_new_make_cube_dist(res_obj,fcol,distances,
444  correct_dist),
445  "could not construct a data cube!");
446  }
447  sinfo_free_image(&res_obj);
448 
449  if (strcmp(cfg->sky_dist, "no_sky") != 0) {
450 
451  sinfo_msg("Create cube sky");
452  if (cfg->northsouthInd == 0) {
453  cknull(csky = sinfo_new_make_cube_spi(res_sky,slit_edges,
454  correct_dist),
455  "could not construct data cube!");
456  }
457  else {
458  cknull(csky = sinfo_new_make_cube_dist(res_sky,fcol,distances,
459  correct_dist),
460  "could not construct a data cube!");
461  }
462  sinfo_free_image(&res_sky);
463  }
464 
465  if (n == 0) {
466  if (strcmp(cfg->mflat_dist, "not_found") != 0) {
467  sinfo_msg("Create cube master flat");
468  if (cfg->northsouthInd == 0) {
469  cknull(cflat=sinfo_new_make_cube_spi(res_flat,slit_edges,
470  correct_dist),
471  "could not construct data cube!");
472  }
473  else {
474  cknull(cflat = sinfo_new_make_cube_dist(res_flat,fcol,distances,
475  correct_dist),
476  "could not construct a data cube!");
477  }
478  sinfo_free_image(&res_flat);
479  }
480  }
481 
482  if (cfg->northsouthInd == 0) {
483  sinfo_new_destroy_2Dfloatarray(&slit_edges, cfg->nslits);
484  }
485  else {
486  sinfo_new_destroy_array(&distances);
487  }
488 
489  /*
490  *--------------------------------------------------------------------
491  *------------------------FINETUNING----------------------------------
492  *--------------------------------------------------------------------
493  * shift the rows of the reconstructed images of the data cube to the
494  * correct sub pixel position select the shift method: polynomial
495  * interpolation, FFT or cubic spline interpolation
496  *--------------------------------------------------------------------
497  */
498 
499  if (strcmp(cfg->sky_dist, "no_sky") != 0) {
500  if (pdensity > 0) {
501  cknull(csky2=sinfo_new_fine_tune(csky,
502  correct_dist,
503  cfg->method,
504  cfg->order,
505  cfg->nslits),
506  " could not fine tune the data cube");
507 
508  sinfo_free_imagelist(&csky);
509  sinfo_msg("Stretch output cube along Y direction");
510 
511  cknull(csky = sinfo_new_bin_cube(csky2, 1, 2, 0, 63, 0, 63),
512  "error rebinning sky cube");
513  sinfo_free_imagelist(&csky2);
514 
515  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%2.2d%s", "out_sky_cube",
516  frame_index, ".fits");
517  ck0(
518  sinfo_pro_save_ims(csky,sof,sof,file_name, PRO_OBS_SKY,NULL,plugin_id,config),
519  "cannot dump cube %s", file_name);
520  cknull(eima_med = sinfo_new_median_cube(csky),
521  "Creating an average image");
522  check_nomsg(center_x = cpl_image_get_size_x(eima_med) / 2. + 0.5);
523  check_nomsg(center_y = cpl_image_get_size_y(eima_med) / 2. + 0.5);
524 
525  sinfo_new_set_wcs_cube(csky, file_name, cwav, dis, cpix, center_x,
526  center_y);
527 
528  sinfo_free_imagelist(&csky);
529 
530  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%2.2d%s", "out_sky_med",
531  frame_index, ".fits");
532  ck0(
533  sinfo_pro_save_ima(eima_med,sof,sof,file_name, PRO_SKY_MED,NULL,plugin_id,config),
534  "cannot save ima %s", file_name);
535 
536  check_nomsg(
537  sinfo_new_set_wcs_image(eima_med, file_name,
538  center_x, center_y));
539  sinfo_free_image(&eima_med);
540  }
541  }
542 
543  if (n == 0) {
544  if (strcmp(cfg->mflat_dist, "not_found") != 0) {
545  if (pdensity > 1) {
546  cknull(cflat2=sinfo_new_fine_tune(cflat,
547  correct_dist,
548  cfg->method,
549  cfg->order,
550  cfg->nslits),
551  " could not fine tune the data cube");
552 
553  sinfo_free_imagelist(&cflat);
554  sinfo_msg("Stretch output cube along Y direction");
555 
556  cknull(cflat = sinfo_new_bin_cube(cflat2, 1, 2, 0, 63, 0, 63),
557  "Error binning flat cube");
558  sinfo_free_imagelist(&cflat2);
559 
560  ck0(
561  sinfo_pro_save_ims(cflat,sof,sof,OBJNOD_OUT_MFLAT_CUBE_FILENAME, PRO_MFLAT_CUBE,NULL,plugin_id,config),
562  "cannot save cube %s",
563  OBJNOD_OUT_MFLAT_CUBE_FILENAME);
564 
565  sinfo_new_set_wcs_cube(cflat, OBJNOD_OUT_MFLAT_CUBE_FILENAME,
566  cwav, dis, cpix, center_x, center_y);
567 
568  cknull(eima_avg = sinfo_new_average_cube_to_image(cflat),
569  "Creating an average image");
570 
571  ck0(
572  sinfo_pro_save_ima(eima_avg,sof,sof,"out_mflat_avg.fits", "MFLAT_AVG",NULL,plugin_id,config),
573  "cannot save ima %s", "out_mflat_avg.fits");
574 
575  sinfo_free_image(&eima_avg);
576 
577  cknull(eima_med = sinfo_new_median_cube(cflat),
578  "Error computing median on cube flat");
579 
580  ck0(
581  sinfo_pro_save_ima(eima_med,sof,sof,"out_mflat_med.fits", "MFLAT_MED",NULL,plugin_id,config),
582  "cannot save ima %s", "out_mflat_med.fits");
583 
584  sinfo_free_imagelist(&cflat);
585  sinfo_free_image(&eima_med);
586  }
587  }
588  }
589 
590  cknull(outcube2=sinfo_new_fine_tune(cube,
591  correct_dist,
592  cfg->method,
593  cfg->order,
594  cfg->nslits),
595  " could not fine tune the data cube");
596 
597  sinfo_msg("Stretch output cube along Y direction");
598  cknull(outcube = sinfo_new_bin_cube(outcube2, 1, 2, 0, 63, 0, 63),
599  "Error binning cube");
600  sinfo_free_imagelist(&cube);
601  cknull_nomsg(qclog_tbl = sinfo_qclog_init());
602  sinfo_get_pupil_shift(outcube, n, &qclog_tbl);
603  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%2.2d%s", "out_cube_obj",
604  frame_index, ".fits");
605 
606  check_nomsg(center_x = cpl_image_get_size_x(
607  cpl_imagelist_get(outcube,0))/2.+0.5);
608  check_nomsg(
609  center_y = cpl_image_get_size_y(cpl_imagelist_get(outcube, 0))
610  / 2. + 0.5);
611 
612  /*----------- atmospheric correction --------------*/
613  if (cfg->polyshiftname && strlen(cfg->polyshiftname)) {
614  sinfo_atm_correction(&outcube, sof, cfg->polyshiftname, dis, cwav, cpix);
615  }
616  /*-------------------------------------------------*/
617 
618  ck0(
619  sinfo_pro_save_ims(outcube, sof, sof, file_name, pro_obs,
620  qclog_tbl, plugin_id, config),
621  "cannot save cube %s", file_name);
622 
623  sinfo_new_set_wcs_cube(outcube, file_name, cwav, dis, cpix, center_x, center_y);
624  /* free memory */
625  /* to prevent error message comment next line */
626 
627  check_nomsg(p = cpl_parameterlist_find(config, "sinfoni.objnod.sky_cor"));
628 
629  check_nomsg(sky_cor = cpl_parameter_get_bool(p));
630  if (sky_cor == 1 && (pdensity == 1 || pdensity == 3)
631  && strcmp(cfg->sky_dist, "no_sky") != 0) {
632  obj_frm = cpl_frameset_find(sof, pro_obs);
633  sky_frm = cpl_frameset_find(sof, PRO_OBS_SKY);
634  sqc = sinfo_skycor_qc_new();
635  ck0(sinfo_skycor(config, obj_frm, sky_frm, sqc, &obj_cor, &int_obj),
636  "determining sky residuals corrected object");
637  cpl_frameset_erase(sof, pro_obs);
638  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%2.2d%s", "out_cube_obj_cor",
639  frame_index, ".fits");
640  ck0_nomsg(
641  sinfo_qclog_add_int(qclog_tbl, "QC SKYCOR THBKGFIT",
642  sqc->th_fit,
643  "Thermal background fit success", "%d"));
644 
645  ck0(
646  sinfo_pro_save_ims(obj_cor, sof, sof, file_name, pro_obs,
647  qclog_tbl, plugin_id, config),
648  "cannot save cube %s", file_name);
649 
650  sinfo_skycor_qc_delete(&sqc);
651 
652  sinfo_new_set_wcs_cube(obj_cor, file_name, cwav, dis, cpix, center_x,
653  center_y);
654 
655  sinfo_free_imagelist(&obj_cor);
656  snprintf(file_name, MAX_NAME_SIZE - 1, "%s%2.2d%s", "out_int_obj",
657  frame_index, ".fits");
658 
659  ck0(
660  sinfo_pro_save_tbl(int_obj,sof,sof,file_name, PRO_SPECTRA_QC,qclog_tbl,plugin_id,config),
661  "cannot save cube %s", file_name);
662  sinfo_free_table(&int_obj);
663  }
664  sinfo_free_table(&qclog_tbl);
665  sinfo_free_imagelist(&outcube2);
666  sinfo_free_imagelist(&outcube);
667  sinfo_free_float(&correct_dist);
668 
669  } /* end loop over n (nframes) */
670 
671  /* free memory */
672  sinfo_objnod_free(&cfg);
673  sinfo_free_frameset(&stk);
674 
675  return 0;
676 
677  cleanup: sinfo_skycor_qc_delete(&sqc);
678  sinfo_free_imagelist(&obj_cor);
679  sinfo_free_propertylist(&plist);
680  sinfo_free_imagelist(&outcube2);
681  sinfo_free_imagelist(&outcube);
682  sinfo_free_table(&qclog_tbl);
683  sinfo_free_image(&eima_avg);
684  sinfo_free_image(&eima_med);
685  sinfo_free_imagelist(&cflat);
686  sinfo_free_imagelist(&cflat2);
687  sinfo_free_imagelist(&cube);
688  sinfo_free_imagelist(&csky);
689  sinfo_free_imagelist(&csky2);
690 
691  if (cfg != NULL ) {
692  if (cfg->northsouthInd == 0) {
693  if (slit_edges != NULL ) {
694  sinfo_new_destroy_2Dfloatarray(&slit_edges, cfg->nslits);
695  }
696  }
697  else {
698  if (distances != NULL ) {
699  sinfo_new_destroy_array(&distances);
700  }
701  }
702  }
703 
704  sinfo_free_float(&correct_dist);
705  sinfo_free_image(&res_flat);
706  sinfo_free_image(&res_sky);
707  sinfo_free_image(&res_wim);
708  sinfo_free_image(&calim);
709  sinfo_free_image(&halospec);
710  sinfo_free_image(&sky_im);
711  sinfo_free_image(&res_obj);
712  sinfo_free_image(&flat_im);
713  sinfo_free_image(&wavemapim);
714  sinfo_free_image(&wim);
715  sinfo_free_image(&im);
716  sinfo_objnod_free(&cfg);
717  sinfo_free_frameset(&stk);
718 
719  return -1;
720 
721 }
722 
723 static void
724 sinfo_atm_correction(cpl_imagelist** ppCube, cpl_frameset* sof,
725  const char* polyshiftname, double dis_cube,
726  double centralLambda_cube, int centralpix_cube)
727 {
728  cpl_polynomial* poly = NULL;
729  cpl_frame* first_frame = NULL;
730  const char* ref_file = NULL;
731  cpl_propertylist *plist_cube = NULL;
732  cpl_propertylist* ppolylist = NULL;
733  cpl_imagelist* retcube = NULL;
734 
735  /* we use the pointer outcube as a handle to *ppCube
736  (don't initialize to NULL!)*/
737  cpl_imagelist* outcube = *ppCube;
738  /* Get the reference file */
739  first_frame = cpl_frameset_get_first(sof);
740  ref_file = cpl_frame_get_filename(first_frame);
741  if (ref_file && strlen(ref_file)) {
742  /* Get FITS header from reference file */
743  sinfo_msg_warning("adjusting atmospheric correction ref_file[%s]", ref_file);
744  plist_cube = cpl_propertylist_load(ref_file, 0);
745  if (plist_cube) {
746  // check the OPTI1.NAME
747  ppolylist = cpl_propertylist_load(polyshiftname, 0);
748  if (ppolylist) {
749  double pixelscale = sinfo_pfits_get_pixscale(plist_cube);
750  double poly_pixelscale = sinfo_pfits_get_pixscale(ppolylist);
751  if (fabs(poly_pixelscale - pixelscale) < 1E-8) {
752  poly = sinfo_atmo_load_polynom(polyshiftname);
753  if (!poly) {
754  sinfo_msg_warning("Cannot load polynom from [%s]",
755  polyshiftname);
756  }
757  else {
758  sinfo_msg_warning("polynom from [%s] is loaded", polyshiftname);
759  }
760  }
761  else {
762  sinfo_msg_warning("pixelscale for the polynomial fit "
763  "is different: provided[%f] expected[%f]",
764  poly_pixelscale, pixelscale);
765  }
766  sinfo_free_propertylist(&ppolylist);
767  }
768  if (!poly) {
769  sinfo_msg_warning("Pixel shift due atmospheric refraction"
770  " would not be applied");
771  }
772  }
773  else {
774  sinfo_msg_warning("cannot load propertylist for the frame");
775  }
776  if (poly) {
777  double airmass = ((cpl_propertylist_get_double(plist_cube,
778  "ESO TEL AIRM START")
779  + cpl_propertylist_get_double(plist_cube,
780  "ESO TEL AIRM END")) / 2);
781  double angle = ((cpl_propertylist_get_double(plist_cube,
782  "ESO ADA ABSROT START")
783  + cpl_propertylist_get_double(plist_cube,
784  "ESO ADA ABSROT END")) / 2) * PI_NUMB / 180;
785  sinfo_msg("dis_cube[%f] centralLambda_cube[%f] centralpix_cube[%d]",
786  dis_cube, centralLambda_cube, centralpix_cube);
787  retcube = sinfo_atmo_apply_cube_polynomial_shift(poly, outcube,
788  centralLambda_cube, airmass, angle, dis_cube,
789  centralpix_cube);
790  sinfo_free_polynomial(&poly);
791  if (retcube) {
792  sinfo_free_imagelist(&outcube);
793  *ppCube = retcube;
794  }
795  }
796  sinfo_free_propertylist(&plist_cube);
797  }
798 
799  return;
800 }
801 
802 /* Temporally commented out as not yet used
803 static cpl_image*
804 sinfo_flux_corr(const cpl_image* inp, const cpl_image* wav, const double dis)
805 {
806 
807  cpl_image* out = NULL;
808  cpl_image* dif = NULL;
809  const float* pi = NULL;
810  const float* pw = NULL;
811  float* po = NULL;
812  float* pd = NULL;
813 
814  int i = 0;
815  int j = 0;
816  int nx = 0;
817  int ny = 0;
818  int stat = 0;
819  nx = cpl_image_get_size_x(inp);
820  ny = cpl_image_get_size_y(inp);
821 
822  out = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
823  dif = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
824  pi = cpl_image_get_data_const(inp);
825  pw = cpl_image_get_data_const(wav);
826  po = cpl_image_get_data(out);
827  pd = cpl_image_get_data(dif);
828 
829  sinfo_msg("dif=%10.8f",
830  2. * dis
831  / (cpl_image_get(wav, 500, 501, &stat)
832  - cpl_image_get(wav, 500,
833  499, &stat)));
834 
835  sinfo_msg("dif=%10.8f",
836  2. * dis
837  / (cpl_image_get(wav, 500, 101, &stat)
838  - cpl_image_get(wav, 500,
839  99, &stat)));
840 
841  sinfo_msg("dif=%10.8f",
842  2. * dis
843  / (cpl_image_get(wav, 500, 1001, &stat)
844  - cpl_image_get(wav, 500,
845  999, &stat)));
846 
847  for (i = 0; i < nx; i++) {
848  for (j = 1; j < ny - 1; j++) {
849  if (pi[nx * j + i] != ZERO || pw[nx * j + i] != ZERO) {
850  po[nx * j + i] = pi[nx * j + i] * dis
851  / ((pw[nx * (j + 1) + i] - pw[nx * (j - 1) + i])
852  * 0.5);
853  pd[nx * j + i] = dis
854  / ((pw[nx * (j + 1) + i] - pw[nx * (j - 1) + i])
855  * 0.5);
856  }
857  else {
858  po[nx * j + i] = ZERO;
859  pd[nx * j + i] = ZERO;
860  }
861  }
862 
863  if (pi[i] != ZERO || pw[i] != ZERO) {
864  po[i] = pi[i] * dis / (pw[nx + i] - pw[i]);
865  pd[i] = dis / (pw[nx + i] - pw[i]);
866  }
867  else {
868  po[i] = ZERO;
869  pd[i] = ZERO;
870  }
871 
872  if (pi[nx * (ny - 1) + i] != ZERO || pw[nx * (ny - 1) + i] != ZERO) {
873  po[nx * (ny - 1) + i] = pi[nx * (ny - 1) + i] * dis
874  / (pw[nx * (ny - 1) + i] - pw[nx * (ny - 2) + i]);
875  pd[nx * (ny - 1) + i] = dis
876  / (pw[nx * (ny - 1) + i] - pw[nx * (ny - 2) + i]);
877  }
878  else {
879  po[nx * (ny - 1) + i] = ZERO;
880  pd[nx * (ny - 1) + i] = ZERO;
881  }
882 
883  }
884  //cpl_image_save(dif,"diff.fits", CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
885 
886  sinfo_free_image(&dif);
887 
888  return out;
889 
890 }
891 */