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