SINFONI Pipeline Reference Manual  2.5.2
sinfo_skycor.c
1 /* $Id: sinfo_skycor.c,v 1.50 2012-05-04 08:11:35 amodigli Exp $
2  *
3  * This file is part of the SINFONI 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: amodigli $
23  * $Date: 2012-05-04 08:11:35 $
24  * $Revision: 1.50 $
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 #include <math.h>
36 #include <cpl.h>
37 #include <sinfo_cpl_size.h>
38 
39 #include <irplib_utils.h>
40 
41 #include <sinfo_skycor.h>
42 #include <sinfo_new_cube_ops.h>
43 #include "sinfo_pfits.h"
44 #include "sinfo_functions.h"
45 
46 #include "sinfo_msg.h"
47 #include "sinfo_error.h"
48 #include "sinfo_globals.h"
49 #include "sinfo_utils_wrappers.h"
50 #include "sinfo_utl_cube2spectrum.h"
51 #include "sinfo_pro_types.h"
52 /*-----------------------------------------------------------------------------
53  Defines
54  ----------------------------------------------------------------------------*/
55 
56 #define BAND_H_WAVE_MIN 1.445 //not used
57 #define BAND_H_WAVE_MAX 1.820 //not used
58 
59 #define BAND_K_WAVE_MIN 1.945 //not used
60 #define BAND_K_WAVE_MAX 2.460 //not used
61 
62 #define BAND_J_WAVE_MIN 1.445 //not used
63 #define BAND_J_WAVE_MAX 1.82 //not used
64 
65 #define SINFO_FIT_BKG_TEMP 280.
66 #define SKY_THRES 0.95
67 #define SKY_LINE_MAX_CUT 4 /* this should be 4 */
68 #define SKY_LINE_MIN_CUT 4 /* this should be 4 */
69 
70 
71 #define XCOR_YSHIFT_KS_CLIP 5 /* this should be 5 */
72 
73 
74 #define HPLANK 6.62606876e-34; // J s
75 #define CLIGHT 2.99792458e+08; // m / s
76 #define KBOLTZ 1.3806503e-23; // J / K
77 #define AMOEBA_FTOL 1.e-5
78 #define NBOUND 14
79 #define NROT 25
80 #define N_ITER_FIT_LM 15
81 #define N_ITER_FIT_AMOEBA 10
82 
83 double sinfo_scale_fct=1;
84 static cpl_vector* sa_vx=NULL;
85 static cpl_vector* sa_vy=NULL;
86 
87 static cpl_vector* sa_ox=NULL;
88 static cpl_vector* sa_oy=NULL;
89 static cpl_vector* sa_sy=NULL;
90 
91 /*-----------------------------------------------------------------------------
92  Functions prototypes
93 -----------------------------------------------------------------------------*/
94 cpl_vector* sinfo_sky_background_estimate(cpl_vector *spectrum,
95  int msize,
96  int fsize);
97 
98 
99 static int
100 sinfo_scales_obj_sky_cubes(cpl_imagelist* obj_cub,
101  cpl_imagelist* sky_cub,
102  cpl_table* bkg,
103  cpl_table* rscale,
104  cpl_imagelist** obj_cor);
105 
106 static int
107 sinfo_sub_thr_bkg_from_obj_cube(cpl_imagelist* obj_cub,
108  cpl_table* int_sky,
109  cpl_imagelist** obj_cor);
110 
111 static cpl_vector*
112 sinfo_filter_min(const cpl_vector* vi, const int size);
113 
114 static cpl_vector*
115 sinfo_filter_max(const cpl_vector* vi, const int size);
116 
117 static cpl_vector*
118 sinfo_filter_smo(const cpl_vector* vi, const int size);
119 
120 static cpl_imagelist*
121 sinfo_cube_zshift_simple(cpl_imagelist* inp,
122  const float shift);
123 
124 static void
125 sinfo_optimise_sky_sub(const double wtol,
126  const double line_hw,
127  const int method,
128  const int do_rot,
129  cpl_table* lrange,
130  cpl_table* lambda,
131  cpl_table* lr41,
132  cpl_table* lr52,
133  cpl_table* lr63,
134  cpl_table* lr74,
135  cpl_table* lr02,
136  cpl_table* lr85,
137  cpl_table* lr20,
138  cpl_table* lr31,
139  cpl_table* lr42,
140  cpl_table* lr53,
141  cpl_table* lr64,
142  cpl_table* lr75,
143  cpl_table* lr86,
144  cpl_table* lr97,
145  cpl_table* lr00,
146  cpl_table** int_obj,
147  cpl_table** int_sky,
148  cpl_table** rscale);
149 
150 static void
151 sinfo_shift_sky(cpl_frame** sky_frm,
152  cpl_table** int_sky,
153  const double zshift);
154 
155 static double
156 sinfo_xcorr(cpl_table* int_obj,
157  cpl_table* int_sky,
158  cpl_table* lambda,
159  const double dispersion,
160  const double line_hw);
161 
162 static cpl_table*
163 sinfo_interpolate_sky(const cpl_table* inp,const cpl_table* lambdas);
164 
165 static int
166 sinfo_check_screw_values(cpl_table** int_obj,
167  cpl_table** int_sky,
168  cpl_table* grange,
169  const double wtol);
170 
171 static int
172 sinfo_choose_good_sky_pixels(cpl_frame* obj_frm,
173  cpl_image* r_img,
174  cpl_image* g_img,
175  const double min_frac,
176  cpl_image** mask);
177 
178 
179 static int
180 sinfo_sum_spectra(const cpl_frame* obj,
181  const cpl_frame* sky,
182  cpl_image* mask,
183  cpl_table* wrange,
184  const int llx,
185  const int lly,
186  const int urx,
187  const int ury,
188  cpl_table** int_obj,
189  cpl_table** int_sky);
190 
191 int
192 sinfo_thermal_background2(cpl_table* int_sky,
193  cpl_table* lambda,
194  cpl_table* lrange,
195  cpl_table** bkg);
196 
197 static int
198 sinfo_thermal_background(cpl_table* int_sky,
199  cpl_table* lambda,
200  cpl_table* lrange,
201  const double temp,
202  const int niter,
203  const int filter_width,
204  const double wtol,
205  cpl_table** bkg,
206  int* success_fit);
207 
208 static int
209 sinfo_object_flag_sky_pixels(cpl_frame* obj_frm,
210  cpl_table* lambda,
211  cpl_table* mrange,
212  cpl_imagelist* flag_data,
213  const double tol,
214  cpl_image** g_img,
215  cpl_image** r_img,
216  cpl_image** image);
217 
218 static int
219 sinfo_object_flag_low_values(cpl_frame* obj_frm,
220  const double cnt,
221  const double sig,
222  cpl_imagelist** flag_data);
223 
224 static int
225 sinfo_object_estimate_noise(cpl_frame* obj_frm, const int obj_noise_fit,
226  double* centre, double* noise);
227 
228 
229 
230 static int
231 sinfo_set_ranges(cpl_frame* obj_frm,
232  cpl_frame* sky_frm,
233  cpl_parameterlist* cfg,
234  cpl_table** lambda,
235  cpl_table** lr41,
236  cpl_table** lr52,
237  cpl_table** lr63,
238  cpl_table** lr74,
239  cpl_table** lr02,
240  cpl_table** lr85,
241  cpl_table** lr20,
242  cpl_table** lr31,
243  cpl_table** lr42,
244  cpl_table** lr53,
245  cpl_table** lr64,
246  cpl_table** lr75,
247  cpl_table** lr86,
248  cpl_table** lr97,
249  cpl_table** lr00,
250  cpl_table** lrange,
251  cpl_table** grange,
252  cpl_table** lambdas,
253  cpl_table** mrange,
254  int* sky_interp_sw,
255  double* dispersion);
256 
257 
258 static cpl_table*
259 sinfo_table_extract_rest(cpl_table* inp,
260  cpl_table* low,
261  cpl_table* med,
262  const double wtol);
263 
264 static int
265 sinfo_get_sub_regions(cpl_table* sky,
266  cpl_table* x1,
267  cpl_table* pos,
268  const double wtol,
269  const int npixw,
270  cpl_table** sub_regions);
271 
272 
273 static int
274 sinfo_get_obj_sky_wav_sub(cpl_table* obj,
275  cpl_table* sky,
276  cpl_table* wav,
277  cpl_table* sel,
278  const double wtol,
279  cpl_table** sub_obj,
280  cpl_table** sub_sky,
281  cpl_table** sub_wav);
282 
283 
284 static cpl_table*
285 sinfo_find_rot_waves(const double w_rot[],
286  const int npix_w,
287  const double w_step,
288  cpl_table* range);
289 static int
290 sinfo_compute_line_ratio(cpl_table* obj,
291  cpl_table* sky,
292  const double wtol,
293  const int meth,
294  const cpl_table* sel_regions,
295  cpl_table* cont_regions,
296  double* r);
297 
298 static cpl_table*
299 sinfo_table_subtract_continuum(cpl_table* lin,cpl_table* cnt);
300 
301 static double
302 sinfo_fit_bkg(double p[]);
303 
304 static double
305 sinfo_fit_sky(double p[]);
306 
307 static int
308 sinfo_get_line_ratio_amoeba(cpl_table* obj,
309  cpl_table* sky,
310  double* r);
311 
312 static cpl_table*
313 sinfo_table_interpol(cpl_table* obj_lin,
314  cpl_table* obj_cnt,
315  cpl_table* sky_lin,
316  cpl_table* sky_cnt,
317  const double r);
318 
319 
320 static int
321 sinfo_get_line_ratio(cpl_table* obj_lin,
322  cpl_table* obj_cnt,
323  cpl_table* sky_lin,
324  cpl_table* sky_cnt,
325  const int method,
326  double* r);
327 
328 static cpl_table*
329 sinfo_table_shift_simple(cpl_table* inp,
330  const char* col,
331  const double shift);
332 /*
333 static int
334 sinfo_table_set_column_invalid(cpl_table** int_sky,const char* col);
335 */
336 static int
337 sinfo_table_set(cpl_table** out,
338  const cpl_table* ref,
339  const double val,
340  const double tol);
341 
342 static int
343 sinfo_table_threshold(cpl_table** t,
344  const char* column,
345  const double low_cut,
346  const double hig_cut,
347  const double low_ass,
348  const double hig_ass);
349 
350 
351 
352 
353 static double sinfo_fac(const double x, const double t);
354 
355 static int sinfo_fitbkg(const double x[],
356  const double a[],
357  double *result);
358 static int sinfo_fitbkg_derivative(const double x[],
359  const double a[],
360  double result[]);
361 
362 
363 static int
364 sinfo_convolve_kernel(cpl_table** t, const int rad);
365 int
366 sinfo_convolve_kernel2(cpl_table** t, const int rad);
367 
368 int
369 sinfo_convolve_gauss(cpl_table** t, const int rad, const double fwhm);
370 int
371 sinfo_convolve_exp(cpl_table** t, const int rad, const double fwhm);
372 
373 static int
374 sinfo_table_sky_obj_flag_nan(cpl_table** s,cpl_table** o, cpl_table** w);
375 
376 static int
377 sinfo_table_set_nan_out_min_max(cpl_table** s,
378  const char* c,
379  const double min,
380  const double max);
381 
382 
383 
384 
385 static double
386 sinfo_gaussian_amp(double area,double sigma,double x,double x0,double off);
387 static double
388 sinfo_gaussian_area(double amp,double sigma,double x,double x0,double off);
389 
390 int
391 sinfo_table_smooth_column(cpl_table** t, const char* c, const int r);
392 
393 static int
394 sinfo_image_flag_nan(cpl_image** im);
395 
396 static int
397 sinfo_table_flag_nan(cpl_table** t,const char* label);
398 
399 
400 
401 static int
402 sinfo_cnt_mask_thresh_and_obj_finite(const cpl_image* mask,
403  const double t,
404  const cpl_image* obj);
405 
406 
407 
408 
409 static cpl_table*
410 sinfo_interpolate(const cpl_table* inp,
411  const cpl_table* lambdas,
412  const char* name,
413  const char* method);
414 
415 static cpl_table*
416 sinfo_image2table(const cpl_image* im);
417 
418 static int
419 sinfo_table_extract_finite(const cpl_table* in1,
420  const cpl_table* in2,
421  cpl_table** ou1,
422  cpl_table** ou2);
423 
424 static cpl_table*
425 sinfo_slice_z(const cpl_imagelist* cin,const int i,const int j);
426 
427 
428 
429 static cpl_imagelist*
430 sinfo_imagelist_select_range(const cpl_imagelist* inp,
431  const cpl_table* full,
432  const cpl_table* good,
433  const double tol);
434 
435 
436 
437 static cpl_table*
438 sinfo_table_select_range(cpl_table* inp,
439  cpl_table* ref,
440  const double tol);
441 
442 static int
443 sinfo_table_fill_column_over_range(cpl_table** inp,
444  const cpl_table* ref,
445  const char* col,
446  const double val,
447  const double tol);
448 
449 
450 
451 
452 static int
453 sinfo_table_column_dindgen(cpl_table** t, const char* label);
454 
455 
456 
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
467 
469 /*---------------------------------------------------------------------------*/
474 /*---------------------------------------------------------------------------*/
475 
482 sinfo_skycor_qc*
483 sinfo_skycor_qc_new(void)
484  {
485  sinfo_skycor_qc * sqc;
486  sqc= cpl_malloc(sizeof(sinfo_skycor_qc));
487 
488  sqc->th_fit=0;
489 
490  return sqc;
491 
492 }
499 void
500 sinfo_skycor_qc_delete(sinfo_skycor_qc** sqc)
501 {
502  if((*sqc) != NULL) {
503  cpl_free(*sqc);
504  *sqc=NULL;
505  }
506 }
507 
508 
509 
520 /*---------------------------------------------------------------------------*/
521 int
522 sinfo_skycor(cpl_parameterlist * config,
523  cpl_frame* obj_frm,
524  cpl_frame* sky_frm,
525  sinfo_skycor_qc* sqc,
526  cpl_imagelist** obj_cor,
527  cpl_table** int_obj)
528 {
529 
530  cpl_table* bkg=NULL;
531 
532  cpl_table* lambda=NULL;
533  cpl_table* lr41=NULL;
534  cpl_table* lr52=NULL;
535  cpl_table* lr63=NULL;
536  cpl_table* lr74=NULL;
537  cpl_table* lr02=NULL;
538  cpl_table* lr85=NULL;
539  cpl_table* lr20=NULL;
540  cpl_table* lr31=NULL;
541  cpl_table* lr42=NULL;
542  cpl_table* lr53=NULL;
543  cpl_table* lr64=NULL;
544  cpl_table* lr75=NULL;
545  cpl_table* lr86=NULL;
546  cpl_table* lr97=NULL;
547  cpl_table* lr00=NULL;
548  cpl_table* lrange=NULL;
549  cpl_table* mrange=NULL;
550  cpl_table* grange=NULL;
551  cpl_table* lambdas=NULL;
552 
553  cpl_table* int_sky=NULL;
554 
555  cpl_image* mask=NULL;
556  cpl_image* gpix=NULL;
557  cpl_image* ratio=NULL;
558  cpl_image* ima_sky=NULL;
559  cpl_imagelist* fdata=NULL;
560  cpl_table* rscale=NULL;
561  cpl_parameter* p=NULL;
562 
563  int th_fit=0;
564  double dispersion=0;
565  double noise=0;
566  //double temp=252.69284;
567  double centre=0;
568  int sky_interp_sw=0;
569  double wshift=0;
570  double pshift=0;
571  int method=0;
572  int do_rot=0;
573  int obj_noise_fit=0;
574  int niter=3;
575  double min_frac=0.8;
576  double line_hw=7;
577  double fit_temp=280;
578  int filter_width=SINFO_SKY_BKG_FILTER_WIDTH;
579  int llx=0;
580  int lly=0;
581  int urx=64;
582  int ury=64;
583  cpl_imagelist* obj_cub=NULL;
584  cpl_imagelist* sky_cub=NULL;
585  int sub_thr_bkg=0;
586 
587 
588  check_nomsg(p=cpl_parameterlist_find(config,
589  "sinfoni.sinfo_utl_skycor.min_frac"));
590  check_nomsg(min_frac=cpl_parameter_get_double(p));
591 
592  check_nomsg(p=cpl_parameterlist_find(config,
593  "sinfoni.sinfo_utl_skycor.line_half_width"));
594  check_nomsg(line_hw=cpl_parameter_get_double(p));
595 
596 
597 
598  check_nomsg(p=cpl_parameterlist_find(config,
599  "sinfoni.sinfo_utl_skycor.sky_bkg_filter_width"));
600  check_nomsg(filter_width=cpl_parameter_get_int(p));
601 
602  check_nomsg(p=cpl_parameterlist_find(config,
603  "sinfoni.sinfo_utl_skycor.scale_method"));
604  check_nomsg(method=cpl_parameter_get_int(p));
605 
606 
607 
608  check_nomsg(p=cpl_parameterlist_find(config,
609  "sinfoni.sinfo_utl_skycor.rot_cor"));
610  check_nomsg(do_rot=cpl_parameter_get_bool(p));
611 
612 
613  check_nomsg(p=cpl_parameterlist_find(config,
614  "sinfoni.sinfo_utl_skycor.sub_thr_bkg_from_obj"));
615  check_nomsg(sub_thr_bkg=cpl_parameter_get_bool(p));
616 
617 
618  check_nomsg(p=cpl_parameterlist_find(config,
619  "sinfoni.sinfo_utl_skycor.fit_obj_noise"));
620  check_nomsg(obj_noise_fit=cpl_parameter_get_bool(p));
621 
622 
623  check_nomsg(p=cpl_parameterlist_find(config,
624  "sinfoni.sinfo_utl_skycor.niter"));
625  check_nomsg(niter=cpl_parameter_get_int(p));
626 
627 
628  check_nomsg(p=cpl_parameterlist_find(config,
629  "sinfoni.sinfo_utl_skycor.pshift"));
630  check_nomsg(pshift=cpl_parameter_get_double(p));
631 
632 
633 
634  check_nomsg(p=cpl_parameterlist_find(config,
635  "sinfoni.sinfo_utl_skycor.llx"));
636  check_nomsg(llx=cpl_parameter_get_int(p));
637 
638 
639  check_nomsg(p=cpl_parameterlist_find(config,
640  "sinfoni.sinfo_utl_skycor.lly"));
641  check_nomsg(lly=cpl_parameter_get_int(p));
642 
643 
644  check_nomsg(p=cpl_parameterlist_find(config,
645  "sinfoni.sinfo_utl_skycor.urx"));
646  check_nomsg(urx=cpl_parameter_get_int(p));
647 
648 
649  check_nomsg(p=cpl_parameterlist_find(config,
650  "sinfoni.sinfo_utl_skycor.ury"));
651  check_nomsg(ury=cpl_parameter_get_int(p));
652 
653  // set wavelength ranges
654  sinfo_msg("Set wavelength ranges");
655  ck0(sinfo_set_ranges(obj_frm,sky_frm,config,&lambda,
656  &lr41,&lr52,&lr63,&lr74,&lr02,&lr85,&lr20,&lr31,&lr42,
657  &lr53,&lr64,&lr75,&lr86,&lr97,&lr00,
658  &lrange,&grange,&lambdas,&mrange,&sky_interp_sw,
659  &dispersion),"Setting wavelength ranges");
660  //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange.fits",
661  //CPL_IO_DEFAULT));
662 
663  /*
664  sinfo_msg("lr20=%d",cpl_table_get_nrow(lr20));
665  sinfo_msg("lr31=%d",cpl_table_get_nrow(lr31));
666  sinfo_msg("lr42=%d",cpl_table_get_nrow(lr42));
667  sinfo_msg("lr53=%d",cpl_table_get_nrow(lr53));
668  sinfo_msg("lr64=%d",cpl_table_get_nrow(lr64));
669  sinfo_msg("lr75=%d",cpl_table_get_nrow(lr75));
670  sinfo_msg("lr86=%d",cpl_table_get_nrow(lr86));
671  sinfo_msg("lr97=%d",cpl_table_get_nrow(lr97));
672  sinfo_msg("lr00=%d",cpl_table_get_nrow(lr00));
673 
674  sinfo_msg("min_lrange=%f",cpl_table_get_column_min(lrange,"INDEX"));
675  sinfo_msg("min_grange=%f",cpl_table_get_column_min(grange,"INDEX"));
676  sinfo_msg("min_srange=%f",cpl_table_get_column_min(lambdas,"WAVE"));
677  sinfo_msg("min_mrange=%f",cpl_table_get_column_min(mrange,"INDEX"));
678 
679  sinfo_msg("max_lrange=%f",cpl_table_get_column_max(lrange,"INDEX"));
680  sinfo_msg("max_grange=%f",cpl_table_get_column_max(grange,"INDEX"));
681  sinfo_msg("max_srange=%f",cpl_table_get_column_max(lambdas,"WAVE"));
682  sinfo_msg("max_mrange=%f",cpl_table_get_column_max(mrange,"INDEX"));
683  */
684 
685  sinfo_msg("Estimate noise");
686  ck0(sinfo_object_estimate_noise(obj_frm,obj_noise_fit,&centre,&noise),
687  "Estimating noise");
688 
689  sinfo_msg("Background=%f Noise=%f",centre,noise);
690  sinfo_msg("Flag object low_levels");
691  ck0(sinfo_object_flag_low_values(obj_frm,centre,noise,&fdata),
692  "Flagging low pix");
693 
694  //cpl_imagelist_save(fdata,"out_fdata.fits",
695  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
696 
697 
698  sinfo_msg("Flag sky pixels");
699  ck0(sinfo_object_flag_sky_pixels(obj_frm,lambda,mrange,fdata,dispersion,
700  &gpix,&ratio,&ima_sky),
701  "Flagging sky pixels");
702 
703  //cpl_image_save(gpix,"out_gpix.fits",CPL_BPP_IEEE_FLOAT,
704  // NULL,CPL_IO_DEFAULT);
705  //cpl_image_save(ratio,"out_ratio.fits",CPL_BPP_IEEE_FLOAT,
706  // NULL,CPL_IO_DEFAULT);
707  //cpl_image_save(ima_sky,"out_ima_sky.fits",
708  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
709 
710 
711 
712 
713  // choose pixels which seems to be good sky pixels
714  // (95% spectral pixels are flagged)
715  sinfo_msg("Choose good sky (with > 95%% good spectral) pixels");
716  ck0(sinfo_choose_good_sky_pixels(obj_frm,ratio,gpix,min_frac,&mask),
717  "Choosing good sky pixels");
718 
719  //cpl_image_save(mask,"out_mask.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
720 
721  // threshold ratio for fraction 'minfract' of spatial pixels to be 'sky'
722  //sinfo_msg("To do: flag_threshold_sky_pixels");
723 
724 
725  // sum spectra of flagged pixels in object and sky frames
726  sinfo_msg("Sum obj and sky spectra");
727  ck0(sinfo_sum_spectra(obj_frm,sky_frm,mask,lambda,llx,lly,urx,ury,int_obj,
728  &int_sky),"summing obj & sky spectra");
729 
730  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
731  // CPL_IO_DEFAULT));
732  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
733  //CPL_IO_DEFAULT));
734 
735  // Computes thermal background
736  sinfo_msg("Computes thermal background");
737  /*
738  ck0(sinfo_thermal_background2(int_sky,lambda,lrange,&bkg),
739  "getting termal bkg");
740  */
741 
742  ck0(sinfo_thermal_background(int_sky,lambda,lrange,fit_temp,niter,
743  filter_width,dispersion,&bkg,&th_fit),
744  "getting termal bkg");
745 
746 
747  check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_SKY_ORG",int_sky,"INT"));
748  check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_BKG_FIT",bkg,"INT2"));
749  check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_BKG_SMO",int_sky,
750  "INT_BKG_SMO"));
751 
752  sqc->th_fit=th_fit;
753  //check_nomsg(cpl_table_save(bkg,NULL,NULL,"out_thermal_background.fits",
754  //CPL_IO_DEFAULT));
755 
756 
757  /*
758  ck0(sinfo_pro_save_tbl(bkg,set,set,"out_thermal_background.fits",
759  "THERMAL_BACKGROUND",NULL,cpl_func,config),
760  "Error saving %s","THERMAL_BACKGROUND");
761  */
762 
763  sinfo_msg("Subtracts thermal background from integrated OH spectrum");
764  //sinfo_msg("nrow=%d %d",cpl_table_get_nrow(int_sky),
765  // cpl_table_get_nrow(bkg));
766  check_nomsg(cpl_table_duplicate_column(int_sky,"BKG",bkg,"INT2"));
767  check_nomsg(cpl_table_duplicate_column(int_sky,"INT0",int_sky,"INT"));
768  check_nomsg(cpl_table_subtract_columns(int_sky,"INT","BKG"));
769 
770 
771 
772  //check_nomsg(cpl_table_duplicate_column(int_obj,"INT",
773  // int_obj,"INT_OBJ_COR"));
774 
775  if(sub_thr_bkg == 1) {
776  check_nomsg(cpl_table_duplicate_column(*int_obj,"THR_BKG",bkg,"INT2"));
777  check_nomsg(cpl_table_subtract_columns(*int_obj,"INT","THR_BKG"));
778  }
779 
780  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
781  //CPL_IO_DEFAULT));
782  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
783  //CPL_IO_DEFAULT));
784 
785 
786  //check_nomsg(cpl_table_erase_column(int_sky,"BKG"));
787  //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange_6.fits",
788  //CPL_IO_DEFAULT));
789 
790  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_sub.fits",
791  //CPL_IO_DEFAULT));
792 
793 
794 
795  // check for screw values at ends of spectrum
796  sinfo_msg("Checks for screw values at ends of spectrum");
797  sinfo_check_screw_values(int_obj,&int_sky,grange,dispersion);
798  //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange_7.fits",
799  //CPL_IO_DEFAULT));
800  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj_chk.fits",
801  //CPL_IO_DEFAULT));
802  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_chk.fits",
803  //CPL_IO_DEFAULT));
804 
805 
806 
807  if(sky_interp_sw == 1) {
808  sinfo_msg("Interpolate sky if necessary");
809  sinfo_interpolate_sky(int_sky,lambdas);
810  }
811 
812 
813  sinfo_msg("Crosscorrelate obj & sky to check for lambda offset");
814  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj_chk.fits",
815  //CPL_IO_DEFAULT));
816  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_chk.fits",
817  //CPL_IO_DEFAULT));
818  check_nomsg(wshift=sinfo_xcorr(*int_obj,int_sky,lambda,dispersion,line_hw));
819 
820 
821  //wshift=-1.7164495*dispersion;
822  sinfo_msg("Dispersion=%f",dispersion);
823  if(pshift == 0) {
824  pshift=wshift/dispersion;
825  }
826  sinfo_msg("Shift sky of %f pixels toward object",pshift);
827 
828  check_nomsg(sinfo_shift_sky(&sky_frm,&int_sky,pshift));
829  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_pip3_int_obj.fits",
830  //CPL_IO_DEFAULT));
831  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_pip3_int_sky.fits",
832  //CPL_IO_DEFAULT));
833 
834 
835  //DEBUG
836  sinfo_msg("Optimise sky subtraction");
837  check_nomsg(sinfo_optimise_sky_sub(dispersion,line_hw,method,do_rot,
838  lrange,lambda,
839  lr41,lr52,lr63,lr74,lr02,lr85,
840  lr20,lr31,lr42,lr53,lr64,lr75,
841  lr86,lr97,lr00,int_obj,&int_sky,
842  &rscale));
843 
844 
845  //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
846  //CPL_IO_DEFAULT));
847  //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
848  //CPL_IO_DEFAULT));
849 
850 
851  sinfo_msg("Apply same scaling to whole cubes");
852 
853 
854  cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
855  CPL_TYPE_DOUBLE,0));
856  cknull_nomsg(sky_cub=cpl_imagelist_load(cpl_frame_get_filename(sky_frm),
857  CPL_TYPE_DOUBLE,0));
858 
859 
860 
861 
862  if(sub_thr_bkg == 1) {
863  ck0_nomsg(sinfo_sub_thr_bkg_from_obj_cube(obj_cub,int_sky,obj_cor));
864  } else {
865  check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
866  }
867 
868  ck0_nomsg(sinfo_scales_obj_sky_cubes(*obj_cor,sky_cub,bkg,rscale,obj_cor));
869 
870  check_nomsg(cpl_table_name_column(*int_obj,"INT","INT_OBJ_ORG"));
871  check_nomsg(cpl_table_name_column(*int_obj,"INTC","INT_OBJ_COR"));
872  check_nomsg(cpl_table_name_column(*int_obj,"SKYC","INT_SKY_COR"));
873 
874 
875  cleanup:
876  sinfo_free_table(&rscale);
877  sinfo_free_imagelist(&fdata);
878 
879  sinfo_free_table(&bkg);
880  sinfo_free_table(&lambda);
881  sinfo_free_table(&lrange);
882  sinfo_free_table(&mrange);
883  sinfo_free_table(&grange);
884  sinfo_free_table(&lambdas);
885  sinfo_free_image(&mask);
886 
887  sinfo_free_table(&lr41);
888  sinfo_free_table(&lr52);
889  sinfo_free_table(&lr63);
890  sinfo_free_table(&lr74);
891  sinfo_free_table(&lr02);
892  sinfo_free_table(&lr85);
893  sinfo_free_table(&lr20);
894  sinfo_free_table(&lr31);
895  sinfo_free_table(&lr42);
896  sinfo_free_table(&lr53);
897  sinfo_free_table(&lr64);
898  sinfo_free_table(&lr75);
899  sinfo_free_table(&lr86);
900  sinfo_free_table(&lr97);
901  sinfo_free_table(&lr00);
902 
903  sinfo_free_image(&gpix);
904  sinfo_free_image(&ratio);
905  sinfo_free_image(&ima_sky);
906  //sinfo_free_table(&int_obj);
907  sinfo_free_table(&int_sky);
908 
909  sinfo_free_imagelist(&obj_cub);
910  sinfo_free_imagelist(&sky_cub);
911 
912  if (cpl_error_get_code() != CPL_ERROR_NONE) {
913  return -1;
914  } else {
915  return 0;
916  }
917 
918 
919 }
920 
921 /*-------------------------------------------------------------------------*/
933 /*--------------------------------------------------------------------------*/
934 
935 
936 static int
937 sinfo_sub_thr_bkg_from_obj_cube(cpl_imagelist* obj_cub,
938  cpl_table* int_sky,
939  cpl_imagelist** obj_cor)
940 
941 {
942  double* pthr_bkg=NULL;
943  int zsz=0;
944  int k=0;
945  cpl_image* imgo=NULL;
946 
947  check_nomsg(pthr_bkg=cpl_table_get_data_double(int_sky,"BKG"));
948  check_nomsg(zsz=cpl_imagelist_get_size(obj_cub));
949  check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
950 
951  for(k=0;k<zsz;k++) {
952  check_nomsg(imgo=cpl_imagelist_get(obj_cub,k));
953  check_nomsg(cpl_image_subtract_scalar(imgo,pthr_bkg[k]));
954  check_nomsg(cpl_imagelist_set(*obj_cor,imgo,k));
955  }
956 
957  cleanup:
958  if (cpl_error_get_code() != CPL_ERROR_NONE) {
959  return -1;
960  } else {
961  return 0;
962  }
963 
964 }
965 
966 /*-------------------------------------------------------------------------*/
997 /*--------------------------------------------------------------------------*/
998 
999 
1000 int
1001 sinfo_set_ranges(cpl_frame* obj_frm,
1002  cpl_frame* sky_frm,
1003  cpl_parameterlist* cfg,
1004  cpl_table** lambda,
1005  cpl_table** lr41,
1006  cpl_table** lr52,
1007  cpl_table** lr63,
1008  cpl_table** lr74,
1009  cpl_table** lr02,
1010  cpl_table** lr85,
1011  cpl_table** lr20,
1012  cpl_table** lr31,
1013  cpl_table** lr42,
1014  cpl_table** lr53,
1015  cpl_table** lr64,
1016  cpl_table** lr75,
1017  cpl_table** lr86,
1018  cpl_table** lr97,
1019  cpl_table** lr00,
1020  cpl_table** lrange,
1021  cpl_table** grange,
1022  cpl_table** lambdas,
1023  cpl_table** mrange,
1024  int* sky_interp_sw,
1025  double* dispersion)
1026 
1027 {
1028 
1029  cpl_propertylist* plist=NULL;
1030  double crval_obj=0;
1031  double cdelt_obj=0;
1032  double crpix_obj=0;
1033  /*
1034  int xsize_obj=0;
1035  int ysize_obj=0;
1036  */
1037  int zsize_obj=0;
1038 
1039 
1040  double crval_sky=0;
1041  double cdelt_sky=0;
1042  double crpix_sky=0;
1043  /*
1044  int xsize_sky=0;
1045  int ysize_sky=0;
1046  */
1047  int zsize_sky=0;
1048 
1049  int nrow=0;
1050  /* wavelength min-max J-H-K band */
1051  const double w_j_min=1.100;
1052  const double w_j_max=1.400;
1053  const double w_h_min=1.445;
1054  const double w_h_max=1.820;
1055  const double w_k_min=1.945;
1056  const double w_k_max=2.460;
1057 
1058  double ws=0;
1059  double we=0;
1060  double mean=0;
1061 
1062  cpl_parameter* p=NULL;
1063 
1064  /* wavelength boundaries between line groups corresponding
1065  to transitions 5-2 to 9-7 */
1066  double w_bound[NBOUND]={1.067,1.125,1.196,1.252,1.289,
1067  1.400,1.472,1.5543,1.6356,1.7253,
1068  1.840,1.9570,2.095,2.300};
1069 
1070  cpl_table* tmp_tbl=NULL;
1071  cpl_table* add1=NULL;
1072 
1073 
1074 
1075  /* Get Object relevant information */
1076  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
1077  check_nomsg(crval_obj=sinfo_pfits_get_crval3(plist));
1078  check_nomsg(cdelt_obj=sinfo_pfits_get_cdelt3(plist));
1079  check_nomsg(crpix_obj=sinfo_pfits_get_crpix3(plist));
1080  //check_nomsg(xsize_obj=sinfo_pfits_get_naxis1(plist));
1081  //check_nomsg(ysize_obj=sinfo_pfits_get_naxis2(plist));
1082  check_nomsg(zsize_obj=sinfo_pfits_get_naxis3(plist));
1083 
1084  sinfo_free_propertylist(&plist);
1085  *dispersion=cdelt_obj;
1086 
1087  /* defines object related wavelength ranges */
1088  check_nomsg(*lambda=cpl_table_new(zsize_obj));
1089  cpl_table_new_column(*lambda,"WAVE",CPL_TYPE_DOUBLE);
1090  cpl_table_new_column(*lambda,"INDEX",CPL_TYPE_DOUBLE);
1091  check_nomsg(sinfo_table_column_dindgen(lambda,"INDEX"));
1092  check_nomsg(sinfo_table_column_dindgen(lambda,"WAVE"));
1093 
1094  check_nomsg(cpl_table_add_scalar(*lambda,"WAVE",1.));
1095  check_nomsg(cpl_table_subtract_scalar(*lambda,"WAVE",crpix_obj));
1096  check_nomsg(cpl_table_multiply_scalar(*lambda,"WAVE",cdelt_obj));
1097  check_nomsg(cpl_table_add_scalar(*lambda,"WAVE",crval_obj));
1098 
1099 
1100 
1101 
1102  cknull_nomsg(*lr41=sinfo_where_tab_min_max(*lambda,
1103  "WAVE",
1104  CPL_NOT_LESS_THAN,
1105  w_j_min,
1106  CPL_LESS_THAN,
1107  w_bound[0]));
1108 
1109  cknull_nomsg(*lr52=sinfo_where_tab_min_max(*lambda,
1110  "WAVE",
1111  CPL_NOT_LESS_THAN,
1112  w_bound[0],
1113  CPL_LESS_THAN,
1114  w_bound[1]));
1115 
1116  cknull_nomsg(*lr63=sinfo_where_tab_min_max(*lambda,
1117  "WAVE",
1118  CPL_NOT_LESS_THAN,
1119  w_bound[1],
1120  CPL_LESS_THAN,
1121  w_bound[2]));
1122 
1123 
1124  cknull_nomsg(*lr74=sinfo_where_tab_min_max(*lambda,
1125  "WAVE",
1126  CPL_NOT_LESS_THAN,
1127  w_bound[2],
1128  CPL_LESS_THAN,
1129  w_bound[3]));
1130 
1131  cknull_nomsg(*lr20=sinfo_where_tab_min_max(*lambda,
1132  "WAVE",
1133  CPL_NOT_LESS_THAN,
1134  w_bound[3],
1135  CPL_LESS_THAN,
1136  w_bound[4]));
1137 
1138  cknull_nomsg(*lr02=sinfo_where_tab_min_max(*lambda,
1139  "WAVE",
1140  CPL_NOT_LESS_THAN,
1141  w_bound[4],
1142  CPL_LESS_THAN,
1143  w_bound[5]));
1144 
1145 
1146  cknull_nomsg(*lr85=sinfo_where_tab_min_max(*lambda,
1147  "WAVE",
1148  CPL_NOT_LESS_THAN,
1149  w_bound[5],
1150  CPL_LESS_THAN,
1151  w_bound[6]));
1152 
1153  cknull_nomsg(*lr31=sinfo_where_tab_min_max(*lambda,
1154  "WAVE",
1155  CPL_NOT_LESS_THAN,
1156  w_bound[6],
1157  CPL_LESS_THAN,
1158  w_bound[7]));
1159 
1160  cknull_nomsg(*lr42=sinfo_where_tab_min_max(*lambda,
1161  "WAVE",
1162  CPL_NOT_LESS_THAN,
1163  w_bound[7],
1164  CPL_LESS_THAN,
1165  w_bound[8]));
1166 
1167  cknull_nomsg(*lr53=sinfo_where_tab_min_max(*lambda,
1168  "WAVE",
1169  CPL_NOT_LESS_THAN,
1170  w_bound[8],
1171  CPL_LESS_THAN,
1172  w_bound[9]));
1173 
1174  cknull_nomsg(*lr64=sinfo_where_tab_min_max(*lambda,
1175  "WAVE",
1176  CPL_NOT_LESS_THAN,
1177  w_bound[0],
1178  CPL_LESS_THAN,
1179  w_bound[10]));
1180 
1181  cknull_nomsg(*lr75=sinfo_where_tab_min_max(*lambda,
1182  "WAVE",
1183  CPL_NOT_LESS_THAN,
1184  w_bound[10],
1185  CPL_LESS_THAN,
1186  w_bound[11]));
1187 
1188  cknull_nomsg(*lr86=sinfo_where_tab_min_max(*lambda,
1189  "WAVE",
1190  CPL_NOT_LESS_THAN,
1191  w_bound[11],
1192  CPL_LESS_THAN,
1193  w_bound[12]));
1194 
1195  cknull_nomsg(*lr97=sinfo_where_tab_min_max(*lambda,
1196  "WAVE",
1197  CPL_NOT_LESS_THAN,
1198  w_bound[12],
1199  CPL_LESS_THAN,
1200  w_bound[13]));
1201 
1202  cknull_nomsg(*lr00=sinfo_where_tab_min_max(*lambda,
1203  "WAVE",
1204  CPL_NOT_LESS_THAN,
1205  w_bound[13],
1206  CPL_LESS_THAN,
1207  w_k_max));
1208 
1209  /* lrange */
1210  cknull_nomsg(*lrange=sinfo_where_tab_min_max(*lambda,
1211  "WAVE",
1212  CPL_NOT_LESS_THAN,
1213  w_j_min,
1214  CPL_NOT_GREATER_THAN,
1215  w_j_max));
1216 
1217 
1218 
1219  cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
1220  "WAVE",
1221  CPL_NOT_LESS_THAN,
1222  w_h_min,
1223  CPL_NOT_GREATER_THAN,
1224  w_h_max));
1225 
1226  check_nomsg(nrow=cpl_table_get_nrow(*lrange));
1227  check_nomsg(cpl_table_insert(*lrange,add1,nrow));
1228  sinfo_free_table(&add1);
1229 
1230  cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
1231  "WAVE",
1232  CPL_NOT_LESS_THAN,
1233  w_k_min,
1234  CPL_NOT_GREATER_THAN,
1235  w_k_max));
1236 
1237 
1238  check_nomsg(nrow=cpl_table_get_nrow(*lrange));
1239  check_nomsg(cpl_table_insert(*lrange,add1,nrow));
1240  sinfo_free_table(&add1);
1241 
1242 
1243  /* mrange */
1244  cknull_nomsg(*grange=sinfo_where_tab_min_max(*lambda,
1245  "WAVE",
1246  CPL_NOT_LESS_THAN,
1247  1.10,
1248  CPL_NOT_GREATER_THAN,
1249  1.35));
1250 
1251 
1252 
1253 
1254  cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
1255  "WAVE",
1256  CPL_NOT_LESS_THAN,
1257  1.5,
1258  CPL_NOT_GREATER_THAN,
1259  1.7));
1260 
1261  check_nomsg(nrow=cpl_table_get_nrow(*grange));
1262  check_nomsg(cpl_table_insert(*grange,add1,nrow));
1263  sinfo_free_table(&add1);
1264 
1265 
1266 
1267  cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
1268  "WAVE",
1269  CPL_NOT_LESS_THAN,
1270  2.0,
1271  CPL_NOT_GREATER_THAN,
1272  2.3));
1273 
1274  check_nomsg(nrow=cpl_table_get_nrow(*grange));
1275  check_nomsg(cpl_table_insert(*grange,add1,nrow));
1276  sinfo_free_table(&add1);
1277 
1278 
1279  /* Get Sky relevant information */
1280  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(sky_frm),0));
1281  check_nomsg(crval_sky=sinfo_pfits_get_crval3(plist));
1282  check_nomsg(cdelt_sky=sinfo_pfits_get_cdelt3(plist));
1283  check_nomsg(crpix_sky=sinfo_pfits_get_crpix3(plist));
1284  //check_nomsg(xsize_sky=sinfo_pfits_get_naxis1(plist));
1285  //check_nomsg(ysize_sky=sinfo_pfits_get_naxis2(plist));
1286  check_nomsg(zsize_sky=sinfo_pfits_get_naxis3(plist));
1287  sinfo_free_propertylist(&plist);
1288 
1289  /* defines sky related wavelength ranges */
1290  check_nomsg(*lambdas=cpl_table_new(zsize_sky));
1291  cpl_table_new_column(*lambdas,"WAVE",CPL_TYPE_DOUBLE);
1292  check_nomsg(sinfo_table_column_dindgen(lambdas,"WAVE"));
1293 
1294  check_nomsg(cpl_table_add_scalar(*lambdas,"WAVE",1.));
1295  check_nomsg(cpl_table_subtract_scalar(*lambdas,"WAVE",crpix_sky));
1296  check_nomsg(cpl_table_multiply_scalar(*lambdas,"WAVE",cdelt_sky));
1297  check_nomsg(cpl_table_add_scalar(*lambdas,"WAVE",crval_sky));
1298 
1299  check_nomsg(p=cpl_parameterlist_find(cfg,"sinfoni.sinfo_utl_skycor.mask_ws"));
1300  check_nomsg(ws=cpl_parameter_get_double(p));
1301  check_nomsg(p=cpl_parameterlist_find(cfg,"sinfoni.sinfo_utl_skycor.mask_we"));
1302  check_nomsg(we=cpl_parameter_get_double(p));
1303  if((ws != SINFO_MASK_WAVE_MIN) || (we != SINFO_MASK_WAVE_MAX)) {
1304  cknull_nomsg(*mrange=sinfo_where_tab_min_max(*lambda,"WAVE",
1305  CPL_NOT_LESS_THAN,ws,
1306  CPL_NOT_GREATER_THAN,we));
1307  } else {
1308  check_nomsg(*mrange=cpl_table_duplicate(*lrange));
1309  }
1310 
1311 
1312  check_nomsg(cpl_table_duplicate_column(*lambda,"WDIFF",*lambdas,"WAVE"));
1313  check_nomsg(cpl_table_subtract_columns(*lambda,"WDIFF","WAVE"));
1314  check_nomsg(mean=cpl_table_get_column_mean(*lambda,"WDIFF"));
1315  check_nomsg(nrow=cpl_table_get_nrow(*lambda));
1316  sinfo_msg_warning("diff %f",nrow*mean);
1317  if((fabs(nrow*mean) > 0) || (zsize_obj != zsize_sky)) {
1318  sinfo_msg("We have to interpolate sky frame - this is not good");
1319  *sky_interp_sw=1;
1320  }
1321 
1322 
1323  return 0;
1324 
1325  cleanup:
1326  sinfo_free_table(&add1);
1327  sinfo_free_table(&tmp_tbl);
1328  sinfo_free_propertylist(&plist);
1329  return -1;
1330 
1331 }
1332 
1333 /*-------------------------------------------------------------------------*/
1344 /*--------------------------------------------------------------------------*/
1345 
1346 static int
1347 sinfo_table_column_dindgen(cpl_table** t, const char* label)
1348 {
1349 
1350  int sz=0;
1351  int i=0;
1352 
1353  cknull(*t,"Null input vector");
1354  check(sz=cpl_table_get_nrow(*t),"Getting size of a vector");
1355  for(i=0;i<sz;i++) {
1356  cpl_table_set(*t,label,i,(double)i);
1357  }
1358 
1359  return 0;
1360  cleanup:
1361  return -1;
1362 
1363 }
1364 
1365 /*-------------------------------------------------------------------------*/
1376 /*--------------------------------------------------------------------------*/
1377 
1378 
1379 int
1380 sinfo_sum_spectra(const cpl_frame* obj_frm,
1381  const cpl_frame* sky_frm,
1382  cpl_image* mask,
1383  cpl_table* wrange,
1384  const int llx,
1385  const int lly,
1386  const int urx,
1387  const int ury,
1388  cpl_table** int_obj,
1389  cpl_table** int_sky)
1390 {
1391 
1392 
1393 
1394  cpl_image* obj_slice=NULL;
1395  cpl_image* sky_slice=NULL;
1396  cpl_image* gslice=NULL;
1397  cpl_image* pos_tmp=NULL;
1398  cpl_image* msk_tmp=NULL;
1399  cpl_imagelist* obj=NULL;
1400  cpl_imagelist* sky=NULL;
1401 
1402 
1403  cpl_table* loop=NULL;
1404  cpl_table* opos_tbl=NULL;
1405  cpl_table* spos_tbl=NULL;
1406  cpl_table* tmp_tbl=NULL;
1407  cpl_table* loop_tbl=NULL;
1408 
1409  double med=0;
1410  double sdv=0;
1411  double avg=0;
1412 
1413  int zsize=0;
1414  int i=0;
1415  int pos_i=0;
1416 
1417  // sum spectra of flagged spaxels
1418 
1419  cknull_nomsg(obj=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
1420  CPL_TYPE_DOUBLE,0));
1421  cknull_nomsg(sky=cpl_imagelist_load(cpl_frame_get_filename(sky_frm),
1422  CPL_TYPE_DOUBLE,0));
1423 
1424  check_nomsg(zsize=cpl_imagelist_get_size(obj));
1425  check_nomsg(*int_obj = cpl_table_new(zsize));
1426  check_nomsg(*int_sky = cpl_table_new(zsize));
1427  check_nomsg(cpl_table_duplicate_column(*int_obj,"WAVE",wrange,"WAVE"));
1428  check_nomsg(cpl_table_duplicate_column(*int_sky,"WAVE",wrange,"WAVE"));
1429  check_nomsg(cpl_table_new_column(*int_obj,"INT",CPL_TYPE_DOUBLE));
1430  check_nomsg(cpl_table_new_column(*int_sky,"INT",CPL_TYPE_DOUBLE));
1431  check_nomsg(cpl_table_fill_column_window_double(*int_obj,"INT",0,zsize,0));
1432  check_nomsg(cpl_table_fill_column_window_double(*int_sky,"INT",0,zsize,0));
1433 
1434  //loop = where(mask > 0.5);
1435  //TO BE REMOVED: loop_tbl is not used
1436  cknull_nomsg(loop_tbl=sinfo_image2table(mask));
1437  check_nomsg(cpl_table_and_selected_double(loop_tbl,"VALUE",
1438  CPL_GREATER_THAN,0.5));
1439  check_nomsg(loop=cpl_table_extract_selected(loop_tbl));
1440  sinfo_free_table(&loop_tbl);
1441  sinfo_free_table(&loop);
1442 
1443  //Determines object spectrum
1444  for (i=0;i<zsize;i++) {
1445  check_nomsg(obj_slice = cpl_imagelist_get(obj,i));
1446 
1447  //pos = where(mask > 0.5 && finite(obj_slice),pos_i);
1448  pos_i=sinfo_cnt_mask_thresh_and_obj_finite(mask,0.5,obj_slice);
1449  if (pos_i >= 1) {
1450  if ((pos_i) < 3 ) {
1451  //int_obj[i] = mean(obj_slice[pos]);
1452  //TODO here obj_slice should be considered only on pos:
1453  // one should do a selection/thresholding
1454  check_nomsg(cpl_table_set_double(*int_obj,"INT",i,
1455  cpl_image_get_mean_window(obj_slice,
1456  llx,lly,
1457  urx,ury)));
1458  } else {
1459  // select only poisitions where mask>0.5 and obj is finite
1460  // gslice = obj_slice[pos];
1461  //sinfo_msg("obj pos_i=%d",pos_i);
1462 
1463  check_nomsg(gslice = cpl_image_duplicate(obj_slice));
1464  check_nomsg(sinfo_image_flag_nan(&gslice));
1465  /*
1466  sinfo_msg("obj: min=%f max=%f",
1467  cpl_image_get_min(obj_slice),
1468  cpl_image_get_max(obj_slice));
1469  */
1470  //check_nomsg(cpl_image_threshold(gslice,SINFO_DBL_MIN,3.0e6,1,0));
1471  //check_nomsg(cpl_image_multiply(gslice,mask));
1472  if(cpl_image_count_rejected(gslice) < 2048) { //2048=64*64/2
1473 
1474  check_nomsg(med = cpl_image_get_median_window(gslice,llx,lly,urx,ury));
1475  check_nomsg(sdv = cpl_image_get_stdev_window(gslice,llx,lly,urx,ury));
1476  //sinfo_msg("med=%f sdv=%f",med,sdv);
1477  //avg = mean(gslice[where(gslice < med+3*sdv && gslice > med-3*sdv)]);
1478  check_nomsg(cpl_image_threshold(gslice,med-3*sdv,med+3*sdv,0,0));
1479  check_nomsg(avg= cpl_image_get_mean_window(gslice,llx,lly,urx,ury));
1480  check_nomsg(cpl_table_set_double(*int_obj,"INT",i,avg));
1481  } else {
1482  check_nomsg(cpl_table_set_invalid(*int_obj,"INT",i));
1483  }
1484 
1485  sinfo_free_image(&gslice);
1486  //sinfo_msg("sky int=%f",avg);
1487  }
1488  }
1489 
1490  //Determines sky spectrum
1491  check_nomsg(sky_slice = cpl_imagelist_get(sky,i));
1492  //pos = where(mask > 0.5 and finite(sky_slice),pos_i);
1493  pos_i=sinfo_cnt_mask_thresh_and_obj_finite(mask,0.5,sky_slice);
1494  if (pos_i >= 1) {
1495  if ((pos_i) < 3) {
1496  //int_obj[i] = mean(obj_slice[pos]);
1497  //TODO here obj_slice should be considered only on pos:
1498  // one should do a selection/thresholding
1499  check_nomsg(cpl_table_set_double(*int_sky,"INT",i,
1500  cpl_image_get_mean_window(sky_slice,
1501  llx,lly,
1502  urx,ury)));
1503  } else {
1504  //sinfo_msg("pos_i=%d",pos_i);
1505  // select only poisitions where mask>0.5 and obj is finite
1506  // gslice = obj_slice[pos];
1507  check_nomsg(gslice = cpl_image_duplicate(sky_slice));
1508  check_nomsg(sinfo_image_flag_nan(&gslice));
1509  //check_nomsg(cpl_image_threshold(gslice,SINFO_DBL_MIN,3.0e6,1,0));
1510  //check_nomsg(cpl_image_multiply(gslice,mask));
1511  if(cpl_image_count_rejected(gslice) < 2048) { //2048=64*64/2
1512 
1513  check_nomsg(med = cpl_image_get_median_window(gslice,llx,lly,urx,ury));
1514  check_nomsg(sdv = cpl_image_get_stdev_window(gslice,llx,lly,urx,ury));
1515  //avg = mean(gslice[where(gslice < med+3*sdv && gslice > med-3*sdv)]);
1516  check_nomsg(cpl_image_threshold(gslice,med-3*sdv,med+3*sdv,0,0));
1517  check_nomsg(avg= cpl_image_get_mean_window(gslice,llx,lly,urx,ury));
1518  check_nomsg(cpl_table_set_double(*int_sky,"INT",i,avg));
1519  } else {
1520  check_nomsg(cpl_table_set_invalid(*int_sky,"INT",i));
1521  }
1522  sinfo_free_image(&gslice);
1523  /*
1524  if(i<100) {
1525  sinfo_msg("sky: wave=%f int=%f",
1526  cpl_table_get_double(*int_sky,"WAVE",i,&status),avg);
1527 
1528  }
1529  */
1530  }
1531  }
1532  }
1533 
1534  sinfo_free_imagelist(&obj);
1535  sinfo_free_imagelist(&sky);
1536 
1537 
1538  return 0;
1539 
1540  cleanup:
1541  sinfo_free_image(&gslice);
1542  sinfo_free_image(&pos_tmp);
1543  sinfo_free_image(&msk_tmp);
1544  sinfo_free_table(&tmp_tbl);
1545  sinfo_free_table(&opos_tbl);
1546  sinfo_free_table(&spos_tbl);
1547  sinfo_free_table(&loop_tbl);
1548  sinfo_free_table(&loop);
1549  sinfo_free_imagelist(&obj);
1550  sinfo_free_imagelist(&sky);
1551 
1552  return -1;
1553 }
1554 
1555 
1556 
1557 
1558 
1559 /*-------------------------------------------------------------------------*/
1570 /*--------------------------------------------------------------------------*/
1571 
1572 
1573 static int
1574 sinfo_cnt_mask_thresh_and_obj_finite(const cpl_image* mask,
1575  const double t,
1576  const cpl_image* obj)
1577 {
1578 
1579  int cnt=0;
1580  int sxm=0;
1581  int sym=0;
1582  int sxo=0;
1583  int syo=0;
1584  int i=0;
1585  const double* pm=NULL;
1586  const double* po=NULL;
1587 
1588  check_nomsg(sxm=cpl_image_get_size_x(mask));
1589  check_nomsg(sym=cpl_image_get_size_y(mask));
1590  check_nomsg(sxo=cpl_image_get_size_x(obj));
1591  check_nomsg(syo=cpl_image_get_size_y(obj));
1592  if( sxm != sxo || sym != syo) {
1593  goto cleanup;
1594  }
1595  check_nomsg(pm=cpl_image_get_data_double_const(mask));
1596  check_nomsg(po=cpl_image_get_data_double_const(obj));
1597 
1598  for(i=0;i<sxm*sym;i++) {
1599 
1600  if( (pm[i] > t) && (!irplib_isnan(po[i]))) { cnt++; }
1601 
1602  }
1603 
1604  return cnt;
1605  cleanup:
1606  return -1;
1607 
1608 }
1609 
1610 
1611 
1612 
1613 
1614 /*-------------------------------------------------------------------------*/
1625 /*--------------------------------------------------------------------------*/
1626 
1627 
1628 static int
1629 sinfo_image_flag_nan(cpl_image** im)
1630 {
1631 
1632  int cnt=0;
1633  int sx=0;
1634  int sy=0;
1635  int i=0;
1636  int j=0;
1637 
1638  double* pi=NULL;
1639 
1640  check_nomsg(sx=cpl_image_get_size_x(*im));
1641  check_nomsg(sy=cpl_image_get_size_y(*im));
1642  check_nomsg(pi=cpl_image_get_data_double(*im));
1643 
1644  for(j=0;j<sy;j++) {
1645  for(i=0;i<sx;i++) {
1646  if(irplib_isnan(pi[j*sx+i])) {
1647  check_nomsg(cpl_image_reject(*im,i+1,j+1));
1648  cnt++;
1649  }
1650  }
1651  }
1652  //sinfo_msg("No bad pixels: %d",cnt);
1653  return cnt;
1654  cleanup:
1655  return -1;
1656 
1657 }
1658 
1659 
1660 
1661 /*-------------------------------------------------------------------------*/
1673 /*--------------------------------------------------------------------------*/
1674 
1675 int
1676 sinfo_object_estimate_noise(cpl_frame* obj_frm,
1677  const int obj_noise_fit,
1678  double* centre,
1679  double* noise)
1680 {
1681 
1682  const int nbins=HISTO_NBINS;
1683 
1684  int xsz=0;
1685  int ysz=0;
1686  int zsz=0;
1687  int n=0;
1688  int i=0;
1689  int k=0;
1690  int r=0;
1691 
1692  //int max_h=0;
1693  int min_x=0;
1694  int max_x=0;
1695  int status=0;
1696  int max_pos=0;
1697  int min_pos=0;
1698  int min_xi_sz=0;
1699  int ndist=0;
1700 
1701  double avg_d=0;
1702  double std_d=0;
1703  double hmin=0;
1704  double hmax=0;
1705  double kappa=3;
1706 
1707  double* pdata=NULL;
1708  double* disth=NULL;
1709  double* distx=NULL;
1710 
1711  double peak=0;
1712  double tempc=0;
1713  //double value=0;
1714  double thres=0;
1715  double val=0;
1716  double x0=0;
1717  double sigma=0;
1718  double area=0;
1719  double offset=0;
1720  //double mse=0;
1721  //double chired=0;
1722 
1723  cpl_propertylist* plist=NULL;
1724  cpl_imagelist* obj_cub=NULL;
1725  cpl_table* data_tbl=NULL;
1726  cpl_table* histo=NULL;
1727  cpl_image* img=NULL;
1728  cpl_table* dist=NULL;
1729  cpl_table* min_xi=NULL;
1730  cpl_table* tmp_tbl1=NULL;
1731  cpl_table* tmp_tbl2=NULL;
1732  cpl_vector* vx=NULL;
1733  cpl_vector* vy=NULL;
1734  cpl_vector* sx=NULL;
1735  cpl_vector* sy=NULL;
1736  int counter=0;
1737 
1738  // Get Object relevant information
1739  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
1740  check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
1741  check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
1742  check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
1743  sinfo_free_propertylist(&plist);
1744 
1745  cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
1746  CPL_TYPE_DOUBLE,0));
1747 
1748  n=xsz*ysz*zsz;
1749  check_nomsg(data_tbl=cpl_table_new(n));
1750  check_nomsg(cpl_table_new_column(data_tbl,"DATA",CPL_TYPE_DOUBLE));
1751 
1752 
1753  for(k=0;k<zsz;k++) {
1754  check_nomsg(img=cpl_imagelist_get(obj_cub,k));
1755  check_nomsg(pdata=cpl_image_get_data(img));
1756  for(i=0;i<xsz*ysz;i++) {
1757  if(!irplib_isnan(pdata[i])) {
1758  cpl_table_set_double(data_tbl,"DATA",r,pdata[i]);
1759  r++;
1760  }
1761  }
1762  }
1763  sinfo_free_imagelist(&obj_cub);
1764 
1765  check_nomsg(cpl_table_erase_invalid(data_tbl));
1766  check_nomsg(avg_d=cpl_table_get_column_mean(data_tbl,"DATA"));
1767  check_nomsg(std_d=cpl_table_get_column_stdev(data_tbl,"DATA"));
1768 
1769  //cpl_table_save(data_tbl, NULL, NULL, "out_data.fits",CPL_IO_DEFAULT);
1770  hmin=avg_d-kappa*std_d;
1771  hmax=avg_d+kappa*std_d;
1772  //sinfo_msg("mean=%f stdv=%f",avg_d,std_d);
1773  //sinfo_msg("hmin=%f hmax=%f",hmin,hmax);
1774  sinfo_msg("Computes histogram");
1775  ck0(sinfo_histogram(data_tbl,nbins,hmin,hmax,&histo),"building histogram");
1776 
1777  //value=(double)(hmax-hmin)/nbins/2.;
1778  //sinfo_msg("value=%10.8f",value);
1779 
1780 
1781  while(min_xi_sz < HISTO_MIN_SIZE && counter < 10) {
1782  counter++;
1783  //check_nomsg(max_h=cpl_table_get_column_max(histo,"HY"));
1784  //cpl_table_save(histo, NULL, NULL, "out_pippo.fits", CPL_IO_DEFAULT);
1785  check_nomsg(max_pos=sinfo_table_get_index_of_max(histo,"HY",CPL_TYPE_INT));
1786  //sinfo_msg("max_pos=%d",max_pos);
1787 
1788  /*
1789  check_nomsg(max_pos=sinfo_extract_table_rows(histo,"HY",
1790  CPL_EQUAL_TO,max_h));
1791  sinfo_msg("size max_pos %d",cpl_table_get_nrow(max_pos));
1792  sinfo_msg("value max_pos %d",cpl_table_get_int(max_pos,"HY",0,&status));
1793  */
1794  min_x=max_pos-1;
1795  max_x=max_pos+2;
1796  //sinfo_msg("min_x=%d max_x=%d",min_x,max_x);
1797 
1798  sinfo_free_table(&tmp_tbl1);
1799  //sinfo_msg("x selection threshold: %f %d",
1800  // cpl_table_get(histo,"HL",max_pos,&status),max_pos);
1801  check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HL",
1802  CPL_LESS_THAN,
1803  cpl_table_get(histo,"HL",max_pos,&status)));
1804  thres=cpl_table_get_column_max(tmp_tbl1,"HY")/HISTO_Y_CUT;
1805  //sinfo_msg("threshold=%f",thres);
1806 
1807 
1808  sinfo_free_table(&min_xi);
1809  check_nomsg(min_xi=sinfo_extract_table_rows(tmp_tbl1,"HY",
1810  CPL_GREATER_THAN,thres));
1811 
1812  //cpl_table_save(min_xi, NULL, NULL, "out_min_xi.fits", CPL_IO_DEFAULT);
1813 
1814 
1815 
1816  min_xi_sz=cpl_table_get_nrow(min_xi);
1817  val=cpl_table_get(min_xi,"HL",0,&status);
1818 
1819  check_nomsg(min_pos=sinfo_table_get_index_of_val(histo,"HL",val,
1820  CPL_TYPE_DOUBLE));
1821  //sinfo_msg("min_pos=%d max_pos=%d max(h)=%d min_xi_sz=%d x[maxpos[0]]=%f",
1822  // min_pos, max_pos, max_h, min_xi_sz, val);
1823 
1824 
1825 
1826  if (min_xi_sz > 0) {
1827  min_x = min_pos-HISTO_X_LEFT_CUT*(max_pos-min_pos);
1828  max_x = max_pos+HISTO_X_RIGHT_CUT*(max_pos-min_pos);
1829  }
1830 
1831  //sinfo_msg("min_x=%d max_x=%d",min_x,max_x);
1832  check_nomsg(hmin=sinfo_table_column_interpolate(histo,"HL",min_x));
1833  check_nomsg(hmax=sinfo_table_column_interpolate(histo,"HL",max_x));
1834  //sinfo_msg("hmin=%f hmax=%f min_xi_sz=%d",hmin,hmax,min_xi_sz);
1835  //cpl_table_save(histo, NULL, NULL, "out_histo.fits", CPL_IO_DEFAULT);
1836  sinfo_free_table(&histo);
1837  ck0(sinfo_histogram(data_tbl,nbins,hmin,hmax,&histo),"building histogram");
1838  //cpl_table_save(histo, NULL, NULL, "out_histo1.fits", CPL_IO_DEFAULT);
1839  check_nomsg(cpl_table_add_scalar(histo,"HL",(hmax-hmin)/nbins/2));
1840  //cpl_table_save(histo, NULL, NULL, "out_histo2.fits", CPL_IO_DEFAULT);
1841 
1842 
1843 
1844  }
1845  sinfo_free_table(&data_tbl);
1846  sinfo_free_table(&min_xi);
1847 
1848  //cpl_table_save(histo, NULL, NULL, "out_histo.fits", CPL_IO_DEFAULT);
1849 
1850  check_nomsg(peak=cpl_table_get_column_max(histo,"HY"));
1851  //sinfo_msg("peak=%f",peak);
1852  sinfo_free_table(&tmp_tbl1);
1853 
1854  check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HY",CPL_EQUAL_TO,peak));
1855 
1856  //cpl_table_save(tmp_tbl1, NULL, NULL, "out_tmp_tbl1.fits", CPL_IO_DEFAULT);
1857 
1858 
1859  check_nomsg(*centre=cpl_table_get_column_mean(tmp_tbl1,"HL"));
1860  //sinfo_msg("Background level=%f",*centre);
1861 
1862  sinfo_free_table(&tmp_tbl1);
1863  check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HY",
1864  CPL_GREATER_THAN,
1865  peak/HISTO_Y_CUT));
1866  sinfo_free_table(&tmp_tbl2);
1867  check_nomsg(tmp_tbl2=sinfo_extract_table_rows(tmp_tbl1,"HY",
1868  CPL_LESS_THAN,peak));
1869  sinfo_free_table(&tmp_tbl1);
1870 
1871  check_nomsg(tempc=*centre-cpl_table_get_column_min(tmp_tbl2,"HL"));
1872  //sinfo_msg("min HX %f",cpl_table_get_column_min(tmp_tbl2,"HL"));
1873  sinfo_free_table(&tmp_tbl2);
1874  //sinfo_msg("Tempc=%f",tempc);
1875  check_nomsg(dist=sinfo_where_tab_min_max(histo,"HL",
1876  CPL_GREATER_THAN,*centre-HISTO_DIST_TEMPC_MIN_FCT*tempc,
1877  CPL_NOT_GREATER_THAN,*centre+HISTO_DIST_TEMPC_MAX_FCT*tempc));
1878 
1879  offset=cpl_table_get_column_min(histo,"HY");
1880  sinfo_free_table(&histo);
1881 
1882 
1883  check_nomsg(ndist=cpl_table_get_nrow(dist));
1884  check_nomsg(cpl_table_cast_column(dist,"HY","HYdouble",CPL_TYPE_DOUBLE));
1885  check_nomsg(disth=cpl_table_get_data_double(dist,"HYdouble"));
1886  check_nomsg(distx=cpl_table_get_data_double(dist,"HL"));
1887  //cpl_table_save(dist, NULL, NULL, "out_dist.fits", CPL_IO_DEFAULT);
1888 
1889  //TODO
1890  //gaussfit(distx,disty,dista,nterms=3);
1891  //*noise=dista[2];
1892  *noise=tempc/2;
1893  /* THIS DOES NOT WORK */
1894  //sinfo_msg("FWHM/2=%f",*noise);
1895 
1896  if(obj_noise_fit == 1) {
1897  check_nomsg(vy=cpl_vector_wrap(ndist,disth));
1898  check_nomsg(vx=cpl_vector_wrap(ndist,distx));
1899  check_nomsg(sx=cpl_vector_new(ndist));
1900  check_nomsg(cpl_vector_fill(sx,1.));
1901  check_nomsg(sy=cpl_vector_duplicate(sx));
1902  x0=*centre;
1903  sigma=tempc/2;
1904 
1905  check_nomsg(cpl_vector_fit_gaussian(vx,NULL,
1906  vy,NULL,
1907  CPL_FIT_ALL,
1908  &x0,&sigma,&area,&offset,
1909  NULL,NULL,NULL));
1910  //sinfo_msg("Gauss fit parameters:"
1911  // "x0=%f sigma=%f area=%f offset=%f mse=%f chired=%f",
1912  // x0,sigma,area,offset,mse,chired);
1913  //sinfo_msg("Background level=%f",*centre);
1914  //sinfo_msg("Noise=%f",sigma);
1915  *noise=sigma;
1916  sinfo_unwrap_vector(&vx);
1917  sinfo_unwrap_vector(&vy);
1918  sinfo_free_my_vector(&sx);
1919  sinfo_free_my_vector(&sy);
1920  }
1921  sinfo_free_table(&dist);
1922  //*noise=18.7448;
1923  //*noise=20.585946;
1924  return 0;
1925 
1926  cleanup:
1927  sinfo_free_imagelist(&obj_cub);
1928  sinfo_free_propertylist(&plist);
1929  sinfo_free_table(&min_xi);
1930  sinfo_free_table(&tmp_tbl1);
1931  sinfo_free_table(&tmp_tbl2);
1932  sinfo_free_table(&histo);
1933  sinfo_free_table(&dist);
1934  sinfo_free_table(&data_tbl);
1935  sinfo_free_my_vector(&sx);
1936  sinfo_free_my_vector(&sy);
1937  sinfo_unwrap_vector(&vx);
1938  sinfo_unwrap_vector(&vy);
1939 
1940  return -1;
1941 
1942 }
1943 
1944 
1957 cpl_table*
1958 sinfo_where_tab_min_max(cpl_table* t,
1959  const char* col,
1960  cpl_table_select_operator op1,
1961  const double v1,
1962  cpl_table_select_operator op2,
1963  const double v2)
1964 {
1965 
1966  cpl_table* res=NULL;
1967  cpl_table* tmp=NULL;
1968 
1969  check_nomsg(cpl_table_and_selected_double(t,col,op1,v1));
1970  check_nomsg(tmp=cpl_table_extract_selected(t));
1971  check_nomsg(cpl_table_and_selected_double(tmp,col,op2,v2));
1972  check_nomsg(res=cpl_table_extract_selected(tmp));
1973  check_nomsg(cpl_table_select_all(t));
1974  sinfo_free_table(&tmp);
1975 
1976  return res;
1977 
1978  cleanup:
1979  sinfo_free_table(&tmp);
1980  sinfo_free_table(&res);
1981 
1982  return NULL;
1983 
1984 }
1985 /*-------------------------------------------------------------------------*/
2009 /*--------------------------------------------------------------------------*/
2010 
2011 int
2012 sinfo_histogram(const cpl_table* data,
2013  const int nbins,
2014  const double min,
2015  const double max,
2016  cpl_table** histo)
2017 {
2018  cpl_table* tmp_tbl1=NULL;
2019  cpl_table* tmp_tbl2=NULL;
2020  cpl_table* dat=NULL;
2021  int ntot=0;
2022  int i=0;
2023  int* phy=NULL;
2024  double* pdt=NULL;
2025  /* double* phx=NULL; */
2026 
2027  double vtmp=0;
2028  double vstp=0;
2029  double vmax=0;
2030  double vmin=0;
2031 
2032  int h=0;
2033  check_nomsg(dat=cpl_table_duplicate(data));
2034  check_nomsg(cpl_table_cast_column(dat,"DATA","DDATA",CPL_TYPE_DOUBLE));
2035  /*
2036  sinfo_msg("min=%f max=%f",
2037  cpl_table_get_column_min(dat,"DDATA"),
2038  cpl_table_get_column_max(dat,"DDATA"));
2039  */
2040  check_nomsg(cpl_table_and_selected_double(dat,"DDATA",
2041  CPL_NOT_GREATER_THAN,max));
2042  /*
2043  check_nomsg(cpl_table_and_selected_double(dat,"DDATA",CPL_LESS_THAN,max));
2044  */
2045  check_nomsg(tmp_tbl1=cpl_table_extract_selected(dat));
2046  /*
2047  sinfo_msg("min=%f max=%f",
2048  cpl_table_get_column_min(tmp_tbl1,"DDATA"),
2049  cpl_table_get_column_max(tmp_tbl1,"DDATA"));
2050  */
2051  /*
2052  check_nomsg(cpl_table_and_selected_double(tmp_tbl1,"DDATA",
2053  CPL_NOT_LESS_THAN,min));
2054  */
2055  check_nomsg(cpl_table_and_selected_double(tmp_tbl1,"DDATA",
2056  CPL_GREATER_THAN,min));
2057  check_nomsg(tmp_tbl2=cpl_table_extract_selected(tmp_tbl1));
2058  /*
2059  sinfo_msg("min=%f max=%f",
2060  cpl_table_get_column_min(tmp_tbl2,"DDATA"),
2061  cpl_table_get_column_max(tmp_tbl2,"DDATA"));
2062  */
2063  sinfo_free_table(&tmp_tbl1);
2064  /*
2065  check_nomsg(tmp_tbl1=sinfo_extract_table_rows(dat,"DDATA",
2066  CPL_NOT_GREATER_THAN,max));
2067  check_nomsg(tmp_tbl2=sinfo_extract_table_rows(tmp_tbl1,"DDATA",
2068  CPL_NOT_LESS_THAN,min));
2069  */
2070 
2071  check_nomsg(ntot=cpl_table_get_nrow(tmp_tbl2));
2072  /* not necessry to sort:
2073  check_nomsg(sinfo_sort_table_1(tmp_tbl2,"DDATA",FALSE));*/
2074  check_nomsg(vmin=cpl_table_get_column_min(tmp_tbl2,"DDATA"));
2075  check_nomsg(vmax=cpl_table_get_column_max(tmp_tbl2,"DDATA"));
2076  vstp=(vmax-vmin)/(nbins-1);
2077  /* sinfo_msg("vmin=%f vmax=%f step=%f",vmin,vmax,vstp); */
2078  check_nomsg(*histo=cpl_table_new(nbins));
2079  check_nomsg(cpl_table_new_column(*histo,"HX",CPL_TYPE_DOUBLE));
2080  check_nomsg(cpl_table_new_column(*histo,"HL",CPL_TYPE_DOUBLE));
2081  check_nomsg(cpl_table_new_column(*histo,"HY",CPL_TYPE_INT));
2082 
2083  /*check_nomsg(cpl_table_fill_column_window(*histo,"HX",0,nbins,0)); */
2084  check_nomsg(cpl_table_fill_column_window(*histo,"HL",0,nbins,0));
2085  check_nomsg(cpl_table_fill_column_window(*histo,"HY",0,nbins,0));
2086 
2087  check_nomsg(phy=cpl_table_get_data_int(*histo,"HY"));
2088  /*check_nomsg(phx=cpl_table_get_data_double(*histo,"HX")); */
2089  check_nomsg(pdt=cpl_table_get_data_double(dat,"DATA"));
2090 
2091  for(i=0;i<nbins;i++) {
2092  cpl_table_set_double(*histo,"HX",i,(double)i);
2093  vtmp=vmin+i*vstp;
2094  cpl_table_set_double(*histo,"HL",i,vtmp);
2095  }
2096  h=0;
2097 
2098  for(i=0;i<ntot;i++) {
2099  h=floor((pdt[i]-vmin)/vstp);
2100  if((h<nbins) && (h>-1)) {
2101  phy[h]++;
2102  }
2103  }
2104  //cpl_table_save(*histo, NULL, NULL, "out_histo_p5.fits", CPL_IO_DEFAULT);
2105 
2106  sinfo_free_table(&tmp_tbl2);
2107  sinfo_free_table(&dat);
2108 
2109 
2110  return 0;
2111  cleanup:
2112  sinfo_free_table(&tmp_tbl1);
2113  sinfo_free_table(&tmp_tbl2);
2114  sinfo_free_table(&dat);
2115 
2116  return -1;
2117 
2118 }
2119 
2120 
2121 /*-------------------------------------------------------------------------*/
2131 /*--------------------------------------------------------------------------*/
2132 
2133 int
2134 sinfo_object_flag_low_values(cpl_frame* obj_frm,
2135  const double cnt,
2136  const double sig,
2137  cpl_imagelist** flag_data)
2138 {
2139 
2140  int xsz=0;
2141  int ysz=0;
2142  int zsz=0;
2143  int n=0;
2144  int i=0;
2145  int k=0;
2146  int r=0;
2147 
2148  cpl_propertylist* plist=NULL;
2149  cpl_table* data_tbl=NULL;
2150  cpl_table* flag_tbl=NULL;
2151  cpl_image* img=NULL;
2152  cpl_imagelist* obj_cub=NULL;
2153 
2154  double* pdata=NULL;
2155  double* pflag=NULL;
2156 
2157  /* Get Object relevant information */
2158  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
2159  check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
2160  check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
2161  check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
2162  sinfo_free_propertylist(&plist);
2163 
2164  cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
2165  CPL_TYPE_DOUBLE,0));
2166 
2167  n=xsz*ysz*zsz;
2168  check_nomsg(data_tbl=cpl_table_new(n));
2169  check_nomsg(cpl_table_new_column(data_tbl,"DATA",CPL_TYPE_DOUBLE));
2170 
2171  for(k=0;k<zsz;k++) {
2172  check_nomsg(img=cpl_imagelist_get(obj_cub,k));
2173  check_nomsg(pdata=cpl_image_get_data_double(img));
2174  for(i=0;i<xsz*ysz;i++) {
2175  if(!irplib_isnan(pdata[i])) {
2176  check_nomsg(cpl_table_set_double(data_tbl,"DATA",r,pdata[i]));
2177  r++;
2178  }
2179  }
2180  }
2181 
2182  check_nomsg(cpl_table_erase_invalid(data_tbl));
2183  //sinfo_msg("Background level: %f Noise: %f",cnt,sig);
2184  check_nomsg(cpl_table_and_selected_double(data_tbl,"DATA",
2185  CPL_LESS_THAN,cnt+2*sig));
2186  check_nomsg(flag_tbl=cpl_table_extract_selected(data_tbl));
2187  sinfo_free_table(&data_tbl);
2188  //check_nomsg(cpl_table_save(flag_tbl,NULL,NULL,
2189  // "out_flag.fits",CPL_IO_DEFAULT));
2190  sinfo_free_table(&flag_tbl);
2191 
2192  check_nomsg(*flag_data=cpl_imagelist_new());
2193  for(i=0;i<zsz;i++) {
2194  check_nomsg(img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
2195  check_nomsg(cpl_image_add_scalar(img,0));
2196  check_nomsg(cpl_imagelist_set(*flag_data,cpl_image_duplicate(img),i));
2197  sinfo_free_image(&img);
2198  }
2199  for(k=0;k<zsz;k++) {
2200  check_nomsg(img=cpl_imagelist_get(*flag_data,k));
2201  pflag=cpl_image_get_data_double(cpl_imagelist_get(*flag_data,k));
2202  pdata=cpl_image_get_data_double(cpl_imagelist_get(obj_cub,k));
2203  for(i=0;i<xsz*ysz;i++) {
2204  if((!irplib_isnan(pdata[i])) && pdata[i] < (cnt+2*sig)) {
2205  pflag[i]=1;
2206  }
2207  }
2208  }
2209 
2210  sinfo_free_imagelist(&obj_cub);
2211 
2212 
2213 
2214 
2215  return 0;
2216 
2217  cleanup:
2218  sinfo_free_propertylist(&plist);
2219  sinfo_free_imagelist(&obj_cub);
2220  sinfo_free_table(&data_tbl);
2221  sinfo_free_table(&flag_tbl);
2222 
2223  return -1;
2224 }
2225 
2226 /*-------------------------------------------------------------------------*/
2240 /*--------------------------------------------------------------------------*/
2241 
2242 
2243 int
2244 sinfo_object_flag_sky_pixels(cpl_frame* obj_frm,
2245  cpl_table* lambda,
2246  cpl_table* mrange,
2247  cpl_imagelist* flag_data,
2248  const double tol,
2249  cpl_image** g_img,
2250  cpl_image** r_img,
2251  cpl_image** image)
2252 {
2253 
2254  int xsz=0;
2255  int ysz=0;
2256  //int zsz=0;
2257  int i=0;
2258  int j=0;
2259  int gpix_i=0;
2260  double tot=0;
2261  double all_pix=0;
2262  double flag_pix=0;
2263  double ratio=0;
2264 
2265  double* pr_img=NULL;
2266  double* pg_img=NULL;
2267  double* pimage=NULL;
2268  cpl_propertylist* plist=NULL;
2269  cpl_imagelist* osel=NULL;
2270  cpl_imagelist* fsel=NULL;
2271  cpl_table* gpix=NULL;
2272  cpl_table* gspec=NULL;
2273  cpl_table* fspec=NULL;
2274  cpl_table* ospec=NULL;
2275 
2276  cpl_imagelist* obj_cub=NULL;
2277 
2278  /* Get Object relevant information */
2279  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
2280 
2281  check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
2282  check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
2283  //check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
2284  sinfo_free_propertylist(&plist);
2285  cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
2286  CPL_TYPE_DOUBLE,0));
2287 
2288  /* Flag sky pixels in data cube */
2289  /* create images */
2290  check_nomsg(*r_img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
2291  check_nomsg(*g_img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
2292  check_nomsg(*image=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
2293 
2294  cknull_nomsg(pr_img=cpl_image_get_data_double(*r_img));
2295  cknull_nomsg(pg_img=cpl_image_get_data_double(*g_img));
2296  cknull_nomsg(pimage=cpl_image_get_data_double(*image));
2297 
2298  /* TODO */
2299  // fill image points:
2300  // g_img: mask with at least half good pixels along spectral range
2301  // r_img: mask with ratio of good pixels along spectral range
2302  // image: image with mean of spectrum over good pixels
2303 
2304  //check_nomsg(cpl_table_save(lambda, NULL, NULL,
2305  // "out_lambda.fits", CPL_IO_DEFAULT));
2306  //check_nomsg(cpl_table_save(mrange, NULL, NULL,
2307  // "out_mrange.fits", CPL_IO_DEFAULT));
2308 
2309  cknull_nomsg(osel=sinfo_imagelist_select_range(obj_cub,lambda,
2310  mrange,tol));
2311 
2312  sinfo_free_imagelist(&obj_cub);
2313 
2314  cknull_nomsg(fsel=sinfo_imagelist_select_range(flag_data,lambda,
2315  mrange,tol));
2316 
2317  //check_nomsg(cpl_imagelist_save(osel,"out_osel.fits",
2318  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
2319  //check_nomsg(cpl_imagelist_save(fsel,"out_fsel.fits",
2320  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
2321 
2322  for(j=0;j<ysz;j++) {
2323  for(i=0;i<xsz;i++) {
2324  // consider only planes in the proper wavelegth ranges
2325  cknull_nomsg(ospec=sinfo_slice_z(osel,i,j));
2326  cknull_nomsg(fspec=sinfo_slice_z(fsel,i,j));
2327  // consider only finite pixels
2328  check_nomsg(gpix_i=sinfo_table_extract_finite(ospec,fspec,&gpix,&gspec));
2329  //sinfo_msg("gpix_i=%d",gpix_i);
2330  if(gpix_i > 0) {
2331  // build two arrays of proper size
2332  all_pix=(double)gpix_i;
2333  /*
2334  sinfo_msg("flagspec: min=%f max=%f",
2335  cpl_table_get_column_min(fspec,"VALUE"),
2336  cpl_table_get_column_max(fspec,"VALUE"));
2337  sinfo_msg("good flagspec: min=%f max=%f",
2338  cpl_table_get_column_min(gspec,"VALUE"),
2339  cpl_table_get_column_max(gspec,"VALUE"));
2340  sinfo_msg("nfspec=%d",cpl_table_get_nrow(fspec));
2341  check_nomsg(cpl_table_save(fspec, NULL, NULL,
2342  "out_fspec.fits",CPL_IO_DEFAULT));
2343  check_nomsg(cpl_table_save(gspec, NULL, NULL,
2344  "out_gspec.fits", CPL_IO_DEFAULT));
2345  */
2346  //check_nomsg(flag_pix=cpl_table_and_selected_double(fspec,"VALUE",
2347  // CPL_GREATER_THAN,0.5));
2348  //sinfo_msg("all_pix=%f flag_pix=%f",all_pix,flag_pix);
2349 
2350  check_nomsg(flag_pix=cpl_table_and_selected_double(gspec,"VALUE",
2351  CPL_GREATER_THAN,0.5));
2352  //sinfo_msg("all_pix=%f flag_pix=%f",all_pix,flag_pix);
2353  // flag_pix = float(n_elements(where(fspec[gpix] > 0.5)));
2354  // compute the ratio between the two arrays
2355  ratio=flag_pix/all_pix;
2356  // considers only pixels with have at least half good pixels
2357  if(all_pix > cpl_table_get_nrow(mrange)/2) {
2358  pg_img[i+j*xsz]=1;
2359  pr_img[i+j*xsz]=ratio;
2360  }
2361  //mean(ospec(gpix))
2362  check_nomsg(pimage[i+j*xsz]=cpl_table_get_column_mean(gpix,"VALUE"));
2363  //sinfo_msg("ix=%d iy=%d r=%f",i,j,ratio);
2364  }
2365  sinfo_free_table(&ospec);
2366  sinfo_free_table(&fspec);
2367  sinfo_free_table(&gpix);
2368  sinfo_free_table(&gspec);
2369 
2370  } /* end for over i */
2371  } /* end for over j */
2372  sinfo_free_imagelist(&osel);
2373  sinfo_free_imagelist(&fsel);
2374 
2375  /*
2376  cpl_image_save(*r_img,"out_r_img.fits",CPL_BPP_IEEE_FLOAT,
2377  NULL,CPL_IO_DEFAULT);
2378  cpl_image_save(*g_img,"out_g_img.fits",CPL_BPP_IEEE_FLOAT,
2379  NULL,CPL_IO_DEFAULT);
2380  cpl_image_save(*image,"out_image.fits",CPL_BPP_IEEE_FLOAT,
2381  NULL,CPL_IO_DEFAULT);
2382  */
2383  // get total(g_arr)
2384  check_nomsg(tot=cpl_image_get_flux(*g_img));
2385  if(tot < 1) {
2386  sinfo_msg_error("no good spaxel");
2387  goto cleanup;
2388  }
2389 
2390  return 0;
2391 
2392 
2393  cleanup:
2394  sinfo_free_propertylist(&plist);
2395  sinfo_free_imagelist(&obj_cub);
2396  sinfo_free_imagelist(&osel);
2397  sinfo_free_imagelist(&fsel);
2398  sinfo_free_table(&ospec);
2399  sinfo_free_table(&fspec);
2400  sinfo_free_table(&gpix);
2401  sinfo_free_table(&gspec);
2402 
2403  return -1;
2404 
2405 
2406 }
2407 
2416 int
2417 sinfo_choose_good_sky_pixels(cpl_frame* obj_frm,
2418  cpl_image* r_img,
2419  cpl_image* g_img,
2420  const double min_frac,
2421  cpl_image** mask)
2422 {
2423 
2424  int xsz=0;
2425  int ysz=0;
2426  //int zsz=0;
2427  int r2i=0;
2428  int status=0;
2429  double tot=0;
2430  double thres=SKY_THRES;
2431  double cum_x_max=0;
2432 
2433  cpl_image* r2img=NULL;
2434  cpl_propertylist* plist=NULL;
2435  cpl_table* cum=NULL;
2436  cpl_table* hcum=NULL;
2437  cpl_table* thres_tbl=NULL;
2438 
2439  cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
2440  check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
2441  check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
2442  //check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
2443  sinfo_free_propertylist(&plist);
2444 
2445  // choose pixels which seem to be sky (ie 95% of spectral pixels are flagged)
2446  check_nomsg(*mask=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
2447  //r2 = where(r_img >= thres,r2i);
2448  // count good pixels: set to 0 what < thres and to 1 what > thres
2449  check_nomsg(r2img=cpl_image_duplicate(r_img));
2450  check_nomsg(cpl_image_threshold(r2img,thres,thres,0,1));
2451  check_nomsg(r2i=cpl_image_get_flux(r2img));
2452 
2453  if(r2i>0) {
2454  sinfo_free_image(&(*mask));
2455  check_nomsg(*mask=cpl_image_duplicate(r2img));
2456  }
2457  sinfo_free_image(&r2img);
2458  check_nomsg(r2img=cpl_image_duplicate(r_img));
2459  check_nomsg(cpl_image_threshold(r2img,thres,SINFO_DBL_MAX,0,SINFO_DBL_MAX));
2460  sinfo_free_image(&r2img);
2461 
2462  check_nomsg(tot=cpl_image_get_flux(g_img));
2463 
2464 
2465  sinfo_msg("%2.2d spaxels (%4.1f %% of good pixels) are designated as sky",
2466  r2i,100.*r2i/tot);
2467 
2468  //threshold ratio for fraction 'minfrac' of spatial pixels to be 'sky'
2469  if (1.*r2i/tot < min_frac) {
2470  sinfo_msg("this is too small - will increase it to %4.1f %%",
2471  100.*min_frac);
2472  check_nomsg(cum=cpl_table_new(xsz*ysz));
2473  check_nomsg(cpl_table_new_column(cum,"X",CPL_TYPE_DOUBLE));
2474  sinfo_table_column_dindgen(&cum,"X");
2475  check_nomsg(cpl_table_add_scalar(cum,"X",1.));
2476 
2477  //hcum = r_img(sort(r_img));
2478  hcum = sinfo_image2table(r_img);
2479  check_nomsg(sinfo_sort_table_1(hcum,"VALUE",FALSE));
2480 
2481  //thresh = hcum[where(xcum/max(xcum) >= 1.-min_frac)];
2482  check_nomsg(cpl_table_duplicate_column(cum,"H",hcum,"VALUE"));
2483  check_nomsg(cum_x_max=cpl_table_get_column_max(cum,"X"));
2484  check_nomsg(cpl_table_duplicate_column(cum,"R",cum,"X"));
2485  check_nomsg(cpl_table_divide_scalar(cum,"R",cum_x_max));
2486  check_nomsg(cpl_table_and_selected_double(cum,"R",
2487  CPL_NOT_LESS_THAN,
2488  (1.-min_frac)));
2489  check_nomsg(thres_tbl=cpl_table_extract_selected(cum));
2490 
2491  check_nomsg(thres = cpl_table_get(thres_tbl,"R",0,&status));
2492  //*mask[where(r_img >= thresh)] = 1;
2493  sinfo_free_image(&(*mask));
2494 
2495 
2496  check_nomsg(*mask=cpl_image_duplicate(r_img));
2497  check_nomsg(cpl_image_threshold(*mask,thres,thres,0,1));
2498  }
2499  sinfo_free_table(&cum);
2500  sinfo_free_table(&hcum);
2501  sinfo_free_table(&thres_tbl);
2502 
2503  return 0;
2504  cleanup:
2505 
2506  sinfo_free_propertylist(&plist);
2507  sinfo_free_image(&r2img);
2508  sinfo_free_table(&cum);
2509  sinfo_free_table(&hcum);
2510  sinfo_free_table(&thres_tbl);
2511 
2512  return -1;
2513 
2514 }
2515 
2516 /*-------------------------------------------------------------------------*/
2525 /*--------------------------------------------------------------------------*/
2526 
2527 static double
2528 sinfo_fit_bkg(double p[])
2529 
2530 {
2531  double* px=NULL;
2532  double* py=NULL;
2533  double* pv=NULL;
2534  cpl_vector* vtmp=NULL;
2535  double max=0;
2536  int i=0;
2537  int np=0;
2538 
2539  double chi2=0;
2540 
2541  check_nomsg(px= cpl_vector_get_data(sa_vx));
2542  check_nomsg(py= cpl_vector_get_data(sa_vy));
2543  check_nomsg(np= cpl_vector_get_size(sa_vx));
2544  check_nomsg(vtmp=cpl_vector_duplicate(sa_vy));
2545  check_nomsg(pv=cpl_vector_get_data(vtmp));
2546 
2547  for(i=0;i<np;i++) {
2548  pv[i]=sinfo_fac(px[i],p[2]);
2549  //sinfo_msg("x=%g p=%g",px[i],pv[i]);
2550  }
2551  check_nomsg(max=cpl_vector_get_max(vtmp));
2552  if(max> 0) {
2553  check_nomsg(cpl_vector_divide_scalar(vtmp,max));
2554  check_nomsg(cpl_vector_multiply_scalar(vtmp,p[1]));
2555  check_nomsg(cpl_vector_add_scalar(vtmp,p[0]));
2556  }
2557 
2558 
2559  for(i=0;i<np;i++) {
2560  chi2+=(py[i]-pv[i])*(py[i]-pv[i]);
2561  }
2562  sinfo_free_my_vector(&vtmp);
2563  return chi2;
2564  cleanup:
2565  sinfo_free_my_vector(&vtmp);
2566  return -1;
2567 
2568 }
2569 
2570 
2571 /*-------------------------------------------------------------------------*/
2583 /*--------------------------------------------------------------------------*/
2584 
2585 int
2586 sinfo_thermal_background2(cpl_table* int_sky,
2587  cpl_table* lambda,
2588  cpl_table* lrange,
2589  cpl_table** bkg)
2590 {
2591 
2592  int n2=0;
2593  int i=0;
2594  int j=0;
2595  int nrow=0;
2596 
2597  cpl_table* tmp1=NULL;
2598  cpl_table* tmp2=NULL;
2599 
2600  double max=0;
2601  double wmin=0;
2602  double wmax=0;
2603  double p0[3];
2604  const int MP=4;
2605  const int NP=3;
2606  double y[MP];
2607  double** ap=NULL;
2608  int nfunc=0;
2609  int status=0;
2610  int row=0;
2611  double bkg_min=0;
2612  double bkg_max=0;
2613  double p0_min=0;
2614  double p0_max=0;
2615  double p1_min=0;
2616  double p1_max=0;
2617  double p2_min=0;
2618  double p2_max=0;
2619  double* pw=NULL;
2620  double* pf=NULL;
2621 
2622  ap=(double**) cpl_calloc(MP,sizeof(double*));
2623 
2624  for(i=0;i<MP;i++) {
2625  ap[i]=cpl_calloc(NP,sizeof(double));
2626  }
2627 
2628  cknull(int_sky,"Null input table sky");
2629  cknull(lambda,"Null input table lambda");
2630  cknull(lrange,"Null input table lrange");
2631 
2632 
2633  //TO BE FIXED: Why lrange to gat wave min and max: int_sky is sufficient
2634  check_nomsg(wmin=cpl_table_get_column_min(lrange,"WAVE"));
2635  check_nomsg(wmax=cpl_table_get_column_max(lrange,"WAVE"));
2636  check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
2637  CPL_NOT_LESS_THAN,wmin));
2638  check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
2639  CPL_NOT_GREATER_THAN,wmax));
2640  check_nomsg(tmp1=cpl_table_extract_selected(int_sky));
2641 
2642  check_nomsg(row=sinfo_table_get_index_of_val(tmp1,"WAVE",
2643  wmax,CPL_TYPE_DOUBLE));
2644  check_nomsg(max=cpl_table_get_double(tmp1,"INT",row,&status));
2645  check_nomsg(sinfo_table_flag_nan(&tmp1,"INT"));
2646  check_nomsg(cpl_table_erase_invalid(tmp1));
2647  check_nomsg(cpl_table_and_selected_double(tmp1,"INT",CPL_NOT_EQUAL_TO,0));
2648  check_nomsg(tmp2=cpl_table_extract_selected(tmp1));
2649 
2650  sinfo_free_table(&tmp1);
2651  check_nomsg(n2=cpl_table_get_nrow(tmp2));
2652  check_nomsg(sa_vx=cpl_vector_wrap(n2,
2653  cpl_table_get_data_double(tmp2,"WAVE")));
2654  check_nomsg(sa_vy=cpl_vector_wrap(n2,
2655  cpl_table_get_data_double(tmp2,"INT")));
2656 
2657 
2658  for(i=0;i<MP;i++) {
2659  for(j=0;j<NP;j++) {
2660  ap[i][j]=0;
2661  }
2662  }
2663 
2664  check_nomsg(bkg_min=cpl_table_get_column_min(tmp2,"INT"));
2665  check_nomsg(bkg_max=cpl_table_get_double(tmp2,"INT",row,&status));
2666 
2667 
2668  //Init amoeba fit parameters
2669  p0_min=bkg_min*0.9;
2670  p0_max=bkg_min*1.1;
2671  p1_min=bkg_max*0.9;
2672  p1_max=bkg_max*1.1;
2673  p1_min=200;
2674  p2_max=300;
2675 
2676  ap[0][0]=p0_min; ap[0][1]=p1_min; ap[0][2]=p2_min;
2677  ap[1][0]=p0_max; ap[1][1]=p1_min; ap[1][2]=p2_min;
2678  ap[2][0]=p0_min; ap[2][1]=p1_max; ap[2][2]=p2_min;
2679  ap[3][0]=p0_min; ap[3][1]=p1_min; ap[3][2]=p2_max;
2680 
2681  sinfo_msg("Before amoeba fit");
2682  for(i=0;i<MP;i++) {
2683  for(j=0;j<NP;j++) {
2684  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
2685  }
2686  }
2687 
2688 
2689 
2690 
2691  for(i=0;i<MP;i++) {
2692  p0[0]=ap[i][0];
2693  p0[1]=ap[i][1];
2694  p0[2]=ap[i][2];
2695  y[i]=sinfo_fit_bkg(p0);
2696  }
2697 
2698  sinfo_msg("p0=%g %g %g",p0[0],p0[1],p0[2]);
2699  for(i=0;i<N_ITER_FIT_AMOEBA;i++) {
2700  check_nomsg(sinfo_fit_amoeba(ap,y,NP,AMOEBA_FTOL,sinfo_fit_bkg,&nfunc));
2701  sinfo_msg("After amoeba fit");
2702  sinfo_msg("iter=%d ap=%g %g %g",i,ap[0][0],ap[0][1],ap[0][2]);
2703  }
2704  sinfo_unwrap_vector(&sa_vx);
2705  sinfo_unwrap_vector(&sa_vy);
2706  sinfo_free_table(&tmp2);
2707 
2708 
2709  sinfo_msg("After amoeba fit");
2710  for(i=0;i<MP;i++) {
2711  for(j=0;j<NP;j++) {
2712  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
2713  }
2714  sinfo_msg("y[%d]=%g",i,y[i]);
2715  }
2716 
2717 
2718 
2719  check_nomsg(nrow=cpl_table_get_nrow(lambda));
2720  check_nomsg(*bkg=cpl_table_new(nrow));
2721  check_nomsg(cpl_table_duplicate_column(*bkg,"WAVE",lambda,"WAVE"));
2722  check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
2723  cpl_table_fill_column_window(*bkg,"INT2",0,nrow,0.);
2724  check_nomsg(pw=cpl_table_get_data_double(*bkg,"WAVE"));
2725  check_nomsg(pf=cpl_table_get_data_double(*bkg,"INT2"));
2726 
2727  for(i=0;i<nrow;i++) {
2728  pf[i]=sinfo_fac(pw[i],ap[0][2]);
2729  }
2730  check_nomsg(max=cpl_table_get_column_max(*bkg,"INT2"));
2731 
2732  if(max != 0) {
2733  check_nomsg(cpl_table_divide_scalar(*bkg,"INT2",max));
2734  }
2735  check_nomsg(cpl_table_multiply_scalar(*bkg,"INT2",ap[0][1]));
2736  check_nomsg(cpl_table_add_scalar(*bkg,"INT2",ap[0][0]));
2737  //check_nomsg(cpl_table_save(*bkg,NULL,NULL,
2738  //"out_amoeba5.fits",CPL_IO_DEFAULT ));
2739  sinfo_new_destroy_2Ddoublearray(&ap,MP);
2740 
2741 
2742  return 0;
2743 
2744  cleanup:
2745  sinfo_new_destroy_2Ddoublearray(&ap,MP);
2746  sinfo_free_table(&tmp1);
2747  sinfo_free_table(&tmp2);
2748  sinfo_unwrap_vector(&sa_vx);
2749  sinfo_unwrap_vector(&sa_vy);
2750  return -1;
2751 
2752 }
2753 
2754 
2755 
2756 /*-------------------------------------------------------------------------*/
2768 /*--------------------------------------------------------------------------*/
2769 
2770 int
2771 sinfo_thermal_background(cpl_table* int_sky,
2772  cpl_table* lambda,
2773  cpl_table* lrange,
2774  const double temp,
2775  const int niter,
2776  const int filter_width,
2777  const double tol,
2778  cpl_table** bkg,
2779  int* success_fit)
2780 {
2781 
2782  int npix=0;
2783  int i=0;
2784  int row=0;
2785  const int ndim=3;/* There are 3 parameters */
2786  int ia[ndim];
2787 
2788  int NPOINTS=0;
2789 
2790 
2791  double temp1=0;
2792  double temp2=0;
2793 
2794  //double r0=80.306773;
2795  //double r1=450.50027;
2796  //double r2=252.17949;
2797  double max_tmp2=0;
2798  double* ptmp1=NULL;
2799  double thermal=0;
2800  double* pw=NULL;
2801  double p0[3];
2802  double wmin=0;
2803  double wmax=0;
2804  double ga0=0;
2805  double ga1=0;
2806  //double ga1=0;
2807  double ga2=0;
2808  double mse=0;
2809  double chired=0;
2810 
2811 
2812  cpl_vector *a = cpl_vector_new(ndim);
2813  cpl_table* xlr=NULL;
2814  cpl_table* ylr=NULL;
2815  cpl_table* wlr=NULL;
2816  cpl_table* tmp=NULL;
2817  cpl_table* temp2_tbl=NULL;
2818 
2819  cpl_vector* y=NULL;
2820  cpl_vector* fy=NULL;
2821 
2822  cpl_vector* sy=NULL;
2823 
2824  cpl_matrix* x_matrix=NULL;
2825  //double bkg_min=0;
2826  double bkg_max=0;
2827  int status=0;
2828  double avg=0;
2829  double sdv=0;
2830  double med=0;
2831  double* pif=NULL;
2832  double* pwf=NULL;
2833  double* pws=NULL;
2834  int k=0;
2835  int nrow=0;
2836 
2837  //check_nomsg(cpl_table_save(int_sky,NULL,NULL,
2838  //"out_pippo.fits", CPL_IO_DEFAULT));
2839  check_nomsg(wmin=cpl_table_get_column_min(lrange,"WAVE"));
2840  check_nomsg(wmax=cpl_table_get_column_max(lrange,"WAVE"));
2841 
2842  //bkg_min=sinfo_fac(wmin,temp);
2843  bkg_max=sinfo_fac(wmax,temp);
2844  //sinfo_msg("bkg: min=%g max=%g",bkg_min,bkg_max);
2845  //sinfo_scale_fct=sinfo_scale_fct*bkg_max;
2846  //sinfo_scale_fct=sinfo_scale_fct;
2847 
2848  check_nomsg(cpl_table_and_selected_double(lambda,"WAVE",
2849  CPL_NOT_LESS_THAN,wmin));
2850  check_nomsg(tmp=cpl_table_extract_selected(lambda));
2851 
2852  check_nomsg(cpl_table_and_selected_double(tmp,"WAVE",
2853  CPL_NOT_GREATER_THAN,wmax));
2854  check_nomsg(xlr=cpl_table_extract_selected(tmp));
2855  sinfo_free_table(&tmp);
2856 
2857 
2858  check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
2859  CPL_NOT_LESS_THAN,wmin));
2860  check_nomsg(tmp=cpl_table_extract_selected(int_sky));
2861  check_nomsg(cpl_table_and_selected_double(tmp,"WAVE",
2862  CPL_NOT_GREATER_THAN,wmax));
2863 
2864 
2865  //To be sure one has not strange cases
2866  check_nomsg(cpl_table_and_selected_double(tmp,"INT",CPL_GREATER_THAN,-2));
2867  check_nomsg(ylr=cpl_table_extract_selected(tmp));
2868  //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr_0.fits",CPL_IO_DEFAULT));
2869  sinfo_free_table(&tmp);
2870  check_nomsg(tmp=cpl_table_duplicate(ylr));
2871  sinfo_free_table(&ylr);
2872 
2873  check_nomsg(avg=cpl_table_get_column_mean(tmp,"INT"));
2874  check_nomsg(sdv=cpl_table_get_column_stdev(tmp,"INT"));
2875  check_nomsg(cpl_table_and_selected_double(tmp,"INT",
2876  CPL_LESS_THAN,avg+10*sdv));
2877 
2878  check_nomsg(ylr=cpl_table_extract_selected(tmp));
2879  sinfo_free_table(&tmp);
2880 
2881 
2882  /*
2883  check_nomsg(xlr=sinfo_table_select_range(lambda,lrange,0.003));
2884  check_nomsg(ylr=sinfo_table_select_range(int_sky,lrange,0.003));
2885  */
2886  check_nomsg(cpl_table_and_selected_double(ylr,"INT",CPL_NOT_EQUAL_TO,0));
2887 
2888  check_nomsg(wlr=cpl_table_extract_selected(ylr));
2889 
2890 
2891  check_nomsg(p0[0]=cpl_table_get_column_min(wlr,"INT"));
2892  check_nomsg(row=sinfo_table_get_index_of_val(ylr,"WAVE",
2893  wmax,CPL_TYPE_DOUBLE));
2894  check_nomsg(p0[1]=cpl_table_get_double(ylr,"INT",row,&status));
2895  p0[2]=temp;
2896 
2897 
2898  ga0=p0[0];
2899  ga1=p0[1]/bkg_max;
2900  //ga1=p0[1];
2901  ga2=p0[2];
2902 
2903  //sinfo_msg("p= %g %g %g",p0[0],p0[1],p0[2]);
2904  check_nomsg(sinfo_table_flag_nan(&wlr,"INT"));
2905  check_nomsg(cpl_table_erase_invalid(wlr));
2906  //check_nomsg(cpl_table_save(xlr,NULL,NULL,"out_xlr.fits",CPL_IO_DEFAULT));
2907  //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr.fits",CPL_IO_DEFAULT));
2908  //check_nomsg(cpl_table_save(wlr,NULL,NULL,"out_wlr.fits",CPL_IO_DEFAULT));
2909 
2910 
2911  check_nomsg(NPOINTS=cpl_table_get_nrow(ylr));
2912 
2913  check_nomsg(x_matrix = cpl_matrix_wrap(NPOINTS,1,
2914  cpl_table_get_data_double(ylr,"WAVE")));
2915  check_nomsg(y=cpl_vector_wrap(NPOINTS,cpl_table_get_data_double(ylr,"INT")));
2916  //check_nomsg(fy=cpl_vector_filter_median_create(y,1));
2917  //check_nomsg(fy=cpl_vector_filter_lowpass_create(y,CPL_LOWPASS_LINEAR,3));
2918  //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr1.fits",CPL_IO_DEFAULT));
2919  check_nomsg(fy=sinfo_sky_background_estimate(y,filter_width,filter_width));
2920  //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr2.fits",CPL_IO_DEFAULT));
2921  pif=cpl_vector_get_data(fy);
2922  pwf=cpl_table_get_data_double(ylr,"WAVE");
2923 
2924 
2925  check_nomsg(cpl_table_new_column(int_sky,"INT_BKG_SMO",CPL_TYPE_DOUBLE));
2926  check_nomsg(cpl_table_new_column(int_sky,"WAVE_SMO",CPL_TYPE_DOUBLE));
2927  pws=cpl_table_get_data_double(int_sky,"WAVE");
2928 
2929  k=0;
2930  i=0;
2931  check_nomsg(nrow=cpl_table_get_nrow(int_sky));
2932  if((pws[0]-pwf[0])>0) {
2933  for(i=0;i<NPOINTS;i++) {
2934  if(fabs(pws[k]-pwf[i]) < tol) {
2935  check_nomsg(cpl_table_set_double(int_sky,"INT_BKG_SMO",k,pif[i]));
2936  check_nomsg(cpl_table_set_double(int_sky,"WAVE_SMO",k,pws[i]));
2937  k++;
2938  }
2939  }
2940  } else {
2941  for(k=0;k<nrow;k++) {
2942  if((i<NPOINTS) && (fabs(pws[k]-pwf[i]) < tol)) {
2943  check_nomsg(cpl_table_set_double(int_sky,"INT_BKG_SMO",k,pif[i]));
2944  check_nomsg(cpl_table_set_double(int_sky,"WAVE_SMO",k,pws[i]));
2945  i++;
2946  }
2947  }
2948 
2949  }
2950 
2951  //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr3.fits",CPL_IO_DEFAULT));
2952 
2953 
2954  check_nomsg(cpl_vector_set(a, 0, ga0));
2955  check_nomsg(cpl_vector_set(a, 1, ga1));
2956  check_nomsg(cpl_vector_set(a, 2, ga2));
2957 
2958  check_nomsg(sy=cpl_vector_duplicate(y));
2959  check_nomsg(cpl_vector_power(sy,2));
2960  check_nomsg(cpl_vector_power(sy,0.5));
2961  //check_nomsg(cpl_vector_fill(sy,0.001));
2962 
2963  ia[0] = 1;
2964  ia[1] = 1;
2965  ia[2] = 1;
2966 
2967 
2968  for(i=0;i<niter;i++) {
2969 
2970  /*
2971  sinfo_msg("before fit: a=%g %g %g",
2972  cpl_vector_get(a,0),
2973  cpl_vector_get(a,1),
2974  cpl_vector_get(a,2));
2975  */
2976  if(CPL_ERROR_NONE != sinfo_fit_lm(x_matrix,NULL,fy,sy,a,ia,sinfo_fitbkg,
2977  sinfo_fitbkg_derivative,
2978  &mse,&chired,NULL)) {
2979  sinfo_msg_warning("Thermal background fit failed");
2980  cpl_error_reset();
2981  *success_fit=1;
2982 
2983  goto recover;
2984  }
2985 
2986  //bkg_max=sinfo_fac(wmax,cpl_vector_get(a,2));
2987  //sinfo_scale_fct=sinfo_scale_fct*bkg_max;
2988  /*
2989  sinfo_msg("after fit: a=%g %g %g chired=%g",
2990  cpl_vector_get(a,0),
2991  cpl_vector_get(a,1),
2992  cpl_vector_get(a,2),
2993  chired);
2994 
2995  */
2996 
2997  }
2998 
2999  sinfo_msg("Last fit: a=%g %g %g chired=%g",
3000  cpl_vector_get(a,0),
3001  cpl_vector_get(a,1),
3002  cpl_vector_get(a,2),
3003  chired);
3004 
3005  sinfo_free_my_vector(&fy);
3006  sinfo_unwrap_vector(&y);
3007  sinfo_free_my_vector(&sy);
3008  sinfo_unwrap_matrix(&x_matrix);
3009  sinfo_free_table(&xlr);
3010  sinfo_free_table(&ylr);
3011  sinfo_free_table(&wlr);
3012 
3013  ga0=cpl_vector_get(a,0);
3014  ga1=cpl_vector_get(a,1);
3015  ga2=cpl_vector_get(a,2);
3016  //ga2=252.69284;
3017  check_nomsg(npix=cpl_table_get_nrow(lrange));
3018  check_nomsg(pw=cpl_table_get_data_double(lrange,"WAVE"));
3019  check_nomsg(temp2_tbl=cpl_table_new(npix));
3020  check_nomsg(cpl_table_new_column(temp2_tbl,"TEMP2",CPL_TYPE_DOUBLE));
3021 
3022  for(i=0;i<npix;i++) {
3023  temp2=sinfo_fac(pw[i],ga2);
3024  check_nomsg(cpl_table_set_double(temp2_tbl,"TEMP2",i,temp2));
3025  }
3026  check_nomsg(max_tmp2=cpl_table_get_column_max(temp2_tbl,"TEMP2"));
3027  sinfo_free_table(&temp2_tbl);
3028 
3029 
3030 
3031  check_nomsg(npix=cpl_table_get_nrow(lambda));
3032  check_nomsg(pw=cpl_table_get_data_double(lambda,"WAVE"));
3033  check_nomsg(*bkg=cpl_table_new(npix));
3034  check_nomsg(cpl_table_new_column(*bkg,"WAVE",CPL_TYPE_DOUBLE));
3035  check_nomsg(cpl_table_new_column(*bkg,"TEMP1",CPL_TYPE_DOUBLE));
3036  check_nomsg(cpl_table_new_column(*bkg,"INT",CPL_TYPE_DOUBLE));
3037  check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
3038 
3039  for(i=0;i<npix;i++) {
3040  check_nomsg(cpl_table_set_double(*bkg,"WAVE",i,pw[i]));
3041  temp1=sinfo_fac(pw[i],ga2);
3042  check_nomsg(cpl_table_set_double(*bkg,"TEMP1",i,temp1));
3043  }
3044 
3045  check_nomsg(ptmp1=cpl_table_get_data_double(*bkg,"TEMP1"));
3046  //bkg_max=sinfo_fac(wmax,ga2);
3047 
3048  for(i=0;i<npix;i++) {
3049  thermal=ga0+ptmp1[i]/max_tmp2*ga1;
3050  check_nomsg(cpl_table_set_double(*bkg,"INT",i,thermal));
3051  thermal=ga0+ga1*sinfo_fac(pw[i],ga2);
3052  check_nomsg(cpl_table_set_double(*bkg,"INT2",i,thermal));
3053  }
3054  sinfo_free_my_vector(&a);
3055 
3056  return 0;
3057 
3058  recover:
3059  sinfo_msg_warning("Recover fit of thermal background");
3060  check_nomsg(npix=cpl_table_get_nrow(lambda));
3061  check_nomsg(*bkg=cpl_table_new(npix));
3062  check_nomsg(cpl_table_new_column(*bkg,"TEMP1",CPL_TYPE_DOUBLE));
3063  check_nomsg(cpl_table_new_column(*bkg,"INT",CPL_TYPE_DOUBLE));
3064  check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
3065 
3066  med=cpl_table_get_column_median(ylr,"INT");
3067  for(i=0;i<npix;i++) {
3068  check_nomsg(cpl_table_set_double(*bkg,"INT",i,med));
3069  check_nomsg(cpl_table_set_double(*bkg,"INT2",i,med));
3070  }
3071 
3072  sinfo_free_my_vector(&a);
3073  sinfo_unwrap_vector(&y);
3074  sinfo_free_my_vector(&sy);
3075  sinfo_unwrap_matrix(&x_matrix);
3076  sinfo_free_table(&xlr);
3077  sinfo_free_table(&ylr);
3078  sinfo_free_table(&wlr);
3079  sinfo_free_table(&tmp);
3080 
3081  return 0;
3082 
3083 
3084  cleanup:
3085  sinfo_free_my_vector(&a);
3086  sinfo_unwrap_vector(&y);
3087  sinfo_free_my_vector(&sy);
3088  sinfo_unwrap_matrix(&x_matrix);
3089 
3090  sinfo_free_table(&xlr);
3091  sinfo_free_table(&ylr);
3092  sinfo_free_table(&wlr);
3093  sinfo_free_table(&tmp);
3094  sinfo_free_table(&temp2_tbl);
3095 
3096  return -1;
3097 
3098 }
3099 
3111 static cpl_vector*
3112 sinfo_filter_min(const cpl_vector* vi, const int size)
3113 {
3114 
3115  cpl_vector* vo=NULL;
3116  double min=0;
3117  int start=size/2;
3118  int end=0;
3119  int length=0;
3120  int i=0;
3121  int j=0;
3122  const double* pi=NULL;
3123  double* po=NULL;
3124  cknull(vi,"null input vector");
3125  pi=cpl_vector_get_data_const(vi);
3126  length=cpl_vector_get_size(vi);
3127  end=length-size/2;
3128  vo=cpl_vector_new(length);
3129  po=cpl_vector_get_data(vo);
3130 
3131  for(i=start; i < end; i++) {
3132  min=pi[i-start];
3133  for(j=i-start+1;j<i+start+1;j++) {
3134  if(min> pi[j]) {
3135  min=pi[j];
3136  }
3137  }
3138  po[i]=min;
3139 
3140  }
3141 
3142  // To prevent border effects:
3143  for (i = 0; i < start; i++) {
3144  po[i] = po[start];
3145  }
3146 
3147  for (i = end; i < length; i++) {
3148  po[i] = po[end-1];
3149  }
3150  return vo;
3151 
3152  cleanup:
3153  return NULL;
3154 
3155 
3156 }
3157 
3158 
3170 static cpl_vector*
3171 sinfo_filter_max(const cpl_vector* vi, const int size)
3172 {
3173 
3174  cpl_vector* vo=NULL;
3175  double max=0;
3176  int start=size/2;
3177  int end=0;
3178  int length=0;
3179  int i=0;
3180  int j=0;
3181  const double* pi=NULL;
3182  double* po=NULL;
3183 
3184  cknull(vi,"null input vector");
3185  pi=cpl_vector_get_data_const(vi);
3186  length=cpl_vector_get_size(vi);
3187  end=length-size/2;
3188  vo=cpl_vector_new(length);
3189  po=cpl_vector_get_data(vo);
3190 
3191  for(i=start; i < end; i++) {
3192  max=pi[i-start];
3193  for(j=i-start+1;j<i+start+1;j++) {
3194  if(max< pi[j]) {
3195  max=pi[j];
3196  }
3197  }
3198  po[i]=max;
3199 
3200  }
3201 
3202  // To prevent border effects:
3203  for (i = 0; i < start; i++) {
3204  po[i] = po[start];
3205  }
3206 
3207  for (i = end; i < length; i++) {
3208  po[i] = po[end-1];
3209  }
3210  return vo;
3211 
3212  cleanup:
3213  return NULL;
3214 
3215 
3216 }
3217 
3218 
3219 
3231 static cpl_vector*
3232 sinfo_filter_smo(const cpl_vector* vi, const int size)
3233 {
3234 
3235 
3236  double sum=0;
3237  int start=size/2;
3238  int end=0;
3239  int length=0;
3240  int i=0;
3241  int j=0;
3242  const double* pi=NULL;
3243  double* po=NULL;
3244  cpl_vector* vo=NULL;
3245 
3246  cknull(vi,"null input vector");
3247  length=cpl_vector_get_size(vi);
3248  end=length-size/2;
3249  vo=cpl_vector_new(length);
3250  pi=cpl_vector_get_data_const(vi);
3251  po=cpl_vector_get_data(vo);
3252 
3253  for(i=start; i < end; i++) {
3254  sum=0;
3255  for(j=i - start;j<i+start+1;j++) {
3256  sum += pi[j];
3257  }
3258  po[i]=sum/size;
3259 
3260  }
3261 
3262  // To prevent border effects:
3263  for (i = 0; i < start; i++) {
3264  po[i] = po[start];
3265  }
3266 
3267  for (i = end; i < length; i++) {
3268  po[i] = po[end-1];
3269  }
3270  return vo;
3271 
3272  cleanup:
3273  return NULL;
3274 
3275 }
3276 
3333 cpl_vector* sinfo_sky_background_estimate(cpl_vector *spectrum,
3334  int msize,
3335  int fsize)
3336 {
3337 
3338  cpl_vector * minf=NULL;
3339  cpl_vector * maxf=NULL;
3340  cpl_vector * smof=NULL;
3341  cpl_vector * back=NULL;
3342  double* pb=NULL;
3343  double* ps=NULL;
3344 
3345  int i=0;
3346  int length=0;
3347 
3348 
3349  cknull(spectrum,"null input data");
3350 
3351  if (msize % 2 == 0)
3352  msize++;
3353 
3354  if (fsize % 2 == 0)
3355  fsize++;
3356  check_nomsg(length=cpl_vector_get_size(spectrum));
3357 
3358  if (msize < 3 || fsize < msize || length < 2*fsize)
3359  return NULL;
3360 
3361 
3362  cknull_nomsg(minf = sinfo_filter_min(spectrum, msize));
3363  cknull_nomsg(smof = sinfo_filter_smo(minf, fsize));
3364  cpl_vector_delete(minf);
3365  cknull_nomsg(maxf = sinfo_filter_max(smof,2*msize+1));
3366  cpl_vector_delete(smof);
3367  cknull_nomsg(smof = sinfo_filter_smo(maxf, 2*fsize+1));
3368  cpl_vector_delete(maxf);
3369  cknull_nomsg(minf = sinfo_filter_min(smof, 2*msize+1));
3370  cpl_vector_delete(smof);
3371  cknull_nomsg(smof = sinfo_filter_smo(minf, 2*fsize+1));
3372  cpl_vector_delete(minf);
3373  cknull_nomsg(back=cpl_vector_new(length));
3374  cknull_nomsg(pb=cpl_vector_get_data(back));
3375  cknull_nomsg(ps=cpl_vector_get_data(smof));
3376 
3377  for (i = 0; i < length; i++) {
3378  pb[i] = ps[i];
3379  }
3380  cpl_vector_delete(smof);
3381 
3382  return back;
3383  cleanup:
3384 
3385  return NULL;
3386 
3387 }
3388 
3389 
3390 
3400 static cpl_table*
3401 sinfo_slice_z(const cpl_imagelist* cin,const int i,const int j)
3402 {
3403  int sx=0;
3404  //int sy=0;
3405  int sz=0;
3406  int k=0;
3407  cpl_table* tout=NULL;
3408  const cpl_image* img=NULL;
3409  const double* pim=NULL;
3410 
3411  cknull(cin,"null input imagelist");
3412  check_nomsg(sz=cpl_imagelist_get_size(cin));
3413  check_nomsg(img=cpl_imagelist_get_const(cin,0));
3414  check_nomsg(sx=cpl_image_get_size_x(img));
3415  //check_nomsg(sy=cpl_image_get_size_y(img));
3416  check_nomsg(tout=cpl_table_new(sz));
3417  check_nomsg(cpl_table_new_column(tout,"VALUE",CPL_TYPE_DOUBLE));
3418  for(k=0;k<sz;k++) {
3419  check_nomsg(img=cpl_imagelist_get_const(cin,k));
3420  check_nomsg(pim=cpl_image_get_data_double_const(img));
3421  check_nomsg(cpl_table_set(tout,"VALUE",k,pim[j*sx+i]));
3422  }
3423 
3424  return tout;
3425  cleanup:
3426  sinfo_free_table(&tout);
3427 
3428  return NULL;
3429 
3430 }
3431 
3442 double
3443 sinfo_xcorr(cpl_table* int_obj,
3444  cpl_table* int_sky,
3445  cpl_table* lambda,
3446  const double dispersion,
3447  const double line_hw)
3448 {
3449 
3450  cpl_table* z=NULL;
3451  cpl_table* tmp_sky=NULL;
3452 
3453  cpl_table* z_diff=NULL;
3454  cpl_table* z_pos=NULL;
3455 
3456  int z_ext=0;
3457  double z_mean=0;
3458  double z_sdv=0;
3459  int nrow=0;
3460  int i=0;
3461  /*
3462  double g_lam=0;
3463  double g_err=0;
3464  */
3465  double sky_max=0;
3466 
3467  double* pint=NULL;
3468  int* ppos=NULL;
3469  int status=0;
3470  int zsize=0;
3471  int iq=0;
3472 
3473  //double g_diff=0;
3474  int jz=0;
3475  int z1=0;
3476  int nfit=0;
3477  int npos=0;
3478  cpl_table* z_good=NULL;
3479  cpl_table* w_tbl=NULL;
3480  cpl_table* o_tbl=NULL;
3481  cpl_table* s_tbl=NULL;
3482  cpl_vector* vw=NULL;
3483  cpl_vector* vs=NULL;
3484  cpl_vector* vo=NULL;
3485  cpl_vector* sx=NULL;
3486  cpl_vector* sy=NULL;
3487 
3488 
3489  double o1=0;
3490  double o2=0;
3491  double oc=0;
3492  double om=0;
3493 
3494 
3495 
3496  double zfit=0;
3497 
3498 
3499  double mse=0;
3500 
3501  double ws=0;
3502  double wc_s=0;
3503  double sig_s=0;
3504  double bkg_s=0;
3505  double amp_s=0;
3506  double area_s=0;
3507 
3508  double wo=0;
3509  double wc_o=0;
3510  double sig_o=0;
3511  double bkg_o=0;
3512  double amp_o=0;
3513  double area_o=0;
3514 
3515  cpl_polynomial* cfit=NULL;
3516  cpl_size pows[2];
3517  cpl_vector* vx=NULL;
3518  cpl_vector* vy=NULL;
3519 
3520 
3521  cpl_error_code error_code=CPL_ERROR_NONE;
3522 
3523  // crosscorrelate obj & sky to check for lambda offset
3524 
3525  //if (mean(z[where(finite(z))]) < 0) z = z * (-1);
3526  //if sky mean is < 0 flip sky intensity
3527  zsize=cpl_table_get_nrow(int_obj);
3528  check_nomsg(z = cpl_table_duplicate(int_sky));
3529  ck0_nomsg(sinfo_table_flag_nan(&z,"INT"));
3530  //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z1.fits",CPL_IO_DEFAULT));
3531  check_nomsg(z_mean=cpl_table_get_column_mean(z,"INT"));
3532  if(z_mean < 0) {
3533  check_nomsg(cpl_table_multiply_scalar(z,"INT",-1));
3534  }
3535  //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z2.fits",CPL_IO_DEFAULT));
3536 
3537  //z[where(int_sky < max(int_sky[where(finite(int_sky))])/4)] = 0;
3538  // take in consideration only strong sky lines (set else to 0)
3539  check_nomsg(tmp_sky=cpl_table_duplicate(int_sky));
3540  ck0_nomsg(sinfo_table_flag_nan(&tmp_sky,"INT"));
3541  check_nomsg(sky_max=cpl_table_get_column_max(tmp_sky,"INT"));
3542  sinfo_free_table(&tmp_sky);
3543 
3544  //flag too low values
3545  check_nomsg(nrow=cpl_table_get_nrow(z));
3546  check_nomsg(pint=cpl_table_get_data_double(z,"INT"));
3547  check_nomsg(sky_max=cpl_table_get_column_max(z,"INT"));
3548  for(i=0;i<nrow;i++) {
3549  if(pint[i]<sky_max/SKY_LINE_MIN_CUT) {
3550  pint[i]=0;
3551  }
3552  }
3553 
3554 
3555  //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z4.fits",CPL_IO_DEFAULT));
3556  //computes gradient
3557  //z_diff = z[0:n_elements(z)-2] - z[1:n_elements(z)-1];
3558  check_nomsg(z_diff=cpl_table_duplicate(z));
3559  check_nomsg(cpl_table_duplicate_column(z_diff,"INT1",z,"INT"));
3560  check_nomsg(cpl_table_duplicate_column(z_diff,"INT2",z,"INT"));
3561  check_nomsg(cpl_table_shift_column(z_diff,"INT1",-1));
3562  check_nomsg(cpl_table_duplicate_column(z_diff,"DIFF",z_diff,"INT2"));
3563  check_nomsg(cpl_table_subtract_columns(z_diff,"DIFF","INT1"));
3564 
3565  check_nomsg(cpl_table_erase_window(z_diff,nrow-2,2));
3566  //check_nomsg(cpl_table_save(z_diff,NULL,NULL,
3567  // "out_z_diff.fits",CPL_IO_DEFAULT));
3568 
3569  //identify points positions at which there is a line pick
3570  check_nomsg(cpl_table_new_column(z_diff,"POS",CPL_TYPE_INT));
3571  check_nomsg(cpl_table_fill_column_window_int(z_diff,"POS",0,nrow,0));
3572 
3573  check_nomsg(pint=cpl_table_get_data_double(z_diff,"DIFF"));
3574  check_nomsg(ppos=cpl_table_get_data_int(z_diff,"POS"));
3575  check_nomsg(nrow=cpl_table_get_nrow(z_diff));
3576  for(i=1;i<nrow;i++) {
3577  if(!irplib_isnan(pint[i]) && (pint[i]>0 && pint[i-1]<0)) {
3578  ppos[i]=i;
3579  }
3580  }
3581 
3582  //check_nomsg(cpl_table_save(z_diff,NULL,NULL,"out_z_diff.fits",
3583  // CPL_IO_DEFAULT));
3584  check_nomsg(cpl_table_select_all(z_diff));
3585  check_nomsg(cpl_table_and_selected_int(z_diff,"POS",CPL_GREATER_THAN,0));
3586  check_nomsg(z_pos=cpl_table_extract_selected(z_diff));
3587  sinfo_free_table(&z_diff);
3588  //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
3589  // "out_z_pos.fits",CPL_IO_DEFAULT));
3590  //Do a gaussian fit in a range of size 2*zext centered at
3591  //each line maximum position (fit the line) to get in corresponding arrays:
3592  // 1) line lambda position of object and sky
3593  // 2) line object -sky intensity
3594  // 3) line object-sky intensity error
3595 
3596  /*
3597  g_lam = 0.;
3598  g_diff = 0.;
3599  g_err = 0.;
3600  */
3601  check_nomsg(npos=cpl_table_get_nrow(z_pos));
3602  z_ext = line_hw ;
3603  check_nomsg(cpl_table_new_column(z_pos,"STATUS_S",CPL_TYPE_INT));
3604  check_nomsg(cpl_table_new_column(z_pos,"STATUS_O",CPL_TYPE_INT));
3605  check_nomsg(cpl_table_fill_column_window_int(z_pos,"STATUS_S",0,npos,0));
3606  check_nomsg(cpl_table_fill_column_window_int(z_pos,"STATUS_O",0,npos,0));
3607  check_nomsg(cpl_table_new_column(z_pos,"SIGS",CPL_TYPE_DOUBLE));
3608  check_nomsg(cpl_table_new_column(z_pos,"WAVES",CPL_TYPE_DOUBLE));
3609  check_nomsg(cpl_table_new_column(z_pos,"BKGS",CPL_TYPE_DOUBLE));
3610  check_nomsg(cpl_table_new_column(z_pos,"AREAS",CPL_TYPE_DOUBLE));
3611  check_nomsg(cpl_table_new_column(z_pos,"AMPS",CPL_TYPE_DOUBLE));
3612 
3613 
3614  check_nomsg(cpl_table_new_column(z_pos,"SIGO",CPL_TYPE_DOUBLE));
3615  check_nomsg(cpl_table_new_column(z_pos,"WAVEO",CPL_TYPE_DOUBLE));
3616  check_nomsg(cpl_table_new_column(z_pos,"BKGO",CPL_TYPE_DOUBLE));
3617  check_nomsg(cpl_table_new_column(z_pos,"AREAO",CPL_TYPE_DOUBLE));
3618  check_nomsg(cpl_table_new_column(z_pos,"AMPO",CPL_TYPE_DOUBLE));
3619 
3620  check_nomsg(cpl_table_new_column(z_pos,"WAVEC",CPL_TYPE_DOUBLE));
3621  check_nomsg(cpl_table_new_column(z_pos,"WDIF",CPL_TYPE_DOUBLE));
3622  check_nomsg(cpl_table_new_column(z_pos,"ERR",CPL_TYPE_DOUBLE));
3623 
3624  nfit=2*z_ext+1;
3625  //sinfo_msg("npos=%d z_ext=%d",npos,z_ext);
3626  //sinfo_table_column_dump(z_pos,"POS",CPL_TYPE_INT);
3627  //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
3628  // "out_z_pos_0.fits",CPL_IO_DEFAULT));
3629  //check_nomsg(cpl_table_save(int_obj,NULL,NULL,
3630  // "out_int_obj_0.fits",CPL_IO_DEFAULT));
3631  //check_nomsg(cpl_table_save(int_sky,NULL,NULL,
3632  // "out_int_sky_0.fits",CPL_IO_DEFAULT));
3633 
3634  for (jz=0;jz<npos;jz++) {
3635  check_nomsg(z1 = cpl_table_get_int(z_pos,"POS",jz,&status));
3636  //sinfo_msg("z1=%d",z1);
3637  // AMO added if check to prevent array explosion
3638  if((z1-z_ext) > 0 && (z1+z_ext) < zsize) {
3639  check_nomsg(cpl_table_select_all(int_sky));
3640  check_nomsg(cpl_table_select_all(int_obj));
3641  check_nomsg(cpl_table_select_all(lambda));
3642  check_nomsg(cpl_table_and_selected_window(int_sky,z1-z_ext,nfit));
3643  check_nomsg(s_tbl=cpl_table_extract_selected(int_sky));
3644  check_nomsg(cpl_table_and_selected_window(lambda,z1-z_ext,nfit));
3645  check_nomsg(w_tbl=cpl_table_extract_selected(lambda));
3646  check_nomsg(cpl_table_and_selected_window(int_obj,z1-z_ext,nfit));
3647  check_nomsg(o_tbl=cpl_table_extract_selected(int_obj));
3648 
3649 
3650  check_nomsg(vw=cpl_vector_wrap(nfit,
3651  cpl_table_get_data_double(w_tbl,"WAVE")));
3652  check_nomsg(vs=cpl_vector_wrap(nfit,
3653  cpl_table_get_data_double(s_tbl,"INT")));
3654  check_nomsg(vo=cpl_vector_wrap(nfit,
3655  cpl_table_get_data_double(o_tbl,"INT")));
3656 
3657 
3658  check_nomsg(sx=cpl_vector_new(nfit));
3659  check_nomsg(cpl_vector_fill(sx,10.));
3660  check_nomsg(sy=cpl_vector_duplicate(sx));
3661 
3662 
3663  // Check if the object line is in emission or absorbtion
3664  o1=cpl_vector_get(vo,0);
3665  o2=cpl_vector_get(vo,nfit-1);
3666  oc=(o1+o2)*0.5;
3667  om=cpl_vector_get_median_const(vo);
3668  if(om<oc) {
3669  cpl_vector_multiply_scalar(vo,-1.);
3670  }
3671  check_nomsg(ws=cpl_table_get_double(lambda,"WAVE",z1,&status));
3672  check_nomsg(amp_s=cpl_table_get_double(z_pos,"INT",jz,&status));
3673  wc_s=ws;
3674  sig_s=z_ext*dispersion;
3675  bkg_s=0;
3676  area_s=sinfo_gaussian_area(amp_s,sig_s,ws,wc_s,bkg_s);
3677  if(wc_s < 2.35) {
3678  //sinfo_msg("wc_s=%f",wc_s);
3679  //cpl_vector_dump(vw,stdout);
3680  //cpl_vector_dump(vs,stdout);
3681 
3682  error_code=cpl_vector_fit_gaussian(vw,NULL,
3683  vs,NULL,
3684  CPL_FIT_ALL,
3685  &wc_s,&sig_s,
3686  &area_s,&bkg_s,
3687  NULL,NULL,NULL);
3688  if(error_code == CPL_ERROR_NONE) {
3689  amp_s=sinfo_gaussian_amp(area_s,sig_s,ws,wc_s,bkg_s);
3690  check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
3691  check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
3692  check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
3693  check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
3694  check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
3695  /*
3696  sinfo_msg("Gauss fit parameters:");
3697  sinfo_msg("wc_s=%f sig_s=%f area_s=%f bkg_s=%f",
3698  wc_s,sig_s,area_s,bkg_s);
3699  sinfo_msg("mse=%f chired=%f amp_s=%f",
3700  mse,chired,amp_s);
3701  */
3702 
3703  } else if (error_code == CPL_ERROR_CONTINUE) {
3704  cpl_error_reset();
3705  amp_s=sinfo_gaussian_amp(area_s,sig_s,ws,wc_s,bkg_s);
3706  check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
3707  check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
3708  check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
3709  check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
3710  check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
3711  check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-1));
3712  } else {
3713  cpl_error_reset();
3714  check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
3715  check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
3716  check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
3717  check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
3718  check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
3719  check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-2));
3720  }
3721  check_nomsg(wo=cpl_table_get_double(lambda,"WAVE",z1,&status));
3722  check_nomsg(amp_o=cpl_table_get_double(z_pos,"INT",jz,&status));
3723  wc_o=wo;
3724  sig_o=z_ext*dispersion;
3725  bkg_o=0;
3726  area_o=sinfo_gaussian_area(amp_o,sig_o,wo,wc_o,bkg_o);
3727  error_code = cpl_vector_fit_gaussian(vw,NULL,
3728  vo,sy,
3729  CPL_FIT_ALL,
3730  &wc_o,&sig_o,
3731  &area_o,&bkg_o,
3732  NULL,NULL,NULL);
3733 
3734  if(error_code == CPL_ERROR_NONE) {
3735 
3736  amp_o=sinfo_gaussian_amp(area_o,sig_o,wo,wc_o,bkg_o);
3737  check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
3738  check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
3739  check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
3740  check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
3741  check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
3742  /*
3743  sinfo_msg("Gauss fit parameters:");
3744  sinfo_msg("wc_o=%f sig_o=%f area_o=%f bkg_o=%f",
3745  wc_o,sig_o,area_o,bkg_o);
3746  sinfo_msg("mse=%f chired=%f amp_o=%f",
3747  mse,chired,amp_o);
3748  */
3749  } else if (error_code == CPL_ERROR_CONTINUE) {
3750 
3751  cpl_error_reset();
3752  amp_o=sinfo_gaussian_amp(area_o,sig_o,wo,wc_o,bkg_o);
3753  check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
3754  check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
3755  check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
3756  check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
3757  check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
3758  check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-1));
3759 
3760  } else {
3761  cpl_error_reset();
3762  check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
3763  check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
3764  check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
3765  check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
3766  check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
3767  check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-2));
3768  /*
3769  if (lambda[z1] < 2.35 &&
3770  total(finite([l1,s1,o1])) == n_elements([l1,s1,o1])) {
3771  gs1 = float(gaussfit(l1,s1,as1,nterms=3));
3772  go1 = float(gaussfit(l1,o1,ao1,nterms=3));
3773  g_lam = [g_lam,(as1[1]+ao1[1])/2.];
3774  g_diff = [g_diff,as1[1]-ao1[1]];
3775  g_err = [g_err,sqrt(as1[2]^2+ao1[2]^2)];
3776  }
3777  */
3778  }
3779  check_nomsg(cpl_table_set_double(z_pos,"ERR",
3780  jz,sqrt(sig_s*sig_s+sig_o*sig_o)));
3781  check_nomsg(cpl_table_set_double(z_pos,"WDIF",jz,wc_s-wc_o));
3782  check_nomsg(cpl_table_set_double(z_pos,"WAVEC",jz,(wc_o+wc_s)/2));
3783 
3784  } else {
3785  check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-3));
3786  check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-3));
3787  }
3788  sinfo_unwrap_vector(&vw);
3789  sinfo_unwrap_vector(&vs);
3790  sinfo_unwrap_vector(&vo);
3791  sinfo_free_my_vector(&sx);
3792  sinfo_free_my_vector(&sy);
3793  sinfo_free_table(&w_tbl);
3794  sinfo_free_table(&s_tbl);
3795  sinfo_free_table(&o_tbl);
3796  }
3797  }
3798 
3799 
3800  check_nomsg(cpl_table_duplicate_column(z_pos,"YDIF",z_pos,"WDIF"));
3801  check_nomsg(cpl_table_divide_scalar(z_pos,"YDIF",dispersion));
3802  //sinfo_table_column_dump(z_pos,"WAVEC",CPL_TYPE_DOUBLE);
3803  //sinfo_table_column_dump(z_pos,"STATUS",CPL_TYPE_INT);
3804  //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
3805 
3806  check_nomsg(cpl_table_and_selected_int(z_pos,"STATUS_S",CPL_GREATER_THAN,-2));
3807  check_nomsg(cpl_table_and_selected_int(z_pos,"STATUS_O",CPL_GREATER_THAN,-2));
3808 
3809  //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
3810  // "out_z_pos.fits",CPL_IO_DEFAULT));
3811 
3812  //goto cleanup;
3813 
3814  check_nomsg(z_good=cpl_table_extract_selected(z_pos));
3815  check_nomsg(npos=cpl_table_get_nrow(z_good));
3816  sinfo_free_table(&z_pos);
3817  if(npos == 0) {
3818  return 0;
3819  }
3820  check_nomsg(z_pos=cpl_table_duplicate(z_good));
3821  check_nomsg(z_mean = cpl_table_get_column_median(z_pos,"WDIF"));
3822  check_nomsg(z_sdv = cpl_table_get_column_stdev(z_pos,"WDIF"));
3823 
3824  //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
3825  // "out_z_pos.fits",CPL_IO_DEFAULT));
3826 
3827  check_nomsg(cpl_table_duplicate_column(z_pos,"CHECK",
3828  z_pos,"WDIF"));
3829 
3830 
3831  cpl_table_erase_column(z_pos,"AMPO");
3832  cpl_table_erase_column(z_pos,"SIGO");
3833  cpl_table_erase_column(z_pos,"AREAO");
3834  cpl_table_erase_column(z_pos,"BKGO");
3835  cpl_table_erase_column(z_pos,"WAVEO");
3836  cpl_table_erase_column(z_pos,"AMPS");
3837  cpl_table_erase_column(z_pos,"SIGS");
3838  cpl_table_erase_column(z_pos,"AREAS");
3839  cpl_table_erase_column(z_pos,"BKGS");
3840  cpl_table_erase_column(z_pos,"WAVES");
3841  cpl_table_erase_column(z_pos,"STATUS_S");
3842  cpl_table_erase_column(z_pos,"STATUS_O");
3843 
3844  cpl_table_erase_column(z_pos,"INT");
3845  cpl_table_erase_column(z_pos,"INT1");
3846  cpl_table_erase_column(z_pos,"INT2");
3847  cpl_table_erase_column(z_pos,"ERR");
3848  cpl_table_erase_column(z_pos,"POS");
3849  cpl_table_erase_column(z_pos,"DIFF");
3850 
3851  //check_nomsg(cpl_table_save(z_good,NULL,NULL,
3852  // "out_z_good.fits",CPL_IO_DEFAULT));
3853  //Do a kappa-sigma clip of the differences of line positions
3854  //as determined in the object and in the sky spectrum
3855 
3856  sinfo_msg("ks-clip1");
3857  sinfo_msg("iter mean (um) sdv (um) mean (pix) sdv (pix)");
3858  //sinfo_table_column_dump(z_pos,"WAVEC",CPL_TYPE_DOUBLE);
3859  //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
3860 
3861  for (iq = 0;iq<XCOR_YSHIFT_KS_CLIP;iq++) {
3862  //sinfo_msg("nval=%d",cpl_table_get_nrow(z_pos));
3863  sinfo_msg(" %d %3.2g %3.2g %5.4g %5.4g",
3864  iq,z_mean,z_sdv,z_mean/dispersion,z_sdv/dispersion);
3865  //z_good = where(abs(g_diff-z_mean) <= 2*z_sdv);
3866 
3867  check_nomsg(cpl_table_subtract_scalar(z_pos,"CHECK",z_mean));
3868  check_nomsg(cpl_table_duplicate_column(z_pos,"CHECKW",z_pos,"CHECK"));
3869  check_nomsg(cpl_table_multiply_columns(z_pos,"CHECKW","CHECK"));
3870  check_nomsg(cpl_table_power_column(z_pos,"CHECKW",0.5));
3871  check_nomsg(cpl_table_add_scalar(z_pos,"CHECK",z_mean));
3872  check_nomsg(cpl_table_and_selected_double(z_pos,"CHECKW",
3873  CPL_NOT_GREATER_THAN,2*z_sdv));
3874  sinfo_free_table(&z_good);
3875  check_nomsg(z_good=cpl_table_extract_selected(z_pos));
3876  //sinfo_msg("ngood=%d",cpl_table_get_nrow(z_good));
3877  check_nomsg(cpl_table_select_all(z_pos));
3878  //z_mean = median(g_diff[z_good]);
3879  //z_sdv = stddev(g_diff[z_good]);
3880  check_nomsg(z_mean = cpl_table_get_column_median(z_good,"WDIF"));
3881  if(nfit>1) {
3882  check_nomsg(z_sdv = cpl_table_get_column_stdev(z_good,"WDIF"));
3883  } else {
3884  z_sdv=0;
3885  }
3886  sinfo_free_table(&z_good);
3887  check_nomsg(cpl_table_erase_column(z_pos,"CHECKW"));
3888 
3889  }
3890  /* do a poly fit of wdif versus wave*/
3891  /*
3892  for (iq = 0; iq<3; iq++) {
3893  // sinfo_msg("%d %f %f",iq,mean(zfit),zsdv);
3894  par1 = poly_fit(g_lam[z_good],g_diff[z_good],poly_n);
3895  z_fit = g_diff*0.;
3896  for (ii=0;ii<poly_n) z_fit = z_fit + par1[ii]*g_lam^ii;
3897  z_res = g_diff-z_fit;
3898  z_sdv = stddev(z_res[zgood]);
3899  z_good = where(abs(z_res) le 3*z_sdv);
3900  }
3901  */
3902  cpl_table_select_all(z_pos);
3903  check_nomsg(cpl_table_new_column(z_pos,"ZFIT",CPL_TYPE_DOUBLE));
3904  check_nomsg(nfit=cpl_table_get_nrow(z_pos));
3905  check_nomsg(cpl_table_fill_column_window(z_pos,"ZFIT",0,nfit,0));
3906  //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
3907  // "out_z_pos2.fits",CPL_IO_DEFAULT));
3908  check_nomsg(z_good=cpl_table_duplicate(z_pos));
3909 
3910  //Do a fit of a uniform function to the residuals line position differences
3911  sinfo_msg("ks-clip2");
3912  sinfo_msg("iter mean (um) sdv (um) mean (pix) sdv (pix)");
3913  check_nomsg(cpl_table_select_all(z_good));
3914  //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
3915  for(iq=0;iq<XCOR_YSHIFT_KS_CLIP;iq++) {
3916  //cpl_table_dump(z_pos,0,cpl_table_get_nrow(z_pos),stdout);
3917  check_nomsg(nfit=cpl_table_get_nrow(z_good));
3918  //sinfo_msg("nfit=%d",nfit);
3919  if(nfit>0) {
3920  check_nomsg(vx=cpl_vector_wrap(nfit,
3921  cpl_table_get_data_double(z_good,"WAVE")));
3922  check_nomsg(vy=cpl_vector_wrap(nfit,
3923  cpl_table_get_data_double(z_good,"WDIF")));
3924  check_nomsg(cfit=sinfo_polynomial_fit_1d_create(vx,vy,0,&mse));
3925  pows[0]=0;
3926  pows[1]=0;
3927  check_nomsg(zfit=cpl_polynomial_get_coeff(cfit,pows));
3928  sinfo_free_polynomial(&cfit);
3929  //sinfo_msg("coeff 0=%g um %g pix",zfit,zfit/dispersion);
3930 
3931  //computes residuals=difference-fit and their standard deviation
3932  //and then do a kappa-sigma clip of outliers (out of 3 sigma)
3933  check_nomsg(cpl_table_fill_column_window(z_good,"ZFIT",0,nfit,zfit));
3934  check_nomsg(cpl_table_duplicate_column(z_good,"WRES",z_good,"WDIF"));
3935  check_nomsg(cpl_table_subtract_columns(z_good,"WRES","ZFIT"));
3936  if(nfit>1) {
3937  //sinfo_msg("nfit=%d",nfit);
3938  //cpl_table_dump(z_good,0,nfit,stdout);
3939  check_nomsg(z_sdv=cpl_table_get_column_stdev(z_good,"WRES"));
3940  //sinfo_msg("z_sdv=%f",z_sdv);
3941  } else {
3942  z_sdv=0;
3943  }
3944  check_nomsg(z_mean=cpl_table_get_column_mean(z_good,"WDIF"));
3945 
3946  sinfo_msg(" %d %3.2g %3.2g %5.4g %5.4g",
3947  iq,z_mean,z_sdv,z_mean/dispersion,z_sdv/dispersion);
3948 
3949  check_nomsg(nfit=cpl_table_get_nrow(z_pos));
3950  check_nomsg(cpl_table_fill_column_window(z_pos,"ZFIT",0,nfit,zfit));
3951  check_nomsg(cpl_table_duplicate_column(z_pos,"WRES",z_pos,"WDIF"));
3952  check_nomsg(cpl_table_subtract_columns(z_pos,"WRES","ZFIT"));
3953 
3954  check_nomsg(cpl_table_multiply_columns(z_pos,"WRES","WRES"));
3955  check_nomsg(cpl_table_power_column(z_pos,"WRES",0.5));
3956  //cpl_table_dump(z_pos,0,cpl_table_get_nrow(z_pos),stdout);
3957  /*
3958  sinfo_msg("min=%g max=%g ndat=%d",
3959  cpl_table_get_column_min(z_pos,"WRES"),
3960  cpl_table_get_column_max(z_pos,"WRES"),
3961  cpl_table_get_nrow(z_pos));
3962  */
3963  check_nomsg(cpl_table_and_selected_double(z_pos,"WRES",
3964  CPL_NOT_GREATER_THAN,3*z_sdv));
3965 
3966  check_nomsg(sinfo_free_table(&z_good));
3967  check_nomsg(z_good=cpl_table_extract_selected(z_pos));
3968 
3969 
3970  check_nomsg(cpl_table_select_all(z_pos));
3971  check_nomsg(cpl_table_select_all(z_good));
3972  check_nomsg(cpl_table_erase_column(z_good,"WRES"));
3973  check_nomsg(cpl_table_erase_column(z_pos,"WRES"));
3974 
3975  sinfo_unwrap_vector(&vx);
3976  sinfo_unwrap_vector(&vy);
3977 
3978  }
3979 
3980  }
3981  //sinfo_msg(">>mean=%g",cpl_table_get_column_mean(z_good,"WDIF"));
3982 
3983  //check_nomsg(cpl_table_save(z_good,NULL,NULL,
3984  // "out_z_pos3.fits",CPL_IO_DEFAULT));
3985  sinfo_unwrap_vector(&vx);
3986  sinfo_unwrap_vector(&vy);
3987  sinfo_free_polynomial(&cfit);
3988  sinfo_free_table(&z);
3989  sinfo_free_table(&z_pos);
3990  sinfo_free_table(&z_good);
3991 
3992 
3993  return zfit;
3994  cleanup:
3995 
3996  sinfo_free_table(&z_good);
3997  sinfo_free_table(&z);
3998  sinfo_free_table(&z_diff);
3999  sinfo_free_table(&tmp_sky);
4000  sinfo_free_table(&z_pos);
4001  sinfo_unwrap_vector(&vw);
4002  sinfo_unwrap_vector(&vs);
4003  sinfo_unwrap_vector(&vo);
4004  sinfo_free_my_vector(&sx);
4005  sinfo_free_my_vector(&sy);
4006  sinfo_unwrap_vector(&vx);
4007  sinfo_unwrap_vector(&vy);
4008  sinfo_free_table(&w_tbl);
4009  sinfo_free_table(&s_tbl);
4010  sinfo_free_table(&o_tbl);
4011  sinfo_free_polynomial(&cfit);
4012 
4013  return 0;
4014 
4015 
4016 }
4017 
4018 
4019 
4020 
4033 static int
4034 sinfo_table_set_nan_out_min_max(cpl_table** t,
4035  const char* c,
4036  const double min,
4037  const double max)
4038 
4039 {
4040 
4041  int sz=0;
4042  int i=0;
4043  double* pt=NULL;
4044 
4045  check_nomsg(sz=cpl_table_get_nrow(*t));
4046  check_nomsg(pt=cpl_table_get_data_double(*t,c));
4047  for(i=0;i<sz;i++) {
4048  if(pt[i] < min || pt[i] > max) {
4049  check_nomsg(cpl_table_set_invalid(*t ,c,i));
4050  }
4051  }
4052 
4053  return 0;
4054 
4055  cleanup:
4056 
4057  return -1;
4058 
4059 
4060 }
4061 
4071 static int
4072 sinfo_table_flag_nan(cpl_table** t,const char* label)
4073 {
4074 
4075  int sz=0;
4076  int i=0;
4077  double* pt=NULL;
4078 
4079  check_nomsg(sz=cpl_table_get_nrow(*t));
4080  check_nomsg(pt=cpl_table_get_data_double(*t,label));
4081  for(i=0;i<sz;i++) {
4082  if(irplib_isnan(pt[i])) {
4083  check_nomsg(cpl_table_set_invalid(*t ,label,i));
4084  }
4085  }
4086 
4087  return 0;
4088 
4089  cleanup:
4090 
4091  return -1;
4092 }
4093 
4103 static int
4104 sinfo_table_sky_obj_flag_nan(cpl_table** s,cpl_table** o, cpl_table** w)
4105 {
4106 
4107  int no=0;
4108  int ns=0;
4109  int nw=0;
4110  int ni=0;
4111 
4112  int i=0;
4113  double* po=NULL;
4114  double* ps=NULL;
4115  double* pw=NULL;
4116 
4117  check_nomsg(no=cpl_table_get_nrow(*o));
4118  check_nomsg(ns=cpl_table_get_nrow(*s));
4119  check_nomsg(nw=cpl_table_get_nrow(*w));
4120  if(no != ns || ns != nw || no != nw) {
4121  sinfo_msg_error("different input tables sizes");
4122  goto cleanup;
4123  }
4124  check_nomsg(po=cpl_table_get_data_double(*o,"INT"));
4125  check_nomsg(ps=cpl_table_get_data_double(*s,"INT"));
4126  check_nomsg(pw=cpl_table_get_data_double(*w,"WAVE"));
4127 
4128  for(i=0;i<no;i++) {
4129  if( (0==cpl_table_is_valid(*o,"INT",i)) ||
4130  irplib_isnan(po[i]) || irplib_isnan(ps[i]) || irplib_isnan(pw[i]) ) {
4131  check_nomsg(cpl_table_set_invalid(*o ,"INT",i));
4132  check_nomsg(cpl_table_set_invalid(*s ,"INT",i));
4133  check_nomsg(cpl_table_set_invalid(*w ,"WAVE",i));
4134  //sinfo_msg_debug("Flagged raw %d",i);
4135  ni++;
4136  }
4137  }
4138 
4139  return no-ni;
4140 
4141  cleanup:
4142 
4143  return -1;
4144 }
4145 
4146 /*
4147 static void
4148 sinfo_shift_sky(const int x,const int y)
4149 {
4150 
4151  //To remove compilation warnings
4152  ck0_nomsg(x);
4153  ck0_nomsg(y);
4154 
4155  // shift sky spectrum of a given amount
4156  if (max(abs(z_fit))/cdelts < 0.01) {
4157  sinfo_msg("shift <0.01 pixels will not be applied");
4158  } else {
4159  sinfo_msg("shifting sky cube by mean of %f pix wrt object",
4160  cpl_table_column_mean(z_fit,"VALUE")/cdelto);
4161  sinfo_msg("this will take a couple of minutes...");
4162  z_good = where(finite(int_sky));
4163  new_sky = spline(lambda[z_good]-z_mean,int_sky[z_good],lambda);
4164  int_sky = new_sky;
4165  sky_out = dblarr(xsize,ysize,zsize) + !values.f_nan;
4166  for (ix=0; ix<xsize;ix++) {
4167  for (iy=0;iy<ysize;iy++) {
4168  old_sky = reform(sky[ix,iy,*]);
4169  z_good = where(finite(old_sky),z_good_i);
4170  if (z_good_i > 0) {
4171  new_sky= spline(lambda[z_good]-z_fit[z_good],old_sky[z_good],lambda);
4172  new_fin= where(finite(new_sky,/infinity) ||
4173  finite(old_sky,/nan),newfin_i);
4174  if (new_fin_i > 0) new_sky[new_fin] = !values.f_nan;
4175  sky_out[ix,iy,*] = new_sky;
4176  }
4177  }
4178  }
4179  sky = sky_out;
4180  }
4181  cleanup:
4182  return;
4183 
4184 }
4185  */
4212 void
4213 sinfo_optimise_sky_sub(const double wtol,
4214  const double line_hw,
4215  const int method,
4216  const int do_rot,
4217  cpl_table* lrange,
4218  cpl_table* lambda,
4219  cpl_table* lr41,
4220  cpl_table* lr52,
4221  cpl_table* lr63,
4222  cpl_table* lr74,
4223  cpl_table* lr02,
4224  cpl_table* lr85,
4225  cpl_table* lr20,
4226  cpl_table* lr31,
4227  cpl_table* lr42,
4228  cpl_table* lr53,
4229  cpl_table* lr64,
4230  cpl_table* lr75,
4231  cpl_table* lr86,
4232  cpl_table* lr97,
4233  cpl_table* lr00,
4234  cpl_table** int_obj,
4235  cpl_table** int_sky,
4236  cpl_table** rscale)
4237 
4238 {
4239 
4240  int npixw=2*line_hw; //full width in pixels of unresolved emission line
4241  cpl_array* do_hk=NULL;
4242  cpl_array* rfit=NULL;
4243  int i=0;
4244  cpl_table* sky_lr=NULL;
4245  cpl_table* obj_lr=NULL;
4246  cpl_table* wav_lr=NULL;
4247  double sky_med=0;
4248  double sky_sdv=0;
4249  int lr41_i=0;
4250  int lr52_i=0;
4251  int lr63_i=0;
4252  int lr74_i=0;
4253  int lr02_i=0;
4254  int lr85_i=0;
4255  int lr20_i=0;
4256  int lr31_i=0;
4257  int lr42_i=0;
4258  int lr53_i=0;
4259  int lr64_i=0;
4260  int lr75_i=0;
4261  int lr86_i=0;
4262  int lr97_i=0;
4263  int lr00_i=0;
4264 
4265  int xxx1_i=0;
4266  int status=0;
4267  int finite_pix_i=0;
4268  double sky_thresh=0.;
4269 
4270  cpl_table* rat_sky=NULL;
4271 
4272  cpl_table* xxx1=NULL;
4273  cpl_table* xxx2=NULL;
4274  cpl_table* xxx1_sub=NULL;
4275  cpl_table* line_regions=NULL;
4276  cpl_table* cont_regions=NULL;
4277  int line_i=0;
4278  int cont_i=0;
4279  double fmed=0;
4280  double fsdv=0;
4281  cpl_table* fline_res=NULL;
4282  int fclip_i=0;
4283  int fline_i=0;
4284  cpl_table* rscale0=NULL;
4285  double r=0;
4286  cpl_table* obj_cont=NULL;
4287  cpl_table* sky_cont=NULL;
4288  cpl_table* obj_line=NULL;
4289  cpl_table* sky_line=NULL;
4290 
4291 
4292  //Rotational parameters
4293  int low_pos_i=0;
4294  int med_pos_i=0;
4295  int hi_pos_i=0;
4296 
4297  cpl_table* finite_pix=NULL;
4298  cpl_table* tmp_tbl=NULL;
4299 
4300  cpl_table* low_scale=NULL;
4301  cpl_table* med_scale=NULL;
4302  cpl_table* hi_regions=NULL;
4303 
4304  cpl_table* low_regions=NULL;
4305  cpl_table* med_regions=NULL;
4306 
4307 
4308  cpl_table* low_pos=NULL;
4309  cpl_table* med_pos=NULL;
4310  cpl_table* hi_pos=NULL;
4311  cpl_table* llr_xxx1=NULL;
4312 
4313  double rhi=0;
4314  double rmed=0;
4315  double rlow=0;
4316 
4317  double min_lrange=0;
4318  double max_lrange=0;
4319 
4320  int nrow=0;
4321 
4322 
4323  double w_rot_low[NROT]={1.00852,1.03757,1.09264,1.15388,1.22293,
4324  1.30216,1.45190,1.52410,1.60308,1.69037,
4325  1.78803,2.02758,2.18023,1.02895,1.08343,
4326  1.14399,1.21226,1.29057,1.43444,1.50555,
4327  1.58333,1.66924,1.76532,2.00082,2.15073};
4328 
4329 
4330  double w_rot_med[NROT]={1.00282,1.02139,1.04212,1.07539,1.09753,
4331  1.13542,1.15917,1.20309,1.22870,1.28070,
4332  1.30853,1.41861,1.46048,1.48877,1.53324,
4333  1.56550,1.61286,1.65024,1.70088,1.74500,
4334  1.79940,1.97719,2.04127,2.12496,2.19956};
4335 
4336 
4337 
4338  check_nomsg(do_hk = cpl_array_new(NBOUND+1,CPL_TYPE_INT));
4339  check_nomsg(rfit = cpl_array_new(NBOUND+1,CPL_TYPE_DOUBLE));
4340 
4341  lr41_i=cpl_table_get_nrow(lr41);
4342  lr52_i=cpl_table_get_nrow(lr52);
4343  lr63_i=cpl_table_get_nrow(lr63);
4344  lr74_i=cpl_table_get_nrow(lr74);
4345  lr02_i=cpl_table_get_nrow(lr02);
4346  lr85_i=cpl_table_get_nrow(lr85);
4347  lr20_i=cpl_table_get_nrow(lr20);
4348  lr31_i=cpl_table_get_nrow(lr31);
4349  lr42_i=cpl_table_get_nrow(lr42);
4350  lr53_i=cpl_table_get_nrow(lr53);
4351  lr64_i=cpl_table_get_nrow(lr64);
4352  lr75_i=cpl_table_get_nrow(lr75);
4353  lr86_i=cpl_table_get_nrow(lr86);
4354  lr97_i=cpl_table_get_nrow(lr97);
4355  check_nomsg(lr00_i=cpl_table_get_nrow(lr00));
4356 
4357  cpl_array_set_int(do_hk,0,lr41_i);
4358  cpl_array_set_int(do_hk,1,lr52_i);
4359  cpl_array_set_int(do_hk,2,lr63_i);
4360  cpl_array_set_int(do_hk,3,lr74_i);
4361  cpl_array_set_int(do_hk,4,lr02_i);
4362  cpl_array_set_int(do_hk,5,lr85_i);
4363  cpl_array_set_int(do_hk,6,lr20_i);
4364  cpl_array_set_int(do_hk,7,lr31_i);
4365  cpl_array_set_int(do_hk,8,lr42_i);
4366  cpl_array_set_int(do_hk,9,lr53_i);
4367  cpl_array_set_int(do_hk,10,lr64_i);
4368  cpl_array_set_int(do_hk,11,lr75_i);
4369  cpl_array_set_int(do_hk,12,lr86_i);
4370  cpl_array_set_int(do_hk,13,lr97_i);
4371  check_nomsg(cpl_array_set_int(do_hk,14,lr00_i));
4372 
4373  check_nomsg(rscale0=cpl_table_duplicate(*int_sky));
4374  check_nomsg(cpl_table_new_column(rscale0,"RATIO",CPL_TYPE_DOUBLE));
4375  check_nomsg(nrow=cpl_table_get_nrow(rscale0));
4376  check_nomsg(cpl_table_fill_column_window(rscale0,"RATIO",0,nrow,0));
4377 
4378  // For each range extract proper: obj, sky, wave spectra
4379  for (i=0;i<NBOUND+1;i++) {
4380  if (cpl_array_get_int(do_hk,i,&status) > 0) {
4381 
4382 
4383  switch(i) {
4384 
4385 
4386  case 0:
4387  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr41,wtol,
4388  &obj_lr,&sky_lr,&wav_lr));
4389  break;
4390 
4391  case 1:
4392  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr52,wtol,
4393  &obj_lr,&sky_lr,&wav_lr));
4394  break;
4395 
4396  case 2:
4397  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr63,wtol,
4398  &obj_lr,&sky_lr,&wav_lr));
4399  break;
4400 
4401  case 3:
4402  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr74,wtol,
4403  &obj_lr,&sky_lr,&wav_lr));
4404  break;
4405 
4406  case 4:
4407  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr02,wtol,
4408  &obj_lr,&sky_lr,&wav_lr));
4409  break;
4410 
4411  case 5:
4412  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr85,wtol,
4413  &obj_lr,&sky_lr,&wav_lr));
4414  break;
4415  case 6:
4416  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr20,wtol,
4417  &obj_lr,&sky_lr,&wav_lr));
4418  break;
4419  case 7:
4420  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr31,wtol,
4421  &obj_lr,&sky_lr,&wav_lr));
4422  break;
4423  case 8:
4424  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr42,wtol,
4425  &obj_lr,&sky_lr,&wav_lr));
4426  break;
4427  case 9:
4428  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr53,wtol,
4429  &obj_lr,&sky_lr,&wav_lr));
4430  break;
4431  case 10:
4432  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr64,wtol,
4433  &obj_lr,&sky_lr,&wav_lr));
4434  break;
4435  case 11:
4436  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr75,wtol,
4437  &obj_lr,&sky_lr,&wav_lr));
4438  break;
4439  case 12:
4440  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr86,wtol,
4441  &obj_lr,&sky_lr,&wav_lr));
4442  break;
4443  case 13:
4444  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr97,wtol,
4445  &obj_lr,&sky_lr,&wav_lr));
4446  break;
4447  case 14:
4448  ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr00,
4449  wtol,&obj_lr,&sky_lr,&wav_lr));
4450  break;
4451  default:
4452  sinfo_msg_error("case not supported");
4453  goto cleanup;
4454  }
4455  if(sky_lr == NULL || obj_lr == NULL || wav_lr == NULL) {
4456  finite_pix_i=0;
4457  sinfo_msg("no good pix left");
4458  } else {
4459  //AMO: the following 2 seems to be critical for robustness
4460  //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,"out_skylr0.fits",
4461  // CPL_IO_DEFAULT));
4462  //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,"out_objlr0.fits",
4463  // CPL_IO_DEFAULT));
4464  //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,"out_wavlr0.fits",
4465  // CPL_IO_DEFAULT));
4466 
4467 
4468 
4469  check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(&sky_lr,
4470  &obj_lr,
4471  &wav_lr));
4472 
4473 
4474  }
4475 
4476 
4477  if (finite_pix_i > npixw) {
4478  // identify sky lines
4479  //sinfo_msg("finite_pix_i=%d",finite_pix_i);
4480  check_nomsg(cpl_table_erase_invalid(obj_lr));
4481  check_nomsg(cpl_table_erase_invalid(sky_lr));
4482  check_nomsg(cpl_table_erase_invalid(wav_lr));
4483 
4484 
4485  check_nomsg(sky_med=cpl_table_get_column_median(sky_lr,"INT"));
4486  check_nomsg(sky_sdv=cpl_table_get_column_stdev(sky_lr,"INT"));
4487  check_nomsg(cpl_table_select_all(sky_lr));
4488  sky_thresh=sky_med+sky_sdv;
4489  //sinfo_msg("sky_thresh=%f",sky_thresh);
4490  check_nomsg(xxx1_i=cpl_table_and_selected_double(sky_lr,"INT",
4491  CPL_GREATER_THAN,sky_thresh));
4492  check_nomsg(xxx1 = cpl_table_extract_selected(sky_lr));
4493  check_nomsg(cpl_table_select_all(sky_lr));
4494 
4495  if (xxx1_i > 0) {
4496  //separate line and continuum regions
4497  //by convolving with a hat region of large as a line
4498  //sinfo_msg("xxx1_i=%d",xxx1_i);
4499  check_nomsg(xxx2 = cpl_table_duplicate(sky_lr));
4500  //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,
4501  // "out_skylr.fits",CPL_IO_DEFAULT));
4502  //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
4503  // "out_objlr.fits",CPL_IO_DEFAULT));
4504  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4505  // "out_xxx2_0.fits",CPL_IO_DEFAULT));
4506  ck0_nomsg(sinfo_table_threshold(&xxx2,"INT",sky_thresh,
4507  sky_thresh,0.,10.));
4508  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4509  // "out_xxx2_1.fits",CPL_IO_DEFAULT));
4510 
4511 
4512  /* TODO
4513  xxx2[xxx1] = 10.;
4514  */
4515  //sinfo_msg("npixw/2=%d",npixw);
4516  check_nomsg(sinfo_convolve_kernel(&xxx2,npixw/2));
4517  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4518  // "out_xxx2_2.fits",CPL_IO_DEFAULT));
4519 
4520  // get line_regions
4521  check_nomsg(line_i=cpl_table_and_selected_double(xxx2,"CNV",
4522  CPL_GREATER_THAN,0));
4523 
4524  check_nomsg(line_regions=cpl_table_extract_selected(xxx2));
4525 
4526  //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
4527  //"out_line_regions.fits",CPL_IO_DEFAULT));
4528 
4529  check_nomsg(cpl_table_erase_column(line_regions,"INT"));
4530  check_nomsg(cpl_table_erase_column(line_regions,"CNV"));
4531 
4532  check_nomsg(cpl_table_select_all(xxx2));
4533 
4534  // get cont_regions
4535  check_nomsg(cont_i=cpl_table_and_selected_double(xxx2,"CNV",
4536  CPL_EQUAL_TO,0));
4537  check_nomsg(cont_regions=cpl_table_extract_selected(xxx2));
4538 
4539  //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
4540  //"out_cont_regions.fits",CPL_IO_DEFAULT));
4541 
4542  check_nomsg(cpl_table_erase_column(cont_regions,"INT"));
4543  check_nomsg(cpl_table_erase_column(cont_regions,"CNV"));
4544  check_nomsg(cpl_table_select_all(xxx2));
4545  sinfo_free_table(&xxx2);
4546 
4547 
4548  if (line_i >= 3 && cont_i >= 3) {
4549  //If we have enough line points and continuum points
4550  //sinfo_msg("line_i=%d cont_i=%d",line_i,cont_i);
4551  if (i == 0) sinfo_msg("optimising 4-1 transitions");
4552  if (i == 1) sinfo_msg("optimising 5-2 transitions");
4553  if (i == 2) sinfo_msg("optimising 6-3 transitions");
4554  if (i == 3) sinfo_msg("optimising 7-4 transitions");
4555  if (i == 4) sinfo_msg("optimising 0-2 transitions");
4556  if (i == 5) sinfo_msg("optimising 8-5 transitions");
4557  if (i == 6) sinfo_msg("optimising 2-0 transitions");
4558  if (i == 7) sinfo_msg("optimising 3-1 transitions");
4559  if (i == 8) sinfo_msg("optimising 4-2 transitions");
4560  if (i == 9) sinfo_msg("optimising 5-3 transitions");
4561  if (i == 10) sinfo_msg("optimising 6-4 transitions");
4562  if (i == 11) sinfo_msg("optimising 7-5 transitions");
4563  if (i == 12) sinfo_msg("optimising 8-6 transitions");
4564  if (i == 13) sinfo_msg("optimising 9-7 transitions");
4565  if (i == 14) sinfo_msg("optimising final bit");
4566  // Fit the object profile='fline_res' of the sky line residuals
4567  // left after proper scaled sky spectrum lines (and continua)
4568  // subtraction. Then determines median and stdev to flag outliers
4569 
4570  //Free memory for each loop
4571  sinfo_free_table(&obj_cont);
4572  sinfo_free_table(&sky_cont);
4573  sinfo_free_table(&sky_line);
4574  sinfo_free_table(&obj_line);
4575  //Identify obj lines and continuum, same for sky
4576  cknull_nomsg(obj_line=sinfo_table_select_range(obj_lr,line_regions,
4577  wtol));
4578 
4579 
4580  cknull_nomsg(sky_line=sinfo_table_select_range(sky_lr,line_regions,
4581  wtol));
4582  cknull_nomsg(obj_cont=sinfo_table_select_range(obj_lr,cont_regions,
4583  wtol));
4584  cknull_nomsg(sky_cont=sinfo_table_select_range(sky_lr,cont_regions,
4585  wtol));
4586 
4587  //Here was commented
4588  //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
4589  // "out_line.fits",CPL_IO_DEFAULT));
4590  //check_nomsg(cpl_table_save(cont_regions,NULL,NULL,
4591  // "out_cont.fits",CPL_IO_DEFAULT));
4592  //check_nomsg(cpl_table_save(obj_cont,NULL,NULL,
4593  // "out_obj_cont.fits",CPL_IO_DEFAULT));
4594  //check_nomsg(cpl_table_save(obj_line,NULL,NULL,
4595  // "out_obj_line.fits",CPL_IO_DEFAULT));
4596  //check_nomsg(cpl_table_save(sky_line,NULL,NULL,
4597  // "out_sky_line.fits",CPL_IO_DEFAULT));
4598  //check_nomsg(cpl_table_save(sky_cont,NULL,NULL,
4599  // "out_sky_cont.fits",CPL_IO_DEFAULT));
4600 
4601 
4602  sinfo_free_table(&fline_res);
4603  //FIXME: in some cases obj_cont is empty
4604  //sinfo_msg("first line ratio determination");
4605  ck0_nomsg(sinfo_get_line_ratio(obj_line,obj_cont,
4606  sky_line,sky_cont,method,&r));
4607  sinfo_msg("1st Line ratio %g",r);
4608 
4609 
4610  if(cpl_table_get_nrow(obj_cont) > 0) {
4611  check_nomsg(fline_res=sinfo_table_interpol(obj_line,obj_cont,
4612  sky_line,sky_cont,
4613  r));
4614  } else {
4615  check_nomsg(fline_res=cpl_table_duplicate(obj_line));
4616  }
4617 
4618  // check if there are outliers
4619  cpl_table_select_all(fline_res);
4620  check_nomsg(fmed = cpl_table_get_column_median(fline_res,"INT"));
4621  check_nomsg(fsdv = cpl_table_get_column_stdev(fline_res,"INT"));
4622 
4623  check_nomsg(cpl_table_duplicate_column(fline_res,"AINT",
4624  fline_res,"INT"));
4625  check_nomsg(cpl_table_multiply_columns(fline_res,"AINT","INT"));
4626  check_nomsg(cpl_table_power_column(fline_res,"AINT",0.5));
4627  check_nomsg(fclip_i=cpl_table_and_selected_double(fline_res,"AINT",
4628  CPL_GREATER_THAN,
4629  fmed+3*fsdv));
4630 
4631  check_nomsg(cpl_table_select_all(fline_res));
4632 
4633 
4634  if (fclip_i > 0) {
4635  // do a k-sigma clip to select a better line region
4636  //sinfo_msg("fclip_i=%d",fclip_i);
4637  //Find again line_regions
4638  check_nomsg(line_i=cpl_table_and_selected_double(fline_res,
4639  "AINT",
4640  CPL_NOT_GREATER_THAN,
4641  fmed+3*fsdv));
4642  // get new (better) line_regions
4643  sinfo_free_table(&line_regions);
4644  //sinfo_msg("line_i=%d",line_i);
4645  check_nomsg(line_regions=cpl_table_extract_selected(fline_res));
4646  check_nomsg(cpl_table_erase_column(line_regions,"INT"));
4647  check_nomsg(cpl_table_erase_column(line_regions,"AINT"));
4648 
4649  sinfo_free_table(&obj_line);
4650  sinfo_free_table(&sky_line);
4651 
4652  //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
4653  // "out_obj_lr.fits",CPL_IO_DEFAULT));
4654  //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
4655  // "out_line_regions.fits",
4656  // CPL_IO_DEFAULT));
4657 
4658 
4659 
4660 
4661  // The following 2 may return an error so we do not check and
4662  // later we reset the error
4663  obj_line=sinfo_table_select_range(obj_lr,line_regions,wtol);
4664  sky_line=sinfo_table_select_range(sky_lr,line_regions,wtol);
4665  fline_i=cpl_table_get_nrow(line_regions);
4666 
4667  //sinfo_msg("fline_i=%d",fline_i);
4668  if(fline_i>=3) {
4669  // repeat the determination of the line ratio
4670  //sinfo_msg("second line ratio determination");
4671  ck0_nomsg(sinfo_get_line_ratio(obj_line,obj_cont,
4672  sky_line,sky_cont,method,&r));
4673 
4674  sinfo_msg("2nd Line ratio %g",r);
4675 
4676  } else {
4677  cpl_error_reset();
4678  }
4679 
4680  sinfo_free_table(&sky_line);
4681  sinfo_free_table(&obj_line);
4682  }
4683 
4684  cpl_msg_info(cpl_func,"use %" CPL_SIZE_FORMAT
4685  " pixels for line and %" CPL_SIZE_FORMAT
4686  " for continuum estimation",
4687  cpl_table_get_nrow(line_regions),cpl_table_get_nrow(cont_regions));
4688 
4689  sinfo_msg("OH spectrum scaling = %f ",r);
4690  check_nomsg(cpl_array_set_double(rfit,i,r));
4691  ck0_nomsg(sinfo_table_set(&rscale0,wav_lr,r,wtol));
4692 
4693  } /* end if line_i */
4694  } /* end if xxx1_i */
4695  } /* end finite_pix_i */
4696 
4697  }
4698 
4699  sinfo_free_table(&xxx1);
4700  sinfo_free_table(&xxx2);
4701  sinfo_free_table(&sky_lr);
4702  sinfo_free_table(&obj_lr);
4703  sinfo_free_table(&wav_lr);
4704 
4705  sinfo_free_table(&line_regions);
4706  sinfo_free_table(&cont_regions);
4707 
4708  } /* end for loop on i */
4709 
4710  sinfo_free_array(&do_hk);
4711  sinfo_free_array(&rfit);
4712 
4713  //sinfo_msg("n scale=%d",cpl_table_get_nrow(rscale0));
4714  //check_nomsg(cpl_table_save(rscale0,NULL,NULL,
4715  // "out_rscale0.fits",CPL_IO_DEFAULT));
4716 
4717  check_nomsg(cpl_table_select_all(rscale0));
4718  /* TODO: here one has to implementa an interpol function
4719  check_nomsg(range0_i=cpl_table_and_selected_double(rscale0,"RATIO",
4720  CPL_NOT_EQUAL_TO,0));
4721  */
4722  check_nomsg(*rscale = cpl_table_extract_selected(rscale0));
4723  sinfo_free_table(&rscale0);
4724 
4725 
4726  check_nomsg(rat_sky=cpl_table_duplicate(*int_sky));
4727  check_nomsg(cpl_table_duplicate_column(rat_sky,"RATIO",*rscale,"RATIO"));
4728  check_nomsg(cpl_table_duplicate_column(*int_obj,"COR_FCT_VIB",
4729  *rscale,"RATIO"));
4730  //check_nomsg(cpl_table_save(rat_sky,NULL,NULL,
4731  // "rat_sky0.fits",CPL_IO_DEFAULT));
4732  check_nomsg(cpl_table_multiply_columns(rat_sky,"INT","RATIO"));
4733 
4734 
4735  //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
4736  // "out_obj0.fits",CPL_IO_DEFAULT));
4737  //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
4738  // "out_sky0.fits",CPL_IO_DEFAULT));
4739 
4740  /*
4741  check_nomsg(cpl_table_duplicate_column(*int_obj,"INTC",*int_obj,"INT"));
4742  check_nomsg(cpl_table_duplicate_column(*int_obj,"SKYC",*int_sky,"INTC"));
4743  check_nomsg(cpl_table_subtract_columns(*int_obj,"INTC","SKYC"));
4744  */
4745 
4746  // do simple rotational correction
4747  if (do_rot == 1) {
4748 
4749  //finite_pix = where(finite(int_sky) && finite(int_obj),finite_pix_i);
4750  check_nomsg(min_lrange=cpl_table_get_column_min(lrange,"WAVE"));
4751  check_nomsg(max_lrange=cpl_table_get_column_max(lrange,"WAVE"));
4752  //sinfo_msg("min_lrange=%g max_lrange=%g",min_lrange,max_lrange);
4753  //check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(&rat_sky,
4754  // int_obj,
4755  // &lambda));
4756  check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(int_sky,
4757  int_obj,
4758  &lambda));
4759 
4760 
4761  check_nomsg(finite_pix=cpl_table_duplicate(lambda));
4762  //TODO: lambda invalid values need to be reset to valid (?)
4763 
4764  check_nomsg(cpl_table_erase_invalid(finite_pix));
4765 
4766 
4767  if (finite_pix_i > npixw) {
4768 
4769  //finite_pix = finite_pix[where(finite_pix > min(lrange) &&
4770  // finite_pix < max(lrange))];
4771 
4772  check_nomsg(cpl_table_and_selected_double(finite_pix,"WAVE",
4773  CPL_GREATER_THAN,
4774  min_lrange));
4775 
4776  check_nomsg(cpl_table_and_selected_double(finite_pix,"WAVE",
4777  CPL_LESS_THAN,
4778  max_lrange));
4779 
4780 
4781 
4782  check_nomsg(tmp_tbl=cpl_table_extract_selected(finite_pix));
4783  sinfo_free_table(&finite_pix);
4784  check_nomsg(finite_pix=cpl_table_duplicate(tmp_tbl));
4785  sinfo_free_table(&tmp_tbl);
4786  sinfo_free_table(&sky_lr);
4787  sinfo_free_table(&obj_lr);
4788  sinfo_free_table(&wav_lr);
4789 
4790 
4791  cknull(sky_lr=sinfo_table_select_range(rat_sky,finite_pix,wtol),
4792  "extracting sky sub range");
4793  cknull(obj_lr=sinfo_table_select_range(*int_obj,finite_pix,wtol),
4794  "extracting obj sub range");
4795  cknull(wav_lr=sinfo_table_select_range(lambda,finite_pix,wtol),
4796  "extracting sky sub range");
4797 
4798 
4799  //check_nomsg(cpl_table_save(rat_sky,NULL,NULL,
4800  // "out_rat_sky.fits",CPL_IO_DEFAULT));
4801  //check_nomsg(cpl_table_save(finite_pix,NULL,NULL,
4802  // "out_finite_pix.fits",CPL_IO_DEFAULT));
4803  //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,
4804  // "out_sky_lr.fits",CPL_IO_DEFAULT));
4805  //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
4806  // "out_obj_lr.fits",CPL_IO_DEFAULT));
4807  //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,
4808  // "out_wav_lr.fits",CPL_IO_DEFAULT));
4809 
4810  //The following may fail (sky_lr may be empty) so we do not check
4811  if(1 == cpl_table_has_valid(sky_lr,"INT")) {
4812  check_nomsg(sky_med=cpl_table_get_column_median(sky_lr,"INT"));
4813  check_nomsg(sky_sdv=cpl_table_get_column_stdev(sky_lr,"INT"));
4814  sky_thresh=sky_med+sky_sdv;
4815  //xxx1 = where(sky_lr > median(sky_lr)+stddev(sky_lr),xxx1_i);
4816  check_nomsg(xxx1_i=cpl_table_and_selected_double(sky_lr,"INT",
4817  CPL_GREATER_THAN,sky_thresh));
4818  check_nomsg(xxx1=cpl_table_extract_selected(sky_lr));
4819  check_nomsg(cpl_table_select_all(sky_lr));
4820  } else {
4821  xxx1_i=0;
4822  }
4823  if (xxx1_i > 0) {
4824  sinfo_msg("xxx1_i=%d",xxx1_i);
4825 
4826  sinfo_msg("wav_lr wmin=%g wmax=%g",
4827  cpl_table_get_column_min(wav_lr,"WAVE"),
4828  cpl_table_get_column_max(wav_lr,"WAVE"));
4829 
4830  cknull_nomsg(llr_xxx1=sinfo_table_select_range(wav_lr,xxx1,wtol));
4831  //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,
4832  // "out_llr_xxx1.fits",CPL_IO_DEFAULT));
4833 
4834  cknull(low_pos=sinfo_find_rot_waves(w_rot_low,npixw,wtol,llr_xxx1),
4835  "Determining low positions");
4836 
4837 
4838  check_nomsg(low_pos_i=cpl_table_get_nrow(low_pos));
4839  //check_nomsg(cpl_table_dump(low_pos,0,low_pos_i,stdout));
4840  cknull(med_pos=sinfo_find_rot_waves(w_rot_med,npixw,wtol,llr_xxx1),
4841  "Determining med positions");
4842  check_nomsg(med_pos_i=cpl_table_get_nrow(med_pos));
4843 
4844 
4845  //check_nomsg(cpl_table_dump(med_pos,0,med_pos_i,stdout));
4846 
4847  //TODO:
4848  //hipos = [0]
4849  //for i=0,n_elements(xxx1)-1 do begin
4850  // x1 = where(lowpos eq i,x1_i)
4851  // x2 = where(medpos eq i,x2_i)
4852  // if (x1_i eq 0 and x2_i eq 0) then hipos = [hipos,i]
4853  //endfor
4854  //hipos = hipos[1:n_elements(hipos)-1]
4855  //TODO: hi_pos=sinfo_find_rot_waves(w_rot_hi,npixw,wtol,wav_lr);
4856 
4857 
4858  cknull(hi_pos=sinfo_table_extract_rest(xxx1,low_pos,med_pos,wtol),
4859  "determining hi position");
4860  check_nomsg(hi_pos_i=cpl_table_get_nrow(hi_pos));
4861  //check_nomsg(cpl_table_dump(hi_pos,0,hi_pos_i,stdout));
4862 
4863 
4864  //xxx2[xxx1] = 10.;
4865  check_nomsg(xxx2 = cpl_table_duplicate(sky_lr));
4866  check_nomsg(nrow=cpl_table_get_nrow(sky_lr));
4867  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4868  // "out_xxx1.fits",CPL_IO_DEFAULT));
4869  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4870  // "out_xxx2_0.fits",CPL_IO_DEFAULT));
4871 
4872  // AMO: Why the following?
4873  //check_nomsg(cpl_table_fill_column_window(xxx2,"INT",0,nrow,0));
4874 
4875  //xxx2 = convol(xxx2,replicate(1,npixw),/edge_truncate,/center);
4876  //cont_regions = where(xxx2 == 0,cont_i);
4877  ck0_nomsg(sinfo_table_threshold(&xxx2,"INT",sky_thresh,
4878  sky_thresh,0.,10.));
4879  sinfo_msg("sky_thresh=%g %g %f",sky_thresh,sky_med,sky_sdv);
4880  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4881  // "out_xxx2_1.fits",CPL_IO_DEFAULT));
4882  check_nomsg(sinfo_convolve_kernel(&xxx2,npixw/2));
4883 
4884  //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
4885  // "out_xxx2_2.fits",CPL_IO_DEFAULT));
4886  check_nomsg(cont_i=cpl_table_and_selected_double(xxx2,"CNV",
4887  CPL_EQUAL_TO,0));
4888  check_nomsg(cont_regions=cpl_table_extract_selected(xxx2));
4889 
4890  sinfo_free_table(&xxx2);
4891  check_nomsg(cpl_table_erase_column(cont_regions,"INT"));
4892  check_nomsg(cpl_table_erase_column(cont_regions,"CNV"));
4893 
4894  check(low_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,low_pos,wtol,
4895  npixw,&low_regions),"failed determining low regions");
4896 
4897  check(med_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,med_pos,wtol,
4898  npixw,&med_regions),"failed determining med regions");
4899 
4900 
4901  check(hi_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,hi_pos,wtol,
4902  npixw,&hi_regions),"failed determining hi regions");
4903  /*
4904  sinfo_msg("xxx1: wmin=%g wmax=%g",
4905  cpl_table_get_column_min(xxx1,"WAVE"),
4906  cpl_table_get_column_max(xxx1,"WAVE"));
4907 
4908  sinfo_msg("low_pos: wmin=%g wmax=%g",
4909  cpl_table_get_column_min(low_pos,"WAVE"),
4910  cpl_table_get_column_max(low_pos,"WAVE"));
4911  */
4912  sinfo_msg("hi_pos_i : %d med_pos_i : %d low_pos_i : %d cont_i: %d",
4913  hi_pos_i, med_pos_i, low_pos_i, cont_i);
4914 
4915 
4916  if (hi_pos_i >= 3 && med_pos_i >= 3 && low_pos_i >= 3 && cont_i >= 3) {
4917 
4918  //compute line ratio for hi_regions
4919  ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
4920  hi_regions,cont_regions,&rhi));
4921  sinfo_msg("high rotational OH scaling %g",rhi);
4922 
4923  //compute line ratio for med_regions
4924  ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
4925  med_regions,cont_regions,&rmed));
4926 
4927  sinfo_msg("P1(3.5) & R1(1.5) rotational OH scaling %g ",rmed);
4928 
4929  //compute line ratio for med_regions
4930  ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
4931  low_regions,cont_regions,&rlow));
4932  sinfo_msg("P1(2.5) & Q1(1.5) rotational OH scaling %g",rlow);
4933 
4934  cknull(low_scale=sinfo_find_rot_waves(w_rot_low,npixw,wtol,lambda),
4935  "Determining low scale");
4936 
4937 
4938 
4939  cknull(med_scale=sinfo_find_rot_waves(w_rot_low,npixw,wtol,lambda),
4940  "Determining low scale");
4941  check_nomsg(cpl_table_multiply_scalar(*rscale,"RATIO",rhi));
4942  ck0_nomsg(sinfo_table_fill_column_over_range(rscale,med_scale,
4943  "RATIO",rmed/rhi,wtol));
4944  ck0_nomsg(sinfo_table_fill_column_over_range(rscale,low_scale,
4945  "RATIO",rlow/rhi,wtol));
4946 
4947  }
4948  } //xxx1_i > 0
4949  }//finitepix > npixw
4950  }//do_rot==1
4951  //end of new rotational bit
4952  //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
4953  // "out_obj.fits",CPL_IO_DEFAULT));
4954  //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
4955  // "out_sky.fits",CPL_IO_DEFAULT));
4956 
4957 
4958  check_nomsg(cpl_table_duplicate_column(*int_sky,"INTC",*int_sky,"INT"));
4959  //sinfo_msg("n sky=%d",cpl_table_get_nrow(*int_sky));
4960  //sinfo_msg("n scale=%d",cpl_table_get_nrow(*rscale));
4961 
4962  check_nomsg(cpl_table_duplicate_column(*int_obj,"COR_FCT_ALL",
4963  *rscale,"RATIO"));
4964  check_nomsg(cpl_table_duplicate_column(*int_sky,"RATIO",*rscale,"RATIO"));
4965  check_nomsg(cpl_table_multiply_columns(*int_sky,"INTC","RATIO"));
4966 
4967  check_nomsg(cpl_table_duplicate_column(*int_obj,"INTC",*int_obj,"INT"));
4968  //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
4969  // "out_obj1.fits",CPL_IO_DEFAULT));
4970  //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
4971  // "out_sky1.fits",CPL_IO_DEFAULT));
4972 
4973  check_nomsg(cpl_table_duplicate_column(*int_obj,"SKYC",*int_sky,"INTC"));
4974  check_nomsg(cpl_table_subtract_columns(*int_obj,"INTC","SKYC"));
4975 
4976 
4977  check_nomsg(cpl_table_erase_column(*int_sky,"INT"));
4978  check_nomsg(cpl_table_name_column(*int_sky,"INTC","INT"));
4979 
4980 
4981 
4982  cleanup:
4983  sinfo_free_table(&llr_xxx1);
4984  sinfo_free_table(&hi_pos);
4985  sinfo_free_table(&low_pos);
4986  sinfo_free_table(&med_pos);
4987  sinfo_free_table(&low_regions);
4988  sinfo_free_table(&med_regions);
4989  sinfo_free_table(&hi_regions);
4990  sinfo_free_table(&low_scale);
4991  sinfo_free_table(&med_scale);
4992 
4993 
4994  sinfo_free_table(&finite_pix);
4995  sinfo_free_table(&xxx1_sub);
4996  sinfo_free_table(&tmp_tbl);
4997  sinfo_free_table(&rat_sky);
4998  sinfo_free_table(&fline_res);
4999  sinfo_free_table(&sky_cont);
5000  sinfo_free_table(&obj_cont);
5001  sinfo_free_table(&obj_line);
5002  sinfo_free_table(&sky_line);
5003  sinfo_free_table(&rscale0);
5004  sinfo_free_table(&xxx1);
5005  sinfo_free_table(&xxx2);
5006  sinfo_free_table(&line_regions);
5007  sinfo_free_table(&cont_regions);
5008  sinfo_free_table(&sky_lr);
5009  sinfo_free_table(&obj_lr);
5010  sinfo_free_table(&wav_lr);
5011  sinfo_free_array(&rfit);
5012  sinfo_free_array(&do_hk);
5013  return;
5014 
5015 }
5024 int
5025 sinfo_table_get_index_of_max(cpl_table* t,const char* name,cpl_type type)
5026 {
5027 
5028  int i=0;
5029  int result=0;
5030  int nrow=0;
5031  int* pi=NULL;
5032  float* pf=NULL;
5033  double* pd=NULL;
5034  double max=0;
5035 
5036 
5037  if(t == NULL) {
5038  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
5039  return result;
5040  }
5041  max=cpl_table_get_column_max(t,name);
5042  nrow=cpl_table_get_nrow(t);
5043  switch(type) {
5044 
5045  case CPL_TYPE_INT:
5046  pi=cpl_table_get_data_int(t,name);
5047  for(i=0;i<nrow;i++) {
5048  if(pi[i]==(int)max) result=i;
5049  }
5050  break;
5051  case CPL_TYPE_FLOAT:
5052  pf=cpl_table_get_data_float(t,name);
5053  for(i=0;i<nrow;i++) {
5054  if(pf[i]==(float)max) result=i;
5055  }
5056  break;
5057  case CPL_TYPE_DOUBLE:
5058  pd=cpl_table_get_data_double(t,name);
5059  for(i=0;i<nrow;i++) {
5060  if(pd[i]==max) result=i;
5061  }
5062  break;
5063  default:
5064  sinfo_msg_error("Wrong column type");
5065  cpl_error_set(cpl_func, CPL_ERROR_TYPE_MISMATCH);
5066  return result;
5067 
5068  }
5069  return result;
5070 }
5071 
5072 
5073 
5083 int
5084 sinfo_table_get_index_of_val(cpl_table* t,
5085  const char* name,
5086  double val,
5087  cpl_type type)
5088 {
5089 
5090  int i=0;
5091  int result=0;
5092  int nrow=0;
5093  int* pi=NULL;
5094  float* pf=NULL;
5095  double* pd=NULL;
5096 
5097  if(t == NULL) {
5098  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
5099  return result;
5100  }
5101 
5102  nrow=cpl_table_get_nrow(t);
5103  switch(type) {
5104 
5105  case CPL_TYPE_INT:
5106  pi=cpl_table_get_data_int(t,name);
5107  for(i=0;i<nrow;i++) {
5108  if(pi[i]==(int)val) result=i;
5109  }
5110  break;
5111  case CPL_TYPE_FLOAT:
5112  pf=cpl_table_get_data_float(t,name);
5113  for(i=0;i<nrow;i++) {
5114  if(pf[i]==(float)val) result=i;
5115  }
5116  break;
5117  case CPL_TYPE_DOUBLE:
5118  pd=cpl_table_get_data_double(t,name);
5119  for(i=0;i<nrow;i++) {
5120  if(pd[i]==val) result=i;
5121  }
5122  break;
5123  default:
5124  sinfo_msg_error("Wrong column type");
5125  cpl_error_set(cpl_func, CPL_ERROR_TYPE_MISMATCH);
5126  return result;
5127 
5128  }
5129  return result;
5130 }
5131 
5144 double
5145 sinfo_table_column_interpolate(const cpl_table* t,
5146  const char* name,
5147  const double x)
5148 {
5149 
5150  double val1=0;
5151  double val2=0;
5152  int x1=0;
5153  int x2=0;
5154  double m=0;
5155  double y=0;
5156  int status=0;
5157  int nrow=0;
5158  nrow=cpl_table_get_nrow(t);
5159  if ((1<x) && (x<nrow-1)) {
5160  x1=x-1;
5161  x2=x+1;
5162  } else if (x<2) {
5163  x1=0;
5164  x2=1;
5165  } else {
5166  x1=nrow-2;
5167  x2=nrow-1;
5168  }
5169  check_nomsg(val1=cpl_table_get(t,name,x1,&status));
5170  check_nomsg(val2=cpl_table_get(t,name,x2,&status));
5171 
5172  m=(val2-val1)/(x2-x1);
5173  y=val1+m*(x-x1);
5174 
5175  return y;
5176 
5177  cleanup:
5178 
5179  return -1;
5180 
5181 
5182 }
5183 
5192 static cpl_imagelist*
5193 sinfo_imagelist_select_range(const cpl_imagelist* inp,
5194  const cpl_table* full,
5195  const cpl_table* good,
5196  const double tol)
5197 {
5198  cpl_imagelist* out=NULL;
5199  //int osz=0;
5200  int isz=0;
5201  int ksz=0;
5202  int k=0;
5203  int i=0;
5204  int status=0;
5205 
5206  double wave_chk=0;
5207  double wave_sel=0;
5208 
5209  const cpl_image* img=NULL;
5210 
5211 
5212  /* Get Object relevant information */
5213  /* here one should scan the inp image constructing a wave range from it
5214  and not from another table */
5215  //check_nomsg(osz=cpl_table_get_nrow(good));
5216  check_nomsg(ksz=cpl_imagelist_get_size(inp));
5217  check_nomsg(isz=cpl_table_get_nrow(good));
5218  check_nomsg(out=cpl_imagelist_new());
5219 
5220 
5221  for(k=0;k<ksz;k++) {
5222  check_nomsg(img=cpl_imagelist_get_const(inp,k));
5223  check_nomsg(wave_chk=cpl_table_get(full,"WAVE",k,&status));
5224  if(i<isz) {
5225  check_nomsg(wave_sel=cpl_table_get(good,"WAVE",i,&status));
5226  }
5227  // insert cubes with wavelengths with appropriate values only
5228  if(fabs(wave_chk - wave_sel) < tol) {
5229  check_nomsg(cpl_imagelist_set(out,cpl_image_duplicate(img),i));
5230  i++;
5231  }
5232  }
5233  if(i==0) {
5234  sinfo_msg_error("No lines selected");
5235  goto cleanup;
5236  }
5237  return out;
5238 
5239  cleanup:
5240 
5241  return NULL;
5242 
5243 }
5244 
5254 static int
5255 sinfo_table_extract_finite(const cpl_table* in1,
5256  const cpl_table* in2,
5257  cpl_table** ou1,
5258  cpl_table** ou2)
5259 {
5260 
5261  int size1=0;
5262  int size2=0;
5263  int i=0;
5264  int ninv1=0;
5265  int ninv2=0;
5266  double* pout1=NULL;
5267  //double* pout2=NULL;
5268 
5269  cknull(in1,"null input image");
5270  cknull(in2,"null input image");
5271  cknull_nomsg(*ou1=cpl_table_duplicate(in1));
5272  cknull_nomsg(*ou2=cpl_table_duplicate(in2));
5273 
5274  check_nomsg(size1=cpl_table_get_nrow(*ou1));
5275  check_nomsg(size2=cpl_table_get_nrow(*ou2));
5276 
5277  check_nomsg(pout1=cpl_table_get_data_double(*ou1,"VALUE"));
5278  //check_nomsg(pout2=cpl_table_get_data_double(*ou2,"VALUE"));
5279  for(i=0;i<size1;i++) {
5280  if (irplib_isnan(pout1[i])) {
5281  check_nomsg(cpl_table_set_invalid(*ou1,"VALUE",i));
5282  check_nomsg(cpl_table_set_invalid(*ou2,"VALUE",i));
5283  }
5284  }
5285  ninv1=cpl_table_count_invalid(*ou1,"VALUE");
5286  ninv2=cpl_table_count_invalid(*ou2,"VALUE");
5287  if(ninv1==size1) {
5288  goto cleanup;
5289  }
5290  if(ninv2==size2) {
5291  goto cleanup;
5292  }
5293  check_nomsg(cpl_table_erase_invalid(*ou1));
5294  check_nomsg(cpl_table_erase_invalid(*ou2));
5295  return (size1-ninv1);
5296 
5297  cleanup:
5298  return 0;
5299 
5300 }
5301 
5308 static cpl_table*
5309 sinfo_image2table(const cpl_image* im)
5310 {
5311  cpl_table* out=NULL;
5312  int sx=0;
5313  int sy=0;
5314  const double* pim=NULL;
5315  //double* pval=NULL;
5316  int i=0;
5317  int j=0;
5318  int k=0;
5319 
5320  cknull(im,"input image is NULL");
5321 
5322  check_nomsg(sx=cpl_image_get_size_x(im));
5323  check_nomsg(sy=cpl_image_get_size_y(im));
5324  check_nomsg(pim=cpl_image_get_data_double_const(im));
5325  check_nomsg(out=cpl_table_new(sx*sy));
5326  check_nomsg(cpl_table_new_column(out,"VALUE",CPL_TYPE_DOUBLE));
5327  //check_nomsg(pval=cpl_table_get_data_double(out,"VALUE"));
5328 
5329  for(j=0;j<sy;j++) {
5330  for(i=0;i<sx;i++) {
5331  /*
5332  pval[k++]=pim[j*sx+i];
5333  sinfo_msg("set tab %f",pim[j*sx+i]);
5334  */
5335  cpl_table_set_double(out,"VALUE",k++,pim[j*sx+i]);
5336  }
5337  }
5338 
5339  return out;
5340  cleanup:
5341  sinfo_free_table(&out);
5342  return NULL;
5343 
5344 }
5353 int
5354 sinfo_check_screw_values(cpl_table** int_obj,
5355  cpl_table** int_sky,
5356  cpl_table* grange,
5357  const double wtol)
5358 {
5359  // check for screwy values at ends of spectrum
5360  cpl_table* xsky=NULL;
5361  cpl_table* xobj=NULL;
5362 
5363  double sky_min=0;
5364  double sky_max=0;
5365  double gsky_min=0;
5366  double gsky_max=0;
5367  double obj_min=0;
5368  double obj_max=0;
5369  double gobj_min=0;
5370  double gobj_max=0;
5371 
5372  cknull(*int_sky,"Null input sky spectrum");
5373  cknull(*int_obj,"Null input obj spectrum");
5374  cknull(grange,"Null input wavelength range");
5375  //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
5376  // "out_grange0.fits",CPL_IO_DEFAULT));
5377  cknull_nomsg(xsky=sinfo_table_select_range(*int_sky,grange,wtol));
5378  //check_nomsg(cpl_table_save(xsky,NULL,NULL,
5379  // "out_grange1.fits",CPL_IO_DEFAULT));
5380  check_nomsg(sky_min=cpl_table_get_column_min(xsky,"INT"));
5381  check_nomsg(sky_max=cpl_table_get_column_max(xsky,"INT"));
5382  //sinfo_msg("gskymax=%f gskymin=%f",sky_max,sky_min);
5383 
5384  gsky_max = (sky_max>0) ? sky_max : 0;
5385  gsky_min = (sky_min<0) ? sky_min : 0;
5386  //gsky_pos = where(int_sky > 1.*gsky_max || int_sky < 1.*gsky_min,gskypos_i);
5387  check_nomsg(cpl_table_select_all(*int_sky));
5388  ck0_nomsg(sinfo_table_set_nan_out_min_max(int_sky,"INT",gsky_min,gsky_max));
5389  //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
5390  // "out_gsky_pos.fits",CPL_IO_DEFAULT));
5391 
5392  sinfo_free_table(&xsky);
5393  //sinfo_msg("gsky_min=%f gsky_max=%f",gsky_min,gsky_max);
5394 
5395  cknull_nomsg(xobj=sinfo_table_select_range(*int_obj,grange,wtol));
5396  check_nomsg(obj_min=cpl_table_get_column_min(xobj,"INT"));
5397  check_nomsg(obj_max=cpl_table_get_column_max(xobj,"INT"));
5398  //check_nomsg(cpl_table_save(xobj,NULL,NULL,"out_xobj.fits",CPL_IO_DEFAULT));
5399  gobj_max = (obj_max>0) ? obj_max : 0;
5400  gobj_min = (obj_min<0) ? obj_min : 0;
5401  //gobj_pos=where(int_obj > 1.*gobj_max || int_obj < 1.*gobj_min,gobj_pos_i);
5402  check_nomsg(cpl_table_select_all(*int_obj));
5403  ck0_nomsg(sinfo_table_set_nan_out_min_max(int_obj,"INT",gobj_min,gobj_max));
5404  //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
5405  // "out_gobj_pos.fits",CPL_IO_DEFAULT));
5406  //sinfo_msg("gobj_min=%f gobj_max=%f",gobj_min,gobj_max);
5407  sinfo_free_table(&xobj);
5408 
5409  return 0;
5410  cleanup:
5411  sinfo_free_table(&xsky);
5412  sinfo_free_table(&xobj);
5413 
5414  return -1;
5415 
5416 
5417 }
5418 
5419 
5420 
5430 static int
5431 sinfo_table_fill_column_over_range(cpl_table** inp,
5432  const cpl_table* ref,
5433  const char* col,
5434  const double val,
5435  const double tol)
5436 {
5437 
5438  int i=0;
5439  int k=0;
5440  int nref=0;
5441  int ninp=0;
5442 
5443  double* pwin=NULL;
5444  double* pcin=NULL;
5445  const double* pwrf=NULL;
5446 
5447  cknull(inp,"null input table");
5448  cknull(ref,"null reference table");
5449 
5450  check_nomsg(ninp=cpl_table_get_nrow(*inp));
5451  check_nomsg(nref=cpl_table_get_nrow(ref));
5452  check_nomsg(pwin=cpl_table_get_data_double(*inp,"WAVE"));
5453  check_nomsg(pcin=cpl_table_get_data_double(*inp,col));
5454  check_nomsg(pwrf=cpl_table_get_data_double_const(ref,"WAVE"));
5455 
5456  k=0;
5457  i=0;
5458  /*
5459  sinfo_msg("ninp=%d nref=%d",ninp,nref);
5460  sinfo_msg("winp(0)=%f wref(0)=%f tol=%f diff=%f",
5461  pwin[0],pwrf[0],tol,fabs(pwin[0]-pwrf[0]));
5462  */
5463  if(pwin[0]<=pwrf[0]) {
5464  //sinfo_msg("case 1");
5465  for(i=0;i<ninp;i++) {
5466  if(k<nref) {
5467  /*
5468  sinfo_msg("case1: %f %f %f %f %d %d",
5469  fabs(pwin[i] - pwrf[k]),tol,pwin[i],pwrf[k],i,k);
5470  */
5471  if(fabs(pwin[i] - pwrf[k])< tol) {
5472  pcin[i]=val;
5473  k++;
5474  }
5475  }
5476  }
5477  } else {
5478 
5479  //pwin[0]>pwrf[0]
5480  //sinfo_msg("case 2");
5481  for(k=0;k<nref;k++) {
5482  if(i<ninp) {
5483  /*
5484  sinfo_msg("case2: %f %f %f %f %d %d",
5485  fabs(pwin[i] - pwrf[k]),tol,pwin[i],pwrf[k],i,k);
5486  */
5487  if(fabs(pwin[i] - pwrf[k])< tol) {
5488  pcin[i]=val;
5489  i++;
5490  }
5491  }
5492  }
5493  }
5494 
5495  return 0;
5496 
5497  cleanup:
5498  return -1;
5499 
5500 }
5501 
5502 
5511 static cpl_table*
5512 sinfo_table_select_range(cpl_table* inp, cpl_table* ref,const double tol)
5513 {
5514 
5515  cpl_table* out=NULL;
5516  int ninp=0;
5517  int nref=0;
5518  int nout=0;
5519 
5520  int i=0;
5521  int k=0;
5522  double* pou;
5523  double* prf;
5524  double wmin=0;
5525  double wmax=0;
5526  cpl_table* tmp=NULL;
5527  cknull(inp,"null input table");
5528  cknull(ref,"null reference table");
5529 
5530  check_nomsg(ninp=cpl_table_get_nrow(inp));
5531  check_nomsg(nref=cpl_table_get_nrow(ref));
5532  if(ninp != nref) {
5533  //sinfo_msg_warning("ninp != nref");
5534  check_nomsg(wmin=cpl_table_get_column_min(ref,"WAVE"));
5535  check_nomsg(wmax=cpl_table_get_column_max(ref,"WAVE"));
5536  //sinfo_msg_debug("wmin=%f wmax=%f",wmin,wmax);
5537  cpl_table_select_all(inp);
5538  check_nomsg(ninp=cpl_table_and_selected_double(inp,"WAVE",
5539  CPL_NOT_LESS_THAN,wmin));
5540  check_nomsg(tmp=cpl_table_extract_selected(inp));
5541  check_nomsg(ninp=cpl_table_and_selected_double(tmp,"WAVE",
5542  CPL_NOT_GREATER_THAN,wmax));
5543  check_nomsg(out=cpl_table_extract_selected(tmp));
5544  sinfo_free_table(&tmp);
5545  } else {
5546  check_nomsg(out=cpl_table_duplicate(inp));
5547  }
5548 
5549  check_nomsg(nout=cpl_table_get_nrow(out));
5550  if(nout == 0) {
5551  //sinfo_msg("nout=%d",nout);
5552  goto cleanup;
5553  }
5554  tmp=cpl_table_duplicate(out);
5555  sinfo_free_table(&out);
5556  check_nomsg(pou=cpl_table_get_data_double(tmp,"WAVE"));
5557  check_nomsg(prf=cpl_table_get_data_double(ref,"WAVE"));
5558 
5559  check_nomsg(cpl_table_new_column(tmp,"FLAG",CPL_TYPE_INT));
5560  check_nomsg(cpl_table_fill_column_window(tmp,"FLAG",0,nout,-1));
5561 
5562  k=0;
5563  i=0;
5564 
5565  //sinfo_msg_debug("nout=%d nref=%d",nout,nref);
5566  //sinfo_msg_debug("wout(0)=%f wref(0)=%f tol=%f diff=%f",
5567  // pou[0],prf[0],tol,fabs(pou[0]-prf[0]));
5568 
5569  if(pou[0]<=prf[0]) {
5570  //sinfo_msg_debug("case 1");
5571  for(i=0;i<nout;i++) {
5572  if(k<nref) {
5573  if(fabs(pou[i] - prf[k])< tol) {
5574  check_nomsg(cpl_table_set_int(tmp,"FLAG",i,1));
5575  k++;
5576  }
5577  }
5578  }
5579  } else {
5580 
5581  //pou[0]>prf[0]
5582  //sinfo_msg_debug("case 2");
5583  for(k=0;k<nref;k++) {
5584  if(i<nout) {
5585  /*
5586  sinfo_msg("check: %f %f %f %f",
5587  fabs(pou[i] - prf[k]),tol,pou[i],prf[k]);
5588  */
5589  if(fabs(pou[i] - prf[k])< tol) {
5590  check_nomsg(cpl_table_set_int(tmp,"FLAG",i,1));
5591  i++;
5592  }
5593  }
5594  }
5595  }
5596  //check_nomsg(cpl_table_save(tmp,NULL,NULL,"out_pre0.fits",CPL_IO_DEFAULT));
5597  check_nomsg(nout=cpl_table_and_selected_int(tmp,"FLAG",CPL_GREATER_THAN,0));
5598  check_nomsg(out=cpl_table_extract_selected(tmp));
5599  sinfo_free_table(&tmp);
5600  check_nomsg(cpl_table_erase_column(out,"FLAG"));
5601  if(nout==0) {
5602  goto cleanup;
5603  }
5604  //check_nomsg(cpl_table_save(out,NULL,NULL,"out_post0.fits",CPL_IO_DEFAULT));
5605  /* sinfo_msg("nout=%d",nout); */
5606  return out;
5607 
5608  cleanup:
5609  sinfo_free_table(&tmp);
5610  sinfo_free_table(&out);
5611  return NULL;
5612 
5613 }
5614 
5624 cpl_table*
5625 sinfo_interpolate_sky(const cpl_table* inp,const cpl_table* lambdas)
5626 {
5627  //interpolate sky if necessary
5628  cpl_table* new=NULL;
5629  new = sinfo_interpolate(inp,lambdas,"WAVE","lsquadratic");;
5630 
5631  return new;
5632 }
5633 
5634 
5644 static cpl_table*
5645 sinfo_interpolate(const cpl_table* inp,
5646  const cpl_table* lambdas,
5647  const char* name,
5648  const char* method)
5649 {
5650  //TODO
5651  cpl_table* out=NULL;
5652 
5653  //To remove compilation warnings
5654  cknull_nomsg(lambdas);
5655  cknull_nomsg(name);
5656  cknull_nomsg(method);
5657 
5658  out=cpl_table_duplicate(inp);
5659  return out;
5660 
5661  cleanup:
5662 
5663  return NULL;
5664 
5665 }
5666 
5667 
5668 
5681 static double
5682 sinfo_gaussian_amp(double area,double sigma,double x,double x0,double off)
5683 {
5684  return area/sqrt(2*PI_NUMB*sigma*sigma)*
5685  exp(-(x-x0)*(x-x0)/(2*sigma*sigma))+off;
5686 }
5687 
5688 
5701 static double
5702 sinfo_gaussian_area(double amp,double sigma,double x,double x0,double off)
5703 {
5704  return sqrt(2*PI_NUMB*sigma*sigma)*exp((x-x0)*(x-x0)/(2*sigma*sigma))*
5705  (amp-off);
5706 }
5707 
5708 
5715 int
5716 sinfo_table_smooth_column(cpl_table** t, const char* c, const int r)
5717 {
5718  int nrow=0;
5719  int i=0;
5720  int j=0;
5721  double* pval=NULL;
5722  double sum;
5723  check_nomsg(nrow=cpl_table_get_nrow(*t));
5724  check_nomsg(pval=cpl_table_get_data_double(*t,c));
5725  for(i=r;i<nrow;i++) {
5726  sum=0;
5727  for(j=-r;j<=r;j++) {
5728  sum+=pval[i+j];
5729  }
5730  pval[i]=sum/(2*r+1);
5731  }
5732  return 0;
5733  cleanup:
5734  return -1;
5735 }
5736 
5745 void
5746 sinfo_shift_sky(cpl_frame** sky_frm,
5747  cpl_table** int_sky,
5748  const double zshift)
5749 {
5750  /*
5751  int xsz=0;
5752  int ysz=0;
5753  int zsz=0;
5754  */
5755  cpl_propertylist* plist=NULL;
5756  cpl_imagelist* sky_cub=NULL;
5757  cpl_imagelist* sky_shift=NULL;
5758  cpl_table* int_sky_dup=NULL;
5759  /*
5760  double min=0;
5761  double max=0;
5762  */
5763  /* Get Object relevant information */
5764  cknull_nomsg(plist=cpl_propertylist_load(
5765  cpl_frame_get_filename(*sky_frm),0));
5766  /*
5767  check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
5768  check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
5769  check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
5770  */
5771  sinfo_free_propertylist(&plist);
5772 
5773  cknull_nomsg(sky_cub=cpl_imagelist_load(cpl_frame_get_filename(*sky_frm),
5774  CPL_TYPE_FLOAT,0));
5775  /*
5776  check_nomsg(min=cpl_table_get_column_min(*int_sky,"INT"));
5777  check_nomsg(max=cpl_table_get_column_max(*int_sky,"INT"));
5778  */
5779  int_sky_dup=cpl_table_duplicate(*int_sky);
5780  sinfo_free_table(&(*int_sky));
5781  /*
5782  cknull_nomsg(*int_sky=sinfo_table_shift_column_int(int_sky_dup,
5783  "INT", zshift,&zrest));
5784  check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
5785  "out_sky_shift1.fits", CPL_IO_DEFAULT));
5786  sinfo_free_table(&(*int_sky));
5787 
5788  sinfo_msg("min=%f max=%f",min,max);
5789  check_nomsg(cpl_table_save(int_sky_dup, NULL, NULL,
5790  "out_sky_pre2.fits", CPL_IO_DEFAULT));
5791  cknull_nomsg(*int_sky=sinfo_table_shift_column_poly(int_sky_dup,
5792  "INT", zshift,2));
5793  check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
5794  "out_sky_shift2.fits", CPL_IO_DEFAULT));
5795  */
5796  //check_nomsg(cpl_table_save(int_sky_dup, NULL, NULL,
5797  // "out_sky_pre2.fits", CPL_IO_DEFAULT));
5798  check_nomsg(*int_sky=sinfo_table_shift_simple(int_sky_dup,"INT",zshift));
5799  /*
5800  sinfo_free_table(&(*int_sky));
5801  cknull_nomsg(*int_sky=sinfo_table_shift_column_spline3(int_sky_dup,
5802  "INT", zshift));
5803  check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
5804  "out_sky_shift3.fits", CPL_IO_DEFAULT));
5805  */
5806  sinfo_free_table(&int_sky_dup);
5807  /*
5808  check_nomsg(cpl_table_select_all(*int_sky));
5809  check_nomsg(n=cpl_table_and_selected_double(*int_sky,"INT",
5810  CPL_LESS_THAN,min));
5811  ck0_nomsg(sinfo_table_set_column_invalid(int_sky,"INT"));
5812  sinfo_msg("n=%d",n);
5813  check_nomsg(cpl_table_select_all(*int_sky));
5814  check_nomsg(n=cpl_table_and_selected_double(*int_sky,"INT",
5815  CPL_GREATER_THAN,max));
5816  sinfo_msg("n=%d",n);
5817  ck0_nomsg(sinfo_table_set_column_invalid(int_sky,"INT"));
5818  check_nomsg(cpl_table_select_all(*int_sky));
5819  */
5820  //check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
5821  // "out_sky_shift3.fits", CPL_IO_DEFAULT));
5822 
5823 
5824 
5825  check_nomsg(sky_shift=sinfo_cube_zshift_simple(sky_cub,(float)zshift));
5826 
5827  //check_nomsg(sky_shift=sinfo_cube_zshift(sky_cub,zshift,&zrest));
5828  //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky1.fits",
5829  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
5830 
5831  sinfo_free_imagelist(&sky_shift);
5832  //sinfo_free_imagelist(&sky_shift);
5833  //sinfo_msg("zrest=%f",zrest);
5834 
5835  //check_nomsg(sky_shift=sinfo_cube_zshift_poly(sky_cub,zshift,2));
5836  //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky2.fits",
5837  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
5838  //sinfo_free_imagelist(&sky_shift);
5839 
5840  //check_nomsg(sky_shift=sinfo_cube_zshift_spline3(sky_cub,zshift));
5841  //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky3.fits",
5842  // CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
5843  //sinfo_free_imagelist(&sky_shift);
5844  sinfo_free_imagelist(&sky_cub);
5845 
5846  return;
5847 
5848  cleanup:
5849  sinfo_free_table(&int_sky_dup);
5850  sinfo_free_propertylist(&plist);
5851  sinfo_free_imagelist(&sky_shift);
5852  sinfo_free_imagelist(&sky_cub);
5853  return;
5854 }
5855 
5856 
5863 static int
5864 sinfo_convolve_kernel(cpl_table** t, const int rad)
5865 {
5866  int i=0;
5867  int j=0;
5868  int np=0;
5869  double val=0;
5870  double* pidata=NULL;
5871  double* pcdata=NULL;
5872  /*
5873  double dw=0;
5874  double dr=0;
5875  double ws=0;
5876  double we=0;
5877  */
5878  cknull(*t,"null input table");
5879  check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
5880  check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
5881  check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
5882  /*
5883  check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
5884  check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
5885  */
5886  check_nomsg(np=cpl_table_get_nrow(*t));
5887  //dw=(we-ws)/(np-1);
5888  //dr=(we-ws)/(rad-1);
5889  /* set to 0 edges */
5890  for(i=0;i<rad;i++) {
5891  pcdata[i]=0.;
5892  }
5893  for(i=np-rad;i<np;i++) {
5894  pcdata[i]=0.;
5895  }
5896  for(i=rad;i<np-rad;i++) {
5897  val=0;
5898  for(j=-rad;j<rad;j++) {
5899  val+=pidata[i+j];
5900  }
5901  /*val*=dw; */
5902  check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
5903  }
5904  return 0;
5905 
5906  cleanup:
5907  return -1;
5908 
5909 }
5910 
5911 
5912 
5920 int
5921 sinfo_convolve_kernel2(cpl_table** t, const int rad)
5922 {
5923  int i=0;
5924  int j=0;
5925  int np=0;
5926  double val=0;
5927  double* pidata=NULL;
5928  double* pcdata=NULL;
5929  /*
5930  double dw=0;
5931  double dr=0;
5932  double ws=0;
5933  double we=0;
5934  */
5935  cknull(*t,"null input table");
5936  check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
5937  check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
5938  check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
5939  /*
5940  check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
5941  check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
5942  */
5943  check_nomsg(np=cpl_table_get_nrow(*t));
5944  /*
5945  dw=(we-ws)/(np-1);
5946  dr=(we-ws)/(rad-1);
5947  */
5948  /* set to 0 edges */
5949  for(i=0;i<rad;i++) {
5950  pcdata[i]=0.;
5951  }
5952  for(i=np-rad;i<np;i++) {
5953  pcdata[i]=0.;
5954  }
5955  for(i=0;i<np-rad;i++) {
5956  val=0;
5957  for(j=0;j<rad;j++) {
5958  val+=pidata[i+j];
5959  }
5960  /*val*=dw; */
5961  check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
5962  }
5963  return 0;
5964 
5965  cleanup:
5966  return -1;
5967 
5968 }
5969 
5970 
5971 
5979 int
5980 sinfo_convolve_exp(cpl_table** t, const int rad, const double fwhm)
5981 {
5982  int i=0;
5983  int j=0;
5984  int np=0;
5985  double ln2=0.693147180560;
5986  double k=ln2/fwhm;
5987  double val=0;
5988  double* pidata=NULL;
5989  double* pcdata=NULL;
5990  /*
5991  double dw=0;
5992  double dr=0;
5993  double ws=0;
5994  double we=0;
5995  */
5996  cknull(*t,"null input table");
5997  check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
5998  check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
5999  check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
6000  /*
6001  check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
6002  check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
6003  */
6004  check_nomsg(np=cpl_table_get_nrow(*t));
6005  //dw=(we-ws)/(np-1);
6006  //dr=(we-ws)/(rad-1);
6007  /* set to 0 edges */
6008  for(i=0;i<rad;i++) {
6009  pcdata[i]=0.;
6010  }
6011  for(i=np-rad;i<np;i++) {
6012  pcdata[i]=0.;
6013  }
6014  for(i=rad;i<np-rad;i++) {
6015  val=0;
6016  for(j=-rad;j<rad;j++) {
6017  val+=pidata[i+j]*k*pow(2.0,-2.0*fabs(i-rad)/fwhm);
6018  }
6019  /*val*=dw; */
6020  check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
6021  }
6022  return 0;
6023 
6024  cleanup:
6025  return -1;
6026 
6027 }
6028 
6029 
6038 int
6039 sinfo_convolve_gauss(cpl_table** t, const int rad, const double fwhm)
6040 {
6041  int i=0;
6042  int j=0;
6043  int np=0;
6044  double val=0;
6045  double sigma=fwhm/2.3548;
6046  double sigma2=sigma*sigma;
6047  double* pidata=NULL;
6048  double* pcdata=NULL;
6049  /*
6050  double dw=0;
6051  double dr=0;
6052  double ws=0;
6053  double we=0;
6054  */
6055  double tx=0;
6056 
6057  cknull(*t,"null input table");
6058  check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
6059  check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
6060  check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
6061  /*
6062  check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
6063  check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
6064  */
6065  check_nomsg(np=cpl_table_get_nrow(*t));
6066  /*
6067  dw=(we-ws)/(np-1);
6068  dr=(we-ws)/(rad-1);
6069  */
6070  /* set to 0 edges */
6071  for(i=0;i<rad;i++) {
6072  pcdata[i]=0.;
6073  }
6074  for(i=np-rad;i<np;i++) {
6075  pcdata[i]=0.;
6076  }
6077  for(i=rad;i<np-rad;i++) {
6078  val=0;
6079  for(j=-rad;j<rad;j++) {
6080  tx=i-rad;
6081  val+=pidata[i+j]*exp(-tx*tx/2.0/sigma2)/(sigma*sqrt(2.0*PI_NUMB));
6082  }
6083  /*val*=dw; */
6084  check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
6085  }
6086  return 0;
6087 
6088  cleanup:
6089  return -1;
6090 
6091 }
6092 
6093 
6094 
6106 static int
6107 sinfo_scales_obj_sky_cubes(cpl_imagelist* obj_cub,
6108  cpl_imagelist* sky_cub,
6109  cpl_table* bkg,
6110  cpl_table* rscale,
6111  cpl_imagelist** obj_cor)
6112 {
6113 
6114 
6115  int i=0;
6116  int j=0;
6117  int k=0;
6118  int xsz=0;
6119  int ysz=0;
6120  int zsz=0;
6121 
6122  double* podata=NULL;
6123  double* psdata=NULL;
6124  double* pbdata=NULL;
6125  double* pcdata=NULL;
6126  double* pscale=NULL;
6127 
6128 
6129  cpl_image* imgo=NULL;
6130  cpl_image* imgs=NULL;
6131  cpl_image* imgc=NULL;
6132 
6133 
6134  check_nomsg(imgo=cpl_imagelist_get(obj_cub,0));
6135  check_nomsg(xsz=cpl_image_get_size_x(imgo));
6136  check_nomsg(ysz=cpl_image_get_size_y(imgo));
6137  check_nomsg(zsz=cpl_imagelist_get_size(obj_cub));
6138 
6139  check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
6140 
6141  for(k=0;k<zsz;k++) {
6142  check_nomsg(imgo=cpl_imagelist_get(obj_cub,k));
6143  check_nomsg(imgc=cpl_imagelist_get(*obj_cor,k));
6144  check_nomsg(imgs=cpl_imagelist_get(sky_cub,k));
6145 
6146  check_nomsg(podata=cpl_image_get_data_double(imgo));
6147  check_nomsg(pcdata=cpl_image_get_data_double(imgc));
6148  check_nomsg(psdata=cpl_image_get_data_double(imgs));
6149  check_nomsg(pbdata=cpl_table_get_data_double(bkg,"INT2"));
6150  check_nomsg(pscale=cpl_table_get_data_double(rscale,"RATIO"));
6151 
6152  for (j=0;j<ysz; j++) {
6153  for (i=0;i<xsz; i++) {
6154  if(!irplib_isnan(podata[i+j*xsz]) &&
6155  !irplib_isnan(psdata[i+j*xsz]) &&
6156  !irplib_isnan(pbdata[k]) &&
6157  !irplib_isnan(pscale[k])) {
6158  pcdata[i+j*xsz] = podata[i+j*xsz]-
6159  (psdata[i+j*xsz]-pbdata[k])*pscale[k];
6160  }
6161  }
6162  }
6163  }
6164 
6165 
6166  return 0;
6167  cleanup:
6168 
6169  return -1;
6170 }
6171 
6172 
6189 static int
6190 sinfo_fitbkg(const double x[],
6191  const double a[],
6192  double *result)
6193 {
6194 
6195 
6196  double fac = sinfo_fac(x[0],a[2]);
6197  /*
6198  int n=sizeof(x)/sizeof(double);
6199  double fmin = sinfo_fac(x[0],a[2]);
6200  double fmax = sinfo_fac(x[n-1],a[2]);
6201  sinfo_msg("n=%d",n);
6202  if(fmax < 0) sinfo_msg("fmax=%f",fmax);
6203  */
6204  //*result = a[0]+a[1]*fac/sinfo_scale_fct;
6205  *result = a[0]+a[1]*fac;
6206 
6207  return 0;
6208 }
6209 
6233 static int
6234 sinfo_fitbkg_derivative(const double x[],
6235  const double a[],
6236  double d[])
6237 {
6238  double c=14387.7;
6239  /*
6240  int n=sizeof(x)/sizeof(double);
6241  double fmin = sinfo_fac(x[0],a[2]);
6242  double fmax = sinfo_fac(x[n],a[2]);
6243  */
6244  double fac = sinfo_fac(x[0],a[2]);
6245  /*
6246  //double f2=0;
6247  //double f1=0;
6248  //double da=0.001;
6249  //f1=a[0]+a[1]*fac;
6250  //f2=f1+da*a[0];
6251  //f2=a[0]+(a[1]+da*a[1])*fac;
6252  //f2=a[0]+a[1]*sinfo_fac(x[0],a[2]+da*a[2]);
6253  */
6254  d[0]=1.;
6255  d[1]=fac;
6256  d[2]=a[1]*fac*fac*x[0]*x[0]*x[0]*x[0]*c/(a[2]*a[2])*exp(c/(x[0]*a[2]));
6257  //sinfo_msg("d0=%g d1=%g d2=%g",d[0]*a[0]/f,d[1]*a[1]/f,d[2]*a[2]/f);
6258  //sinfo_msg("comp d1=%g",d[2]);
6259  //sinfo_msg("real d1=%g",(f2-f1)/(da*a[2]));
6260 
6261  return 0;
6262 }
6263 
6264 
6265 
6279 static double
6280 sinfo_fac(const double x, const double t)
6281 {
6282 
6283  double c=14387.7;
6284 
6285  //return pow(x,-5.)/(exp(c/(x*fabs(t)))-1.)/sinfo_scale_fct;
6286  /* replace pow(x,-5.)/(exp(c/(x*fabs(t)))-1.); by
6287  * pow(x,-5.)/(expm1(c/(x*fabs(t))));
6288  * to get better accuracy
6289  */
6290 
6291  return pow(x,-5.)/(expm1(c/(x*fabs(t))));
6292 }
6293 
6303 static int
6304 sinfo_table_threshold(cpl_table** t,
6305  const char* column,
6306  const double low_cut,
6307  const double hig_cut,
6308  const double low_ass,
6309  const double hig_ass)
6310 {
6311 
6312  int nrow=0;
6313  int i=0;
6314  double* pdata=NULL;
6315  cknull(*t,"null input table!");
6316 
6317  check_nomsg(nrow=cpl_table_get_nrow(*t));
6318  check_nomsg(pdata=cpl_table_get_data_double(*t,column));
6319 
6320  for(i=0;i<nrow;i++) {
6321 
6322  if(pdata[i]<low_cut) {
6323  pdata[i]=low_ass;
6324  }
6325  if (pdata[i] >= hig_cut) {
6326  pdata[i]=hig_ass;
6327  }
6328 
6329  }
6330 
6331  return 0;
6332 
6333  cleanup:
6334 
6335  return -1;
6336 }
6337 
6366 static int
6367 sinfo_table_set(cpl_table** inp,
6368  const cpl_table* ref,
6369  const double val,
6370  const double tol)
6371 {
6372 
6373  int ninp=0;
6374  //int nref=0;
6375  double* piw=NULL;
6376  const double* prw=NULL;
6377  //double* pir=NULL;
6378  int i=0;
6379  int k=0;
6380  cknull(*inp,"NULL input table");
6381  cknull(ref,"NULL reference table");
6382 
6383  check_nomsg(ninp=cpl_table_get_nrow(*inp));
6384  //check_nomsg(nref=cpl_table_get_nrow(ref));
6385 
6386  check_nomsg(prw=cpl_table_get_data_double_const(ref,"WAVE"));
6387  check_nomsg(piw=cpl_table_get_data_double(*inp,"WAVE"));
6388  //check_nomsg(pir=cpl_table_get_data_double(*inp,"RATIO"));
6389 
6390 
6391  for(i=0;i<ninp;i++) {
6392  /*sinfo_msg("check =%g thresh=%g",fabs(piw[i]-prw[k]),tol); */
6393  if(fabs(piw[i]-prw[k]) < tol) {
6394  check_nomsg(cpl_table_set_double(*inp,"RATIO",i,val));
6395  k++;
6396  }
6397  }
6398  return 0;
6399 
6400  cleanup:
6401 
6402  return -1;
6403 
6404 }
6405 
6406 
6407 
6408 static cpl_table*
6409 sinfo_table_shift_simple(cpl_table* inp,
6410  const char* col,
6411  const double shift)
6412 {
6413 
6414  int nrow=0;
6415  cpl_table* out=NULL;
6416  int is=(int)shift;
6417  double ds=shift-is;
6418  double* pi=NULL;
6419  double* po=NULL;
6420  double m=0;
6421  int i=0;
6422  cknull(inp,"null input table");
6423 
6424  check_nomsg(nrow=cpl_table_get_nrow(inp));
6425  check_nomsg(out=cpl_table_duplicate(inp));
6426  check_nomsg(cpl_table_fill_column_window(out,col,0,nrow,0));
6427  check_nomsg(pi=cpl_table_get_data_double(inp,col));
6428  check_nomsg(po=cpl_table_get_data_double(out,col));
6429 
6430 
6431  for(i=0;i<nrow;i++) {
6432  if((i+is)>0 && (i+is+1) < nrow) {
6433  m=pi[i+is+1]-pi[i+is];
6434  po[i]=pi[i+is]+m*ds;
6435  }
6436  }
6437  return out;
6438  cleanup:
6439  sinfo_free_table(&out);
6440  return NULL;
6441 
6442 }
6443 
6444 
6445 
6446 
6447 static cpl_imagelist*
6448 sinfo_cube_zshift_simple(cpl_imagelist* inp,
6449  const float shift)
6450 {
6451 
6452  int nx=0;
6453  int ny=0;
6454  int nz=0;
6455 
6456  int i=0;
6457  int j=0;
6458  int k=0;
6459  int ks=(int)shift;
6460 
6461  float ds=shift-ks;
6462  float* pu=NULL;
6463  float* pl=NULL;
6464  float* po=NULL;
6465 
6466  float int2=0;
6467  float int1=0;
6468  float m=0;
6469 
6470  cpl_imagelist* out=NULL;
6471  cpl_image* imgu=NULL;
6472  cpl_image* imgl=NULL;
6473  cpl_image* imgo=NULL;
6474 
6475 
6476  cknull(inp,"null input cube");
6477 
6478  check_nomsg(nz=cpl_imagelist_get_size(inp));
6479  check_nomsg(out=cpl_imagelist_duplicate(inp));
6480  check_nomsg(imgo=cpl_imagelist_get(out,0));
6481  check_nomsg(nx=cpl_image_get_size_x(imgo));
6482  check_nomsg(ny=cpl_image_get_size_y(imgo));
6483 
6484  for(k=0;k<nz;k++) {
6485  if((k+ks)>0 && (k+ks+1) < nz) {
6486 
6487  check_nomsg(imgu=cpl_imagelist_get(inp,k+ks+1));
6488  check_nomsg(imgl=cpl_imagelist_get(inp,k+ks));
6489  check_nomsg(imgo=cpl_imagelist_get(out,k));
6490 
6491  check_nomsg(pu=cpl_image_get_data_float(imgu));
6492  check_nomsg(pl=cpl_image_get_data_float(imgl));
6493  check_nomsg(po=cpl_image_get_data_float(imgo));
6494 
6495 
6496  for(j=0;j<ny;j++) {
6497  for(i=0;i<nx;i++) {
6498  int2=pu[nx*j+i];
6499  int1=pl[nx*j+i];
6500  m=int2-int1;
6501  po[nx*j+i]=int1+m*ds;
6502  }
6503  }
6504  }
6505 
6506 
6507  }
6508  return out;
6509  cleanup:
6510  sinfo_free_imagelist(&out);
6511  return NULL;
6512 
6513 }
6514 
6515 
6526 static int
6527 sinfo_get_line_ratio(cpl_table* obj_lin,
6528  cpl_table* obj_cnt,
6529  cpl_table* sky_lin,
6530  cpl_table* sky_cnt,
6531  const int method,
6532  double* r)
6533 {
6534 
6535  int nobj;
6536  int nsky;
6537  int i=0;
6538 
6539  cpl_table* obj_dif=NULL;
6540  cpl_table* sky_dif=NULL;
6541 
6542  double* poi=NULL;
6543  double* psi=NULL;
6544  double* pvd=NULL;
6545  double* pvn=NULL;
6546  double* pvr=NULL;
6547 
6548  cpl_vector* num=NULL;
6549  cpl_vector* den=NULL;
6550  cpl_vector* rat=NULL;
6551  cpl_vector* wav=NULL;
6552  double mnum=0;
6553  double mden=0;
6554  double tnum=0;
6555  double tden=0;
6556  cpl_size pows[2];
6557  cpl_polynomial* cfit=NULL;
6558  double mse=0;
6559 
6560  cknull(obj_lin,"null obj line table");
6561  cknull(sky_lin,"null sky line table");
6562 
6563  cknull(obj_cnt,"null obj cont table");
6564  cknull(sky_cnt,"null sky cont table");
6565 
6566 
6567  cknull_nomsg(obj_dif=sinfo_table_subtract_continuum(obj_lin,obj_cnt));
6568  cknull_nomsg(sky_dif=sinfo_table_subtract_continuum(sky_lin,sky_cnt));
6569 
6570  check_nomsg(nobj=cpl_table_get_nrow(obj_dif));
6571  check_nomsg(nsky=cpl_table_get_nrow(sky_dif));
6572 
6573 
6574 
6575  if(nobj != nsky) {
6576  sinfo_msg_error("obj and sky table must have the same no of rows!");
6577  sinfo_msg_error("nobj=%d nsky=%d",nobj,nsky);
6578  goto cleanup;
6579  }
6580  //sinfo_msg("Object sky residuals/Sky lines ratio determination method=%d",
6581  // method);
6582  if(method == 0) {
6583  ck0_nomsg(sinfo_get_line_ratio_amoeba(obj_dif,sky_dif,r));
6584  sinfo_free_table(&obj_dif);
6585  sinfo_free_table(&sky_dif);
6586  return 0;
6587  }
6588 
6589 
6590  check_nomsg(poi=cpl_table_get_data_double(obj_dif,"INT"));
6591  check_nomsg(psi=cpl_table_get_data_double(sky_dif,"INT"));
6592 
6593  check_nomsg(num=cpl_vector_new(nobj));
6594  check_nomsg(den=cpl_vector_new(nobj));
6595  check_nomsg(rat=cpl_vector_new(nobj));
6596  check_nomsg(cpl_vector_fill(num,0));
6597  check_nomsg(cpl_vector_fill(den,0));
6598  check_nomsg(cpl_vector_fill(rat,0));
6599  check_nomsg(pvd=cpl_vector_get_data(den));
6600  check_nomsg(pvn=cpl_vector_get_data(num));
6601  check_nomsg(pvr=cpl_vector_get_data(rat));
6602 
6603  for(i=0;i<nobj;i++) {
6604  if(!irplib_isnan(psi[i]) &&
6605  !irplib_isnan(poi[i]) &&
6606  !irplib_isinf(psi[i]) &&
6607  !irplib_isinf(poi[i]) ) {
6608  pvn[i]=psi[i]*poi[i];
6609  pvd[i]=psi[i]*psi[i];
6610  if(psi[i] != 0) {
6611  pvr[i]=poi[i]/psi[i];
6612  }
6613  }
6614  }
6615  sinfo_free_table(&sky_dif);
6616 
6617  check_nomsg(mnum=cpl_vector_get_median_const(num));
6618  check_nomsg(mden=cpl_vector_get_median_const(den));
6619  check_nomsg(tnum=cpl_vector_get_mean(num)*nobj);
6620  check_nomsg(tden=cpl_vector_get_mean(den)*nobj);
6621 
6622  //sinfo_msg("mden=%g tden=%g",mden,tden);
6623  //sinfo_msg("mnum=%g tnum=%g",mnum,tnum);
6624  sinfo_free_my_vector(&num);
6625  sinfo_free_my_vector(&den);
6626  if(method == 1) {
6627  *r=tnum/tden;
6628  } else if (method == 2) {
6629  *r=mnum/mden;
6630  } else if (method == 3) {
6631  *r=cpl_vector_get_median_const(rat);
6632  } else if (method == 4) {
6633  *r=cpl_vector_get_mean(rat);
6634  } else if (method == 5) {
6635 
6636  check_nomsg(wav=cpl_vector_wrap(nobj,
6637  cpl_table_get_data_double(obj_dif,"WAVE")));
6638  check_nomsg(cfit=sinfo_polynomial_fit_1d_create(wav,rat,0,&mse));
6639  sinfo_unwrap_vector(&wav);
6640  pows[0]=0;
6641  pows[1]=0;
6642  check_nomsg(*r=cpl_polynomial_get_coeff(cfit,pows));
6643  sinfo_free_polynomial(&cfit);
6644 
6645  }
6646 
6647  sinfo_free_table(&obj_dif);
6648  sinfo_free_my_vector(&rat);
6649  return 0;
6650  cleanup:
6651  sinfo_free_table(&obj_dif);
6652  sinfo_free_table(&sky_dif);
6653  sinfo_free_my_vector(&num);
6654  sinfo_free_my_vector(&den);
6655  sinfo_free_my_vector(&rat);
6656  sinfo_unwrap_vector(&wav);
6657 
6658  return -1;
6659 }
6660 
6661 
6662 
6663 
6673 static int
6674 sinfo_get_line_ratio_amoeba(cpl_table* obj,
6675  cpl_table* sky,
6676  double* r)
6677 {
6678 
6679 
6680  int i=0;
6681  const int MP=2;
6682  const int NP=1;
6683  double y[MP];
6684  double p0[NP];
6685  double** ap=NULL;
6686  int nfunc=0;
6687  int np=0;
6688  check_nomsg(np=cpl_table_get_nrow(obj));
6689  check_nomsg(sa_ox=cpl_vector_wrap(np,cpl_table_get_data_double(obj,"WAVE")));
6690  check_nomsg(sa_oy=cpl_vector_wrap(np,cpl_table_get_data_double(obj,"INT")));
6691  check_nomsg(sa_sy=cpl_vector_wrap(np,cpl_table_get_data_double(sky,"INT")));
6692  // Amoeba part
6693 
6694 
6695  ap=(double**) cpl_calloc(MP,sizeof(double*));
6696  for(i=0;i<MP;i++) {
6697  ap[i]=cpl_calloc(NP,sizeof(double));
6698  }
6699 
6700  ap[0][0]=-1.;
6701  ap[1][0]=+1.;
6702 
6703  //sinfo_msg("Before amoeba fit");
6704  //sinfo_msg("ap[0][0]=%g ap[0][1]=%g",ap[0][0],ap[1][0]);
6705  for(i=0;i<MP;i++) {
6706  p0[0]=ap[i][0];
6707  y[i]=sinfo_fit_sky(p0);
6708  }
6709 
6710 
6711  check_nomsg(sinfo_fit_amoeba(ap,y,NP,AMOEBA_FTOL,sinfo_fit_sky,&nfunc));
6712 
6713  sinfo_msg("After amoeba fit");
6714  sinfo_msg("ap[0][0]=%g ap[0][1]=%g",ap[0][0],ap[1][0]);
6715 
6716  *r=ap[0][0];
6717 
6718  sinfo_unwrap_vector(&sa_ox);
6719  sinfo_unwrap_vector(&sa_oy);
6720  sinfo_unwrap_vector(&sa_sy);
6721  sinfo_new_destroy_2Ddoublearray(&ap,MP);
6722 
6723 
6724  return 0;
6725 
6726  cleanup:
6727  sinfo_unwrap_vector(&sa_ox);
6728  sinfo_unwrap_vector(&sa_oy);
6729  sinfo_unwrap_vector(&sa_sy);
6730  sinfo_new_destroy_2Ddoublearray(&ap,MP);
6731 
6732  return -1;
6733 
6734 }
6735 
6736 
6737 /*-------------------------------------------------------------------------*/
6746 /*--------------------------------------------------------------------------*/
6747 
6748 static double
6749 sinfo_fit_sky(double p[])
6750 
6751 {
6752  double* ps=NULL;
6753  double* po=NULL;
6754  double* pv=NULL;
6755  cpl_vector* vtmp=NULL;
6756  int i=0;
6757  int np=0;
6758  cpl_size pows[2];
6759  double mse=0;
6760  double cont=0;
6761  cpl_polynomial* pfit=NULL;
6762 
6763  double rms=0;
6764 
6765 
6766  //fit residual obj continuum and subtract it
6767  check_nomsg(pfit=sinfo_polynomial_fit_1d_create(sa_ox,sa_oy,0,&mse));
6768  pows[0]=0;
6769  pows[1]=0;
6770  check_nomsg(cont=cpl_polynomial_get_coeff(pfit,pows));
6771  check_nomsg(sinfo_free_polynomial(&pfit));
6772  check_nomsg(cpl_vector_subtract_scalar(sa_oy,cont));
6773 
6774 
6775  //fit residual sky continuum and subtract it
6776  check_nomsg(pfit=sinfo_polynomial_fit_1d_create(sa_ox,sa_sy,0,&mse));
6777  pows[0]=0;
6778  pows[1]=0;
6779  check_nomsg(cont=cpl_polynomial_get_coeff(pfit,pows));
6780  check_nomsg(sinfo_free_polynomial(&pfit));
6781  check_nomsg(cpl_vector_subtract_scalar(sa_sy,cont));
6782 
6783  //computes diff=(obj-conto)-(sky-contsky)*p[0]
6784  check_nomsg(po= cpl_vector_get_data(sa_oy));
6785  check_nomsg(ps= cpl_vector_get_data(sa_sy));
6786 
6787  check_nomsg(np=cpl_vector_get_size(sa_oy));
6788  check_nomsg(vtmp=cpl_vector_new(np));
6789  check_nomsg(pv= cpl_vector_get_data(vtmp));
6790 
6791 
6792  for(i=0;i<np;i++) {
6793  pv[i]=po[i]-ps[i]*p[0];
6794  }
6795  //computes rms diff
6796  check_nomsg(rms=cpl_vector_get_stdev(vtmp));
6797  sinfo_free_my_vector(&vtmp);
6798  return rms;
6799  cleanup:
6800  sinfo_free_my_vector(&vtmp);
6801  return -1;
6802 
6803 }
6804 
6805 
6806 
6818 static cpl_table*
6819 sinfo_table_interpol(cpl_table* obj_lin,
6820  cpl_table* obj_cnt,
6821  cpl_table* sky_lin,
6822  cpl_table* sky_cnt,
6823  const double r)
6824 {
6825 
6826  cpl_table* out=NULL;
6827  cpl_table* obj_dif=NULL;
6828  cpl_table* sky_dif=NULL;
6829  cknull(obj_lin,"null line table");
6830  cknull(obj_cnt,"null cont table");
6831 
6832  cknull_nomsg(obj_dif=sinfo_table_subtract_continuum(obj_lin,obj_cnt));
6833  cknull_nomsg(sky_dif=sinfo_table_subtract_continuum(sky_lin,sky_cnt));
6834 
6835  check_nomsg(out=cpl_table_duplicate(obj_dif));
6836  check_nomsg(cpl_table_duplicate_column(out,"CSKY",sky_dif,"INT"));
6837  check_nomsg(cpl_table_multiply_scalar(out,"CSKY",r));
6838  check_nomsg(cpl_table_subtract_columns(out,"INT","CSKY"));
6839 
6840  sinfo_free_table(&obj_dif);
6841  sinfo_free_table(&sky_dif);
6842 
6843  return out;
6844 
6845  cleanup:
6846  sinfo_free_table(&obj_dif);
6847  sinfo_free_table(&sky_dif);
6848  sinfo_free_table(&out);
6849  return NULL;
6850 
6851 }
6852 
6853 
6854 
6855 
6856 
6857 
6866 static cpl_table*
6867 sinfo_table_subtract_continuum(cpl_table* lin,
6868  cpl_table* cnt)
6869 
6870 {
6871 
6872  cpl_table* out=NULL;
6873  int nlin=0;
6874  int ncnt=0;
6875  int i=0;
6876  double* poi=NULL;
6877  cpl_vector* vx=NULL;
6878  cpl_vector* vy=NULL;
6879  cpl_polynomial* cfit=NULL;
6880  cpl_size pows[2];
6881  double mse=0;
6882  double yfit=0;
6883 
6884  cknull(lin,"null line table");
6885  cknull(cnt,"null cont table");
6886  check_nomsg(out=cpl_table_duplicate(lin));
6887  check_nomsg(cpl_table_new_column(out,"CONT",CPL_TYPE_DOUBLE));
6888  check_nomsg(nlin=cpl_table_get_nrow(lin));
6889  check_nomsg(ncnt=cpl_table_get_nrow(cnt));
6890  //sinfo_msg("nlin=%d",nlin);
6891  check_nomsg(cpl_table_fill_column_window(out,"CONT",0,nlin,0));
6892 
6893  //do a uniform fit
6894  check_nomsg(vx=cpl_vector_wrap(ncnt,cpl_table_get_data_double(cnt,"WAVE")));
6895  check_nomsg(vy=cpl_vector_wrap(ncnt,cpl_table_get_data_double(cnt,"INT")));
6896  check_nomsg(cfit=sinfo_polynomial_fit_1d_create(vx,vy,0,&mse));
6897  sinfo_unwrap_vector(&vx);
6898  sinfo_unwrap_vector(&vy);
6899 
6900  pows[0]=0;
6901  pows[1]=0;
6902  check_nomsg(yfit=cpl_polynomial_get_coeff(cfit,pows));
6903  sinfo_free_polynomial(&cfit);
6904  //sinfo_msg("coeff 0=%g",yfit);
6905 
6906  check_nomsg(poi=cpl_table_get_data_double(out,"CONT"));
6907  for(i=0;i<nlin;i++) {
6908  poi[i]=yfit;
6909  }
6910 
6911  check_nomsg(cpl_table_subtract_columns(out,"INT","CONT"));
6912  check_nomsg(cpl_table_erase_column(out,"CONT"));
6913 
6914 
6915 
6916  return out;
6917 
6918  cleanup:
6919  sinfo_unwrap_vector(&vx);
6920  sinfo_unwrap_vector(&vy);
6921  sinfo_free_polynomial(&cfit);
6922  sinfo_free_table(&out);
6923  return NULL;
6924 
6925 }
6926 
6927 
6928 static int
6929 sinfo_compute_line_ratio(cpl_table* obj,
6930  cpl_table* sky,
6931  const double wtol,
6932  const int meth,
6933  const cpl_table* sel_regions,
6934  cpl_table* cont_regions,
6935  double* r)
6936 {
6937  cpl_table* line_regions=NULL;
6938  cpl_table* obj_cnt=NULL;
6939  cpl_table* sky_cnt=NULL;
6940  cpl_table* obj_lin=NULL;
6941  cpl_table* sky_lin=NULL;
6942  cpl_table* lres=NULL;
6943  double fmed=0;
6944  double fsdv=0;
6945  double fthresh=0;
6946  int fclip_i=0;
6947  int line_i=0;
6948 
6949 
6950  //line_regions = med_regions;
6951  check_nomsg(line_regions = cpl_table_duplicate(sel_regions));
6952  //r = amoeba(1.e-5,function_name='fitsky',p0=[1.],scale=[0.1]);
6953  //Identify obj lines and continuum, same for sky
6954  check_nomsg(obj_lin=sinfo_table_select_range(obj,line_regions,wtol));
6955  check_nomsg(sky_lin=sinfo_table_select_range(sky,line_regions,wtol));
6956  check_nomsg(obj_cnt=sinfo_table_select_range(obj,cont_regions,wtol));
6957  check_nomsg(sky_cnt=sinfo_table_select_range(sky,cont_regions,wtol));
6958 
6959  ck0_nomsg(sinfo_get_line_ratio(obj_lin,obj_cnt,sky_lin,sky_cnt,meth,r));
6960 
6961 
6962  //fline_res = (obj_lr[line_regions]-
6963  // interpol(obj_lr[cont_regions],llr[cont_regions],
6964  // llr[line_regions])) -
6965  // (sky_lr[line_regions] -
6966  // interpol(sky_lr[cont_regions],llr[cont_regions],
6967  //
6968  // llr[line_regions]))*r[0];
6969  check_nomsg(lres=sinfo_table_interpol(obj_lin,obj_cnt,sky_lin,sky_cnt,*r));
6970 
6971  check_nomsg(fmed = cpl_table_get_column_median(lres,"INT"));
6972  check_nomsg(fsdv = cpl_table_get_column_stdev(lres,"INT"));
6973  fthresh=fmed+3*fsdv;
6974  //fclip = where(abs(fline_res) > fmed+3*fsdv,fclip_i);
6975  check_nomsg(cpl_table_duplicate_column(lres,"AINT",lres,"INT"));
6976  check_nomsg(cpl_table_multiply_columns(lres,"AINT","INT"));
6977  check_nomsg(cpl_table_power_column(lres,"AINT",0.5));
6978  check_nomsg(fclip_i=cpl_table_and_selected_double(lres,"AINT",
6979  CPL_GREATER_THAN,
6980  fthresh));
6981  check_nomsg(cpl_table_select_all(lres));
6982 
6983 
6984  if (fclip_i > 0) {
6985  //line_regions = line_regions[where(abs(fline_res) < fmed+3*fsdv)];
6986  check_nomsg(line_i=cpl_table_and_selected_double(lres,"AINT",
6987  CPL_LESS_THAN,
6988  fthresh));
6989  sinfo_free_table(&line_regions);
6990  check_nomsg(line_regions=cpl_table_extract_selected(lres));
6991  sinfo_free_table(&lres);
6992 
6993  check_nomsg(cpl_table_erase_column(line_regions,"INT"));
6994  check_nomsg(cpl_table_erase_column(line_regions,"AINT"));
6995 
6996 
6997  if (line_i >= 3) {
6998 
6999  sinfo_free_table(&obj_lin);
7000  sinfo_free_table(&sky_lin);
7001  check_nomsg(obj_lin=sinfo_table_select_range(obj,line_regions,wtol));
7002  check_nomsg(sky_lin=sinfo_table_select_range(sky,line_regions,wtol));
7003 
7004  sinfo_free_table(&line_regions);
7005 
7006 
7007  //r = amoeba(1.e-5,function_name='fitsky',p0=[1.],scale=[0.1]);
7008  ck0_nomsg(sinfo_get_line_ratio(obj_lin,obj_cnt,sky_lin,sky_cnt,meth,r));
7009  }
7010  }
7011  *r=fabs(*r);
7012  //Free memory
7013  sinfo_free_table(&obj_cnt);
7014  sinfo_free_table(&sky_cnt);
7015  sinfo_free_table(&sky_lin);
7016  sinfo_free_table(&obj_lin);
7017  sinfo_free_table(&lres);
7018  sinfo_free_table(&line_regions);
7019 
7020 
7021  return 0;
7022 
7023 
7024  cleanup:
7025 
7026 
7027  sinfo_free_table(&obj_cnt);
7028  sinfo_free_table(&sky_cnt);
7029  sinfo_free_table(&sky_lin);
7030  sinfo_free_table(&obj_lin);
7031 
7032  sinfo_free_table(&lres);
7033  sinfo_free_table(&line_regions);
7034 
7035  return -1;
7036 
7037 }
7049 static cpl_table*
7050 sinfo_find_rot_waves(
7051  const double w_rot[],
7052  const int npix_w,
7053  const double w_step,
7054  cpl_table* range
7055  )
7056 {
7057  int i=0;
7058  int x_i=0;
7059  int r_start=0;
7060  double w_min=0;
7061  double w_max=0;
7062 
7063  cpl_table* w_sel=NULL;
7064  cpl_table* res=NULL;
7065 
7066  check_nomsg(res = cpl_table_new(0));
7067 
7068  check_nomsg(cpl_table_copy_structure(res,range));
7069 
7070  for (i=0; i< NROT; i++) {
7071 
7072  //x = where(lambda > l_rot_low[i]-npixw*cdelto &&
7073  // lambda < l_rot_low[i]+npixw*cdelto,x_i);
7074 
7075  w_min=w_rot[i]-npix_w*w_step;
7076  w_max=w_rot[i]+npix_w*w_step;
7077 
7078  check_nomsg(cpl_table_and_selected_double(range,"WAVE",
7079  CPL_GREATER_THAN,w_min));
7080  check_nomsg(cpl_table_and_selected_double(range,"WAVE",
7081  CPL_LESS_THAN,w_max));
7082  sinfo_free_table(&w_sel);
7083  check_nomsg(w_sel=cpl_table_extract_selected(range));
7084  check_nomsg(x_i=cpl_table_get_nrow(w_sel));
7085 
7086  if (x_i > 0) {
7087  check_nomsg(r_start=cpl_table_get_nrow(res));
7088  //sinfo_msg("i=%d x_i=%d w_min=%g w_max=%g",i,x_i,w_min,w_max);
7089  check_nomsg(cpl_table_insert(res,w_sel,r_start));
7090  }
7091  check_nomsg(cpl_table_select_all(range));
7092  }
7093 
7094  //res = range[1:cpl_table_get_nrow(res)-1];
7095  sinfo_free_table(&w_sel);
7096 
7097 
7098  return res;
7099 
7100  cleanup:
7101  sinfo_free_table(&w_sel);
7102  sinfo_free_table(&res);
7103  return NULL;
7104 
7105 }
7106 
7119 static int
7120 sinfo_get_obj_sky_wav_sub(cpl_table* obj,
7121  cpl_table* sky,
7122  cpl_table* wav,
7123  cpl_table* sel,
7124  const double wtol,
7125  cpl_table** sub_obj,
7126  cpl_table** sub_sky,
7127  cpl_table** sub_wav)
7128 
7129 {
7130  cknull_nomsg(*sub_obj = sinfo_table_select_range(obj,sel,wtol));
7131  cknull_nomsg(*sub_sky = sinfo_table_select_range(sky,sel,wtol));
7132  cknull_nomsg(*sub_wav = sinfo_table_select_range(wav,sel,wtol));
7133  return 0;
7134 
7135  cleanup:
7136  sinfo_free_table(&(*sub_obj));
7137  sinfo_free_table(&(*sub_sky));
7138  sinfo_free_table(&(*sub_wav));
7139 
7140  return -1;
7141 
7142 }
7143 
7144 static int
7145 sinfo_get_sub_regions(cpl_table* sky,
7146  cpl_table* x1,
7147  cpl_table* pos,
7148  const double wtol,
7149  const int npixw,
7150  cpl_table** res)
7151 {
7152 
7153  cpl_table* x1_sub=NULL;
7154  cpl_table* x2=NULL;
7155 
7156  int nrow=0;
7157  int np=0;
7158 
7159  cknull(sky,"Null input sky table");
7160  cknull(x1 ,"Null input x1 table");
7161  cknull(pos,"Null input pos table");
7162 
7163  check_nomsg(x2=cpl_table_duplicate(sky));
7164  check_nomsg(nrow=cpl_table_get_nrow(sky));
7165  check_nomsg(cpl_table_fill_column_window(x2,"INT",0,nrow,0));
7166 
7167  //x2[x1[pos]] = 10.;
7168  //x2 = convol(x2,replicate(1,npixw),/edge_truncate,/center);
7169  //res = where(x2 > 0,hi_i);
7170  //cpl_table_save(x1, NULL, NULL, "out_x1.fits", CPL_IO_DEFAULT);
7171 
7172  x1_sub=sinfo_table_select_range(x1,pos,wtol);
7173 
7174  if(x1_sub != NULL) {
7175  ck0_nomsg(sinfo_table_fill_column_over_range(&x2,x1_sub,"INT",10.,wtol));
7176  sinfo_free_table(&x1_sub);
7177  check_nomsg(sinfo_convolve_kernel(&x2,npixw/2));
7178  check_nomsg(np=cpl_table_and_selected_double(x2,"CNV",CPL_GREATER_THAN,0));
7179  check_nomsg(*res=cpl_table_extract_selected(x2));
7180  sinfo_free_table(&x2);
7181  check_nomsg(cpl_table_erase_column(*res,"INT"));
7182  check_nomsg(cpl_table_erase_column(*res,"CNV"));
7183 
7184  } else {
7185  cpl_error_reset();
7186  sinfo_free_table(&x1_sub);
7187  sinfo_free_table(&x2);
7188 
7189  return np;
7190  }
7191 
7192  return np;
7193  cleanup:
7194 
7195  sinfo_free_table(&x1_sub);
7196  sinfo_free_table(&x2);
7197  return -1;
7198 
7199 }
7200 
7201 static cpl_table*
7202 sinfo_table_extract_rest(cpl_table* inp,
7203  cpl_table* low,
7204  cpl_table* med,
7205  const double wtol)
7206 {
7207 
7208  cpl_table* out=NULL;
7209  double* pinp=NULL;
7210  double* plow=NULL;
7211  double* pmed=NULL;
7212  int nlow=0;
7213  int nmed=0;
7214 
7215  int nrow=0;
7216  int i=0;
7217  int k=0;
7218  cpl_table* tmp=NULL;
7219 
7220  cknull(inp,"null input table");
7221 
7222 
7223  check_nomsg(tmp=cpl_table_duplicate(inp));
7224  check_nomsg(nrow=cpl_table_get_nrow(tmp));
7225  check_nomsg(cpl_table_new_column(tmp,"SEL",CPL_TYPE_INT));
7226  check_nomsg(cpl_table_fill_column_window_int(tmp,"SEL",0,nrow,0));
7227 
7228  check_nomsg(pinp=cpl_table_get_data_double(inp,"WAVE"));
7229  check_nomsg(plow=cpl_table_get_data_double(low,"WAVE"));
7230  check_nomsg(pmed=cpl_table_get_data_double(med,"WAVE"));
7231  nlow=cpl_table_get_nrow(low);
7232 
7233 
7234  //check_nomsg(cpl_table_save(low,NULL,NULL,"out_low.fits",CPL_IO_DEFAULT));
7235  if(nlow > 0) {
7236  k=0;
7237  for(i=0;i<nrow;i++) {
7238  if(fabs(pinp[i]-plow[k]) < wtol) {
7239  cpl_table_set_int(tmp,"SEL",k,-1);
7240  k++;
7241  }
7242  }
7243  }
7244  nmed=cpl_table_get_nrow(med);
7245 
7246  k=0;
7247  if(nmed > 0) {
7248  for(i=0;i<nrow;i++) {
7249  if(fabs(pinp[i]-pmed[k]) < wtol) {
7250  cpl_table_set_int(tmp,"SEL",k,-1);
7251  k++;
7252  }
7253  }
7254  }
7255 
7256  check_nomsg(cpl_table_and_selected_int(tmp,"SEL",CPL_GREATER_THAN,-1));
7257  check_nomsg(out=cpl_table_extract_selected(tmp));
7258  sinfo_free_table(&tmp);
7259  check_nomsg(cpl_table_erase_column(out,"SEL"));
7260 
7261  return out;
7262 
7263  cleanup:
7264  sinfo_free_table(&tmp);
7265  return NULL;
7266 
7267 }
7268