SINFONI Pipeline Reference Manual  2.5.2
sinfo_utl_table_test.c
1 /* $Id: sinfo_utl_table_test.c,v 1.6 2012-03-03 10:38:03 amodigli Exp $
2  *
3  * This file is part of the SINFONI Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: amodigli $
23  * $Date: 2012-03-03 10:38:03 $
24  * $Revision: 1.6 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <math.h>
32 /*-----------------------------------------------------------------------------
33  Includes
34  ----------------------------------------------------------------------------*/
35 #include <stdlib.h>
36 /* cpl */
37 #include <cpl.h>
38 /* irplib */
39 #include <irplib_utils.h>
40 
41 #include <sinfo_tpl_utils.h>
42 #include <sinfo_pfits.h>
43 #include <sinfo_tpl_dfs.h>
44 #include <sinfo_msg.h>
45 #include <sinfo_error.h>
46 #include <sinfo_utils_wrappers.h>
47 #include <sinfo_globals.h>
48 #include <sinfo_recipes.h>
49 #include <sinfo_function_1d.h>
50 #include <sinfo_functions.h>
51 #include <sinfo_fit.h>
52 /*-----------------------------------------------------------------------------
53  Functions prototypes
54  ----------------------------------------------------------------------------*/
55 
56 static int sinfo_utl_table_test_create(cpl_plugin *) ;
57 static int sinfo_utl_table_test_exec(cpl_plugin *) ;
58 static int sinfo_utl_table_test_destroy(cpl_plugin *) ;
59 static int sinfo_utl_table_test_shift(cpl_parameterlist *, cpl_frameset *) ;
60 
61 static int
62 sinfo_utl_table_test_amoeba_poly(cpl_parameterlist * parlist,
63  cpl_frameset * framelist);
64 static int
65 sinfo_utl_table_test_amoeba_boltzmann(cpl_parameterlist * parlist,
66  cpl_frameset * framelist);
67 
68 static cpl_vector* sa_vx=NULL;
69 static cpl_vector* sa_vy=NULL;
70 
71 static double
72 sinfo_fit_boltzmann(double p[]);
73 
74 
75 static int
76 sinfo_fitbkg(const double x[],
77  const double a[],
78  double *result);
79 
80 static double
81 sinfo_fac(const double x, const double t);
82 
83 static double
84 sinfo_fit_poly(double p[]);;
85 
86 static cpl_table*
87 sinfo_table_shift_column_spline3(cpl_table* t,
88  const char* col,
89  const double s);
90 
91 static cpl_table*
92 sinfo_table_shift_column_poly(cpl_table* t,
93  const char* col,
94  const double s,
95  const int order);
96 
97 static cpl_table*
98 sinfo_table_shift_column_int(const cpl_table* t,
99  const char* col,
100  const double s,
101  double* r);
102 
103 static cpl_table*
104 sinfo_table_shift_simple(cpl_table* inp,
105  const char* col,
106  const double shift);
107 
108 #define NPOINT 1000
109 /*-----------------------------------------------------------------------------
110  Static variables
111  ----------------------------------------------------------------------------*/
112 
113 static char sinfo_utl_table_test_description[] =
114  "This recipe perform cubes combination.\n"
115  "The input files are several cubeses\n"
116  "their associated tags should be CUBE.\n"
117  "The output is a cube PRO_CUBE resulting from the input cubes\n"
118  "accurding to the value of op where op indicates the operation to be \n"
119  "performed specified by the parameter sinfoni.sinfo_utl_table_test.op\n"
120  "\n";
121 
122 /*-----------------------------------------------------------------------------
123  Functions code
124  ----------------------------------------------------------------------------*/
126 /*---------------------------------------------------------------------------*/
130 /*---------------------------------------------------------------------------*/
131 
132 /*---------------------------------------------------------------------------*/
140 /*---------------------------------------------------------------------------*/
141 int cpl_plugin_get_info(cpl_pluginlist * list)
142 {
143  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe ) ;
144  cpl_plugin * plugin = &recipe->interface ;
145 
146  cpl_plugin_init(plugin,
147  CPL_PLUGIN_API,
148  SINFONI_BINARY_VERSION,
149  CPL_PLUGIN_TYPE_RECIPE,
150  "sinfo_utl_table_test",
151  "Combines a cube list in an output cube",
152  sinfo_utl_table_test_description,
153  "Andrea Modigliani",
154  "Andrea.Modigliani@eso.org",
155  sinfo_get_license(),
156  sinfo_utl_table_test_create,
157  sinfo_utl_table_test_exec,
158  sinfo_utl_table_test_destroy) ;
159 
160  cpl_pluginlist_append(list, plugin) ;
161 
162  return 0;
163 }
164 
165 /*---------------------------------------------------------------------------*/
174 /*---------------------------------------------------------------------------*/
175 static int sinfo_utl_table_test_create(cpl_plugin * plugin)
176 {
177  cpl_recipe * recipe ;
178  cpl_parameter * p ;
179 
180  /* Get the recipe out of the plugin */
181  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
182  recipe = (cpl_recipe *)plugin ;
183  else return -1 ;
184  cpl_error_reset();
185  irplib_reset();
186 
187  /* Create the parameters list in the cpl_recipe object */
188  recipe->parameters = cpl_parameterlist_new() ;
189 
190  /* Fill the parameters list */
191  /* --stropt */
192  p = cpl_parameter_new_value("sinfoni.sinfo_utl_table_test.method",
193  CPL_TYPE_STRING,
194  "Output filename",
195  "sinfoni.sinfo_utl_table_test",
196  "sinfo_clean_mean");
197  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method") ;
198  cpl_parameterlist_append(recipe->parameters, p) ;
199 
200  /* --doubleopt */
201  p = cpl_parameter_new_value("sinfoni.sinfo_utl_table_test.wshift",
202  CPL_TYPE_DOUBLE,
203  "Shift",
204  "sinfoni.sinfo_utl_table_test",
205  0.01) ;
206 
207  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wshift") ;
208  cpl_parameterlist_append(recipe->parameters, p) ;
209 
210  /* --doubleopt */
211  p = cpl_parameter_new_value("sinfoni.sinfo_utl_table_test.wstart",
212  CPL_TYPE_DOUBLE,
213  "Shift",
214  "sinfoni.sinfo_utl_table_test",
215  1.45) ;
216 
217 
218  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wstart") ;
219  cpl_parameterlist_append(recipe->parameters, p) ;
220 
221 
222  /* --doubleopt */
223  p = cpl_parameter_new_value("sinfoni.sinfo_utl_table_test.wend",
224  CPL_TYPE_DOUBLE,
225  "End Wavelength",
226  "sinfoni.sinfo_utl_table_test",
227  2.45) ;
228 
229 
230  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wend") ;
231  cpl_parameterlist_append(recipe->parameters, p) ;
232 
233 
234  /* Return */
235  return 0;
236 }
237 
238 /*---------------------------------------------------------------------------*/
244 /*---------------------------------------------------------------------------*/
245 static int sinfo_utl_table_test_exec(cpl_plugin * plugin)
246 {
247  cpl_recipe * recipe ;
248  int status=0;
249  cpl_errorstate initial_errorstate = cpl_errorstate_get();
250 
251  /* Get the recipe out of the plugin */
252  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
253  recipe = (cpl_recipe *)plugin ;
254  else return -1 ;
255  status+=sinfo_utl_table_test_shift(recipe->parameters, recipe->frames);
256  status+=sinfo_utl_table_test_amoeba_poly(recipe->parameters,
257  recipe->frames);
258  status+=sinfo_utl_table_test_amoeba_boltzmann(recipe->parameters,
259  recipe->frames);
260  if (!cpl_errorstate_is_equal(initial_errorstate)) {
261  /* Dump the error history since recipe execution start.
262  At this point the recipe cannot recover from the error */
263  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
264  }
265  return status ;
266 }
267 
268 /*---------------------------------------------------------------------------*/
274 /*---------------------------------------------------------------------------*/
275 static int sinfo_utl_table_test_destroy(cpl_plugin * plugin)
276 {
277  cpl_recipe * recipe ;
278 
279  /* Get the recipe out of the plugin */
280  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
281  recipe = (cpl_recipe *)plugin ;
282  else return -1 ;
283 
284  cpl_parameterlist_delete(recipe->parameters) ;
285  return 0 ;
286 }
287 
288 
289 /*---------------------------------------------------------------------------*/
296 /*---------------------------------------------------------------------------*/
297 static int
298 sinfo_utl_table_test_shift(cpl_parameterlist * parlist,
299  cpl_frameset * framelist)
300 {
301 
302  cpl_table* t=NULL;
303  cpl_table* t_shift=NULL;
304  int np=NPOINT;
305  cpl_parameter* p=NULL;
306  const char* op=NULL;
307  double ws=0;
308  double we=0;
309  double wd=0;
310  double wshift=0;
311  double pshift=0;
312 
313  double* pw=NULL;
314  double* pi=NULL;
315 
316  int i=0;
317 
318  double ra=0;
319  const double pg=3.1415926535897932384626433832795;
320 
321 
322  check(sinfo_dfs_set_groups(framelist),
323  "Cannot identify RAW and CALIB frames") ;
324 
325  // read input parameters
326  check_nomsg(p=cpl_parameterlist_find(parlist,
327  "sinfoni.sinfo_utl_table_test.method"));
328  check_nomsg(op=cpl_parameter_get_string(p));
329 
330 
331  check_nomsg(p=cpl_parameterlist_find(parlist,
332  "sinfoni.sinfo_utl_table_test.wstart"));
333  check_nomsg(ws=cpl_parameter_get_double(p)) ;
334 
335 
336  wd=(we-ws)/np;
337  check_nomsg(p=cpl_parameterlist_find(parlist,
338  "sinfoni.sinfo_utl_table_test.wend"));
339  check_nomsg(we=cpl_parameter_get_double(p)) ;
340 
341  check_nomsg(p=cpl_parameterlist_find(parlist,
342  "sinfoni.sinfo_utl_table_test.wshift"));
343  check_nomsg(wshift=cpl_parameter_get_double(p)) ;
344 
345 
346 
347  // create the table
348  check_nomsg(t=cpl_table_new(np));
349  check_nomsg(cpl_table_new_column(t,"WAVE",CPL_TYPE_DOUBLE));
350  check_nomsg(cpl_table_new_column(t,"INT",CPL_TYPE_DOUBLE));
351  check_nomsg(cpl_table_fill_column_window(t,"WAVE",0,np,0));
352  check_nomsg(cpl_table_fill_column_window(t,"INT",0,np,0));
353 
354  check_nomsg(pw=cpl_table_get_data_double(t,"WAVE"));
355  check_nomsg(pi=cpl_table_get_data_double(t,"INT"));
356 
357 
358 
359  for(i=0;i<np;i++) {
360  pw[i]=ws+i*wd;
361  ra=(double)i/(double)np*6.*pg;
362  pi[i]=cos(ra);
363  }
364  pshift=wshift/wd;
365  check_nomsg(cpl_table_save(t, NULL, NULL, "out_cosine.fits", 0));
366  /*
367  sinfo_msg("shift1");
368  cknull_nomsg(t_shift=sinfo_table_shift_column_int(t, "INT", pshift,&wrest));
369  check_nomsg(cpl_table_save(t_shift,NULL,NULL,"out_cosine_shift1.fits", 0));
370  sinfo_msg("shift2");
371  sinfo_free_table(&t_shift);
372  cknull_nomsg(t_shift=sinfo_table_shift_column_poly(t,"INT", pshift,2));
373  check_nomsg(cpl_table_save(t_shift,NULL,NULL,"out_cosine_shift2.fits", 0));
374  sinfo_msg("shift3");
375  sinfo_free_table(&t_shift);
376  cknull_nomsg(t_shift=sinfo_table_shift_column_spline3(t_shift,"INT",pshift));
377 
378  */
379 
380  check_nomsg(t_shift=sinfo_table_shift_simple(t,"INT",pshift));
381  check_nomsg(cpl_table_save(t_shift,NULL,NULL, "out_cosine_shift3.fits", 0));
382  sinfo_free_table(&t);
383 
384  return -1;
385  cleanup:
386 
387  sinfo_free_table(&t);
388  return -1;
389 
390 
391 }
392 
393 
394 
395 /*---------------------------------------------------------------------------*/
402 /*---------------------------------------------------------------------------*/
403 static int
404 sinfo_utl_table_test_amoeba_poly(cpl_parameterlist * parlist,
405  cpl_frameset * framelist)
406 {
407 
408  cpl_table* t=NULL;
409  int np=NPOINT;
410  cpl_parameter* p=NULL;
411  const char* op=NULL;
412  double ws=0;
413  double we=0;
414  double wd=0;
415  double wshift=0;
416 
417  double* pw=NULL;
418  double* pi=NULL;
419  double* pf=NULL;
420  int i=0;
421  int j=0;
422  double a[3];
423  double p0[3];
424 
425 
426  // Amoeba fit:
427  const int MP=4;
428  const int NP=3;
429  double y[MP];
430  double** ap=NULL;
431  double FTOL=2e-6;
432  int nfunc=0;
433 
434  check(sinfo_dfs_set_groups(framelist),
435  "Cannot identify RAW and CALIB frames") ;
436 
437  // read input parameters
438  check_nomsg(p=cpl_parameterlist_find(parlist,
439  "sinfoni.sinfo_utl_table_test.method"));
440  check_nomsg(op=cpl_parameter_get_string(p));
441 
442 
443  check_nomsg(p=cpl_parameterlist_find(parlist,
444  "sinfoni.sinfo_utl_table_test.wstart"));
445  check_nomsg(ws=cpl_parameter_get_double(p)) ;
446 
447 
448  wd=(we-ws)/np;
449  check_nomsg(p=cpl_parameterlist_find(parlist,
450  "sinfoni.sinfo_utl_table_test.wend"));
451  check_nomsg(we=cpl_parameter_get_double(p)) ;
452 
453  check_nomsg(p=cpl_parameterlist_find(parlist,
454  "sinfoni.sinfo_utl_table_test.wshift"));
455  check_nomsg(wshift=cpl_parameter_get_double(p)) ;
456 
457 
458  //Prepare a template function (polynomial)
459  check_nomsg(t=cpl_table_new(np));
460  check_nomsg(cpl_table_new_column(t,"WAVE",CPL_TYPE_DOUBLE));
461  check_nomsg(cpl_table_new_column(t,"INT",CPL_TYPE_DOUBLE));
462  check_nomsg(cpl_table_fill_column_window(t,"WAVE",0,np,0));
463  check_nomsg(cpl_table_fill_column_window(t,"INT",0,np,0));
464 
465  check_nomsg(pw=cpl_table_get_data_double(t,"WAVE"));
466  check_nomsg(pi=cpl_table_get_data_double(t,"INT"));
467  ws=-2.;
468  we=+4.;
469  a[0]=+1.;
470  a[1]=-2.;
471  a[2]=1.;
472  wd=(we-ws)/np;
473  for(i=0;i<np;i++) {
474  pw[i]=ws+i*wd;
475  //pi[i]=(pw[i]-a[0])*(pw[i]-a[0])+1.*rand()/RAND_MAX;
476  pi[i]=a[0]+a[1]*pw[i]+a[2]*pw[i]*pw[i]+1.*rand()/RAND_MAX;
477  }
478 
479 
480  sa_vx=cpl_vector_wrap(np,cpl_table_get_data_double(t,"WAVE"));
481  sa_vy=cpl_vector_wrap(np,cpl_table_get_data_double(t,"INT"));
482  // Amoeba part
483  ap=(double**) cpl_calloc(MP,sizeof(double*));
484  for(i=0;i<MP;i++) {
485  ap[i]=cpl_calloc(NP,sizeof(double));
486  }
487 
488  for(i=0;i<MP;i++) {
489  for(j=0;j<NP;j++) {
490  ap[i][j]=0;
491  }
492  }
493  //ap[0][0]=-5;
494  //ap[1][0]=-2;
495 
496  ap[0][0]=-3; ap[0][1]=-3; ap[0][2]=-3;
497  ap[1][0]=+3; ap[1][1]=-3; ap[1][2]=-3;
498  ap[2][0]=+3; ap[2][1]=+3; ap[2][2]=-3;
499  ap[3][0]=+3; ap[3][1]=-3; ap[3][2]=+3;
500 
501  sinfo_msg("Before amoeba fit");
502  for(i=0;i<MP;i++) {
503  for(j=0;j<NP;j++) {
504  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
505  }
506  }
507 
508  for(i=0;i<MP;i++) {
509  p0[0]=ap[i][0];
510  p0[1]=ap[i][1];
511  p0[2]=ap[i][2];
512  y[i]=sinfo_fit_poly(p0);
513  }
514 
515  sinfo_fit_amoeba(ap,y,NP,FTOL,sinfo_fit_poly,&nfunc);
516 
517  sinfo_msg("After amoeba fit");
518  for(i=0;i<MP;i++) {
519  for(j=0;j<NP;j++) {
520  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
521  }
522  }
523 
524  check_nomsg(cpl_table_new_column(t,"FIT",CPL_TYPE_DOUBLE));
525  check_nomsg(cpl_table_fill_column_window(t,"FIT",0,np,0));
526  check_nomsg(pf=cpl_table_get_data_double(t,"FIT"));
527 
528  wd=(we-ws)/np;
529  for(i=0;i<np;i++) {
530  pw[i]=ws+i*wd;
531  pf[i]=ap[0][0]+ap[0][1]*pw[i]+ap[0][2]*pw[i]*pw[i];
532  }
533 
534  check_nomsg(cpl_table_save(t,NULL,NULL, "out_amoeba_poly.fits", 0));
535  cpl_vector_unwrap(sa_vx);
536  cpl_vector_unwrap(sa_vy);
537 
538  sinfo_free_table(&t);
539  return -1;
540  cleanup:
541  cpl_vector_unwrap(sa_vx);
542  cpl_vector_unwrap(sa_vy);
543 
544  sinfo_free_table(&t);
545  return -1;
546 
547 
548 }
549 
550 /*---------------------------------------------------------------------------*/
557 /*---------------------------------------------------------------------------*/
558 static int
559 sinfo_utl_table_test_amoeba_boltzmann(cpl_parameterlist * parlist,
560  cpl_frameset * framelist)
561 {
562 
563  cpl_table* t=NULL;
564  int np=NPOINT;
565  cpl_parameter* p=NULL;
566  const char* op=NULL;
567  double ws=0;
568  double we=0;
569  double wd=0;
570  double wshift=0;
571 
572  double* pw=NULL;
573  double* pi=NULL;
574  double* pf=NULL;
575  int i=0;
576  int j=0;
577  double a[3];
578  double p0[3];
579 
580 
581  // Amoeba fit:
582  const int MP=4;
583  const int NP=3;
584  double y[MP];
585  double** ap=NULL;
586  double FTOL=2e-6;
587  int nfunc=0;
588  double max=0;
589 
590  double bkg_min=0;
591  double bkg_max=0;
592  double p0_min=0;
593  double p0_max=0;
594  double p1_min=0;
595  double p1_max=0;
596  double p2_min=0;
597  double p2_max=0;
598 
599 
600  check(sinfo_dfs_set_groups(framelist),
601  "Cannot identify RAW and CALIB frames") ;
602 
603  // read input parameters
604  check_nomsg(p=cpl_parameterlist_find(parlist,
605  "sinfoni.sinfo_utl_table_test.method"));
606  check_nomsg(op=cpl_parameter_get_string(p));
607 
608 
609  check_nomsg(p=cpl_parameterlist_find(parlist,
610  "sinfoni.sinfo_utl_table_test.wstart"));
611  check_nomsg(ws=cpl_parameter_get_double(p)) ;
612 
613 
614  wd=(we-ws)/np;
615  check_nomsg(p=cpl_parameterlist_find(parlist,
616  "sinfoni.sinfo_utl_table_test.wend"));
617  check_nomsg(we=cpl_parameter_get_double(p)) ;
618 
619  check_nomsg(p=cpl_parameterlist_find(parlist,
620  "sinfoni.sinfo_utl_table_test.wshift"));
621  check_nomsg(wshift=cpl_parameter_get_double(p)) ;
622 
623 
624  //Prepare a template function (polynomial)
625  check_nomsg(t=cpl_table_new(np));
626  check_nomsg(cpl_table_new_column(t,"WAVE",CPL_TYPE_DOUBLE));
627  check_nomsg(cpl_table_new_column(t,"INT",CPL_TYPE_DOUBLE));
628  check_nomsg(cpl_table_fill_column_window(t,"WAVE",0,np,0));
629  check_nomsg(cpl_table_fill_column_window(t,"INT",0,np,0));
630 
631  check_nomsg(pw=cpl_table_get_data_double(t,"WAVE"));
632  check_nomsg(pi=cpl_table_get_data_double(t,"INT"));
633  ws=1.4;
634  we=2.5;
635  wd=(we-ws)/np;
636  a[2]=280;
637  a[1]=55.817665;
638  a[0]=548.77802;
639  for(i=0;i<np;i++) {
640  pw[i]=ws+i*wd;
641  pi[i]=sinfo_fac(pw[i],a[2])*(1.+0.1*rand()/RAND_MAX);
642  }
643  check_nomsg(max=cpl_table_get_column_max(t,"INT"));
644  check_nomsg(cpl_table_duplicate_column(t,"THERMAL",t,"INT"));
645  check_nomsg(cpl_table_divide_scalar(t,"THERMAL",max));
646  check_nomsg(cpl_table_multiply_scalar(t,"THERMAL",a[1]));
647  check_nomsg(cpl_table_add_scalar(t,"THERMAL",a[0]));
648 
649  check_nomsg(sa_vx=cpl_vector_wrap(np,cpl_table_get_data_double(t,"WAVE")));
650  check_nomsg(sa_vy=cpl_vector_wrap(np,cpl_table_get_data_double(t,"THERMAL")));
651  // Amoeba part
652  ap=(double**) cpl_calloc(MP,sizeof(double*));
653  for(i=0;i<MP;i++) {
654  ap[i]=cpl_calloc(NP,sizeof(double));
655  }
656 
657  for(i=0;i<MP;i++) {
658  for(j=0;j<NP;j++) {
659  ap[i][j]=0;
660  }
661  }
662  //ap[0][0]=-5;
663  //ap[1][0]=-2;
664  bkg_min=cpl_table_get_column_min(t,"THERMAL");
665  bkg_max=cpl_table_get_column_max(t,"THERMAL");
666 
667  p0_min=bkg_min/2;
668  p0_max=bkg_min*2;
669  p1_min=bkg_min/2.;
670  p1_max=bkg_max*2;
671  p1_min=200;
672  p2_max=300;
673 
674  ap[0][0]=p0_min; ap[0][1]=p1_min; ap[0][2]=p2_min;
675  ap[1][0]=p0_max; ap[1][1]=p1_min; ap[1][2]=p2_min;
676  ap[2][0]=p0_min; ap[2][1]=p1_max; ap[2][2]=p2_min;
677  ap[3][0]=p0_min; ap[3][1]=p1_min; ap[3][2]=p2_max;
678 
679  sinfo_msg("Before amoeba fit");
680  for(i=0;i<MP;i++) {
681  for(j=0;j<NP;j++) {
682  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
683  }
684  }
685 
686  for(i=0;i<MP;i++) {
687  p0[0]=ap[i][0];
688  p0[1]=ap[i][1];
689  p0[2]=ap[i][2];
690  y[i]=sinfo_fit_boltzmann(p0);
691  }
692 
693  sinfo_fit_amoeba(ap,y,NP,FTOL,sinfo_fit_boltzmann,&nfunc);
694 
695  sinfo_msg("After amoeba fit");
696  for(i=0;i<MP;i++) {
697  for(j=0;j<NP;j++) {
698  sinfo_msg("ap[%d][%d]=%g",i,j,ap[i][j]);
699  }
700  }
701 
702  check_nomsg(cpl_table_new_column(t,"FIT",CPL_TYPE_DOUBLE));
703  check_nomsg(cpl_table_fill_column_window(t,"FIT",0,np,0));
704  check_nomsg(pf=cpl_table_get_data_double(t,"FIT"));
705 
706  wd=(we-ws)/np;
707  for(i=0;i<np;i++) {
708  pw[i]=ws+i*wd;
709  pf[i]=sinfo_fac(pw[i],ap[0][2]);
710  }
711  check_nomsg(max=cpl_table_get_column_max(t,"FIT"));
712  check_nomsg(cpl_table_divide_scalar(t,"FIT",max));
713  check_nomsg(cpl_table_multiply_scalar(t,"FIT",ap[0][1]));
714  check_nomsg(cpl_table_add_scalar(t,"FIT",ap[0][0]));
715 
716  check_nomsg(cpl_table_save(t,NULL,NULL, "out_amoeba_boltzmann.fits", 0));
717 
718 
719  cleanup:
720 
721  cpl_vector_unwrap(sa_vx);
722  cpl_vector_unwrap(sa_vy);
723  sinfo_free_table(&t);
724 
725  if (cpl_error_get_code() != CPL_ERROR_NONE) {
726  return -1;
727  } else {
728  return 0;
729  }
730 
731 
732 
733 }
734 
735 
736 static cpl_table*
737 sinfo_table_shift_column_int(const cpl_table* t,
738  const char* col,
739  const double s,
740  double* r)
741 {
742  cpl_table* out=NULL;
743  int is=(int)s;
744  int nrow=0;
745  int i=0;
746 
747  double* pi=NULL;
748  double* po=NULL;
749 
750  cknull(t,"null input table");
751  out=cpl_table_duplicate(t);
752  *r=s-is;
753  nrow=cpl_table_get_nrow(t);
754  pi=cpl_table_get_data_double(t,col);
755  po=cpl_table_get_data_double(out,col);
756  sinfo_msg("shifting of %d pixels",is);
757  if(is > 0 ) {
758  for(i=0;i<nrow;i++) {
759  if( ((i-is) >=0) && ((i-is) < nrow)) {
760  po[i-is]=pi[i];
761  }
762  }
763  } else {
764  for(i=nrow-1;i>-1;i--) {
765  if( ((i-is) >=0) && ((i-is) < nrow)) {
766  po[i-is]=pi[i];
767  }
768  }
769  }
770  return out;
771  cleanup:
772  sinfo_free_table(&out);
773  return NULL;
774 
775 }
776 
777 
778 
779 static cpl_table*
780 sinfo_table_shift_column_poly(cpl_table* t,
781  const char* col,
782  const double shift,
783  const int order)
784 {
785  cpl_table* out=NULL;
786  int nrow=0;
787  int i=0;
788  int flag=0;
789  int n_points=0;
790  int firstpos=0;
791  int z=0;
792  float eval=0;
793  float sum=0;
794  float new_sum=0;
795  float* pi=NULL;
796  float* po=NULL;
797  float* spec=NULL ;
798  float* corrected_spec=NULL ;
799  float* xnum=NULL ;
800  float* tableptr=NULL;
801 
802  cknull(t,"null input table");
803  if ( order <= 0 ) {
804  sinfo_msg_error("wrong order of interpolation polynom given!") ;
805  goto cleanup;
806  }
807 
808  out=cpl_table_duplicate(t);
809 
810  nrow=cpl_table_get_nrow(t);
811  cpl_table_cast_column(t,col,"FINT",CPL_TYPE_FLOAT);
812  cpl_table_cast_column(out,col,"FINT",CPL_TYPE_FLOAT);
813  pi=cpl_table_get_data_float(t,"FINT");
814  po=cpl_table_get_data_float(out,"FINT");
815 
816  n_points = order + 1 ;
817  if ( n_points % 2 == 0 ) {
818  firstpos = (int)(n_points/2) - 1 ;
819  } else {
820  firstpos = (int)(n_points/2) ;
821  }
822  spec=cpl_calloc(nrow,sizeof(float)) ;
823  corrected_spec=cpl_calloc(nrow,sizeof(float)) ;
824  xnum=cpl_calloc(order+1,sizeof(float)) ;
825  /* fill the xa[] array for the polint function */
826  for ( i = 0 ; i < n_points ; i++ ) {
827  xnum[i] = i ;
828  }
829 
830 
831  for(i=0;i<nrow;i++) {
832  corrected_spec[i] = 0. ;
833  }
834 
835  sum = 0. ;
836  for ( z = 0 ; z < nrow ; z++ ) {
837  spec[z] = pi[z] ;
838  if (isnan(spec[z]) ) {
839  spec[z] = 0. ;
840 
841  for ( i = z - firstpos ; i < z-firstpos+n_points ; i++ ) {
842  if ( i < 0 ) continue ;
843  if ( i >= nrow) continue ;
844  corrected_spec[i] = ZERO ;
845  }
846  }
847  if ( z != 0 && z != nrow - 1 ) {
848  sum += spec[z] ;
849  }
850  }
851 
852  new_sum = 0. ;
853  for ( z = 0 ; z < nrow ; z++ ) {
854  /* ---------------------------------------------------------------
855  * now determine the arrays of size n_points with which the
856  * polynom is determined and determine the position eval
857  * where the polynom is evaluated in polynomial interpolation.
858  * Take care of the points near the row edges!
859  */
860  if (isnan(corrected_spec[z])) continue ;
861  if ( z - firstpos < 0 ) {
862  tableptr = &spec[0] ;
863  eval = shift + z ;
864  } else if ( z - firstpos + n_points >= nrow ) {
865  tableptr = &spec[nrow - n_points] ;
866  eval = shift + z + n_points - nrow ;
867  } else {
868  tableptr = &spec[z-firstpos] ;
869  eval = shift + firstpos ;
870  }
871 
872  flag=0;
873  corrected_spec[z]=sinfo_new_nev_ille(xnum,tableptr,order,eval,&flag);
874  if ( z != 0 && z != nrow - 1 ) {
875  new_sum += corrected_spec[z] ;
876  }
877  }
878 
879  /* fill the output spectrum */
880  for (z = 0 ; z < nrow ; z++ ) {
881  if ( new_sum == 0. ) {
882  new_sum = 1. ;
883  }
884  if ( z == 0 ) {
885  po[z] = ZERO ;
886  } else if ( z == nrow - 1 ) {
887  po[z] = ZERO ;
888  } else if ( isnan(corrected_spec[z]) ) {
889  po[z] = ZERO ;
890  } else {
891  corrected_spec[z] *= sum / new_sum ;
892  po[z] = corrected_spec[z] ;
893  }
894  }
895  check_nomsg(cpl_table_erase_column(t,"FINT"));
896  check_nomsg(cpl_table_erase_column(out,col));
897  check_nomsg(cpl_table_cast_column(out,"FINT",col,CPL_TYPE_DOUBLE));
898  check_nomsg(cpl_table_erase_column(out,"FINT"));
899 
900  sinfo_free_float(&spec) ;
901  sinfo_free_float(&corrected_spec) ;
902  sinfo_free_float(&xnum) ;
903 
904  return out;
905  cleanup:
906 
907 
908  sinfo_free_float(&spec) ;
909  sinfo_free_float(&corrected_spec) ;
910  sinfo_free_float(&xnum) ;
911  sinfo_free_table(&out);
912  return NULL;
913 
914 
915 }
916 
917 
918 
919 
920 static cpl_table*
921 sinfo_table_shift_column_spline3(cpl_table* t,
922  const char* col,
923  const double shift)
924 {
925  cpl_table* out=NULL;
926  int nrow=0;
927  int i=0;
928  int z=0;
929 
930  float sum=0;
931  float new_sum=0;
932 
933  float* pi=NULL;
934  float* po=NULL;
935  float* eval=NULL;
936  float* xnum=NULL;
937  float* spec=NULL;
938  float* corrected_spec=NULL;
939 
940  cknull(t,"null input table");
941  out=cpl_table_duplicate(t);
942 
943  nrow=cpl_table_get_nrow(t);
944  check_nomsg(cpl_table_cast_column(t,col,"FINT",CPL_TYPE_FLOAT));
945  check_nomsg(cpl_table_cast_column(out,col,"FINT",CPL_TYPE_FLOAT));
946  pi=cpl_table_get_data_float(t,"FINT");
947  po=cpl_table_get_data_float(out,"FINT");
948 
949 
950 
951  xnum=cpl_calloc(nrow,sizeof(float)) ;
952  /* fill the xa[] array for the spline function */
953  for ( i = 0 ; i < nrow ; i++ ) {
954  xnum[i] = i ;
955  }
956 
957  spec=cpl_calloc(nrow,sizeof(float)) ;
958  corrected_spec=cpl_calloc(nrow,sizeof(float)) ;
959  eval=cpl_calloc(nrow,sizeof(float)) ;
960 
961  sum = 0. ;
962  for ( z = 0 ; z < nrow ; z++ ) {
963  spec[z] = pi[z] ;
964  if (isnan(spec[z]) ) {
965  for ( i = z-1 ; i <= z+1 ; i++ ) {
966  if ( i < 0 ) continue ;
967  if ( i >= nrow) continue ;
968  corrected_spec[i] = ZERO ;
969  }
970  spec[z] = 0. ;
971  }
972  sum += spec[z] ;
973  eval[z] = (float)shift+(float)z ;
974  }
975  /* now we do the spline interpolation*/
976  if ( -1 == sinfo_function1d_natural_spline(xnum,spec, nrow,
977  eval,corrected_spec, nrow))
978  {
979  sinfo_msg_error("error in spline interpolation!") ;
980  goto cleanup;
981  }
982 
983  new_sum = 0. ;
984  for ( z = 0 ; z < nrow ; z++ ) {
985  if ( isnan(corrected_spec[z]) ) {
986  continue ;
987  }
988  new_sum += corrected_spec[z] ;
989  }
990  /* fill output imagelist */
991  for ( z = 0 ; z < nrow ; z++ ) {
992  if ( new_sum == 0. ) new_sum =1. ;
993  {
994  if ( isnan(corrected_spec[z]) ) {
995  po[z] = ZERO ;
996  } else {
997  corrected_spec[z] *= sum / new_sum ;
998  po[z] = corrected_spec[z] ;
999  }
1000  }
1001  }
1002 
1003  sinfo_free_float(&xnum);
1004  sinfo_free_float(&spec) ;
1005  sinfo_free_float(&corrected_spec) ;
1006  sinfo_free_float(&eval) ;
1007 
1008  check_nomsg(cpl_table_erase_column(t,"FINT"));
1009  check_nomsg(cpl_table_erase_column(out,col));
1010  check_nomsg(cpl_table_cast_column(out,"FINT",col,CPL_TYPE_DOUBLE));
1011  check_nomsg(cpl_table_erase_column(out,"FINT"));
1012 
1013  return out;
1014  cleanup:
1015 
1016  sinfo_free_float(&xnum);
1017  sinfo_free_float(&spec) ;
1018  sinfo_free_float(&corrected_spec) ;
1019  sinfo_free_float(&eval) ;
1020  sinfo_free_table(&out);
1021  return NULL;
1022 
1023 
1024 }
1025 
1026 
1027 static cpl_table*
1028 sinfo_table_shift_simple(cpl_table* inp,
1029  const char* col,
1030  const double shift)
1031 {
1032 
1033  int nrow=0;
1034  cpl_table* out=NULL;
1035  int is=(int)shift;
1036  double ds=shift-is;
1037  double* pi=NULL;
1038  double* po=NULL;
1039  double m=0;
1040  int i=0;
1041  cknull(inp,"null input table");
1042 
1043  check_nomsg(nrow=cpl_table_get_nrow(inp));
1044  check_nomsg(out=cpl_table_duplicate(inp));
1045  check_nomsg(cpl_table_fill_column_window(out,col,0,nrow,0));
1046  check_nomsg(pi=cpl_table_get_data_double(inp,col));
1047  check_nomsg(po=cpl_table_get_data_double(out,col));
1048 
1049 
1050  for(i=0;i<nrow;i++) {
1051  if((i+is)>0 && (i+is+1) < nrow) {
1052  m=pi[i+is+1]-pi[i+is];
1053  po[i]=pi[i+is]+m*ds;
1054  }
1055  }
1056  return out;
1057  cleanup:
1058  sinfo_free_table(&out);
1059  return NULL;
1060 
1061 }
1062 
1063 
1064 /*-------------------------------------------------------------------------*/
1071 /*--------------------------------------------------------------------------*/
1072 
1073 static double
1074 sinfo_fit_poly(double p[])
1075 
1076 {
1077 
1078  double* px=NULL;
1079  double* py=NULL;
1080 
1081  int i=0;
1082  int np=0;
1083 
1084  double fy=0;
1085  double chi2=0;
1086 
1087  check_nomsg(px= cpl_vector_get_data(sa_vx));
1088  check_nomsg(py= cpl_vector_get_data(sa_vy));
1089  check_nomsg(np= cpl_vector_get_size(sa_vx));
1090 
1091  for(i=0;i<np;i++) {
1092  //fy=(px[i]-p[0])*(px[i]-p[0]);
1093  fy=p[0]+p[1]*px[i]+p[2]*px[i]*px[i];
1094  chi2+=(py[i]-fy)*(py[i]-fy);
1095  }
1096 
1097  return chi2;
1098  cleanup:
1099  return -1;
1100 
1101 }
1102 
1103 static double
1104 sinfo_fit_boltzmann(double p[])
1105 
1106 {
1107 
1108  double* px=NULL;
1109  double* py=NULL;
1110  double* pv=NULL;
1111  cpl_vector* vtmp=NULL;
1112  double max=0;
1113  int i=0;
1114  int np=0;
1115 
1116  double chi2=0;
1117 
1118  check_nomsg(px= cpl_vector_get_data(sa_vx));
1119  check_nomsg(py= cpl_vector_get_data(sa_vy));
1120  check_nomsg(np= cpl_vector_get_size(sa_vx));
1121  check_nomsg(vtmp=cpl_vector_duplicate(sa_vy));
1122  check_nomsg(pv=cpl_vector_get_data(vtmp));
1123 
1124  for(i=0;i<np;i++) {
1125  pv[i]=sinfo_fac(px[i],p[2]);
1126  //sinfo_msg("x=%g p=%g",px[i],pv[i]);
1127  }
1128  check_nomsg(max=cpl_vector_get_max(vtmp));
1129  if(max> 0) {
1130  check_nomsg(cpl_vector_divide_scalar(vtmp,max));
1131  check_nomsg(cpl_vector_multiply_scalar(vtmp,p[1]));
1132  check_nomsg(cpl_vector_add_scalar(vtmp,p[0]));
1133  }
1134 
1135 
1136  for(i=0;i<np;i++) {
1137  chi2+=(py[i]-pv[i])*(py[i]-pv[i]);
1138  }
1139 
1140  return chi2;
1141  cleanup:
1142  return -1;
1143 
1144 }
1145 
1146 static int
1147 sinfo_fitbkg(const double x[],
1148  const double a[],
1149  double *result)
1150 {
1151 
1152  double fac = sinfo_fac(x[0],a[2]);
1153  *result = a[0]+a[1]*fac;
1154 
1155  return 0;
1156 }
1157 
1158 static double
1159 sinfo_fac(const double x, const double t)
1160 {
1161 
1162  double c=14387.7;
1163 
1164  /* replaced pow(x,-5.)/(exp(c/(x*fabs(t)))-1.); by
1165  * pow(x,-5.)/(expm1(c/(x*fabs(t))));
1166  * to get better accuracty if x is very small
1167  */
1168  return pow(x,-5.)/(expm1(c/(x*fabs(t))));
1169 }
1170 
1171