sinfo_skycor.c

00001 /* $Id: sinfo_skycor.c,v 1.45 2009/09/03 15:04:48 kmirny Exp $
00002  *
00003  * This file is part of the SINFONI Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: kmirny $
00023  * $Date: 2009/09/03 15:04:48 $
00024  * $Revision: 1.45 $
00025  * $Name: sinfo-2_2_5 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  ----------------------------------------------------------------------------*/
00035 #include <math.h>
00036 #include <cpl.h>
00037 
00038 #include <irplib_utils.h>
00039 
00040 #include <sinfo_skycor.h>
00041 #include <sinfo_new_cube_ops.h>
00042 #include "sinfo_pfits.h"
00043 #include "sinfo_functions.h"
00044 
00045 #include "sinfo_msg.h"
00046 #include "sinfo_error.h"
00047 #include "sinfo_globals.h"
00048 #include "sinfo_utils_wrappers.h"
00049 #include "sinfo_utl_cube2spectrum.h"
00050 #include "sinfo_pro_types.h"
00051 /*-----------------------------------------------------------------------------
00052                                 Defines
00053  ----------------------------------------------------------------------------*/
00054 
00055 #define BAND_H_WAVE_MIN 1.445 //not used
00056 #define BAND_H_WAVE_MAX 1.820 //not used
00057 
00058 #define BAND_K_WAVE_MIN 1.945 //not used
00059 #define BAND_K_WAVE_MAX 2.460 //not used
00060 
00061 #define BAND_J_WAVE_MIN 1.445 //not used
00062 #define BAND_J_WAVE_MAX 1.82  //not used
00063 
00064 #define SINFO_FIT_BKG_TEMP 280.
00065 #define SKY_THRES 0.95
00066 #define SKY_LINE_MAX_CUT 4      /* this should be 4 */
00067 #define SKY_LINE_MIN_CUT 4      /* this should be 4 */
00068 
00069 
00070 #define XCOR_YSHIFT_KS_CLIP 5      /* this should be 5 */
00071 
00072 
00073 #define HPLANK 6.62606876e-34;   // J s
00074 #define CLIGHT 2.99792458e+08;   // m / s
00075 #define KBOLTZ 1.3806503e-23;    // J / K
00076 #define AMOEBA_FTOL 1.e-5
00077 #define NBOUND 14
00078 #define NROT   25
00079 #define N_ITER_FIT_LM 15
00080 #define N_ITER_FIT_AMOEBA 10
00081 
00082 double sinfo_scale_fct=1;
00083 static cpl_vector* sa_vx=NULL;
00084 static cpl_vector* sa_vy=NULL;
00085 
00086 static cpl_vector* sa_ox=NULL;
00087 static cpl_vector* sa_oy=NULL;
00088 static cpl_vector* sa_sy=NULL;
00089 
00090 /*-----------------------------------------------------------------------------
00091                             Functions prototypes
00092 -----------------------------------------------------------------------------*/
00093 cpl_vector* sinfo_sky_background_estimate(cpl_vector *spectrum,
00094                                              int msize,
00095                                              int fsize);
00096 
00097 
00098 static int
00099 sinfo_scales_obj_sky_cubes(cpl_imagelist* obj_cub,
00100                             cpl_imagelist* sky_cub,
00101                             cpl_table* bkg,
00102                             cpl_table* rscale,
00103                             cpl_imagelist** obj_cor);
00104 
00105 static int
00106 sinfo_sub_thr_bkg_from_obj_cube(cpl_imagelist* obj_cub,
00107                 cpl_table* int_sky,
00108                 cpl_imagelist** obj_cor);
00109 
00110 static cpl_vector*
00111 sinfo_filter_min(const cpl_vector* vi, const int size);
00112 
00113 static cpl_vector*
00114 sinfo_filter_max(const cpl_vector* vi, const int size);
00115 
00116 static cpl_vector*
00117 sinfo_filter_smo(const cpl_vector* vi, const int size);
00118 
00119 static cpl_imagelist*
00120 sinfo_cube_zshift_simple(cpl_imagelist* inp,
00121                         const float shift);
00122 
00123 static void
00124 sinfo_optimise_sky_sub(const double wtol,
00125                        const double line_hw,
00126                        const int method,
00127                        const int do_rot,
00128                        cpl_table* lrange,
00129                        cpl_table* lambda,
00130                        cpl_table* lr41,
00131                        cpl_table* lr52,
00132                        cpl_table* lr63,
00133                        cpl_table* lr74,
00134                        cpl_table* lr02,
00135                        cpl_table* lr85,
00136                        cpl_table* lr20,
00137                        cpl_table* lr31,
00138                        cpl_table* lr42,
00139                        cpl_table* lr53,
00140                        cpl_table* lr64,
00141                        cpl_table* lr75,
00142                        cpl_table* lr86,
00143                        cpl_table* lr97,
00144                        cpl_table* lr00,
00145                        cpl_table** int_obj,
00146                        cpl_table** int_sky,
00147                        cpl_table** rscale);
00148 
00149 static void
00150 sinfo_shift_sky(cpl_frame** sky_frm,
00151                 cpl_table** int_sky,
00152                 const double zshift);
00153 
00154 static double
00155 sinfo_xcorr(cpl_table* int_obj,
00156             cpl_table* int_sky,
00157             cpl_table* lambda,
00158             const double dispersion,
00159             const double line_hw);
00160 
00161 static cpl_table*
00162 sinfo_interpolate_sky(const cpl_table* inp,const cpl_table* lambdas);
00163 
00164 static int
00165 sinfo_check_screw_values(cpl_table** int_obj,
00166                          cpl_table** int_sky,
00167                          cpl_table* grange,
00168                          const double wtol);
00169 
00170 static int
00171 sinfo_choose_good_sky_pixels(cpl_frame* obj_frm,
00172                              cpl_image* r_img,
00173                              cpl_image* g_img,
00174                              const double min_frac,
00175                              cpl_image** mask);
00176 
00177 
00178 static int
00179 sinfo_sum_spectra(const cpl_frame* obj,
00180                   const cpl_frame* sky,
00181                   cpl_image* mask,
00182                   cpl_table* wrange,
00183                   const int llx,
00184                   const int lly,
00185                   const int urx,
00186                   const int ury,
00187                   cpl_table** int_obj,
00188                   cpl_table** int_sky);
00189 
00190 int
00191 sinfo_thermal_background2(cpl_table* int_sky,
00192                          cpl_table* lambda,
00193                          cpl_table* lrange,
00194               cpl_table** bkg);
00195 
00196 static int
00197 sinfo_thermal_background(cpl_table* int_sky,
00198                          cpl_table* lambda,
00199                          cpl_table* lrange,
00200                          const double temp,
00201                          const int niter,
00202                          const int filter_width,
00203                          const double wtol,
00204                          cpl_table** bkg,
00205                          int* success_fit);
00206 
00207 static int
00208 sinfo_object_flag_sky_pixels(cpl_frame* obj_frm,
00209                              cpl_table* lambda,
00210                              cpl_table* mrange,
00211                  cpl_imagelist* flag_data,
00212                              const double tol,
00213                              cpl_image** g_img,
00214                              cpl_image** r_img,
00215                              cpl_image** image);
00216 
00217 static int
00218 sinfo_object_flag_low_values(cpl_frame* obj_frm,
00219                              const double cnt,
00220                              const double sig,
00221                              cpl_imagelist** flag_data);
00222 
00223 static int
00224 sinfo_object_estimate_noise(cpl_frame* obj_frm, const int obj_noise_fit,
00225                             double* centre, double* noise);
00226 
00227 
00228 
00229 static int
00230 sinfo_set_ranges(cpl_frame* obj_frm,
00231                  cpl_frame* sky_frm,
00232                  cpl_parameterlist* cfg,
00233                  cpl_table** lambda,
00234                  cpl_table** lr41,
00235                  cpl_table** lr52,
00236                  cpl_table** lr63,
00237                  cpl_table** lr74,
00238                  cpl_table** lr02,
00239                  cpl_table** lr85,
00240                  cpl_table** lr20,
00241                  cpl_table** lr31,
00242                  cpl_table** lr42,
00243                  cpl_table** lr53,
00244                  cpl_table** lr64,
00245                  cpl_table** lr75,
00246                  cpl_table** lr86,
00247                  cpl_table** lr97,
00248                  cpl_table** lr00,
00249                  cpl_table** lrange,
00250                  cpl_table** grange,
00251                  cpl_table** lambdas,
00252                  cpl_table** mrange,
00253                  int* sky_interp_sw,
00254                  double* dispersion);
00255 
00256 
00257 static cpl_table*
00258 sinfo_table_extract_rest(cpl_table* inp,
00259                          cpl_table* low,
00260                          cpl_table* med,
00261                          const double wtol);
00262 
00263 static int
00264 sinfo_get_sub_regions(cpl_table* sky,
00265                       cpl_table* x1,
00266                       cpl_table* pos,
00267                       const double wtol,
00268                       const int npixw,
00269                       cpl_table** sub_regions);
00270 
00271 
00272 static int
00273 sinfo_get_obj_sky_wav_sub(cpl_table* obj,
00274                           cpl_table* sky,
00275                           cpl_table* wav,
00276                           cpl_table* sel,
00277                           const double wtol,
00278                           cpl_table** sub_obj,
00279                           cpl_table** sub_sky,
00280                           cpl_table** sub_wav);
00281 
00282 
00283 static cpl_table*
00284 sinfo_find_rot_waves(const double w_rot[],
00285                      const int npix_w,
00286                      const double w_step,
00287                      cpl_table* range);
00288 static int
00289 sinfo_compute_line_ratio(cpl_table* obj,
00290                          cpl_table* sky,
00291                          const double wtol,
00292                          const int meth,
00293                          const cpl_table* sel_regions,
00294                          cpl_table* cont_regions,
00295                          double* r);
00296 
00297 static cpl_table*
00298 sinfo_table_subtract_continuum(cpl_table* lin,cpl_table* cnt);
00299 
00300 static double
00301 sinfo_fit_bkg(double p[]);
00302 
00303 static double
00304 sinfo_fit_sky(double p[]);
00305 
00306 static int
00307 sinfo_get_line_ratio_amoeba(cpl_table* obj,
00308                             cpl_table* sky,
00309                             double* r);
00310 
00311 static cpl_table*
00312 sinfo_table_interpol(cpl_table* obj_lin,
00313                      cpl_table* obj_cnt,
00314                      cpl_table* sky_lin,
00315                      cpl_table* sky_cnt,
00316                      const double r);
00317 
00318 
00319 static int
00320 sinfo_get_line_ratio(cpl_table* obj_lin,
00321                      cpl_table* obj_cnt,
00322                      cpl_table* sky_lin,
00323                      cpl_table* sky_cnt,
00324                      const int method,
00325                      double* r);
00326 
00327 static cpl_table*
00328 sinfo_table_shift_simple(cpl_table* inp,
00329                          const char* col,
00330                          const double shift);
00331 /*
00332 static int
00333 sinfo_table_set_column_invalid(cpl_table** int_sky,const char* col);
00334 */
00335 static int
00336 sinfo_table_set(cpl_table** out,
00337                 const cpl_table* ref,
00338                 const double val,
00339                 const double tol);
00340 
00341 static int
00342 sinfo_table_threshold(cpl_table** t,
00343                       const char* column,
00344                       const double low_cut,
00345                       const double hig_cut,
00346                       const double low_ass,
00347                       const double hig_ass);
00348 
00349 
00350 
00351 
00352 static double sinfo_fac(const double x, const double t);
00353 
00354 static int sinfo_fitbkg(const double x[],
00355                         const double a[],
00356                         double *result);
00357 static int sinfo_fitbkg_derivative(const double x[],
00358                                    const double a[],
00359                        double result[]);
00360 
00361 
00362 static int
00363 sinfo_convolve_kernel(cpl_table** t, const int rad);
00364 int
00365 sinfo_convolve_kernel2(cpl_table** t, const int rad);
00366 
00367 int
00368 sinfo_convolve_gauss(cpl_table** t, const int rad, const double fwhm);
00369 int
00370 sinfo_convolve_exp(cpl_table** t, const int rad, const double fwhm);
00371 
00372 static int
00373 sinfo_table_sky_obj_flag_nan(cpl_table** s,cpl_table** o, cpl_table** w);
00374 
00375 static int
00376 sinfo_table_set_nan_out_min_max(cpl_table** s,
00377                                 const char* c,
00378                                 const double min,
00379                                 const double max);
00380 
00381 
00382 
00383 
00384 static double
00385 sinfo_gaussian_amp(double area,double sigma,double x,double x0,double off);
00386 static double
00387 sinfo_gaussian_area(double amp,double sigma,double x,double x0,double off);
00388 
00389 int
00390 sinfo_table_smooth_column(cpl_table** t, const char* c, const int r);
00391 
00392 static int
00393 sinfo_image_flag_nan(cpl_image** im);
00394 
00395 static int
00396 sinfo_table_flag_nan(cpl_table** t,const char* label);
00397 
00398 
00399 
00400 static int
00401 sinfo_cnt_mask_thresh_and_obj_finite(const cpl_image* mask,
00402                                      const double t,
00403                                      const cpl_image* obj);
00404 
00405 
00406 
00407 
00408 static cpl_table*
00409 sinfo_interpolate(const cpl_table* inp,
00410                   const cpl_table* lambdas,
00411                   const char* name,
00412                   const char* method);
00413 
00414 static cpl_table*
00415 sinfo_image2table(const cpl_image* im);
00416 
00417 static int
00418 sinfo_table_extract_finite(const cpl_table* in1,
00419                            const cpl_table* in2,
00420                                  cpl_table** ou1,
00421                                  cpl_table** ou2);
00422 
00423 static cpl_table*
00424 sinfo_slice_z(const cpl_imagelist* cin,const int i,const int j);
00425 
00426 
00427 
00428 static cpl_imagelist*
00429 sinfo_imagelist_select_range(const cpl_imagelist* inp,
00430                                   const cpl_table* full,
00431                                   const cpl_table* good,
00432                                   const double tol);
00433 
00434 
00435 
00436 static cpl_table*
00437 sinfo_table_select_range(cpl_table* inp,
00438                               cpl_table* ref,
00439                               const double tol);
00440 
00441 static int
00442 sinfo_table_fill_column_over_range(cpl_table** inp,
00443                                    const cpl_table* ref,
00444                                    const char* col,
00445                                    const double val,
00446                                    const double tol);
00447 
00448 
00449 
00450 
00451 static int
00452 sinfo_table_column_dindgen(cpl_table** t, const char* label);
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 /*---------------------------------------------------------------------------*/
00472 /*---------------------------------------------------------------------------*/
00481 sinfo_skycor_qc*
00482 sinfo_skycor_qc_new(void)
00483  {
00484    sinfo_skycor_qc * sqc;
00485    sqc= cpl_malloc(sizeof(sinfo_skycor_qc));
00486 
00487    sqc->th_fit=0;
00488 
00489    return sqc;
00490 
00491 }
00498 void
00499 sinfo_skycor_qc_delete(sinfo_skycor_qc** sqc)
00500 {
00501   if((*sqc) != NULL) {
00502     cpl_free(*sqc);
00503     *sqc=NULL;
00504   }
00505 }
00506 
00507 
00508 
00519 /*---------------------------------------------------------------------------*/
00520 int
00521 sinfo_skycor(cpl_parameterlist * config,
00522              cpl_frame* obj_frm,
00523              cpl_frame* sky_frm,
00524              sinfo_skycor_qc* sqc,
00525              cpl_imagelist** obj_cor,
00526              cpl_table** int_obj)
00527 {
00528 
00529   cpl_table* bkg=NULL;
00530 
00531   cpl_table* lambda=NULL;
00532   cpl_table* lr41=NULL;
00533   cpl_table* lr52=NULL;
00534   cpl_table* lr63=NULL;
00535   cpl_table* lr74=NULL;
00536   cpl_table* lr02=NULL;
00537   cpl_table* lr85=NULL;
00538   cpl_table* lr20=NULL;
00539   cpl_table* lr31=NULL;
00540   cpl_table* lr42=NULL;
00541   cpl_table* lr53=NULL;
00542   cpl_table* lr64=NULL;
00543   cpl_table* lr75=NULL;
00544   cpl_table* lr86=NULL;
00545   cpl_table* lr97=NULL;
00546   cpl_table* lr00=NULL;
00547   cpl_table* lrange=NULL;
00548   cpl_table* mrange=NULL;
00549   cpl_table* grange=NULL;
00550   cpl_table* lambdas=NULL;
00551 
00552   cpl_table* int_sky=NULL;
00553 
00554   cpl_image* mask=NULL;
00555   cpl_image* gpix=NULL;
00556   cpl_image* ratio=NULL;
00557   cpl_image* ima_sky=NULL;
00558   cpl_imagelist* fdata=NULL;
00559   cpl_table* rscale=NULL;
00560   cpl_parameter* p=NULL;
00561 
00562   int th_fit=0;
00563   double dispersion=0;
00564   double noise=0;
00565   //double temp=252.69284;
00566   double centre=0;
00567   int sky_interp_sw=0;
00568   double wshift=0;
00569   double pshift=0;
00570   int method=0;
00571   int do_rot=0;
00572   int obj_noise_fit=0;
00573   int niter=3;
00574   double min_frac=0.8;
00575   double line_hw=7;
00576   double fit_temp=280;
00577   int filter_width=SINFO_SKY_BKG_FILTER_WIDTH;
00578   int llx=0;
00579   int lly=0;
00580   int urx=64;
00581   int ury=64;
00582   cpl_imagelist* obj_cub=NULL;
00583   cpl_imagelist* sky_cub=NULL;
00584   int sub_thr_bkg=0;
00585 
00586 
00587   check_nomsg(p=cpl_parameterlist_find(config,
00588                 "sinfoni.sinfo_utl_skycor.min_frac"));
00589   check_nomsg(min_frac=cpl_parameter_get_double(p));
00590 
00591   check_nomsg(p=cpl_parameterlist_find(config,
00592                 "sinfoni.sinfo_utl_skycor.line_half_width"));
00593   check_nomsg(line_hw=cpl_parameter_get_double(p));
00594 
00595 
00596 
00597   check_nomsg(p=cpl_parameterlist_find(config,
00598                 "sinfoni.sinfo_utl_skycor.sky_bkg_filter_width"));
00599   check_nomsg(filter_width=cpl_parameter_get_int(p));
00600 
00601   check_nomsg(p=cpl_parameterlist_find(config,
00602                 "sinfoni.sinfo_utl_skycor.scale_method"));
00603   check_nomsg(method=cpl_parameter_get_int(p));
00604 
00605 
00606 
00607   check_nomsg(p=cpl_parameterlist_find(config,
00608                 "sinfoni.sinfo_utl_skycor.rot_cor"));
00609   check_nomsg(do_rot=cpl_parameter_get_bool(p));
00610 
00611 
00612   check_nomsg(p=cpl_parameterlist_find(config,
00613                 "sinfoni.sinfo_utl_skycor.sub_thr_bkg_from_obj"));
00614   check_nomsg(sub_thr_bkg=cpl_parameter_get_bool(p));
00615 
00616 
00617   check_nomsg(p=cpl_parameterlist_find(config,
00618                 "sinfoni.sinfo_utl_skycor.fit_obj_noise"));
00619   check_nomsg(obj_noise_fit=cpl_parameter_get_bool(p));
00620 
00621 
00622   check_nomsg(p=cpl_parameterlist_find(config,
00623                 "sinfoni.sinfo_utl_skycor.niter"));
00624   check_nomsg(niter=cpl_parameter_get_int(p));
00625 
00626 
00627   check_nomsg(p=cpl_parameterlist_find(config,
00628                 "sinfoni.sinfo_utl_skycor.pshift"));
00629   check_nomsg(pshift=cpl_parameter_get_double(p));
00630 
00631 
00632 
00633   check_nomsg(p=cpl_parameterlist_find(config,
00634                 "sinfoni.sinfo_utl_skycor.llx"));
00635   check_nomsg(llx=cpl_parameter_get_int(p));
00636 
00637 
00638   check_nomsg(p=cpl_parameterlist_find(config,
00639                 "sinfoni.sinfo_utl_skycor.lly"));
00640   check_nomsg(lly=cpl_parameter_get_int(p));
00641 
00642 
00643   check_nomsg(p=cpl_parameterlist_find(config,
00644                 "sinfoni.sinfo_utl_skycor.urx"));
00645   check_nomsg(urx=cpl_parameter_get_int(p));
00646 
00647 
00648   check_nomsg(p=cpl_parameterlist_find(config,
00649                 "sinfoni.sinfo_utl_skycor.ury"));
00650   check_nomsg(ury=cpl_parameter_get_int(p));
00651 
00652   // set wavelength ranges
00653   sinfo_msg("Set wavelength ranges");
00654   ck0(sinfo_set_ranges(obj_frm,sky_frm,config,&lambda,
00655                        &lr41,&lr52,&lr63,&lr74,&lr02,&lr85,&lr20,&lr31,&lr42,
00656                        &lr53,&lr64,&lr75,&lr86,&lr97,&lr00,
00657                        &lrange,&grange,&lambdas,&mrange,&sky_interp_sw,
00658                        &dispersion),"Setting wavelength ranges");
00659   //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange.fits",
00660   //CPL_IO_DEFAULT));
00661 
00662   /*
00663   sinfo_msg("lr20=%d",cpl_table_get_nrow(lr20));
00664   sinfo_msg("lr31=%d",cpl_table_get_nrow(lr31));
00665   sinfo_msg("lr42=%d",cpl_table_get_nrow(lr42));
00666   sinfo_msg("lr53=%d",cpl_table_get_nrow(lr53));
00667   sinfo_msg("lr64=%d",cpl_table_get_nrow(lr64));
00668   sinfo_msg("lr75=%d",cpl_table_get_nrow(lr75));
00669   sinfo_msg("lr86=%d",cpl_table_get_nrow(lr86));
00670   sinfo_msg("lr97=%d",cpl_table_get_nrow(lr97));
00671   sinfo_msg("lr00=%d",cpl_table_get_nrow(lr00));
00672 
00673   sinfo_msg("min_lrange=%f",cpl_table_get_column_min(lrange,"INDEX"));
00674   sinfo_msg("min_grange=%f",cpl_table_get_column_min(grange,"INDEX"));
00675   sinfo_msg("min_srange=%f",cpl_table_get_column_min(lambdas,"WAVE"));
00676   sinfo_msg("min_mrange=%f",cpl_table_get_column_min(mrange,"INDEX"));
00677 
00678   sinfo_msg("max_lrange=%f",cpl_table_get_column_max(lrange,"INDEX"));
00679   sinfo_msg("max_grange=%f",cpl_table_get_column_max(grange,"INDEX"));
00680   sinfo_msg("max_srange=%f",cpl_table_get_column_max(lambdas,"WAVE"));
00681   sinfo_msg("max_mrange=%f",cpl_table_get_column_max(mrange,"INDEX"));
00682   */
00683 
00684   sinfo_msg("Estimate noise");
00685   ck0(sinfo_object_estimate_noise(obj_frm,obj_noise_fit,&centre,&noise),
00686                                   "Estimating noise");
00687 
00688   sinfo_msg("Background=%f Noise=%f",centre,noise);
00689   sinfo_msg("Flag object low_levels");
00690   ck0(sinfo_object_flag_low_values(obj_frm,centre,noise,&fdata),
00691       "Flagging low pix");
00692 
00693   //cpl_imagelist_save(fdata,"out_fdata.fits",
00694   //                   CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00695 
00696 
00697   sinfo_msg("Flag sky pixels");
00698   ck0(sinfo_object_flag_sky_pixels(obj_frm,lambda,mrange,fdata,dispersion,
00699                                    &gpix,&ratio,&ima_sky),
00700                                    "Flagging sky pixels");
00701 
00702   //cpl_image_save(gpix,"out_gpix.fits",CPL_BPP_IEEE_FLOAT,
00703   //                 NULL,CPL_IO_DEFAULT);
00704   //cpl_image_save(ratio,"out_ratio.fits",CPL_BPP_IEEE_FLOAT,
00705   //                 NULL,CPL_IO_DEFAULT);
00706   //cpl_image_save(ima_sky,"out_ima_sky.fits",
00707   //               CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00708 
00709 
00710 
00711 
00712   // choose pixels which seems to be good sky pixels
00713   // (95% spectral pixels are flagged)
00714   sinfo_msg("Choose good sky (with > 95%% good spectral) pixels");
00715   ck0(sinfo_choose_good_sky_pixels(obj_frm,ratio,gpix,min_frac,&mask),
00716       "Choosing good sky pixels");
00717 
00718   //cpl_image_save(mask,"out_mask.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00719 
00720   // threshold ratio for fraction 'minfract' of spatial pixels to be 'sky'
00721   //sinfo_msg("To do: flag_threshold_sky_pixels");
00722 
00723 
00724   // sum spectra of flagged pixels in object and sky frames
00725   sinfo_msg("Sum obj and sky spectra");
00726   ck0(sinfo_sum_spectra(obj_frm,sky_frm,mask,lambda,llx,lly,urx,ury,int_obj,
00727             &int_sky),"summing obj & sky spectra");
00728 
00729   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
00730   // CPL_IO_DEFAULT));
00731   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
00732   //CPL_IO_DEFAULT));
00733 
00734    // Computes thermal background
00735   sinfo_msg("Computes thermal background");
00736   /*
00737   ck0(sinfo_thermal_background2(int_sky,lambda,lrange,&bkg),
00738      "getting termal bkg");
00739   */
00740 
00741   ck0(sinfo_thermal_background(int_sky,lambda,lrange,fit_temp,niter,
00742                                filter_width,dispersion,&bkg,&th_fit),
00743       "getting termal bkg");
00744 
00745 
00746   check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_SKY_ORG",int_sky,"INT"));
00747   check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_BKG_FIT",bkg,"INT2"));
00748   check_nomsg(cpl_table_duplicate_column(*int_obj,"INT_BKG_SMO",int_sky,
00749                                          "INT_BKG_SMO"));
00750 
00751   sqc->th_fit=th_fit;
00752   //check_nomsg(cpl_table_save(bkg,NULL,NULL,"out_thermal_background.fits",
00753   //CPL_IO_DEFAULT));
00754 
00755 
00756   /*
00757   ck0(sinfo_pro_save_tbl(bkg,set,set,"out_thermal_background.fits",
00758              "THERMAL_BACKGROUND",NULL,cpl_func,config),
00759       "Error saving %s","THERMAL_BACKGROUND");
00760   */
00761 
00762   sinfo_msg("Subtracts thermal background from integrated OH spectrum");
00763   //sinfo_msg("nrow=%d %d",cpl_table_get_nrow(int_sky),
00764   //                       cpl_table_get_nrow(bkg));
00765   check_nomsg(cpl_table_duplicate_column(int_sky,"BKG",bkg,"INT2"));
00766   check_nomsg(cpl_table_duplicate_column(int_sky,"INT0",int_sky,"INT"));
00767   check_nomsg(cpl_table_subtract_columns(int_sky,"INT","BKG"));
00768 
00769 
00770 
00771   //check_nomsg(cpl_table_duplicate_column(int_obj,"INT",
00772   //                                         int_obj,"INT_OBJ_COR"));
00773 
00774   if(sub_thr_bkg == 1) {
00775     check_nomsg(cpl_table_duplicate_column(*int_obj,"THR_BKG",bkg,"INT2"));
00776     check_nomsg(cpl_table_subtract_columns(*int_obj,"INT","THR_BKG"));
00777   }
00778 
00779   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
00780   //CPL_IO_DEFAULT));
00781   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
00782   //CPL_IO_DEFAULT));
00783 
00784 
00785   //check_nomsg(cpl_table_erase_column(int_sky,"BKG"));
00786   //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange_6.fits",
00787   //CPL_IO_DEFAULT));
00788 
00789    //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_sub.fits",
00790    //CPL_IO_DEFAULT));
00791 
00792 
00793 
00794   // check for screw values at ends of spectrum
00795   sinfo_msg("Checks for screw values at ends of spectrum");
00796   sinfo_check_screw_values(int_obj,&int_sky,grange,dispersion);
00797   //check_nomsg(cpl_table_save(grange, NULL, NULL, "out_grange_7.fits",
00798   //CPL_IO_DEFAULT));
00799   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj_chk.fits",
00800   //CPL_IO_DEFAULT));
00801   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_chk.fits",
00802   //CPL_IO_DEFAULT));
00803 
00804 
00805 
00806   if(sky_interp_sw == 1) {
00807     sinfo_msg("Interpolate sky if necessary");
00808     sinfo_interpolate_sky(int_sky,lambdas);
00809   }
00810 
00811 
00812   sinfo_msg("Crosscorrelate obj & sky to check for lambda offset");
00813   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj_chk.fits",
00814   //CPL_IO_DEFAULT));
00815   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky_chk.fits",
00816   //CPL_IO_DEFAULT));
00817   check_nomsg(wshift=sinfo_xcorr(*int_obj,int_sky,lambda,dispersion,line_hw));
00818 
00819 
00820   //wshift=-1.7164495*dispersion;
00821   sinfo_msg("Dispersion=%f",dispersion);
00822   if(pshift == 0) {
00823     pshift=wshift/dispersion;
00824   }
00825   sinfo_msg("Shift sky of %f pixels toward object",pshift);
00826 
00827   check_nomsg(sinfo_shift_sky(&sky_frm,&int_sky,pshift));
00828   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_pip3_int_obj.fits",
00829   //CPL_IO_DEFAULT));
00830   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_pip3_int_sky.fits",
00831   //CPL_IO_DEFAULT));
00832 
00833 
00834   //DEBUG
00835   sinfo_msg("Optimise sky subtraction");
00836   check_nomsg(sinfo_optimise_sky_sub(dispersion,line_hw,method,do_rot,
00837                                      lrange,lambda,
00838                                      lr41,lr52,lr63,lr74,lr02,lr85,
00839                                      lr20,lr31,lr42,lr53,lr64,lr75,
00840                      lr86,lr97,lr00,int_obj,&int_sky,
00841                      &rscale));
00842 
00843 
00844   //check_nomsg(cpl_table_save(*int_obj, NULL, NULL, "out_int_obj.fits",
00845   //CPL_IO_DEFAULT));
00846   //check_nomsg(cpl_table_save(int_sky, NULL, NULL, "out_int_sky.fits",
00847   //CPL_IO_DEFAULT));
00848 
00849 
00850   sinfo_msg("Apply same scaling to whole cubes");
00851 
00852 
00853   cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
00854                                           CPL_TYPE_DOUBLE,0));
00855   cknull_nomsg(sky_cub=cpl_imagelist_load(cpl_frame_get_filename(sky_frm),
00856                                           CPL_TYPE_DOUBLE,0));
00857 
00858 
00859 
00860 
00861   if(sub_thr_bkg == 1) {
00862     ck0_nomsg(sinfo_sub_thr_bkg_from_obj_cube(obj_cub,int_sky,obj_cor));
00863   } else {
00864     check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
00865   }
00866 
00867   ck0_nomsg(sinfo_scales_obj_sky_cubes(*obj_cor,sky_cub,bkg,rscale,obj_cor));
00868 
00869   check_nomsg(cpl_table_name_column(*int_obj,"INT","INT_OBJ_ORG"));
00870   check_nomsg(cpl_table_name_column(*int_obj,"INTC","INT_OBJ_COR"));
00871   check_nomsg(cpl_table_name_column(*int_obj,"SKYC","INT_SKY_COR"));
00872 
00873 
00874  cleanup:
00875   sinfo_free_table(&rscale);
00876   sinfo_free_imagelist(&fdata);
00877 
00878   sinfo_free_table(&bkg);
00879   sinfo_free_table(&lambda);
00880   sinfo_free_table(&lrange);
00881   sinfo_free_table(&mrange);
00882   sinfo_free_table(&grange);
00883   sinfo_free_table(&lambdas);
00884   sinfo_free_image(&mask);
00885 
00886   sinfo_free_table(&lr41);
00887   sinfo_free_table(&lr52);
00888   sinfo_free_table(&lr63);
00889   sinfo_free_table(&lr74);
00890   sinfo_free_table(&lr02);
00891   sinfo_free_table(&lr85);
00892   sinfo_free_table(&lr20);
00893   sinfo_free_table(&lr31);
00894   sinfo_free_table(&lr42);
00895   sinfo_free_table(&lr53);
00896   sinfo_free_table(&lr64);
00897   sinfo_free_table(&lr75);
00898   sinfo_free_table(&lr86);
00899   sinfo_free_table(&lr97);
00900   sinfo_free_table(&lr00);
00901 
00902   sinfo_free_image(&gpix);
00903   sinfo_free_image(&ratio);
00904   sinfo_free_image(&ima_sky);
00905   //sinfo_free_table(&int_obj);
00906   sinfo_free_table(&int_sky);
00907 
00908   sinfo_free_imagelist(&obj_cub);
00909   sinfo_free_imagelist(&sky_cub);
00910 
00911   if (cpl_error_get_code() != CPL_ERROR_NONE) {
00912     return -1;
00913   } else {
00914     return 0;
00915   }
00916 
00917 
00918 }
00919 
00920 /*-------------------------------------------------------------------------*/
00932 /*--------------------------------------------------------------------------*/
00933 
00934 
00935 static int
00936 sinfo_sub_thr_bkg_from_obj_cube(cpl_imagelist* obj_cub,
00937                 cpl_table* int_sky,
00938                 cpl_imagelist** obj_cor)
00939 
00940 {
00941   double* pthr_bkg=NULL;
00942   int zsz=0;
00943   int k=0;
00944   cpl_image* imgo=NULL;
00945 
00946   check_nomsg(pthr_bkg=cpl_table_get_data_double(int_sky,"BKG"));
00947   check_nomsg(zsz=cpl_imagelist_get_size(obj_cub));
00948   check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
00949 
00950   for(k=0;k<zsz;k++) {
00951     check_nomsg(imgo=cpl_imagelist_get(obj_cub,k));
00952     check_nomsg(cpl_image_subtract_scalar(imgo,pthr_bkg[k]));
00953     check_nomsg(cpl_imagelist_set(*obj_cor,imgo,k));
00954   }
00955 
00956  cleanup:
00957   if (cpl_error_get_code() != CPL_ERROR_NONE) {
00958     return -1;
00959   } else {
00960     return 0;
00961   }
00962 
00963 }
00964 
00965 /*-------------------------------------------------------------------------*/
00996 /*--------------------------------------------------------------------------*/
00997 
00998 
00999 int
01000 sinfo_set_ranges(cpl_frame* obj_frm,
01001                  cpl_frame* sky_frm,
01002                  cpl_parameterlist* cfg,
01003                  cpl_table** lambda,
01004                  cpl_table** lr41,
01005                  cpl_table** lr52,
01006                  cpl_table** lr63,
01007                  cpl_table** lr74,
01008                  cpl_table** lr02,
01009                  cpl_table** lr85,
01010                  cpl_table** lr20,
01011                  cpl_table** lr31,
01012                  cpl_table** lr42,
01013                  cpl_table** lr53,
01014                  cpl_table** lr64,
01015                  cpl_table** lr75,
01016                  cpl_table** lr86,
01017                  cpl_table** lr97,
01018                  cpl_table** lr00,
01019                  cpl_table** lrange,
01020                  cpl_table** grange,
01021                  cpl_table** lambdas,
01022                  cpl_table** mrange,
01023                  int* sky_interp_sw,
01024                  double* dispersion)
01025 
01026 {
01027 
01028   cpl_propertylist* plist=NULL;
01029   double crval_obj=0;
01030   double cdelt_obj=0;
01031   double crpix_obj=0;
01032   int xsize_obj=0;
01033   int ysize_obj=0;
01034   int zsize_obj=0;
01035 
01036 
01037   double crval_sky=0;
01038   double cdelt_sky=0;
01039   double crpix_sky=0;
01040   int xsize_sky=0;
01041   int ysize_sky=0;
01042   int zsize_sky=0;
01043 
01044   int nrow=0;
01045   /* wavelength min-max J-H-K band */
01046   const double w_j_min=1.100;
01047   const double w_j_max=1.400;
01048   const double w_h_min=1.445;
01049   const double w_h_max=1.820;
01050   const double w_k_min=1.945;
01051   const double w_k_max=2.460;
01052 
01053   double ws=0;
01054   double we=0;
01055   double mean=0;
01056 
01057   cpl_parameter* p=NULL;
01058 
01059   /* wavelength boundaries between line groups corresponding
01060      to transitions 5-2 to 9-7 */
01061   double w_bound[NBOUND]={1.067,1.125,1.196,1.252,1.289,
01062                           1.400,1.472,1.5543,1.6356,1.7253,
01063                           1.840,1.9570,2.095,2.300};
01064 
01065   cpl_table* tmp_tbl=NULL;
01066   cpl_table* add1=NULL;
01067 
01068 
01069 
01070   /* Get Object relevant information */
01071   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
01072   check_nomsg(crval_obj=sinfo_pfits_get_crval3(plist));
01073   check_nomsg(cdelt_obj=sinfo_pfits_get_cdelt3(plist));
01074   check_nomsg(crpix_obj=sinfo_pfits_get_crpix3(plist));
01075   check_nomsg(xsize_obj=sinfo_pfits_get_naxis1(plist));
01076   check_nomsg(ysize_obj=sinfo_pfits_get_naxis2(plist));
01077   check_nomsg(zsize_obj=sinfo_pfits_get_naxis3(plist));
01078 
01079   sinfo_free_propertylist(&plist);
01080   *dispersion=cdelt_obj;
01081 
01082   /* defines object related wavelength ranges */
01083   check_nomsg(*lambda=cpl_table_new(zsize_obj));
01084   cpl_table_new_column(*lambda,"WAVE",CPL_TYPE_DOUBLE);
01085   cpl_table_new_column(*lambda,"INDEX",CPL_TYPE_DOUBLE);
01086   check_nomsg(sinfo_table_column_dindgen(lambda,"INDEX"));
01087   check_nomsg(sinfo_table_column_dindgen(lambda,"WAVE"));
01088 
01089   check_nomsg(cpl_table_add_scalar(*lambda,"WAVE",1.));
01090   check_nomsg(cpl_table_subtract_scalar(*lambda,"WAVE",crpix_obj));
01091   check_nomsg(cpl_table_multiply_scalar(*lambda,"WAVE",cdelt_obj));
01092   check_nomsg(cpl_table_add_scalar(*lambda,"WAVE",crval_obj));
01093 
01094 
01095 
01096 
01097   cknull_nomsg(*lr41=sinfo_where_tab_min_max(*lambda,
01098                                              "WAVE",
01099                                              CPL_NOT_LESS_THAN,
01100                                              w_j_min,
01101                                              CPL_LESS_THAN,
01102                                              w_bound[0]));
01103 
01104   cknull_nomsg(*lr52=sinfo_where_tab_min_max(*lambda,
01105                                              "WAVE",
01106                                              CPL_NOT_LESS_THAN,
01107                                              w_bound[0],
01108                                              CPL_LESS_THAN,
01109                                              w_bound[1]));
01110 
01111   cknull_nomsg(*lr63=sinfo_where_tab_min_max(*lambda,
01112                                              "WAVE",
01113                                              CPL_NOT_LESS_THAN,
01114                                              w_bound[1],
01115                                              CPL_LESS_THAN,
01116                                              w_bound[2]));
01117 
01118 
01119   cknull_nomsg(*lr74=sinfo_where_tab_min_max(*lambda,
01120                                              "WAVE",
01121                                              CPL_NOT_LESS_THAN,
01122                                              w_bound[2],
01123                                              CPL_LESS_THAN,
01124                                              w_bound[3]));
01125 
01126  cknull_nomsg(*lr20=sinfo_where_tab_min_max(*lambda,
01127                                              "WAVE",
01128                                              CPL_NOT_LESS_THAN,
01129                                              w_bound[3],
01130                                              CPL_LESS_THAN,
01131                                              w_bound[4]));
01132 
01133  cknull_nomsg(*lr02=sinfo_where_tab_min_max(*lambda,
01134                                              "WAVE",
01135                                              CPL_NOT_LESS_THAN,
01136                                              w_bound[4],
01137                                              CPL_LESS_THAN,
01138                                              w_bound[5]));
01139 
01140 
01141  cknull_nomsg(*lr85=sinfo_where_tab_min_max(*lambda,
01142                                              "WAVE",
01143                                              CPL_NOT_LESS_THAN,
01144                                              w_bound[5],
01145                                              CPL_LESS_THAN,
01146                                              w_bound[6]));
01147 
01148   cknull_nomsg(*lr31=sinfo_where_tab_min_max(*lambda,
01149                                              "WAVE",
01150                                              CPL_NOT_LESS_THAN,
01151                                              w_bound[6],
01152                                              CPL_LESS_THAN,
01153                                              w_bound[7]));
01154 
01155   cknull_nomsg(*lr42=sinfo_where_tab_min_max(*lambda,
01156                                              "WAVE",
01157                                              CPL_NOT_LESS_THAN,
01158                                              w_bound[7],
01159                                              CPL_LESS_THAN,
01160                                              w_bound[8]));
01161 
01162   cknull_nomsg(*lr53=sinfo_where_tab_min_max(*lambda,
01163                                              "WAVE",
01164                                              CPL_NOT_LESS_THAN,
01165                                              w_bound[8],
01166                                              CPL_LESS_THAN,
01167                                              w_bound[9]));
01168 
01169   cknull_nomsg(*lr64=sinfo_where_tab_min_max(*lambda,
01170                                              "WAVE",
01171                                              CPL_NOT_LESS_THAN,
01172                                              w_bound[0],
01173                                              CPL_LESS_THAN,
01174                                              w_bound[10]));
01175 
01176   cknull_nomsg(*lr75=sinfo_where_tab_min_max(*lambda,
01177                                              "WAVE",
01178                                              CPL_NOT_LESS_THAN,
01179                                              w_bound[10],
01180                                              CPL_LESS_THAN,
01181                                              w_bound[11]));
01182 
01183   cknull_nomsg(*lr86=sinfo_where_tab_min_max(*lambda,
01184                                              "WAVE",
01185                                              CPL_NOT_LESS_THAN,
01186                                              w_bound[11],
01187                                              CPL_LESS_THAN,
01188                                              w_bound[12]));
01189 
01190   cknull_nomsg(*lr97=sinfo_where_tab_min_max(*lambda,
01191                                              "WAVE",
01192                                              CPL_NOT_LESS_THAN,
01193                                              w_bound[12],
01194                                              CPL_LESS_THAN,
01195                                              w_bound[13]));
01196 
01197   cknull_nomsg(*lr00=sinfo_where_tab_min_max(*lambda,
01198                                              "WAVE",
01199                                               CPL_NOT_LESS_THAN,
01200                                               w_bound[13],
01201                                               CPL_LESS_THAN,
01202                                               w_k_max));
01203 
01204   /* lrange */
01205   cknull_nomsg(*lrange=sinfo_where_tab_min_max(*lambda,
01206                                                "WAVE",
01207                                                CPL_NOT_LESS_THAN,
01208                                                w_j_min,
01209                                                CPL_NOT_GREATER_THAN,
01210                                                w_j_max));
01211 
01212 
01213 
01214   cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
01215                                                "WAVE",
01216                                                CPL_NOT_LESS_THAN,
01217                                                w_h_min,
01218                                                CPL_NOT_GREATER_THAN,
01219                                                w_h_max));
01220 
01221   check_nomsg(nrow=cpl_table_get_nrow(*lrange));
01222   check_nomsg(cpl_table_insert(*lrange,add1,nrow));
01223   sinfo_free_table(&add1);
01224 
01225   cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
01226                                                "WAVE",
01227                                                CPL_NOT_LESS_THAN,
01228                                                w_k_min,
01229                                                CPL_NOT_GREATER_THAN,
01230                                                w_k_max));
01231 
01232 
01233   check_nomsg(nrow=cpl_table_get_nrow(*lrange));
01234   check_nomsg(cpl_table_insert(*lrange,add1,nrow));
01235   sinfo_free_table(&add1);
01236 
01237 
01238   /* mrange */
01239   cknull_nomsg(*grange=sinfo_where_tab_min_max(*lambda,
01240                                                "WAVE",
01241                                                CPL_NOT_LESS_THAN,
01242                                                1.10,
01243                                                CPL_NOT_GREATER_THAN,
01244                                                1.35));
01245 
01246 
01247 
01248 
01249   cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
01250                                                "WAVE",
01251                                                CPL_NOT_LESS_THAN,
01252                                                1.5,
01253                                                CPL_NOT_GREATER_THAN,
01254                                                1.7));
01255 
01256   check_nomsg(nrow=cpl_table_get_nrow(*grange));
01257   check_nomsg(cpl_table_insert(*grange,add1,nrow));
01258   sinfo_free_table(&add1);
01259 
01260 
01261 
01262   cknull_nomsg(add1=sinfo_where_tab_min_max(*lambda,
01263                                             "WAVE",
01264                                             CPL_NOT_LESS_THAN,
01265                                             2.0,
01266                                             CPL_NOT_GREATER_THAN,
01267                                             2.3));
01268 
01269   check_nomsg(nrow=cpl_table_get_nrow(*grange));
01270   check_nomsg(cpl_table_insert(*grange,add1,nrow));
01271   sinfo_free_table(&add1);
01272 
01273 
01274   /* Get Sky relevant information */
01275   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(sky_frm),0));
01276   check_nomsg(crval_sky=sinfo_pfits_get_crval3(plist));
01277   check_nomsg(cdelt_sky=sinfo_pfits_get_cdelt3(plist));
01278   check_nomsg(crpix_sky=sinfo_pfits_get_crpix3(plist));
01279   check_nomsg(xsize_sky=sinfo_pfits_get_naxis1(plist));
01280   check_nomsg(ysize_sky=sinfo_pfits_get_naxis2(plist));
01281   check_nomsg(zsize_sky=sinfo_pfits_get_naxis3(plist));
01282   sinfo_free_propertylist(&plist);
01283 
01284   /* defines sky related wavelength ranges */
01285   check_nomsg(*lambdas=cpl_table_new(zsize_sky));
01286   cpl_table_new_column(*lambdas,"WAVE",CPL_TYPE_DOUBLE);
01287   check_nomsg(sinfo_table_column_dindgen(lambdas,"WAVE"));
01288 
01289   check_nomsg(cpl_table_add_scalar(*lambdas,"WAVE",1.));
01290   check_nomsg(cpl_table_subtract_scalar(*lambdas,"WAVE",crpix_sky));
01291   check_nomsg(cpl_table_multiply_scalar(*lambdas,"WAVE",cdelt_sky));
01292   check_nomsg(cpl_table_add_scalar(*lambdas,"WAVE",crval_sky));
01293 
01294   check_nomsg(p=cpl_parameterlist_find(cfg,"sinfoni.sinfo_utl_skycor.mask_ws"));
01295   check_nomsg(ws=cpl_parameter_get_double(p));
01296   check_nomsg(p=cpl_parameterlist_find(cfg,"sinfoni.sinfo_utl_skycor.mask_we"));
01297   check_nomsg(we=cpl_parameter_get_double(p));
01298   if((ws != SINFO_MASK_WAVE_MIN) || (we != SINFO_MASK_WAVE_MAX)) {
01299     cknull_nomsg(*mrange=sinfo_where_tab_min_max(*lambda,"WAVE",
01300                                                  CPL_NOT_LESS_THAN,ws,
01301                                                  CPL_NOT_GREATER_THAN,we));
01302    } else {
01303      check_nomsg(*mrange=cpl_table_duplicate(*lrange));
01304   }
01305 
01306 
01307   check_nomsg(cpl_table_duplicate_column(*lambda,"WDIFF",*lambdas,"WAVE"));
01308   check_nomsg(cpl_table_subtract_columns(*lambda,"WDIFF","WAVE"));
01309   check_nomsg(mean=cpl_table_get_column_mean(*lambda,"WDIFF"));
01310   check_nomsg(nrow=cpl_table_get_nrow(*lambda));
01311   sinfo_msg_warning("diff %f",nrow*mean);
01312   if((fabs(nrow*mean) > 0) || (zsize_obj != zsize_sky)) {
01313     sinfo_msg("We have to interpolate sky frame - this is not good");
01314     *sky_interp_sw=1;
01315   }
01316 
01317 
01318   return 0;
01319 
01320  cleanup:
01321   sinfo_free_table(&add1);
01322   sinfo_free_table(&tmp_tbl);
01323   sinfo_free_propertylist(&plist);
01324   return -1;
01325 
01326 }
01327 
01328 /*-------------------------------------------------------------------------*/
01339 /*--------------------------------------------------------------------------*/
01340 
01341 static int
01342 sinfo_table_column_dindgen(cpl_table** t, const char* label)
01343 {
01344 
01345   int sz=0;
01346   int i=0;
01347 
01348   cknull(*t,"Null input vector");
01349   check(sz=cpl_table_get_nrow(*t),"Getting size of a vector");
01350   for(i=0;i<sz;i++) {
01351     cpl_table_set(*t,label,i,(double)i);
01352   }
01353 
01354   return 0;
01355  cleanup:
01356   return -1;
01357 
01358 }
01359 
01360 /*-------------------------------------------------------------------------*/
01371 /*--------------------------------------------------------------------------*/
01372 
01373 
01374 int
01375 sinfo_sum_spectra(const cpl_frame* obj_frm,
01376                   const cpl_frame* sky_frm,
01377                   cpl_image* mask,
01378                   cpl_table* wrange,
01379                   const int llx,
01380                   const int lly,
01381                   const int urx,
01382                   const int ury,
01383                   cpl_table** int_obj,
01384                   cpl_table** int_sky)
01385 {
01386 
01387 
01388 
01389   cpl_image* obj_slice=NULL;
01390   cpl_image* sky_slice=NULL;
01391   cpl_image* gslice=NULL;
01392   cpl_image* pos_tmp=NULL;
01393   cpl_image* msk_tmp=NULL;
01394   cpl_imagelist* obj=NULL;
01395   cpl_imagelist* sky=NULL;
01396 
01397 
01398   cpl_table* loop=NULL;
01399   cpl_table* opos_tbl=NULL;
01400   cpl_table* spos_tbl=NULL;
01401   cpl_table* tmp_tbl=NULL;
01402   cpl_table* loop_tbl=NULL;
01403 
01404   double med=0;
01405   double sdv=0;
01406   double avg=0;
01407 
01408   int zsize=0;
01409   int i=0;
01410   int pos_i=0;
01411 
01412   // sum spectra of flagged spaxels
01413 
01414   cknull_nomsg(obj=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
01415                                       CPL_TYPE_DOUBLE,0));
01416   cknull_nomsg(sky=cpl_imagelist_load(cpl_frame_get_filename(sky_frm),
01417                                       CPL_TYPE_DOUBLE,0));
01418 
01419   check_nomsg(zsize=cpl_imagelist_get_size(obj));
01420   check_nomsg(*int_obj = cpl_table_new(zsize));
01421   check_nomsg(*int_sky = cpl_table_new(zsize));
01422   check_nomsg(cpl_table_duplicate_column(*int_obj,"WAVE",wrange,"WAVE"));
01423   check_nomsg(cpl_table_duplicate_column(*int_sky,"WAVE",wrange,"WAVE"));
01424   check_nomsg(cpl_table_new_column(*int_obj,"INT",CPL_TYPE_DOUBLE));
01425   check_nomsg(cpl_table_new_column(*int_sky,"INT",CPL_TYPE_DOUBLE));
01426   check_nomsg(cpl_table_fill_column_window_double(*int_obj,"INT",0,zsize,0));
01427   check_nomsg(cpl_table_fill_column_window_double(*int_sky,"INT",0,zsize,0));
01428 
01429   //loop = where(mask > 0.5);
01430   //TO BE REMOVED: loop_tbl is not used
01431   cknull_nomsg(loop_tbl=sinfo_image2table(mask));
01432   check_nomsg(cpl_table_and_selected_double(loop_tbl,"VALUE",
01433                                             CPL_GREATER_THAN,0.5));
01434   check_nomsg(loop=cpl_table_extract_selected(loop_tbl));
01435   sinfo_free_table(&loop_tbl);
01436   sinfo_free_table(&loop);
01437 
01438   //Determines object spectrum
01439   for (i=0;i<zsize;i++) {
01440     check_nomsg(obj_slice = cpl_imagelist_get(obj,i));
01441 
01442     //pos = where(mask > 0.5 && finite(obj_slice),pos_i);
01443     pos_i=sinfo_cnt_mask_thresh_and_obj_finite(mask,0.5,obj_slice);
01444     if (pos_i >= 1) {
01445       if ((pos_i) < 3 ) {
01446     //int_obj[i] = mean(obj_slice[pos]);
01447         //TODO here obj_slice should be considered only on pos:
01448         //     one should do a selection/thresholding
01449         check_nomsg(cpl_table_set_double(*int_obj,"INT",i,
01450                      cpl_image_get_mean_window(obj_slice,
01451                                    llx,lly,
01452                                    urx,ury)));
01453       } else {
01454         // select only poisitions where mask>0.5 and obj is finite
01455     // gslice = obj_slice[pos];
01456         //sinfo_msg("obj pos_i=%d",pos_i);
01457 
01458         check_nomsg(gslice = cpl_image_duplicate(obj_slice));
01459         check_nomsg(sinfo_image_flag_nan(&gslice));
01460     /*
01461         sinfo_msg("obj: min=%f max=%f",
01462                   cpl_image_get_min(obj_slice),
01463           cpl_image_get_max(obj_slice));
01464     */
01465         //check_nomsg(cpl_image_threshold(gslice,SINFO_DBL_MIN,3.0e6,1,0));
01466         //check_nomsg(cpl_image_multiply(gslice,mask));
01467         if(cpl_image_count_rejected(gslice) < 2048) { //2048=64*64/2
01468 
01469       check_nomsg(med = cpl_image_get_median_window(gslice,llx,lly,urx,ury));
01470       check_nomsg(sdv = cpl_image_get_stdev_window(gslice,llx,lly,urx,ury));
01471       //sinfo_msg("med=%f sdv=%f",med,sdv);
01472       //avg = mean(gslice[where(gslice < med+3*sdv && gslice > med-3*sdv)]);
01473       check_nomsg(cpl_image_threshold(gslice,med-3*sdv,med+3*sdv,0,0));
01474       check_nomsg(avg= cpl_image_get_mean_window(gslice,llx,lly,urx,ury));
01475       check_nomsg(cpl_table_set_double(*int_obj,"INT",i,avg));
01476     } else {
01477       check_nomsg(cpl_table_set_invalid(*int_obj,"INT",i));
01478     }
01479 
01480         sinfo_free_image(&gslice);
01481         //sinfo_msg("sky int=%f",avg);
01482       }
01483     }
01484 
01485     //Determines sky spectrum
01486     check_nomsg(sky_slice = cpl_imagelist_get(sky,i));
01487     //pos = where(mask > 0.5 and finite(sky_slice),pos_i);
01488     pos_i=sinfo_cnt_mask_thresh_and_obj_finite(mask,0.5,sky_slice);
01489     if (pos_i >= 1) {
01490       if ((pos_i) < 3) {
01491     //int_obj[i] = mean(obj_slice[pos]);
01492         //TODO here obj_slice should be considered only on pos:
01493         //     one should do a selection/thresholding
01494         check_nomsg(cpl_table_set_double(*int_sky,"INT",i,
01495                      cpl_image_get_mean_window(sky_slice,
01496                                    llx,lly,
01497                                    urx,ury)));
01498       } else {
01499         //sinfo_msg("pos_i=%d",pos_i);
01500         // select only poisitions where mask>0.5 and obj is finite
01501     // gslice = obj_slice[pos];
01502         check_nomsg(gslice = cpl_image_duplicate(sky_slice));
01503         check_nomsg(sinfo_image_flag_nan(&gslice));
01504         //check_nomsg(cpl_image_threshold(gslice,SINFO_DBL_MIN,3.0e6,1,0));
01505         //check_nomsg(cpl_image_multiply(gslice,mask));
01506         if(cpl_image_count_rejected(gslice) < 2048) { //2048=64*64/2
01507 
01508     check_nomsg(med = cpl_image_get_median_window(gslice,llx,lly,urx,ury));
01509     check_nomsg(sdv = cpl_image_get_stdev_window(gslice,llx,lly,urx,ury));
01510         //avg = mean(gslice[where(gslice < med+3*sdv && gslice > med-3*sdv)]);
01511         check_nomsg(cpl_image_threshold(gslice,med-3*sdv,med+3*sdv,0,0));
01512     check_nomsg(avg= cpl_image_get_mean_window(gslice,llx,lly,urx,ury));
01513         check_nomsg(cpl_table_set_double(*int_sky,"INT",i,avg));
01514     } else {
01515       check_nomsg(cpl_table_set_invalid(*int_sky,"INT",i));
01516     }
01517         sinfo_free_image(&gslice);
01518     /*
01519         if(i<100) {
01520            sinfo_msg("sky: wave=%f int=%f",
01521                       cpl_table_get_double(*int_sky,"WAVE",i,&status),avg);
01522 
01523     }
01524     */
01525       }
01526     }
01527   }
01528 
01529   sinfo_free_imagelist(&obj);
01530   sinfo_free_imagelist(&sky);
01531 
01532 
01533   return 0;
01534 
01535  cleanup:
01536   sinfo_free_image(&gslice);
01537   sinfo_free_image(&pos_tmp);
01538   sinfo_free_image(&msk_tmp);
01539   sinfo_free_table(&tmp_tbl);
01540   sinfo_free_table(&opos_tbl);
01541   sinfo_free_table(&spos_tbl);
01542   sinfo_free_table(&loop_tbl);
01543   sinfo_free_table(&loop);
01544   sinfo_free_imagelist(&obj);
01545   sinfo_free_imagelist(&sky);
01546 
01547   return -1;
01548 }
01549 
01550 
01551 
01552 
01553 
01554 /*-------------------------------------------------------------------------*/
01565 /*--------------------------------------------------------------------------*/
01566 
01567 
01568 static int
01569 sinfo_cnt_mask_thresh_and_obj_finite(const cpl_image* mask,
01570                                      const double t,
01571                                      const cpl_image* obj)
01572 {
01573 
01574   int cnt=0;
01575   int sxm=0;
01576   int sym=0;
01577   int sxo=0;
01578   int syo=0;
01579   int i=0;
01580   const double* pm=NULL;
01581   const double* po=NULL;
01582 
01583   check_nomsg(sxm=cpl_image_get_size_x(mask));
01584   check_nomsg(sym=cpl_image_get_size_y(mask));
01585   check_nomsg(sxo=cpl_image_get_size_x(obj));
01586   check_nomsg(syo=cpl_image_get_size_y(obj));
01587   if( sxm != sxo || sym != syo) {
01588     goto cleanup;
01589   }
01590   check_nomsg(pm=cpl_image_get_data_double_const(mask));
01591   check_nomsg(po=cpl_image_get_data_double_const(obj));
01592 
01593   for(i=0;i<sxm*sym;i++) {
01594 
01595     if( (pm[i] > t) && (!irplib_isnan(po[i]))) { cnt++; }
01596 
01597   }
01598 
01599   return cnt;
01600  cleanup:
01601   return -1;
01602 
01603 }
01604 
01605 
01606 
01607 
01608 
01609 /*-------------------------------------------------------------------------*/
01620 /*--------------------------------------------------------------------------*/
01621 
01622 
01623 static int
01624 sinfo_image_flag_nan(cpl_image** im)
01625 {
01626 
01627   int cnt=0;
01628   int sx=0;
01629   int sy=0;
01630   int i=0;
01631   int j=0;
01632 
01633   double* pi=NULL;
01634 
01635   check_nomsg(sx=cpl_image_get_size_x(*im));
01636   check_nomsg(sy=cpl_image_get_size_y(*im));
01637   check_nomsg(pi=cpl_image_get_data_double(*im));
01638 
01639   for(j=0;j<sy;j++) {
01640     for(i=0;i<sx;i++) {
01641      if(irplib_isnan(pi[j*sx+i])) {
01642     check_nomsg(cpl_image_reject(*im,i+1,j+1));
01643     cnt++;
01644       }
01645     }
01646   }
01647   //sinfo_msg("No bad pixels: %d",cnt);
01648   return cnt;
01649  cleanup:
01650   return -1;
01651 
01652 }
01653 
01654 
01655 
01656 /*-------------------------------------------------------------------------*/
01668 /*--------------------------------------------------------------------------*/
01669 
01670 int
01671 sinfo_object_estimate_noise(cpl_frame* obj_frm,
01672                             const int obj_noise_fit,
01673                             double* centre,
01674                             double* noise)
01675 {
01676 
01677   const int nbins=HISTO_NBINS;
01678 
01679   int xsz=0;
01680   int ysz=0;
01681   int zsz=0;
01682   int n=0;
01683   int i=0;
01684   int k=0;
01685   int r=0;
01686 
01687   int max_h=0;
01688   int min_x=0;
01689   int max_x=0;
01690   int status=0;
01691   int max_pos=0;
01692   int min_pos=0;
01693   int min_xi_sz=0;
01694   int ndist=0;
01695 
01696   double avg_d=0;
01697   double std_d=0;
01698   double hmin=0;
01699   double hmax=0;
01700   double kappa=3;
01701 
01702   double* pdata=NULL;
01703   double* disth=NULL;
01704   double* distx=NULL;
01705 
01706   double peak=0;
01707   double tempc=0;
01708   double value=0;
01709   double thres=0;
01710   double val=0;
01711   double x0=0;
01712   double sigma=0;
01713   double area=0;
01714   double offset=0;
01715   //double mse=0;
01716   //double chired=0;
01717 
01718   cpl_propertylist* plist=NULL;
01719   cpl_imagelist* obj_cub=NULL;
01720   cpl_table* data_tbl=NULL;
01721   cpl_table* histo=NULL;
01722   cpl_image* img=NULL;
01723   cpl_table* dist=NULL;
01724   cpl_table* min_xi=NULL;
01725   cpl_table* tmp_tbl1=NULL;
01726   cpl_table* tmp_tbl2=NULL;
01727   cpl_vector* vx=NULL;
01728   cpl_vector* vy=NULL;
01729   cpl_vector* sx=NULL;
01730   cpl_vector* sy=NULL;
01731   int counter=0;
01732 
01733   // Get Object relevant information
01734   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
01735   check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
01736   check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
01737   check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
01738   sinfo_free_propertylist(&plist);
01739 
01740   cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
01741                                           CPL_TYPE_DOUBLE,0));
01742 
01743   n=xsz*ysz*zsz;
01744   check_nomsg(data_tbl=cpl_table_new(n));
01745   check_nomsg(cpl_table_new_column(data_tbl,"DATA",CPL_TYPE_DOUBLE));
01746 
01747 
01748   for(k=0;k<zsz;k++) {
01749     check_nomsg(img=cpl_imagelist_get(obj_cub,k));
01750     check_nomsg(pdata=cpl_image_get_data(img));
01751     for(i=0;i<xsz*ysz;i++) {
01752       if(!irplib_isnan(pdata[i])) {
01753     cpl_table_set_double(data_tbl,"DATA",r,pdata[i]);
01754         r++;
01755       }
01756     }
01757   }
01758   sinfo_free_imagelist(&obj_cub);
01759 
01760   check_nomsg(cpl_table_erase_invalid(data_tbl));
01761   check_nomsg(avg_d=cpl_table_get_column_mean(data_tbl,"DATA"));
01762   check_nomsg(std_d=cpl_table_get_column_stdev(data_tbl,"DATA"));
01763 
01764   //cpl_table_save(data_tbl, NULL, NULL, "out_data.fits",CPL_IO_DEFAULT);
01765   hmin=avg_d-kappa*std_d;
01766   hmax=avg_d+kappa*std_d;
01767   //sinfo_msg("mean=%f stdv=%f",avg_d,std_d);
01768   //sinfo_msg("hmin=%f hmax=%f",hmin,hmax);
01769   sinfo_msg("Computes histogram");
01770   ck0(sinfo_histogram(data_tbl,nbins,hmin,hmax,&histo),"building histogram");
01771 
01772   value=(double)(hmax-hmin)/nbins/2.;
01773   //sinfo_msg("value=%10.8f",value);
01774 
01775 
01776   while(min_xi_sz < HISTO_MIN_SIZE && counter < 10) {
01777     counter++;
01778     check_nomsg(max_h=cpl_table_get_column_max(histo,"HY"));
01779     //cpl_table_save(histo, NULL, NULL, "out_pippo.fits", CPL_IO_DEFAULT);
01780     check_nomsg(max_pos=sinfo_table_get_index_of_max(histo,"HY",CPL_TYPE_INT));
01781     //sinfo_msg("max_pos=%d",max_pos);
01782 
01783     /*
01784     check_nomsg(max_pos=sinfo_extract_table_rows(histo,"HY",
01785                                                  CPL_EQUAL_TO,max_h));
01786     sinfo_msg("size max_pos %d",cpl_table_get_nrow(max_pos));
01787     sinfo_msg("value max_pos %d",cpl_table_get_int(max_pos,"HY",0,&status));
01788     */
01789     min_x=max_pos-1;
01790     max_x=max_pos+2;
01791     //sinfo_msg("min_x=%d max_x=%d",min_x,max_x);
01792 
01793     sinfo_free_table(&tmp_tbl1);
01794     //sinfo_msg("x selection threshold: %f %d",
01795     //          cpl_table_get(histo,"HL",max_pos,&status),max_pos);
01796     check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HL",
01797                                                   CPL_LESS_THAN,
01798                                  cpl_table_get(histo,"HL",max_pos,&status)));
01799     thres=cpl_table_get_column_max(tmp_tbl1,"HY")/HISTO_Y_CUT;
01800     //sinfo_msg("threshold=%f",thres);
01801 
01802 
01803     sinfo_free_table(&min_xi);
01804     check_nomsg(min_xi=sinfo_extract_table_rows(tmp_tbl1,"HY",
01805                                                 CPL_GREATER_THAN,thres));
01806 
01807     //cpl_table_save(min_xi, NULL, NULL, "out_min_xi.fits", CPL_IO_DEFAULT);
01808 
01809 
01810 
01811     min_xi_sz=cpl_table_get_nrow(min_xi);
01812     val=cpl_table_get(min_xi,"HL",0,&status);
01813 
01814     check_nomsg(min_pos=sinfo_table_get_index_of_val(histo,"HL",val,
01815                                                      CPL_TYPE_DOUBLE));
01816     //sinfo_msg("min_pos=%d max_pos=%d max(h)=%d min_xi_sz=%d x[maxpos[0]]=%f",
01817     //           min_pos,   max_pos,   max_h,    min_xi_sz, val);
01818 
01819 
01820 
01821     if (min_xi_sz > 0) {
01822       min_x = min_pos-HISTO_X_LEFT_CUT*(max_pos-min_pos);
01823       max_x = max_pos+HISTO_X_RIGHT_CUT*(max_pos-min_pos);
01824     }
01825 
01826     //sinfo_msg("min_x=%d max_x=%d",min_x,max_x);
01827     check_nomsg(hmin=sinfo_table_column_interpolate(histo,"HL",min_x));
01828     check_nomsg(hmax=sinfo_table_column_interpolate(histo,"HL",max_x));
01829     //sinfo_msg("hmin=%f hmax=%f min_xi_sz=%d",hmin,hmax,min_xi_sz);
01830     //cpl_table_save(histo, NULL, NULL, "out_histo.fits", CPL_IO_DEFAULT);
01831     sinfo_free_table(&histo);
01832     ck0(sinfo_histogram(data_tbl,nbins,hmin,hmax,&histo),"building histogram");
01833     //cpl_table_save(histo, NULL, NULL, "out_histo1.fits", CPL_IO_DEFAULT);
01834     check_nomsg(cpl_table_add_scalar(histo,"HL",(hmax-hmin)/nbins/2));
01835     //cpl_table_save(histo, NULL, NULL, "out_histo2.fits", CPL_IO_DEFAULT);
01836 
01837 
01838 
01839   }
01840   sinfo_free_table(&data_tbl);
01841   sinfo_free_table(&min_xi);
01842 
01843   //cpl_table_save(histo, NULL, NULL, "out_histo.fits", CPL_IO_DEFAULT);
01844 
01845   check_nomsg(peak=cpl_table_get_column_max(histo,"HY"));
01846   //sinfo_msg("peak=%f",peak);
01847   sinfo_free_table(&tmp_tbl1);
01848 
01849   check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HY",CPL_EQUAL_TO,peak));
01850 
01851   //cpl_table_save(tmp_tbl1, NULL, NULL, "out_tmp_tbl1.fits", CPL_IO_DEFAULT);
01852 
01853 
01854   check_nomsg(*centre=cpl_table_get_column_mean(tmp_tbl1,"HL"));
01855   //sinfo_msg("Background level=%f",*centre);
01856 
01857   sinfo_free_table(&tmp_tbl1);
01858   check_nomsg(tmp_tbl1=sinfo_extract_table_rows(histo,"HY",
01859                                                 CPL_GREATER_THAN,
01860                                                 peak/HISTO_Y_CUT));
01861   sinfo_free_table(&tmp_tbl2);
01862   check_nomsg(tmp_tbl2=sinfo_extract_table_rows(tmp_tbl1,"HY",
01863                                                 CPL_LESS_THAN,peak));
01864   sinfo_free_table(&tmp_tbl1);
01865 
01866   check_nomsg(tempc=*centre-cpl_table_get_column_min(tmp_tbl2,"HL"));
01867   //sinfo_msg("min HX %f",cpl_table_get_column_min(tmp_tbl2,"HL"));
01868   sinfo_free_table(&tmp_tbl2);
01869   //sinfo_msg("Tempc=%f",tempc);
01870   check_nomsg(dist=sinfo_where_tab_min_max(histo,"HL",
01871                  CPL_GREATER_THAN,*centre-HISTO_DIST_TEMPC_MIN_FCT*tempc,
01872                  CPL_NOT_GREATER_THAN,*centre+HISTO_DIST_TEMPC_MAX_FCT*tempc));
01873 
01874   offset=cpl_table_get_column_min(histo,"HY");
01875   sinfo_free_table(&histo);
01876 
01877 
01878   check_nomsg(ndist=cpl_table_get_nrow(dist));
01879   check_nomsg(cpl_table_cast_column(dist,"HY","HYdouble",CPL_TYPE_DOUBLE));
01880   check_nomsg(disth=cpl_table_get_data_double(dist,"HYdouble"));
01881   check_nomsg(distx=cpl_table_get_data_double(dist,"HL"));
01882   //cpl_table_save(dist, NULL, NULL, "out_dist.fits", CPL_IO_DEFAULT);
01883 
01884   //TODO
01885   //gaussfit(distx,disty,dista,nterms=3);
01886   //*noise=dista[2];
01887   *noise=tempc/2;
01888   /* THIS DOES NOT WORK */
01889   //sinfo_msg("FWHM/2=%f",*noise);
01890 
01891   if(obj_noise_fit == 1) {
01892     check_nomsg(vy=cpl_vector_wrap(ndist,disth));
01893     check_nomsg(vx=cpl_vector_wrap(ndist,distx));
01894     check_nomsg(sx=cpl_vector_new(ndist));
01895     check_nomsg(cpl_vector_fill(sx,1.));
01896     check_nomsg(sy=cpl_vector_duplicate(sx));
01897     x0=*centre;
01898     sigma=tempc/2;
01899 
01900     check_nomsg(cpl_vector_fit_gaussian(vx,NULL,
01901                                         vy,NULL,
01902                                         CPL_FIT_ALL,
01903                                         &x0,&sigma,&area,&offset,
01904                                         NULL,NULL,NULL));
01905     //sinfo_msg("Gauss fit parameters:"
01906     //          "x0=%f sigma=%f area=%f offset=%f mse=%f chired=%f",
01907     //           x0,sigma,area,offset,mse,chired);
01908     //sinfo_msg("Background level=%f",*centre);
01909     //sinfo_msg("Noise=%f",sigma);
01910     *noise=sigma;
01911     sinfo_unwrap_vector(&vx);
01912     sinfo_unwrap_vector(&vy);
01913     sinfo_free_my_vector(&sx);
01914     sinfo_free_my_vector(&sy);
01915   }
01916   sinfo_free_table(&dist);
01917   //*noise=18.7448;
01918   //*noise=20.585946;
01919   return 0;
01920 
01921  cleanup:
01922   sinfo_free_imagelist(&obj_cub);
01923   sinfo_free_propertylist(&plist);
01924   sinfo_free_table(&min_xi);
01925   sinfo_free_table(&tmp_tbl1);
01926   sinfo_free_table(&tmp_tbl2);
01927   sinfo_free_table(&histo);
01928   sinfo_free_table(&dist);
01929   sinfo_free_table(&data_tbl);
01930   sinfo_free_my_vector(&sx);
01931   sinfo_free_my_vector(&sy);
01932   sinfo_unwrap_vector(&vx);
01933   sinfo_unwrap_vector(&vy);
01934 
01935   return -1;
01936 
01937 }
01938 
01939 
01952 cpl_table*
01953 sinfo_where_tab_min_max(cpl_table* t,
01954                         const char* col,
01955                         cpl_table_select_operator op1,
01956                         const double v1,
01957                         cpl_table_select_operator op2,
01958                         const double v2)
01959 {
01960 
01961   cpl_table* res=NULL;
01962   cpl_table* tmp=NULL;
01963 
01964   check_nomsg(cpl_table_and_selected_double(t,col,op1,v1));
01965   check_nomsg(tmp=cpl_table_extract_selected(t));
01966   check_nomsg(cpl_table_and_selected_double(tmp,col,op2,v2));
01967   check_nomsg(res=cpl_table_extract_selected(tmp));
01968   check_nomsg(cpl_table_select_all(t));
01969   sinfo_free_table(&tmp);
01970 
01971   return res;
01972 
01973  cleanup:
01974   sinfo_free_table(&tmp);
01975   sinfo_free_table(&res);
01976 
01977   return NULL;
01978 
01979 }
01980 /*-------------------------------------------------------------------------*/
02004 /*--------------------------------------------------------------------------*/
02005 
02006 int
02007 sinfo_histogram(const cpl_table* data,
02008                 const int nbins,
02009                 const double min,
02010                 const double max,
02011                 cpl_table** histo)
02012 {
02013   cpl_table* tmp_tbl1=NULL;
02014   cpl_table* tmp_tbl2=NULL;
02015   cpl_table* dat=NULL;
02016   int ntot=0;
02017   int i=0;
02018   int* phy=NULL;
02019   double* pdt=NULL;
02020   /* double* phx=NULL; */
02021 
02022   double vtmp=0;
02023   double vstp=0;
02024   double vmax=0;
02025   double vmin=0;
02026 
02027   int h=0;
02028   check_nomsg(dat=cpl_table_duplicate(data));
02029   check_nomsg(cpl_table_cast_column(dat,"DATA","DDATA",CPL_TYPE_DOUBLE));
02030   /*
02031   sinfo_msg("min=%f max=%f",
02032             cpl_table_get_column_min(dat,"DDATA"),
02033             cpl_table_get_column_max(dat,"DDATA"));
02034   */
02035   check_nomsg(cpl_table_and_selected_double(dat,"DDATA",
02036                                             CPL_NOT_GREATER_THAN,max));
02037   /*
02038   check_nomsg(cpl_table_and_selected_double(dat,"DDATA",CPL_LESS_THAN,max));
02039   */
02040   check_nomsg(tmp_tbl1=cpl_table_extract_selected(dat));
02041   /*
02042   sinfo_msg("min=%f max=%f",
02043              cpl_table_get_column_min(tmp_tbl1,"DDATA"),
02044              cpl_table_get_column_max(tmp_tbl1,"DDATA"));
02045   */
02046   /*
02047   check_nomsg(cpl_table_and_selected_double(tmp_tbl1,"DDATA",
02048                                             CPL_NOT_LESS_THAN,min));
02049   */
02050   check_nomsg(cpl_table_and_selected_double(tmp_tbl1,"DDATA",
02051                                             CPL_GREATER_THAN,min));
02052   check_nomsg(tmp_tbl2=cpl_table_extract_selected(tmp_tbl1));
02053   /*
02054   sinfo_msg("min=%f max=%f",
02055              cpl_table_get_column_min(tmp_tbl2,"DDATA"),
02056              cpl_table_get_column_max(tmp_tbl2,"DDATA"));
02057   */
02058   sinfo_free_table(&tmp_tbl1);
02059   /*
02060   check_nomsg(tmp_tbl1=sinfo_extract_table_rows(dat,"DDATA",
02061                                                 CPL_NOT_GREATER_THAN,max));
02062   check_nomsg(tmp_tbl2=sinfo_extract_table_rows(tmp_tbl1,"DDATA",
02063                                                 CPL_NOT_LESS_THAN,min));
02064   */
02065 
02066   check_nomsg(ntot=cpl_table_get_nrow(tmp_tbl2));
02067   /* not necessry to sort:
02068     check_nomsg(sinfo_sort_table_1(tmp_tbl2,"DDATA",FALSE));*/
02069   check_nomsg(vmin=cpl_table_get_column_min(tmp_tbl2,"DDATA"));
02070   check_nomsg(vmax=cpl_table_get_column_max(tmp_tbl2,"DDATA"));
02071   vstp=(vmax-vmin)/(nbins-1);
02072   /* sinfo_msg("vmin=%f vmax=%f step=%f",vmin,vmax,vstp); */
02073   check_nomsg(*histo=cpl_table_new(nbins));
02074   check_nomsg(cpl_table_new_column(*histo,"HX",CPL_TYPE_DOUBLE));
02075   check_nomsg(cpl_table_new_column(*histo,"HL",CPL_TYPE_DOUBLE));
02076   check_nomsg(cpl_table_new_column(*histo,"HY",CPL_TYPE_INT));
02077 
02078   /*check_nomsg(cpl_table_fill_column_window(*histo,"HX",0,nbins,0)); */
02079   check_nomsg(cpl_table_fill_column_window(*histo,"HL",0,nbins,0));
02080   check_nomsg(cpl_table_fill_column_window(*histo,"HY",0,nbins,0));
02081 
02082   check_nomsg(phy=cpl_table_get_data_int(*histo,"HY"));
02083   /*check_nomsg(phx=cpl_table_get_data_double(*histo,"HX")); */
02084   check_nomsg(pdt=cpl_table_get_data_double(dat,"DATA"));
02085 
02086   for(i=0;i<nbins;i++) {
02087     cpl_table_set_double(*histo,"HX",i,(double)i);
02088     vtmp=vmin+i*vstp;
02089     cpl_table_set_double(*histo,"HL",i,vtmp);
02090   }
02091   h=0;
02092 
02093   for(i=0;i<ntot;i++) {
02094     h=floor((pdt[i]-vmin)/vstp);
02095     if((h<nbins) && (h>-1)) {
02096       phy[h]++;
02097     }
02098   }
02099   //cpl_table_save(*histo, NULL, NULL, "out_histo_p5.fits", CPL_IO_DEFAULT);
02100 
02101   sinfo_free_table(&tmp_tbl2);
02102   sinfo_free_table(&dat);
02103 
02104 
02105   return 0;
02106  cleanup:
02107   sinfo_free_table(&tmp_tbl1);
02108   sinfo_free_table(&tmp_tbl2);
02109   sinfo_free_table(&dat);
02110 
02111   return -1;
02112 
02113 }
02114 
02115 
02116 /*-------------------------------------------------------------------------*/
02126 /*--------------------------------------------------------------------------*/
02127 
02128 int
02129 sinfo_object_flag_low_values(cpl_frame* obj_frm,
02130                              const double cnt,
02131                              const double sig,
02132                              cpl_imagelist** flag_data)
02133 {
02134 
02135   int xsz=0;
02136   int ysz=0;
02137   int zsz=0;
02138   int n=0;
02139   int i=0;
02140   int k=0;
02141   int r=0;
02142 
02143   cpl_propertylist* plist=NULL;
02144   cpl_table* data_tbl=NULL;
02145   cpl_table* flag_tbl=NULL;
02146   cpl_image* img=NULL;
02147   cpl_imagelist* obj_cub=NULL;
02148 
02149   double* pdata=NULL;
02150   double* pflag=NULL;
02151 
02152  /* Get Object relevant information */
02153   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
02154   check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
02155   check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
02156   check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
02157   sinfo_free_propertylist(&plist);
02158 
02159   cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
02160                                           CPL_TYPE_DOUBLE,0));
02161 
02162   n=xsz*ysz*zsz;
02163   check_nomsg(data_tbl=cpl_table_new(n));
02164   check_nomsg(cpl_table_new_column(data_tbl,"DATA",CPL_TYPE_DOUBLE));
02165 
02166   for(k=0;k<zsz;k++) {
02167     check_nomsg(img=cpl_imagelist_get(obj_cub,k));
02168     check_nomsg(pdata=cpl_image_get_data_double(img));
02169     for(i=0;i<xsz*ysz;i++) {
02170       if(!irplib_isnan(pdata[i])) {
02171     check_nomsg(cpl_table_set_double(data_tbl,"DATA",r,pdata[i]));
02172         r++;
02173       }
02174     }
02175   }
02176 
02177   check_nomsg(cpl_table_erase_invalid(data_tbl));
02178   //sinfo_msg("Background level: %f Noise: %f",cnt,sig);
02179   check_nomsg(cpl_table_and_selected_double(data_tbl,"DATA",
02180                                            CPL_LESS_THAN,cnt+2*sig));
02181   check_nomsg(flag_tbl=cpl_table_extract_selected(data_tbl));
02182   sinfo_free_table(&data_tbl);
02183   //check_nomsg(cpl_table_save(flag_tbl,NULL,NULL,
02184   //                             "out_flag.fits",CPL_IO_DEFAULT));
02185   sinfo_free_table(&flag_tbl);
02186 
02187   check_nomsg(*flag_data=cpl_imagelist_new());
02188   for(i=0;i<zsz;i++) {
02189     check_nomsg(img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
02190     check_nomsg(cpl_image_add_scalar(img,0));
02191     check_nomsg(cpl_imagelist_set(*flag_data,cpl_image_duplicate(img),i));
02192     sinfo_free_image(&img);
02193   }
02194   for(k=0;k<zsz;k++) {
02195     check_nomsg(img=cpl_imagelist_get(*flag_data,k));
02196     pflag=cpl_image_get_data_double(cpl_imagelist_get(*flag_data,k));
02197     pdata=cpl_image_get_data_double(cpl_imagelist_get(obj_cub,k));
02198     for(i=0;i<xsz*ysz;i++) {
02199       if((!irplib_isnan(pdata[i])) && pdata[i] < (cnt+2*sig)) {
02200         pflag[i]=1;
02201       }
02202     }
02203   }
02204 
02205   sinfo_free_imagelist(&obj_cub);
02206 
02207 
02208 
02209 
02210   return 0;
02211 
02212  cleanup:
02213   sinfo_free_propertylist(&plist);
02214   sinfo_free_imagelist(&obj_cub);
02215   sinfo_free_table(&data_tbl);
02216   sinfo_free_table(&flag_tbl);
02217 
02218   return -1;
02219 }
02220 
02221 /*-------------------------------------------------------------------------*/
02235 /*--------------------------------------------------------------------------*/
02236 
02237 
02238 int
02239 sinfo_object_flag_sky_pixels(cpl_frame* obj_frm,
02240                              cpl_table* lambda,
02241                              cpl_table* mrange,
02242                  cpl_imagelist* flag_data,
02243                              const double tol,
02244                              cpl_image** g_img,
02245                              cpl_image** r_img,
02246                              cpl_image** image)
02247 {
02248 
02249   int xsz=0;
02250   int ysz=0;
02251   int zsz=0;
02252   int i=0;
02253   int j=0;
02254   int gpix_i=0;
02255   double tot=0;
02256   double all_pix=0;
02257   double flag_pix=0;
02258   double ratio=0;
02259 
02260   double* pr_img=NULL;
02261   double* pg_img=NULL;
02262   double* pimage=NULL;
02263   cpl_propertylist* plist=NULL;
02264   cpl_imagelist* osel=NULL;
02265   cpl_imagelist* fsel=NULL;
02266   cpl_table* gpix=NULL;
02267   cpl_table* gspec=NULL;
02268   cpl_table* fspec=NULL;
02269   cpl_table* ospec=NULL;
02270 
02271   cpl_imagelist* obj_cub=NULL;
02272 
02273   /* Get Object relevant information */
02274   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
02275 
02276   check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
02277   check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
02278   check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
02279   sinfo_free_propertylist(&plist);
02280   cknull_nomsg(obj_cub=cpl_imagelist_load(cpl_frame_get_filename(obj_frm),
02281                                                       CPL_TYPE_DOUBLE,0));
02282 
02283   /* Flag sky pixels in data cube */
02284   /* create images */
02285   check_nomsg(*r_img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
02286   check_nomsg(*g_img=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
02287   check_nomsg(*image=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
02288 
02289   cknull_nomsg(pr_img=cpl_image_get_data_double(*r_img));
02290   cknull_nomsg(pg_img=cpl_image_get_data_double(*g_img));
02291   cknull_nomsg(pimage=cpl_image_get_data_double(*image));
02292 
02293   /* TODO */
02294   // fill image points:
02295   // g_img: mask with at least half good pixels along spectral range
02296   // r_img: mask with ratio of good pixels along spectral range
02297   // image: image with mean of spectrum over good pixels
02298 
02299   //check_nomsg(cpl_table_save(lambda, NULL, NULL,
02300   //                             "out_lambda.fits", CPL_IO_DEFAULT));
02301   //check_nomsg(cpl_table_save(mrange, NULL, NULL,
02302   //                             "out_mrange.fits", CPL_IO_DEFAULT));
02303 
02304   cknull_nomsg(osel=sinfo_imagelist_select_range(obj_cub,lambda,
02305                                                       mrange,tol));
02306 
02307   sinfo_free_imagelist(&obj_cub);
02308 
02309   cknull_nomsg(fsel=sinfo_imagelist_select_range(flag_data,lambda,
02310                                                       mrange,tol));
02311 
02312   //check_nomsg(cpl_imagelist_save(osel,"out_osel.fits",
02313   //                               CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
02314   //check_nomsg(cpl_imagelist_save(fsel,"out_fsel.fits",
02315   //                               CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
02316 
02317   for(j=0;j<ysz;j++) {
02318     for(i=0;i<xsz;i++) {
02319       // consider only planes in the proper wavelegth ranges
02320       cknull_nomsg(ospec=sinfo_slice_z(osel,i,j));
02321       cknull_nomsg(fspec=sinfo_slice_z(fsel,i,j));
02322       // consider only finite pixels
02323       check_nomsg(gpix_i=sinfo_table_extract_finite(ospec,fspec,&gpix,&gspec));
02324       //sinfo_msg("gpix_i=%d",gpix_i);
02325       if(gpix_i > 0) {
02326         // build two arrays of proper size
02327         all_pix=(double)gpix_i;
02328     /*
02329         sinfo_msg("flagspec: min=%f max=%f",
02330                   cpl_table_get_column_min(fspec,"VALUE"),
02331                   cpl_table_get_column_max(fspec,"VALUE"));
02332         sinfo_msg("good flagspec: min=%f max=%f",
02333                   cpl_table_get_column_min(gspec,"VALUE"),
02334                   cpl_table_get_column_max(gspec,"VALUE"));
02335         sinfo_msg("nfspec=%d",cpl_table_get_nrow(fspec));
02336         check_nomsg(cpl_table_save(fspec, NULL, NULL,
02337                     "out_fspec.fits",CPL_IO_DEFAULT));
02338         check_nomsg(cpl_table_save(gspec, NULL, NULL,
02339                     "out_gspec.fits", CPL_IO_DEFAULT));
02340     */
02341         //check_nomsg(flag_pix=cpl_table_and_selected_double(fspec,"VALUE",
02342         //                                              CPL_GREATER_THAN,0.5));
02343         //sinfo_msg("all_pix=%f flag_pix=%f",all_pix,flag_pix);
02344 
02345         check_nomsg(flag_pix=cpl_table_and_selected_double(gspec,"VALUE",
02346                                                         CPL_GREATER_THAN,0.5));
02347         //sinfo_msg("all_pix=%f flag_pix=%f",all_pix,flag_pix);
02348         // flag_pix = float(n_elements(where(fspec[gpix] > 0.5)));
02349         // compute the ratio between the two arrays
02350         ratio=flag_pix/all_pix;
02351         // considers only pixels with have at least half good pixels
02352         if(all_pix > cpl_table_get_nrow(mrange)/2) {
02353           pg_img[i+j*xsz]=1;
02354           pr_img[i+j*xsz]=ratio;
02355         }
02356         //mean(ospec(gpix))
02357         check_nomsg(pimage[i+j*xsz]=cpl_table_get_column_mean(gpix,"VALUE"));
02358         //sinfo_msg("ix=%d iy=%d r=%f",i,j,ratio);
02359       }
02360       sinfo_free_table(&ospec);
02361       sinfo_free_table(&fspec);
02362       sinfo_free_table(&gpix);
02363       sinfo_free_table(&gspec);
02364 
02365     } /* end for over i */
02366   } /* end for over j */
02367   sinfo_free_imagelist(&osel);
02368   sinfo_free_imagelist(&fsel);
02369 
02370   /*
02371   cpl_image_save(*r_img,"out_r_img.fits",CPL_BPP_IEEE_FLOAT,
02372                  NULL,CPL_IO_DEFAULT);
02373   cpl_image_save(*g_img,"out_g_img.fits",CPL_BPP_IEEE_FLOAT,
02374                  NULL,CPL_IO_DEFAULT);
02375   cpl_image_save(*image,"out_image.fits",CPL_BPP_IEEE_FLOAT,
02376                  NULL,CPL_IO_DEFAULT);
02377   */
02378   // get total(g_arr)
02379   check_nomsg(tot=cpl_image_get_flux(*g_img));
02380   if(tot < 1) {
02381     sinfo_msg_error("no good spaxel");
02382     goto cleanup;
02383   }
02384 
02385   return 0;
02386 
02387 
02388  cleanup:
02389   sinfo_free_propertylist(&plist);
02390   sinfo_free_imagelist(&obj_cub);
02391   sinfo_free_imagelist(&osel);
02392   sinfo_free_imagelist(&fsel);
02393    sinfo_free_table(&ospec);
02394   sinfo_free_table(&fspec);
02395   sinfo_free_table(&gpix);
02396   sinfo_free_table(&gspec);
02397 
02398   return -1;
02399 
02400 
02401 }
02402 
02411 int
02412 sinfo_choose_good_sky_pixels(cpl_frame* obj_frm,
02413                              cpl_image* r_img,
02414                              cpl_image* g_img,
02415                              const double min_frac,
02416                              cpl_image** mask)
02417 {
02418 
02419   int xsz=0;
02420   int ysz=0;
02421   int zsz=0;
02422   int r2i=0;
02423   int status=0;
02424   double tot=0;
02425   double thres=SKY_THRES;
02426   double cum_x_max=0;
02427 
02428   cpl_image* r2img=NULL;
02429   cpl_propertylist* plist=NULL;
02430   cpl_table* cum=NULL;
02431   cpl_table* hcum=NULL;
02432   cpl_table* thres_tbl=NULL;
02433 
02434   cknull_nomsg(plist=cpl_propertylist_load(cpl_frame_get_filename(obj_frm),0));
02435   check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
02436   check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
02437   check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
02438   sinfo_free_propertylist(&plist);
02439 
02440   // choose pixels which seem to be sky (ie 95% of spectral pixels are flagged)
02441   check_nomsg(*mask=cpl_image_new(xsz,ysz,CPL_TYPE_DOUBLE));
02442   //r2 = where(r_img >= thres,r2i);
02443   // count good pixels: set to 0 what < thres and to 1 what > thres
02444   check_nomsg(r2img=cpl_image_duplicate(r_img));
02445   check_nomsg(cpl_image_threshold(r2img,thres,thres,0,1));
02446   check_nomsg(r2i=cpl_image_get_flux(r2img));
02447 
02448   if(r2i>0) {
02449     sinfo_free_image(&(*mask));
02450     check_nomsg(*mask=cpl_image_duplicate(r2img));
02451   }
02452   sinfo_free_image(&r2img);
02453   check_nomsg(r2img=cpl_image_duplicate(r_img));
02454   check_nomsg(cpl_image_threshold(r2img,thres,SINFO_DBL_MAX,0,SINFO_DBL_MAX));
02455   sinfo_free_image(&r2img);
02456 
02457   check_nomsg(tot=cpl_image_get_flux(g_img));
02458 
02459 
02460    sinfo_msg("%2.2d spaxels (%4.1f %% of good pixels) are designated as sky",
02461              r2i,100.*r2i/tot);
02462 
02463    //threshold ratio for fraction 'minfrac' of spatial pixels to be 'sky'
02464    if (1.*r2i/tot < min_frac) {
02465      sinfo_msg("this is too small - will increase it to %4.1f %%",
02466            100.*min_frac);
02467      check_nomsg(cum=cpl_table_new(xsz*ysz));
02468      check_nomsg(cpl_table_new_column(cum,"X",CPL_TYPE_DOUBLE));
02469      sinfo_table_column_dindgen(&cum,"X");
02470      check_nomsg(cpl_table_add_scalar(cum,"X",1.));
02471 
02472      //hcum = r_img(sort(r_img));
02473      hcum = sinfo_image2table(r_img);
02474      check_nomsg(sinfo_sort_table_1(hcum,"VALUE",FALSE));
02475 
02476      //thresh = hcum[where(xcum/max(xcum) >= 1.-min_frac)];
02477      check_nomsg(cpl_table_duplicate_column(cum,"H",hcum,"VALUE"));
02478      check_nomsg(cum_x_max=cpl_table_get_column_max(cum,"X"));
02479      check_nomsg(cpl_table_duplicate_column(cum,"R",cum,"X"));
02480      check_nomsg(cpl_table_divide_scalar(cum,"R",cum_x_max));
02481      check_nomsg(cpl_table_and_selected_double(cum,"R",
02482                                               CPL_NOT_LESS_THAN,
02483                                               (1.-min_frac)));
02484      check_nomsg(thres_tbl=cpl_table_extract_selected(cum));
02485 
02486      check_nomsg(thres = cpl_table_get(thres_tbl,"R",0,&status));
02487      //*mask[where(r_img >= thresh)] = 1;
02488      sinfo_free_image(&(*mask));
02489 
02490 
02491      check_nomsg(*mask=cpl_image_duplicate(r_img));
02492      check_nomsg(cpl_image_threshold(*mask,thres,thres,0,1));
02493   }
02494   sinfo_free_table(&cum);
02495   sinfo_free_table(&hcum);
02496   sinfo_free_table(&thres_tbl);
02497 
02498   return 0;
02499  cleanup:
02500 
02501   sinfo_free_propertylist(&plist);
02502   sinfo_free_image(&r2img);
02503   sinfo_free_table(&cum);
02504   sinfo_free_table(&hcum);
02505   sinfo_free_table(&thres_tbl);
02506 
02507   return -1;
02508 
02509 }
02510 
02511 /*-------------------------------------------------------------------------*/
02520 /*--------------------------------------------------------------------------*/
02521 
02522 static double
02523 sinfo_fit_bkg(double p[])
02524 
02525 {
02526  double* px=NULL;
02527   double* py=NULL;
02528   double* pv=NULL;
02529   cpl_vector* vtmp=NULL;
02530   double max=0;
02531   int i=0;
02532   int np=0;
02533 
02534   double chi2=0;
02535 
02536   check_nomsg(px= cpl_vector_get_data(sa_vx));
02537   check_nomsg(py= cpl_vector_get_data(sa_vy));
02538   check_nomsg(np= cpl_vector_get_size(sa_vx));
02539   check_nomsg(vtmp=cpl_vector_duplicate(sa_vy));
02540   check_nomsg(pv=cpl_vector_get_data(vtmp));
02541 
02542   for(i=0;i<np;i++) {
02543     pv[i]=sinfo_fac(px[i],p[2]);
02544     //sinfo_msg("x=%g p=%g",px[i],pv[i]);
02545   }
02546   check_nomsg(max=cpl_vector_get_max(vtmp));
02547   if(max> 0) {
02548     check_nomsg(cpl_vector_divide_scalar(vtmp,max));
02549     check_nomsg(cpl_vector_multiply_scalar(vtmp,p[1]));
02550     check_nomsg(cpl_vector_add_scalar(vtmp,p[0]));
02551   }
02552 
02553 
02554   for(i=0;i<np;i++) {
02555     chi2+=(py[i]-pv[i])*(py[i]-pv[i]);
02556   }
02557   sinfo_free_my_vector(&vtmp);
02558   return chi2;
02559  cleanup:
02560   sinfo_free_my_vector(&vtmp);
02561   return -1;
02562 
02563 }
02564 
02565 
02566 /*-------------------------------------------------------------------------*/
02578 /*--------------------------------------------------------------------------*/
02579 
02580 int
02581 sinfo_thermal_background2(cpl_table* int_sky,
02582                          cpl_table* lambda,
02583                          cpl_table* lrange,
02584                          cpl_table** bkg)
02585 {
02586 
02587   int n2=0;
02588   int i=0;
02589   int j=0;
02590   int nrow=0;
02591 
02592   cpl_table* tmp1=NULL;
02593   cpl_table* tmp2=NULL;
02594 
02595   double max=0;
02596   double wmin=0;
02597   double wmax=0;
02598   double p0[3];
02599   const int MP=4;
02600   const int NP=3;
02601   double y[MP];
02602   double** ap=NULL;
02603   int nfunc=0;
02604   int status=0;
02605   int row=0;
02606   double bkg_min=0;
02607   double bkg_max=0;
02608   double p0_min=0;
02609   double p0_max=0;
02610   double p1_min=0;
02611   double p1_max=0;
02612   double p2_min=0;
02613   double p2_max=0;
02614   double* pw=NULL;
02615   double* pf=NULL;
02616 
02617   ap=(double**) cpl_calloc(MP,sizeof(double*));
02618 
02619   for(i=0;i<MP;i++) {
02620     ap[i]=cpl_calloc(NP,sizeof(double));
02621   }
02622 
02623   cknull(int_sky,"Null input table sky");
02624   cknull(lambda,"Null input table lambda");
02625   cknull(lrange,"Null input table lrange");
02626 
02627 
02628   //TO BE FIXED: Why lrange to gat wave min and max: int_sky is sufficient
02629   check_nomsg(wmin=cpl_table_get_column_min(lrange,"WAVE"));
02630   check_nomsg(wmax=cpl_table_get_column_max(lrange,"WAVE"));
02631   check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
02632               CPL_NOT_LESS_THAN,wmin));
02633   check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
02634               CPL_NOT_GREATER_THAN,wmax));
02635   check_nomsg(tmp1=cpl_table_extract_selected(int_sky));
02636 
02637   check_nomsg(row=sinfo_table_get_index_of_val(tmp1,"WAVE",
02638                                                wmax,CPL_TYPE_DOUBLE));
02639   check_nomsg(max=cpl_table_get_double(tmp1,"INT",row,&status));
02640   check_nomsg(sinfo_table_flag_nan(&tmp1,"INT"));
02641   check_nomsg(cpl_table_erase_invalid(tmp1));
02642   check_nomsg(cpl_table_and_selected_double(tmp1,"INT",CPL_NOT_EQUAL_TO,0));
02643   check_nomsg(tmp2=cpl_table_extract_selected(tmp1));
02644 
02645   sinfo_free_table(&tmp1);
02646   check_nomsg(n2=cpl_table_get_nrow(tmp2));
02647   check_nomsg(sa_vx=cpl_vector_wrap(n2,
02648               cpl_table_get_data_double(tmp2,"WAVE")));
02649   check_nomsg(sa_vy=cpl_vector_wrap(n2,
02650               cpl_table_get_data_double(tmp2,"INT")));
02651 
02652 
02653   for(i=0;i<MP;i++) {
02654     for(j=0;j<NP;j++) {
02655       ap[i][j]=0;
02656     }
02657   }
02658 
02659   check_nomsg(bkg_min=cpl_table_get_column_min(tmp2,"INT"));
02660   check_nomsg(bkg_max=cpl_table_get_double(tmp2,"INT",row,&status));
02661 
02662 
02663   //Init amoeba fit parameters
02664   p0_min=bkg_min*0.9;
02665   p0_max=bkg_min*1.1;
02666   p1_min=bkg_max*0.9;
02667   p1_max=bkg_max*1.1;
02668   p1_min=200;
02669   p2_max=300;
02670 
02671   ap[0][0]=p0_min; ap[0][1]=p1_min; ap[0][2]=p2_min;
02672   ap[1][0]=p0_max; ap[1][1]=p1_min; ap[1][2]=p2_min;
02673   ap[2][0]=p0_min; ap[2][1]=p1_max; ap[2][2]=p2_min;
02674   ap[3][0]=p0_min; ap[3][1]=p1_min; ap[3][2]=p2_max;
02675 
02676   sinfo_msg("Before amoeba fit");
02677   for(i=0;i<MP;i++) {
02678     for(j=0;j<NP;j++) {
02679       sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
02680     }
02681   }
02682 
02683 
02684 
02685 
02686   for(i=0;i<MP;i++) {
02687     p0[0]=ap[i][0];
02688     p0[1]=ap[i][1];
02689     p0[2]=ap[i][2];
02690     y[i]=sinfo_fit_bkg(p0);
02691   }
02692 
02693   sinfo_msg("p0=%g %g %g",p0[0],p0[1],p0[2]);
02694   for(i=0;i<N_ITER_FIT_AMOEBA;i++) {
02695     check_nomsg(sinfo_fit_amoeba(ap,y,NP,AMOEBA_FTOL,sinfo_fit_bkg,&nfunc));
02696     sinfo_msg("After amoeba fit");
02697     sinfo_msg("iter=%d ap=%g %g %g",i,ap[0][0],ap[0][1],ap[0][2]);
02698   }
02699   sinfo_unwrap_vector(&sa_vx);
02700   sinfo_unwrap_vector(&sa_vy);
02701   sinfo_free_table(&tmp2);
02702 
02703 
02704   sinfo_msg("After amoeba fit");
02705   for(i=0;i<MP;i++) {
02706     for(j=0;j<NP;j++) {
02707       sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
02708     }
02709     sinfo_msg("y[%d]=%g",i,y[i]);
02710   }
02711 
02712 
02713 
02714   check_nomsg(nrow=cpl_table_get_nrow(lambda));
02715   check_nomsg(*bkg=cpl_table_new(nrow));
02716   check_nomsg(cpl_table_duplicate_column(*bkg,"WAVE",lambda,"WAVE"));
02717   check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
02718   cpl_table_fill_column_window(*bkg,"INT2",0,nrow,0.);
02719   check_nomsg(pw=cpl_table_get_data_double(*bkg,"WAVE"));
02720   check_nomsg(pf=cpl_table_get_data_double(*bkg,"INT2"));
02721 
02722   for(i=0;i<nrow;i++) {
02723     pf[i]=sinfo_fac(pw[i],ap[0][2]);
02724   }
02725   check_nomsg(max=cpl_table_get_column_max(*bkg,"INT2"));
02726 
02727   if(max != 0) {
02728      check_nomsg(cpl_table_divide_scalar(*bkg,"INT2",max));
02729   }
02730   check_nomsg(cpl_table_multiply_scalar(*bkg,"INT2",ap[0][1]));
02731   check_nomsg(cpl_table_add_scalar(*bkg,"INT2",ap[0][0]));
02732   //check_nomsg(cpl_table_save(*bkg,NULL,NULL,
02733   //"out_amoeba5.fits",CPL_IO_DEFAULT ));
02734   sinfo_new_destroy_2Ddoublearray(&ap,MP);
02735 
02736 
02737   return 0;
02738 
02739  cleanup:
02740   sinfo_new_destroy_2Ddoublearray(&ap,MP);
02741   sinfo_free_table(&tmp1);
02742   sinfo_free_table(&tmp2);
02743   sinfo_unwrap_vector(&sa_vx);
02744   sinfo_unwrap_vector(&sa_vy);
02745   return -1;
02746 
02747 }
02748 
02749 
02750 
02751 /*-------------------------------------------------------------------------*/
02763 /*--------------------------------------------------------------------------*/
02764 
02765 int
02766 sinfo_thermal_background(cpl_table* int_sky,
02767                          cpl_table* lambda,
02768                          cpl_table* lrange,
02769                          const double temp,
02770                          const int niter,
02771                          const int filter_width,
02772                          const double tol,
02773                          cpl_table** bkg,
02774                          int* success_fit)
02775 {
02776 
02777   int npix=0;
02778   int i=0;
02779   int row=0;
02780   const int ndim=3;/* There are 3 parameters */
02781     int ia[ndim];
02782 
02783   int NPOINTS=0;
02784 
02785 
02786   double temp1=0;
02787   double temp2=0;
02788 
02789   //double r0=80.306773;
02790   //double r1=450.50027;
02791   //double r2=252.17949;
02792   double max_tmp2=0;
02793   double* ptmp1=NULL;
02794   double thermal=0;
02795   double* pw=NULL;
02796   double p0[3];
02797   double wmin=0;
02798   double wmax=0;
02799   double ga0=0;
02800   double ga1=0;
02801   //double ga1=0;
02802   double ga2=0;
02803   double mse=0;
02804   double chired=0;
02805 
02806 
02807   cpl_vector *a = cpl_vector_new(ndim);
02808   cpl_table* xlr=NULL;
02809   cpl_table* ylr=NULL;
02810   cpl_table* wlr=NULL;
02811   cpl_table* tmp=NULL;
02812   cpl_table* temp2_tbl=NULL;
02813 
02814   cpl_vector* y=NULL;
02815   cpl_vector* fy=NULL;
02816 
02817   cpl_vector* sy=NULL;
02818 
02819   cpl_matrix* x_matrix=NULL;
02820   double bkg_min=0;
02821   double bkg_max=0;
02822   int status=0;
02823   double avg=0;
02824   double sdv=0;
02825   double med=0;
02826   double* pif=NULL;
02827   double* pwf=NULL;
02828   double* pws=NULL;
02829   int k=0;
02830   int nrow=0;
02831 
02832   //check_nomsg(cpl_table_save(int_sky,NULL,NULL,
02833   //"out_pippo.fits", CPL_IO_DEFAULT));
02834   check_nomsg(wmin=cpl_table_get_column_min(lrange,"WAVE"));
02835   check_nomsg(wmax=cpl_table_get_column_max(lrange,"WAVE"));
02836 
02837   bkg_min=sinfo_fac(wmin,temp);
02838   bkg_max=sinfo_fac(wmax,temp);
02839   //sinfo_msg("bkg: min=%g max=%g",bkg_min,bkg_max);
02840   //sinfo_scale_fct=sinfo_scale_fct*bkg_max;
02841   //sinfo_scale_fct=sinfo_scale_fct;
02842 
02843   check_nomsg(cpl_table_and_selected_double(lambda,"WAVE",
02844                                             CPL_NOT_LESS_THAN,wmin));
02845   check_nomsg(tmp=cpl_table_extract_selected(lambda));
02846 
02847   check_nomsg(cpl_table_and_selected_double(tmp,"WAVE",
02848                                             CPL_NOT_GREATER_THAN,wmax));
02849   check_nomsg(xlr=cpl_table_extract_selected(tmp));
02850   sinfo_free_table(&tmp);
02851 
02852 
02853   check_nomsg(cpl_table_and_selected_double(int_sky,"WAVE",
02854                                             CPL_NOT_LESS_THAN,wmin));
02855   check_nomsg(tmp=cpl_table_extract_selected(int_sky));
02856   check_nomsg(cpl_table_and_selected_double(tmp,"WAVE",
02857                                             CPL_NOT_GREATER_THAN,wmax));
02858 
02859 
02860   //To be sure one has not strange cases
02861   check_nomsg(cpl_table_and_selected_double(tmp,"INT",CPL_GREATER_THAN,-2));
02862   check_nomsg(ylr=cpl_table_extract_selected(tmp));
02863   //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr_0.fits",CPL_IO_DEFAULT));
02864   sinfo_free_table(&tmp);
02865   check_nomsg(tmp=cpl_table_duplicate(ylr));
02866   sinfo_free_table(&ylr);
02867 
02868   check_nomsg(avg=cpl_table_get_column_mean(tmp,"INT"));
02869   check_nomsg(sdv=cpl_table_get_column_stdev(tmp,"INT"));
02870   check_nomsg(cpl_table_and_selected_double(tmp,"INT",
02871                         CPL_LESS_THAN,avg+10*sdv));
02872 
02873   check_nomsg(ylr=cpl_table_extract_selected(tmp));
02874   sinfo_free_table(&tmp);
02875 
02876 
02877   /*
02878   check_nomsg(xlr=sinfo_table_select_range(lambda,lrange,0.003));
02879   check_nomsg(ylr=sinfo_table_select_range(int_sky,lrange,0.003));
02880   */
02881   check_nomsg(cpl_table_and_selected_double(ylr,"INT",CPL_NOT_EQUAL_TO,0));
02882 
02883   check_nomsg(wlr=cpl_table_extract_selected(ylr));
02884 
02885 
02886   check_nomsg(p0[0]=cpl_table_get_column_min(wlr,"INT"));
02887   check_nomsg(row=sinfo_table_get_index_of_val(ylr,"WAVE",
02888                                                wmax,CPL_TYPE_DOUBLE));
02889   check_nomsg(p0[1]=cpl_table_get_double(ylr,"INT",row,&status));
02890   p0[2]=temp;
02891 
02892 
02893   ga0=p0[0];
02894   ga1=p0[1]/bkg_max;
02895   //ga1=p0[1];
02896   ga2=p0[2];
02897 
02898   //sinfo_msg("p= %g %g %g",p0[0],p0[1],p0[2]);
02899   check_nomsg(sinfo_table_flag_nan(&wlr,"INT"));
02900   check_nomsg(cpl_table_erase_invalid(wlr));
02901   //check_nomsg(cpl_table_save(xlr,NULL,NULL,"out_xlr.fits",CPL_IO_DEFAULT));
02902   //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr.fits",CPL_IO_DEFAULT));
02903   //check_nomsg(cpl_table_save(wlr,NULL,NULL,"out_wlr.fits",CPL_IO_DEFAULT));
02904 
02905 
02906   check_nomsg(NPOINTS=cpl_table_get_nrow(ylr));
02907 
02908   check_nomsg(x_matrix = cpl_matrix_wrap(NPOINTS,1,
02909                                        cpl_table_get_data_double(ylr,"WAVE")));
02910   check_nomsg(y=cpl_vector_wrap(NPOINTS,cpl_table_get_data_double(ylr,"INT")));
02911   //check_nomsg(fy=cpl_vector_filter_median_create(y,1));
02912   //check_nomsg(fy=cpl_vector_filter_lowpass_create(y,CPL_LOWPASS_LINEAR,3));
02913   //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr1.fits",CPL_IO_DEFAULT));
02914   check_nomsg(fy=sinfo_sky_background_estimate(y,filter_width,filter_width));
02915   //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr2.fits",CPL_IO_DEFAULT));
02916   pif=cpl_vector_get_data(fy);
02917   pwf=cpl_table_get_data_double(ylr,"WAVE");
02918 
02919 
02920   check_nomsg(cpl_table_new_column(int_sky,"INT_BKG_SMO",CPL_TYPE_DOUBLE));
02921   check_nomsg(cpl_table_new_column(int_sky,"WAVE_SMO",CPL_TYPE_DOUBLE));
02922   pws=cpl_table_get_data_double(int_sky,"WAVE");
02923 
02924   k=0;
02925   i=0;
02926   check_nomsg(nrow=cpl_table_get_nrow(int_sky));
02927   if((pws[0]-pwf[0])>0) {
02928     for(i=0;i<NPOINTS;i++) {
02929       if(fabs(pws[k]-pwf[i]) < tol) {
02930     check_nomsg(cpl_table_set_double(int_sky,"INT_BKG_SMO",k,pif[i]));
02931     check_nomsg(cpl_table_set_double(int_sky,"WAVE_SMO",k,pws[i]));
02932     k++;
02933       }
02934     }
02935   } else {
02936     for(k=0;k<nrow;k++) {
02937       if((i<NPOINTS) && (fabs(pws[k]-pwf[i]) < tol)) {
02938     check_nomsg(cpl_table_set_double(int_sky,"INT_BKG_SMO",k,pif[i]));
02939     check_nomsg(cpl_table_set_double(int_sky,"WAVE_SMO",k,pws[i]));
02940     i++;
02941       }
02942     }
02943 
02944   }
02945 
02946   //check_nomsg(cpl_table_save(ylr,NULL,NULL,"out_ylr3.fits",CPL_IO_DEFAULT));
02947 
02948 
02949   check_nomsg(cpl_vector_set(a, 0, ga0));
02950   check_nomsg(cpl_vector_set(a, 1, ga1));
02951   check_nomsg(cpl_vector_set(a, 2, ga2));
02952 
02953   check_nomsg(sy=cpl_vector_duplicate(y));
02954   check_nomsg(cpl_vector_power(sy,2));
02955   check_nomsg(cpl_vector_power(sy,0.5));
02956   //check_nomsg(cpl_vector_fill(sy,0.001));
02957 
02958   ia[0] = 1;
02959   ia[1] = 1;
02960   ia[2] = 1;
02961 
02962 
02963   for(i=0;i<niter;i++) {
02964 
02965     /*
02966     sinfo_msg("before fit: a=%g %g %g",
02967               cpl_vector_get(a,0),
02968               cpl_vector_get(a,1),
02969               cpl_vector_get(a,2));
02970     */
02971     if(CPL_ERROR_NONE != sinfo_fit_lm(x_matrix,NULL,fy,sy,a,ia,sinfo_fitbkg,
02972                       sinfo_fitbkg_derivative,
02973                       &mse,&chired,NULL)) {
02974       sinfo_msg_warning("Thermal background fit failed");
02975       cpl_error_reset();
02976       *success_fit=1;
02977 
02978       goto recover;
02979     }
02980 
02981     bkg_max=sinfo_fac(wmax,cpl_vector_get(a,2));
02982     //sinfo_scale_fct=sinfo_scale_fct*bkg_max;
02983     /*
02984     sinfo_msg("after fit: a=%g %g %g chired=%g",
02985               cpl_vector_get(a,0),
02986           cpl_vector_get(a,1),
02987               cpl_vector_get(a,2),
02988               chired);
02989 
02990     */
02991 
02992   }
02993 
02994     sinfo_msg("Last fit: a=%g %g %g chired=%g",
02995               cpl_vector_get(a,0),
02996           cpl_vector_get(a,1),
02997               cpl_vector_get(a,2),
02998               chired);
02999 
03000   sinfo_free_my_vector(&fy);
03001   sinfo_unwrap_vector(&y);
03002   sinfo_free_my_vector(&sy);
03003   sinfo_unwrap_matrix(&x_matrix);
03004   sinfo_free_table(&xlr);
03005   sinfo_free_table(&ylr);
03006   sinfo_free_table(&wlr);
03007 
03008   ga0=cpl_vector_get(a,0);
03009   ga1=cpl_vector_get(a,1);
03010   ga2=cpl_vector_get(a,2);
03011   //ga2=252.69284;
03012   check_nomsg(npix=cpl_table_get_nrow(lrange));
03013   check_nomsg(pw=cpl_table_get_data_double(lrange,"WAVE"));
03014   check_nomsg(temp2_tbl=cpl_table_new(npix));
03015   check_nomsg(cpl_table_new_column(temp2_tbl,"TEMP2",CPL_TYPE_DOUBLE));
03016 
03017   for(i=0;i<npix;i++) {
03018     temp2=sinfo_fac(pw[i],ga2);
03019     check_nomsg(cpl_table_set_double(temp2_tbl,"TEMP2",i,temp2));
03020   }
03021   check_nomsg(max_tmp2=cpl_table_get_column_max(temp2_tbl,"TEMP2"));
03022   sinfo_free_table(&temp2_tbl);
03023 
03024 
03025 
03026   check_nomsg(npix=cpl_table_get_nrow(lambda));
03027   check_nomsg(pw=cpl_table_get_data_double(lambda,"WAVE"));
03028   check_nomsg(*bkg=cpl_table_new(npix));
03029   check_nomsg(cpl_table_new_column(*bkg,"WAVE",CPL_TYPE_DOUBLE));
03030   check_nomsg(cpl_table_new_column(*bkg,"TEMP1",CPL_TYPE_DOUBLE));
03031   check_nomsg(cpl_table_new_column(*bkg,"INT",CPL_TYPE_DOUBLE));
03032   check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
03033 
03034   for(i=0;i<npix;i++) {
03035     check_nomsg(cpl_table_set_double(*bkg,"WAVE",i,pw[i]));
03036     temp1=sinfo_fac(pw[i],ga2);
03037     check_nomsg(cpl_table_set_double(*bkg,"TEMP1",i,temp1));
03038   }
03039 
03040   check_nomsg(ptmp1=cpl_table_get_data_double(*bkg,"TEMP1"));
03041   bkg_max=sinfo_fac(wmax,ga2);
03042 
03043   for(i=0;i<npix;i++) {
03044     thermal=ga0+ptmp1[i]/max_tmp2*ga1;
03045     check_nomsg(cpl_table_set_double(*bkg,"INT",i,thermal));
03046     thermal=ga0+ga1*sinfo_fac(pw[i],ga2);
03047     check_nomsg(cpl_table_set_double(*bkg,"INT2",i,thermal));
03048   }
03049   sinfo_free_my_vector(&a);
03050 
03051   return 0;
03052 
03053  recover:
03054   sinfo_msg_warning("Recover fit of thermal background");
03055   check_nomsg(npix=cpl_table_get_nrow(lambda));
03056   check_nomsg(*bkg=cpl_table_new(npix));
03057   check_nomsg(cpl_table_new_column(*bkg,"TEMP1",CPL_TYPE_DOUBLE));
03058   check_nomsg(cpl_table_new_column(*bkg,"INT",CPL_TYPE_DOUBLE));
03059   check_nomsg(cpl_table_new_column(*bkg,"INT2",CPL_TYPE_DOUBLE));
03060 
03061   med=cpl_table_get_column_median(ylr,"INT");
03062   for(i=0;i<npix;i++) {
03063     check_nomsg(cpl_table_set_double(*bkg,"INT",i,med));
03064     check_nomsg(cpl_table_set_double(*bkg,"INT2",i,med));
03065   }
03066 
03067   sinfo_free_my_vector(&a);
03068   sinfo_unwrap_vector(&y);
03069   sinfo_free_my_vector(&sy);
03070   sinfo_unwrap_matrix(&x_matrix);
03071   sinfo_free_table(&xlr);
03072   sinfo_free_table(&ylr);
03073   sinfo_free_table(&wlr);
03074   sinfo_free_table(&tmp);
03075 
03076   return 0;
03077 
03078 
03079  cleanup:
03080   sinfo_free_my_vector(&a);
03081   sinfo_unwrap_vector(&y);
03082   sinfo_free_my_vector(&sy);
03083   sinfo_unwrap_matrix(&x_matrix);
03084 
03085   sinfo_free_table(&xlr);
03086   sinfo_free_table(&ylr);
03087   sinfo_free_table(&wlr);
03088   sinfo_free_table(&tmp);
03089   sinfo_free_table(&temp2_tbl);
03090 
03091   return -1;
03092 
03093 }
03094 
03106 static cpl_vector*
03107 sinfo_filter_min(const cpl_vector* vi, const int size)
03108 {
03109 
03110   cpl_vector* vo=NULL;
03111   double min=0;
03112   int start=size/2;
03113   int end=0;
03114   int length=0;
03115   int i=0;
03116   int j=0;
03117   const double* pi=NULL;
03118   double* po=NULL;
03119   cknull(vi,"null input vector");
03120   pi=cpl_vector_get_data_const(vi);
03121   length=cpl_vector_get_size(vi);
03122   end=length-size/2;
03123   vo=cpl_vector_new(length);
03124   po=cpl_vector_get_data(vo);
03125 
03126   for(i=start; i < end; i++) {
03127     min=pi[i-start];
03128     for(j=i-start+1;j<i+start+1;j++) {
03129       if(min> pi[j]) {
03130     min=pi[j];
03131       }
03132     }
03133     po[i]=min;
03134 
03135   }
03136 
03137   // To prevent border effects:
03138   for (i = 0; i < start; i++) {
03139     po[i] = po[start];
03140   }
03141 
03142   for (i = end; i < length; i++) {
03143     po[i] = po[end-1];
03144   }
03145   return vo;
03146 
03147  cleanup:
03148   return NULL;
03149 
03150 
03151 }
03152 
03153 
03165 static cpl_vector*
03166 sinfo_filter_max(const cpl_vector* vi, const int size)
03167 {
03168 
03169   cpl_vector* vo=NULL;
03170   double max=0;
03171   int start=size/2;
03172   int end=0;
03173   int length=0;
03174   int i=0;
03175   int j=0;
03176   const double* pi=NULL;
03177   double* po=NULL;
03178 
03179   cknull(vi,"null input vector");
03180   pi=cpl_vector_get_data_const(vi);
03181   length=cpl_vector_get_size(vi);
03182   end=length-size/2;
03183   vo=cpl_vector_new(length);
03184   po=cpl_vector_get_data(vo);
03185 
03186   for(i=start; i < end; i++) {
03187     max=pi[i-start];
03188     for(j=i-start+1;j<i+start+1;j++) {
03189       if(max< pi[j]) {
03190     max=pi[j];
03191       }
03192     }
03193     po[i]=max;
03194 
03195   }
03196 
03197   // To prevent border effects:
03198   for (i = 0; i < start; i++) {
03199     po[i] = po[start];
03200   }
03201 
03202   for (i = end; i < length; i++) {
03203     po[i] = po[end-1];
03204   }
03205   return vo;
03206 
03207  cleanup:
03208   return NULL;
03209 
03210 
03211 }
03212 
03213 
03214 
03226 static cpl_vector*
03227 sinfo_filter_smo(const cpl_vector* vi, const int size)
03228 {
03229 
03230 
03231   double sum=0;
03232   int start=size/2;
03233   int end=0;
03234   int length=0;
03235   int i=0;
03236   int j=0;
03237   const double* pi=NULL;
03238   double* po=NULL;
03239   cpl_vector* vo=NULL;
03240 
03241   cknull(vi,"null input vector");
03242   length=cpl_vector_get_size(vi);
03243   end=length-size/2;
03244   vo=cpl_vector_new(length);
03245   pi=cpl_vector_get_data_const(vi);
03246   po=cpl_vector_get_data(vo);
03247 
03248   for(i=start; i < end; i++) {
03249     sum=0;
03250     for(j=i - start;j<i+start+1;j++) {
03251       sum += pi[j];
03252     }
03253     po[i]=sum/size;
03254 
03255   }
03256 
03257   // To prevent border effects:
03258   for (i = 0; i < start; i++) {
03259     po[i] = po[start];
03260   }
03261 
03262   for (i = end; i < length; i++) {
03263     po[i] = po[end-1];
03264   }
03265   return vo;
03266 
03267  cleanup:
03268   return NULL;
03269 
03270 }
03271 
03328 cpl_vector* sinfo_sky_background_estimate(cpl_vector *spectrum,
03329                                              int msize,
03330                                              int fsize)
03331 {
03332 
03333     cpl_vector  * minf=NULL;
03334     cpl_vector  * maxf=NULL;
03335     cpl_vector  * smof=NULL;
03336     cpl_vector  * back=NULL;
03337     double* pb=NULL;
03338     double* ps=NULL;
03339 
03340     int     i=0;
03341     int length=0;
03342 
03343 
03344     cknull(spectrum,"null input data");
03345 
03346     if (msize % 2 == 0)
03347         msize++;
03348 
03349     if (fsize % 2 == 0)
03350         fsize++;
03351     check_nomsg(length=cpl_vector_get_size(spectrum));
03352 
03353     if (msize < 3 || fsize < msize || length < 2*fsize)
03354         return NULL;
03355 
03356 
03357     cknull_nomsg(minf = sinfo_filter_min(spectrum, msize));
03358     cknull_nomsg(smof = sinfo_filter_smo(minf, fsize));
03359     cpl_vector_delete(minf);
03360     cknull_nomsg(maxf = sinfo_filter_max(smof,2*msize+1));
03361     cpl_vector_delete(smof);
03362     cknull_nomsg(smof = sinfo_filter_smo(maxf, 2*fsize+1));
03363     cpl_vector_delete(maxf);
03364     cknull_nomsg(minf = sinfo_filter_min(smof, 2*msize+1));
03365     cpl_vector_delete(smof);
03366     cknull_nomsg(smof = sinfo_filter_smo(minf, 2*fsize+1));
03367     cpl_vector_delete(minf);
03368     cknull_nomsg(back=cpl_vector_new(length));
03369     cknull_nomsg(pb=cpl_vector_get_data(back));
03370     cknull_nomsg(ps=cpl_vector_get_data(smof));
03371 
03372     for (i = 0; i < length; i++) {
03373         pb[i] = ps[i];
03374      }
03375     cpl_vector_delete(smof);
03376 
03377     return back;
03378  cleanup:
03379 
03380     return NULL;
03381 
03382 }
03383 
03384 
03385 
03395 static cpl_table*
03396 sinfo_slice_z(const cpl_imagelist* cin,const int i,const int j)
03397 {
03398   int sx=0;
03399   int sy=0;
03400   int sz=0;
03401   int k=0;
03402   cpl_table* tout=NULL;
03403   const cpl_image* img=NULL;
03404   const double* pim=NULL;
03405 
03406   cknull(cin,"null input imagelist");
03407   check_nomsg(sz=cpl_imagelist_get_size(cin));
03408   check_nomsg(img=cpl_imagelist_get_const(cin,0));
03409   check_nomsg(sx=cpl_image_get_size_x(img));
03410   check_nomsg(sy=cpl_image_get_size_y(img));
03411   check_nomsg(tout=cpl_table_new(sz));
03412   check_nomsg(cpl_table_new_column(tout,"VALUE",CPL_TYPE_DOUBLE));
03413   for(k=0;k<sz;k++) {
03414     check_nomsg(img=cpl_imagelist_get_const(cin,k));
03415     check_nomsg(pim=cpl_image_get_data_double_const(img));
03416     check_nomsg(cpl_table_set(tout,"VALUE",k,pim[j*sx+i]));
03417   }
03418 
03419   return tout;
03420  cleanup:
03421   sinfo_free_table(&tout);
03422 
03423   return NULL;
03424 
03425 }
03426 
03437 double
03438 sinfo_xcorr(cpl_table* int_obj,
03439             cpl_table* int_sky,
03440             cpl_table* lambda,
03441             const double dispersion,
03442             const double line_hw)
03443 {
03444 
03445   cpl_table* z=NULL;
03446   cpl_table* tmp_sky=NULL;
03447 
03448   cpl_table* z_diff=NULL;
03449   cpl_table* z_pos=NULL;
03450 
03451   int z_ext=0;
03452   double z_mean=0;
03453   double z_sdv=0;
03454   int nrow=0;
03455   int i=0;
03456 
03457   double g_lam=0;
03458   double g_err=0;
03459 
03460   double sky_max=0;
03461 
03462   double* pint=NULL;
03463   int* ppos=NULL;
03464   int status=0;
03465   int zsize=0;
03466   int iq=0;
03467 
03468   double g_diff=0;
03469   int jz=0;
03470   int z1=0;
03471   int nfit=0;
03472   int npos=0;
03473   cpl_table* z_good=NULL;
03474   cpl_table* w_tbl=NULL;
03475   cpl_table* o_tbl=NULL;
03476   cpl_table* s_tbl=NULL;
03477   cpl_vector* vw=NULL;
03478   cpl_vector* vs=NULL;
03479   cpl_vector* vo=NULL;
03480   cpl_vector* sx=NULL;
03481   cpl_vector* sy=NULL;
03482 
03483 
03484   double o1=0;
03485   double o2=0;
03486   double oc=0;
03487   double om=0;
03488 
03489 
03490 
03491   double zfit=0;
03492 
03493 
03494   double mse=0;
03495 
03496   double ws=0;
03497   double wc_s=0;
03498   double sig_s=0;
03499   double bkg_s=0;
03500   double amp_s=0;
03501   double area_s=0;
03502 
03503   double wo=0;
03504   double wc_o=0;
03505   double sig_o=0;
03506   double bkg_o=0;
03507   double amp_o=0;
03508   double area_o=0;
03509 
03510   cpl_polynomial* cfit=NULL;
03511   int pows[2];
03512   cpl_vector* vx=NULL;
03513   cpl_vector* vy=NULL;
03514 
03515 
03516   cpl_error_code error_code=CPL_ERROR_NONE;
03517 
03518   // crosscorrelate obj & sky to check for lambda offset
03519 
03520   //if (mean(z[where(finite(z))]) < 0) z = z * (-1);
03521   //if sky mean is < 0 flip sky intensity
03522   zsize=cpl_table_get_nrow(int_obj);
03523   check_nomsg(z = cpl_table_duplicate(int_sky));
03524   ck0_nomsg(sinfo_table_flag_nan(&z,"INT"));
03525   //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z1.fits",CPL_IO_DEFAULT));
03526   check_nomsg(z_mean=cpl_table_get_column_mean(z,"INT"));
03527   if(z_mean < 0) {
03528     check_nomsg(cpl_table_multiply_scalar(z,"INT",-1));
03529   }
03530   //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z2.fits",CPL_IO_DEFAULT));
03531 
03532   //z[where(int_sky < max(int_sky[where(finite(int_sky))])/4)] = 0;
03533   // take in consideration only strong sky lines (set else to 0)
03534   check_nomsg(tmp_sky=cpl_table_duplicate(int_sky));
03535   ck0_nomsg(sinfo_table_flag_nan(&tmp_sky,"INT"));
03536   check_nomsg(sky_max=cpl_table_get_column_max(tmp_sky,"INT"));
03537   sinfo_free_table(&tmp_sky);
03538 
03539   //flag too low values
03540   check_nomsg(nrow=cpl_table_get_nrow(z));
03541   check_nomsg(pint=cpl_table_get_data_double(z,"INT"));
03542   check_nomsg(sky_max=cpl_table_get_column_max(z,"INT"));
03543   for(i=0;i<nrow;i++) {
03544     if(pint[i]<sky_max/SKY_LINE_MIN_CUT) {
03545       pint[i]=0;
03546     }
03547   }
03548 
03549 
03550   //check_nomsg(cpl_table_save(z,NULL,NULL,"out_z4.fits",CPL_IO_DEFAULT));
03551   //computes gradient
03552   //z_diff = z[0:n_elements(z)-2] - z[1:n_elements(z)-1];
03553   check_nomsg(z_diff=cpl_table_duplicate(z));
03554   check_nomsg(cpl_table_duplicate_column(z_diff,"INT1",z,"INT"));
03555   check_nomsg(cpl_table_duplicate_column(z_diff,"INT2",z,"INT"));
03556   check_nomsg(cpl_table_shift_column(z_diff,"INT1",-1));
03557   check_nomsg(cpl_table_duplicate_column(z_diff,"DIFF",z_diff,"INT2"));
03558   check_nomsg(cpl_table_subtract_columns(z_diff,"DIFF","INT1"));
03559 
03560   check_nomsg(cpl_table_erase_window(z_diff,nrow-2,2));
03561   //check_nomsg(cpl_table_save(z_diff,NULL,NULL,
03562   //                             "out_z_diff.fits",CPL_IO_DEFAULT));
03563 
03564   //identify points positions at which there is a line pick
03565   check_nomsg(cpl_table_new_column(z_diff,"POS",CPL_TYPE_INT));
03566   check_nomsg(cpl_table_fill_column_window_int(z_diff,"POS",0,nrow,0));
03567 
03568   check_nomsg(pint=cpl_table_get_data_double(z_diff,"DIFF"));
03569   check_nomsg(ppos=cpl_table_get_data_int(z_diff,"POS"));
03570   check_nomsg(nrow=cpl_table_get_nrow(z_diff));
03571   for(i=1;i<nrow;i++) {
03572     if(!irplib_isnan(pint[i]) && (pint[i]>0 && pint[i-1]<0)) {
03573       ppos[i]=i;
03574     }
03575   }
03576 
03577   //check_nomsg(cpl_table_save(z_diff,NULL,NULL,"out_z_diff.fits",
03578   //                             CPL_IO_DEFAULT));
03579   check_nomsg(cpl_table_select_all(z_diff));
03580   check_nomsg(cpl_table_and_selected_int(z_diff,"POS",CPL_GREATER_THAN,0));
03581   check_nomsg(z_pos=cpl_table_extract_selected(z_diff));
03582   sinfo_free_table(&z_diff);
03583   //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
03584   //                             "out_z_pos.fits",CPL_IO_DEFAULT));
03585   //Do a gaussian fit in a range of size 2*zext centered at
03586   //each line maximum position (fit the line) to get in corresponding arrays:
03587   // 1) line lambda position of object and sky
03588   // 2) line object -sky intensity
03589   // 3) line object-sky intensity error
03590 
03591 
03592   g_lam = 0.;
03593   g_diff = 0.;
03594   g_err = 0.;
03595   check_nomsg(npos=cpl_table_get_nrow(z_pos));
03596   z_ext = line_hw ;
03597   check_nomsg(cpl_table_new_column(z_pos,"STATUS_S",CPL_TYPE_INT));
03598   check_nomsg(cpl_table_new_column(z_pos,"STATUS_O",CPL_TYPE_INT));
03599   check_nomsg(cpl_table_fill_column_window_int(z_pos,"STATUS_S",0,npos,0));
03600   check_nomsg(cpl_table_fill_column_window_int(z_pos,"STATUS_O",0,npos,0));
03601   check_nomsg(cpl_table_new_column(z_pos,"SIGS",CPL_TYPE_DOUBLE));
03602   check_nomsg(cpl_table_new_column(z_pos,"WAVES",CPL_TYPE_DOUBLE));
03603   check_nomsg(cpl_table_new_column(z_pos,"BKGS",CPL_TYPE_DOUBLE));
03604   check_nomsg(cpl_table_new_column(z_pos,"AREAS",CPL_TYPE_DOUBLE));
03605   check_nomsg(cpl_table_new_column(z_pos,"AMPS",CPL_TYPE_DOUBLE));
03606 
03607 
03608   check_nomsg(cpl_table_new_column(z_pos,"SIGO",CPL_TYPE_DOUBLE));
03609   check_nomsg(cpl_table_new_column(z_pos,"WAVEO",CPL_TYPE_DOUBLE));
03610   check_nomsg(cpl_table_new_column(z_pos,"BKGO",CPL_TYPE_DOUBLE));
03611   check_nomsg(cpl_table_new_column(z_pos,"AREAO",CPL_TYPE_DOUBLE));
03612   check_nomsg(cpl_table_new_column(z_pos,"AMPO",CPL_TYPE_DOUBLE));
03613 
03614   check_nomsg(cpl_table_new_column(z_pos,"WAVEC",CPL_TYPE_DOUBLE));
03615   check_nomsg(cpl_table_new_column(z_pos,"WDIF",CPL_TYPE_DOUBLE));
03616   check_nomsg(cpl_table_new_column(z_pos,"ERR",CPL_TYPE_DOUBLE));
03617 
03618   nfit=2*z_ext+1;
03619   //sinfo_msg("npos=%d z_ext=%d",npos,z_ext);
03620   //sinfo_table_column_dump(z_pos,"POS",CPL_TYPE_INT);
03621   //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
03622   //                             "out_z_pos_0.fits",CPL_IO_DEFAULT));
03623   //check_nomsg(cpl_table_save(int_obj,NULL,NULL,
03624   //                             "out_int_obj_0.fits",CPL_IO_DEFAULT));
03625   //check_nomsg(cpl_table_save(int_sky,NULL,NULL,
03626   //                             "out_int_sky_0.fits",CPL_IO_DEFAULT));
03627 
03628   for (jz=0;jz<npos;jz++) {
03629     check_nomsg(z1 = cpl_table_get_int(z_pos,"POS",jz,&status));
03630     //sinfo_msg("z1=%d",z1);
03631     // AMO added if check to prevent array explosion
03632     if((z1-z_ext) > 0 && (z1+z_ext) < zsize) {
03633       check_nomsg(cpl_table_select_all(int_sky));
03634       check_nomsg(cpl_table_select_all(int_obj));
03635       check_nomsg(cpl_table_select_all(lambda));
03636       check_nomsg(cpl_table_and_selected_window(int_sky,z1-z_ext,nfit));
03637       check_nomsg(s_tbl=cpl_table_extract_selected(int_sky));
03638       check_nomsg(cpl_table_and_selected_window(lambda,z1-z_ext,nfit));
03639       check_nomsg(w_tbl=cpl_table_extract_selected(lambda));
03640       check_nomsg(cpl_table_and_selected_window(int_obj,z1-z_ext,nfit));
03641       check_nomsg(o_tbl=cpl_table_extract_selected(int_obj));
03642 
03643 
03644       check_nomsg(vw=cpl_vector_wrap(nfit,
03645                      cpl_table_get_data_double(w_tbl,"WAVE")));
03646       check_nomsg(vs=cpl_vector_wrap(nfit,
03647                      cpl_table_get_data_double(s_tbl,"INT")));
03648       check_nomsg(vo=cpl_vector_wrap(nfit,
03649                      cpl_table_get_data_double(o_tbl,"INT")));
03650 
03651 
03652       check_nomsg(sx=cpl_vector_new(nfit));
03653       check_nomsg(cpl_vector_fill(sx,10.));
03654       check_nomsg(sy=cpl_vector_duplicate(sx));
03655 
03656 
03657       // Check if the object line is in emission or absorbtion
03658       o1=cpl_vector_get(vo,0);
03659       o2=cpl_vector_get(vo,nfit-1);
03660       oc=(o1+o2)*0.5;
03661       om=cpl_vector_get_median_const(vo);
03662       if(om<oc) {
03663     cpl_vector_multiply_scalar(vo,-1.);
03664       }
03665       check_nomsg(ws=cpl_table_get_double(lambda,"WAVE",z1,&status));
03666       check_nomsg(amp_s=cpl_table_get_double(z_pos,"INT",jz,&status));
03667       wc_s=ws;
03668       sig_s=z_ext*dispersion;
03669       bkg_s=0;
03670       area_s=sinfo_gaussian_area(amp_s,sig_s,ws,wc_s,bkg_s);
03671       if(wc_s < 2.35) {
03672         //sinfo_msg("wc_s=%f",wc_s);
03673         //cpl_vector_dump(vw,stdout);
03674         //cpl_vector_dump(vs,stdout);
03675 
03676         error_code=cpl_vector_fit_gaussian(vw,NULL,
03677                         vs,NULL,
03678                        CPL_FIT_ALL,
03679                        &wc_s,&sig_s,
03680                        &area_s,&bkg_s,
03681                        NULL,NULL,NULL);
03682         if(error_code == CPL_ERROR_NONE) {
03683       amp_s=sinfo_gaussian_amp(area_s,sig_s,ws,wc_s,bkg_s);
03684           check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
03685           check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
03686           check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
03687           check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
03688           check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
03689       /*
03690           sinfo_msg("Gauss fit parameters:");
03691           sinfo_msg("wc_s=%f sig_s=%f area_s=%f bkg_s=%f",
03692                      wc_s,sig_s,area_s,bkg_s);
03693           sinfo_msg("mse=%f chired=%f amp_s=%f",
03694                      mse,chired,amp_s);
03695       */
03696 
03697     } else if (error_code == CPL_ERROR_CONTINUE) {
03698       cpl_error_reset();
03699       amp_s=sinfo_gaussian_amp(area_s,sig_s,ws,wc_s,bkg_s);
03700           check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
03701           check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
03702           check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
03703           check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
03704           check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
03705           check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-1));
03706     } else {
03707       cpl_error_reset();
03708           check_nomsg(cpl_table_set_double(z_pos,"WAVES",jz,wc_s));
03709           check_nomsg(cpl_table_set_double(z_pos,"SIGS",jz,sig_s));
03710           check_nomsg(cpl_table_set_double(z_pos,"AREAS",jz,area_s));
03711           check_nomsg(cpl_table_set_double(z_pos,"BKGS",jz,bkg_s));
03712           check_nomsg(cpl_table_set_double(z_pos,"AMPS",jz,amp_s));
03713           check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-2));
03714     }
03715         check_nomsg(wo=cpl_table_get_double(lambda,"WAVE",z1,&status));
03716         check_nomsg(amp_o=cpl_table_get_double(z_pos,"INT",jz,&status));
03717         wc_o=wo;
03718         sig_o=z_ext*dispersion;
03719         bkg_o=0;
03720         area_o=sinfo_gaussian_area(amp_o,sig_o,wo,wc_o,bkg_o);
03721         error_code = cpl_vector_fit_gaussian(vw,NULL,
03722                       vo,sy,
03723                      CPL_FIT_ALL,
03724                      &wc_o,&sig_o,
03725                      &area_o,&bkg_o,
03726                      NULL,NULL,NULL);
03727 
03728         if(error_code == CPL_ERROR_NONE) {
03729 
03730           amp_o=sinfo_gaussian_amp(area_o,sig_o,wo,wc_o,bkg_o);
03731           check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
03732           check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
03733           check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
03734           check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
03735           check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
03736       /*
03737           sinfo_msg("Gauss fit parameters:");
03738           sinfo_msg("wc_o=%f sig_o=%f area_o=%f bkg_o=%f",
03739                      wc_o,sig_o,area_o,bkg_o);
03740           sinfo_msg("mse=%f chired=%f amp_o=%f",
03741                      mse,chired,amp_o);
03742       */
03743     } else if (error_code == CPL_ERROR_CONTINUE) {
03744 
03745       cpl_error_reset();
03746           amp_o=sinfo_gaussian_amp(area_o,sig_o,wo,wc_o,bkg_o);
03747           check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
03748           check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
03749           check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
03750           check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
03751           check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
03752           check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-1));
03753 
03754     } else {
03755       cpl_error_reset();
03756           check_nomsg(cpl_table_set_double(z_pos,"WAVEO",jz,wc_o));
03757           check_nomsg(cpl_table_set_double(z_pos,"SIGO",jz,sig_o));
03758           check_nomsg(cpl_table_set_double(z_pos,"AREAO",jz,area_o));
03759           check_nomsg(cpl_table_set_double(z_pos,"BKGO",jz,bkg_o));
03760           check_nomsg(cpl_table_set_double(z_pos,"AMPO",jz,amp_o));
03761           check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-2));
03762           /*
03763           if (lambda[z1] < 2.35 &&
03764              total(finite([l1,s1,o1])) == n_elements([l1,s1,o1])) {
03765             gs1 = float(gaussfit(l1,s1,as1,nterms=3));
03766             go1 = float(gaussfit(l1,o1,ao1,nterms=3));
03767             g_lam = [g_lam,(as1[1]+ao1[1])/2.];
03768             g_diff = [g_diff,as1[1]-ao1[1]];
03769             g_err = [g_err,sqrt(as1[2]^2+ao1[2]^2)];
03770           }
03771           */
03772         }
03773         check_nomsg(cpl_table_set_double(z_pos,"ERR",
03774                                        jz,sqrt(sig_s*sig_s+sig_o*sig_o)));
03775         check_nomsg(cpl_table_set_double(z_pos,"WDIF",jz,wc_s-wc_o));
03776         check_nomsg(cpl_table_set_double(z_pos,"WAVEC",jz,(wc_o+wc_s)/2));
03777 
03778       } else {
03779           check_nomsg(cpl_table_set_int(z_pos,"STATUS_S",jz,-3));
03780           check_nomsg(cpl_table_set_int(z_pos,"STATUS_O",jz,-3));
03781       }
03782       sinfo_unwrap_vector(&vw);
03783       sinfo_unwrap_vector(&vs);
03784       sinfo_unwrap_vector(&vo);
03785       sinfo_free_my_vector(&sx);
03786       sinfo_free_my_vector(&sy);
03787       sinfo_free_table(&w_tbl);
03788       sinfo_free_table(&s_tbl);
03789       sinfo_free_table(&o_tbl);
03790     }
03791   }
03792 
03793 
03794   check_nomsg(cpl_table_duplicate_column(z_pos,"YDIF",z_pos,"WDIF"));
03795   check_nomsg(cpl_table_divide_scalar(z_pos,"YDIF",dispersion));
03796   //sinfo_table_column_dump(z_pos,"WAVEC",CPL_TYPE_DOUBLE);
03797   //sinfo_table_column_dump(z_pos,"STATUS",CPL_TYPE_INT);
03798   //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
03799 
03800   check_nomsg(cpl_table_and_selected_int(z_pos,"STATUS_S",CPL_GREATER_THAN,-2));
03801   check_nomsg(cpl_table_and_selected_int(z_pos,"STATUS_O",CPL_GREATER_THAN,-2));
03802 
03803   //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
03804   //                             "out_z_pos.fits",CPL_IO_DEFAULT));
03805 
03806   //goto cleanup;
03807 
03808   check_nomsg(z_good=cpl_table_extract_selected(z_pos));
03809   check_nomsg(npos=cpl_table_get_nrow(z_good));
03810   sinfo_free_table(&z_pos);
03811   if(npos == 0) {
03812     return 0;
03813   }
03814   check_nomsg(z_pos=cpl_table_duplicate(z_good));
03815   check_nomsg(z_mean = cpl_table_get_column_median(z_pos,"WDIF"));
03816   check_nomsg(z_sdv  = cpl_table_get_column_stdev(z_pos,"WDIF"));
03817 
03818   //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
03819   //                             "out_z_pos.fits",CPL_IO_DEFAULT));
03820 
03821   check_nomsg(cpl_table_duplicate_column(z_pos,"CHECK",
03822                                          z_pos,"WDIF"));
03823 
03824 
03825   cpl_table_erase_column(z_pos,"AMPO");
03826   cpl_table_erase_column(z_pos,"SIGO");
03827   cpl_table_erase_column(z_pos,"AREAO");
03828   cpl_table_erase_column(z_pos,"BKGO");
03829   cpl_table_erase_column(z_pos,"WAVEO");
03830   cpl_table_erase_column(z_pos,"AMPS");
03831   cpl_table_erase_column(z_pos,"SIGS");
03832   cpl_table_erase_column(z_pos,"AREAS");
03833   cpl_table_erase_column(z_pos,"BKGS");
03834   cpl_table_erase_column(z_pos,"WAVES");
03835   cpl_table_erase_column(z_pos,"STATUS_S");
03836   cpl_table_erase_column(z_pos,"STATUS_O");
03837 
03838   cpl_table_erase_column(z_pos,"INT");
03839   cpl_table_erase_column(z_pos,"INT1");
03840   cpl_table_erase_column(z_pos,"INT2");
03841   cpl_table_erase_column(z_pos,"ERR");
03842   cpl_table_erase_column(z_pos,"POS");
03843   cpl_table_erase_column(z_pos,"DIFF");
03844 
03845   //check_nomsg(cpl_table_save(z_good,NULL,NULL,
03846   //                             "out_z_good.fits",CPL_IO_DEFAULT));
03847   //Do a kappa-sigma clip of the differences of line positions
03848   //as determined in the object and in the sky spectrum
03849 
03850   sinfo_msg("ks-clip1");
03851   sinfo_msg("iter mean (um) sdv (um) mean (pix) sdv (pix)");
03852   //sinfo_table_column_dump(z_pos,"WAVEC",CPL_TYPE_DOUBLE);
03853   //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
03854 
03855   for (iq = 0;iq<XCOR_YSHIFT_KS_CLIP;iq++) {
03856     //sinfo_msg("nval=%d",cpl_table_get_nrow(z_pos));
03857     sinfo_msg("  %d  %3.2g   %3.2g  %5.4g     %5.4g",
03858                iq,z_mean,z_sdv,z_mean/dispersion,z_sdv/dispersion);
03859     //z_good = where(abs(g_diff-z_mean) <= 2*z_sdv);
03860 
03861     check_nomsg(cpl_table_subtract_scalar(z_pos,"CHECK",z_mean));
03862     check_nomsg(cpl_table_duplicate_column(z_pos,"CHECKW",z_pos,"CHECK"));
03863     check_nomsg(cpl_table_multiply_columns(z_pos,"CHECKW","CHECK"));
03864     check_nomsg(cpl_table_power_column(z_pos,"CHECKW",0.5));
03865     check_nomsg(cpl_table_add_scalar(z_pos,"CHECK",z_mean));
03866     check_nomsg(cpl_table_and_selected_double(z_pos,"CHECKW",
03867                                               CPL_NOT_GREATER_THAN,2*z_sdv));
03868     sinfo_free_table(&z_good);
03869     check_nomsg(z_good=cpl_table_extract_selected(z_pos));
03870     //sinfo_msg("ngood=%d",cpl_table_get_nrow(z_good));
03871     check_nomsg(cpl_table_select_all(z_pos));
03872     //z_mean = median(g_diff[z_good]);
03873     //z_sdv = stddev(g_diff[z_good]);
03874     check_nomsg(z_mean = cpl_table_get_column_median(z_good,"WDIF"));
03875     if(nfit>1) {
03876     check_nomsg(z_sdv  = cpl_table_get_column_stdev(z_good,"WDIF"));
03877     } else {
03878       z_sdv=0;
03879     }
03880     sinfo_free_table(&z_good);
03881     check_nomsg(cpl_table_erase_column(z_pos,"CHECKW"));
03882 
03883   }
03884   /* do a poly fit of wdif versus wave*/
03885   /*
03886   for (iq = 0; iq<3; iq++) {
03887     // sinfo_msg("%d %f %f",iq,mean(zfit),zsdv);
03888     par1 = poly_fit(g_lam[z_good],g_diff[z_good],poly_n);
03889     z_fit = g_diff*0.;
03890     for (ii=0;ii<poly_n) z_fit = z_fit + par1[ii]*g_lam^ii;
03891     z_res = g_diff-z_fit;
03892     z_sdv = stddev(z_res[zgood]);
03893     z_good = where(abs(z_res) le 3*z_sdv);
03894   }
03895   */
03896   cpl_table_select_all(z_pos);
03897   check_nomsg(cpl_table_new_column(z_pos,"ZFIT",CPL_TYPE_DOUBLE));
03898   check_nomsg(nfit=cpl_table_get_nrow(z_pos));
03899   check_nomsg(cpl_table_fill_column_window(z_pos,"ZFIT",0,nfit,0));
03900   //check_nomsg(cpl_table_save(z_pos,NULL,NULL,
03901   //                             "out_z_pos2.fits",CPL_IO_DEFAULT));
03902   check_nomsg(z_good=cpl_table_duplicate(z_pos));
03903 
03904   //Do a fit of a uniform function to the residuals line position differences
03905   sinfo_msg("ks-clip2");
03906   sinfo_msg("iter mean (um) sdv (um) mean (pix) sdv (pix)");
03907   check_nomsg(cpl_table_select_all(z_good));
03908   //sinfo_table_column_dump(z_pos,"WDIF",CPL_TYPE_DOUBLE);
03909   for(iq=0;iq<XCOR_YSHIFT_KS_CLIP;iq++) {
03910     //cpl_table_dump(z_pos,0,cpl_table_get_nrow(z_pos),stdout);
03911     check_nomsg(nfit=cpl_table_get_nrow(z_good));
03912     //sinfo_msg("nfit=%d",nfit);
03913     if(nfit>0) {
03914     check_nomsg(vx=cpl_vector_wrap(nfit,
03915                    cpl_table_get_data_double(z_good,"WAVE")));
03916     check_nomsg(vy=cpl_vector_wrap(nfit,
03917                    cpl_table_get_data_double(z_good,"WDIF")));
03918     check_nomsg(cfit=sinfo_polynomial_fit_1d_create(vx,vy,0,&mse));
03919     pows[0]=0;
03920     pows[1]=0;
03921     check_nomsg(zfit=cpl_polynomial_get_coeff(cfit,pows));
03922     sinfo_free_polynomial(&cfit);
03923     //sinfo_msg("coeff 0=%g um %g pix",zfit,zfit/dispersion);
03924 
03925     //computes residuals=difference-fit and their standard deviation
03926     //and then do a kappa-sigma clip of outliers (out of 3 sigma)
03927     check_nomsg(cpl_table_fill_column_window(z_good,"ZFIT",0,nfit,zfit));
03928     check_nomsg(cpl_table_duplicate_column(z_good,"WRES",z_good,"WDIF"));
03929     check_nomsg(cpl_table_subtract_columns(z_good,"WRES","ZFIT"));
03930     if(nfit>1) {
03931       //sinfo_msg("nfit=%d",nfit);
03932       //cpl_table_dump(z_good,0,nfit,stdout);
03933       check_nomsg(z_sdv=cpl_table_get_column_stdev(z_good,"WRES"));
03934       //sinfo_msg("z_sdv=%f",z_sdv);
03935     } else {
03936       z_sdv=0;
03937     }
03938     check_nomsg(z_mean=cpl_table_get_column_mean(z_good,"WDIF"));
03939 
03940     sinfo_msg("  %d  %3.2g   %3.2g  %5.4g     %5.4g",
03941               iq,z_mean,z_sdv,z_mean/dispersion,z_sdv/dispersion);
03942 
03943     check_nomsg(nfit=cpl_table_get_nrow(z_pos));
03944     check_nomsg(cpl_table_fill_column_window(z_pos,"ZFIT",0,nfit,zfit));
03945     check_nomsg(cpl_table_duplicate_column(z_pos,"WRES",z_pos,"WDIF"));
03946     check_nomsg(cpl_table_subtract_columns(z_pos,"WRES","ZFIT"));
03947 
03948     check_nomsg(cpl_table_multiply_columns(z_pos,"WRES","WRES"));
03949     check_nomsg(cpl_table_power_column(z_pos,"WRES",0.5));
03950     //cpl_table_dump(z_pos,0,cpl_table_get_nrow(z_pos),stdout);
03951     /*
03952     sinfo_msg("min=%g max=%g ndat=%d",
03953               cpl_table_get_column_min(z_pos,"WRES"),
03954               cpl_table_get_column_max(z_pos,"WRES"),
03955               cpl_table_get_nrow(z_pos));
03956     */
03957     check_nomsg(cpl_table_and_selected_double(z_pos,"WRES",
03958                                               CPL_NOT_GREATER_THAN,3*z_sdv));
03959 
03960     check_nomsg(sinfo_free_table(&z_good));
03961     check_nomsg(z_good=cpl_table_extract_selected(z_pos));
03962 
03963 
03964     check_nomsg(cpl_table_select_all(z_pos));
03965     check_nomsg(cpl_table_select_all(z_good));
03966     check_nomsg(cpl_table_erase_column(z_good,"WRES"));
03967     check_nomsg(cpl_table_erase_column(z_pos,"WRES"));
03968 
03969     sinfo_unwrap_vector(&vx);
03970     sinfo_unwrap_vector(&vy);
03971 
03972     }
03973 
03974   }
03975   //sinfo_msg(">>mean=%g",cpl_table_get_column_mean(z_good,"WDIF"));
03976 
03977   //check_nomsg(cpl_table_save(z_good,NULL,NULL,
03978   //                             "out_z_pos3.fits",CPL_IO_DEFAULT));
03979   sinfo_unwrap_vector(&vx);
03980   sinfo_unwrap_vector(&vy);
03981   sinfo_free_polynomial(&cfit);
03982   sinfo_free_table(&z);
03983   sinfo_free_table(&z_pos);
03984   sinfo_free_table(&z_good);
03985 
03986 
03987   return zfit;
03988  cleanup:
03989 
03990   sinfo_free_table(&z_good);
03991   sinfo_free_table(&z);
03992   sinfo_free_table(&z_diff);
03993   sinfo_free_table(&tmp_sky);
03994   sinfo_free_table(&z_pos);
03995   sinfo_unwrap_vector(&vw);
03996   sinfo_unwrap_vector(&vs);
03997   sinfo_unwrap_vector(&vo);
03998   sinfo_free_my_vector(&sx);
03999   sinfo_free_my_vector(&sy);
04000   sinfo_unwrap_vector(&vx);
04001   sinfo_unwrap_vector(&vy);
04002   sinfo_free_table(&w_tbl);
04003   sinfo_free_table(&s_tbl);
04004   sinfo_free_table(&o_tbl);
04005   sinfo_free_polynomial(&cfit);
04006 
04007   return 0;
04008 
04009 
04010 }
04011 
04012 
04013 
04014 
04027 static int
04028 sinfo_table_set_nan_out_min_max(cpl_table** t,
04029                                 const char* c,
04030                                 const double min,
04031                                 const double max)
04032 
04033 {
04034 
04035   int sz=0;
04036   int i=0;
04037   double* pt=NULL;
04038 
04039   check_nomsg(sz=cpl_table_get_nrow(*t));
04040   check_nomsg(pt=cpl_table_get_data_double(*t,c));
04041   for(i=0;i<sz;i++) {
04042     if(pt[i] < min || pt[i] > max) {
04043       check_nomsg(cpl_table_set_invalid(*t ,c,i));
04044     }
04045   }
04046 
04047   return 0;
04048 
04049  cleanup:
04050 
04051   return -1;
04052 
04053 
04054 }
04055 
04065 static int
04066 sinfo_table_flag_nan(cpl_table** t,const char* label)
04067 {
04068 
04069   int sz=0;
04070   int i=0;
04071   double* pt=NULL;
04072 
04073   check_nomsg(sz=cpl_table_get_nrow(*t));
04074   check_nomsg(pt=cpl_table_get_data_double(*t,label));
04075   for(i=0;i<sz;i++) {
04076     if(irplib_isnan(pt[i])) {
04077       check_nomsg(cpl_table_set_invalid(*t ,label,i));
04078     }
04079   }
04080 
04081   return 0;
04082 
04083  cleanup:
04084 
04085   return -1;
04086 }
04087 
04097 static int
04098 sinfo_table_sky_obj_flag_nan(cpl_table** s,cpl_table** o, cpl_table** w)
04099 {
04100 
04101   int no=0;
04102   int ns=0;
04103   int nw=0;
04104   int ni=0;
04105 
04106   int i=0;
04107   double* po=NULL;
04108   double* ps=NULL;
04109   double* pw=NULL;
04110 
04111   check_nomsg(no=cpl_table_get_nrow(*o));
04112   check_nomsg(ns=cpl_table_get_nrow(*s));
04113   check_nomsg(nw=cpl_table_get_nrow(*w));
04114   if(no != ns || ns != nw || no != nw) {
04115     sinfo_msg_error("different input tables sizes");
04116     goto cleanup;
04117   }
04118   check_nomsg(po=cpl_table_get_data_double(*o,"INT"));
04119   check_nomsg(ps=cpl_table_get_data_double(*s,"INT"));
04120   check_nomsg(pw=cpl_table_get_data_double(*w,"WAVE"));
04121 
04122   for(i=0;i<no;i++) {
04123     if( (0==cpl_table_is_valid(*o,"INT",i)) ||
04124         irplib_isnan(po[i]) || irplib_isnan(ps[i]) || irplib_isnan(pw[i]) ) {
04125       check_nomsg(cpl_table_set_invalid(*o ,"INT",i));
04126       check_nomsg(cpl_table_set_invalid(*s ,"INT",i));
04127       check_nomsg(cpl_table_set_invalid(*w ,"WAVE",i));
04128       //sinfo_msg_debug("Flagged raw %d",i);
04129       ni++;
04130     }
04131   }
04132 
04133   return no-ni;
04134 
04135  cleanup:
04136 
04137   return -1;
04138 }
04139 
04140 /*
04141 static void
04142 sinfo_shift_sky(const int x,const int y)
04143 {
04144 
04145   //To remove compilation warnings
04146   ck0_nomsg(x);
04147   ck0_nomsg(y);
04148 
04149   // shift sky spectrum of a given amount
04150   if (max(abs(z_fit))/cdelts < 0.01) {
04151     sinfo_msg("shift <0.01 pixels will not be applied");
04152   } else {
04153     sinfo_msg("shifting sky cube by mean of %f pix wrt object",
04154              cpl_table_column_mean(z_fit,"VALUE")/cdelto);
04155     sinfo_msg("this will take a couple of minutes...");
04156     z_good = where(finite(int_sky));
04157     new_sky = spline(lambda[z_good]-z_mean,int_sky[z_good],lambda);
04158     int_sky = new_sky;
04159     sky_out = dblarr(xsize,ysize,zsize) + !values.f_nan;
04160     for (ix=0; ix<xsize;ix++) {
04161       for (iy=0;iy<ysize;iy++) {
04162     old_sky = reform(sky[ix,iy,*]);
04163     z_good = where(finite(old_sky),z_good_i);
04164     if (z_good_i > 0) {
04165           new_sky= spline(lambda[z_good]-z_fit[z_good],old_sky[z_good],lambda);
04166           new_fin= where(finite(new_sky,/infinity) ||
04167                           finite(old_sky,/nan),newfin_i);
04168       if (new_fin_i > 0) new_sky[new_fin] = !values.f_nan;
04169       sky_out[ix,iy,*] = new_sky;
04170     }
04171       }
04172     }
04173     sky = sky_out;
04174   }
04175  cleanup:
04176   return;
04177 
04178 }
04179   */
04206 void
04207 sinfo_optimise_sky_sub(const double wtol,
04208                        const double line_hw,
04209                        const int method,
04210                        const int do_rot,
04211                        cpl_table* lrange,
04212                        cpl_table* lambda,
04213                        cpl_table* lr41,
04214                        cpl_table* lr52,
04215                        cpl_table* lr63,
04216                        cpl_table* lr74,
04217                        cpl_table* lr02,
04218                        cpl_table* lr85,
04219                        cpl_table* lr20,
04220                        cpl_table* lr31,
04221                        cpl_table* lr42,
04222                        cpl_table* lr53,
04223                        cpl_table* lr64,
04224                        cpl_table* lr75,
04225                        cpl_table* lr86,
04226                        cpl_table* lr97,
04227                        cpl_table* lr00,
04228                        cpl_table** int_obj,
04229                        cpl_table** int_sky,
04230                        cpl_table** rscale)
04231 
04232 {
04233 
04234   int npixw=2*line_hw; //full width in pixels of unresolved emission line
04235   cpl_array* do_hk=NULL;
04236   cpl_array* rfit=NULL;
04237   int i=0;
04238   cpl_table* sky_lr=NULL;
04239   cpl_table* obj_lr=NULL;
04240   cpl_table* wav_lr=NULL;
04241   double sky_med=0;
04242   double sky_sdv=0;
04243   int lr41_i=0;
04244   int lr52_i=0;
04245   int lr63_i=0;
04246   int lr74_i=0;
04247   int lr02_i=0;
04248   int lr85_i=0;
04249   int lr20_i=0;
04250   int lr31_i=0;
04251   int lr42_i=0;
04252   int lr53_i=0;
04253   int lr64_i=0;
04254   int lr75_i=0;
04255   int lr86_i=0;
04256   int lr97_i=0;
04257   int lr00_i=0;
04258 
04259   int xxx1_i=0;
04260   int status=0;
04261   int finite_pix_i=0;
04262   double sky_thresh=0.;
04263 
04264   cpl_table* rat_sky=NULL;
04265 
04266   cpl_table* xxx1=NULL;
04267   cpl_table* xxx2=NULL;
04268   cpl_table* xxx1_sub=NULL;
04269   cpl_table* line_regions=NULL;
04270   cpl_table* cont_regions=NULL;
04271   int line_i=0;
04272   int cont_i=0;
04273   double fmed=0;
04274   double fsdv=0;
04275   cpl_table* fline_res=NULL;
04276   int fclip_i=0;
04277   int fline_i=0;
04278   cpl_table* rscale0=NULL;
04279   double r=0;
04280   cpl_table* obj_cont=NULL;
04281   cpl_table* sky_cont=NULL;
04282   cpl_table* obj_line=NULL;
04283   cpl_table* sky_line=NULL;
04284 
04285 
04286   //Rotational parameters
04287   int low_pos_i=0;
04288   int med_pos_i=0;
04289   int hi_pos_i=0;
04290 
04291   cpl_table* finite_pix=NULL;
04292   cpl_table* tmp_tbl=NULL;
04293 
04294   cpl_table* low_scale=NULL;
04295   cpl_table* med_scale=NULL;
04296   cpl_table* hi_regions=NULL;
04297 
04298   cpl_table* low_regions=NULL;
04299   cpl_table* med_regions=NULL;
04300 
04301 
04302   cpl_table* low_pos=NULL;
04303   cpl_table* med_pos=NULL;
04304   cpl_table* hi_pos=NULL;
04305   cpl_table* llr_xxx1=NULL;
04306 
04307   double rhi=0;
04308   double rmed=0;
04309   double rlow=0;
04310 
04311   double min_lrange=0;
04312   double max_lrange=0;
04313 
04314   int nrow=0;
04315 
04316 
04317   double w_rot_low[NROT]={1.00852,1.03757,1.09264,1.15388,1.22293,
04318                           1.30216,1.45190,1.52410,1.60308,1.69037,
04319                           1.78803,2.02758,2.18023,1.02895,1.08343,
04320                           1.14399,1.21226,1.29057,1.43444,1.50555,
04321                           1.58333,1.66924,1.76532,2.00082,2.15073};
04322 
04323 
04324   double w_rot_med[NROT]={1.00282,1.02139,1.04212,1.07539,1.09753,
04325                           1.13542,1.15917,1.20309,1.22870,1.28070,
04326                           1.30853,1.41861,1.46048,1.48877,1.53324,
04327                           1.56550,1.61286,1.65024,1.70088,1.74500,
04328                           1.79940,1.97719,2.04127,2.12496,2.19956};
04329 
04330 
04331 
04332   check_nomsg(do_hk = cpl_array_new(NBOUND+1,CPL_TYPE_INT));
04333   check_nomsg(rfit  = cpl_array_new(NBOUND+1,CPL_TYPE_DOUBLE));
04334 
04335   lr41_i=cpl_table_get_nrow(lr41);
04336   lr52_i=cpl_table_get_nrow(lr52);
04337   lr63_i=cpl_table_get_nrow(lr63);
04338   lr74_i=cpl_table_get_nrow(lr74);
04339   lr02_i=cpl_table_get_nrow(lr02);
04340   lr85_i=cpl_table_get_nrow(lr85);
04341   lr20_i=cpl_table_get_nrow(lr20);
04342   lr31_i=cpl_table_get_nrow(lr31);
04343   lr42_i=cpl_table_get_nrow(lr42);
04344   lr53_i=cpl_table_get_nrow(lr53);
04345   lr64_i=cpl_table_get_nrow(lr64);
04346   lr75_i=cpl_table_get_nrow(lr75);
04347   lr86_i=cpl_table_get_nrow(lr86);
04348   lr97_i=cpl_table_get_nrow(lr97);
04349   check_nomsg(lr00_i=cpl_table_get_nrow(lr00));
04350 
04351   cpl_array_set_int(do_hk,0,lr41_i);
04352   cpl_array_set_int(do_hk,1,lr52_i);
04353   cpl_array_set_int(do_hk,2,lr63_i);
04354   cpl_array_set_int(do_hk,3,lr74_i);
04355   cpl_array_set_int(do_hk,4,lr02_i);
04356   cpl_array_set_int(do_hk,5,lr85_i);
04357   cpl_array_set_int(do_hk,6,lr20_i);
04358   cpl_array_set_int(do_hk,7,lr31_i);
04359   cpl_array_set_int(do_hk,8,lr42_i);
04360   cpl_array_set_int(do_hk,9,lr53_i);
04361   cpl_array_set_int(do_hk,10,lr64_i);
04362   cpl_array_set_int(do_hk,11,lr75_i);
04363   cpl_array_set_int(do_hk,12,lr86_i);
04364   cpl_array_set_int(do_hk,13,lr97_i);
04365   check_nomsg(cpl_array_set_int(do_hk,14,lr00_i));
04366 
04367   check_nomsg(rscale0=cpl_table_duplicate(*int_sky));
04368   check_nomsg(cpl_table_new_column(rscale0,"RATIO",CPL_TYPE_DOUBLE));
04369   check_nomsg(nrow=cpl_table_get_nrow(rscale0));
04370   check_nomsg(cpl_table_fill_column_window(rscale0,"RATIO",0,nrow,0));
04371 
04372   // For each range extract proper: obj, sky, wave spectra
04373   for (i=0;i<NBOUND+1;i++) {
04374     if (cpl_array_get_int(do_hk,i,&status) > 0) {
04375 
04376 
04377       switch(i) {
04378 
04379 
04380       case 0:
04381         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr41,wtol,
04382                         &obj_lr,&sky_lr,&wav_lr));
04383     break;
04384 
04385       case 1:
04386         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr52,wtol,
04387                         &obj_lr,&sky_lr,&wav_lr));
04388     break;
04389 
04390       case 2:
04391         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr63,wtol,
04392                         &obj_lr,&sky_lr,&wav_lr));
04393     break;
04394 
04395       case 3:
04396         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr74,wtol,
04397                         &obj_lr,&sky_lr,&wav_lr));
04398     break;
04399 
04400       case 4:
04401         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr02,wtol,
04402                         &obj_lr,&sky_lr,&wav_lr));
04403     break;
04404 
04405       case 5:
04406         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr85,wtol,
04407                         &obj_lr,&sky_lr,&wav_lr));
04408     break;
04409       case 6:
04410         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr20,wtol,
04411                         &obj_lr,&sky_lr,&wav_lr));
04412     break;
04413       case 7:
04414         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr31,wtol,
04415                         &obj_lr,&sky_lr,&wav_lr));
04416     break;
04417       case 8:
04418         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr42,wtol,
04419                         &obj_lr,&sky_lr,&wav_lr));
04420     break;
04421       case 9:
04422         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr53,wtol,
04423                         &obj_lr,&sky_lr,&wav_lr));
04424     break;
04425       case 10:
04426         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr64,wtol,
04427                         &obj_lr,&sky_lr,&wav_lr));
04428     break;
04429       case 11:
04430         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr75,wtol,
04431                         &obj_lr,&sky_lr,&wav_lr));
04432     break;
04433       case 12:
04434         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr86,wtol,
04435                         &obj_lr,&sky_lr,&wav_lr));
04436     break;
04437       case 13:
04438         ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr97,wtol,
04439                         &obj_lr,&sky_lr,&wav_lr));
04440     break;
04441       case 14:
04442          ck0_nomsg(sinfo_get_obj_sky_wav_sub(*int_obj,*int_sky,lambda,lr00,
04443                          wtol,&obj_lr,&sky_lr,&wav_lr));
04444      break;
04445       default:
04446         sinfo_msg_error("case not supported");
04447     goto cleanup;
04448       }
04449       if(sky_lr == NULL || obj_lr == NULL || wav_lr == NULL) {
04450     finite_pix_i=0;
04451         sinfo_msg("no good pix left");
04452       } else {
04453     //AMO: the following 2 seems to be critical for robustness
04454     //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,"out_skylr0.fits",
04455     //             CPL_IO_DEFAULT));
04456     //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,"out_objlr0.fits",
04457     //             CPL_IO_DEFAULT));
04458     //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,"out_wavlr0.fits",
04459     //             CPL_IO_DEFAULT));
04460 
04461 
04462 
04463     check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(&sky_lr,
04464                                                               &obj_lr,
04465                                                               &wav_lr));
04466 
04467 
04468       }
04469 
04470 
04471       if (finite_pix_i > npixw) {
04472         // identify sky lines
04473         //sinfo_msg("finite_pix_i=%d",finite_pix_i);
04474         check_nomsg(cpl_table_erase_invalid(obj_lr));
04475     check_nomsg(cpl_table_erase_invalid(sky_lr));
04476     check_nomsg(cpl_table_erase_invalid(wav_lr));
04477 
04478 
04479     check_nomsg(sky_med=cpl_table_get_column_median(sky_lr,"INT"));
04480     check_nomsg(sky_sdv=cpl_table_get_column_stdev(sky_lr,"INT"));
04481         check_nomsg(cpl_table_select_all(sky_lr));
04482         sky_thresh=sky_med+sky_sdv;
04483         //sinfo_msg("sky_thresh=%f",sky_thresh);
04484         check_nomsg(xxx1_i=cpl_table_and_selected_double(sky_lr,"INT",
04485                            CPL_GREATER_THAN,sky_thresh));
04486     check_nomsg(xxx1 = cpl_table_extract_selected(sky_lr));
04487         check_nomsg(cpl_table_select_all(sky_lr));
04488 
04489     if (xxx1_i > 0) {
04490       //separate line and continuum regions
04491           //by convolving with a hat region of large as a line
04492           //sinfo_msg("xxx1_i=%d",xxx1_i);
04493       check_nomsg(xxx2 = cpl_table_duplicate(sky_lr));
04494           //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,
04495           //                           "out_skylr.fits",CPL_IO_DEFAULT));
04496           //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
04497           //                             "out_objlr.fits",CPL_IO_DEFAULT));
04498           //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04499           //                             "out_xxx2_0.fits",CPL_IO_DEFAULT));
04500           ck0_nomsg(sinfo_table_threshold(&xxx2,"INT",sky_thresh,
04501                                           sky_thresh,0.,10.));
04502           //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04503           //                             "out_xxx2_1.fits",CPL_IO_DEFAULT));
04504 
04505 
04506           /* TODO
04507       xxx2[xxx1] = 10.;
04508       */
04509           //sinfo_msg("npixw/2=%d",npixw);
04510       check_nomsg(sinfo_convolve_kernel(&xxx2,npixw/2));
04511           //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04512           //                             "out_xxx2_2.fits",CPL_IO_DEFAULT));
04513 
04514           // get line_regions
04515           check_nomsg(line_i=cpl_table_and_selected_double(xxx2,"CNV",
04516                                                          CPL_GREATER_THAN,0));
04517 
04518           check_nomsg(line_regions=cpl_table_extract_selected(xxx2));
04519 
04520           //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
04521           //"out_line_regions.fits",CPL_IO_DEFAULT));
04522 
04523       check_nomsg(cpl_table_erase_column(line_regions,"INT"));
04524       check_nomsg(cpl_table_erase_column(line_regions,"CNV"));
04525 
04526           check_nomsg(cpl_table_select_all(xxx2));
04527 
04528           // get cont_regions
04529           check_nomsg(cont_i=cpl_table_and_selected_double(xxx2,"CNV",
04530                                                            CPL_EQUAL_TO,0));
04531           check_nomsg(cont_regions=cpl_table_extract_selected(xxx2));
04532 
04533           //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
04534           //"out_cont_regions.fits",CPL_IO_DEFAULT));
04535 
04536       check_nomsg(cpl_table_erase_column(cont_regions,"INT"));
04537       check_nomsg(cpl_table_erase_column(cont_regions,"CNV"));
04538           check_nomsg(cpl_table_select_all(xxx2));
04539       sinfo_free_table(&xxx2);
04540 
04541 
04542       if (line_i >= 3 && cont_i >= 3) {
04543             //If we have enough line points and continuum points
04544              //sinfo_msg("line_i=%d cont_i=%d",line_i,cont_i);
04545         if (i == 0) sinfo_msg("optimising 4-1 transitions");
04546             if (i == 1) sinfo_msg("optimising 5-2 transitions");
04547             if (i == 2) sinfo_msg("optimising 6-3 transitions");
04548             if (i == 3) sinfo_msg("optimising 7-4 transitions");
04549             if (i == 4) sinfo_msg("optimising 0-2 transitions");
04550             if (i == 5) sinfo_msg("optimising 8-5 transitions");
04551             if (i == 6) sinfo_msg("optimising 2-0 transitions");
04552             if (i == 7) sinfo_msg("optimising 3-1 transitions");
04553             if (i == 8) sinfo_msg("optimising 4-2 transitions");
04554             if (i == 9) sinfo_msg("optimising 5-3 transitions");
04555             if (i == 10) sinfo_msg("optimising 6-4 transitions");
04556             if (i == 11) sinfo_msg("optimising 7-5 transitions");
04557             if (i == 12) sinfo_msg("optimising 8-6 transitions");
04558             if (i == 13) sinfo_msg("optimising 9-7 transitions");
04559             if (i == 14) sinfo_msg("optimising final bit");
04560         // Fit the object profile='fline_res' of the sky line residuals
04561             // left after proper scaled sky spectrum lines (and continua)
04562             // subtraction. Then determines median and stdev to flag outliers
04563 
04564         //Free memory for each loop
04565             sinfo_free_table(&obj_cont);
04566             sinfo_free_table(&sky_cont);
04567             sinfo_free_table(&sky_line);
04568             sinfo_free_table(&obj_line);
04569         //Identify obj lines and continuum, same for sky
04570             cknull_nomsg(obj_line=sinfo_table_select_range(obj_lr,line_regions,
04571                                   wtol));
04572 
04573 
04574             cknull_nomsg(sky_line=sinfo_table_select_range(sky_lr,line_regions,
04575                                   wtol));
04576             cknull_nomsg(obj_cont=sinfo_table_select_range(obj_lr,cont_regions,
04577                                   wtol));
04578              cknull_nomsg(sky_cont=sinfo_table_select_range(sky_lr,cont_regions,
04579                                   wtol));
04580 
04581         //Here was commented
04582             //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
04583             //            "out_line.fits",CPL_IO_DEFAULT));
04584             //check_nomsg(cpl_table_save(cont_regions,NULL,NULL,
04585             //            "out_cont.fits",CPL_IO_DEFAULT));
04586             //check_nomsg(cpl_table_save(obj_cont,NULL,NULL,
04587             //            "out_obj_cont.fits",CPL_IO_DEFAULT));
04588             //check_nomsg(cpl_table_save(obj_line,NULL,NULL,
04589             //            "out_obj_line.fits",CPL_IO_DEFAULT));
04590             //check_nomsg(cpl_table_save(sky_line,NULL,NULL,
04591             //            "out_sky_line.fits",CPL_IO_DEFAULT));
04592             //check_nomsg(cpl_table_save(sky_cont,NULL,NULL,
04593             //            "out_sky_cont.fits",CPL_IO_DEFAULT));
04594 
04595 
04596             sinfo_free_table(&fline_res);
04597             //FIXME: in some cases obj_cont is empty
04598             //sinfo_msg("first line ratio determination");
04599             ck0_nomsg(sinfo_get_line_ratio(obj_line,obj_cont,
04600                        sky_line,sky_cont,method,&r));
04601         sinfo_msg("1st Line ratio %g",r);
04602 
04603 
04604             if(cpl_table_get_nrow(obj_cont) > 0) {
04605                check_nomsg(fline_res=sinfo_table_interpol(obj_line,obj_cont,
04606                                                           sky_line,sky_cont,
04607                                                           r));
04608         } else {
04609               check_nomsg(fline_res=cpl_table_duplicate(obj_line));
04610         }
04611 
04612             // check if there are outliers
04613             cpl_table_select_all(fline_res);
04614             check_nomsg(fmed = cpl_table_get_column_median(fline_res,"INT"));
04615             check_nomsg(fsdv = cpl_table_get_column_stdev(fline_res,"INT"));
04616 
04617             check_nomsg(cpl_table_duplicate_column(fline_res,"AINT",
04618                                                    fline_res,"INT"));
04619             check_nomsg(cpl_table_multiply_columns(fline_res,"AINT","INT"));
04620             check_nomsg(cpl_table_power_column(fline_res,"AINT",0.5));
04621             check_nomsg(fclip_i=cpl_table_and_selected_double(fline_res,"AINT",
04622                                                   CPL_GREATER_THAN,
04623                                                   fmed+3*fsdv));
04624 
04625             check_nomsg(cpl_table_select_all(fline_res));
04626 
04627 
04628         if (fclip_i > 0) {
04629               // do a k-sigma clip to select a better line region
04630               //sinfo_msg("fclip_i=%d",fclip_i);
04631               //Find again line_regions
04632               check_nomsg(line_i=cpl_table_and_selected_double(fline_res,
04633                                    "AINT",
04634                                    CPL_NOT_GREATER_THAN,
04635                                    fmed+3*fsdv));
04636           // get new (better) line_regions
04637           sinfo_free_table(&line_regions);
04638               //sinfo_msg("line_i=%d",line_i);
04639               check_nomsg(line_regions=cpl_table_extract_selected(fline_res));
04640               check_nomsg(cpl_table_erase_column(line_regions,"INT"));
04641               check_nomsg(cpl_table_erase_column(line_regions,"AINT"));
04642 
04643           sinfo_free_table(&obj_line);
04644           sinfo_free_table(&sky_line);
04645 
04646           //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
04647               //                           "out_obj_lr.fits",CPL_IO_DEFAULT));
04648           //check_nomsg(cpl_table_save(line_regions,NULL,NULL,
04649               //                           "out_line_regions.fits",
04650               //                           CPL_IO_DEFAULT));
04651 
04652 
04653 
04654 
04655           // The following 2 may return an error so we do not check and
04656           // later we reset the error
04657               obj_line=sinfo_table_select_range(obj_lr,line_regions,wtol);
04658               sky_line=sinfo_table_select_range(sky_lr,line_regions,wtol);
04659               fline_i=cpl_table_get_nrow(line_regions);
04660 
04661               //sinfo_msg("fline_i=%d",fline_i);
04662               if(fline_i>=3) {
04663                 // repeat the determination of the line ratio
04664                 //sinfo_msg("second line ratio determination");
04665                 ck0_nomsg(sinfo_get_line_ratio(obj_line,obj_cont,
04666                                                 sky_line,sky_cont,method,&r));
04667 
04668         sinfo_msg("2nd Line ratio %g",r);
04669 
04670           } else {
04671                 cpl_error_reset();
04672           }
04673 
04674           sinfo_free_table(&sky_line);
04675           sinfo_free_table(&obj_line);
04676         }
04677 
04678             sinfo_msg("use %d pixels for line and %d for continuum estimation",
04679             cpl_table_get_nrow(line_regions),cpl_table_get_nrow(cont_regions));
04680 
04681         sinfo_msg("OH spectrum scaling = %f ",r);
04682             check_nomsg(cpl_array_set_double(rfit,i,r));
04683             ck0_nomsg(sinfo_table_set(&rscale0,wav_lr,r,wtol));
04684 
04685       } /* end if line_i */
04686         } /* end if xxx1_i */
04687      } /* end finite_pix_i */
04688 
04689     }
04690 
04691     sinfo_free_table(&xxx1);
04692     sinfo_free_table(&xxx2);
04693     sinfo_free_table(&sky_lr);
04694     sinfo_free_table(&obj_lr);
04695     sinfo_free_table(&wav_lr);
04696 
04697     sinfo_free_table(&line_regions);
04698     sinfo_free_table(&cont_regions);
04699 
04700   } /* end for loop on i */
04701 
04702   sinfo_free_array(&do_hk);
04703   sinfo_free_array(&rfit);
04704 
04705   //sinfo_msg("n scale=%d",cpl_table_get_nrow(rscale0));
04706   //check_nomsg(cpl_table_save(rscale0,NULL,NULL,
04707   //                                   "out_rscale0.fits",CPL_IO_DEFAULT));
04708 
04709   check_nomsg(cpl_table_select_all(rscale0));
04710  /* TODO: here one has to implementa an interpol function
04711   check_nomsg(range0_i=cpl_table_and_selected_double(rscale0,"RATIO",
04712                                                      CPL_NOT_EQUAL_TO,0));
04713  */
04714   check_nomsg(*rscale = cpl_table_extract_selected(rscale0));
04715   sinfo_free_table(&rscale0);
04716 
04717 
04718   check_nomsg(rat_sky=cpl_table_duplicate(*int_sky));
04719   check_nomsg(cpl_table_duplicate_column(rat_sky,"RATIO",*rscale,"RATIO"));
04720   check_nomsg(cpl_table_duplicate_column(*int_obj,"COR_FCT_VIB",
04721                      *rscale,"RATIO"));
04722   //check_nomsg(cpl_table_save(rat_sky,NULL,NULL,
04723   //                           "rat_sky0.fits",CPL_IO_DEFAULT));
04724   check_nomsg(cpl_table_multiply_columns(rat_sky,"INT","RATIO"));
04725 
04726 
04727   //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
04728   //                             "out_obj0.fits",CPL_IO_DEFAULT));
04729   //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
04730   //                             "out_sky0.fits",CPL_IO_DEFAULT));
04731 
04732   /*
04733   check_nomsg(cpl_table_duplicate_column(*int_obj,"INTC",*int_obj,"INT"));
04734   check_nomsg(cpl_table_duplicate_column(*int_obj,"SKYC",*int_sky,"INTC"));
04735   check_nomsg(cpl_table_subtract_columns(*int_obj,"INTC","SKYC"));
04736   */
04737 
04738   // do simple rotational correction
04739   if (do_rot == 1) {
04740 
04741     //finite_pix = where(finite(int_sky) && finite(int_obj),finite_pix_i);
04742     check_nomsg(min_lrange=cpl_table_get_column_min(lrange,"WAVE"));
04743     check_nomsg(max_lrange=cpl_table_get_column_max(lrange,"WAVE"));
04744     //sinfo_msg("min_lrange=%g max_lrange=%g",min_lrange,max_lrange);
04745     //check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(&rat_sky,
04746     //                                                      int_obj,
04747     //                                                      &lambda));
04748     check_nomsg(finite_pix_i=sinfo_table_sky_obj_flag_nan(int_sky,
04749                                                           int_obj,
04750                                                           &lambda));
04751 
04752 
04753     check_nomsg(finite_pix=cpl_table_duplicate(lambda));
04754     //TODO: lambda invalid values need to be reset to valid (?)
04755 
04756     check_nomsg(cpl_table_erase_invalid(finite_pix));
04757 
04758 
04759     if (finite_pix_i > npixw) {
04760 
04761       //finite_pix = finite_pix[where(finite_pix > min(lrange) &&
04762       //                              finite_pix < max(lrange))];
04763 
04764       check_nomsg(cpl_table_and_selected_double(finite_pix,"WAVE",
04765                                                 CPL_GREATER_THAN,
04766                                                 min_lrange));
04767 
04768       check_nomsg(cpl_table_and_selected_double(finite_pix,"WAVE",
04769                                                 CPL_LESS_THAN,
04770                                                 max_lrange));
04771 
04772 
04773 
04774       check_nomsg(tmp_tbl=cpl_table_extract_selected(finite_pix));
04775       sinfo_free_table(&finite_pix);
04776       check_nomsg(finite_pix=cpl_table_duplicate(tmp_tbl));
04777       sinfo_free_table(&tmp_tbl);
04778       sinfo_free_table(&sky_lr);
04779       sinfo_free_table(&obj_lr);
04780       sinfo_free_table(&wav_lr);
04781 
04782 
04783       cknull(sky_lr=sinfo_table_select_range(rat_sky,finite_pix,wtol),
04784          "extracting sky sub range");
04785       cknull(obj_lr=sinfo_table_select_range(*int_obj,finite_pix,wtol),
04786          "extracting obj sub range");
04787       cknull(wav_lr=sinfo_table_select_range(lambda,finite_pix,wtol),
04788          "extracting sky sub range");
04789 
04790 
04791       //check_nomsg(cpl_table_save(rat_sky,NULL,NULL,
04792       //                             "out_rat_sky.fits",CPL_IO_DEFAULT));
04793       //check_nomsg(cpl_table_save(finite_pix,NULL,NULL,
04794       //                             "out_finite_pix.fits",CPL_IO_DEFAULT));
04795       //check_nomsg(cpl_table_save(sky_lr,NULL,NULL,
04796       //                             "out_sky_lr.fits",CPL_IO_DEFAULT));
04797       //check_nomsg(cpl_table_save(obj_lr,NULL,NULL,
04798       //                             "out_obj_lr.fits",CPL_IO_DEFAULT));
04799       //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,
04800       //                             "out_wav_lr.fits",CPL_IO_DEFAULT));
04801 
04802       //The following may fail (sky_lr may be empty) so we do not check
04803       if(1 == cpl_table_has_valid(sky_lr,"INT")) {
04804     check_nomsg(sky_med=cpl_table_get_column_median(sky_lr,"INT"));
04805     check_nomsg(sky_sdv=cpl_table_get_column_stdev(sky_lr,"INT"));
04806     sky_thresh=sky_med+sky_sdv;
04807         //xxx1 = where(sky_lr > median(sky_lr)+stddev(sky_lr),xxx1_i);
04808         check_nomsg(xxx1_i=cpl_table_and_selected_double(sky_lr,"INT",
04809                            CPL_GREATER_THAN,sky_thresh));
04810         check_nomsg(xxx1=cpl_table_extract_selected(sky_lr));
04811         check_nomsg(cpl_table_select_all(sky_lr));
04812       } else {
04813         xxx1_i=0;
04814       }
04815       if (xxx1_i > 0) {
04816         sinfo_msg("xxx1_i=%d",xxx1_i);
04817 
04818         sinfo_msg("wav_lr wmin=%g wmax=%g",
04819           cpl_table_get_column_min(wav_lr,"WAVE"),
04820           cpl_table_get_column_max(wav_lr,"WAVE"));
04821 
04822         cknull_nomsg(llr_xxx1=sinfo_table_select_range(wav_lr,xxx1,wtol));
04823         //check_nomsg(cpl_table_save(wav_lr,NULL,NULL,
04824         //                             "out_llr_xxx1.fits",CPL_IO_DEFAULT));
04825 
04826         cknull(low_pos=sinfo_find_rot_waves(w_rot_low,npixw,wtol,llr_xxx1),
04827            "Determining low positions");
04828 
04829 
04830         check_nomsg(low_pos_i=cpl_table_get_nrow(low_pos));
04831         //check_nomsg(cpl_table_dump(low_pos,0,low_pos_i,stdout));
04832         cknull(med_pos=sinfo_find_rot_waves(w_rot_med,npixw,wtol,llr_xxx1),
04833                "Determining med positions");
04834         check_nomsg(med_pos_i=cpl_table_get_nrow(med_pos));
04835 
04836 
04837         //check_nomsg(cpl_table_dump(med_pos,0,med_pos_i,stdout));
04838 
04839         //TODO:
04840         //hipos = [0]
04841         //for i=0,n_elements(xxx1)-1 do begin
04842         //    x1 = where(lowpos eq i,x1_i)
04843         //    x2 = where(medpos eq i,x2_i)
04844         //    if (x1_i eq 0 and x2_i eq 0) then hipos = [hipos,i]
04845         //endfor
04846         //hipos = hipos[1:n_elements(hipos)-1]
04847         //TODO: hi_pos=sinfo_find_rot_waves(w_rot_hi,npixw,wtol,wav_lr);
04848 
04849 
04850         cknull(hi_pos=sinfo_table_extract_rest(xxx1,low_pos,med_pos,wtol),
04851            "determining hi position");
04852         check_nomsg(hi_pos_i=cpl_table_get_nrow(hi_pos));
04853         //check_nomsg(cpl_table_dump(hi_pos,0,hi_pos_i,stdout));
04854 
04855 
04856         //xxx2[xxx1] = 10.;
04857         check_nomsg(xxx2 = cpl_table_duplicate(sky_lr));
04858         check_nomsg(nrow=cpl_table_get_nrow(sky_lr));
04859         //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04860         //                             "out_xxx1.fits",CPL_IO_DEFAULT));
04861         //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04862         //                             "out_xxx2_0.fits",CPL_IO_DEFAULT));
04863 
04864         // AMO: Why the following?
04865         //check_nomsg(cpl_table_fill_column_window(xxx2,"INT",0,nrow,0));
04866 
04867         //xxx2 = convol(xxx2,replicate(1,npixw),/edge_truncate,/center);
04868         //cont_regions = where(xxx2 == 0,cont_i);
04869         ck0_nomsg(sinfo_table_threshold(&xxx2,"INT",sky_thresh,
04870                     sky_thresh,0.,10.));
04871         sinfo_msg("sky_thresh=%g %g %f",sky_thresh,sky_med,sky_sdv);
04872         //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04873         //                             "out_xxx2_1.fits",CPL_IO_DEFAULT));
04874         check_nomsg(sinfo_convolve_kernel(&xxx2,npixw/2));
04875 
04876         //check_nomsg(cpl_table_save(xxx2,NULL,NULL,
04877         //                             "out_xxx2_2.fits",CPL_IO_DEFAULT));
04878         check_nomsg(cont_i=cpl_table_and_selected_double(xxx2,"CNV",
04879                              CPL_EQUAL_TO,0));
04880         check_nomsg(cont_regions=cpl_table_extract_selected(xxx2));
04881 
04882         sinfo_free_table(&xxx2);
04883         check_nomsg(cpl_table_erase_column(cont_regions,"INT"));
04884         check_nomsg(cpl_table_erase_column(cont_regions,"CNV"));
04885 
04886         check(low_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,low_pos,wtol,
04887                          npixw,&low_regions),"failed determining low regions");
04888 
04889         check(med_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,med_pos,wtol,
04890                          npixw,&med_regions),"failed determining med regions");
04891 
04892 
04893         check(hi_pos_i=sinfo_get_sub_regions(sky_lr,xxx1,hi_pos,wtol,
04894                         npixw,&hi_regions),"failed determining hi regions");
04895     /*
04896         sinfo_msg("xxx1: wmin=%g wmax=%g",
04897                    cpl_table_get_column_min(xxx1,"WAVE"),
04898                    cpl_table_get_column_max(xxx1,"WAVE"));
04899 
04900         sinfo_msg("low_pos: wmin=%g wmax=%g",
04901                    cpl_table_get_column_min(low_pos,"WAVE"),
04902                    cpl_table_get_column_max(low_pos,"WAVE"));
04903     */
04904         sinfo_msg("hi_pos_i : %d med_pos_i : %d low_pos_i : %d cont_i: %d",
04905                    hi_pos_i,     med_pos_i,     low_pos_i,     cont_i);
04906 
04907 
04908         if (hi_pos_i >= 3 && med_pos_i >= 3 && low_pos_i >= 3 && cont_i >= 3) {
04909 
04910           //compute line ratio for hi_regions
04911           ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
04912                                              hi_regions,cont_regions,&rhi));
04913           sinfo_msg("high rotational OH scaling %g",rhi);
04914 
04915           //compute line ratio for med_regions
04916           ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
04917                                              med_regions,cont_regions,&rmed));
04918 
04919           sinfo_msg("P1(3.5) & R1(1.5) rotational OH scaling %g ",rmed);
04920 
04921           //compute line ratio for med_regions
04922           ck0_nomsg(sinfo_compute_line_ratio(obj_lr, sky_lr,wtol, method,
04923                                              low_regions,cont_regions,&rlow));
04924           sinfo_msg("P1(2.5) & Q1(1.5) rotational OH scaling %g",rlow);
04925 
04926           cknull(low_scale=sinfo_find_rot_waves(w_rot_low,npixw,wtol,lambda),
04927          "Determining low scale");
04928 
04929 
04930 
04931           cknull(med_scale=sinfo_find_rot_waves(w_rot_low,npixw,wtol,lambda),
04932          "Determining low scale");
04933           check_nomsg(cpl_table_multiply_scalar(*rscale,"RATIO",rhi));
04934           ck0_nomsg(sinfo_table_fill_column_over_range(rscale,med_scale,
04935                                                   "RATIO",rmed/rhi,wtol));
04936           ck0_nomsg(sinfo_table_fill_column_over_range(rscale,low_scale,
04937                                  "RATIO",rlow/rhi,wtol));
04938 
04939     }
04940       } //xxx1_i > 0
04941     }//finitepix > npixw
04942   }//do_rot==1
04943   //end of new rotational bit
04944   //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
04945   //                             "out_obj.fits",CPL_IO_DEFAULT));
04946   //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
04947   //                             "out_sky.fits",CPL_IO_DEFAULT));
04948 
04949 
04950   check_nomsg(cpl_table_duplicate_column(*int_sky,"INTC",*int_sky,"INT"));
04951   //sinfo_msg("n sky=%d",cpl_table_get_nrow(*int_sky));
04952   //sinfo_msg("n scale=%d",cpl_table_get_nrow(*rscale));
04953 
04954   check_nomsg(cpl_table_duplicate_column(*int_obj,"COR_FCT_ALL",
04955                                          *rscale,"RATIO"));
04956   check_nomsg(cpl_table_duplicate_column(*int_sky,"RATIO",*rscale,"RATIO"));
04957   check_nomsg(cpl_table_multiply_columns(*int_sky,"INTC","RATIO"));
04958 
04959   check_nomsg(cpl_table_duplicate_column(*int_obj,"INTC",*int_obj,"INT"));
04960   //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
04961   //                             "out_obj1.fits",CPL_IO_DEFAULT));
04962   //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
04963   //                             "out_sky1.fits",CPL_IO_DEFAULT));
04964 
04965   check_nomsg(cpl_table_duplicate_column(*int_obj,"SKYC",*int_sky,"INTC"));
04966   check_nomsg(cpl_table_subtract_columns(*int_obj,"INTC","SKYC"));
04967 
04968 
04969   check_nomsg(cpl_table_erase_column(*int_sky,"INT"));
04970   check_nomsg(cpl_table_name_column(*int_sky,"INTC","INT"));
04971 
04972 
04973 
04974  cleanup:
04975   sinfo_free_table(&llr_xxx1);
04976   sinfo_free_table(&hi_pos);
04977   sinfo_free_table(&low_pos);
04978   sinfo_free_table(&med_pos);
04979   sinfo_free_table(&low_regions);
04980   sinfo_free_table(&med_regions);
04981   sinfo_free_table(&hi_regions);
04982   sinfo_free_table(&low_scale);
04983   sinfo_free_table(&med_scale);
04984 
04985 
04986   sinfo_free_table(&finite_pix);
04987   sinfo_free_table(&xxx1_sub);
04988   sinfo_free_table(&tmp_tbl);
04989   sinfo_free_table(&rat_sky);
04990   sinfo_free_table(&fline_res);
04991   sinfo_free_table(&sky_cont);
04992   sinfo_free_table(&obj_cont);
04993   sinfo_free_table(&obj_line);
04994   sinfo_free_table(&sky_line);
04995   sinfo_free_table(&rscale0);
04996   sinfo_free_table(&xxx1);
04997   sinfo_free_table(&xxx2);
04998   sinfo_free_table(&line_regions);
04999   sinfo_free_table(&cont_regions);
05000   sinfo_free_table(&sky_lr);
05001   sinfo_free_table(&obj_lr);
05002   sinfo_free_table(&wav_lr);
05003   sinfo_free_array(&rfit);
05004   sinfo_free_array(&do_hk);
05005   return;
05006 
05007 }
05016 int
05017 sinfo_table_get_index_of_max(cpl_table* t,const char* name,cpl_type type)
05018 {
05019 
05020   int i=0;
05021   int result=0;
05022   int nrow=0;
05023   int* pi=NULL;
05024   float* pf=NULL;
05025   double* pd=NULL;
05026   double max=0;
05027 
05028 
05029   if(t == NULL) {
05030    cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
05031    return result;
05032   }
05033   max=cpl_table_get_column_max(t,name);
05034   nrow=cpl_table_get_nrow(t);
05035   switch(type) {
05036 
05037   case CPL_TYPE_INT:
05038     pi=cpl_table_get_data_int(t,name);
05039     for(i=0;i<nrow;i++) {
05040       if(pi[i]==(int)max) result=i;
05041     }
05042     break;
05043   case CPL_TYPE_FLOAT:
05044     pf=cpl_table_get_data_float(t,name);
05045     for(i=0;i<nrow;i++) {
05046       if(pf[i]==(float)max) result=i;
05047     }
05048     break;
05049   case CPL_TYPE_DOUBLE:
05050     pd=cpl_table_get_data_double(t,name);
05051     for(i=0;i<nrow;i++) {
05052       if(pd[i]==max) result=i;
05053     }
05054     break;
05055   default:
05056     sinfo_msg_error("Wrong column type");
05057    cpl_error_set(cpl_func, CPL_ERROR_TYPE_MISMATCH);
05058    return result;
05059 
05060   }
05061   return result;
05062 }
05063 
05064 
05065 
05075 int
05076 sinfo_table_get_index_of_val(cpl_table* t,
05077                              const char* name,
05078                              double val,
05079                              cpl_type type)
05080 {
05081 
05082   int i=0;
05083   int result=0;
05084   int nrow=0;
05085   int* pi=NULL;
05086   float* pf=NULL;
05087   double* pd=NULL;
05088 
05089   if(t == NULL) {
05090    cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
05091    return result;
05092   }
05093 
05094   nrow=cpl_table_get_nrow(t);
05095   switch(type) {
05096 
05097   case CPL_TYPE_INT:
05098     pi=cpl_table_get_data_int(t,name);
05099     for(i=0;i<nrow;i++) {
05100       if(pi[i]==(int)val) result=i;
05101     }
05102     break;
05103   case CPL_TYPE_FLOAT:
05104     pf=cpl_table_get_data_float(t,name);
05105     for(i=0;i<nrow;i++) {
05106       if(pf[i]==(float)val) result=i;
05107     }
05108     break;
05109   case CPL_TYPE_DOUBLE:
05110     pd=cpl_table_get_data_double(t,name);
05111     for(i=0;i<nrow;i++) {
05112       if(pd[i]==val) result=i;
05113     }
05114     break;
05115   default:
05116     sinfo_msg_error("Wrong column type");
05117    cpl_error_set(cpl_func, CPL_ERROR_TYPE_MISMATCH);
05118    return result;
05119 
05120   }
05121   return result;
05122 }
05123 
05136 double
05137 sinfo_table_column_interpolate(const cpl_table* t,
05138                                const char* name,
05139                                const double x)
05140 {
05141 
05142   double val1=0;
05143   double val2=0;
05144   int x1=0;
05145   int x2=0;
05146   double m=0;
05147   double y=0;
05148   int status=0;
05149   int nrow=0;
05150   nrow=cpl_table_get_nrow(t);
05151   if ((1<x) && (x<nrow-1)) {
05152     x1=x-1;
05153     x2=x+1;
05154   } else if (x<2) {
05155     x1=0;
05156     x2=1;
05157   } else {
05158     x1=nrow-2;
05159     x2=nrow-1;
05160   }
05161   check_nomsg(val1=cpl_table_get(t,name,x1,&status));
05162   check_nomsg(val2=cpl_table_get(t,name,x2,&status));
05163 
05164   m=(val2-val1)/(x2-x1);
05165   y=val1+m*(x-x1);
05166 
05167   return y;
05168 
05169  cleanup:
05170 
05171   return -1;
05172 
05173 
05174 }
05175 
05184 static cpl_imagelist*
05185 sinfo_imagelist_select_range(const cpl_imagelist* inp,
05186                                   const cpl_table* full,
05187                                   const cpl_table* good,
05188                                   const double tol)
05189 {
05190   cpl_imagelist* out=NULL;
05191   int osz=0;
05192   int isz=0;
05193   int ksz=0;
05194   int k=0;
05195   int i=0;
05196   int status=0;
05197 
05198   double wave_chk=0;
05199   double wave_sel=0;
05200 
05201   const cpl_image* img=NULL;
05202 
05203 
05204   /* Get Object relevant information */
05205   /* here one should scan the inp image constructing a wave range from it
05206      and not from another table */
05207   check_nomsg(osz=cpl_table_get_nrow(good));
05208   check_nomsg(ksz=cpl_imagelist_get_size(inp));
05209   check_nomsg(isz=cpl_table_get_nrow(good));
05210   check_nomsg(out=cpl_imagelist_new());
05211 
05212 
05213   for(k=0;k<ksz;k++) {
05214     check_nomsg(img=cpl_imagelist_get_const(inp,k));
05215     check_nomsg(wave_chk=cpl_table_get(full,"WAVE",k,&status));
05216     if(i<isz) {
05217       check_nomsg(wave_sel=cpl_table_get(good,"WAVE",i,&status));
05218     }
05219     // insert cubes with wavelengths with appropriate values only
05220     if(fabs(wave_chk - wave_sel) < tol) {
05221       check_nomsg(cpl_imagelist_set(out,cpl_image_duplicate(img),i));
05222       i++;
05223     }
05224   }
05225   if(i==0) {
05226     sinfo_msg_error("No lines selected");
05227     goto cleanup;
05228   }
05229   return out;
05230 
05231  cleanup:
05232 
05233   return NULL;
05234 
05235 }
05236 
05246 static int
05247 sinfo_table_extract_finite(const cpl_table* in1,
05248                            const cpl_table* in2,
05249                                  cpl_table** ou1,
05250                                  cpl_table** ou2)
05251 {
05252 
05253   int size1=0;
05254   int size2=0;
05255   int i=0;
05256   int ninv1=0;
05257   int ninv2=0;
05258   double* pout1=NULL;
05259   double* pout2=NULL;
05260 
05261   cknull(in1,"null input image");
05262   cknull(in2,"null input image");
05263   cknull_nomsg(*ou1=cpl_table_duplicate(in1));
05264   cknull_nomsg(*ou2=cpl_table_duplicate(in2));
05265 
05266   check_nomsg(size1=cpl_table_get_nrow(*ou1));
05267   check_nomsg(size2=cpl_table_get_nrow(*ou2));
05268 
05269   check_nomsg(pout1=cpl_table_get_data_double(*ou1,"VALUE"));
05270   check_nomsg(pout2=cpl_table_get_data_double(*ou2,"VALUE"));
05271   for(i=0;i<size1;i++) {
05272     if (irplib_isnan(pout1[i])) {
05273       check_nomsg(cpl_table_set_invalid(*ou1,"VALUE",i));
05274       check_nomsg(cpl_table_set_invalid(*ou2,"VALUE",i));
05275     }
05276   }
05277   ninv1=cpl_table_count_invalid(*ou1,"VALUE");
05278   ninv2=cpl_table_count_invalid(*ou2,"VALUE");
05279   if(ninv1==size1) {
05280     goto cleanup;
05281   }
05282   if(ninv2==size2) {
05283     goto cleanup;
05284   }
05285   check_nomsg(cpl_table_erase_invalid(*ou1));
05286   check_nomsg(cpl_table_erase_invalid(*ou2));
05287   return (size1-ninv1);
05288 
05289  cleanup:
05290   return 0;
05291 
05292 }
05293 
05300 static cpl_table*
05301 sinfo_image2table(const cpl_image* im)
05302 {
05303   cpl_table* out=NULL;
05304   int sx=0;
05305   int sy=0;
05306   const double* pim=NULL;
05307   double* pval=NULL;
05308   int i=0;
05309   int j=0;
05310   int k=0;
05311 
05312   cknull(im,"input image is NULL");
05313 
05314   check_nomsg(sx=cpl_image_get_size_x(im));
05315   check_nomsg(sy=cpl_image_get_size_y(im));
05316   check_nomsg(pim=cpl_image_get_data_double_const(im));
05317   check_nomsg(out=cpl_table_new(sx*sy));
05318   check_nomsg(cpl_table_new_column(out,"VALUE",CPL_TYPE_DOUBLE));
05319   check_nomsg(pval=cpl_table_get_data_double(out,"VALUE"));
05320 
05321   for(j=0;j<sy;j++) {
05322     for(i=0;i<sx;i++) {
05323       /*
05324       pval[k++]=pim[j*sx+i];
05325       sinfo_msg("set tab %f",pim[j*sx+i]);
05326       */
05327       cpl_table_set_double(out,"VALUE",k++,pim[j*sx+i]);
05328     }
05329   }
05330 
05331   return out;
05332  cleanup:
05333   sinfo_free_table(&out);
05334   return NULL;
05335 
05336 }
05345 int
05346 sinfo_check_screw_values(cpl_table** int_obj,
05347                          cpl_table** int_sky,
05348                          cpl_table* grange,
05349                          const double wtol)
05350 {
05351   // check for screwy values at ends of spectrum
05352   cpl_table* xsky=NULL;
05353   cpl_table* xobj=NULL;
05354 
05355   double sky_min=0;
05356   double sky_max=0;
05357   double gsky_min=0;
05358   double gsky_max=0;
05359   double obj_min=0;
05360   double obj_max=0;
05361   double gobj_min=0;
05362   double gobj_max=0;
05363 
05364   cknull(*int_sky,"Null input sky spectrum");
05365   cknull(*int_obj,"Null input obj spectrum");
05366   cknull(grange,"Null input wavelength range");
05367   //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
05368   //                             "out_grange0.fits",CPL_IO_DEFAULT));
05369   cknull_nomsg(xsky=sinfo_table_select_range(*int_sky,grange,wtol));
05370   //check_nomsg(cpl_table_save(xsky,NULL,NULL,
05371   //                             "out_grange1.fits",CPL_IO_DEFAULT));
05372   check_nomsg(sky_min=cpl_table_get_column_min(xsky,"INT"));
05373   check_nomsg(sky_max=cpl_table_get_column_max(xsky,"INT"));
05374   //sinfo_msg("gskymax=%f gskymin=%f",sky_max,sky_min);
05375 
05376   gsky_max = (sky_max>0) ? sky_max : 0;
05377   gsky_min = (sky_min<0) ? sky_min : 0;
05378   //gsky_pos = where(int_sky > 1.*gsky_max || int_sky < 1.*gsky_min,gskypos_i);
05379   check_nomsg(cpl_table_select_all(*int_sky));
05380   ck0_nomsg(sinfo_table_set_nan_out_min_max(int_sky,"INT",gsky_min,gsky_max));
05381   //check_nomsg(cpl_table_save(*int_sky,NULL,NULL,
05382   //                             "out_gsky_pos.fits",CPL_IO_DEFAULT));
05383 
05384   sinfo_free_table(&xsky);
05385   //sinfo_msg("gsky_min=%f gsky_max=%f",gsky_min,gsky_max);
05386 
05387   cknull_nomsg(xobj=sinfo_table_select_range(*int_obj,grange,wtol));
05388   check_nomsg(obj_min=cpl_table_get_column_min(xobj,"INT"));
05389   check_nomsg(obj_max=cpl_table_get_column_max(xobj,"INT"));
05390   //check_nomsg(cpl_table_save(xobj,NULL,NULL,"out_xobj.fits",CPL_IO_DEFAULT));
05391   gobj_max = (obj_max>0) ? obj_max : 0;
05392   gobj_min = (obj_min<0) ? obj_min : 0;
05393   //gobj_pos=where(int_obj > 1.*gobj_max || int_obj < 1.*gobj_min,gobj_pos_i);
05394   check_nomsg(cpl_table_select_all(*int_obj));
05395   ck0_nomsg(sinfo_table_set_nan_out_min_max(int_obj,"INT",gobj_min,gobj_max));
05396   //check_nomsg(cpl_table_save(*int_obj,NULL,NULL,
05397   //              "out_gobj_pos.fits",CPL_IO_DEFAULT));
05398   //sinfo_msg("gobj_min=%f gobj_max=%f",gobj_min,gobj_max);
05399   sinfo_free_table(&xobj);
05400 
05401   return 0;
05402  cleanup:
05403   sinfo_free_table(&xsky);
05404   sinfo_free_table(&xobj);
05405 
05406   return -1;
05407 
05408 
05409 }
05410 
05411 
05412 
05422 static int
05423 sinfo_table_fill_column_over_range(cpl_table** inp,
05424                                    const cpl_table* ref,
05425                                    const char* col,
05426                                    const double val,
05427                                    const double tol)
05428 {
05429 
05430   int i=0;
05431   int k=0;
05432   int nref=0;
05433   int ninp=0;
05434 
05435   double* pwin=NULL;
05436   double* pcin=NULL;
05437   const double* pwrf=NULL;
05438 
05439   cknull(inp,"null input table");
05440   cknull(ref,"null reference table");
05441 
05442   check_nomsg(ninp=cpl_table_get_nrow(*inp));
05443   check_nomsg(nref=cpl_table_get_nrow(ref));
05444   check_nomsg(pwin=cpl_table_get_data_double(*inp,"WAVE"));
05445   check_nomsg(pcin=cpl_table_get_data_double(*inp,col));
05446   check_nomsg(pwrf=cpl_table_get_data_double_const(ref,"WAVE"));
05447 
05448   k=0;
05449   i=0;
05450   /*
05451   sinfo_msg("ninp=%d nref=%d",ninp,nref);
05452   sinfo_msg("winp(0)=%f wref(0)=%f tol=%f diff=%f",
05453             pwin[0],pwrf[0],tol,fabs(pwin[0]-pwrf[0]));
05454   */
05455   if(pwin[0]<=pwrf[0]) {
05456     //sinfo_msg("case 1");
05457     for(i=0;i<ninp;i++) {
05458       if(k<nref) {
05459     /*
05460         sinfo_msg("case1: %f %f %f %f %d %d",
05461                   fabs(pwin[i] - pwrf[k]),tol,pwin[i],pwrf[k],i,k);
05462     */
05463     if(fabs(pwin[i] - pwrf[k])< tol) {
05464       pcin[i]=val;
05465       k++;
05466     }
05467       }
05468     }
05469   } else {
05470 
05471     //pwin[0]>pwrf[0]
05472     //sinfo_msg("case 2");
05473     for(k=0;k<nref;k++) {
05474       if(i<ninp) {
05475     /*
05476         sinfo_msg("case2: %f %f %f %f %d %d",
05477                   fabs(pwin[i] - pwrf[k]),tol,pwin[i],pwrf[k],i,k);
05478     */
05479     if(fabs(pwin[i] - pwrf[k])< tol) {
05480       pcin[i]=val;
05481       i++;
05482     }
05483       }
05484     }
05485   }
05486 
05487   return 0;
05488 
05489  cleanup:
05490   return -1;
05491 
05492 }
05493 
05494 
05503 static cpl_table*
05504 sinfo_table_select_range(cpl_table* inp, cpl_table* ref,const double tol)
05505 {
05506 
05507   cpl_table* out=NULL;
05508   int ninp=0;
05509   int nref=0;
05510   int nout=0;
05511 
05512   int i=0;
05513   int k=0;
05514   double* pou;
05515   double* prf;
05516   double wmin=0;
05517   double wmax=0;
05518   cpl_table* tmp=NULL;
05519   cknull(inp,"null input table");
05520   cknull(ref,"null reference table");
05521 
05522   check_nomsg(ninp=cpl_table_get_nrow(inp));
05523   check_nomsg(nref=cpl_table_get_nrow(ref));
05524   if(ninp != nref) {
05525     //sinfo_msg_warning("ninp != nref");
05526     check_nomsg(wmin=cpl_table_get_column_min(ref,"WAVE"));
05527     check_nomsg(wmax=cpl_table_get_column_max(ref,"WAVE"));
05528     //sinfo_msg_debug("wmin=%f wmax=%f",wmin,wmax);
05529     cpl_table_select_all(inp);
05530     check_nomsg(ninp=cpl_table_and_selected_double(inp,"WAVE",
05531                                                    CPL_NOT_LESS_THAN,wmin));
05532     check_nomsg(tmp=cpl_table_extract_selected(inp));
05533     check_nomsg(ninp=cpl_table_and_selected_double(tmp,"WAVE",
05534                                                    CPL_NOT_GREATER_THAN,wmax));
05535     check_nomsg(out=cpl_table_extract_selected(tmp));
05536     sinfo_free_table(&tmp);
05537   } else {
05538     check_nomsg(out=cpl_table_duplicate(inp));
05539   }
05540 
05541   check_nomsg(nout=cpl_table_get_nrow(out));
05542   if(nout == 0) {
05543     //sinfo_msg("nout=%d",nout);
05544     goto cleanup;
05545   }
05546   tmp=cpl_table_duplicate(out);
05547   sinfo_free_table(&out);
05548   check_nomsg(pou=cpl_table_get_data_double(tmp,"WAVE"));
05549   check_nomsg(prf=cpl_table_get_data_double(ref,"WAVE"));
05550 
05551   check_nomsg(cpl_table_new_column(tmp,"FLAG",CPL_TYPE_INT));
05552   check_nomsg(cpl_table_fill_column_window(tmp,"FLAG",0,nout,-1));
05553 
05554   k=0;
05555   i=0;
05556 
05557   //sinfo_msg_debug("nout=%d nref=%d",nout,nref);
05558   //sinfo_msg_debug("wout(0)=%f wref(0)=%f tol=%f diff=%f",
05559   //          pou[0],prf[0],tol,fabs(pou[0]-prf[0]));
05560 
05561   if(pou[0]<=prf[0]) {
05562     //sinfo_msg_debug("case 1");
05563     for(i=0;i<nout;i++) {
05564       if(k<nref) {
05565     if(fabs(pou[i] - prf[k])< tol) {
05566       check_nomsg(cpl_table_set_int(tmp,"FLAG",i,1));
05567       k++;
05568     }
05569       }
05570     }
05571   } else {
05572 
05573     //pou[0]>prf[0]
05574     //sinfo_msg_debug("case 2");
05575     for(k=0;k<nref;k++) {
05576       if(i<nout) {
05577     /*
05578         sinfo_msg("check: %f %f %f %f",
05579                   fabs(pou[i] - prf[k]),tol,pou[i],prf[k]);
05580     */
05581     if(fabs(pou[i] - prf[k])< tol) {
05582       check_nomsg(cpl_table_set_int(tmp,"FLAG",i,1));
05583       i++;
05584     }
05585       }
05586     }
05587   }
05588   //check_nomsg(cpl_table_save(tmp,NULL,NULL,"out_pre0.fits",CPL_IO_DEFAULT));
05589   check_nomsg(nout=cpl_table_and_selected_int(tmp,"FLAG",CPL_GREATER_THAN,0));
05590   check_nomsg(out=cpl_table_extract_selected(tmp));
05591   sinfo_free_table(&tmp);
05592   check_nomsg(cpl_table_erase_column(out,"FLAG"));
05593   if(nout==0) {
05594     goto cleanup;
05595   }
05596   //check_nomsg(cpl_table_save(out,NULL,NULL,"out_post0.fits",CPL_IO_DEFAULT));
05597   /* sinfo_msg("nout=%d",nout); */
05598   return out;
05599 
05600  cleanup:
05601   sinfo_free_table(&tmp);
05602   sinfo_free_table(&out);
05603   return NULL;
05604 
05605 }
05606 
05616 cpl_table*
05617 sinfo_interpolate_sky(const cpl_table* inp,const cpl_table* lambdas)
05618 {
05619   //interpolate sky if necessary
05620   cpl_table* new=NULL;
05621   new = sinfo_interpolate(inp,lambdas,"WAVE","lsquadratic");;
05622 
05623   return new;
05624 }
05625 
05626 
05636 static cpl_table*
05637 sinfo_interpolate(const cpl_table* inp,
05638                   const cpl_table* lambdas,
05639                   const char* name,
05640                   const char* method)
05641 {
05642   //TODO
05643   cpl_table* out=NULL;
05644 
05645   //To remove compilation warnings
05646   cknull_nomsg(lambdas);
05647   cknull_nomsg(name);
05648   cknull_nomsg(method);
05649 
05650   out=cpl_table_duplicate(inp);
05651   return out;
05652 
05653  cleanup:
05654 
05655   return NULL;
05656 
05657 }
05658 
05659 
05660 
05673 static double
05674 sinfo_gaussian_amp(double area,double sigma,double x,double x0,double off)
05675 {
05676   return area/sqrt(2*PI_NUMB*sigma*sigma)*
05677          exp(-(x-x0)*(x-x0)/(2*sigma*sigma))+off;
05678 }
05679 
05680 
05693 static double
05694 sinfo_gaussian_area(double amp,double sigma,double x,double x0,double off)
05695 {
05696   return sqrt(2*PI_NUMB*sigma*sigma)*exp((x-x0)*(x-x0)/(2*sigma*sigma))*
05697          (amp-off);
05698 }
05699 
05700 
05707 int
05708 sinfo_table_smooth_column(cpl_table** t, const char* c, const int r)
05709 {
05710   int nrow=0;
05711   int i=0;
05712   int j=0;
05713   double* pval=NULL;
05714   double sum;
05715   check_nomsg(nrow=cpl_table_get_nrow(*t));
05716   check_nomsg(pval=cpl_table_get_data_double(*t,c));
05717   for(i=r;i<nrow;i++) {
05718     sum=0;
05719     for(j=-r;j<=r;j++) {
05720       sum+=pval[i+j];
05721     }
05722     pval[i]=sum/(2*r+1);
05723   }
05724   return 0;
05725  cleanup:
05726   return -1;
05727 }
05728 
05737 void
05738 sinfo_shift_sky(cpl_frame** sky_frm,
05739                 cpl_table** int_sky,
05740                 const double zshift)
05741 {
05742 
05743   int xsz=0;
05744   int ysz=0;
05745   int zsz=0;
05746   cpl_propertylist* plist=NULL;
05747   cpl_imagelist* sky_cub=NULL;
05748   cpl_imagelist* sky_shift=NULL;
05749   cpl_table* int_sky_dup=NULL;
05750 
05751   double min=0;
05752   double max=0;
05753 
05754  /* Get Object relevant information */
05755   cknull_nomsg(plist=cpl_propertylist_load(
05756                      cpl_frame_get_filename(*sky_frm),0));
05757 
05758   check_nomsg(xsz=sinfo_pfits_get_naxis1(plist));
05759   check_nomsg(ysz=sinfo_pfits_get_naxis2(plist));
05760   check_nomsg(zsz=sinfo_pfits_get_naxis3(plist));
05761   sinfo_free_propertylist(&plist);
05762 
05763   cknull_nomsg(sky_cub=cpl_imagelist_load(cpl_frame_get_filename(*sky_frm),
05764                                             CPL_TYPE_FLOAT,0));
05765 
05766   check_nomsg(min=cpl_table_get_column_min(*int_sky,"INT"));
05767   check_nomsg(max=cpl_table_get_column_max(*int_sky,"INT"));
05768   int_sky_dup=cpl_table_duplicate(*int_sky);
05769   sinfo_free_table(&(*int_sky));
05770   /*
05771   cknull_nomsg(*int_sky=sinfo_table_shift_column_int(int_sky_dup,
05772                                                      "INT", zshift,&zrest));
05773   check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
05774                              "out_sky_shift1.fits", CPL_IO_DEFAULT));
05775   sinfo_free_table(&(*int_sky));
05776 
05777   sinfo_msg("min=%f max=%f",min,max);
05778   check_nomsg(cpl_table_save(int_sky_dup, NULL, NULL,
05779                              "out_sky_pre2.fits", CPL_IO_DEFAULT));
05780   cknull_nomsg(*int_sky=sinfo_table_shift_column_poly(int_sky_dup,
05781                                                       "INT", zshift,2));
05782   check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
05783                              "out_sky_shift2.fits", CPL_IO_DEFAULT));
05784   */
05785   //check_nomsg(cpl_table_save(int_sky_dup, NULL, NULL,
05786   //                             "out_sky_pre2.fits", CPL_IO_DEFAULT));
05787   check_nomsg(*int_sky=sinfo_table_shift_simple(int_sky_dup,"INT",zshift));
05788   /*
05789   sinfo_free_table(&(*int_sky));
05790   cknull_nomsg(*int_sky=sinfo_table_shift_column_spline3(int_sky_dup,
05791                                                          "INT", zshift));
05792   check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
05793                              "out_sky_shift3.fits", CPL_IO_DEFAULT));
05794   */
05795   sinfo_free_table(&int_sky_dup);
05796   /*
05797   check_nomsg(cpl_table_select_all(*int_sky));
05798   check_nomsg(n=cpl_table_and_selected_double(*int_sky,"INT",
05799                                               CPL_LESS_THAN,min));
05800   ck0_nomsg(sinfo_table_set_column_invalid(int_sky,"INT"));
05801   sinfo_msg("n=%d",n);
05802   check_nomsg(cpl_table_select_all(*int_sky));
05803   check_nomsg(n=cpl_table_and_selected_double(*int_sky,"INT",
05804                 CPL_GREATER_THAN,max));
05805   sinfo_msg("n=%d",n);
05806   ck0_nomsg(sinfo_table_set_column_invalid(int_sky,"INT"));
05807   check_nomsg(cpl_table_select_all(*int_sky));
05808   */
05809   //check_nomsg(cpl_table_save(*int_sky, NULL, NULL,
05810   //                           "out_sky_shift3.fits", CPL_IO_DEFAULT));
05811 
05812 
05813 
05814   check_nomsg(sky_shift=sinfo_cube_zshift_simple(sky_cub,(float)zshift));
05815 
05816   //check_nomsg(sky_shift=sinfo_cube_zshift(sky_cub,zshift,&zrest));
05817   //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky1.fits",
05818   //                 CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
05819 
05820   sinfo_free_imagelist(&sky_shift);
05821   //sinfo_free_imagelist(&sky_shift);
05822   //sinfo_msg("zrest=%f",zrest);
05823 
05824   //check_nomsg(sky_shift=sinfo_cube_zshift_poly(sky_cub,zshift,2));
05825   //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky2.fits",
05826   //                               CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
05827   //sinfo_free_imagelist(&sky_shift);
05828 
05829   //check_nomsg(sky_shift=sinfo_cube_zshift_spline3(sky_cub,zshift));
05830   //check_nomsg(cpl_imagelist_save(sky_shift,"out_sky3.fits",
05831   //                               CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
05832   //sinfo_free_imagelist(&sky_shift);
05833   sinfo_free_imagelist(&sky_cub);
05834 
05835   return;
05836 
05837  cleanup:
05838   sinfo_free_table(&int_sky_dup);
05839   sinfo_free_propertylist(&plist);
05840   sinfo_free_imagelist(&sky_shift);
05841   sinfo_free_imagelist(&sky_cub);
05842   return;
05843 }
05844 
05845 
05852 static int
05853 sinfo_convolve_kernel(cpl_table** t, const int rad)
05854 {
05855   int i=0;
05856   int j=0;
05857   int np=0;
05858   double val=0;
05859   double* pidata=NULL;
05860   double* pcdata=NULL;
05861   double dw=0;
05862   double dr=0;
05863   double ws=0;
05864   double we=0;
05865   cknull(*t,"null input table");
05866   check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
05867   check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
05868   check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
05869   check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
05870   check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
05871   check_nomsg(np=cpl_table_get_nrow(*t));
05872   dw=(we-ws)/(np-1);
05873   dr=(we-ws)/(rad-1);
05874   /* set to 0 edges */
05875   for(i=0;i<rad;i++) {
05876     pcdata[i]=0.;
05877   }
05878   for(i=np-rad;i<np;i++) {
05879     pcdata[i]=0.;
05880   }
05881   for(i=rad;i<np-rad;i++) {
05882     val=0;
05883     for(j=-rad;j<rad;j++) {
05884       val+=pidata[i+j];
05885     }
05886     /*val*=dw; */
05887     check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
05888   }
05889   return 0;
05890 
05891  cleanup:
05892   return -1;
05893 
05894 }
05895 
05896 
05897 
05905 int
05906 sinfo_convolve_kernel2(cpl_table** t, const int rad)
05907 {
05908   int i=0;
05909   int j=0;
05910   int np=0;
05911   double val=0;
05912   double* pidata=NULL;
05913   double* pcdata=NULL;
05914   double dw=0;
05915   double dr=0;
05916   double ws=0;
05917   double we=0;
05918   cknull(*t,"null input table");
05919   check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
05920   check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
05921   check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
05922   check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
05923   check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
05924   check_nomsg(np=cpl_table_get_nrow(*t));
05925   dw=(we-ws)/(np-1);
05926   dr=(we-ws)/(rad-1);
05927   /* set to 0 edges */
05928   for(i=0;i<rad;i++) {
05929     pcdata[i]=0.;
05930   }
05931   for(i=np-rad;i<np;i++) {
05932     pcdata[i]=0.;
05933   }
05934   for(i=0;i<np-rad;i++) {
05935     val=0;
05936     for(j=0;j<rad;j++) {
05937       val+=pidata[i+j];
05938     }
05939     /*val*=dw; */
05940     check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
05941   }
05942   return 0;
05943 
05944  cleanup:
05945   return -1;
05946 
05947 }
05948 
05949 
05950 
05958 int
05959 sinfo_convolve_exp(cpl_table** t, const int rad, const double fwhm)
05960 {
05961   int i=0;
05962   int j=0;
05963   int np=0;
05964   double ln2=0.693147180560;
05965   double k=ln2/fwhm;
05966   double val=0;
05967   double* pidata=NULL;
05968   double* pcdata=NULL;
05969   double dw=0;
05970   double dr=0;
05971   double ws=0;
05972   double we=0;
05973   cknull(*t,"null input table");
05974   check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
05975   check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
05976   check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
05977   check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
05978   check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
05979   check_nomsg(np=cpl_table_get_nrow(*t));
05980   dw=(we-ws)/(np-1);
05981   dr=(we-ws)/(rad-1);
05982   /* set to 0 edges */
05983   for(i=0;i<rad;i++) {
05984     pcdata[i]=0.;
05985   }
05986   for(i=np-rad;i<np;i++) {
05987     pcdata[i]=0.;
05988   }
05989   for(i=rad;i<np-rad;i++) {
05990     val=0;
05991     for(j=-rad;j<rad;j++) {
05992       val+=pidata[i+j]*k*pow(2.0,-2.0*fabs(i-rad)/fwhm);
05993     }
05994     /*val*=dw; */
05995     check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
05996   }
05997   return 0;
05998 
05999  cleanup:
06000   return -1;
06001 
06002 }
06003 
06004 
06013 int
06014 sinfo_convolve_gauss(cpl_table** t, const int rad, const double fwhm)
06015 {
06016   int i=0;
06017   int j=0;
06018   int np=0;
06019   double val=0;
06020   double sigma=fwhm/2.3548;
06021   double sigma2=sigma*sigma;
06022   double* pidata=NULL;
06023   double* pcdata=NULL;
06024   double dw=0;
06025   double dr=0;
06026   double ws=0;
06027   double we=0;
06028   double tx=0;
06029 
06030   cknull(*t,"null input table");
06031   check_nomsg(cpl_table_new_column(*t,"CNV",CPL_TYPE_DOUBLE));
06032   check_nomsg(pidata=cpl_table_get_data_double(*t,"INT"));
06033   check_nomsg(pcdata=cpl_table_get_data_double(*t,"CNV"));
06034   check_nomsg(ws=cpl_table_get_column_min(*t,"WAVE"));
06035   check_nomsg(we=cpl_table_get_column_max(*t,"WAVE"));
06036   check_nomsg(np=cpl_table_get_nrow(*t));
06037   dw=(we-ws)/(np-1);
06038   dr=(we-ws)/(rad-1);
06039   /* set to 0 edges */
06040   for(i=0;i<rad;i++) {
06041     pcdata[i]=0.;
06042   }
06043   for(i=np-rad;i<np;i++) {
06044     pcdata[i]=0.;
06045   }
06046   for(i=rad;i<np-rad;i++) {
06047     val=0;
06048     for(j=-rad;j<rad;j++) {
06049       tx=i-rad;
06050       val+=pidata[i+j]*exp(-tx*tx/2.0/sigma2)/(sigma*sqrt(2.0*PI_NUMB));
06051     }
06052     /*val*=dw; */
06053     check_nomsg(cpl_table_set_double(*t,"CNV",i,val));
06054   }
06055   return 0;
06056 
06057  cleanup:
06058   return -1;
06059 
06060 }
06061 
06062 
06063 
06075 static int
06076 sinfo_scales_obj_sky_cubes(cpl_imagelist* obj_cub,
06077                             cpl_imagelist* sky_cub,
06078                             cpl_table* bkg,
06079                             cpl_table* rscale,
06080                             cpl_imagelist** obj_cor)
06081 {
06082 
06083 
06084   int i=0;
06085   int j=0;
06086   int k=0;
06087   int xsz=0;
06088   int ysz=0;
06089   int zsz=0;
06090 
06091   double* podata=NULL;
06092   double* psdata=NULL;
06093   double* pbdata=NULL;
06094   double* pcdata=NULL;
06095   double* pscale=NULL;
06096 
06097 
06098   cpl_image* imgo=NULL;
06099   cpl_image* imgs=NULL;
06100   cpl_image* imgc=NULL;
06101 
06102 
06103   check_nomsg(imgo=cpl_imagelist_get(obj_cub,0));
06104   check_nomsg(xsz=cpl_image_get_size_x(imgo));
06105   check_nomsg(ysz=cpl_image_get_size_y(imgo));
06106   check_nomsg(zsz=cpl_imagelist_get_size(obj_cub));
06107 
06108   check_nomsg(*obj_cor=cpl_imagelist_duplicate(obj_cub));
06109 
06110   for(k=0;k<zsz;k++) {
06111     check_nomsg(imgo=cpl_imagelist_get(obj_cub,k));
06112     check_nomsg(imgc=cpl_imagelist_get(*obj_cor,k));
06113     check_nomsg(imgs=cpl_imagelist_get(sky_cub,k));
06114 
06115     check_nomsg(podata=cpl_image_get_data_double(imgo));
06116     check_nomsg(pcdata=cpl_image_get_data_double(imgc));
06117     check_nomsg(psdata=cpl_image_get_data_double(imgs));
06118     check_nomsg(pbdata=cpl_table_get_data_double(bkg,"INT2"));
06119     check_nomsg(pscale=cpl_table_get_data_double(rscale,"RATIO"));
06120 
06121     for (j=0;j<ysz; j++) {
06122       for (i=0;i<xsz; i++) {
06123         if(!irplib_isnan(podata[i+j*xsz]) &&
06124            !irplib_isnan(psdata[i+j*xsz]) &&
06125            !irplib_isnan(pbdata[k]) &&
06126            !irplib_isnan(pscale[k])) {
06127     pcdata[i+j*xsz] = podata[i+j*xsz]-
06128                           (psdata[i+j*xsz]-pbdata[k])*pscale[k];
06129     }
06130       }
06131     }
06132   }
06133 
06134 
06135   return 0;
06136  cleanup:
06137 
06138   return -1;
06139 }
06140 
06141 
06158 static int
06159 sinfo_fitbkg(const double x[],
06160              const double a[],
06161              double *result)
06162 {
06163 
06164 
06165   double fac  = sinfo_fac(x[0],a[2]);
06166   /*
06167   int n=sizeof(x)/sizeof(double);
06168   double fmin = sinfo_fac(x[0],a[2]);
06169   double fmax = sinfo_fac(x[n-1],a[2]);
06170   sinfo_msg("n=%d",n);
06171   if(fmax < 0) sinfo_msg("fmax=%f",fmax);
06172   */
06173   //*result = a[0]+a[1]*fac/sinfo_scale_fct;
06174   *result = a[0]+a[1]*fac;
06175 
06176   return 0;
06177 }
06178 
06202 static int
06203 sinfo_fitbkg_derivative(const double x[],
06204                         const double a[],
06205                   double d[])
06206 {
06207   double c=14387.7;
06208   /*
06209   int n=sizeof(x)/sizeof(double);
06210   double fmin = sinfo_fac(x[0],a[2]);
06211   double fmax = sinfo_fac(x[n],a[2]);
06212   */
06213   double fac  = sinfo_fac(x[0],a[2]);
06214   double f2=0;
06215   double f1=0;
06216   double da=0.001;
06217   f1=a[0]+a[1]*fac;
06218   //f2=f1+da*a[0];
06219   //f2=a[0]+(a[1]+da*a[1])*fac;
06220   f2=a[0]+a[1]*sinfo_fac(x[0],a[2]+da*a[2]);
06221   d[0]=1.;
06222   d[1]=fac;
06223   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]));
06224   //sinfo_msg("d0=%g d1=%g d2=%g",d[0]*a[0]/f,d[1]*a[1]/f,d[2]*a[2]/f);
06225   //sinfo_msg("comp d1=%g",d[2]);
06226   //sinfo_msg("real d1=%g",(f2-f1)/(da*a[2]));
06227 
06228   return 0;
06229 }
06230 
06231 
06232 
06246 static double
06247 sinfo_fac(const double x, const double t)
06248 {
06249 
06250   double c=14387.7;
06251 
06252   //return pow(x,-5.)/(exp(c/(x*fabs(t)))-1.)/sinfo_scale_fct;
06253   return pow(x,-5.)/(exp(c/(x*fabs(t)))-1.);
06254 }
06255 
06265 static int
06266 sinfo_table_threshold(cpl_table** t,
06267                       const char* column,
06268                       const double low_cut,
06269                       const double hig_cut,
06270                       const double low_ass,
06271                       const double hig_ass)
06272 {
06273 
06274   int nrow=0;
06275   int i=0;
06276   double* pdata=NULL;
06277   cknull(*t,"null input table!");
06278 
06279   check_nomsg(nrow=cpl_table_get_nrow(*t));
06280   check_nomsg(pdata=cpl_table_get_data_double(*t,column));
06281 
06282   for(i=0;i<nrow;i++) {
06283 
06284     if(pdata[i]<low_cut) {
06285       pdata[i]=low_ass;
06286     }
06287     if (pdata[i] >= hig_cut) {
06288       pdata[i]=hig_ass;
06289     }
06290 
06291   }
06292 
06293   return 0;
06294 
06295  cleanup:
06296 
06297   return -1;
06298 }
06299 
06328 static int
06329 sinfo_table_set(cpl_table** inp,
06330                 const cpl_table* ref,
06331                 const double val,
06332                 const double tol)
06333 {
06334 
06335   int ninp=0;
06336   int nref=0;
06337   double* piw=NULL;
06338   const double* prw=NULL;
06339   double* pir=NULL;
06340   int i=0;
06341   int k=0;
06342   cknull(*inp,"NULL input table");
06343   cknull(ref,"NULL reference table");
06344 
06345   check_nomsg(ninp=cpl_table_get_nrow(*inp));
06346   check_nomsg(nref=cpl_table_get_nrow(ref));
06347 
06348   check_nomsg(prw=cpl_table_get_data_double_const(ref,"WAVE"));
06349   check_nomsg(piw=cpl_table_get_data_double(*inp,"WAVE"));
06350   check_nomsg(pir=cpl_table_get_data_double(*inp,"RATIO"));
06351 
06352 
06353   for(i=0;i<ninp;i++) {
06354     /*sinfo_msg("check =%g thresh=%g",fabs(piw[i]-prw[k]),tol); */
06355     if(fabs(piw[i]-prw[k]) < tol) {
06356       check_nomsg(cpl_table_set_double(*inp,"RATIO",i,val));
06357       k++;
06358     }
06359   }
06360   return 0;
06361 
06362  cleanup:
06363 
06364   return -1;
06365 
06366 }
06367 
06368 
06369 
06370 static cpl_table*
06371 sinfo_table_shift_simple(cpl_table* inp,
06372                          const char* col,
06373                          const double shift)
06374 {
06375 
06376   int nrow=0;
06377   cpl_table* out=NULL;
06378   int is=(int)shift;
06379   double ds=shift-is;
06380   double* pi=NULL;
06381   double* po=NULL;
06382   double m=0;
06383   int i=0;
06384   cknull(inp,"null input table");
06385 
06386   check_nomsg(nrow=cpl_table_get_nrow(inp));
06387   check_nomsg(out=cpl_table_duplicate(inp));
06388   check_nomsg(cpl_table_fill_column_window(out,col,0,nrow,0));
06389   check_nomsg(pi=cpl_table_get_data_double(inp,col));
06390   check_nomsg(po=cpl_table_get_data_double(out,col));
06391 
06392 
06393   for(i=0;i<nrow;i++) {
06394     if((i+is)>0 && (i+is+1) < nrow) {
06395       m=pi[i+is+1]-pi[i+is];
06396       po[i]=pi[i+is]+m*ds;
06397     }
06398   }
06399   return out;
06400   cleanup:
06401   sinfo_free_table(&out);
06402   return NULL;
06403 
06404 }
06405 
06406 
06407 
06408 
06409 static cpl_imagelist*
06410 sinfo_cube_zshift_simple(cpl_imagelist* inp,
06411                         const float shift)
06412 {
06413 
06414   int nx=0;
06415   int ny=0;
06416   int nz=0;
06417 
06418   int i=0;
06419   int j=0;
06420   int k=0;
06421   int ks=(int)shift;
06422 
06423   float ds=shift-ks;
06424   float* pu=NULL;
06425   float* pl=NULL;
06426   float* po=NULL;
06427 
06428   float  int2=0;
06429   float  int1=0;
06430   float m=0;
06431 
06432   cpl_imagelist* out=NULL;
06433   cpl_image* imgu=NULL;
06434   cpl_image* imgl=NULL;
06435   cpl_image* imgo=NULL;
06436 
06437 
06438   cknull(inp,"null input cube");
06439 
06440   check_nomsg(nz=cpl_imagelist_get_size(inp));
06441   check_nomsg(out=cpl_imagelist_duplicate(inp));
06442   check_nomsg(imgo=cpl_imagelist_get(out,0));
06443   check_nomsg(nx=cpl_image_get_size_x(imgo));
06444   check_nomsg(ny=cpl_image_get_size_y(imgo));
06445 
06446   for(k=0;k<nz;k++) {
06447     if((k+ks)>0 && (k+ks+1) < nz) {
06448 
06449       check_nomsg(imgu=cpl_imagelist_get(inp,k+ks+1));
06450       check_nomsg(imgl=cpl_imagelist_get(inp,k+ks));
06451       check_nomsg(imgo=cpl_imagelist_get(out,k));
06452 
06453       check_nomsg(pu=cpl_image_get_data_float(imgu));
06454       check_nomsg(pl=cpl_image_get_data_float(imgl));
06455       check_nomsg(po=cpl_image_get_data_float(imgo));
06456 
06457 
06458       for(j=0;j<ny;j++) {
06459     for(i=0;i<nx;i++) {
06460           int2=pu[nx*j+i];
06461           int1=pl[nx*j+i];
06462       m=int2-int1;
06463       po[nx*j+i]=int1+m*ds;
06464     }
06465       }
06466     }
06467 
06468 
06469   }
06470   return out;
06471   cleanup:
06472   sinfo_free_imagelist(&out);
06473   return NULL;
06474 
06475 }
06476 
06477 
06488 static int
06489 sinfo_get_line_ratio(cpl_table* obj_lin,
06490                       cpl_table* obj_cnt,
06491                       cpl_table* sky_lin,
06492                       cpl_table* sky_cnt,
06493                       const int method,
06494                       double* r)
06495 {
06496 
06497   int nobj;
06498   int nsky;
06499   int i=0;
06500 
06501   cpl_table* obj_dif=NULL;
06502   cpl_table* sky_dif=NULL;
06503 
06504   double* poi=NULL;
06505   double* psi=NULL;
06506   double* pvd=NULL;
06507   double* pvn=NULL;
06508   double* pvr=NULL;
06509 
06510   cpl_vector* num=NULL;
06511   cpl_vector* den=NULL;
06512   cpl_vector* rat=NULL;
06513   cpl_vector* wav=NULL;
06514   double mnum=0;
06515   double mden=0;
06516   double tnum=0;
06517   double tden=0;
06518   int pows[2];
06519   cpl_polynomial* cfit=NULL;
06520   double mse=0;
06521 
06522   cknull(obj_lin,"null obj line table");
06523   cknull(sky_lin,"null sky line table");
06524 
06525   cknull(obj_cnt,"null obj cont table");
06526   cknull(sky_cnt,"null sky cont table");
06527 
06528 
06529   cknull_nomsg(obj_dif=sinfo_table_subtract_continuum(obj_lin,obj_cnt));
06530   cknull_nomsg(sky_dif=sinfo_table_subtract_continuum(sky_lin,sky_cnt));
06531 
06532   check_nomsg(nobj=cpl_table_get_nrow(obj_dif));
06533   check_nomsg(nsky=cpl_table_get_nrow(sky_dif));
06534 
06535 
06536 
06537   if(nobj != nsky) {
06538     sinfo_msg_error("obj and sky table must have the same no of rows!");
06539     sinfo_msg_error("nobj=%d nsky=%d",nobj,nsky);
06540     goto cleanup;
06541   }
06542   //sinfo_msg("Object sky residuals/Sky lines ratio determination method=%d",
06543   //          method);
06544   if(method == 0) {
06545     ck0_nomsg(sinfo_get_line_ratio_amoeba(obj_dif,sky_dif,r));
06546     sinfo_free_table(&obj_dif);
06547     sinfo_free_table(&sky_dif);
06548    return 0;
06549   }
06550 
06551 
06552   check_nomsg(poi=cpl_table_get_data_double(obj_dif,"INT"));
06553   check_nomsg(psi=cpl_table_get_data_double(sky_dif,"INT"));
06554 
06555   check_nomsg(num=cpl_vector_new(nobj));
06556   check_nomsg(den=cpl_vector_new(nobj));
06557   check_nomsg(rat=cpl_vector_new(nobj));
06558   check_nomsg(cpl_vector_fill(num,0));
06559   check_nomsg(cpl_vector_fill(den,0));
06560   check_nomsg(cpl_vector_fill(rat,0));
06561   check_nomsg(pvd=cpl_vector_get_data(den));
06562   check_nomsg(pvn=cpl_vector_get_data(num));
06563   check_nomsg(pvr=cpl_vector_get_data(rat));
06564 
06565   for(i=0;i<nobj;i++) {
06566     if(!irplib_isnan(psi[i]) &&
06567        !irplib_isnan(poi[i]) &&
06568        !irplib_isinf(psi[i]) &&
06569        !irplib_isinf(poi[i]) ) {
06570       pvn[i]=psi[i]*poi[i];
06571       pvd[i]=psi[i]*psi[i];
06572       if(psi[i] != 0) {
06573          pvr[i]=poi[i]/psi[i];
06574       }
06575     }
06576   }
06577   sinfo_free_table(&sky_dif);
06578 
06579   check_nomsg(mnum=cpl_vector_get_median_const(num));
06580   check_nomsg(mden=cpl_vector_get_median_const(den));
06581   check_nomsg(tnum=cpl_vector_get_mean(num)*nobj);
06582   check_nomsg(tden=cpl_vector_get_mean(den)*nobj);
06583 
06584   //sinfo_msg("mden=%g tden=%g",mden,tden);
06585   //sinfo_msg("mnum=%g tnum=%g",mnum,tnum);
06586   sinfo_free_my_vector(&num);
06587   sinfo_free_my_vector(&den);
06588   if(method == 1) {
06589     *r=tnum/tden;
06590   } else if (method == 2) {
06591     *r=mnum/mden;
06592   } else if (method == 3) {
06593     *r=cpl_vector_get_median_const(rat);
06594   } else if (method == 4) {
06595     *r=cpl_vector_get_mean(rat);
06596   } else if (method == 5) {
06597 
06598     check_nomsg(wav=cpl_vector_wrap(nobj,
06599                     cpl_table_get_data_double(obj_dif,"WAVE")));
06600     check_nomsg(cfit=sinfo_polynomial_fit_1d_create(wav,rat,0,&mse));
06601     sinfo_unwrap_vector(&wav);
06602     pows[0]=0;
06603     pows[1]=0;
06604     check_nomsg(*r=cpl_polynomial_get_coeff(cfit,pows));
06605     sinfo_free_polynomial(&cfit);
06606 
06607   }
06608 
06609   sinfo_free_table(&obj_dif);
06610   sinfo_free_my_vector(&rat);
06611   return 0;
06612  cleanup:
06613   sinfo_free_table(&obj_dif);
06614   sinfo_free_table(&sky_dif);
06615   sinfo_free_my_vector(&num);
06616   sinfo_free_my_vector(&den);
06617   sinfo_free_my_vector(&rat);
06618   sinfo_unwrap_vector(&wav);
06619 
06620   return -1;
06621 }
06622 
06623 
06624 
06625 
06635 static int
06636 sinfo_get_line_ratio_amoeba(cpl_table* obj,
06637                             cpl_table* sky,
06638                             double* r)
06639 {
06640 
06641 
06642   int i=0;
06643   const int MP=2;
06644   const int NP=1;
06645   double y[MP];
06646   double p0[NP];
06647   double** ap=NULL;
06648   int nfunc=0;
06649   int np=0;
06650   check_nomsg(np=cpl_table_get_nrow(obj));
06651   check_nomsg(sa_ox=cpl_vector_wrap(np,cpl_table_get_data_double(obj,"WAVE")));
06652   check_nomsg(sa_oy=cpl_vector_wrap(np,cpl_table_get_data_double(obj,"INT")));
06653   check_nomsg(sa_sy=cpl_vector_wrap(np,cpl_table_get_data_double(sky,"INT")));
06654   // Amoeba part
06655 
06656 
06657   ap=(double**) cpl_calloc(MP,sizeof(double*));
06658   for(i=0;i<MP;i++) {
06659     ap[i]=cpl_calloc(NP,sizeof(double));
06660   }
06661 
06662   ap[0][0]=-1.;
06663   ap[1][0]=+1.;
06664 
06665   //sinfo_msg("Before amoeba fit");
06666   //sinfo_msg("ap[0][0]=%g ap[0][1]=%g",ap[0][0],ap[1][0]);
06667   for(i=0;i<MP;i++) {
06668     p0[0]=ap[i][0];
06669     y[i]=sinfo_fit_sky(p0);
06670   }
06671 
06672 
06673   check_nomsg(sinfo_fit_amoeba(ap,y,NP,AMOEBA_FTOL,sinfo_fit_sky,&nfunc));
06674 
06675   sinfo_msg("After amoeba fit");
06676   sinfo_msg("ap[0][0]=%g ap[0][1]=%g",ap[0][0],ap[1][0]);
06677 
06678   *r=ap[0][0];
06679 
06680   sinfo_unwrap_vector(&sa_ox);
06681   sinfo_unwrap_vector(&sa_oy);
06682   sinfo_unwrap_vector(&sa_sy);
06683   sinfo_new_destroy_2Ddoublearray(&ap,MP);
06684 
06685 
06686   return 0;
06687 
06688  cleanup:
06689   sinfo_unwrap_vector(&sa_ox);
06690   sinfo_unwrap_vector(&sa_oy);
06691   sinfo_unwrap_vector(&sa_sy);
06692   sinfo_new_destroy_2Ddoublearray(&ap,MP);
06693 
06694   return -1;
06695 
06696 }
06697 
06698 
06699 /*-------------------------------------------------------------------------*/
06708 /*--------------------------------------------------------------------------*/
06709 
06710 static double
06711 sinfo_fit_sky(double p[])
06712 
06713 {
06714   double* ps=NULL;
06715   double* po=NULL;
06716   double* pv=NULL;
06717   cpl_vector* vtmp=NULL;
06718   int i=0;
06719   int np=0;
06720   int pows[2];
06721   double mse=0;
06722   double cont=0;
06723   cpl_polynomial* pfit=NULL;
06724 
06725   double rms=0;
06726 
06727 
06728   //fit residual obj continuum and subtract it
06729   check_nomsg(pfit=sinfo_polynomial_fit_1d_create(sa_ox,sa_oy,0,&mse));
06730   pows[0]=0;
06731   pows[1]=0;
06732   check_nomsg(cont=cpl_polynomial_get_coeff(pfit,pows));
06733   check_nomsg(sinfo_free_polynomial(&pfit));
06734   check_nomsg(cpl_vector_subtract_scalar(sa_oy,cont));
06735 
06736 
06737   //fit residual sky continuum and subtract it
06738   check_nomsg(pfit=sinfo_polynomial_fit_1d_create(sa_ox,sa_sy,0,&mse));
06739   pows[0]=0;
06740   pows[1]=0;
06741   check_nomsg(cont=cpl_polynomial_get_coeff(pfit,pows));
06742   check_nomsg(sinfo_free_polynomial(&pfit));
06743   check_nomsg(cpl_vector_subtract_scalar(sa_sy,cont));
06744 
06745   //computes diff=(obj-conto)-(sky-contsky)*p[0]
06746   check_nomsg(po= cpl_vector_get_data(sa_oy));
06747   check_nomsg(ps= cpl_vector_get_data(sa_sy));
06748 
06749   check_nomsg(np=cpl_vector_get_size(sa_oy));
06750   check_nomsg(vtmp=cpl_vector_new(np));
06751   check_nomsg(pv= cpl_vector_get_data(vtmp));
06752 
06753 
06754   for(i=0;i<np;i++) {
06755     pv[i]=po[i]-ps[i]*p[0];
06756   }
06757   //computes rms diff
06758   check_nomsg(rms=cpl_vector_get_stdev(vtmp));
06759   sinfo_free_my_vector(&vtmp);
06760   return rms;
06761  cleanup:
06762   sinfo_free_my_vector(&vtmp);
06763   return -1;
06764 
06765 }
06766 
06767 
06768 
06780 static cpl_table*
06781 sinfo_table_interpol(cpl_table* obj_lin,
06782                      cpl_table* obj_cnt,
06783                      cpl_table* sky_lin,
06784                      cpl_table* sky_cnt,
06785                      const double r)
06786 {
06787 
06788   cpl_table* out=NULL;
06789   cpl_table* obj_dif=NULL;
06790   cpl_table* sky_dif=NULL;
06791   cknull(obj_lin,"null line table");
06792   cknull(obj_cnt,"null cont table");
06793 
06794   cknull_nomsg(obj_dif=sinfo_table_subtract_continuum(obj_lin,obj_cnt));
06795   cknull_nomsg(sky_dif=sinfo_table_subtract_continuum(sky_lin,sky_cnt));
06796 
06797   check_nomsg(out=cpl_table_duplicate(obj_dif));
06798   check_nomsg(cpl_table_duplicate_column(out,"CSKY",sky_dif,"INT"));
06799   check_nomsg(cpl_table_multiply_scalar(out,"CSKY",r));
06800   check_nomsg(cpl_table_subtract_columns(out,"INT","CSKY"));
06801 
06802   sinfo_free_table(&obj_dif);
06803   sinfo_free_table(&sky_dif);
06804 
06805   return out;
06806 
06807  cleanup:
06808   sinfo_free_table(&obj_dif);
06809   sinfo_free_table(&sky_dif);
06810   sinfo_free_table(&out);
06811   return NULL;
06812 
06813 }
06814 
06815 
06816 
06817 
06818 
06819 
06828 static cpl_table*
06829 sinfo_table_subtract_continuum(cpl_table* lin,
06830                                cpl_table* cnt)
06831 
06832 {
06833 
06834   cpl_table* out=NULL;
06835   int nlin=0;
06836   int ncnt=0;
06837   int i=0;
06838   double* poi=NULL;
06839   cpl_vector* vx=NULL;
06840   cpl_vector* vy=NULL;
06841   cpl_polynomial* cfit=NULL;
06842   int pows[2];
06843   double mse=0;
06844   double yfit=0;
06845 
06846   cknull(lin,"null line table");
06847   cknull(cnt,"null cont table");
06848   check_nomsg(out=cpl_table_duplicate(lin));
06849   check_nomsg(cpl_table_new_column(out,"CONT",CPL_TYPE_DOUBLE));
06850   check_nomsg(nlin=cpl_table_get_nrow(lin));
06851   check_nomsg(ncnt=cpl_table_get_nrow(cnt));
06852   //sinfo_msg("nlin=%d",nlin);
06853   check_nomsg(cpl_table_fill_column_window(out,"CONT",0,nlin,0));
06854 
06855   //do a uniform fit
06856   check_nomsg(vx=cpl_vector_wrap(ncnt,cpl_table_get_data_double(cnt,"WAVE")));
06857   check_nomsg(vy=cpl_vector_wrap(ncnt,cpl_table_get_data_double(cnt,"INT")));
06858   check_nomsg(cfit=sinfo_polynomial_fit_1d_create(vx,vy,0,&mse));
06859   sinfo_unwrap_vector(&vx);
06860   sinfo_unwrap_vector(&vy);
06861 
06862   pows[0]=0;
06863   pows[1]=0;
06864   check_nomsg(yfit=cpl_polynomial_get_coeff(cfit,pows));
06865   sinfo_free_polynomial(&cfit);
06866   //sinfo_msg("coeff 0=%g",yfit);
06867 
06868   check_nomsg(poi=cpl_table_get_data_double(out,"CONT"));
06869   for(i=0;i<nlin;i++) {
06870     poi[i]=yfit;
06871   }
06872 
06873   check_nomsg(cpl_table_subtract_columns(out,"INT","CONT"));
06874   check_nomsg(cpl_table_erase_column(out,"CONT"));
06875 
06876 
06877 
06878   return out;
06879 
06880  cleanup:
06881   sinfo_unwrap_vector(&vx);
06882   sinfo_unwrap_vector(&vy);
06883   sinfo_free_polynomial(&cfit);
06884   sinfo_free_table(&out);
06885   return NULL;
06886 
06887 }
06888 
06889 
06890 static int
06891 sinfo_compute_line_ratio(cpl_table* obj,
06892                          cpl_table* sky,
06893                          const double wtol,
06894                          const int meth,
06895                          const cpl_table* sel_regions,
06896                          cpl_table* cont_regions,
06897                          double* r)
06898 {
06899   cpl_table* line_regions=NULL;
06900   cpl_table* obj_cnt=NULL;
06901   cpl_table* sky_cnt=NULL;
06902   cpl_table* obj_lin=NULL;
06903   cpl_table* sky_lin=NULL;
06904   cpl_table* lres=NULL;
06905   double fmed=0;
06906   double fsdv=0;
06907   double fthresh=0;
06908   int fclip_i=0;
06909   int line_i=0;
06910 
06911 
06912   //line_regions = med_regions;
06913   check_nomsg(line_regions = cpl_table_duplicate(sel_regions));
06914   //r = amoeba(1.e-5,function_name='fitsky',p0=[1.],scale=[0.1]);
06915   //Identify obj lines and continuum, same for sky
06916   check_nomsg(obj_lin=sinfo_table_select_range(obj,line_regions,wtol));
06917   check_nomsg(sky_lin=sinfo_table_select_range(sky,line_regions,wtol));
06918   check_nomsg(obj_cnt=sinfo_table_select_range(obj,cont_regions,wtol));
06919   check_nomsg(sky_cnt=sinfo_table_select_range(sky,cont_regions,wtol));
06920 
06921   ck0_nomsg(sinfo_get_line_ratio(obj_lin,obj_cnt,sky_lin,sky_cnt,meth,r));
06922 
06923 
06924   //fline_res = (obj_lr[line_regions]-
06925   //             interpol(obj_lr[cont_regions],llr[cont_regions],
06926   //             llr[line_regions])) -
06927   //            (sky_lr[line_regions] -
06928   //             interpol(sky_lr[cont_regions],llr[cont_regions],
06929   //
06930   //            llr[line_regions]))*r[0];
06931   check_nomsg(lres=sinfo_table_interpol(obj_lin,obj_cnt,sky_lin,sky_cnt,*r));
06932 
06933   check_nomsg(fmed = cpl_table_get_column_median(lres,"INT"));
06934   check_nomsg(fsdv = cpl_table_get_column_stdev(lres,"INT"));
06935   fthresh=fmed+3*fsdv;
06936   //fclip = where(abs(fline_res) > fmed+3*fsdv,fclip_i);
06937   check_nomsg(cpl_table_duplicate_column(lres,"AINT",lres,"INT"));
06938   check_nomsg(cpl_table_multiply_columns(lres,"AINT","INT"));
06939   check_nomsg(cpl_table_power_column(lres,"AINT",0.5));
06940   check_nomsg(fclip_i=cpl_table_and_selected_double(lres,"AINT",
06941                                                     CPL_GREATER_THAN,
06942                                                     fthresh));
06943   check_nomsg(cpl_table_select_all(lres));
06944 
06945 
06946   if (fclip_i > 0) {
06947     //line_regions = line_regions[where(abs(fline_res) < fmed+3*fsdv)];
06948     check_nomsg(line_i=cpl_table_and_selected_double(lres,"AINT",
06949                              CPL_LESS_THAN,
06950                              fthresh));
06951     sinfo_free_table(&line_regions);
06952     check_nomsg(line_regions=cpl_table_extract_selected(lres));
06953     sinfo_free_table(&lres);
06954 
06955     check_nomsg(cpl_table_erase_column(line_regions,"INT"));
06956     check_nomsg(cpl_table_erase_column(line_regions,"AINT"));
06957 
06958 
06959     if (line_i >= 3) {
06960 
06961     sinfo_free_table(&obj_lin);
06962     sinfo_free_table(&sky_lin);
06963     check_nomsg(obj_lin=sinfo_table_select_range(obj,line_regions,wtol));
06964     check_nomsg(sky_lin=sinfo_table_select_range(sky,line_regions,wtol));
06965 
06966     sinfo_free_table(&line_regions);
06967 
06968 
06969      //r = amoeba(1.e-5,function_name='fitsky',p0=[1.],scale=[0.1]);
06970       ck0_nomsg(sinfo_get_line_ratio(obj_lin,obj_cnt,sky_lin,sky_cnt,meth,r));
06971     }
06972   }
06973   *r=fabs(*r);
06974   //Free memory
06975   sinfo_free_table(&obj_cnt);
06976   sinfo_free_table(&sky_cnt);
06977   sinfo_free_table(&sky_lin);
06978   sinfo_free_table(&obj_lin);
06979   sinfo_free_table(&lres);
06980   sinfo_free_table(&line_regions);
06981 
06982 
06983   return 0;
06984 
06985 
06986  cleanup:
06987 
06988 
06989   sinfo_free_table(&obj_cnt);
06990   sinfo_free_table(&sky_cnt);
06991   sinfo_free_table(&sky_lin);
06992   sinfo_free_table(&obj_lin);
06993 
06994   sinfo_free_table(&lres);
06995   sinfo_free_table(&line_regions);
06996 
06997   return -1;
06998 
06999 }
07011 static cpl_table*
07012 sinfo_find_rot_waves(
07013              const double  w_rot[],
07014                      const int npix_w,
07015                      const double w_step,
07016                      cpl_table* range
07017              )
07018 {
07019   int i=0;
07020   int x_i=0;
07021   int r_start=0;
07022   double w_min=0;
07023   double w_max=0;
07024 
07025   cpl_table* w_sel=NULL;
07026   cpl_table* res=NULL;
07027 
07028   check_nomsg(res = cpl_table_new(0));
07029 
07030   check_nomsg(cpl_table_copy_structure(res,range));
07031 
07032   for (i=0; i< NROT; i++) {
07033 
07034     //x = where(lambda > l_rot_low[i]-npixw*cdelto &&
07035     //          lambda < l_rot_low[i]+npixw*cdelto,x_i);
07036 
07037     w_min=w_rot[i]-npix_w*w_step;
07038     w_max=w_rot[i]+npix_w*w_step;
07039 
07040     check_nomsg(cpl_table_and_selected_double(range,"WAVE",
07041                                               CPL_GREATER_THAN,w_min));
07042     check_nomsg(cpl_table_and_selected_double(range,"WAVE",
07043                                               CPL_LESS_THAN,w_max));
07044     sinfo_free_table(&w_sel);
07045     check_nomsg(w_sel=cpl_table_extract_selected(range));
07046     check_nomsg(x_i=cpl_table_get_nrow(w_sel));
07047 
07048     if (x_i > 0) {
07049       check_nomsg(r_start=cpl_table_get_nrow(res));
07050       //sinfo_msg("i=%d x_i=%d w_min=%g w_max=%g",i,x_i,w_min,w_max);
07051       check_nomsg(cpl_table_insert(res,w_sel,r_start));
07052     }
07053     check_nomsg(cpl_table_select_all(range));
07054   }
07055 
07056   //res = range[1:cpl_table_get_nrow(res)-1];
07057   sinfo_free_table(&w_sel);
07058 
07059 
07060   return res;
07061 
07062  cleanup:
07063   sinfo_free_table(&w_sel);
07064   sinfo_free_table(&res);
07065   return NULL;
07066 
07067 }
07068 
07081 static int
07082 sinfo_get_obj_sky_wav_sub(cpl_table* obj,
07083                           cpl_table* sky,
07084                           cpl_table* wav,
07085                           cpl_table* sel,
07086                           const double wtol,
07087                           cpl_table** sub_obj,
07088                           cpl_table** sub_sky,
07089                           cpl_table** sub_wav)
07090 
07091 {
07092   cknull_nomsg(*sub_obj = sinfo_table_select_range(obj,sel,wtol));
07093   cknull_nomsg(*sub_sky = sinfo_table_select_range(sky,sel,wtol));
07094   cknull_nomsg(*sub_wav = sinfo_table_select_range(wav,sel,wtol));
07095   return 0;
07096 
07097  cleanup:
07098   sinfo_free_table(&(*sub_obj));
07099   sinfo_free_table(&(*sub_sky));
07100   sinfo_free_table(&(*sub_wav));
07101 
07102   return -1;
07103 
07104 }
07105 
07106 static int
07107 sinfo_get_sub_regions(cpl_table* sky,
07108                       cpl_table* x1,
07109                       cpl_table* pos,
07110                       const double wtol,
07111                       const int npixw,
07112                       cpl_table** res)
07113 {
07114 
07115   cpl_table* x1_sub=NULL;
07116   cpl_table* x2=NULL;
07117 
07118   int nrow=0;
07119   int np=0;
07120 
07121   cknull(sky,"Null input sky table");
07122   cknull(x1 ,"Null input x1 table");
07123   cknull(pos,"Null input pos table");
07124 
07125   check_nomsg(x2=cpl_table_duplicate(sky));
07126   check_nomsg(nrow=cpl_table_get_nrow(sky));
07127   check_nomsg(cpl_table_fill_column_window(x2,"INT",0,nrow,0));
07128 
07129   //x2[x1[pos]] = 10.;
07130   //x2 = convol(x2,replicate(1,npixw),/edge_truncate,/center);
07131   //res = where(x2 > 0,hi_i);
07132   //cpl_table_save(x1, NULL, NULL, "out_x1.fits", CPL_IO_DEFAULT);
07133 
07134   x1_sub=sinfo_table_select_range(x1,pos,wtol);
07135 
07136   if(x1_sub != NULL) {
07137     ck0_nomsg(sinfo_table_fill_column_over_range(&x2,x1_sub,"INT",10.,wtol));
07138     sinfo_free_table(&x1_sub);
07139     check_nomsg(sinfo_convolve_kernel(&x2,npixw/2));
07140     check_nomsg(np=cpl_table_and_selected_double(x2,"CNV",CPL_GREATER_THAN,0));
07141     check_nomsg(*res=cpl_table_extract_selected(x2));
07142     sinfo_free_table(&x2);
07143     check_nomsg(cpl_table_erase_column(*res,"INT"));
07144     check_nomsg(cpl_table_erase_column(*res,"CNV"));
07145 
07146   } else {
07147     cpl_error_reset();
07148     sinfo_free_table(&x1_sub);
07149     sinfo_free_table(&x2);
07150 
07151     return np;
07152   }
07153 
07154   return np;
07155  cleanup:
07156 
07157   sinfo_free_table(&x1_sub);
07158   sinfo_free_table(&x2);
07159   return -1;
07160 
07161 }
07162 
07163 static cpl_table*
07164 sinfo_table_extract_rest(cpl_table* inp,
07165                          cpl_table* low,
07166                          cpl_table* med,
07167                          const double wtol)
07168 {
07169 
07170   cpl_table* out=NULL;
07171   double* pinp=NULL;
07172   double* plow=NULL;
07173   double* pmed=NULL;
07174   int nlow=0;
07175   int nmed=0;
07176 
07177   int nrow=0;
07178   int i=0;
07179   int k=0;
07180   cpl_table* tmp=NULL;
07181 
07182   cknull(inp,"null input table");
07183 
07184 
07185   check_nomsg(tmp=cpl_table_duplicate(inp));
07186   check_nomsg(nrow=cpl_table_get_nrow(tmp));
07187   check_nomsg(cpl_table_new_column(tmp,"SEL",CPL_TYPE_INT));
07188   check_nomsg(cpl_table_fill_column_window_int(tmp,"SEL",0,nrow,0));
07189 
07190   check_nomsg(pinp=cpl_table_get_data_double(inp,"WAVE"));
07191   check_nomsg(plow=cpl_table_get_data_double(low,"WAVE"));
07192   check_nomsg(pmed=cpl_table_get_data_double(med,"WAVE"));
07193   nlow=cpl_table_get_nrow(low);
07194 
07195 
07196   //check_nomsg(cpl_table_save(low,NULL,NULL,"out_low.fits",CPL_IO_DEFAULT));
07197   if(nlow > 0) {
07198     k=0;
07199     for(i=0;i<nrow;i++) {
07200       if(fabs(pinp[i]-plow[k]) < wtol) {
07201     cpl_table_set_int(tmp,"SEL",k,-1);
07202     k++;
07203       }
07204     }
07205   }
07206   nmed=cpl_table_get_nrow(med);
07207 
07208   k=0;
07209   if(nmed > 0) {
07210     for(i=0;i<nrow;i++) {
07211       if(fabs(pinp[i]-pmed[k]) < wtol) {
07212     cpl_table_set_int(tmp,"SEL",k,-1);
07213     k++;
07214       }
07215     }
07216   }
07217 
07218   check_nomsg(cpl_table_and_selected_int(tmp,"SEL",CPL_GREATER_THAN,-1));
07219   check_nomsg(out=cpl_table_extract_selected(tmp));
07220   sinfo_free_table(&tmp);
07221   check_nomsg(cpl_table_erase_column(out,"SEL"));
07222 
07223   return out;
07224 
07225  cleanup:
07226   sinfo_free_table(&tmp);
07227   return NULL;
07228 
07229 }
07230 

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1