SINFONI Pipeline Reference Manual  2.6.0
sinfo_new_cube_ops.c
1 /*$Id: sinfo_new_cube_ops.c,v 1.47 2013-08-02 14:11:23 amodigli Exp $
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 /*************************************************************************
20  * E.S.O. - VLT project
21  *
22  *
23  *
24  * who when what
25  * -------- -------- ----------------------------------------------
26  * schreib 17/05/00 created
27  */
28 /*
29  * $Author: amodigli $
30  * $Date: 2013-08-02 14:11:23 $
31  * $Revision: 1.47 $
32  * $Name: not supported by cvs2svn $
33  */
34 
35 /************************************************************************
36  * NAME
37  * sinfo_new_cube_ops.c -
38  * cube arithmetic routines
39  *
40  * SYNOPSIS
41  * #include "sinfo_new_cube_ops.h"
42  *
43  *
44  *
45  * 2) cpl_imagelist *
46  * sinfo_new_cube_ops( cpl_imagelist * cube1,
47  * cpl_imagelist * cube2,
48  * int operation)
49  *
50  * 3) cpl_imagelist *
51  * sinfo_new_cube_const_ops(
52  * cpl_imagelist * cube1,
53  * double constant,
54  * int operation)
55  *
56  * 4) cpl_imagelist *
57  * sinfo_new_cube_sub(
58  * cpl_imagelist * c1,
59  * cpl_imagelist * c2 )
60  *
61  * 5) cpl_imagelist *
62  * sinfo_new_cube_add(
63  * cpl_imagelist * c1,
64  * cpl_imagelist * c2 )
65  * 6) cpl_imagelist *
66  * sinfo_new_cube_mul(
67  * cpl_imagelist * c1,
68  * cpl_imagelist * c2 )
69  *
70  * 7) cpl_imagelist *
71  * sinfo_new_cube_div(
72  * cpl_imagelist * c1,
73  * cpl_imagelist * c2 )
74  *
75  * 8) cpl_imagelist * sinfo_new_add_image_to_cube(cpl_imagelist * cu,
76  cpl_image * im)
77  *
78  * 9) cpl_imagelist * sinfo_new_sub_image_from_cube (cpl_imagelist * cu,
79  cpl_image * im)
80  *
81  * 10) cpl_imagelist * sinfo_new_mul_image_to_cube(cpl_imagelist * cu,
82  cpl_image * im)
83  *
84  * 11) cpl_imagelist * sinfo_new_div_cube_by_image(cpl_imagelist * cu,
85  cpl_image * im)
86  *
87  * 12) cpl_imagelist * sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu,
88  Vector *spec)
89  *
90  * 13) cpl_imagelist * sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu,
91  Vector *spec)
92  *
93  * 14) cpl_imagelist * sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu,
94  Vector *spec)
95  *
96  * 15) cpl_imagelist * sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu,
97  Vector *spec)
98  *
99  * 16) Vector * sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
100  * int llx,
101  * int lly,
102  * int urx,
103  * int ury,
104  * double lo_reject,
105  * double hi_reject)
106  *
107  * 17) cpl_image * sinfo_new_median_cube(cpl_imagelist * cube)
108  *
109  * 18) cpl_image * sinfo_new_average_cube_to_image(cpl_imagelist * cube)
110  *
111  * 19) cpl_image * sinfo_new_sum_cube_to_image(cpl_imagelist * cube)
112  *
113  * 20) cpl_image *
114  sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
115  * float dispersion,
116  * float centralWave,
117  * float initialLambda,
118  * float finalLambda)
119  *
120  * 21) cpl_image * sinfo_new_extract_image_from_cube(cpl_imagelist * cube,
121  int plane_index)
122  *
123  * 22) Vector * sinfo_new_extract_spectrum_from_cube( cpl_imagelist * cube,
124  int x_pos, int y_pos )
125  * 23) cpl_imagelist *
126  sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
127  * cpl_imagelist * mergedCube,
128  * int n_cubes,
129  * float * cumoffsetx,
130  * float * cumoffsety,
131  * float * exptimes,
132  * char * kernel_type )
133  * 24) cpl_imagelist * sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
134  * cpl_imagelist * badcube,
135  * int maxdist )
136  *
137  *
138  * 25) cpl_imagelist * sinfo_cube_zshift(const cpl_imagelist * cube,
139  * const double shift,
140  * double* rest)
141  *
142  * 26) cpl_imagelist * sinfo_cube_zshift_poly(const cpl_imagelist * cube,
143  * const double shift,
144  * const int order)
145  *
146  * 27) cpl_imagelist * sinfo_cube_zshift_spline3(const cpl_imagelist * cube,
147  * const double shift)
148  *
149  *
150  *
151  *
152  * DESCRIPTION
153  * 2) 4 operations between 2 cubes
154  * 3) 4 operations between a cube and a constant
155  * 4) subtract one cube from another
156  * 5) add a cube to another
157  * 6) multiply two cubes
158  * 7) divide two cubes
159  * 8) add an image to all planes in the cube
160  * 9) subtract an image from all planes in the cube
161  * 10) multiply an image to all planes in the cube
162  * 11) divide all planes in the cube by an image
163  * 12) adds a spectrum (in z-direction) to all data
164  * points in a cube
165  * 13) subtracts a spectrum (in z-direction) from all
166  * data points in a cube
167  * 14) multiplies a spectrum (in z-direction) to all data
168  * points in a cube
169  * 15) divides all data points of a cube by a spectrum
170  * (in z-direction)
171  * 16) averaging routine to get a better spectral S/N, sorts
172  * the values of the same z-position, cuts the lowest and
173  * highest values according to given thresholds and then
174  * takes the average within the x-y plane , cannot have
175  * a sum of low and high rejected values greater than 90%
176  * of all values
177  * 17) determines the sinfo_new_median value in every pixel position
178  * by considering all pixels along the third axis.
179  * ZERO pixels in a plane are not considered. If all
180  * pixels at a position are not valid the result will
181  * be 'ZERO'.
182  * 18) determines the average value in every pixel position
183  * by considering all pixels along the third axis.
184  * ZERO pixels in a plane are not considered. If all
185  * pixels at a position are not valid the result will
186  * be 'ZERO'.
187  * 19) determines the sum value in every pixel position
188  * by considering all pixels along the third axis.
189  * ZERO pixels in a plane are not considered. If all
190  * pixels at a position are not valid the result will
191  * be 'ZERO'.
192  * 20) determines the average value in every pixel position
193  * by considering only the pixels along the third axis
194  * which lie between the given wavelength values.
195  * These values are first recalculated to plane indices
196  * by using the given dispersion and minimum wavelength in
197  * the cube.
198  * ZERO pixels in a plane are not considered. If all
199  * pixels at a position are not valid the result will
200  * be 'ZERO'.
201  * 21) returns the wanted image plane of the cube
202  * 22) returns the wanted single spectrum of the cube
203  * 23) merges jittered data cubes to one bigger cube
204  * by averaging the overlap regions weighted by
205  * the integration times. The x, y size of the final data
206  * cube is user given, and should be between 32 and 64
207  * pixels, while the relative pixel-offset (sub-pixel
208  * accuracy) of the single cubes with respect to the
209  * first cube in the list is read from the SEQ CUMOFFSETX,Y
210  * fits header keyword.
211  * 24) interpolates bad pixel of an object cube if a bad pixel
212  * mask cube is available by using the nearest neighbors
213  * in 3 dimensions.
214  *
215  * 25) shifts an imagelist by a given amount to integer pixel accuracy
216  * 26) shifts an imagelist by a given amount to sub-pixel accuracy
217  * 27) shifts an imagelist by a given amount to sub-pixel accuracy
218  * FILES
219  *
220  * ENVIRONMENT
221  *
222  * RETURN VALUES
223  *
224  * CAUTIONS
225  *
226  * EXAMPLES
227  *
228  * SEE ALSO
229  *
230  * BUGS
231  *
232  *------------------------------------------------------------------------
233  */
234 #ifdef HAVE_CONFIG_H
235 # include <config.h>
236 #endif
237 
238 #include "sinfo_vltPort.h"
239 
240 /*
241  * System Headers
242  */
243 
244 #include <sys/types.h>
245 #include <sys/times.h>
246 #include <math.h>
247 /*
248  * Local Headers
249  */
250 #include "sinfo_dfs.h"
251 #include "sinfo_new_cube_ops.h"
252 #include "sinfo_resampling.h"
253 #include "sinfo_function_1d.h"
254 #include "sinfo_error.h"
255 #include "sinfo_globals.h"
256 #include "sinfo_utils_wrappers.h"
257 
258 #include <cpl_vector.h>
259 /*----------------------------------------------------------------------------
260  * Function codes
261  *--------------------------------------------------------------------------*/
262 
263 
264 static int
265 sinfo_shift_cubes(cpl_imagelist** tmpcubes,
266  char* kernel_type,
267  const int n_cubes,
268  cpl_imagelist** cubes,
269  const int z_min,
270  const int z_max,
271  float* sub_offsetx,
272  float* sub_offsety,
273  const int mlx,
274  const int mly,
275  cpl_imagelist* mask);
276 
277 static int
278 sinfo_build_mask_cube(const int z_min,
279  const int z_max,
280  const int olx,
281  const int oly,
282  const int n_cubes,
283  const int* llx,
284  const int* lly,
285  double * exptimes,
286  cpl_imagelist** cubes,
287  cpl_imagelist** tmpcubes,
288  cpl_imagelist* mask);
289 
290 static int
291 sinfo_build_mask_cube_thomas(const int z_min,
292  const int z_max,
293  const int olx,
294  const int oly,
295  const int n_cubes,
296  const int* llx,
297  const int* lly,
298  double * exptimes,
299  cpl_imagelist** cubes,
300  cpl_imagelist** tmpcubes,
301  cpl_imagelist* mask);
302 static int
303 sinfo_compute_weight_average(const int z_min,
304  const int z_max,
305  const int ilx,
306  const int ily,
307  const int n_cubes,
308  cpl_imagelist* mergedCube,
309  cpl_imagelist* mask,
310  cpl_imagelist** tmpcubes,
311  double* exptimes,
312  int* llx,
313  int* lly);
314 
315 static int
316 sinfo_check_input(cpl_imagelist** cubes,
317  const int n_cubes,
318  float* cumoffsetx,
319  float* cumoffsety,
320  double* exptimes);
321 static int
322 sinfo_coadd_with_ks_clip2(const int z_min,
323  const int z_max,
324  const int ilx,
325  const int ily,
326  const int n_cubes,
327  const double kappa,
328  int* llx,
329  int* lly,
330  double* exptimes,
331  cpl_imagelist* mask,
332  cpl_imagelist* mergedCube,
333  cpl_imagelist** tmpcubes);
334 
335 
336 /* temporally commented out as not yet used
337 static int
338 sinfo_ks_clip(
339  const int n_cubes,
340  const int nc,
341  const int ilx,
342  const int ily,
343  const double kappa,
344  int* llx,
345  int* lly,
346  double* exptimes,
347  cpl_imagelist** tmpcubes,
348  float* podata,
349  float* pmdata,
350  const int x,
351  const int y,
352  const int m,
353  const int mlx,
354  const int olx
355  );
356 
357 
358  */
359 
360 static int
361 sinfo_coadd_with_ks_clip(const int z_min,
362  const int z_max,
363  const int ilx,
364  const int ily,
365  const int n_cubes,
366  const double kappa,
367  int* llx,
368  int* lly,
369  double* exptimes,
370  cpl_imagelist* mask,
371  cpl_imagelist* mergedCube,
372  cpl_imagelist** tmpcubes);
373 
374 
398 /* TODO: not used */
399 cpl_imagelist *
400 sinfo_new_cube_ops(
401  cpl_imagelist * cube1,
402  cpl_imagelist * cube2,
403  int operation)
404 {
405 
406  if (cube1==NULL || cube2==NULL)
407  {
408  sinfo_msg_error("null cubes");
409  return NULL ;
410  }
411 
412  switch(operation)
413  {
414  case '+':
415  return sinfo_new_cube_add(cube1, cube2) ;
416 
417  case '-':
418  return sinfo_new_cube_sub(cube1, cube2) ;
419 
420 
421  case '*':
422  return sinfo_new_cube_mul(cube1, cube2) ;
423 
424 
425  case '/':
426  return sinfo_new_cube_div(cube1, cube2) ;
427 
428 
429  default:
430  sinfo_msg_error("illegal requested operation: aborting cube arithmetic") ;
431  return NULL ;
432  }
433 }
434 
435 
436 /*----------------------------------------------------------------------------
437  Function : sinfo_new_cube_const_ops()
438  In : 1 cube, 1 constant, operation to perform
439  Out : result cube
440  Job : 4 operations between a cube and a constant
441  Notice : possible operations are:
442  Addition '+'
443  Subtraction '-'
444  Multiplication '*'
445  Division '/'
446  Logarithm 'l'
447  Power '^'
448  Exponentiation 'e'
449 
450  ---------------------------------------------------------------------------*/
451 /* TODO: not used */
452 cpl_imagelist *
453 sinfo_new_cube_const_ops(
454  cpl_imagelist * c1,
455  double constant,
456  int operation)
457 {
458  /*
459  int ilx1=0;
460  int ily1=0;
461  int inp1=0;
462  */
463  cpl_imagelist* c2=NULL;
464  //cpl_image* img1=NULL;
465 
466 
467 
468  if (c1 == NULL)
469  {
470  sinfo_msg_error("null cube") ;
471  return NULL ;
472  }
473  //inp1=cpl_imagelist_get_size(c1);
474  //img1=cpl_imagelist_get(c1,0);
475  //ilx1=cpl_image_get_size_x(img1);
476  //ily1=cpl_image_get_size_y(img1);
477 
478 
479 
480 
481 
482  if ((constant == 0.0) && (operation == '/'))
483  {
484  sinfo_msg_error("division by zero requested "
485  "in cube/constant operation") ;
486  return NULL ;
487  }
488  /*
489  if ( NULL == (c2 = cpl_imagelist_new()) )
490  {
491  sinfo_msg_error ("cannot allocate new cube" ) ;
492  return NULL ;
493  }
494  */
495  c2=cpl_imagelist_duplicate(c1);
496  if(operation == '+') {
497  cpl_imagelist_add_scalar(c2,constant);
498  } else if (operation == '-') {
499  cpl_imagelist_subtract_scalar(c2,constant);
500  } else if (operation == '*') {
501  cpl_imagelist_multiply_scalar(c2,constant);
502  } else if (operation == '/') {
503  cpl_imagelist_divide_scalar(c2,constant);
504 
505  } else {
506  sinfo_free_imagelist(&c2);
507  sinfo_msg_error("operation not supported");
508  return NULL;
509  }
510  return c2 ;
511 }
512 
513 
514 /*----------------------------------------------------------------------------
515  * Function : sinfo_new_cube_sub()
516  * In : two cubes
517  * Out : result cube
518  * Job : subtract one cube from another
519  *--------------------------------------------------------------------------*/
520 
521 cpl_imagelist *
522 sinfo_new_cube_sub(
523  cpl_imagelist * c1,
524  cpl_imagelist * c2
525 )
526 {
527  cpl_imagelist * c3 ;
528  ulong32 i ;
529  int np ;
530  int ilx1=0;
531  int ily1=0;
532  int inp1=0;
533  int ilx2=0;
534  int ily2=0;
535  int inp2=0;
536 
537  cpl_image* i_img=NULL;
538 
539  inp1=cpl_imagelist_get_size(c1);
540  i_img=cpl_imagelist_get(c1,0);
541  ilx1=cpl_image_get_size_x(i_img);
542  ily1=cpl_image_get_size_y(i_img);
543 
544 
545  inp2=cpl_imagelist_get_size(c2);
546  i_img=cpl_imagelist_get(c2,0);
547  ilx2=cpl_image_get_size_x(i_img);
548  ily2=cpl_image_get_size_y(i_img);
549 
550  if ((ilx1 != ilx2) ||
551  (ily1 != ily2))
552  {
553  sinfo_msg_error("incompatible size: cannot subtract") ;
554  return NULL ;
555  }
556 
557  if ((inp2 != inp1) &&
558  (inp2 != 1))
559  {
560  sinfo_msg_error("cannot compute with these number of planes") ;
561  return NULL ;
562  }
563 
564  if ( NULL == (c3 = cpl_imagelist_new()) )
565  {
566  sinfo_msg_error ("cannot allocate new cube" ) ;
567  return NULL ;
568  }
569  cpl_image* img3=NULL;
570  for (np=0 ; np < inp1 ; np++)
571  {
572  img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
573  cpl_imagelist_set(c3,img3,np);
574  }
575 
576  for (np=0 ; np < inp1 ; np++)
577  {
578  cpl_image* img1=cpl_imagelist_get(c1,np);
579  float* p1data=cpl_image_get_data_float(img1);
580  cpl_image* img2=cpl_imagelist_get(c2,np);
581  float* p2data=cpl_image_get_data_float(img2);
582  img3=cpl_imagelist_get(c3,np);
583  float* p3data=cpl_image_get_data_float(img3);
584 
585  for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
586  {
587  p3data[i] = p1data[i] - p2data[i] ;
588  }
589  }
590 
591  return c3 ;
592 }
593 
594 
595 /*----------------------------------------------------------------------------
596  * Function : sinfo_new_cube_add()
597  * In : two cubes
598  * Out : result cube
599  * Job : add a cube to another
600  *--------------------------------------------------------------------------*/
601 
602 cpl_imagelist *
603 sinfo_new_cube_add(
604  cpl_imagelist * c1,
605  cpl_imagelist * c2
606 )
607 {
608  cpl_imagelist * c3 ;
609  ulong32 i ;
610  int np ;
611  int ilx1=0;
612  int ily1=0;
613  int inp1=0;
614  int ilx2=0;
615  int ily2=0;
616  int inp2=0;
617 
618 
619  cpl_image* i_img=NULL;
620  cpl_image* img3=NULL;
621 
622  inp1=cpl_imagelist_get_size(c1);
623  i_img=cpl_imagelist_get(c1,0);
624  ilx1=cpl_image_get_size_x(i_img);
625  ily1=cpl_image_get_size_y(i_img);
626 
627  inp2=cpl_imagelist_get_size(c2);
628  i_img=cpl_imagelist_get(c2,0);
629  ilx2=cpl_image_get_size_x(i_img);
630  ily2=cpl_image_get_size_y(i_img);
631  if ((ilx1 != ilx2) || (ily1 != ily2))
632  {
633  sinfo_msg_error("incompatible size: cannot add") ;
634  return NULL ;
635  }
636  if ((inp2 != inp1) && (inp2 != 1))
637  {
638  sinfo_msg_error("cannot compute with these number of planes") ;
639  return NULL ;
640  }
641 
642  if (NULL == (c3 = cpl_imagelist_new()) )
643  {
644  sinfo_msg_error ("cannot allocate new cube") ;
645  return NULL ;
646  }
647 
648  for (np=0 ; np < inp1 ; np++)
649  {
650  img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
651  cpl_imagelist_set(c3,img3,np);
652  }
653 
654 
655  for (np=0 ; np < inp1 ; np++)
656  {
657  cpl_image* img1=cpl_imagelist_get(c1,np);
658  float* p1data=cpl_image_get_data_float(img1);
659  cpl_image* img2=cpl_imagelist_get(c2,np);
660  float* p2data=cpl_image_get_data_float(img2);
661  img3=cpl_imagelist_get(c3,np);
662  float* p3data=cpl_image_get_data_float(img3);
663  for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
664  {
665  p3data[i] = p1data[i] + p2data[i] ;
666  }
667  }
668 
669  return c3 ;
670 }
671 
672 /*----------------------------------------------------------------------------
673  * Function : sinfo_new_cube_mul()
674  * In : two cubes
675  * Out : result cube
676  * Job : multiply 2 cubes
677  *--------------------------------------------------------------------------*/
678 
679 cpl_imagelist *
680 sinfo_new_cube_mul(
681  cpl_imagelist * c1,
682  cpl_imagelist * c2
683 )
684 {
685  cpl_imagelist *c3 ;
686  ulong32 i ;
687  int np ;
688  int ilx1=0;
689  int ily1=0;
690  int inp1=0;
691  int ilx2=0;
692  int ily2=0;
693  int inp2=0;
694 
695 
696  cpl_image* i_img=NULL;
697 
698  inp1=cpl_imagelist_get_size(c1);
699  i_img=cpl_imagelist_get(c1,0);
700  ilx1=cpl_image_get_size_x(i_img);
701  ily1=cpl_image_get_size_y(i_img);
702 
703  inp2=cpl_imagelist_get_size(c2);
704  i_img=cpl_imagelist_get(c2,0);
705  ilx2=cpl_image_get_size_x(i_img);
706  ily2=cpl_image_get_size_y(i_img);
707 
708  if ((ilx1 != ilx2) || (ily1 != ily2))
709  {
710  sinfo_msg_error("incompatible size: cannot multiply") ;
711  return NULL ;
712  }
713 
714  if ((inp2 != inp1) && (inp2 != 1))
715  {
716  sinfo_msg_error("cannot compute with these number of planes") ;
717  return NULL ;
718  }
719 
720  if ( NULL == (c3 = cpl_imagelist_new()) )
721  {
722  sinfo_msg_error ("cannot allocate new cube" ) ;
723  return NULL ;
724  }
725 
726  cpl_image* img3=NULL;
727  for (np=0 ; np < inp1 ; np++)
728  {
729  img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
730  cpl_imagelist_set(c3,img3,np);
731  }
732 
733 
734  for (np=0 ; np < inp1 ; np++)
735  {
736  cpl_image* img1=cpl_imagelist_get(c1,np);
737  float* p1data=cpl_image_get_data_float(img1);
738  cpl_image* img2=cpl_imagelist_get(c2,np);
739  float* p2data=cpl_image_get_data_float(img2);
740  img3=cpl_imagelist_get(c3,np);
741  float* p3data=cpl_image_get_data_float(img3);
742  for (i=0 ; i< (ulong32)ilx1*ilx2 ; i++)
743  {
744  p3data[i] = p1data[i] * p2data[i] ;
745  }
746  }
747 
748  return c3 ;
749 }
750 
751 
752 /*----------------------------------------------------------------------------
753  * Function : sinfo_new_cube_div()
754  * In : two cubes
755  * Out : result cube
756  * Job : divide 2 cubes
757  *--------------------------------------------------------------------------*/
758 
759 cpl_imagelist *
760 sinfo_new_cube_div(
761  cpl_imagelist * c1,
762  cpl_imagelist * c2
763 )
764 {
765  cpl_imagelist * c3 ;
766  ulong32 i ;
767  int np ;
768  int ilx1=0;
769  int ily1=0;
770  int inp1=0;
771  int ilx2=0;
772  int ily2=0;
773  int inp2=0;
774 
775  cpl_image* i_img=NULL;
776 
777  inp1=cpl_imagelist_get_size(c1);
778  i_img=cpl_imagelist_get(c1,0);
779  ilx1=cpl_image_get_size_x(i_img);
780  ily1=cpl_image_get_size_y(i_img);
781 
782  inp2=cpl_imagelist_get_size(c2);
783  i_img=cpl_imagelist_get(c2,0);
784  ilx2=cpl_image_get_size_x(i_img);
785  ily2=cpl_image_get_size_y(i_img);
786 
787  if ((ilx1 != ilx2) ||
788  (ily1 != ily2))
789  {
790  sinfo_msg_error("incompatible size: cannot divide") ;
791  return NULL ;
792  }
793 
794  if ((inp2 != inp1) && (inp2 != 1))
795  {
796  sinfo_msg_error("cannot compute with these number of planes") ;
797  return NULL ;
798  }
799 
800  if (NULL == (c3 = cpl_imagelist_new()) )
801  {
802  sinfo_msg_error ("cannot allocate a new cube") ;
803  return NULL ;
804  }
805 
806  cpl_image* img3=NULL;
807  for (np=0 ; np < inp1 ; np++)
808  {
809  img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
810  cpl_imagelist_set(c3,img3,np);
811  }
812 
813  for (np=0 ; np < inp1 ; np++)
814  {
815  cpl_image* img1=cpl_imagelist_get(c1,np);
816  float* p1data=cpl_image_get_data_float(img1);
817  cpl_image* img2=cpl_imagelist_get(c2,np);
818  float* p2data=cpl_image_get_data_float(img2);
819  img3=cpl_imagelist_get(c3,np);
820  float* p3data=cpl_image_get_data_float(img3);
821 
822 
823  for (i=0 ; i< (ulong32) ilx1*ily1 ; i++)
824  {
825  if (fabs((double)p2data[i]) < 1e-10)
826  {
827  p3data[i] = 0.0 ;
828  }
829  else
830  {
831  p3data[i] = p1data[i] / p2data[i] ;
832  }
833  }
834  }
835 
836  return c3 ;
837 }
838 
839 
840 
841 /*---------------------------------------------------------------------------
842  Function : sinfo_new_add_image_to_cube()
843  In : 1 allocated cube, 1 allocated image
844  Out : result cube
845  Job : add an image to all planes in the cube
846  ---------------------------------------------------------------------------*/
847 
848 cpl_imagelist *
849 sinfo_new_add_image_to_cube(cpl_imagelist * cu, cpl_image * im)
850 {
851  cpl_imagelist * cube ;
852  int i ;
853  int clx=0;
854  int cly=0;
855  int cnp=0;
856  int ilx=0;
857  int ily=0;
858 
859 
860  cpl_image* i_img=NULL;
861 
862  if (cu==NULL || im==NULL)
863  {
864  sinfo_msg_error ("null cube or null image") ;
865  return NULL ;
866  }
867  cnp=cpl_imagelist_get_size(cu);
868  i_img=cpl_imagelist_get(cu,0);
869  clx=cpl_image_get_size_x(i_img);
870  cly=cpl_image_get_size_y(i_img);
871 
872  ilx=cpl_image_get_size_x(im);
873  ily=cpl_image_get_size_y(im);
874 
875  if ((clx != ilx) || (cly != ily))
876  {
877  sinfo_msg_error("incompatible size: cannot add image to cube") ;
878  return NULL ;
879  }
880 
881  cube = cpl_imagelist_duplicate (cu) ;
882 
883  for (i=0 ; i<cnp ; i++)
884  {
885  /* AMO
886  here may be we have to use cpl_image_add_create and cpl_imagelist_set
887  */
888  cpl_image_add(cpl_imagelist_get(cube,i), im) ;
889  }
890 
891  return cube ;
892 }
893 
894 /*---------------------------------------------------------------------------
895  Function : sinfo_new_sub_image_from_cube()
896  In : 1 allocated cube, 1 allocated image
897  Out : result cube
898  Job : subtract an image from all planes in the cube
899  ---------------------------------------------------------------------------*/
900 
901 cpl_imagelist *
902 sinfo_new_sub_image_from_cube (cpl_imagelist * cu, cpl_image * im)
903 {
904  cpl_imagelist * cube ;
905  int i ;
906  int clx=0;
907  int cly=0;
908  int cnp=0;
909  int ilx=0;
910  int ily=0;
911 
912 
913  cpl_image* i_img=NULL;
914 
915  if (cu==NULL || im==NULL)
916  {
917  sinfo_msg_error ("null cube or null image") ;
918  return NULL ;
919  }
920  cnp=cpl_imagelist_get_size(cu);
921  i_img=cpl_imagelist_get(cu,0);
922  clx=cpl_image_get_size_x(i_img);
923  cly=cpl_image_get_size_y(i_img);
924 
925  ilx=cpl_image_get_size_x(im);
926  ily=cpl_image_get_size_y(im);
927 
928  if ((clx != ilx) || (cly != ily))
929  {
930 
931  sinfo_msg_error("incompatible size: cannot subtract image from cube") ;
932  return NULL ;
933  }
934 
935  cube = cpl_imagelist_duplicate (cu) ;
936 
937  for (i=0 ; i<cnp ; i++)
938  {
939  /* AMO
940  here may be we have to use cpl_image_add_create and cpl_imagelist_set
941  */
942  cpl_image_subtract(cpl_imagelist_get(cube,i), im) ;
943  }
944  return cube ;
945 }
946 
947 /*---------------------------------------------------------------------------
948  Function : sinfo_new_mul_image_to_cube()
949  In : 1 allocated cube, 1 allocated image
950  Out : result cube
951  Job : multiply an image to all planes in the cube
952  ---------------------------------------------------------------------------*/
953 
954 cpl_imagelist *
955 sinfo_new_mul_image_to_cube(cpl_imagelist * cu, cpl_image * im)
956 {
957  cpl_imagelist * cube ;
958  int i ;
959  int clx=0;
960  int cly=0;
961  int cnp=0;
962  int ilx=0;
963  int ily=0;
964 
965 
966  cpl_image* i_img=NULL;
967 
968  if (cu==NULL || im==NULL)
969  {
970  sinfo_msg_error("null cube or null image") ;
971  return NULL ;
972  }
973  cnp=cpl_imagelist_get_size(cu);
974  i_img=cpl_imagelist_get(cu,0);
975  clx=cpl_image_get_size_x(i_img);
976  cly=cpl_image_get_size_y(i_img);
977 
978  ilx=cpl_image_get_size_x(im);
979  ily=cpl_image_get_size_y(im);
980 
981  if ((clx != ilx) || (cly != ily))
982  {
983  sinfo_msg_error("incompatible size: cannot multiply image by cube") ;
984  return NULL ;
985  }
986 
987  cube = cpl_imagelist_duplicate (cu) ;
988 
989  for (i=0 ; i<cnp ; i++)
990  {
991  /* AMO
992  here may be we have to use cpl_image_add_create and cpl_imagelist_set
993  */
994  cpl_image_multiply(cpl_imagelist_get(cube,i), im) ;
995  }
996 
997  return cube ;
998 }
999 
1000 /*---------------------------------------------------------------------------
1001  Function : sinfo_new_div_cube_by_image()
1002  In : 1 allocated cube, 1 allocated image
1003  Out : result cube
1004  Job : divide all planes in the cube by an image
1005  ---------------------------------------------------------------------------*/
1006 
1007 cpl_imagelist *
1008 sinfo_new_div_cube_by_image(cpl_imagelist * cu, cpl_image * im)
1009 {
1010  cpl_imagelist * cube ;
1011  int i ;
1012  int clx=0;
1013  int cly=0;
1014  int cnp=0;
1015  int ilx=0;
1016  int ily=0;
1017 
1018 
1019  cpl_image* i_img=NULL;
1020 
1021  if (cu==NULL || im==NULL)
1022  {
1023  sinfo_msg_error ("null cube or null image") ;
1024  return NULL ;
1025  }
1026  cnp=cpl_imagelist_get_size(cu);
1027  i_img=cpl_imagelist_get(cu,0);
1028  clx=cpl_image_get_size_x(i_img);
1029  cly=cpl_image_get_size_y(i_img);
1030 
1031  ilx=cpl_image_get_size_x(im);
1032  ily=cpl_image_get_size_y(im);
1033 
1034  if ((clx != ilx) || (cly != ily))
1035  {
1036  sinfo_msg_error("incompatible size: cannot divide cube by image") ;
1037  return NULL ;
1038  }
1039 
1040  cube = cpl_imagelist_duplicate (cu) ;
1041 
1042  for (i=0 ; i<cnp ; i++)
1043  {
1044  /* AMO
1045  here may be we have to use cpl_image_add_create and cpl_imagelist_set
1046  */
1047  cpl_image_divide(cpl_imagelist_get(cube,i), im) ;
1048  }
1049 
1050  return cube ;
1051 }
1052 
1053 
1054 /*---------------------------------------------------------------------------
1055  Function : sinfo_new_add_spectrum_to_cube()
1056  In : 1 allocated cube, 1 allocated spectrum sinfo_vector
1057  Out : result cube
1058  Job : adds a spectrum (in z-direction) to all data
1059  points in a cube
1060  ---------------------------------------------------------------------------*/
1061 
1062 cpl_imagelist *
1063 sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
1064 {
1065  cpl_imagelist * cube ;
1066  int i ,j ;
1067  int ilx=0;
1068  int ily=0;
1069  int inp=0;
1070  float* pidata=NULL;
1071 
1072  cpl_image* i_img=NULL;
1073  cpl_image* o_img=NULL;
1074 
1075  if (cu == NULL || spec == NULL)
1076  {
1077  sinfo_msg_error ("null cube or null spectrum") ;
1078  return NULL ;
1079  }
1080  inp=cpl_imagelist_get_size(cu);
1081  i_img=cpl_imagelist_get(cu,0);
1082  ilx=cpl_image_get_size_x(i_img);
1083  ily=cpl_image_get_size_y(i_img);
1084 
1085  if ( inp != spec -> n_elements )
1086  {
1087  sinfo_msg_error("cube length and spectrum length are not compatible") ;
1088  return NULL ;
1089  }
1090 
1091  if ( NULL == (cube = cpl_imagelist_new ()) )
1092  {
1093  sinfo_msg_error ("cannot allocate new cube" ) ;
1094  return NULL ;
1095  }
1096  for ( i = 0; i < inp; i++)
1097  {
1098  o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
1099  cpl_imagelist_set(cube,o_img,i);
1100  }
1101 
1102 
1103  for ( i = 0; i < inp; i++)
1104  {
1105  i_img=cpl_imagelist_get(cu,i);
1106  pidata=cpl_image_get_data_float(i_img);
1107  o_img=cpl_imagelist_get(cube,i);
1108  float* podata=cpl_image_get_data_float(o_img);
1109  for ( j = 0; j < (int) ilx*ily; j++)
1110  {
1111  podata[j] = pidata[j] + spec -> data[i] ;
1112  }
1113  }
1114 
1115  return cube ;
1116 }
1117 
1118 /*---------------------------------------------------------------------------
1119  Function : sinfo_new_sub_spectrum_from_cube()
1120  In : 1 allocated cube, 1 allocated spectrum sinfo_vector
1121  Out : result cube
1122  Job : subtracts a spectrum (in z-direction) from all
1123  data points in a cube
1124  ---------------------------------------------------------------------------*/
1125 
1126 cpl_imagelist *
1127 sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu, Vector *spec)
1128 {
1129  cpl_imagelist * cube ;
1130  int i ,j ;
1131  int ilx=0;
1132  int ily=0;
1133  int inp=0;
1134  float* pidata=NULL;
1135 
1136  cpl_image* i_img=NULL;
1137  cpl_image* o_img=NULL;
1138 
1139  if (cu == NULL || spec == NULL)
1140  {
1141  sinfo_msg_error ("null cube or null spectrum") ;
1142  return NULL ;
1143  }
1144  inp=cpl_imagelist_get_size(cu);
1145  i_img=cpl_imagelist_get(cu,0);
1146  ilx=cpl_image_get_size_x(i_img);
1147  ily=cpl_image_get_size_y(i_img);
1148 
1149  if ( inp != spec -> n_elements )
1150  {
1151  sinfo_msg_error("cube length and spectrum length are not compatible") ;
1152  return NULL ;
1153  }
1154 
1155  if ( NULL == (cube = cpl_imagelist_new()) )
1156  {
1157  sinfo_msg_error ("cannot allocate new cube" ) ;
1158  return NULL ;
1159  }
1160  for ( i = 0; i < inp; i++)
1161  {
1162  o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
1163  cpl_imagelist_set(cube,o_img,i);
1164  }
1165 
1166 
1167  for ( i = 0; i < inp; i++)
1168  {
1169  i_img=cpl_imagelist_get(cu,i);
1170  pidata=cpl_image_get_data_float(i_img);
1171  o_img=cpl_imagelist_get(cube,i);
1172  float* podata=cpl_image_get_data_float(o_img);
1173  for ( j = 0; j < (int) ilx*ily; j++)
1174  {
1175  if ( isnan(pidata[j]) || isnan(spec -> data[i]) )
1176  {
1177  podata[j] = ZERO ;
1178  }
1179  else
1180  {
1181  podata[j] = pidata[j] - spec -> data[i] ;
1182  }
1183  }
1184  }
1185 
1186  return cube ;
1187 }
1188 
1189 
1190 /*---------------------------------------------------------------------------
1191  Function : sinfo_new_mul_spectrum_to_cube()
1192  In : 1 allocated cube, 1 allocated spectrum sinfo_vector
1193  Out : result cube
1194  Job : multiplies a spectrum (in z-direction) to all data
1195  points in a cube
1196  ---------------------------------------------------------------------------*/
1197 
1198 cpl_imagelist *
1199 sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
1200 {
1201  cpl_imagelist * cube ;
1202  int i ,j ;
1203  int ilx=0;
1204  int ily=0;
1205  int inp=0;
1206  float* pidata=NULL;
1207 
1208  cpl_image* i_img=NULL;
1209  cpl_image* o_img=NULL;
1210 
1211  if (cu == NULL || spec == NULL)
1212  {
1213  sinfo_msg_error ("null cube or null spectrum") ;
1214  return NULL ;
1215  }
1216  inp=cpl_imagelist_get_size(cu);
1217  i_img=cpl_imagelist_get(cu,0);
1218  ilx=cpl_image_get_size_x(i_img);
1219  ily=cpl_image_get_size_y(i_img);
1220 
1221  if ( inp != spec -> n_elements )
1222  {
1223  sinfo_msg_error("cube length and spectrum length are not compatible") ;
1224  return NULL ;
1225  }
1226 
1227  if ( NULL == (cube = cpl_imagelist_new ()) )
1228  {
1229  sinfo_msg_error ("cannot allocate new cube" ) ;
1230  return NULL ;
1231  }
1232 
1233  for ( i = 0; i < inp; i++)
1234  {
1235  o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
1236  cpl_imagelist_set(cube,o_img,i);
1237  }
1238 
1239 
1240  for ( i = 0; i < inp; i++)
1241  {
1242  i_img=cpl_imagelist_get(cu,i);
1243  pidata=cpl_image_get_data_float(i_img);
1244  o_img=cpl_imagelist_get(cube,i);
1245  float* podata=cpl_image_get_data_float(o_img);
1246  for ( j = 0; j < (int) ilx*ily; j++)
1247  {
1248  if ( isnan(pidata[j]) || isnan(spec->data[i]) )
1249  {
1250  podata[j] = ZERO ;
1251  }
1252  else
1253  {
1254  podata[j] = pidata[j] * spec -> data[i] ;
1255  }
1256  }
1257  }
1258 
1259  return cube ;
1260 }
1261 
1262 
1263 /*---------------------------------------------------------------------------
1264  Function : sinfo_new_div_cube_by_spectrum()
1265  In : 1 allocated cube, 1 allocated spectrum sinfo_vector
1266  Out : result cube
1267  Job : divides all data points of a cube by a spectrum
1268  (in z-direction)
1269  ---------------------------------------------------------------------------*/
1270 
1271 cpl_imagelist *
1272 sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu, Vector *spec)
1273 {
1274  cpl_imagelist * cube ;
1275  float help ;
1276  int i ,j ;
1277  int ilx=0;
1278  int ily=0;
1279  int inp=0;
1280  float* pidata=NULL;
1281 
1282  cpl_image* i_img=NULL;
1283  cpl_image* o_img=NULL;
1284 
1285  if (cu == NULL || spec == NULL)
1286  {
1287  sinfo_msg_error ("null cube or null spectrum") ;
1288  return NULL ;
1289  }
1290  inp=cpl_imagelist_get_size(cu);
1291  i_img=cpl_imagelist_get(cu,0);
1292  ilx=cpl_image_get_size_x(i_img);
1293  ily=cpl_image_get_size_y(i_img);
1294 
1295  if ( inp != spec -> n_elements )
1296  {
1297  sinfo_msg_error("cube length and spectrum length are not compatible") ;
1298  return NULL ;
1299  }
1300 
1301  if (NULL == (cube = cpl_imagelist_new ()) )
1302  {
1303  sinfo_msg_error ("cannot allocate new cube") ;
1304  return NULL ;
1305  }
1306 
1307  for ( i = 0; i < inp; i++)
1308  {
1309  o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
1310  cpl_imagelist_set(cube,o_img,i);
1311  }
1312 
1313 
1314  for ( i = 0; i < inp; i++)
1315  {
1316 
1317  i_img=cpl_imagelist_get(cu,i);
1318  pidata=cpl_image_get_data_float(i_img);
1319  o_img=cpl_imagelist_get(cube,i);
1320  float* podata=cpl_image_get_data_float(o_img);
1321  for ( j = 0; j < (int) ilx*ily; j++)
1322  {
1323  if (!isnan(spec->data[i]) && spec->data[i] != 0.)
1324  {
1325  help = 1/spec->data[i] ;
1326  if ( help > THRESH )
1327  {
1328  help = 1. ;
1329  }
1330  }
1331  else
1332  {
1333  help = ZERO ;
1334  }
1335 
1336  if ( isnan(help) || isnan(pidata[j]) )
1337  {
1338  podata[j] = ZERO ;
1339  }
1340  else
1341  {
1342  podata[j] = pidata[j] * help ;
1343  }
1344  }
1345  }
1346  return cube ;
1347 }
1348 
1349 
1350 /*---------------------------------------------------------------------------
1351  Function : sinfo_new_clean_mean_of_spectra()
1352  In : 1 allocated cube, position of rectangle in x-y plane ,
1353  low and high cut threshold
1354  Out : result spectrum sinfo_vector
1355  Job : averaging routine to get a better spectral S/N, sorts
1356  the values of the same z-position, cuts the lowest and
1357  highest values according to given thresholds and then
1358  takes the average within the x-y plane , cannot have
1359  a sum of low and high rejected values greater than 90%
1360  of all values
1361  ---------------------------------------------------------------------------*/
1362 /* TODO: not used */
1363 Vector *
1364 sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
1365  int llx,
1366  int lly,
1367  int urx,
1368  int ury,
1369  double lo_reject,
1370  double hi_reject)
1371 {
1372  Vector * mean ;
1373 
1374  int i, j, k, l;
1375  int recsize, lo_n, hi_n;
1376  int ilx=0;
1377  int ily=0;
1378  int inp=0;
1379  float* pidata=NULL;
1380  cpl_image* i_img=NULL;
1381 
1382  if ( cube == NULL || cpl_imagelist_get_size(cube) < 1 )
1383  {
1384  sinfo_msg_error ("no cube to take the mean of his spectra") ;
1385  return NullVector ;
1386  }
1387  inp=cpl_imagelist_get_size(cube);
1388  i_img=cpl_imagelist_get(cube,0);
1389  ilx=cpl_image_get_size_x(i_img);
1390  ily=cpl_image_get_size_y(i_img);
1391 
1392  if ((llx<1) || (llx>ilx) ||
1393  (urx<1) || (urx>ilx) ||
1394  (lly<1) || (lly>ily) ||
1395  (ury<1) || (ury>ily) ||
1396  (llx>=urx) || (lly>=ury))
1397  {
1398  sinfo_msg_error("invalid rectangle coordinates:") ;
1399  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1400  llx, lly, urx, ury) ;
1401  return NullVector ;
1402  }
1403 
1404  if ((lo_reject + hi_reject) > 0.9)
1405  {
1406  sinfo_msg_error("illegal rejection thresholds: [%f] and [%f]",
1407  lo_reject, hi_reject) ;
1408  sinfo_msg_error("threshold sum should not be over 0.9"
1409  " aborting average") ;
1410  return NullVector ;
1411  }
1412 
1413  /* shift from FITS coordinates to C coordinates */
1414  llx -- ;
1415  lly -- ;
1416  urx -- ;
1417  ury -- ;
1418 
1419  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1420 
1421  lo_n = (int) (recsize * lo_reject + 0.5) ;
1422  hi_n = (int) (recsize * hi_reject + 0.5) ;
1423 
1424  if (lo_n + hi_n >= recsize)
1425  {
1426  sinfo_msg_error ("everything would be rejected") ;
1427  return NullVector;
1428  }
1429 
1430  /* allocate a new sinfo_vector to store the average spectral values */
1431  if (NULL == (mean = sinfo_new_vector (inp)) )
1432  {
1433  sinfo_msg_error ("cannot allocate a new sinfo_vector") ;
1434  return NullVector ;
1435  }
1436 
1437  /*------------------------------------------------------------------------
1438  * loop through the cube planes, through the x axis and the y-axis of the
1439  * plane rectangle and store pixel values in a buffer.
1440  */
1441 
1442  for ( i = 0 ; i < inp ; i++ )
1443  {
1444  i_img=cpl_imagelist_get(cube,i);
1445  pidata=cpl_image_get_data_float(i_img);
1446  int m = 0 ;
1447  pixelvalue* local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
1448 
1449  for ( j = lly ; j <= ury ; j++ )
1450  {
1451  for ( k = llx ; k <= urx ; k++ )
1452  {
1453  local_rectangle[m] = pidata[k + j * ilx] ;
1454  m ++ ;
1455  }
1456  }
1457  /*sorts the pixelvalues in the buffer*/
1458  sinfo_pixel_qsort (local_rectangle, recsize) ;
1459 
1460  int nv = 0 ;
1461  for ( l = lo_n ; l < (recsize - hi_n) ; l++ )
1462  {
1463  mean -> data[i] += local_rectangle[l] ;
1464  nv ++;
1465  }
1466  mean -> data[i] /= nv ;
1467 
1468  cpl_free ( local_rectangle ) ;
1469  }
1470  return mean ;
1471 }
1472 
1473 
1474 /*---------------------------------------------------------------------------
1475  Function :sinfo_new_median_cube()
1476  In :1 allocated cube
1477  Out :result image
1478  Job :determines the sinfo_new_median value in every pixel position
1479  by considering all pixels along the third axis.
1480  ZERO pixels in a plane are not considered. If all
1481  pixels at a position are not valid the result will
1482  be 'ZERO'.
1483  ---------------------------------------------------------------------------*/
1484 cpl_image *
1485 sinfo_new_median_cube(cpl_imagelist * cube)
1486 {
1487  cpl_image * im ;
1488  pixelvalue * buffer ;
1489  int i, j ;
1490  int ilx=0;
1491  int ily=0;
1492  int inp=0;
1493  float* pidata=NULL;
1494  float* podata=NULL;
1495  cpl_image* i_img=NULL;
1496 
1497  if ( cube == NULL )
1498  {
1499  sinfo_msg_error ("null cube") ;
1500  return NULL ;
1501  }
1502  inp=cpl_imagelist_get_size(cube);
1503  i_img=cpl_imagelist_get(cube,0);
1504  ilx=cpl_image_get_size_x(i_img);
1505  ily=cpl_image_get_size_y(i_img);
1506 
1507  /* allocate memory */
1508  if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
1509  {
1510  sinfo_msg_error ("cannot allocate new image") ;
1511  return NULL ;
1512  }
1513 
1514  /*------------------------------------------------------------------------
1515  * transfer each sinfo_vector in z direction in a buffer and collect
1516  only non-blank data.
1517  */
1518 
1519  podata=cpl_image_get_data_float(im);
1520  for ( i = 0 ; i < (int) ilx*ily ; i++ )
1521  {
1522  buffer = (pixelvalue *) cpl_calloc (inp, sizeof (pixelvalue *));
1523  int k = 0 ;
1524  for ( j = 0 ; j < inp ; j ++ )
1525  {
1526  i_img=cpl_imagelist_get(cube,j);
1527  pidata=cpl_image_get_data_float(i_img);
1528  if ( !isnan(pidata[i]) )
1529  {
1530  buffer[k] = pidata[i] ;
1531  k ++ ;
1532  }
1533  }
1534  int nz = k ;
1535 
1536  /* proceed depending on the number of valid pixels */
1537  if ( nz > 2 )
1538  {
1539  podata[i] = sinfo_new_median ( buffer, nz ) ;
1540  }
1541  else if (nz == 2)
1542  {
1543  podata[i] = (buffer[0] + buffer[1]) / 2. ;
1544  }
1545  else if (nz == 1)
1546  {
1547  podata[i] = buffer[0] ;
1548  }
1549  else if (nz == 0)
1550  {
1551  podata[i] = ZERO ;
1552  }
1553 
1554  cpl_free ( buffer ) ;
1555  }
1556 
1557  return im ;
1558 }
1559 
1560 
1561 /*---------------------------------------------------------------------------
1562  Function : sinfo_new_average_cube_to_image()
1563  In : 1 allocated cube
1564  Out : result image
1565  Job : determines the average value in every pixel position
1566  by considering all pixels along the third axis.
1567  ZERO pixels in a plane are not considered. If all
1568  pixels at a position are not valid the result will
1569  be 'ZERO'.
1570  ---------------------------------------------------------------------------*/
1571 cpl_image *
1572 sinfo_new_average_cube_to_image(cpl_imagelist * cube)
1573 {
1574  cpl_image * im ;
1575  int i, j;
1576  int ilx=0;
1577  int ily=0;
1578  int inp=0;
1579  float* pidata=NULL;
1580  float* podata=NULL;
1581  cpl_image* i_img=NULL;
1582 
1583  if ( cube == NULL )
1584  {
1585  sinfo_msg_error ("null cube") ;
1586  return NULL ;
1587  }
1588  inp=cpl_imagelist_get_size(cube);
1589  i_img=cpl_imagelist_get(cube,0);
1590  ilx=cpl_image_get_size_x(i_img);
1591  ily=cpl_image_get_size_y(i_img);
1592 
1593  /* allocate memory */
1594  if (NULL == (im = cpl_image_new (ilx, ily,CPL_TYPE_FLOAT )) )
1595  {
1596  sinfo_msg_error ("cannot allocate new image") ;
1597  return NULL ;
1598  }
1599 
1600  /*------------------------------------------------------------------------
1601  * transfer each vector in z direction in a buffer and collect
1602  only non-blank data.
1603  */
1604 
1605  podata=cpl_image_get_data_float(im);
1606  for ( i = 0 ; i < (int) ilx*ily ; i++ )
1607  {
1608  int nz = 0 ;
1609  for ( j = 0 ; j < inp ; j ++ )
1610  {
1611  i_img=cpl_imagelist_get(cube,j);
1612  pidata=cpl_image_get_data_float(i_img);
1613  if ( !isnan(pidata[i]) )
1614  {
1615  nz ++ ;
1616  podata[i] += pidata[i] ;
1617  }
1618  }
1619 
1620  /* proceed depending on the number of valid pixels */
1621  if ( nz >= 1 )
1622  {
1623  podata[i] /= nz ;
1624  }
1625  else if (nz == 0)
1626  {
1627  podata[i] = ZERO ;
1628  }
1629  }
1630 
1631  return im ;
1632 }
1633 
1634 /*---------------------------------------------------------------------------
1635  Function : sinfo_new_sum_cube_to_image()
1636  In : 1 allocated cube
1637  Out : result image
1638  Job : determines the sum value in every pixel position
1639  by considering all pixels along the third axis.
1640  ZERO pixels in a plane are not considered. If all
1641  pixels at a position are not valid the result will
1642  be 'ZERO'.
1643  ---------------------------------------------------------------------------*/
1644 cpl_image *
1645 sinfo_new_sum_cube_to_image(cpl_imagelist * cube)
1646 {
1647  cpl_image * im ;
1648  int i, j;
1649  int ilx=0;
1650  int ily=0;
1651  int inp=0;
1652  float* pidata=NULL;
1653  float* podata=NULL;
1654  cpl_image* i_img=NULL;
1655 
1656  if ( cube == NULL )
1657  {
1658  sinfo_msg_error ("null cube") ;
1659  return NULL ;
1660  }
1661  inp=cpl_imagelist_get_size(cube);
1662  i_img=cpl_imagelist_get(cube,0);
1663  ilx=cpl_image_get_size_x(i_img);
1664  ily=cpl_image_get_size_y(i_img);
1665 
1666  /* allocate memory */
1667  if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
1668  {
1669  sinfo_msg_error ("cannot allocate new image") ;
1670  return NULL ;
1671  }
1672 
1673  /*-------------------------------------------------------------------------
1674  * transfer each vector in z direction in a buffer and collect only
1675  non-blank data.
1676  */
1677 
1678  podata=cpl_image_get_data_float(im);
1679  for ( i = 0 ; i < (int) ilx*ily ; i++ )
1680  {
1681  int nz = 0 ;
1682  for ( j = 0 ; j < inp ; j ++ )
1683  {
1684  i_img=cpl_imagelist_get(cube,j);
1685  pidata=cpl_image_get_data_float(i_img);
1686  if ( !isnan(pidata[i]) )
1687  {
1688  nz++ ;
1689  podata[i] += pidata[i] ;
1690  }
1691  }
1692 
1693  /* proceed depending on the number of valid pixels */
1694  if (nz == 0)
1695  {
1696  podata[i] = ZERO ;
1697  }
1698  }
1699 
1700  return im ;
1701 }
1702 
1703 /*---------------------------------------------------------------------------
1704  Function sinfo_new_average_cube_to_image_between_waves()
1705  In cube: data cube to collapse
1706  dispersion: dispersion per pixel in microns/pixel
1707  (derived from fits header information)
1708  centralWave: central wavelength in the cube in microns
1709  (derived from fits header information)
1710  initialLambda, finalLambda: wavelength values in microns
1711  within which the cube is averaged
1712  Out :resulting averaged image
1713  Job :determines the average value in every pixel position
1714  by considering only the pixels along the third axis
1715  which lie between the given wavelength values.
1716  These values are first recalculated to plane indices
1717  by using the given dispersion and minimum wavelength in
1718  the cube.
1719  ZERO pixels in a plane are not considered. If all
1720  pixels at a position are not valid the result will
1721  be 'ZERO'.
1722  ---------------------------------------------------------------------------*/
1723 cpl_image *
1724 sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
1725  float dispersion,
1726  float centralWave,
1727  float initialLambda,
1728  float finalLambda)
1729 {
1730  cpl_image * im ;
1731  int firstPlane ;
1732  int lastPlane ;
1733  int i, j;
1734  float minWave ;
1735  int ilx=0;
1736  int ily=0;
1737  int inp=0;
1738  float* pidata=NULL;
1739  float* podata=NULL;
1740  cpl_image* i_img=NULL;
1741 
1742  if ( cube == NULL )
1743  {
1744  sinfo_msg_error ("null cube") ;
1745  return NULL ;
1746  }
1747  i_img=cpl_imagelist_get(cube,0);
1748  ilx=cpl_image_get_size_x(i_img);
1749  ily=cpl_image_get_size_y(i_img);
1750 
1751  inp=cpl_imagelist_get_size(cube);
1752 
1753  minWave = centralWave - (float) (inp / 2)*dispersion ;
1754 
1755  if ( dispersion <= 0. || minWave <= 0. )
1756  {
1757  sinfo_msg_error ("wrong dispersion or minimum wavelength given") ;
1758  return NULL ;
1759  }
1760 
1761  if ( initialLambda < minWave ||
1762  (initialLambda >= minWave + dispersion * inp) )
1763  {
1764  sinfo_msg_error ("wrong initial wavelength given") ;
1765  return NULL ;
1766  }
1767 
1768  if ( finalLambda <= minWave ||
1769  (finalLambda > minWave + dispersion * inp) )
1770  {
1771  sinfo_msg_error ("wrong final wavelength given") ;
1772  return NULL ;
1773  }
1774 
1775  /* allocate memory */
1776  if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
1777  {
1778  sinfo_msg_error ("cannot allocate new image") ;
1779  return NULL ;
1780  }
1781 
1782  /* transfer the wavelength range to image plane indices */
1783  firstPlane = sinfo_new_nint ((double) ((initialLambda - minWave) /
1784  dispersion)) ;
1785  lastPlane = sinfo_new_nint ((double) ((finalLambda - minWave) /
1786  dispersion)) ;
1787 
1788  if ( firstPlane < 0 || firstPlane >= inp ||
1789  lastPlane < 0 || lastPlane > inp )
1790  {
1791  sinfo_msg_error ("wrong values given!") ;
1792  cpl_image_delete(im);
1793  return NULL ;
1794  }
1795 
1796  /*------------------------------------------------------------------------
1797  * transfer each vector in z direction in a buffer and collect only
1798  non-blank data.
1799  */
1800 
1801 
1802 
1803  podata=cpl_image_get_data_float(im);
1804  for ( i = 0 ; i < (int) ilx*ily ; i++ )
1805  {
1806  int nz = 0 ;
1807 
1808  for ( j = firstPlane ; j <= lastPlane ; j ++ )
1809  {
1810  i_img=cpl_imagelist_get(cube,j);
1811  pidata=cpl_image_get_data_float(i_img);
1812  if ( !isnan(pidata[i]) )
1813  {
1814  nz ++ ;
1815  podata[i] += pidata[i] ;
1816  }
1817  }
1818 
1819  /* proceed depending on the number of valid pixels */
1820  if ( nz >= 1 )
1821  {
1822  podata[i] /= nz ;
1823  }
1824  else if (nz == 0)
1825  {
1826  podata[i] = ZERO ;
1827  }
1828  }
1829 
1830  return im ;
1831 }
1832 
1833 /*---------------------------------------------------------------------------
1834  Function : sinfo_new_extract_image_from_cube()
1835  In : 1 allocated cube
1836  index of cube plane
1837  Out : extracted image
1838  Job : returns the wanted image plane of the cube
1839  ---------------------------------------------------------------------------*/
1840 /* TODO: not used */
1841 
1842 cpl_image *
1843 sinfo_new_extract_image_from_cube(cpl_imagelist * cube, int plane_index)
1844 {
1845  if ( cube == NULL )
1846  {
1847  sinfo_msg_error ("null cube") ;
1848  return NULL ;
1849  }
1850 
1851  if ( plane_index < 0 || plane_index >= cpl_imagelist_get_size(cube) )
1852  {
1853  sinfo_msg_error ("wrong plane index for image to be extracted") ;
1854  return NULL ;
1855  }
1856 
1857  return cpl_imagelist_get(cube,plane_index) ;
1858 }
1859 
1860 /*---------------------------------------------------------------------------
1861  Function :sinfo_new_extract_spectrum_from_cube()
1862  In :cube: 1 allocated cube
1863  x_pos, y_pos: x, y pixel position of the
1864  spectrum counted from 0
1865  Out :extracted spectral sinfo_vector object
1866  Job :returns the wanted single spectrum of the cube
1867  ---------------------------------------------------------------------------*/
1868 /* TODO: not used */
1869 
1870 Vector *
1871 sinfo_new_extract_spectrum_from_cube(cpl_imagelist * cube,
1872  int x_pos, int y_pos)
1873 {
1874  Vector * returnedSpectrum ;
1875  int i ;
1876  int ilx=0;
1877  int ily=0;
1878  int inp=0;
1879  float* pidata=NULL;
1880  cpl_image* i_img=NULL;
1881 
1882  if ( cube == NULL )
1883  {
1884  sinfo_msg_error ("no cube given!") ;
1885  return NullVector ;
1886  }
1887  i_img=cpl_imagelist_get(cube,0);
1888  ilx=cpl_image_get_size_x(i_img);
1889  ily=cpl_image_get_size_y(i_img);
1890  inp=cpl_imagelist_get_size(cube);
1891 
1892  if ( x_pos < 0 || x_pos >= ilx )
1893  {
1894  sinfo_msg_error ("wrong x-positon of spectrum given!") ;
1895  return NullVector ;
1896  }
1897 
1898  if ( y_pos < 0 || y_pos >= ily )
1899  {
1900  sinfo_msg_error ("wrong y-positon of spectrum given!") ;
1901  return NullVector ;
1902  }
1903 
1904  /* allocate memory */
1905  if ( NULL == (returnedSpectrum = sinfo_new_vector ( inp )) )
1906  {
1907  sinfo_msg_error ("cannot allocate new spectrum!") ;
1908  return NullVector ;
1909  }
1910 
1911  for ( i = 0 ; i < inp ; i++ )
1912  {
1913  i_img=cpl_imagelist_get(cube,i);
1914  pidata=cpl_image_get_data_float(i_img);
1915  returnedSpectrum -> data[i] = pidata[x_pos + ilx*y_pos] ;
1916  }
1917 
1918  return returnedSpectrum ;
1919 }
1920 
1921 /*---------------------------------------------------------------------------
1922  Function : sinfo_new_combine_jittered_cubes()
1923  In : cubes: list of jittered cubes to mosaic
1924  mergedCube: resulting merged cube containing the
1925  jittered cubes
1926  n_cubes: number of cubes in the list to merge
1927  cumoffsetx,y: array of relative x, y pixel offsets
1928  with respect to the first frame in the
1929  same sequence as the cube list.
1930  exptimes: exposure times array giving the time
1931  in the same sequence as the cube list
1932  kernel_type: the name of the interpolation kernel
1933  that you want to generate using the
1934  eclipse routine
1935  sinfo_generate_interpolation_kernel()
1936  Supported kernels are:
1937  NULL: default kernel, currently tanh
1938  "default": dito
1939  "tanh": Hyperbolic tangent
1940  "sinc2": Square sinc
1941  "lanczos": Lanczos2 kernel
1942  "hamming": Hamming kernel
1943  "hann": Hann kernel
1944  Out : mask: cube of the same size as combinedCube
1945  containing 0 for blank (ZERO pixels) and
1946  the summed integration times for
1947  overlapping regions
1948  mergedCube: final data cube containing the
1949  jittered cubes
1950  Job : merges jittered data cubes to one bigger cube
1951  by averaging the overlap regions weighted by
1952  the integration times. The x, y size of the final data
1953  cube is user given, and should be between 32 and 64
1954  pixels, while the relative pixel-offset (sub-pixel
1955  accuracy) of the single cubes with respect to the
1956  first cube in the list is read from the
1957  SEQ CUMOFFSETX,Y
1958  fits header keyword.
1959  ---------------------------------------------------------------------------*/
1960 /* TODO: not used */
1961 
1962 cpl_imagelist *
1963 sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
1964  cpl_imagelist * mergedCube,
1965  int n_cubes,
1966  float * cumoffsetx,
1967  float * cumoffsety,
1968  float * exptimes,
1969  char * kernel_type )
1970 {
1971 
1972  int i=0 ;
1973  int x=0;
1974  int y=0;
1975  int z=0;
1976  int llx0=0;
1977  int lly0=0;
1978  int posx=0;
1979  int posy=0;
1980  float weight=0;
1981  cpl_imagelist * mask=NULL;
1982  double * kernel=NULL;
1983  /*cpl_image * shiftedImage ;*/
1984 
1985  int* llx=NULL ;
1986  int* lly=NULL ;
1987 
1988  float* sub_offsetx=NULL ;
1989  float* sub_offsety=NULL ;
1990 
1991  cpl_imagelist ** tmpcubes=NULL ;
1992 
1993 
1994 
1995  int ilx=0;
1996  int ily=0;
1997  int olx=0;
1998  int oly=0;
1999  int mlx=0;
2000  int onp=0;
2001  int inp=0;
2002 
2003  float* podata=NULL;
2004  float* pmdata=NULL;
2005  float* ptdata=NULL;
2006 
2007  cpl_image* i_img=NULL;
2008  cpl_image* o_img=NULL;
2009  cpl_image* m_img=NULL;
2010  cpl_image* t_img=NULL;
2011 
2012 
2013  if ( cubes == NULL )
2014  {
2015  sinfo_msg_error ("no cube list given!") ;
2016  return NULL ;
2017  }
2018  if ( n_cubes <= 0 )
2019  {
2020  sinfo_msg_error ("wrong number of data cubes in list!") ;
2021  return NULL ;
2022  }
2023  if ( cumoffsetx == NULL || cumoffsety == NULL )
2024  {
2025  sinfo_msg_error ("no cumoffsetx/y given!") ;
2026  return NULL ;
2027  }
2028  if ( exptimes == NULL )
2029  {
2030  sinfo_msg_error ("no exposure time array given!") ;
2031  return NULL ;
2032  }
2033 
2034  o_img=cpl_imagelist_get(mergedCube,0);
2035  olx=cpl_image_get_size_x(o_img);
2036  oly=cpl_image_get_size_y(o_img);
2037  onp=cpl_imagelist_get_size(mergedCube);
2038  if ( NULL == (mask = cpl_imagelist_new()) )
2039  {
2040  sinfo_msg_error ("could not allocate cube!") ;
2041  return NULL ;
2042  }
2043  for(i=0;i<onp;i++){
2044  o_img=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
2045  cpl_imagelist_set(mergedCube,o_img,i);
2046  }
2047 
2048  i_img=cpl_imagelist_get(cubes[0],0);
2049  ilx=cpl_image_get_size_x(i_img);
2050  ily=cpl_image_get_size_y(i_img);
2051 
2052  inp=cpl_imagelist_get_size(cubes[0]);
2053 
2054  /*--------------------------------------------------------------------
2055  * center the cubes within the allocated big cube
2056  * that means define the (0,0) positions of the cubes in the image planes
2057  * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
2058  */
2059  /* position of first reference frame, centered in big cube */
2060  llx0 = olx/2 - ilx/2 ;
2061  lly0 = oly/2 - ily/2 ;
2062 
2063  /*--------------------------------------------------------------------
2064  * go through the frame list and determine the lower left edge position
2065  * of the shifted cubes. Additionnally, the sub-pixel offsets are
2066  * determined.
2067  */
2068 
2069  llx=cpl_calloc(n_cubes,sizeof(int)); ;
2070  lly=cpl_calloc(n_cubes,sizeof(int)) ;
2071 
2072  sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
2073  sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
2074 
2075  for ( i = 0 ; i < n_cubes ; i++ )
2076  {
2077  llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
2078  sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
2079  lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
2080  sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
2081  }
2082 
2083 
2084  /* -------------------------------------------------------------
2085  * shift the cubes according to the computed sub-pixel offsets
2086  * that means shift the single image planes of each cube
2087  * first determine an interpolation kernel
2088  */
2089  if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)))
2090  {
2091  sinfo_msg_warning ("could not generate desired interpolation kernel"
2092  " or no kernel_typ was given, the default kernel"
2093  " is used now!") ;
2094  }
2095  /* go through the frame list */
2096 
2097 
2098  tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
2099 
2100  for ( i = 0 ; i < n_cubes ; i++ )
2101  {
2102  pixelvalue* tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
2103  tmpcubes[i] = cpl_imagelist_new();
2104 
2105  for ( z = 0 ; z < inp ; z++ )
2106  {
2107 
2108 
2109  t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
2110  sub_offsetx[i], sub_offsety[i], kernel);
2111 
2112  if (t_img==NULL)
2113  {
2114  sinfo_msg_error ("could not shift image plane no %d"
2115  " in cube no %d!", z, i) ;
2116  cpl_imagelist_delete(mergedCube) ;
2117  cpl_imagelist_delete(mask) ;
2118  cpl_free(kernel) ;
2119  return NULL ;
2120  }
2121  cpl_imagelist_set(tmpcubes[i],t_img,z);
2122  }
2123  cpl_free(tmpspace);
2124  }
2125 
2126  /*-------------------------------------------------------------------------
2127  * Build the mask data cube.
2128  * The mask is 0 where no data is available, otherwise the integration
2129  time of one frame, respectively the summed integration
2130  * times in the overlapping regions are inserted
2131  */
2132  /* go through the frame list */
2133  for ( i = 0 ; i < n_cubes ; i++ )
2134  {
2135 
2136  /* go through the first image plane of the big data cube */
2137  for ( y = 0 ; y < oly ; y++ )
2138  {
2139  for ( x = 0 ; x < olx ; x++ )
2140  {
2141  /* find the position of the present cube and
2142  go through the single spectra */
2143  if ( y >= lly[i] && y < lly[i]+ily &&
2144  x >= llx[i] && x < llx[i]+ilx )
2145  {
2146  posx = x - llx[i] ;
2147  posy = y - lly[i] ;
2148  for ( z = 0 ; z < onp ; z++ )
2149  {
2150  t_img=cpl_imagelist_get(tmpcubes[i],z);
2151  ptdata=cpl_image_get_data_float(t_img);
2152  m_img=cpl_imagelist_get(mask,z);
2153  pmdata=cpl_image_get_data_float(m_img);
2154  if (!isnan(ptdata[posx+posy*ilx]) &&
2155  ptdata[posx+posy*ilx] != 0.)
2156  {
2157  pmdata[x+y*mlx] += exptimes[i] ;
2158  }
2159  }
2160  }
2161  }
2162  }
2163  }
2164 
2165 
2166 
2167 
2168 
2169 
2170  /* calculate a weighted average using the
2171  exposure time of the single frames
2172  of the overlapping regions of the cubes */
2173  for ( i = 0 ; i < n_cubes ; i++ )
2174  {
2175 
2176  /* go through the first image plane of the big data cube */
2177  for ( y = 0 ; y < oly ; y++ )
2178  {
2179 
2180  for ( x = 0 ; x < olx ; x++ )
2181  {
2182 
2183  /* find the position of the present cube
2184  and go through the single spectra */
2185  if ( y >= lly[i] && y < lly[i]+ily &&
2186  x >= llx[i] && x < llx[i]+ilx )
2187  {
2188 
2189  posx = x - llx[i] ;
2190  posy = y - lly[i] ;
2191  for ( z = 0 ; z < onp ; z++ )
2192  {
2193 
2194  t_img=cpl_imagelist_get(tmpcubes[i],z);
2195  ptdata=cpl_image_get_data_float(t_img);
2196  m_img=cpl_imagelist_get(mask,z);
2197  pmdata=cpl_image_get_data_float(m_img);
2198  mlx=cpl_image_get_size_x(m_img);
2199 
2200  o_img=cpl_imagelist_get(mergedCube,z);
2201  podata=cpl_image_get_data_float(o_img);
2202  podata[x+y*olx]=0;
2203  if (!isnan(ptdata[posx+posy*ilx]))
2204  {
2205  if (pmdata[x+y*mlx] != 0.)
2206  {
2207  /* adjust the intensities to
2208  the first reference cube */
2209  weight = exptimes[0] / pmdata[x+y*mlx] ;
2210  }
2211  else
2212  {
2213  weight = 0. ;
2214  }
2215  podata[x+y*olx] +=
2216  weight*ptdata[posx+posy*ilx] ;
2217  }
2218  }
2219  }
2220  }
2221  }
2222  }
2223 
2224 
2225 
2226 
2227  /* convert the "free space" in the cube to blank pixels */
2228  /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
2229  cpl_free(kernel) ; /* originated by eclise-malloc */
2230  for( i = 0 ; i < n_cubes ; i++ )
2231  {
2232  cpl_imagelist_delete (tmpcubes[i]) ;
2233  }
2234 
2235  cpl_free(tmpcubes); ;
2236  cpl_free(llx); ;
2237  cpl_free(lly) ;
2238 
2239  cpl_free(sub_offsetx) ;
2240  cpl_free(sub_offsety) ;
2241 
2242  return mask ;
2243 }
2244 
2245 
2246 
2247 
2248 
2249 
2250 
2251 
2281 static int
2282 sinfo_build_mask_cube(const int z_min,
2283  const int z_max,
2284  const int olx,
2285  const int oly,
2286  const int n_cubes,
2287  const int* llx,
2288  const int* lly,
2289  double * exptimes,
2290  cpl_imagelist** cubes,
2291  cpl_imagelist** tmpcubes,
2292  cpl_imagelist* mask)
2293 {
2294 
2295  int i=0;
2296  int y=0;
2297  int z=0;
2298  int ilx=0;
2299  int ily=0;
2300  cpl_image* i_img=NULL;
2301  cpl_image* t_img=NULL;
2302  int posx=0;
2303  int posy=0;
2304  float* ptdata=NULL;
2305  float* pmdata=NULL;
2306  int m=0;
2307  int x=0;
2308  int mlx=0;
2309  cpl_image* m_img=NULL;
2310 
2311 
2312  for ( z = z_min, m=0 ; z < z_max ; z++, m++ ) {
2313 
2314  // go through the first image plane of the big data cube
2315  for ( y = 0 ; y < oly ; y++ ) {
2316  for ( x = 0 ; x < olx ; x++ ) {
2317  for ( i = 0 ; i < n_cubes ; i++ ) {
2318 
2319  i_img=cpl_imagelist_get(cubes[i],0);
2320  ilx=cpl_image_get_size_x(i_img);
2321  ily=cpl_image_get_size_y(i_img);
2322 
2323 
2324  // find the position of the present cube and go
2325  // through the single spectra */
2326  if ( y >= lly[i] && y < lly[i]+ily &&
2327  x >= llx[i] && x < llx[i]+ilx )
2328  {
2329  posx = x - llx[i] ;
2330  posy = y - lly[i] ;
2331 
2332 
2333  t_img=cpl_imagelist_get(tmpcubes[i],m);
2334  ptdata=cpl_image_get_data_float(t_img);
2335  m_img=cpl_imagelist_get(mask,z);
2336  pmdata=cpl_image_get_data_float(m_img);
2337  mlx=cpl_image_get_size_x(m_img);
2338 
2339  if (!isnan(ptdata[posx+posy*ilx]) &&
2340  ptdata[posx+posy*ilx] != 0.)
2341  {
2342  pmdata[x+y*mlx] += (float)exptimes[i] ;
2343  } else if (isnan(ptdata[posx+posy*ilx])) {
2344  sinfo_msg_debug("ptdata %d, %d, %d is NAN\t",x,y,z);
2345  } else if (ptdata[posx+posy*ilx] == 0.) {
2346  sinfo_msg_debug("ptdata %d, %d, %d is 0\t",x,y,z);
2347  }
2348 
2349  } else {
2350  sinfo_msg_debug("point %d, %d, %d outside range\n",x,y,z);
2351  }
2352  }
2353  }
2354  }
2355  }
2356  return 0;
2357 
2358 }
2359 
2360 
2361 
2362 
2363 static int
2364 sinfo_build_mask_cube_thomas(const int z_min,
2365  const int z_max,
2366  const int olx,
2367  const int oly,
2368  const int n_cubes,
2369  const int* llx,
2370  const int* lly,
2371  double * exptimes,
2372  cpl_imagelist** cubes,
2373  cpl_imagelist** tmpcubes,
2374  cpl_imagelist* mask)
2375 {
2376 
2377  int i=0;
2378  int y=0;
2379  int z=0;
2380  //int inp=0;
2381 
2382  cpl_image* t_img=NULL;
2383  int posx=0;
2384  int posy=0;
2385  float* ptdata=NULL;
2386  float* pmdata=NULL;
2387  int m=0;
2388  int x=0;
2389  int mlx=0;
2390 
2391 
2392  for ( i = 0 ; i < n_cubes ; i++ ) {
2393 
2394  cpl_image* i_img=cpl_imagelist_get(cubes[i],0);
2395  int ilx=cpl_image_get_size_x(i_img);
2396  int ily=cpl_image_get_size_y(i_img);
2397  //inp=cpl_imagelist_get_size(cubes[i]);
2398 
2399  //go through the first image plane of the big data cube
2400  for ( y = 0 ; y < oly ; y++ ){
2401  for ( x = 0 ; x < olx ; x++ ){
2402  // find the position of the present cube and go
2403  // through the single spectra
2404  if ( y >= lly[i] && y < lly[i]+ily &&
2405  x >= llx[i] && x < llx[i]+ilx ) {
2406  posx = x - llx[i] ;
2407  posy = y - lly[i] ;
2408  for ( z = z_min,m=0 ; z < z_max ; z++,m++ ) {
2409  t_img=cpl_imagelist_get(tmpcubes[i],m);
2410  ptdata=cpl_image_get_data_float(t_img);
2411  cpl_image* m_img=cpl_imagelist_get(mask,z);
2412  pmdata=cpl_image_get_data_float(m_img);
2413  mlx=cpl_image_get_size_x(m_img);
2414 
2415  if (!isnan(ptdata[posx+posy*ilx]) &&
2416  ptdata[posx+posy*ilx] != 0.) {
2417  pmdata[x+y*mlx] += (float)exptimes[i] ;
2418  }
2419  }
2420  }
2421  }
2422  }
2423  }
2424  return 0;
2425 }
2426 
2427 
2428 
2429 
2430 
2481 int
2482 sinfo_new_combine_jittered_cubes_range ( cpl_imagelist ** cubes,
2483  cpl_imagelist * mergedCube,
2484  cpl_imagelist * mask,
2485  int n_cubes,
2486  float * cumoffsetx,
2487  float * cumoffsety,
2488  double * exptimes,
2489  char * kernel_type,
2490  const int z_min, const int z_max )
2491 {
2492 
2493  int i;
2494  int llx0, lly0 ;
2495  cpl_imagelist ** tmpcubes=NULL ;
2496  int* llx=NULL ;
2497  int* lly=NULL ;
2498  float* sub_offsetx=NULL ;
2499  float* sub_offsety=NULL ;
2500 
2501  int ilx=0;
2502  int ily=0;
2503  int olx=0;
2504  int oly=0;
2505  int mlx=0;
2506  int mly=0;
2507 
2508  cpl_image* i_img=NULL;
2509  cpl_image* o_img=NULL;
2510 
2511 
2512  if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
2513  return -1;
2514  }
2515 
2516  o_img=cpl_imagelist_get(mergedCube,z_min);
2517  olx=cpl_image_get_size_x(o_img);
2518  oly=cpl_image_get_size_y(o_img);
2519  i_img=cpl_imagelist_get(cubes[0],0);
2520  ilx=cpl_image_get_size_x(i_img);
2521  ily=cpl_image_get_size_y(i_img);
2522  mlx=olx;
2523  mly=oly;
2524 
2525 
2526  /*--------------------------------------------------------------------
2527  * center the cubes within the allocated big cube
2528  * that means define the (0,0) positions of the cubes in the image planes
2529  * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
2530  */
2531  /* position of first reference frame, centered in big cube */
2532  llx0 = olx/2 - ilx/2 ;
2533  lly0 = oly/2 - ily/2 ;
2534 
2535  /*--------------------------------------------------------------------
2536  * go through the frame list and determine the lower left edge position
2537  * of the shifted cubes. Additionnally, the sub-pixel offsets are
2538  * determined.
2539  */
2540 
2541 
2542  llx=cpl_calloc(n_cubes,sizeof(int)) ;
2543  lly=cpl_calloc(n_cubes,sizeof(int)) ;
2544  sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
2545  sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
2546 
2547  for ( i = 0 ; i < n_cubes ; i++ )
2548  {
2549  llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
2550  sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
2551  lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
2552  sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
2553  }
2554 
2555  tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
2556  /* -------------------------------------------------------------
2557  * shift the cubes according to the computed sub-pixel offsets
2558  * that means shift the single image planes of each cube
2559  * first determine an interpolation kernel
2560  */
2561  if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
2562  sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
2563  cpl_free(llx) ;
2564  cpl_free(lly) ;
2565  return -1;
2566  }
2567 
2568 
2569  /*-----------------------------------------------------------------------
2570  * Build the mask data cube.
2571  * The mask is 0 where no data is available, otherwise the
2572  integration time of
2573  * one frame, respectively the summed integration
2574  * times in the overlapping regions are inserted
2575  */
2576  /* go through the frame list */
2577  sinfo_build_mask_cube(z_min,z_max,olx,oly,n_cubes,llx,lly,exptimes,
2578  cubes,tmpcubes,mask);
2579 
2580 
2581  /* calculate a weighted average using the exposure time of the
2582  single frames of the overlapping regions of the cubes */
2583 
2584  sinfo_compute_weight_average(z_min,z_max,ilx,ily,n_cubes,mergedCube,mask,
2585  tmpcubes,exptimes,llx,lly);
2586 
2587  /* convert the "free space" in the cube to blank pixels */
2588  /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
2589 
2590  for( i = 0 ; i < n_cubes ; i++ )
2591  {
2592  cpl_imagelist_delete (tmpcubes[i]) ;
2593  }
2594 
2595 
2596  cpl_free(tmpcubes) ;
2597  cpl_free(llx) ;
2598  cpl_free(lly) ;
2599  cpl_free(sub_offsetx) ;
2600  cpl_free(sub_offsety) ;
2601 
2602  return 0 ;
2603 }
2604 
2622 static int
2623 sinfo_check_input(cpl_imagelist** cubes,
2624  const int n_cubes,
2625  float* cumoffsetx,
2626  float* cumoffsety,
2627  double* exptimes)
2628 {
2629  if ( cubes == NULL )
2630  {
2631  sinfo_msg_error ("no cube list given!") ;
2632  return -1 ;
2633  }
2634  if ( n_cubes <= 0 )
2635  {
2636  sinfo_msg_error ("wrong number of data cubes in list!") ;
2637  return -1 ;
2638  }
2639  if ( cumoffsetx == NULL || cumoffsety == NULL )
2640  {
2641  sinfo_msg_error ("no cumoffsetx/y given!") ;
2642  return -1;
2643  }
2644  if ( exptimes == NULL )
2645  {
2646  sinfo_msg_error ("no exposure time array given!") ;
2647  return -1 ;
2648  }
2649 
2650  return 0;
2651 }
2652 
2678 static int
2679 sinfo_compute_weight_average(const int z_min,
2680  const int z_max,
2681  const int ilx,
2682  const int ily,
2683  const int n_cubes,
2684  cpl_imagelist* mergedCube,
2685  cpl_imagelist* mask,
2686  cpl_imagelist** tmpcubes,
2687  double* exptimes,
2688  int* llx,
2689  int* lly)
2690 {
2691 
2692  int m=0;
2693  int x=0;
2694  int y=0;
2695  int z=0;
2696  int i=0;
2697 
2698  int mlx=0;
2699  //int mly=0;
2700  int olx=0;
2701  int oly=0;
2702 
2703  cpl_image* o_img=NULL;
2704 
2705  cpl_image* t_img=NULL;
2706 
2707 
2708  double weight=0;
2709 
2710  int posx=0;
2711  int posy=0;
2712 
2713 
2714  o_img=cpl_imagelist_get(mergedCube,z_min);
2715  olx=cpl_image_get_size_x(o_img);
2716  oly=cpl_image_get_size_y(o_img);
2717  mlx=olx;
2718  //mly=oly;
2719 
2720  /* calculate a weighted average using the exposure time of the
2721  single frames of the overlapping regions of the cubes */
2722 
2723  float* ptdata=NULL;
2724  for ( z = z_min, m = 0 ; z < z_max ; z++, m++ ) {
2725  o_img=cpl_imagelist_get(mergedCube,z);
2726  float* podata=cpl_image_get_data_float(o_img);
2727  cpl_image* m_img=cpl_imagelist_get(mask,z);
2728  float* pmdata=cpl_image_get_data_float(m_img);
2729  mlx=cpl_image_get_size_x(m_img);
2730 
2731  /* go through the first image plane of the big data cube */
2732  for ( y = 0 ; y < oly ; y++ ) {
2733  for ( x = 0 ; x < olx ; x++ ) {
2734 
2735  /* find the position of the present cube and
2736  go through the single spectra */
2737 
2738  for ( i = 0 ; i < n_cubes ; i++ ) {
2739 
2740  if ( y >= lly[i] && y < lly[i]+ily &&
2741  x >= llx[i] && x < llx[i]+ilx ) {
2742  posx = x - llx[i] ;
2743  posy = y - lly[i] ;
2744 
2745  t_img=cpl_imagelist_get(tmpcubes[i],m);
2746  ptdata=cpl_image_get_data_float(t_img);
2747  /* To prevent black regions in peculiar batterfly cases
2748  podata[x+y*olx]=0;
2749  */
2750  if (!isnan(ptdata[posx+posy*ilx])) {
2751  if (pmdata[x+y*mlx] != 0.) {
2752  /* adjust the intensities to the
2753  first reference cube */
2754  weight = exptimes[0] / pmdata[x+y*mlx] ;
2755  } else {
2756  weight = 0. ;
2757  }
2758  podata[x+y*olx] += weight*ptdata[posx+posy*ilx] ;
2759 
2760  }
2761  }
2762  }
2763  }
2764  }
2765  }
2766  return 0;
2767 }
2768 
2769 
2809 static int
2810 sinfo_shift_cubes(cpl_imagelist** tmpcubes,
2811  char* kernel_type,
2812  const int n_cubes,
2813  cpl_imagelist** cubes,
2814  const int z_min,
2815  const int z_max,
2816  float* sub_offsetx,
2817  float* sub_offsety,
2818  const int mlx,
2819  const int mly,
2820  cpl_imagelist* mask)
2821 {
2822 
2823  double * kernel ;
2824  int i=0;
2825 
2826  //int inp=0;
2827 
2828  int z=0;
2829  cpl_image* t_img=NULL;
2830  cpl_image* m_img=NULL;
2831  int m=0;
2832 
2833  /* -------------------------------------------------------------
2834  * shift the cubes according to the computed sub-pixel offsets
2835  * that means shift the single image planes of each cube
2836  * first determine an interpolation kernel
2837  */
2838 
2839  if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
2840  {
2841  sinfo_msg_warning ("could not generate desired interpolation kernel"
2842  "or no kernel_typ was given, the default kernel"
2843  "is used now!") ;
2844  }
2845  /* go through the frame list */
2846  for ( i = 0 ; i < n_cubes ; i++ )
2847  {
2848 
2849  cpl_image* i_img=cpl_imagelist_get(cubes[i],0);
2850  int ilx=cpl_image_get_size_x(i_img);
2851  int ily=cpl_image_get_size_y(i_img);
2852  //inp=cpl_imagelist_get_size(cubes[i]);
2853  pixelvalue *tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
2854  tmpcubes[i]=cpl_imagelist_new();
2855 
2856  for ( z = z_min, m=0 ; z < z_max ; z++, m++ )
2857  {
2858  t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
2859  sub_offsetx[i],
2860  sub_offsety[i],
2861  kernel);
2862 
2863  if (t_img==NULL)
2864  {
2865  sinfo_msg_error("could not shift image plane no %d "
2866  "in cube no %d!", z, i) ;
2867  cpl_free(kernel) ;
2868  return -1 ;
2869  }
2870 
2871  cpl_imagelist_set(tmpcubes[i],t_img,m);
2872  m_img=cpl_image_new(mlx,mly,CPL_TYPE_FLOAT);
2873  cpl_imagelist_set(mask,m_img,z);
2874  }
2875 
2876  cpl_free(tmpspace);
2877 
2878  }
2879  if(kernel != NULL) cpl_free(kernel) ;
2880 
2881  return 0;
2882 
2883 }
2884 
2885 
2886 /* Temporally commented out as not yet used
2887 static int
2888 sinfo_ks_clip(
2889  const int n_cubes,
2890  const int nc,
2891  const int ilx,
2892  const int ily,
2893  const double kappa,
2894  int* llx,
2895  int* lly,
2896  double* exptimes,
2897  cpl_imagelist** tmpcubes,
2898  float* podata,
2899  float* pmdata,
2900  const int x,
2901  const int y,
2902  const int m,
2903  const int mlx,
2904  const int olx
2905  )
2906 {
2907 
2908 
2909  int posx=0;
2910  int posy=0;
2911  int i=0;
2912  int nclip=0;
2913  int ks=0;
2914 
2915  float sig=0;
2916  float med=0;
2917  float ovr=0;
2918  float avg=0;
2919 
2920  float* ptdata=NULL;
2921  float* pvdata=NULL;
2922 
2923  cpl_image* t_img=NULL;
2924  float msk_sum=0;
2925  float val_msk_sum=0;
2926  cpl_image* v_img=NULL;
2927 
2928  cpl_vector* val=NULL;
2929  cpl_vector* msk=NULL;
2930 
2931  msk=cpl_vector_new(n_cubes);
2932  for (i=0;i<n_cubes;i++) {
2933  cpl_vector_set(msk,i,1);
2934  }
2935 
2936  // k-s clipping
2937  nclip=0;
2938 
2939  for (ks=0;ks<nc;ks++) {
2940 
2941  sig=0;
2942  med=0;
2943  ovr=0;
2944  if(nc-nclip >0) {
2945  val=cpl_vector_new(nc-nclip);
2946  }
2947 
2948  // fill val
2949  for ( i = 0 ; i < n_cubes ; i++ ) {
2950  t_img=cpl_imagelist_get(tmpcubes[i],m);
2951  ptdata=cpl_image_get_data_float(t_img);
2952  if ( y >= lly[i] && y < lly[i]+ily &&
2953  x >= llx[i] && x < llx[i]+ilx ) {
2954  posx = x - llx[i] ;
2955  posy = y - lly[i] ;
2956  if (!isnan(ptdata[posx+posy*ilx]) &&
2957  ptdata[posx+posy*ilx] != 0. &&
2958  (cpl_vector_get(msk,i) != 0)) {
2959  cpl_vector_set(val,ovr,(double)ptdata[posx+posy*ilx]);
2960  ovr++;
2961  }
2962  }
2963  }
2964 
2965  // get avg, med, sig
2966  if(ovr>0) {
2967  avg=cpl_vector_get_mean(val);
2968  med=cpl_vector_get_median_const(val);
2969  if(ovr>1) {
2970  sig=cpl_vector_get_stdev(val);
2971  } else {
2972  sig=0;
2973  }
2974  cpl_vector_delete(val);
2975  }
2976 
2977  for ( i = 0 ; i < n_cubes ; i++ ) {
2978  t_img=cpl_imagelist_get(tmpcubes[i],m);
2979  ptdata=cpl_image_get_data_float(t_img);
2980  // Do k-s clipping at each pixel
2981  if ( y >= lly[i] && y < lly[i]+ily &&
2982  x >= llx[i] && x < llx[i]+ilx ) {
2983  posx = x - llx[i] ;
2984  posy = y - lly[i] ;
2985  //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
2986  //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
2987  if (!isnan(ptdata[posx+posy*ilx]) &&
2988  ptdata[posx+posy*ilx] != 0. &&
2989  (cpl_vector_get(msk,i) != 0)) {
2990  if(abs((ptdata[posx+posy*ilx]-med))> kappa*sig) {
2991  ptdata[posx+posy*ilx]=0;
2992 
2993  pmdata[x+y*mlx] -= exptimes[i] ;
2994 
2995  cpl_vector_set(msk,i,0);
2996  nclip++;
2997  }
2998  }
2999  }
3000 
3001  }
3002  }
3003 
3004  msk_sum=0;
3005  val_msk_sum=0;
3006  for ( i = 0 ; i < n_cubes ; i++ ) {
3007  v_img=cpl_imagelist_get(tmpcubes[i],m);
3008  pvdata=cpl_image_get_data_float(v_img);
3009  // computes sky at each point
3010  if ( y >= lly[i] && y < lly[i]+ily &&
3011  x >= llx[i] && x < llx[i]+ilx ) {
3012  posx = x - llx[i] ;
3013  posy = y - lly[i] ;
3014  if (!isnan(pvdata[posx+posy*ilx]) &&
3015  pvdata[posx+posy*ilx] != 0. &&
3016  (cpl_vector_get(msk,i) != 0)) {
3017 
3018  msk_sum+= pmdata[x+y*mlx];
3019 
3020  val_msk_sum+=pvdata[posx+posy*ilx]*
3021  pmdata[x+y*mlx];
3022 
3023  }
3024  }
3025  }
3026 
3027  podata[x+y*olx]=val_msk_sum/msk_sum;
3028  cpl_vector_delete(msk);
3029 
3030  return 0;
3031 
3032 }
3033 
3034  */
3035 
3085 int
3086 sinfo_new_combine_jittered_cubes_thomas_range(cpl_imagelist ** cubes,
3087  cpl_imagelist * mergedCube,
3088  cpl_imagelist * mask,
3089  int n_cubes,
3090  float * cumoffsetx,
3091  float * cumoffsety,
3092  double * exptimes,
3093  char * kernel_type,
3094  const int z_min,
3095  const int z_max,
3096  const double kappa )
3097 {
3098  const int VERY_BIG_INT = 268431360;
3099  int i ;
3100  int llx0, lly0 ;
3101  int* llx=NULL;
3102  int* lly=NULL ;
3103  float* sub_offsetx=NULL ;
3104  float* sub_offsety=NULL ;
3105  cpl_imagelist ** tmpcubes=NULL ;
3106  const int z_siz=z_max-z_min;
3107  int ilx=0;
3108  int ily=0;
3109  int olx=0;
3110  int oly=0;
3111  int mlx=0;
3112  int mly=0;
3113  //int onp=0;
3114  cpl_image* i_img=NULL;
3115  cpl_image* o_img=NULL;
3116  int min_lx = VERY_BIG_INT;
3117  int min_ly = VERY_BIG_INT;
3118 
3119 
3120  if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
3121  return -1;
3122  }
3123 
3124  if (z_siz <= 0 ){
3125  sinfo_msg_error ("z_max <= z_min given!") ;
3126  return -1 ;
3127  }
3128 
3129  i_img=cpl_imagelist_get(cubes[0],0);
3130  o_img=cpl_imagelist_get(mergedCube,0);
3131  ilx=cpl_image_get_size_x(i_img);
3132  ily=cpl_image_get_size_y(i_img);
3133  olx=cpl_image_get_size_x(o_img);
3134  oly=cpl_image_get_size_y(o_img);
3135  mlx=olx;
3136  mly=oly;
3137  // sinfo_msg_warning(" cube size [%d:%d] merged cube size[%d:%d]" , ilx, ily, olx, oly);
3138  /*--------------------------------------------------------------------
3139  * center the cubes within the allocated big cube
3140  * that means define the (0,0) positions of the cubes in the image planes
3141  * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
3142  */
3143  /* position of first reference frame, centered in big cube */
3144  llx0 = (1.0 * olx- 1.0 * ilx)/2.0 ;
3145  lly0 = (1.0 * oly - 1.0 * ily)/2.0 ;
3146  // sinfo_msg_warning(" zero point [%d:%d]" , llx0, lly0);
3147  /*--------------------------------------------------------------------
3148  * go through the frame list and determine the lower left edge position
3149  * of the shifted cubes. Additionnally, the sub-pixel offsets are
3150  * determined.
3151  */
3152 
3153  llx=cpl_calloc(n_cubes,sizeof(int));
3154  lly=cpl_calloc(n_cubes,sizeof(int)) ;
3155  sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
3156  sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
3157 
3158  for ( i = 0 ; i < n_cubes ; i++ ) {
3159  llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
3160 
3161  sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
3162  lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
3163  sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
3164  /* sinfo_msg_warning("suboff[%d]= %f %f ll[%d:%d] cumoffset[%f:%f]" ,
3165  i,sub_offsetx[i],sub_offsety[i], llx[i], lly[i],
3166  cumoffsetx[i], cumoffsety[i]);*/
3167  if (llx[i] < min_lx)
3168  {
3169  min_lx = llx[i];
3170  }
3171  if (lly[i] < min_ly)
3172  {
3173  min_ly = lly[i];
3174  }
3175  }
3176  /***********---------
3177  * "normalize" the shift - minimum should be 0
3178  **********************************************/
3179  if (min_lx != 0)
3180  {
3181  for (i = 0 ; i < n_cubes ; i++ )
3182  {
3183  llx[i] = llx[i] - min_lx;
3184  }
3185  }
3186  if (min_ly != 0)
3187  {
3188  for (i = 0 ; i < n_cubes ; i++ )
3189  {
3190  lly[i] = lly[i] - min_ly;
3191  }
3192  }
3193 
3194  /* -------------------------------------------------------------
3195  * shift the cubes according to the computed sub-pixel offsets
3196  * that means shift the single image planes of each cube
3197  * first determine an interpolation kernel
3198  */
3199 
3200  tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
3201 
3202  if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
3203  sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
3204  cpl_free(llx);
3205  cpl_free(lly) ;
3206  return -1;
3207 
3208  }
3209 
3210 
3211  /*-------------------------------------------------------------------------
3212  * Build the mask data cube.
3213  * The mask is 0 where no data is available, otherwise the integration
3214  * time of one frame, respectively the summed integration
3215  * times in the overlapping regions are inserted
3216  */
3217  /* go through the frame list */
3218 
3219 
3220  o_img=cpl_imagelist_get(mergedCube,0);
3221  olx=cpl_image_get_size_x(o_img);
3222  oly=cpl_image_get_size_y(o_img);
3223  //onp=cpl_imagelist_get_size(mergedCube);
3224 
3225  if(-1 == sinfo_build_mask_cube_thomas(z_min,z_max,olx,oly,n_cubes,llx,lly,
3226  exptimes,cubes,tmpcubes,mask) ) {
3227  return -1;
3228  }
3230  /*
3231  check_nomsg(sinfo_coadd_with_ks_clip_optimized(z_min,z_max,n_cubes,
3232  kappa,llx,lly,
3233  exptimes,mask,mergedCube,tmpcubes));
3234  */
3237  check_nomsg(sinfo_coadd_with_ks_clip2(z_min,z_max,ilx,ily,n_cubes,kappa,llx,lly,
3238  exptimes,mask,mergedCube,tmpcubes));
3239 
3241  /* convert the "free space" in the cube to blank pixels */
3242  /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
3243  /* convert_0_to_ZERO_for_cubes(mergedSky) ; */
3244  //cpl_free(kernel) ; /* originated by eclise-malloc */
3245 
3246  cleanup:
3247 
3248  for( i = 0 ; i < n_cubes ; i++ ) {
3249  cpl_imagelist_delete (tmpcubes[i]) ;
3250  }
3251 
3252  cpl_free(tmpcubes);
3253  cpl_free(llx);
3254  cpl_free(lly) ;
3255  cpl_free(sub_offsetx) ;
3256  cpl_free(sub_offsety) ;
3257  sinfo_print_rec_status(0);
3258 
3259  return 0 ;
3260 }
3261 
3274  /* TODO: not used */
3275 cpl_imagelist *
3276 sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
3277  cpl_imagelist * badcube,
3278  int maxdist )
3279 {
3280  cpl_imagelist * intercube ;
3281  float* goodNeighbors=NULL ;
3282  int z, row, col ;
3283  int nx, ny, nz ;
3284  int llx, lly, llz ;
3285  int zi, coli, rowi ;
3286  int n ;
3287 
3288  //int bly=0;
3289 
3290  int cnp=0;
3291 
3292 
3293 
3294 
3295 
3296 
3297 
3298  cpl_image* bzi_img=NULL;
3299  cpl_image* czi_img=NULL;
3300 
3301 
3302 
3303  if ( cube == NULL || badcube == NULL )
3304  {
3305  sinfo_msg_error("no cube given!") ;
3306  return NULL ;
3307  }
3308  if ( maxdist < 1 )
3309  {
3310  sinfo_msg_error("wrong maxrad given!") ;
3311  return NULL ;
3312  }
3313  intercube = cpl_imagelist_duplicate(cube) ;
3314 
3315  goodNeighbors=cpl_calloc((2*maxdist+1)*(2*maxdist+1)*(2*maxdist+1) -1,
3316  sizeof(float)) ;
3317 
3318  cnp=cpl_imagelist_get_size(cube);
3319  float* pczidata=NULL;
3320  float* pbzidata=NULL;
3321  for ( z = 0 ; z < cnp ; z++ )
3322  {
3323  cpl_image* b_img=cpl_imagelist_get(badcube,z);
3324  cpl_image* i_img=cpl_imagelist_get(intercube,z);
3325  float* pbdata=cpl_image_get_data_float(b_img);
3326  float* pidata=cpl_image_get_data_float(i_img);
3327  int blx=cpl_image_get_size_x(b_img);
3328  //bly=cpl_image_get_size_y(b_img);
3329 
3330  cpl_image* c_img=cpl_imagelist_get(cube,z);
3331  int clx=cpl_image_get_size_x(c_img);
3332  int cly=cpl_image_get_size_y(c_img);
3333 
3334  for ( row = 0 ; row < cly ; row++ )
3335  {
3336  for ( col = 0 ; col < clx ; col++ )
3337  {
3338  if ( pbdata[col+row*clx] == 0 )
3339  {
3340  /* determine the lower left sinfo_edge of the cube */
3341  llx = col - maxdist ;
3342  nx = 2*maxdist +1 ;
3343  if (llx < 0)
3344  {
3345  nx += llx ;
3346  llx = 0 ;
3347  }
3348  if ( llx + nx > clx )
3349  {
3350  nx -= (llx + nx - clx) ;
3351  }
3352 
3353  lly = row - maxdist ;
3354  ny = 2*maxdist +1 ;
3355  if (lly < 0)
3356  {
3357  ny += lly ;
3358  lly = 0 ;
3359  }
3360  if ( lly + ny > cly )
3361  {
3362  ny -= (lly + ny - cly) ;
3363  }
3364 
3365  llz = z - maxdist ;
3366  nz = 2*maxdist +1 ;
3367  if (llz < 0)
3368  {
3369  nz += llz ;
3370  llz = 0 ;
3371  }
3372  if ( llz + nz > cnp )
3373  {
3374  nz -= (llz + nz - cnp) ;
3375  }
3376  n = 0 ;
3377  for ( zi = llz ; zi < llz+nz ; zi++ )
3378  {
3379  bzi_img=cpl_imagelist_get(badcube,zi);
3380  czi_img=cpl_imagelist_get(cube,zi);
3381  pbzidata=cpl_image_get_data_float(bzi_img);
3382  pczidata=cpl_image_get_data_float(czi_img);
3383 
3384  for ( rowi = lly ; rowi < lly+ny ; rowi++ )
3385  {
3386  for ( coli = llx ; coli < llx+nx ; coli++ )
3387  {
3388  if ( pbzidata[coli+rowi*blx] == 1 )
3389  {
3390  goodNeighbors[n] = pczidata[coli+rowi*clx] ;
3391  n++ ;
3392  }
3393  }
3394  }
3395  }
3396  if ( n > 0 )
3397  {
3398  pidata[col+row*clx]=sinfo_new_median(goodNeighbors,n);
3399  pbdata[col+row*clx]=1 ;
3400  }
3401  else
3402  {
3403  continue ;
3404  }
3405  }
3406  }
3407  }
3408  }
3409  cpl_free(goodNeighbors) ;
3410  return intercube ;
3411 }
3412 
3413 
3414 
3415 
3416 
3468 /* TODO: not used */
3469 cpl_imagelist *
3470 sinfo_new_combine_cubes ( cpl_imagelist ** cubes,
3471  cpl_imagelist * mergedCube,
3472  int n_cubes,
3473  float * cumoffsetx,
3474  float * cumoffsety,
3475  float factor,
3476  char * kernel_type )
3477 {
3478  int i=0 ;
3479  int x=0;
3480  int y=0;
3481  int z=0;
3482  int llx0=0;
3483  int lly0=0;
3484  int posx=0;
3485  int posy=0;
3486  cpl_imagelist * mask=NULL ;
3487  double * kernel=NULL ;
3488  cpl_image * shiftedImage=NULL ;
3489  int n=0;
3490  int ns=0;
3491  double sum=0;
3492  double sum2=0;
3493  double mean=0;
3494  double sigma=0;
3495 
3496  cpl_imagelist ** tmpcubes=NULL ;
3497 
3498  int* llx=NULL ;
3499  int* lly=NULL ;
3500 
3501  float* sub_offsetx=NULL ;
3502  float* sub_offsety=NULL ;
3503  float* cubedata=NULL ;
3504 
3505  int mlx=0;
3506  int mly=0;
3507  int clx=0;
3508  int cly=0;
3509  int mnp=0;
3510  int cnp=0;
3511 
3512 
3513  float* ptdata=NULL;
3514  float* podata=NULL;
3515  float* pmdata=NULL;
3516 
3517  cpl_image* tmp_img=NULL;
3518  cpl_image* o_img=NULL;
3519  cpl_image* m_img=NULL;
3520  cpl_image* c_img=NULL;
3521  cpl_image* t_img=NULL;
3522 
3523 
3524 
3525 
3526  if ( cubes == NULL )
3527  {
3528  sinfo_msg_error ("no cube list given!") ;
3529  return NULL ;
3530  }
3531 
3532 
3533  if ( mergedCube == NULL )
3534  {
3535  sinfo_msg_error ("no out cube given!") ;
3536  return NULL ;
3537  }
3538 
3539 
3540  if ( n_cubes <= 0 )
3541  {
3542  sinfo_msg_error ("wrong number of data cubes in list!") ;
3543  return NULL ;
3544  }
3545  if ( cumoffsetx == NULL || cumoffsety == NULL )
3546  {
3547  sinfo_msg_error ("no cumoffsetx/y given!") ;
3548  return NULL;
3549  }
3550 
3551  if ( factor <= 0. )
3552  {
3553  sinfo_msg_error ("wrong factor given!") ;
3554  return NULL ;
3555  }
3556 
3557  m_img=cpl_imagelist_get(mergedCube,0);
3558  mlx=cpl_image_get_size_x(m_img);
3559  mly=cpl_image_get_size_y(m_img);
3560  cnp=cpl_imagelist_get_size(cubes[0]);
3561  c_img=cpl_imagelist_get(cubes[0],0);
3562  clx=cpl_image_get_size_x(c_img);
3563  cly=cpl_image_get_size_y(c_img);
3564 
3565 
3566  tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
3567 
3568  /* allocation for a cube structure without the image planes */
3569  /*
3570  for ( i = 0 ; i < n_cubes ; i++ )
3571  {
3572  tmpcubes[i] = (cpl_imagelist*)cpl_malloc(sizeof(cpl_imagelist)) ;
3573  tmpcubes[i]->plane = (cpl_image**)cpl_calloc(cubes[0]->np ,
3574  sizeof(cpl_image*)) ;
3575 
3576  tmpcubes[i]->lx = cubes[0]->lx ;
3577  tmpcubes[i]->ly = cubes[0]->ly ;
3578  tmpcubes[i]->np = cubes[0]->np ;
3579  tmpcubes[i]->nbpix = (ulong32)cubes[0]->lx *
3580  (ulong32)cubes[0]->ly *
3581  (ulong32)cubes[0]->np ;
3582  tmpcubes[i]->history = (char*)NULL ;
3583  tmpcubes[i]->n_comments = 0 ;
3584  tmpcubes[i]->orig_ptype = BPP_DEFAULT ;
3585  tmpcubes[i]->filename = NULL ;
3586  }
3587  */
3588  tmpcubes[0]=cpl_imagelist_duplicate(cubes[0]);
3589 
3590  /*--------------------------------------------------------------------
3591  * center the cubes within the allocated big cube
3592  * that means define the (0,0) positions of the cubes in the image planes
3593  * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
3594  */
3595  /* position of first reference frame, centered in big cube */
3596  llx0 = mlx/2 - clx/2 ;
3597  lly0 = mly/2 - cly/2 ;
3598 
3599  /*--------------------------------------------------------------------
3600  * go through the frame list and determine the lower left edge position
3601  * of the shifted cubes. Additionnally, the sub-pixel offsets are
3602  * determined.
3603  */
3604 
3605 
3606  llx=cpl_calloc(n_cubes,sizeof(int)) ;
3607  lly=cpl_calloc(n_cubes,sizeof(int)) ;
3608  sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
3609  sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
3610 
3611  for ( i = 0 ; i < n_cubes ; i++ )
3612  {
3613  llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
3614  sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
3615  lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
3616  sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
3617  }
3618 
3619  /* -------------------------------------------------------------
3620  * shift the cubes according to the computed sub-pixel offsets
3621  * that means shift the single image planes of each cube
3622  * first determine an interpolation kernel
3623  */
3624  if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
3625  {
3626  sinfo_msg_warning ("could not generate desired interpolation kernel"
3627  " or no kernel_typ was given, the default kernel"
3628  " is used now!") ;
3629  }
3630  /* go through the frame list */
3631  for ( i = 0 ; i < n_cubes ; i++ )
3632  {
3633  /* go through the image planes and shift each plane by a
3634  sub-pixel value */
3635  for ( z = 0 ; z < cnp ; z++ )
3636  {
3637  tmp_img=cpl_imagelist_get(cubes[i],z);
3638  if ( NULL == (shiftedImage = sinfo_new_shift_image(tmp_img,
3639  sub_offsetx[i],
3640  sub_offsety[i],
3641  kernel ) ) )
3642  {
3643  sinfo_msg_error ("could not shift image plane no %d "
3644  "in cube no %d!", z, i) ;
3645  cpl_imagelist_delete(mergedCube) ;
3646  cpl_imagelist_delete(mask) ;
3647  cpl_free(kernel) ;
3648  for( i = 0 ; i < n_cubes ; i++ ) {
3649  cpl_imagelist_delete (tmpcubes[i]) ;
3650  }
3651  cpl_free(tmpcubes);
3652  return NULL ;
3653  }
3654  cpl_imagelist_set(tmpcubes[i],shiftedImage,z);
3655  }
3656  }
3657 
3658  cubedata=cpl_calloc(n_cubes,sizeof(float)) ;
3659 
3660  for ( y = 0 ; y < mly ; y++ )
3661  {
3662  for ( x = 0 ; x < mlx ; x++ )
3663  {
3664  for ( z = 0 ; z < mnp ; z++ )
3665  {
3666  sum = 0. ;
3667  sum2 = 0. ;
3668  n = 0 ;
3669  for ( i = 0 ; i < n_cubes ; i++ )
3670  {
3671  c_img=cpl_imagelist_get(cubes[i],z);
3672 
3673  clx=cpl_image_get_size_x(c_img);
3674  cly=cpl_image_get_size_y(c_img);
3675 
3676  t_img=cpl_imagelist_get(tmpcubes[i],z);
3677  ptdata=cpl_image_get_data_float(t_img);
3678 
3679  m_img=cpl_imagelist_get(mergedCube,z);
3680  pmdata=cpl_image_get_data_float(m_img);
3681  o_img=cpl_imagelist_get(mask,z);
3682  podata=cpl_image_get_data_float(o_img);
3683  /*
3684  find the position of the present cube and go
3685  through the single spectra
3686  */
3687  if ( y >= lly[i] && y < lly[i]+cly &&
3688  x >= llx[i] && x < llx[i]+clx )
3689  {
3690  posx = x - llx[i] ;
3691  posy = y - lly[i] ;
3692  if (!isnan(ptdata[posx+posy*clx]))
3693  {
3694  sum += ptdata[posx+posy*clx] ;
3695  sum2 += (ptdata[posx+posy*clx] *
3696  ptdata[posx+posy*clx]) ;
3697  cubedata[n] = ptdata[posx+posy*clx] ;
3698  n++ ;
3699  }
3700  }
3701  }
3702 
3703  if ( n == 0 )
3704  {
3705  mean = 0. ;
3706  sigma = 0. ;
3707  pmdata[x+y*mlx] = 0. ;
3708  podata[x+y*mlx] = 0 ;
3709  }
3710  else if ( n == 1 )
3711  {
3712  mean = sum ;
3713  sigma = 0. ;
3714  pmdata[x+y*mlx] = mean ;
3715  podata[x+y*mlx] = 1 ;
3716  }
3717  else
3718  {
3719  mean = sum/(double)n ;
3720  sigma = sqrt( (sum2 - sum*mean) / (double)(n - 1) ) ;
3721  ns = 0 ;
3722  for ( i = 0 ; i < n ; i++ )
3723  {
3724  if ( cubedata[i] > mean+factor*sigma ||
3725  cubedata[i] < mean-factor*sigma )
3726  {
3727  continue ;
3728  }
3729  else
3730  {
3731  pmdata[x+y*mlx] += cubedata[i] ;
3732  ns++ ;
3733  }
3734  }
3735  if ( ns == 0 )
3736  {
3737  pmdata[x+y*mlx] = 0. ;
3738  }
3739  else
3740  {
3741  pmdata[x+y*mlx] /= (float)ns ;
3742  }
3743  podata[x+y*mlx] = (float)ns ;
3744  }
3745  }
3746  }
3747  }
3748 
3749  for( i = 0 ; i < n_cubes ; i++ )
3750  {
3751  cpl_imagelist_delete (tmpcubes[i]) ;
3752  }
3753  cpl_free(tmpcubes);
3754  cpl_free(llx);
3755  cpl_free(lly);
3756  cpl_free(sub_offsetx);
3757  cpl_free(sub_offsety);
3758  cpl_free(cubedata);
3759 
3760  /* convert the "free space" in the cube to blank pixels */
3761  sinfo_new_convert_0_to_ZERO_for_cubes(mergedCube) ;
3762  cpl_free(kernel) ;
3763  return mask ;
3764 }
3765 
3766 cpl_imagelist *
3767 sinfo_new_bin_cube(cpl_imagelist *cu,
3768  int xscale,
3769  int yscale,
3770  int xmin,
3771  int xmax,
3772  int ymin,
3773  int ymax)
3774 {
3775  int i,j,k;
3776  cpl_imagelist * cube;
3777  int ilx=0;
3778  //int ily=0;
3779  int olx=0;
3780  int oly=0;
3781  int inp=0;
3782 
3783 
3784 
3785  cpl_image* i_img=NULL;
3786 
3787 
3788 
3789  /* old code
3790  if (NULL == (cube = sinfo_newCube (xmax-xmin+1,ymax-ymin+1, cu->np)) )
3791  {
3792  sinfo_msg_error ("cannot allocate new cube") ;
3793  return NULL ;
3794  }
3795  */
3796  inp=cpl_imagelist_get_size(cu);
3797  i_img=cpl_imagelist_get(cu,0);
3798  ilx=cpl_image_get_size_x(i_img);
3799  //ily=cpl_image_get_size_y(i_img);
3800  olx=xmax-xmin+1;
3801  oly=ymax-ymin+1;
3802 
3803 
3804  cube=cpl_imagelist_new();
3805  cpl_image* o_img=NULL;
3806  for ( i = 0 ; i < inp ; i++ ) {
3807  o_img = cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
3808  cpl_imagelist_set(cube,o_img,i);
3809  }
3810 
3811 
3812  for (i=0;i<inp;i++){
3813  cpl_image* i_img=cpl_imagelist_get(cu,i);
3814  float* pidata=cpl_image_get_data_float(i_img);
3815  o_img=cpl_imagelist_get(cube,i);
3816  float* podata=cpl_image_get_data_float(o_img);
3817  for (j=0 ; j < olx ; j++) {
3818  for (k=0 ; k< oly ; k++) {
3819  podata[j+k*olx]=pidata[((int) (j+xmin)/xscale)+
3820  ((int) (k+ymin)/yscale)*ilx]/
3821  (xscale*yscale);
3822  }
3823  }
3824  }
3825 
3826  return cube;
3827 }
3828 
3829 /* TODO: not used */
3830 cpl_imagelist *
3831 sinfo_new_scale_cube(cpl_imagelist *cu,
3832  float xscale,
3833  float yscale,
3834  char * kernel_type)
3835 {
3836  cpl_imagelist * cube ;
3837  int i=0, j=0, k=0, l=0 ;
3838  int lx_out, ly_out ;
3839  double cur ;
3840  double * invert_transform ;
3841  double neighbors[16] ;
3842  double rsc[8],
3843  sumrs ;
3844  double param[6];
3845  double x, y ;
3846  int px, py ;
3847  int pos ;
3848  int tabx, taby ;
3849  double * kernel ;
3850  int leaps[16] ;
3851  int ilx=0;
3852  int ily=0;
3853 
3854  int inp;
3855  cpl_image* in_img=NULL;
3856 
3857 
3858  if (cu == NULL)
3859  {
3860  sinfo_msg_error ("null cube") ;
3861  return NULL ;
3862  }
3863 
3864  param[0]=xscale;
3865  param[1]=0;
3866  param[2]=0;
3867  param[3]=0;
3868  param[4]=yscale;
3869  param[5]=0;
3870 
3871 
3872  invert_transform = sinfo_invert_linear_transform(param) ;
3873  if (invert_transform == NULL) {
3874  sinfo_msg_error("cannot compute sinfo_invert transform: "
3875  "aborting warping") ;
3876  return NULL ;
3877  }
3878 
3879  /* Generate default interpolation kernel */
3880  kernel = sinfo_generate_interpolation_kernel(kernel_type) ;
3881  if (kernel == NULL) {
3882  sinfo_msg_error("cannot generate kernel: aborting resampling") ;
3883  return NULL ;
3884  }
3885 
3886  /* Compute new image size */
3887  /* Compute new image size */
3888  ilx=cpl_image_get_size_x(cpl_imagelist_get(cu,0));
3889  ily=cpl_image_get_size_y(cpl_imagelist_get(cu,0));
3890  inp=cpl_imagelist_get_size(cu);
3891 
3892  lx_out = (int) ilx*xscale ;
3893  ly_out = (int) ily*yscale ;
3894 
3895  cube=cpl_imagelist_new();
3896  for ( l = 0 ; l < inp ; l++ ) {
3897  in_img = cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
3898  cpl_imagelist_set(cube,in_img,l);
3899  }
3900 
3901  /* old code
3902  if (NULL == (cube = sinfo_newCube (lx_out, ly_out, cu->np)) )
3903  {
3904  sinfo_msg_error (" cannot allocate new cube") ;
3905  return NULL ;
3906  }
3907  */
3908 
3909  for (l=0;l<inp;l++){
3910  in_img=cpl_imagelist_get(cu,l);
3911  cpl_image* ou_img=cpl_imagelist_get(cube,l);
3912  int tlx=cpl_image_get_size_x(in_img);
3913  int tly=cpl_image_get_size_y(in_img);
3914  float* podata=cpl_image_get_data_float(ou_img);
3915  /* Pre compute leaps for 16 closest neighbors positions */
3916  leaps[0] = -1 - tlx ;
3917  leaps[1] = - tlx ;
3918  leaps[2] = 1 - tlx ;
3919  leaps[3] = 2 - tlx ;
3920 
3921  leaps[4] = -1 ;
3922  leaps[5] = 0 ;
3923  leaps[6] = 1 ;
3924  leaps[7] = 2 ;
3925 
3926  leaps[8] = -1 + tlx ;
3927  leaps[9] = tlx ;
3928  leaps[10]= 1 + tlx ;
3929  leaps[11]= 2 + tlx ;
3930 
3931  leaps[12]= -1 + 2*tlx ;
3932  leaps[13]= 2*tlx ;
3933  leaps[14]= 1 + 2*tlx ;
3934  leaps[15]= 2 + 2*tlx ;
3935 
3936  /* Double loop on the output image */
3937  for (j=0 ; j < ly_out ; j++) {
3938  for (i=0 ; i< lx_out ; i++) {
3939  /* Compute the original source for this pixel */
3940 
3941  x = invert_transform[0] * (double)i +
3942  invert_transform[1] * (double)j +
3943  invert_transform[2] ;
3944 
3945  y = invert_transform[3] * (double)i +
3946  invert_transform[4] * (double)j +
3947  invert_transform[5] ;
3948 
3949  /* Which is the closest integer positioned neighbor? */
3950  px = (int)x ;
3951  py = (int)y ;
3952 
3953  if ((px < 1) ||
3954  (px > (tlx-2)) ||
3955  (py < 1) ||
3956  (py > (tly-2)))
3957  podata[i+j*lx_out] = (pixelvalue)0.0 ;
3958  else {
3959  /* Now feed the positions for the closest 16 neighbors */
3960  pos = px + py * tlx ;
3961  for (k=0 ; k<16 ; k++){
3962  if(!isnan(podata[(int)(pos+leaps[k])])) neighbors[k] =
3963  (double)(podata[(int)(pos+leaps[k])]) ;
3964  else neighbors[k]=0;
3965  }
3966 
3967  /* Which tabulated value index shall we use? */
3968  tabx = (x - (double)px) * (double)(TABSPERPIX) ;
3969  taby = (y - (double)py) * (double)(TABSPERPIX) ;
3970 
3971  /* Compute resampling coefficients */
3972  /* rsc[0..3] in x, rsc[4..7] in y */
3973 
3974  rsc[0] = kernel[TABSPERPIX + tabx] ;
3975  rsc[1] = kernel[tabx] ;
3976  rsc[2] = kernel[TABSPERPIX - tabx] ;
3977  rsc[3] = kernel[2 * TABSPERPIX - tabx] ;
3978  rsc[4] = kernel[TABSPERPIX + taby] ;
3979  rsc[5] = kernel[taby] ;
3980  rsc[6] = kernel[TABSPERPIX - taby] ;
3981  rsc[7] = kernel[2 * TABSPERPIX - taby] ;
3982 
3983  sumrs = (rsc[0]+rsc[1]+rsc[2]+rsc[3]) *
3984  (rsc[4]+rsc[5]+rsc[6]+rsc[7]) ;
3985 
3986  /* Compute interpolated pixel now */
3987  cur = rsc[4] * ( rsc[0]*neighbors[0] +
3988  rsc[1]*neighbors[1] +
3989  rsc[2]*neighbors[2] +
3990  rsc[3]*neighbors[3] ) +
3991  rsc[5] * ( rsc[0]*neighbors[4] +
3992  rsc[1]*neighbors[5] +
3993  rsc[2]*neighbors[6] +
3994  rsc[3]*neighbors[7] ) +
3995  rsc[6] * ( rsc[0]*neighbors[8] +
3996  rsc[1]*neighbors[9] +
3997  rsc[2]*neighbors[10] +
3998  rsc[3]*neighbors[11] ) +
3999  rsc[7] * ( rsc[0]*neighbors[12] +
4000  rsc[1]*neighbors[13] +
4001  rsc[2]*neighbors[14] +
4002  rsc[3]*neighbors[15] ) ;
4003 
4004  /* Affect the value to the output image */
4005  podata[i+j*lx_out] = (pixelvalue)(cur/sumrs) ;
4006  /* done ! */
4007  }
4008  }
4009  }
4010  }
4011  cpl_free(kernel) ;
4012  cpl_free(invert_transform) ;
4013  return cube ;
4014 }
4015 
4016 
4025 /* TODO: not used */
4026 cpl_imagelist *
4027 sinfo_cube_zshift(const cpl_imagelist * cube_inp,
4028  const double shift,
4029  double* sub_shift)
4030 {
4031 
4032  cpl_imagelist * cube_out=NULL ;
4033  const cpl_image* img_inp=NULL;
4034  cpl_image* img_out=NULL;
4035  int col, row,z ;
4036  int int_shift ;
4037  int ilx=0;
4038  int ily=0;
4039  int ilz=0;
4040 
4041  int olx=0;
4042  int oly=0;
4043  int olz=0;
4044  int i=0;
4045  const float* pidata=NULL;
4046  float* podata=NULL;
4047 
4048  cknull(cube_inp,"no input cube given!") ;
4049  check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,0));
4050  check_nomsg(ilx=cpl_image_get_size_x(img_inp));
4051  check_nomsg(ily=cpl_image_get_size_y(img_inp));
4052  check_nomsg(ilz=cpl_imagelist_get_size(cube_inp));
4053 
4054  olx=ilx;
4055  oly=ily;
4056  olz=ilz;
4057 
4058  int_shift = sinfo_new_nint(shift) ;
4059  *sub_shift = shift - (double) int_shift ;
4060  if ( int_shift == 0 )
4061  {
4062  cube_out =cpl_imagelist_duplicate(cube_inp) ;
4063  return cube_out ;
4064  }
4065  else
4066  {
4067  /* allocate memory */
4068  cknull(cube_out = cpl_imagelist_new(),"could not allocate memory!") ;
4069  for ( i = 0 ; i < olz ; i++ ) {
4070  check_nomsg(img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT));
4071  check_nomsg(cpl_imagelist_set(cube_out,img_out,i));
4072  }
4073  }
4074 
4075  for(z=0; z< ilz; z++) {
4076  if ( (z-int_shift >= 0 ) && (z - int_shift < olz) ) {
4077  check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,z));
4078  check_nomsg(img_out=cpl_imagelist_get(cube_out,z-int_shift));
4079  check_nomsg(pidata=cpl_image_get_data_float_const(img_inp));
4080  check_nomsg(podata=cpl_image_get_data_float(img_out));
4081  for ( col = 0 ; col < ilx ; col++ ) {
4082  for ( row = 0 ; row < ily ; row++ ) {
4083  podata[col+row*olx] = pidata[col+row*olx] ;
4084  }
4085  }
4086  }
4087  }
4088  return cube_out ;
4089 
4090  cleanup:
4091  sinfo_free_imagelist(&cube_out);
4092  return NULL ;
4093 }
4094 
4103 /* TODO: not used */
4104 cpl_imagelist *
4105 sinfo_cube_zshift_poly(const cpl_imagelist * cube_inp,
4106  const double sub_shift,
4107  const int order)
4108 {
4109  cpl_imagelist * cube_out ;
4110 
4111  float* spec=NULL ;
4112  float* corrected_spec=NULL ;
4113  float* xnum=NULL ;
4114 
4115  float sum=0;
4116  float new_sum=0 ;
4117  float eval=0 ;
4118  float * imageptr=NULL ;
4119  int row=0;
4120  int col=0 ;
4121  int firstpos=0 ;
4122  int n_points=0 ;
4123  int i=0 ;
4124  int flag=0;
4125  int ilx=0;
4126  int ily=0;
4127  int ilz=0;
4128 
4129  int olx=0;
4130  int oly=0;
4131  //int olz=0;
4132  int z=0;
4133 
4134  const float* pidata=NULL;
4135  float* podata=NULL;
4136  const cpl_image* img_inp=NULL;
4137  cpl_image* img_out=NULL;
4138 
4139  if ( cube_inp == NULL ) {
4140  sinfo_msg_error("no imagelist given!") ;
4141  return NULL ;
4142  }
4143 
4144  img_inp=cpl_imagelist_get_const(cube_inp,0);
4145 
4146  ilx=cpl_image_get_size_x(img_inp);
4147  ily=cpl_image_get_size_y(img_inp);
4148  ilz=cpl_imagelist_get_size(cube_inp);
4149 
4150  if ( order <= 0 ) {
4151  sinfo_msg_error("wrong order of interpolation polynom given!") ;
4152  return NULL ;
4153  }
4154 
4155 
4156  olx=ilx;
4157  oly=ily;
4158  //olz=ilz;
4159  /* allocate memory */
4160 
4161  if ( NULL == (cube_out = cpl_imagelist_new()) ) {
4162  sinfo_msg_error ("could not allocate memory!") ;
4163  return NULL ;
4164  } else {
4165  for ( i = 0 ; i < ilz ; i++ ) {
4166  img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
4167  cpl_imagelist_set(cube_out,img_out,i);
4168  }
4169  }
4170 
4171 
4172  n_points = order + 1 ;
4173  if ( n_points % 2 == 0 ) {
4174  firstpos = (int)(n_points/2) - 1 ;
4175  } else {
4176  firstpos = (int)(n_points/2) ;
4177  }
4178 
4179  spec=cpl_calloc(ilz,sizeof(float)) ;
4180  corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
4181  xnum=cpl_calloc(order+1,sizeof(float)) ;
4182 
4183 
4184  /* fill the xa[] array for the polint function */
4185  for ( i = 0 ; i < n_points ; i++ ) {
4186  xnum[i] = i ;
4187  }
4188 
4189  for ( col = 0 ; col < ilx ; col++ ) {
4190  for ( row = 0 ; row < ily ; row++ ) {
4191  for( z=0; z< ilz; z++) {
4192  corrected_spec[z] = 0. ;
4193  }
4194  sum = 0. ;
4195  for ( z = 0 ; z < ilz ; z++ ) {
4196  img_inp=cpl_imagelist_get_const(cube_inp,z);
4197  pidata=cpl_image_get_data_float_const(img_inp);
4198  spec[z] = pidata[col + row*ilx] ;
4199  if (isnan(spec[z]) ) {
4200  spec[z] = 0. ;
4201 
4202  for ( i = z - firstpos ; i < z-firstpos+n_points ; i++ ) {
4203  if ( i < 0 ) continue ;
4204  if ( i >= ilz) continue ;
4205  corrected_spec[i] = ZERO ;
4206  }
4207  }
4208  if ( z != 0 && z != ilz - 1 ) {
4209  sum += spec[z] ;
4210  }
4211 
4212  }
4213 
4214  new_sum = 0. ;
4215  for ( z = 0 ; z < ilz ; z++ ) {
4216 
4217  /* ---------------------------------------------------------------
4218  * now determine the arrays of size n_points with which the
4219  * polynom is determined and determine the position eval
4220  * where the polynom is evaluated in polynomial interpolation.
4221  * Take care of the points near the row edges!
4222  */
4223  if (isnan(corrected_spec[z])) continue ;
4224  if ( z - firstpos < 0 ) {
4225  imageptr = &spec[0] ;
4226  eval = sub_shift + z ;
4227  } else if ( z - firstpos + n_points >= ilz ) {
4228  imageptr = &spec[ilz - n_points] ;
4229  eval = sub_shift + z + n_points - ilz ;
4230  } else {
4231  imageptr = &spec[z-firstpos] ;
4232  eval = sub_shift + firstpos ;
4233  }
4234 
4235  flag=0;
4236  corrected_spec[z]=sinfo_new_nev_ille(xnum,imageptr,order,eval,&flag);
4237  if ( z != 0 && z != ilz - 1 ) {
4238  new_sum += corrected_spec[z] ;
4239  }
4240  }
4241 
4242  /* fill the output spectrum */
4243  for (z = 0 ; z < ilz ; z++ )
4244  {
4245  img_out=cpl_imagelist_get(cube_out,z);
4246  podata=cpl_image_get_data_float(img_out);
4247  if ( new_sum == 0. ) {
4248  new_sum = 1. ;
4249  }
4250  if ( z == 0 ) {
4251  podata[col+row*olx] = ZERO ;
4252  } else if ( z == ilz - 1 ) {
4253  podata[col+row*olx] = ZERO ;
4254  } else if ( isnan(corrected_spec[z]) ) {
4255  podata[col+row*olx] = ZERO ;
4256  } else {
4257  corrected_spec[z] *= sum / new_sum ;
4258  podata[col+row*olx] = corrected_spec[z] ;
4259  }
4260  }
4261 
4262  }
4263  }
4264 
4265  cpl_free(spec) ;
4266  cpl_free(corrected_spec) ;
4267  cpl_free(xnum) ;
4268  return cube_out ;
4269 
4270 
4271 }
4272 
4280 /* TODO: not used */
4281 cpl_imagelist *
4282 sinfo_cube_zshift_spline3(const cpl_imagelist * cube_inp,
4283  const double sub_shift)
4284 {
4285 
4286  cpl_imagelist * cube_out=NULL ;
4287  float* spec=NULL ;
4288  float* corrected_spec=NULL ;
4289  float* xnum=NULL ;
4290  float* eval=NULL ;
4291  float sum=0;
4292  float new_sum=0 ;
4293  int row=0;
4294  int col=0;
4295  int i=0;
4296  int z=0;
4297 
4298  int ilx=0;
4299  int ily=0;
4300  int ilz=0;
4301  int olx=0;
4302  int oly=0;
4303  //int olz=0;
4304 
4305  const float* pidata=NULL;
4306  float* podata=NULL;
4307  const cpl_image* img_inp=NULL;
4308  cpl_image* img_out=NULL;
4309 
4310  if ( cube_inp == NULL ) {
4311  sinfo_msg_error("no imagelist given!") ;
4312  return NULL ;
4313  }
4314 
4315  img_inp=cpl_imagelist_get_const(cube_inp,0);
4316  ilx=cpl_image_get_size_x(img_inp);
4317  ily=cpl_image_get_size_y(img_inp);
4318  ilz=cpl_imagelist_get_size(cube_inp);
4319 
4320 
4321  olx=ilx;
4322  oly=ily;
4323  //olz=ilz;
4324  /* allocate memory */
4325  if ( NULL == (cube_out = cpl_imagelist_new()) ) {
4326  sinfo_msg_error ("could not allocate memory!") ;
4327  return NULL ;
4328  } else {
4329  for ( i = 0 ; i < ilz ; i++ ) {
4330  img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
4331  cpl_imagelist_set(cube_out,img_out,i);
4332  }
4333  }
4334 
4335  xnum=cpl_calloc(ilz,sizeof(float)) ;
4336  /* fill the xa[] array for the spline function */
4337  for ( i = 0 ; i < ilz ; i++ ) {
4338  xnum[i] = i ;
4339  }
4340 
4341  spec=cpl_calloc(ilz,sizeof(float)) ;
4342  corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
4343  eval=cpl_calloc(ilz,sizeof(float)) ;
4344 
4345  for ( col = 0 ; col < ilx ; col++ ) {
4346  for ( row = 0 ; row < ily ; row++ ) {
4347  sum = 0. ;
4348  for ( z = 0 ; z < ilz ; z++ ) {
4349  img_inp=cpl_imagelist_get_const(cube_inp,z);
4350  pidata=cpl_image_get_data_float_const(img_inp);
4351  spec[z] = pidata[col + row*ilx] ;
4352  if (isnan(spec[z]) ) {
4353  for ( i = z-1 ; i <= z+1 ; i++ ) {
4354  if ( i < 0 ) continue ;
4355  if ( i >= ilz) continue ;
4356  corrected_spec[i] = ZERO ;
4357  }
4358  spec[z] = 0. ;
4359  }
4360  sum += spec[z] ;
4361  eval[z] = (float)sub_shift+(float)z ;
4362  }
4363  /* now we do the spline interpolation*/
4364  if ( -1 == sinfo_function1d_natural_spline( xnum, spec, ilz, eval,
4365  corrected_spec, ilz ) )
4366  {
4367  sinfo_msg_error("error in spline interpolation!") ;
4368  return NULL ;
4369  }
4370 
4371  new_sum = 0. ;
4372  for ( z = 0 ; z < ilz ; z++ ) {
4373  if ( isnan(corrected_spec[z]) ) {
4374  continue ;
4375  }
4376  new_sum += corrected_spec[z] ;
4377  }
4378  /* fill output imagelist */
4379  for ( z = 0 ; z < ilz ; z++ ) {
4380  img_out=cpl_imagelist_get(cube_out,z);
4381  podata=cpl_image_get_data_float(img_out);
4382  if ( new_sum == 0. ) new_sum =1. ;
4383  {
4384  if ( isnan(corrected_spec[z]) ) {
4385  podata[col+row*olx] = ZERO ;
4386  } else {
4387  corrected_spec[z] *= sum / new_sum ;
4388  podata[col+row*olx] = corrected_spec[z] ;
4389  }
4390  }
4391  }
4392  }
4393  }
4394  cpl_free(xnum);
4395  cpl_free(spec) ;
4396  cpl_free(corrected_spec) ;
4397  cpl_free(eval) ;
4398 
4399  return cube_out ;
4400 }
4401 
4402 /* kappa-sigma optimized version */
4403 /* The structure for string index data for kappa-sigma
4404  *
4405  * */
4406 struct _CubeData
4407 {
4408  int iCubeNumber;
4409  int iLocalX;
4410  int iLocalY;
4411 };
4412 typedef struct _CubeData CubeData;
4413 
4414 struct _CubeDataVector
4415 {
4416  int size;
4417  CubeData** pdata;
4418 };
4419 typedef struct _CubeDataVector CubeDataVector;
4437 static int sinfo_kappa_sigma_offset_with_mask(
4438  int z_min,
4439  int z_max,
4440  int nCubes,
4441  cpl_imagelist** inputCubes,
4442  const double* exptimes,
4443  cpl_imagelist* imResult,
4444  int* offsetX,
4445  int* offsetY,
4446  cpl_imagelist* sky_mask,
4447  const double kappa
4448 );
4449 static void
4450 sinfo_kappa_sigma_CubeDataVector(
4451  int globalX,
4452  int globalY,
4453  CubeDataVector* pCubeDataVector,
4454  cpl_imagelist* imlistResult,
4455  cpl_imagelist** input_cubes,
4456  cpl_imagelist* sky_mask,
4457  int iPlanesNumber,
4458  int z_min,
4459  const double kappa,
4460  const double* exptimes
4461 );
4462 
4463 double
4464 sinfo_kappa_sigma_array_with_mask(cpl_array* parray, int szArray,
4465  const double kappa,cpl_image* imMask,
4466  const double* exptimes, int x, int y,
4467  double mask_delta)
4468 {
4469  double result = 0;
4470  int nInvalidPoints = 0;
4471  const double EPS = 1E-10;
4472  //sinfo_msg("sinfo_kappa_sigma_array_with_mask, x[%d] y[%d]"
4473  double mask_adjustment = mask_delta;
4474  do
4475  {
4476  double median = 0;
4477  double sig = 0;
4478  int z = 0;
4479  nInvalidPoints = 0;
4480 
4481  check_nomsg(median = cpl_array_get_median(parray));
4482  check_nomsg(sig = cpl_array_get_stdev(parray));
4483  for (z = 0; z < szArray; z++)
4484  {
4485  int isnull = 0;
4486  double value = 0;
4487  check_nomsg(value = cpl_array_get(parray, z, &isnull));
4488  if(!isnull)
4489  {
4490  if (fabs(value - median) > (kappa * sig))
4491  {
4492 
4493  // sinfo_msg("entered");
4494  // sinfo_msg("val=%g check=%g",
4495  // fabs(value - median),(kappa * sig));
4496  // sinfo_msg("kappa=%f sig=%g median=%g value=%g",
4497  // kappa,sig,median,value);
4498 
4499  //double msk_new_value = 0;
4500  cpl_array_fill_window_invalid(parray, z, 1);
4501  mask_adjustment += exptimes[z];
4502  ++nInvalidPoints;
4503  }
4504  }
4505  }
4506  /*if (nInvalidPoints)
4507  {
4508  sinfo_msg("nInvalidPoints %d[%d][%d] median[%f] sig[%f]", nInvalidPoints,x,y, median, sig );
4509  }*/
4510 
4511  }
4512  while (nInvalidPoints);
4513  if(imMask && fabs(mask_adjustment) > EPS)
4514  {
4515  // adjust mask image
4516  int px_rejected = 0;
4517  double msk_value = 0;
4518  check_nomsg(msk_value = cpl_image_get(imMask, x, y, &px_rejected));
4519  check_nomsg(cpl_image_set(imMask, x,y, msk_value - mask_adjustment));
4520  }
4521  // get a result value for the point
4522  check_nomsg(result = cpl_array_get_mean(parray));
4523  return result;
4524  cleanup:
4525  sinfo_msg("Error in sinfo_kappa_sigma_array_with_mask");
4526  return 0;
4527 }
4528 
4529 
4530 int sinfo_coadd_with_ks_clip_optimized(
4531  const int z_min,
4532  const int z_max,
4533  const int n_cubes,
4534  const double kappa,
4535  int* llx,
4536  int* lly,
4537  double* exptimes,
4538  cpl_imagelist* sky_mask,
4539  cpl_imagelist* mergedCube,
4540  cpl_imagelist** tmpcubes
4541 )
4542 {
4543  /*
4544  sinfo_msg("sinfo_coadd_with_ks_clip_optimized() z_min[%d] z_max[%d] n_cubes[%d] kappa[%f] llx[%d] lly[%d] exptimes[%d] sky_mask[%d]",
4545  z_min, z_max, ilx, ily, n_cubes, kappa,llx, lly,exptimes,sky_mask);
4546  */
4547  int result=0;
4548  check_nomsg(result=sinfo_kappa_sigma_offset_with_mask(z_min, z_max, n_cubes, tmpcubes, exptimes, mergedCube, llx, lly, sky_mask, kappa));
4549 
4550  cleanup:
4551 
4552  return result;
4553 
4554 }
4555 
4556 static int sinfo_kappa_sigma_offset_with_mask(
4557  int z_min,
4558  int z_max,
4559  int nCubes,
4560  cpl_imagelist** inputCubes,
4561  const double* exptimes,
4562  cpl_imagelist* imResult,
4563  int* global_offsetX,
4564  int* global_offsetY,
4565  cpl_imagelist* sky_mask,
4566  const double kappa
4567 )
4568 {
4569  const int BIG_ENOUGH_INT = 65535;
4570  CubeDataVector*** indexX = 0;
4571  int x = 0;
4572  int y = 0;
4573  int z = 0;
4574  int iPlanesNumber = z_max - z_min;
4575  int nIndexXbytes = 0;
4576  int globalSizeX = 0 ;
4577  int globalSizeY = 0;
4578 
4579  int xmax = -BIG_ENOUGH_INT;
4580  int ymax = -BIG_ENOUGH_INT;
4581  int xmin = BIG_ENOUGH_INT;
4582  int ymin = BIG_ENOUGH_INT;
4583  int* offsetX = 0; // local offset of the cubes, normalized
4584  int* offsetY = 0;
4585  //sinfo_msg(" starting kappa-sigma clipping for cubes[%d] planes[%d]", nCubes, z_max - z_min );
4586  // determine size of the coadded cube
4587  sinfo_check_rec_status(0);
4588  for (z = 0; z < nCubes; z++)
4589  {
4590 
4591  cpl_imagelist* pCube = inputCubes[z];
4592  cpl_image* pImage = 0;
4593  int localMaxX = 0;
4594  int localMaxY = 0;
4595  int localMinX = 0;
4596  int localMinY = 0;
4597 
4598  pImage = cpl_imagelist_get(pCube, 0);
4599 
4600  localMaxX = cpl_image_get_size_x(pImage) + global_offsetX[z];
4601  localMaxY = cpl_image_get_size_y(pImage) + global_offsetY[z];
4602  localMinX = global_offsetX[z];
4603  localMinY = global_offsetY[z];
4604 
4605  if(localMaxX > xmax) xmax = localMaxX;
4606  if(localMaxY > ymax) ymax = localMaxY;
4607 
4608  if(localMinX < xmin) xmin = localMinX;
4609  if(localMinY < ymin) ymin = localMinY;
4610  }
4611  sinfo_check_rec_status(1);
4612 
4613  // DFS09121 xmax and ymax could be more then output cube - check and adjust
4614  {
4615  int msize_x = 0;
4616  int msize_y = 0;
4617  //sinfo_msg("DFS09121 before: xmax=%d ymax=%d", xmax, ymax);
4618  cpl_image * pmaskimage = cpl_imagelist_get(sky_mask, 0);
4619  msize_x = cpl_image_get_size_x(pmaskimage);
4620  msize_y = cpl_image_get_size_y(pmaskimage);
4621  xmax = msize_x < xmax ? msize_x : xmax;
4622  ymax = msize_y < ymax ? msize_y : ymax;
4623  //sinfo_msg("DFS09121 after: xmax=%d ymax=%d", xmax, ymax);
4624  }
4625  // rely on the data received outside
4626  globalSizeX = xmax;// - xmin;
4627  globalSizeY = ymax;// - ymin;
4628  // calculate local offset
4629  check_nomsg(offsetX = cpl_malloc(sizeof(offsetX[0]) * nCubes));
4630  check_nomsg(offsetY = cpl_malloc(sizeof(offsetY[0]) * nCubes));
4631  sinfo_check_rec_status(2);
4632  for (z = 0; z < nCubes; z++) // use the offset from the caller
4633  {
4634  offsetX[z] = global_offsetX[z];// - xmin;
4635  offsetY[z] = global_offsetY[z];// - ymin;
4636  // sinfo_msg("for cube [%d] offset X[%d : %d] Y[%d : %d]", z, offsetX[z], global_offsetX[z], offsetY[z], global_offsetY[z]);
4637  }
4638  sinfo_check_rec_status(3);
4639  // Because of DFS09121, the allocated size is taken +1
4640  nIndexXbytes = sizeof(CubeDataVector**) * (globalSizeX+1 );
4641  // sinfo_msg(" kappa_sigma_offset, globalSizeX[%d] globalSizeY[%d] nIndexXbytes[%d]", globalSizeX, globalSizeY, nIndexXbytes);
4642  indexX = cpl_malloc(nIndexXbytes);
4643  memset(&indexX[0], 0, (globalSizeX+1 )* sizeof(indexX[0]));
4644  // prepare result planes and mask
4645 
4646  // 1. Fill indexes - do it only for a 0 plane in the cube
4647  for (z = 0; z < nCubes; z++)
4648  {
4649  int iCubeSizeX = 0;
4650  int iCubeSizeY = 0;
4651  int iOffsetX = 0;
4652  int iOffsetY = 0;
4653 
4654  cpl_imagelist* pCube = inputCubes[z];
4655  cpl_image* pImage = 0;
4656  pImage = cpl_imagelist_get(pCube, 0);
4657 
4658  iCubeSizeX = cpl_image_get_size_x(pImage);
4659  iCubeSizeY = cpl_image_get_size_y(pImage);
4660  iOffsetX = offsetX[z];
4661  iOffsetY = offsetY[z];
4662  // sinfo_msg(" processing cube [%d] offsetX[%d] offsetY[%d] iCubeSizeX[%d] iCubeSizeY[%d]", z, iOffsetX, iOffsetY, iCubeSizeX, iCubeSizeY);
4663  for (x = 1; x <= iCubeSizeX; x++)
4664  {
4665  int iGlobalX = x + iOffsetX;
4666 
4667  CubeDataVector** ppVector = 0;
4668  if (indexX[iGlobalX - 1] == 0)
4669  {
4670  // Because of DFS09121, the allocated size is taken +1
4671  int nBytes = sizeof(CubeDataVector*) * (globalSizeY+1 );
4672  ppVector= cpl_malloc(nBytes);
4673  memset(&ppVector[0],0,(globalSizeY+1) * sizeof(ppVector[0]));
4674  indexX[iGlobalX - 1] = ppVector;
4675  }
4676  else
4677  {
4678  ppVector = indexX[iGlobalX - 1];
4679  }
4680  for (y = 1; y <=iCubeSizeY; y++)
4681  {
4682  CubeData* pCubeData = 0;
4683  int iGlobalY = y + iOffsetY;
4684  CubeDataVector* pVector = ppVector[iGlobalY - 1];
4685  if(pVector == 0)
4686  {
4687  int nbytes = sizeof(CubeDataVector);
4688  check_nomsg(pVector = cpl_malloc(nbytes));
4689  ppVector[iGlobalY - 1] = pVector;
4690  pVector->size = 0;
4691  nbytes = sizeof(CubeData*) * nCubes;
4692  pVector->pdata = cpl_malloc(nbytes);
4693  // memset(&pVector->pdata[0], 0, nCubes * sizeof(pVector->pdata[0]));
4694  }
4695  pCubeData = cpl_malloc(sizeof(CubeData));
4696  pVector->pdata[(pVector->size)++] = pCubeData;
4697  pCubeData->iCubeNumber = z;
4698  pCubeData->iLocalX = x;
4699  pCubeData->iLocalY = y;
4700  }
4701  }
4702  }
4703  sinfo_check_rec_status(4);
4704 
4705  // 2. for each index value in global coordinates (x,y) call kappa-sigma
4706  for (x = 1; x <= globalSizeX; x++)
4707  {
4708  CubeDataVector** pDataX = indexX[x - 1];
4709  if (pDataX)
4710  {
4711  for (y = 1; y <= globalSizeY; y++)
4712  {
4713  CubeDataVector* pDataY = pDataX[y - 1];
4714  if (pDataY && pDataY->size)
4715  {
4716  sinfo_kappa_sigma_CubeDataVector(x, y, pDataY, imResult,
4717  inputCubes, sky_mask, iPlanesNumber, z_min,
4718  kappa, exptimes);
4719  }
4720  if (pDataY)
4721  {
4722  check_nomsg(cpl_free(pDataY->pdata));
4723  check_nomsg(cpl_free(pDataY));
4724  }
4725  }
4726  check_nomsg(cpl_free(pDataX));
4727  }
4728  }
4729  sinfo_check_rec_status(5);
4730  cleanup:
4731  cpl_free(indexX);
4732  cpl_free(offsetX);
4733  cpl_free(offsetY);
4734  return 0;
4735 
4736 }
4737 
4738 static void
4739 sinfo_kappa_sigma_CubeDataVector(
4740  int globalX,
4741  int globalY,
4742  CubeDataVector* pCubeDataVector,
4743  cpl_imagelist* imlistResult,
4744  cpl_imagelist** input_cubes,
4745  cpl_imagelist* sky_mask,
4746  int iPlanesNumber,
4747  int z_min,
4748  const double kappa,
4749  const double* exptimes
4750 )
4751 {
4752  int plane = 0;
4753  int z = 0;
4754 
4755  // iterate through all planes
4756  cpl_array* pArray = 0;
4757  check_nomsg(pArray = cpl_array_new(pCubeDataVector->size, CPL_TYPE_DOUBLE));
4758 
4759 
4760  for (plane = z_min; plane < z_min + iPlanesNumber; plane++)
4761  {
4762  //double val_msk = 0; // value of the mask in the point
4763  //int px = 0;
4764  cpl_image* imResult = 0;
4765  cpl_image* imMask = 0;
4766  double mask_adjustment = 0;
4767  int nValidPoints = 0;
4768  cpl_array_fill_window_invalid(pArray, 0, pCubeDataVector->size);
4769  check_nomsg(imMask = cpl_imagelist_get(sky_mask, plane - z_min));
4770  //check_nomsg(val_msk = cpl_image_get(imMask, globalX, globalY, &px));
4771  for (z = 0; z < pCubeDataVector->size; z++) // through all cubes for that point - prepare the array
4772  {
4773 
4774  cpl_imagelist* pCube = 0;
4775  CubeData* pCubeData = pCubeDataVector->pdata[z];
4776  pCube = input_cubes[pCubeData->iCubeNumber];
4777  if (pCube)
4778  {
4779  cpl_image* pImage = cpl_imagelist_get(pCube, plane - z_min);
4780 
4781  if (pImage)
4782  {
4783  int is_rejected = 0;
4784  double value = 0;
4785  check_nomsg(value = cpl_image_get(pImage, pCubeData->iLocalX,
4786  pCubeData->iLocalY, &is_rejected));
4787  if (!isnan(value))
4788  {
4789  check_nomsg(cpl_array_set(pArray, z, value));
4790  ++nValidPoints;
4791  }
4792  else
4793  {
4794  mask_adjustment += exptimes[z];
4795  }
4796  }
4797  else
4798  {
4799  sinfo_msg("pImage is null");
4800  }
4801  }
4802  }
4803  if(nValidPoints)
4804  {
4805  sinfo_kappa_sigma_array_with_mask(pArray, pCubeDataVector->size,
4806  kappa, imMask, exptimes, globalX, globalY,
4807  mask_adjustment);
4808  check_nomsg(imResult = cpl_imagelist_get(imlistResult, plane));
4809  if (imResult)
4810  {
4811  check_nomsg(cpl_image_set(imResult, globalX, globalY,
4812  cpl_array_get_mean(pArray)));
4813  }
4814  else
4815  {
4816  sinfo_msg("imResult is null");
4817  }
4818  } else
4819  {
4820  // adjust the mask
4821  check_nomsg(cpl_image_set(imMask, globalX,globalY, 0));
4822  }
4823  }
4824  for (z = 0; z < pCubeDataVector->size; z++) // through all cubes - delete the data
4825  {
4826  CubeData* pCubeData = pCubeDataVector->pdata[z];
4827  cpl_free(pCubeData);
4828  }
4829  cpl_array_delete(pArray);
4830  return;
4831  cleanup:
4832  // sinfo_msg(" -----cleanup");
4833  return;
4834 }
4835 
4836 /* TODO: not used */
4837 static int
4838 sinfo_coadd_with_ks_clip(const int z_min,
4839  const int z_max,
4840  const int ilx,
4841  const int ily,
4842  const int n_cubes,
4843  const double kappa,
4844  int* llx,
4845  int* lly,
4846  double* exptimes,
4847  cpl_imagelist* mask,
4848  cpl_imagelist* mergedCube,
4849  cpl_imagelist** tmpcubes)
4850 
4851 {
4852 
4853  int m=0;
4854  int x=0;
4855  int y=0;
4856  int z=0;
4857 
4858  //int mly=0;
4859  int nc=0;
4860  int olx=0;
4861  int oly=0;
4862  int posx=0;
4863  int posy=0;
4864  int i=0;
4865  int nclip=0;
4866  int ks=0;
4867 
4868  float sig=0;
4869  float med=0;
4870  float ovr=0;
4871  float msk_sum=0;
4872  float val_msk_sum=0;
4873  //float avg=0;
4874 
4875  float* pmdata=NULL;
4876  float* ptdata=NULL;
4877  float* pvdata=NULL;
4878  cpl_image* t_img=NULL;
4879  cpl_image* v_img=NULL;
4880 
4881 
4882  cpl_vector* val=NULL;
4883  cpl_vector* msk=NULL;
4884 
4885 
4886  cpl_image* o_img=cpl_imagelist_get(mergedCube,0);
4887  olx=cpl_image_get_size_x(o_img);
4888  oly=cpl_image_get_size_y(o_img);
4889 
4890  m=0;
4891  for ( z = z_min; z < z_max ; z++ ) {
4892  cpl_image* m_img=cpl_imagelist_get(mask,z);
4893  pmdata=cpl_image_get_data_float(m_img);
4894  o_img=cpl_imagelist_get(mergedCube,z);
4895  float* podata=cpl_image_get_data_float(o_img);
4896  int mlx=cpl_image_get_size_x(m_img);
4897  //mly=cpl_image_get_size_y(m_img);
4898  // go through the first image plane of the big data cube
4899  for ( y = 0 ; y < oly ; y++ ) {
4900  for ( x = 0 ; x < olx ; x++ ) {
4901  //avg=0;
4902  nc=0;
4903  // computes nc
4904  for ( i = 0 ; i < n_cubes ; i++ ) {
4905  t_img=cpl_imagelist_get(tmpcubes[i],m);
4906  ptdata=cpl_image_get_data_float(t_img);
4907  if ( y >= lly[i] && y < lly[i]+ily &&
4908  x >= llx[i] && x < llx[i]+ilx ) {
4909  posx = x - llx[i] ;
4910  posy = y - lly[i] ;
4911  if (!isnan(ptdata[posx+posy*ilx]) &&
4912  ptdata[posx+posy*ilx] != 0.) {
4913  nc++;
4914  }
4915  }
4916  }
4917  if( nc > 0 ) {
4918 
4919 
4920  msk=cpl_vector_new(n_cubes);
4921  for (i=0;i<n_cubes;i++) {
4922  cpl_vector_set(msk,i,1);
4923  }
4924 
4925  // k-s clipping
4926  nclip=0;
4927 
4928 
4929  for (ks=0;ks<nc;ks++) {
4930  sig=0;
4931  med=0;
4932  ovr=0;
4933  if(nc-nclip >0) {
4934  val=cpl_vector_new(nc-nclip);
4935  }
4936  // fill val
4937  for ( i = 0 ; i < n_cubes ; i++ ) {
4938  t_img=cpl_imagelist_get(tmpcubes[i],m);
4939  ptdata=cpl_image_get_data_float(t_img);
4940  if ( y >= lly[i] && y < lly[i]+ily &&
4941  x >= llx[i] && x < llx[i]+ilx ) {
4942  posx = x - llx[i] ;
4943  posy = y - lly[i] ;
4944  if (!isnan(ptdata[posx+posy*ilx]) &&
4945  ptdata[posx+posy*ilx] != 0. &&
4946  (cpl_vector_get(msk,i) != 0)) {
4947  cpl_vector_set(val,ovr,(double)ptdata[posx+posy*ilx]);
4948  ovr++;
4949  }
4950  }
4951  }
4952 
4953  // get avg, med, sig
4954  if(ovr>0) {
4955  //avg=cpl_vector_get_mean(val);
4956  med=cpl_vector_get_median_const(val);
4957  if(ovr>1) {
4958  sig=cpl_vector_get_stdev(val);
4959  } else {
4960  sig=0;
4961  }
4962  cpl_vector_delete(val);
4963  }
4964 
4965  for ( i = 0 ; i < n_cubes ; i++ ) {
4966  t_img=cpl_imagelist_get(tmpcubes[i],m);
4967  ptdata=cpl_image_get_data_float(t_img);
4968  // Do k-s clipping at each pixel
4969  if ( y >= lly[i] && y < lly[i]+ily &&
4970  x >= llx[i] && x < llx[i]+ilx ) {
4971  posx = x - llx[i] ;
4972  posy = y - lly[i] ;
4973  if (!isnan(ptdata[posx+posy*ilx]) &&
4974  ptdata[posx+posy*ilx] != 0. &&
4975  (cpl_vector_get(msk,i) != 0)) {
4976  if(abs((ptdata[posx+posy*ilx]-med))> kappa*sig) {
4977  ptdata[posx+posy*ilx]=0;
4978  pmdata[x+y*mlx] -= exptimes[i] ;
4979  cpl_vector_set(msk,i,0);
4980  nclip++;
4981  }
4982  }
4983  }
4984  }
4985  } // end of k-s clipping
4986 
4987  msk_sum=0;
4988  val_msk_sum=0;
4989  for ( i = 0 ; i < n_cubes ; i++ ) {
4990  v_img=cpl_imagelist_get(tmpcubes[i],m);
4991  pvdata=cpl_image_get_data_float(v_img);
4992  // computes sky at each point
4993  if ( y >= lly[i] && y < lly[i]+ily &&
4994  x >= llx[i] && x < llx[i]+ilx ) {
4995  posx = x - llx[i] ;
4996  posy = y - lly[i] ;
4997  //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
4998  //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
4999  if (!isnan(pvdata[posx+posy*ilx]) &&
5000  pvdata[posx+posy*ilx] != 0. &&
5001  (cpl_vector_get(msk,i) != 0)) {
5002  msk_sum+=pmdata[x+y*mlx];
5003  val_msk_sum+=pvdata[posx+posy*ilx]*
5004  pmdata[x+y*mlx];
5005  }
5006  }
5007  }
5008  podata[x+y*olx]=val_msk_sum/msk_sum;
5009  cpl_vector_delete(msk);
5010  /*
5011  sinfo_ks_clip(n_cubes,nc,ilx,ily,kappa,llx,lly,exptimes,
5012  tmpcubes,podata,pmdata,x,y,m,mlx,oly);
5013 
5014  */
5015 
5016  } // end check if overlap nc >0
5017  } // end loop over x
5018  } // end loop over y
5019  m++;
5020  } // end loop over z
5021 
5022  return 0;
5023 
5024 
5025 }
5026 
5027 
5028 
5029 
5030 static int
5031 sinfo_compute_contributes_at_pos(cpl_imagelist** tmpcubes,
5032  int* llx, int* lly,
5033  const int x, const int y,
5034  const int ilx, const int ily,
5035  const int m,const int n_cubes)
5036 {
5037 
5038  int result=0;
5039  int i=0;
5040  int post=0;
5041  int posx=0;
5042  int posy=0;
5043 
5044  /* computes nc the number of intensity contributes from
5045  each overlapping cube point intensity at x,y
5046  */
5047  for ( i = 0 ; i < n_cubes ; i++ ) {
5048  cpl_image* t_img=cpl_imagelist_get(tmpcubes[i],m);
5049  float* ptdata=cpl_image_get_data_float(t_img);
5050  int lox=llx[i];
5051  int loy=lly[i];
5052  int upx=llx[i]+ilx;
5053  int upy=lly[i]+ily;
5054 
5055  if ( y >= loy && y < upy && x >= lox && x < upx ) {
5056  posx = x - lox;
5057  posy = y - loy;
5058  post = posx+posy*ilx;
5059 
5060  if (!isnan(ptdata[post]) && ptdata[post] != 0.) {
5061  result++;
5062  }
5063  }
5064  }
5065 
5066 
5067  return result;
5068 
5069 }
5070 
5071 
5072 
5073 
5074 static int
5075 sinfo_cubes_coadd_with_ks_clip(cpl_imagelist** tmpcubes,
5076  const int n_cubes,const int nc,
5077  const int x, const int y, const int m,
5078  int* llx, int* lly,
5079  const int ilx, const int ily,
5080  const double kappa,
5081  double* exptimes, float** pmdata,
5082  cpl_vector** msk, const int mlx)
5083 
5084 
5085 {
5086 
5087 
5088  cpl_vector* val=NULL;
5089  cpl_image* t_img=NULL;
5090 
5091  int i=0;
5092  int nclip=0;
5093  int ks=0;
5094 
5095  int lox=0;
5096  int loy=0;
5097  int upx=0;
5098  int upy=0;
5099 
5100  int posx=0;
5101  int posy=0;
5102  int post=0;
5103 
5104  int ovr=0;
5105 
5106  float sig=0;
5107  //float avg=0;
5108  float med=0;
5109 
5110  float* ptdata=NULL;
5111 
5112 
5113  // k-s clipping
5114  nclip=0;
5115 
5116 
5117  for (ks=0;ks<nc;ks++) {
5118  sig=0;
5119  med=0;
5120  ovr=0;
5121  if(nc-nclip >0) {
5122  check_nomsg(val=cpl_vector_new(nc-nclip));
5123  }
5124  // fill val
5125  for ( i = 0 ; i < n_cubes ; i++ ) {
5126  check_nomsg(t_img=cpl_imagelist_get(tmpcubes[i],m));
5127  check_nomsg(ptdata=cpl_image_get_data_float(t_img));
5128 
5129  lox=llx[i];
5130  loy=lly[i];
5131  upx=llx[i]+ilx;
5132  upy=lly[i]+ily;
5133 
5134  if ( y >= loy && y < upy && x >= lox && x < upx ) {
5135  posx = x - lox ;
5136  posy = y - loy ;
5137  post=posx+posy*ilx;
5138 
5139  if (!isnan(ptdata[post]) && ptdata[post] != 0. &&
5140  (cpl_vector_get(*msk,i) != 0)) {
5141  cpl_vector_set(val,ovr,(double)ptdata[post]);
5142  ovr++;
5143  }
5144  }
5145  }
5146 
5147  // get avg, med, sig
5148  if(ovr>0) {
5149  //check_nomsg(avg=cpl_vector_get_mean(val));
5150  med=cpl_vector_get_median_const(val);
5151  if(ovr>1) {
5152  sig=cpl_vector_get_stdev(val);
5153  } else {
5154  sig=0;
5155  }
5156  cpl_vector_delete(val);
5157  }
5158 
5159  for ( i = 0 ; i < n_cubes ; i++ ) {
5160  t_img=cpl_imagelist_get(tmpcubes[i],m);
5161  ptdata=cpl_image_get_data_float(t_img);
5162 
5163  lox=llx[i];
5164  loy=lly[i];
5165  upx=llx[i]+ilx;
5166  upy=lly[i]+ily;
5167 
5168  // Do k-s clipping at each pixel
5169  if ( y >= loy && y < upy && x >= lox && x < upx ) {
5170  posx = x - lox ;
5171  posy = y - loy ;
5172  post = posx+posy*ilx;
5173  if (!isnan(ptdata[post]) && ptdata[post] != 0. &&
5174  (cpl_vector_get(*msk,i) != 0)) {
5175  if( abs( (ptdata[post]-med) ) > kappa*sig ) {
5176  ptdata[post]=0;
5177  (*pmdata)[x+y*mlx] -= exptimes[i] ;
5178  check_nomsg(cpl_vector_set(*msk,i,0));
5179  nclip++;
5180  }
5181  }
5182  }
5183  }
5184  } // end of k-s clipping
5185 
5186  cleanup:
5187  return 0;
5188 }
5189 
5213 static int
5214 sinfo_coadd_with_ks_clip2(const int z_min,
5215  const int z_max,
5216  const int ilx,
5217  const int ily,
5218  const int n_cubes,
5219  const double kappa,
5220  int* llx,
5221  int* lly,
5222  double* exptimes,
5223  cpl_imagelist* mask,
5224  cpl_imagelist* mergedCube,
5225  cpl_imagelist** tmpcubes)
5226 
5227 {
5228 
5229  int m=0;
5230  int x=0;
5231  int y=0;
5232  int z=0;
5233 
5234  //int mly=0;
5235  int nc=0;
5236  int olx=0;
5237  int oly=0;
5238  int posx=0;
5239  int posy=0;
5240  int i=0;
5241 
5242  float msk_sum=0;
5243  float val_msk_sum=0;
5244  //float avg=0;
5245 
5246  float* pmdata=NULL;
5247  float* pvdata=NULL;
5248 
5249  cpl_image* o_img=NULL;
5250  cpl_image* v_img=NULL;
5251 
5252 
5253  cpl_vector* msk=NULL;
5254 
5255 
5256  o_img=cpl_imagelist_get(mergedCube,0);
5257  olx=cpl_image_get_size_x(o_img);
5258  oly=cpl_image_get_size_y(o_img);
5259 
5260  m=0;
5261  for ( z = z_min; z < z_max ; z++ ) {
5262  cpl_image* m_img=cpl_imagelist_get(mask,z);
5263  pmdata=cpl_image_get_data_float(m_img);
5264  o_img=cpl_imagelist_get(mergedCube,z);
5265  float* podata=cpl_image_get_data_float(o_img);
5266  int mlx=cpl_image_get_size_x(m_img);
5267  //mly=cpl_image_get_size_y(m_img);
5268  // go through the first image plane of the big data cube
5269  for ( y = 0 ; y < oly ; y++ ) {
5270  for ( x = 0 ; x < olx ; x++ ) {
5271  //avg=0;
5272  //nc=0;
5273  // computes nc
5274 
5275  nc=sinfo_compute_contributes_at_pos(tmpcubes,llx,lly,x,y,
5276  ilx,ily,m,n_cubes);
5277 
5278  if( nc > 0 ) {
5279 
5280 
5281  msk=cpl_vector_new(n_cubes);
5282  for (i=0;i<n_cubes;i++) {
5283  cpl_vector_set(msk,i,1);
5284  }
5285 
5286 
5287  sinfo_cubes_coadd_with_ks_clip(tmpcubes, n_cubes,nc,x,y,m,
5288  llx,lly,ilx,ily,kappa,
5289  exptimes,&pmdata, &msk,mlx);
5290 
5291  msk_sum=0;
5292  val_msk_sum=0;
5293  for ( i = 0 ; i < n_cubes ; i++ ) {
5294  v_img=cpl_imagelist_get(tmpcubes[i],m);
5295  pvdata=cpl_image_get_data_float(v_img);
5296  // computes sky at each point
5297  if ( y >= lly[i] && y < lly[i]+ily &&
5298  x >= llx[i] && x < llx[i]+ilx ) {
5299  posx = x - llx[i] ;
5300  posy = y - lly[i] ;
5301  //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
5302  //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
5303  if (!isnan(pvdata[posx+posy*ilx]) &&
5304  pvdata[posx+posy*ilx] != 0. &&
5305  (cpl_vector_get(msk,i) != 0)) {
5306  msk_sum+=pmdata[x+y*mlx];
5307  val_msk_sum+=pvdata[posx+posy*ilx]*
5308  pmdata[x+y*mlx];
5309  }
5310  }
5311  }
5312  podata[x+y*olx]=val_msk_sum/msk_sum;
5313  cpl_vector_delete(msk);
5314  /*
5315  sinfo_ks_clip(n_cubes,nc,ilx,ily,kappa,llx,lly,exptimes,
5316  tmpcubes,podata,pmdata,x,y,m,mlx,oly);
5317 
5318  */
5319 
5320  } // end check if overlap nc >0
5321  } // end loop over x
5322  } // end loop over y
5323  m++;
5324  } // end loop over z
5325 
5326  return 0;
5327 
5328 
5329 }
5330 
5331 cpl_error_code
5332 sinfo_imagelist_reject_value(cpl_imagelist* iml,cpl_value value)
5333 {
5334  int sz=cpl_imagelist_get_size(iml);
5335  int i;
5336  for(i=0;i<sz;i++) {
5337  cpl_image* ima=cpl_imagelist_get(iml,i);
5338  cpl_image_reject_value(ima, CPL_VALUE_NAN);
5339  }
5340  return cpl_error_get_code();
5341 }
5342 
5343 
#define sinfo_msg_debug(...)
Print a debug message.
Definition: sinfo_msg.h:103
#define sinfo_msg_error(...)
Print an error message.
Definition: sinfo_msg.h:69
#define sinfo_msg_warning(...)
Print an warning message.
Definition: sinfo_msg.h:93