sinfo_skycor.c

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

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1