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