X-shooter Pipeline Reference Manual 3.8.15
xsh_utils_image.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-shooter Pipeline *
3 * Copyright (C) 2006 European Southern Observatory *
4 * *
5 * This library 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/*
21 * $Author: amodigli $
22 * $Date: 2013-03-13 12:35:04 $
23 * $Revision: 1.87 $
24 * $Name: not supported by cvs2svn $
25 */
26
27#include <xsh_utils_wrappers.h>
28#include <xsh_utils_image.h>
29#include <xsh_error.h>
30#include <xsh_utils.h>
31#include <xsh_pfits_qc.h>
32#include <xsh_pfits.h>
33#include <xsh_dfs.h>
34#include <xsh_data_pre.h>
35#include <xsh_data_instrument.h>
36#include <math.h>
37#include <string.h>
38#include <float.h>
39#define FLAG -1.e+9
40
41
42/*----------------------------------------------------------------------------
43 Function prototypes
44 ---------------------------------------------------------------------------*/
45
46
47static Stats *
48xsh_image_stats_on_rectangle ( cpl_image * im,
49 float loReject,
50 float hiReject,
51 int llx,
52 int lly,
53 int urx,
54 int ury );
55
56
57
58
59
60static cpl_image*
61xsh_image_crop(const cpl_image *image,
62 int xlo, int ylo,
63 int xhi, int yhi);
64
65static float
66xsh_clean_mean( float * array,
67 int n_elements,
68 float throwaway_low,
69 float throwaway_high ) ;
70
71
72static cpl_error_code
74 const double dxdu,
75 const double dydv,
76 const double dxdv,
77 const double dydu,
78 const double du,
79 const double dv,
80 double* dA);
81
82
83static double xsh_sinc(double x);
84static void reverse_tanh_kernel(double * data, int nn);
85
86static cpl_image *
87xsh_gen_lowpass(const int xs,
88 const int ys,
89 const double sigma_x,
90 const double sigma_y);
91
108static cpl_error_code
110 const double dxdu,
111 const double dydv,
112 const double dxdv,
113 const double dydu,
114 const double du,
115 const double dv,
116 double* dA)
117{
118
119
120 *dA=fabs(dxdu*dydv-dxdv*dydu)*du*dv;
121 return cpl_error_get_code();
122
123}
124
125
133cpl_image*
135{
136
137 cpl_image* out=NULL;
138 //float* pdata=NULL;
139 int sx=0;
140 int sy=0;
141 register int i=0;
142 register int j=0;
143 double dxdu=0;
144 double dydv=0;
145 double dxdv=0;
146 double dydu=0;
147 double du=0;
148 double dv=0;
149 double dA=0;
150
151 assure (in != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
152 check(sx=cpl_image_get_size_x(in));
153 check(sy=cpl_image_get_size_y(in));
154
155 //pdata=cpl_image_get_data_float(out);
156 for(j=0;j<sy;j++) {
157 for(i=0;i<sx;i++) {
158 //Here we compute dxdu,dydv,dxdv,dydu,du,dv using some extra input
159 //describing the transformation u=f(x,y) v=g(x,y) or the inverse
160 // x=F(u,v) y=G(u,v)
161 check(xsh_compute_geom_corr(dxdu,dydv,dxdv,dydu,du,dv,&dA));
162 }
163 }
164
165 cleanup:
166
167 if(cpl_error_get_code() != CPL_ERROR_NONE) {
168 xsh_free_image(&out);
169 return NULL;
170 } else {
171 return out;
172 }
173}
174
175
176
177
178/*-------------------------------------------------------------------------*/
202/*--------------------------------------------------------------------------*/
203
204double *
205xsh_generate_interpolation_kernel(const char * kernel_type)
206{
207 double * tab ;
208 int i ;
209 double x ;
210 double alpha ;
211 double inv_norm ;
212 int samples = KERNEL_SAMPLES ;
213
214 if (kernel_type==NULL) {
216 } else if (!strcmp(kernel_type, "default")) {
218 } else if (!strcmp(kernel_type, "sinc")) {
219 tab = cpl_malloc(samples * sizeof(double)) ;
220 tab[0] = 1.0 ;
221 tab[samples-1] = 0.0 ;
222 for (i=1 ; i<samples ; i++) {
223 x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
224 tab[i] = xsh_sinc(x) ;
225 }
226 } else if (!strcmp(kernel_type, "sinc2")) {
227 tab = cpl_malloc(samples * sizeof(double)) ;
228 tab[0] = 1.0 ;
229 tab[samples-1] = 0.0 ;
230 for (i=1 ; i<samples ; i++) {
231 x = 2.0 * (double)i/(double)(samples-1) ;
232 tab[i] = xsh_sinc(x) ;
233 tab[i] *= tab[i] ;
234 }
235 } else if (!strcmp(kernel_type, "lanczos")) {
236 tab = cpl_malloc(samples * sizeof(double)) ;
237 for (i=0 ; i<samples ; i++) {
238 x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
239 if (fabs(x)<2) {
240 tab[i] = xsh_sinc(x) * xsh_sinc(x/2) ;
241 } else {
242 tab[i] = 0.00 ;
243 }
244 }
245 } else if (!strcmp(kernel_type, "hamming")) {
246 tab = cpl_malloc(samples * sizeof(double)) ;
247 alpha = 0.54 ;
248 inv_norm = 1.00 / (double)(samples - 1) ;
249 for (i=0 ; i<samples ; i++) {
250 x = (double)i ;
251 if (i<(samples-1)/2) {
252 tab[i] = alpha + (1-alpha) * cos(2.0*M_PI*x*inv_norm) ;
253 } else {
254 tab[i] = 0.0 ;
255 }
256 }
257 } else if (!strcmp(kernel_type, "hann")) {
258 tab = cpl_malloc(samples * sizeof(double)) ;
259 alpha = 0.50 ;
260 inv_norm = 1.00 / (double)(samples - 1) ;
261 for (i=0 ; i<samples ; i++) {
262 x = (double)i ;
263 if (i<(samples-1)/2) {
264 tab[i] = alpha + (1-alpha) * cos(2.0*M_PI*x*inv_norm) ;
265 } else {
266 tab[i] = 0.0 ;
267 }
268 }
269 } else if (!strcmp(kernel_type, "tanh")) {
271 } else {
272 xsh_msg_error("unrecognized kernel type [%s]: aborting generation",
273 kernel_type) ;
274 return NULL ;
275 }
276
277 return tab ;
278}
279
280
281/*-------------------------------------------------------------------------*/
292/*--------------------------------------------------------------------------*/
293
294static double
295xsh_sinc(double x)
296{
297 if (fabs(x)<1e-4)
298 return (double)1.00 ;
299 else
300 return ((sin(x * (double)M_PI)) / (x * (double)M_PI)) ;
301}
302
303
304
305/*-------------------------------------------------------------------------*/
341/*--------------------------------------------------------------------------*/
342
343cpl_image *
345 cpl_image * image_in,
346 char * kernel_type,
347 cpl_polynomial * poly_u,
348 cpl_polynomial * poly_v
349)
350{
351 cpl_image * image_out ;
352 int i, j, k ;
353 int lx_out, ly_out ;
354 double cur ;
355 double neighbors[16] ;
356 double rsc[8],
357 sumrs ;
358 double x, y ;
359 int px, py ;
360 int pos ;
361 int tabx, taby ;
362 double * kernel ;
363 int leaps[16] ;
364 int ilx=0;
365 int ily=0;
366 float* pidata=NULL;
367 float* podata=NULL;
368 cpl_vector* vx=NULL;
369 if (image_in == NULL) return NULL ;
370
371
372 /* Generate default interpolation kernel */
373 kernel = xsh_generate_interpolation_kernel(kernel_type) ;
374 if (kernel == NULL) {
375 xsh_msg_error("cannot generate kernel: aborting resampling") ;
376 return NULL ;
377 }
378 ilx=cpl_image_get_size_x(image_in);
379 ily=cpl_image_get_size_y(image_in);
380 pidata=cpl_image_get_data_float(image_in);
381
382 /* Compute new image size */
383 lx_out = (int)ilx ;
384 ly_out = (int)ily ;
385
386 image_out = cpl_image_new(lx_out, ly_out,CPL_TYPE_FLOAT) ;
387 podata=cpl_image_get_data_float(image_out);
388
389 /* Pre compute leaps for 16 closest neighbors positions */
390
391 leaps[0] = -1 - ilx ;
392 leaps[1] = - ilx ;
393 leaps[2] = 1 - ilx ;
394 leaps[3] = 2 - ilx ;
395
396 leaps[4] = -1 ;
397 leaps[5] = 0 ;
398 leaps[6] = 1 ;
399 leaps[7] = 2 ;
400
401 leaps[8] = -1 + ilx ;
402 leaps[9] = ilx ;
403 leaps[10]= 1 + ilx ;
404 leaps[11]= 2 + ilx ;
405
406 leaps[12]= -1 + 2*ilx ;
407 leaps[13]= 2*ilx ;
408 leaps[14]= 1 + 2*ilx ;
409 leaps[15]= 2 + 2*ilx ;
410
411 vx=cpl_vector_new(2); /* vector of size 2 = polynomial dimension */
412 /* Double loop on the output image */
413 for (j=0 ; j < ly_out ; j++) {
414 for (i=0 ; i< lx_out ; i++) {
415 /* Compute the original source for this pixel */
416 cpl_vector_set(vx,0,(double)i);
417 cpl_vector_set(vx,1,(double)j);
418 x = cpl_polynomial_eval(poly_u, vx);
419 y = cpl_polynomial_eval(poly_v, vx);
420
421 /* Which is the closest integer positioned neighbor? */
422 px = (int)x ;
423 py = (int)y ;
424
425 if ((px < 1) ||
426 (px > (ilx-3)) ||
427 (py < 1) ||
428 (py > (ily-3)))
429 podata[i+j*lx_out] = (pixelvalue)0.0/0.0 ;
430 else {
431 /* Now feed the positions for the closest 16 neighbors */
432 pos = px + py * ilx ;
433 for (k=0 ; k<16 ; k++)
434 neighbors[k] = (double)(pidata[(int)(pos+leaps[k])]) ;
435
436 /* Which tabulated value index shall we use? */
437 tabx = (x - (double)px) * (double)(TABSPERPIX) ;
438 taby = (y - (double)py) * (double)(TABSPERPIX) ;
439
440 /* Compute resampling coefficients */
441 /* rsc[0..3] in x, rsc[4..7] in y */
442
443 rsc[0] = kernel[TABSPERPIX + tabx] ;
444 rsc[1] = kernel[tabx] ;
445 rsc[2] = kernel[TABSPERPIX - tabx] ;
446 rsc[3] = kernel[2 * TABSPERPIX - tabx] ;
447 rsc[4] = kernel[TABSPERPIX + taby] ;
448 rsc[5] = kernel[taby] ;
449 rsc[6] = kernel[TABSPERPIX - taby] ;
450 rsc[7] = kernel[2 * TABSPERPIX - taby] ;
451
452 sumrs = (rsc[0]+rsc[1]+rsc[2]+rsc[3]) *
453 (rsc[4]+rsc[5]+rsc[6]+rsc[7]) ;
454
455 /* Compute interpolated pixel now */
456 cur = rsc[4] * ( rsc[0]*neighbors[0] +
457 rsc[1]*neighbors[1] +
458 rsc[2]*neighbors[2] +
459 rsc[3]*neighbors[3] ) +
460 rsc[5] * ( rsc[0]*neighbors[4] +
461 rsc[1]*neighbors[5] +
462 rsc[2]*neighbors[6] +
463 rsc[3]*neighbors[7] ) +
464 rsc[6] * ( rsc[0]*neighbors[8] +
465 rsc[1]*neighbors[9] +
466 rsc[2]*neighbors[10] +
467 rsc[3]*neighbors[11] ) +
468 rsc[7] * ( rsc[0]*neighbors[12] +
469 rsc[1]*neighbors[13] +
470 rsc[2]*neighbors[14] +
471 rsc[3]*neighbors[15] ) ;
472
473 /* Affect the value to the output image */
474 podata[i+j*lx_out] = (pixelvalue)(cur/sumrs) ;
475 /* done ! */
476 }
477 }
478 }
479 cpl_vector_delete(vx);
480 cpl_free(kernel) ;
481 return image_out ;
482}
483
484
485#define hk_gen(x,s) (((tanh(s*(x+0.5))+1)/2)*((tanh(s*(-x+0.5))+1)/2))
486
487/*-------------------------------------------------------------------------*/
508/*--------------------------------------------------------------------------*/
509
510double * xsh_generate_tanh_kernel(double steep)
511{
512 double * kernel ;
513 double * x ;
514 double width ;
515 double inv_np ;
516 double ind ;
517 int i ;
518 int np ;
519 int samples ;
520
521 width = (double)TABSPERPIX / 2.0 ;
522 samples = KERNEL_SAMPLES ;
523 np = 32768 ; /* Hardcoded: should never be changed */
524 inv_np = 1.00 / (double)np ;
525
526 /*
527 * Generate the kernel expression in Fourier space
528 * with a correct frequency ordering to allow standard FT
529 */
530 x = cpl_malloc((2*np+1)*sizeof(double)) ;
531 for (i=0 ; i<np/2 ; i++) {
532 ind = (double)i * 2.0 * width * inv_np ;
533 x[2*i] = hk_gen(ind, steep) ;
534 x[2*i+1] = 0.00 ;
535 }
536 for (i=np/2 ; i<np ; i++) {
537 ind = (double)(i-np) * 2.0 * width * inv_np ;
538 x[2*i] = hk_gen(ind, steep) ;
539 x[2*i+1] = 0.00 ;
540 }
541
542 /*
543 * Reverse Fourier to come back to image space
544 */
546
547 /*
548 * Allocate and fill in returned array
549 */
550 kernel = cpl_malloc(samples * sizeof(double)) ;
551 for (i=0 ; i<samples ; i++) {
552 kernel[i] = 2.0 * width * x[2*i] * inv_np ;
553 }
554 cpl_free(x) ;
555 return kernel ;
556}
557
558
559#define KERNEL_SW(a,b) tempr=(a);(a)=(b);(b)=tempr
560/*-------------------------------------------------------------------------*/
572/*--------------------------------------------------------------------------*/
573
574static void
575reverse_tanh_kernel(double * data, int nn)
576{
577 unsigned long n,
578 mmax,
579 m,
580 i, j,
581 istep ;
582 double wtemp,
583 wr,
584 wpr,
585 wpi,
586 wi,
587 theta;
588 double tempr,
589 tempi;
590
591 n = (unsigned long)nn << 1;
592 j = 1;
593 for (i=1 ; i<n ; i+=2) {
594 if (j > i) {
595 KERNEL_SW(data[j-1],data[i-1]);
596 KERNEL_SW(data[j],data[i]);
597 }
598 m = n >> 1;
599 while (m>=2 && j>m) {
600 j -= m;
601 m >>= 1;
602 }
603 j += m;
604 }
605 mmax = 2;
606 while (n > mmax) {
607 istep = mmax << 1;
608 theta = 2 * M_PI / mmax;
609 wtemp = sin(0.5 * theta);
610 wpr = -2.0 * wtemp * wtemp;
611 wpi = sin(theta);
612 wr = 1.0;
613 wi = 0.0;
614 for (m=1 ; m<mmax ; m+=2) {
615 for (i=m ; i<=n ; i+=istep) {
616 j = i + mmax;
617 tempr = wr * data[j-1] - wi * data[j];
618 tempi = wr * data[j] + wi * data[j-1];
619 data[j-1] = data[i-1] - tempr;
620 data[j] = data[i] - tempi;
621 data[i-1] += tempr;
622 data[i] += tempi;
623 }
624 wr = (wtemp = wr) * wpr - wi * wpi + wr;
625 wi = wi * wpr + wtemp * wpi + wi;
626 }
627 mmax = istep;
628 }
629}
630#undef KERNEL_SW
631
632
633
634/*-------------------------------------------------------------------------*/
647/*--------------------------------------------------------------------------*/
648
649void xsh_show_interpolation_kernel(char * kernel_name)
650{
651 double * ker ;
652 int i ;
653 double x ;
654
655
656 ker = xsh_generate_interpolation_kernel(kernel_name) ;
657 if (ker == NULL)
658 return ;
659
660 (void)fprintf(stdout, "# Kernel is %s\n", kernel_name) ;
661 x = 0.00 ;
662 for (i=0 ; i<KERNEL_SAMPLES ; i++) {
663 (void)fprintf(stdout, "%g %g\n", x, ker[i]) ;
664 x += 1.00 / (double)TABSPERPIX ;
665 }
666 cpl_free(ker) ;
667 return ;
668}
669
677double
678xsh_image_get_stdev_robust(const cpl_image *image,
679 double cut,
680 double *dstdev)
681{
682 cpl_mask *rejected = NULL;
683 cpl_image *im = NULL;
684 double median = 0;
685 double robust_stdev = 0;
686
687 assure (image != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
688 assure( cut > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal cut: %f", cut );
689 assure( dstdev == NULL, CPL_ERROR_ILLEGAL_INPUT, "Unsupported");
690
691 median = cpl_image_get_median(image);
692
693 im = cpl_image_duplicate(image);
694 cpl_image_subtract_scalar(im, median);
695 cpl_image_power(im, 2);
696 /* Now squared residuals wrt median */
697
698 rejected = cpl_mask_threshold_image_create(image,median - cut,
699 median + cut);
700 cpl_mask_not(rejected);
701 cpl_image_reject_from_mask(im, rejected);
702
703 robust_stdev = sqrt(cpl_image_get_mean(im));
704
705 cleanup:
706 xsh_free_image(&im);
707 xsh_free_mask(&rejected);
708
709 return robust_stdev;
710}
711
718double xsh_image_get_stdev_clean(const cpl_image *image,
719 double *dstdev)
720{
721 cpl_mask *rejected = NULL;
722 cpl_image *im = NULL;
723 double median = 0;
724 double stdev = 0;
725 double robust_stdev = 0;
726 double kappa=3.0;
727 double cut=0;
728
729 assure (image != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
730 assure( dstdev == NULL, CPL_ERROR_ILLEGAL_INPUT, "Unsupported");
731
732 median = cpl_image_get_median(image);
733 stdev=cpl_image_get_stdev(image);
734 cut=kappa*stdev;
735
736 im = cpl_image_duplicate(image);
737 cpl_image_subtract_scalar(im, median);
738 cpl_image_power(im, 2);
739 /* Now squared residuals wrt median */
740
741 rejected = cpl_mask_threshold_image_create(image,median - cut,
742 median + cut);
743 cpl_mask_not(rejected);
744 cpl_image_reject_from_mask(im, rejected);
745
746 robust_stdev = sqrt(cpl_image_get_mean(im));
747
748 cleanup:
749 xsh_free_image(&im);
750 xsh_free_mask(&rejected);
751
752 return robust_stdev;
753}
754
755
756
764double
765xsh_fixed_pattern_noise(const cpl_image *master,
766 double convert_ADU,
767 double master_noise)
768{
769 double master_fixed_pattern_noise=0;
770 cpl_image *image1 = NULL;
771 cpl_image *image2 = NULL;
772
773 assure (master != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
774
775 /* Use central 101x101 window
776 and 101x101 window shifted (10, 10) from center
777 */
778 if (cpl_image_get_size_x(master) >= 121 &&
779 cpl_image_get_size_y(master) >= 121) {
780
781 int mid_x = (cpl_image_get_size_x(master) + 1) / 2;
782 int mid_y = (cpl_image_get_size_y(master) + 1) / 2;
783
784
785 image1=xsh_image_crop(master,
786 mid_x - 50, mid_y - 50,
787 mid_x + 50, mid_y + 50);
788
789
790 image2=xsh_image_crop(master,
791 mid_x + 10 - 50, mid_y + 10 - 50,
792 mid_x + 10 + 50, mid_y + 10 + 50);
793
794 cpl_image_subtract(image1, image2);
795
796 master_fixed_pattern_noise = cpl_image_get_stdev(image1) / sqrt(2);
797
798 /* Convert to ADU */
799 master_fixed_pattern_noise *= convert_ADU;
800
801 /* Subtract photon noise */
802 if (master_fixed_pattern_noise >= master_noise) {
803
804 master_fixed_pattern_noise = sqrt(master_fixed_pattern_noise*
805 master_fixed_pattern_noise
806 -
807 master_noise*
808 master_noise);
809 }
810 else {
811 cpl_msg_warning(cpl_func,
812 "Zero-shift noise (%f ADU) is greater than "
813 "accumulated zero-shift and fixed pattern noise (%f ADU), "
814 "setting fixed pattern noise to zero",
815 master_noise,
816 master_fixed_pattern_noise);
817 master_fixed_pattern_noise = 0;
818 }
819 }
820 else {
821 cpl_msg_warning(cpl_func,
822 "Master flat too small (%" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT "), "
823 "need size 121x121 to compute master flat "
824 "fixed pattern noise",
825 cpl_image_get_size_x(master),
826 cpl_image_get_size_y(master));
827 master_fixed_pattern_noise = -1;
828 }
829
830 cleanup:
831 xsh_free_image(&image1);
832 xsh_free_image(&image2);
833
834 return master_fixed_pattern_noise;
835}
836
844double
845xsh_fixed_pattern_noise_bias(const cpl_image *first_raw,
846 const cpl_image *second_raw,
847 double ron)
848{
849 double bias_fixed_pattern_noise=0;
850 cpl_image *image1 = NULL;
851 cpl_image *image2 = NULL;
852 int nx, ny;
853
854 assure (first_raw != NULL, CPL_ERROR_NULL_INPUT,"NULL input image");
855 assure (second_raw != NULL, CPL_ERROR_NULL_INPUT,"NULL input image");
856
857 /*
858 * Extract the largest possible two windows shifted (10, 10)
859 */
860
861 nx = cpl_image_get_size_x(first_raw);
862 ny = cpl_image_get_size_y(first_raw);
863
864
865 image1=xsh_image_crop(first_raw, 1, 1,nx - 10, ny - 10);
866
867
868 image2=xsh_image_crop(second_raw, 11, 11,nx, ny);
869
870 cpl_image_subtract(image1, image2);
871
872 bias_fixed_pattern_noise = xsh_image_get_stdev_robust(image1, 50, NULL)
873 / sqrt(2);
874
875 /*
876 * Subtract ron quadratically
877 */
878
879 if (bias_fixed_pattern_noise > ron) {
880
881 bias_fixed_pattern_noise = sqrt(bias_fixed_pattern_noise *
882 bias_fixed_pattern_noise
883 -
884 ron * ron);
885 }
886 else {
887 cpl_msg_warning(cpl_func,
888 "Zero-shift noise (%f ADU) is greater than "
889 "accumulated zero-shift and fixed pattern "
890 "noise (%f ADU), "
891 "setting fixed pattern noise to zero",
892 ron,
893 bias_fixed_pattern_noise);
894 bias_fixed_pattern_noise = 0;
895 }
896
897 cleanup:
898 xsh_free_image(&image1);
899 xsh_free_image(&image2);
900
901 return bias_fixed_pattern_noise;
902}
903
904
919static cpl_image*
920xsh_image_crop(const cpl_image *image,
921 int xlo, int ylo,
922 int xhi, int yhi)
923{
924 /* CPL is missing the function to locally extract an image,
925 so this this inefficient CPL function */
926 cpl_image *image_crop = NULL;
927 assure( image != NULL, CPL_ERROR_ILLEGAL_INPUT, "Null input image" );
928 assure( 1 <= xlo && xlo <= xhi && xhi <= cpl_image_get_size_x(image) &&
929 1 <= ylo && ylo <= yhi && yhi <= cpl_image_get_size_y(image),
930 CPL_ERROR_ILLEGAL_INPUT,
931 "Cannot extraction region (%d, %d) - (%d, %d) of %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " image",
932 xlo, ylo, xhi, yhi,
933 cpl_image_get_size_x(image),
934 cpl_image_get_size_y(image));
935
936
937
938 check(image_crop = cpl_image_extract(image,xlo, ylo,xhi, yhi));
939
940/* Not computed for the moment
941 cpl_image *new_data = cpl_image_extract(image,xlo, ylo,xhi, yhi);
942 cpl_image_delete(image);
943
944 cpl_image* new_variance = cpl_image_extract(image->variance,
945 xlo, ylo,
946 xhi, yhi);
947 cpl_image_delete(image->variance);
948
949 image->data = new_data;
950 image->variance = new_variance;
951*/
952 cleanup:
953 if(cpl_error_get_code() != CPL_ERROR_NONE) {
954 return NULL;
955 } else {
956 return image_crop;
957 }
958}
959
960
961
1012cpl_error_code xsh_image_warp_polynomial_scale(cpl_image *out,
1013 const cpl_polynomial *poly_x,
1014 const cpl_polynomial *poly_y)
1015{
1016 cpl_polynomial *dxdu=NULL;
1017 cpl_polynomial *dxdv=NULL;
1018 cpl_polynomial *dydu=NULL;
1019 cpl_polynomial *dydv=NULL;
1020
1021 cpl_vector *val=NULL;
1022 double *pval=NULL;
1023
1024 double *ddata=NULL;
1025 float *fdata=NULL;
1026
1027 int nx, ny;
1028 int i, j;
1029
1030
1031 if (out == NULL || poly_x == NULL || poly_y == NULL)
1032 return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1033
1034 if (cpl_polynomial_get_dimension(poly_x) != 2 ||
1035 cpl_polynomial_get_dimension(poly_y) != 2)
1036 return cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1037
1038 if (cpl_image_get_type(out) != CPL_TYPE_FLOAT &&
1039 cpl_image_get_type(out) != CPL_TYPE_DOUBLE)
1040 return cpl_error_set(cpl_func, CPL_ERROR_INVALID_TYPE);
1041
1042
1043 /*
1044 * Compute the partial derivatives of the transformation:
1045 */
1046
1047 dxdu = cpl_polynomial_duplicate(poly_x);
1048 dxdv = cpl_polynomial_duplicate(poly_x);
1049 dydu = cpl_polynomial_duplicate(poly_y);
1050 dydv = cpl_polynomial_duplicate(poly_y);
1051
1052 cpl_polynomial_derivative(dxdu, 0);
1053 cpl_polynomial_derivative(dxdv, 1);
1054 cpl_polynomial_derivative(dydu, 0);
1055 cpl_polynomial_derivative(dydv, 1);
1056
1057
1058 /*
1059 * This section is for assigning the (local) scaling factor
1060 * to each pixel of the reference image.
1061 */
1062
1063 nx = cpl_image_get_size_x(out);
1064 ny = cpl_image_get_size_y(out);
1065
1066 val = cpl_vector_new(2);
1067 pval = cpl_vector_get_data(val);
1068
1069 switch (cpl_image_get_type(out)) {
1070 case CPL_TYPE_FLOAT:
1071 fdata = cpl_image_get_data_float(out);
1072 for (j=0; j < ny; j++) {
1073 pval[1] = j + 1;
1074 for (i=0; i < nx; i++) {
1075 pval[0] = i + 1;
1076 *fdata++ = cpl_polynomial_eval(dxdu, val)
1077 * cpl_polynomial_eval(dydv, val)
1078 - cpl_polynomial_eval(dxdv, val)
1079 * cpl_polynomial_eval(dydu, val);
1080 }
1081 }
1082 break;
1083 case CPL_TYPE_DOUBLE:
1084 ddata = cpl_image_get_data_double(out);
1085 for (j=0; j < ny; j++) {
1086 pval[1] = j + 1;
1087 for (i=0; i < nx; i++) {
1088 pval[0] = i + 1;
1089 *ddata++ = cpl_polynomial_eval(dxdu, val)
1090 * cpl_polynomial_eval(dydv, val)
1091 - cpl_polynomial_eval(dxdv, val)
1092 * cpl_polynomial_eval(dydu, val);
1093 }
1094 }
1095 break;
1096 default:
1097
1098 /*
1099 * Impossible to reach this point. An assert(0) here
1100 * would be in order, but what the heck...
1101 */
1102
1103 break;
1104 }
1105
1106 cpl_vector_delete(val);
1107 cpl_polynomial_delete(dxdu);
1108 cpl_polynomial_delete(dxdv);
1109 cpl_polynomial_delete(dydu);
1110 cpl_polynomial_delete(dydv);
1111
1112
1113 /*
1114 * Ensure the scale factor is positive...
1115 */
1116
1117 cpl_image_abs(out);
1118
1119 return CPL_ERROR_NONE;
1120
1121}
1122
1123
1130cpl_image*
1131xsh_scharr_x(cpl_image* in) {
1132
1133 cpl_image* scharr_x=NULL;
1134 float* pscharr_x=NULL;
1135 float* pin=NULL;
1136 int sx=0;
1137 int sy=0;
1138 int i=0;
1139 int j=0;
1140
1141
1142 check(scharr_x=cpl_image_duplicate(in));
1143 check(pscharr_x=cpl_image_get_data_float(scharr_x));
1144 check(pin=cpl_image_get_data_float(in));
1145 check(sx=cpl_image_get_size_x(in));
1146 check(sy=cpl_image_get_size_y(in));
1147
1148 for(i=1;i<sx-1;i++) {
1149 for(j=1;j<sy-1;j++) {
1150 pscharr_x[i+j*sx]=3*pin[i-1+(j+1)*sx]-3*pin[i+1+(j+1)*sx]+
1151 10*pin[i-1+j*sx]-10*pin[i+1+j*sx]+
1152 3*pin[i-1+(j-1)*sx]-3*pin[i+1+(j-1)*sx];
1153 }
1154 }
1155
1156 cleanup:
1157 return scharr_x;
1158
1159}
1160
1161
1162
1169cpl_image*
1170xsh_scharr_y(cpl_image* in) {
1171
1172 cpl_image* scharr_y=NULL;
1173 float* pscharr_y=NULL;
1174 float* pin=NULL;
1175 int sx=0;
1176 int sy=0;
1177 int i=0;
1178 int j=0;
1179
1180
1181 check(scharr_y=cpl_image_duplicate(in));
1182 check(pscharr_y=cpl_image_get_data_float(scharr_y));
1183 check(pin=cpl_image_get_data_float(in));
1184 check(sx=cpl_image_get_size_x(in));
1185 check(sy=cpl_image_get_size_y(in));
1186
1187 for(i=1;i<sx-1;i++) {
1188 for(j=1;j<sy-1;j++) {
1189 pscharr_y[i+j*sx]=3*pin[i-1+(j+1)*sx]+10*pin[i+(j+1)*sx]+3*pin[i+1+(j+1)*sx]+
1190 -3*pin[i-1+(j-1)*sx]-10*pin[i+(j-1)*sx]-3*pin[i+1+(j-1)*sx];
1191 }
1192 }
1193
1194 cleanup:
1195 return scharr_y;
1196
1197}
1198
1199
1207cpl_image*
1208xsh_sobel_lx(cpl_image* in) {
1209
1210 cpl_image* lx=NULL;
1211 float* plx=NULL;
1212 float* pin=NULL;
1213 int sx=0;
1214 int sy=0;
1215 int i=0;
1216 int j=0;
1217
1218
1219 check(lx=cpl_image_duplicate(in));
1220 check(plx=cpl_image_get_data_float(lx));
1221 check(pin=cpl_image_get_data_float(in));
1222 check(sx=cpl_image_get_size_x(in));
1223 check(sy=cpl_image_get_size_y(in));
1224
1225 for(i=1;i<sx-1;i++) {
1226 for(j=1;j<sy-1;j++) {
1227 plx[i+j*sx]=pin[i-1+(j+1)*sx]-pin[i+1+(j+1)*sx]+
1228 2*pin[i-1+j*sx]-2*pin[i+1+j*sx]+
1229 pin[i-1+(j-1)*sx]-pin[i+1+(j-1)*sx];
1230 }
1231 }
1232
1233 cleanup:
1234 return lx;
1235
1236}
1237
1238
1239
1247cpl_image*
1248xsh_sobel_ly(cpl_image* in) {
1249
1250
1251
1252 cpl_image* ly=NULL;
1253 float* ply=NULL;
1254 float* pin=NULL;
1255 int sx=0;
1256 int sy=0;
1257 int i=0;
1258 int j=0;
1259
1260
1261 check(ly=cpl_image_duplicate(in));
1262 check(ply=cpl_image_get_data_float(ly));
1263 check(pin=cpl_image_get_data_float(in));
1264 check(sx=cpl_image_get_size_x(in));
1265 check(sy=cpl_image_get_size_y(in));
1266
1267 for(i=1;i<sx-1;i++) {
1268 for(j=1;j<sy-1;j++) {
1269 ply[i+j*sx]=pin[i-1+(j+1)*sx]+2*pin[i+(j+1)*sx]+pin[i+1+(j+1)*sx]+
1270 -pin[i-1+(j-1)*sx]-2*pin[i+(j-1)*sx]-pin[i+1+(j-1)*sx];
1271 }
1272 }
1273 cleanup:
1274 return ly;
1275
1276}
1277
1293cpl_error_code
1294xsh_compute_ron(cpl_frameset* frames,
1295 int llx,
1296 int lly,
1297 int urx,
1298 int ury,
1299 int nsampl,
1300 int hsize,
1301 const int reg_id,
1302 double* ron,
1303 double* ron_err)
1304{
1305
1306 cpl_frame* bias1=NULL;
1307 cpl_frame* bias2=NULL;
1308
1309 cpl_image* ima1=NULL;
1310 cpl_image* ima2=NULL;
1311 cpl_image* imad=NULL;
1312
1313 const char* name1=NULL;
1314 const char* name2=NULL;
1315 int nx1=0;
1316 int ny1=0;
1317 int nx2=0;
1318 int ny2=0;
1319 cpl_size zone[4];
1320 int nfrm=0;
1321 cpl_propertylist* plist=NULL;
1322 //const char* name_o="BIAS_PAIR_DIFF.fits";
1323
1324
1325 check(nfrm=cpl_frameset_get_size(frames));
1326
1327 if ( nfrm < 2 ) goto cleanup;
1328
1329 check(bias1=cpl_frameset_get_frame(frames,0));
1330 check(bias2=cpl_frameset_get_frame(frames,1));
1331 check(name1=cpl_frame_get_filename(bias1));
1332 check(name2=cpl_frame_get_filename(bias2));
1333 check(ima1=cpl_image_load(name1,CPL_TYPE_FLOAT,0,0));
1334 check(ima2=cpl_image_load(name2,CPL_TYPE_FLOAT,0,0));
1335
1336 check(nx1=cpl_image_get_size_x(ima1));
1337 check(nx2=cpl_image_get_size_x(ima2));
1338
1339 check(ny1=cpl_image_get_size_y(ima1));
1340 check(ny2=cpl_image_get_size_y(ima2));
1341
1342 if((nx1 != nx2) || (ny1 != ny2)) {
1343 xsh_error_msg("image1's size: [%d,%d] != from image2's size [%d,%d]",
1344 nx1,ny1,nx2,ny2);
1345 goto cleanup;
1346 }
1347
1348 check(plist=cpl_propertylist_load(name1,0));
1349
1350 if(llx == -1) llx=1;
1351 if(lly == -1) lly=1;
1352
1353 if(urx == -1) urx=nx1;
1354 if(ury == -1) ury=ny1;
1355
1356 zone[0]=llx;
1357 zone[1]=urx;
1358 zone[2]=lly;
1359 zone[3]=ury;
1360
1361 check(imad=cpl_image_duplicate(ima1));
1362 check(cpl_image_subtract(imad,ima2));
1363
1364 check(cpl_flux_get_noise_window(imad, zone,hsize,nsampl,ron,ron_err));
1365
1366
1367 *ron/=sqrt(2);
1368 *ron_err/=sqrt(2);
1369
1370
1371
1372 if(reg_id==1) {
1373 xsh_pfits_set_qc_ron1(plist,*ron);
1374 xsh_pfits_set_qc_ron1_err(plist,*ron_err);
1375 } else{
1376 xsh_pfits_set_qc_ron2(plist,*ron);
1377 xsh_pfits_set_qc_ron2_err(plist,*ron_err);
1378 }
1379 check(cpl_propertylist_append_string(plist,XSH_PCATG,"BIAS_PAIR_DIFF"));
1380 //check(cpl_image_save(imad,name_o,CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT));
1381
1382 cleanup:
1383 xsh_free_image(&ima1);
1384 xsh_free_image(&ima2);
1385 xsh_free_image(&imad);
1386 xsh_free_propertylist(&plist);
1387
1388
1389
1390 if (cpl_error_get_code()) {
1391 return -1 ;
1392 } else {
1393 return 0 ;
1394 }
1395
1396
1397}
1398
1428cpl_image *
1430 float thresh_sigma_factor,
1431 float low_threshold,
1432 float high_threshold,
1433 int llx,
1434 int lly,
1435 int urx,
1436 int ury)
1437{
1438 cpl_image * bp_map =NULL;
1439 int z, n, i ;
1440 int lx, ly ;
1441 int row, col ;
1442 int low_n, high_n ;
1443 float * spectrum =NULL;
1444 double pix_sum ;
1445 double sqr_sum ;
1446 Stats * stats =NULL;
1447 cpl_image* img_src=NULL;
1448
1449 float* psrcdata=NULL;
1450 float* pbpdata=NULL;
1451
1452 int lz=0;
1453
1454 if ( NULL == darks )
1455 {
1456 xsh_msg_error("no input cube given!\n") ;
1457 return NULL ;
1458 }
1459
1460 if ( thresh_sigma_factor <= 0. )
1461 {
1462 xsh_msg_error("factor is smaller or equal zero!\n") ;
1463 return NULL ;
1464 }
1465 if ( low_threshold < 0. || high_threshold < 0. || (low_threshold + high_threshold) >= 100. )
1466 {
1467 xsh_msg_error("wrong reject percentage values!\n") ;
1468 return NULL ;
1469 }
1470
1471 lz=cpl_imagelist_get_size(darks);
1472 if ( lz < 1 )
1473 {
1474 xsh_msg_error("not enough dark frames given for good statistics!") ;
1475 return NULL ;
1476 }
1477 img_src=cpl_imagelist_get(darks,0);
1478
1479 lx = cpl_image_get_size_x(img_src) ;
1480 ly = cpl_image_get_size_y(img_src) ;
1481
1482 if (llx == -1) llx=1;
1483 if (lly == -1) lly=1;
1484
1485 if (urx == -1) urx=lx;
1486 if (ury == -1) ury=ly;
1487
1488 llx = (llx<1) ? 1 : llx;
1489 lly = (lly<1) ? 1 : lly;
1490
1491 urx = (urx>lx) ? lx : urx;
1492 ury = (ury>ly) ? lx : ury;
1493
1494
1495
1496 low_n = (int)(low_threshold/100. *(float)lz) ;
1497 high_n = (int)(high_threshold/100. *(float)lz) ;
1498
1499 if (NULL == (bp_map = cpl_image_new (lx, ly,CPL_TYPE_FLOAT) ) )
1500 {
1501 xsh_msg_error("could not allocate new memory!\n") ;
1502 return NULL ;
1503 }
1504 pbpdata=cpl_image_get_data(bp_map);
1505 if (NULL == (spectrum = (float*) cpl_calloc(lz, sizeof(float)) ) )
1506 {
1507 xsh_msg_error("could not allocate new memory!\n") ;
1508 return NULL ;
1509 }
1510
1511
1512 for ( row = 0 ; row < ly ; row++ ) {
1513
1514 for ( col = 0 ; col < lx ; col++ ) {
1515
1516 for ( z = 0 ; z < lz ; z++ ) {
1517 img_src=cpl_imagelist_get(darks,z);
1518 psrcdata=cpl_image_get_data(img_src);
1519 spectrum[z] = psrcdata[col+lx*row] ;
1520 }
1521 xsh_pixel_qsort(spectrum, lz) ;
1522 n = 0 ;
1523 pix_sum = 0.;
1524 sqr_sum = 0.;
1525 for ( i = low_n ; i < lz - high_n ; i++ ) {
1526 pix_sum += (double)spectrum[i] ;
1527 sqr_sum += ((double)spectrum[i]*(double)spectrum[i]) ;
1528 n++ ;
1529 }
1530 /* compute the noise in each pixel */
1531 pix_sum /= (double)n ;
1532 sqr_sum /= (double)n ;
1533
1534 pbpdata[col+lx*row] = (float)sqrt(sqr_sum - pix_sum*pix_sum) ;
1535 }
1536 }
1537
1538 cpl_free(spectrum) ;
1539 if ( NULL == (stats = xsh_image_stats_on_rectangle(bp_map,
1540 low_threshold,
1541 high_threshold,
1542 llx, lly,urx,ury)))
1543 {
1544 xsh_msg_error("could not get image statistics!\n") ;
1545 cpl_image_delete (bp_map) ;
1546 return NULL ;
1547 }
1548
1549
1550 /* now build the bad pixel mask */
1551 for ( row = 0 ; row < ly ; row++ ) {
1552 for ( col = 0 ; col < lx ; col++ ) {
1553 if (pbpdata[col+lx*row] >
1554 stats->cleanmean+thresh_sigma_factor*stats->cleanstdev ||
1555 pbpdata[col+lx*row] <
1556 stats->cleanmean-thresh_sigma_factor*stats->cleanstdev)
1557 {
1558 pbpdata[col+lx*row] = QFLAG_HOT_PIXEL ;
1559 }
1560 else
1561 {
1562 pbpdata[col+lx*row] = 0. ;
1563 }
1564 }
1565 }
1566
1567 cpl_free (stats) ;
1568 return bp_map ;
1569}
1570
1571
1589 float loReject,
1590 float hiReject,
1591 int llx,
1592 int lly,
1593 int urx,
1594 int ury )
1595{
1596 Stats * retstats=NULL;
1597 int i=0 ;
1598 int row=0;
1599 int col=0;
1600 int n=0;
1601 int npix=0;
1602 int lo_n=0;
1603 int hi_n=0;
1604 double pix_sum=0;
1605 double sqr_sum=0;
1606 float * pix_array=NULL;
1607 int im_lx=0;
1608 int im_ly=0;
1609 float* pim=NULL;
1610
1611 if ( NULL == im )
1612 {
1613 xsh_msg_error("sorry, no input image given!") ;
1614 return NULL ;
1615 }
1616 if ( loReject+hiReject >= 100. )
1617 {
1618 xsh_msg_error("sorry, too much pixels rejected!") ;
1619 return NULL ;
1620 }
1621 if ( loReject < 0. || loReject >= 100. ||
1622 hiReject < 0. || hiReject >= 100. )
1623 {
1624 xsh_msg_error("sorry, negative reject values!") ;
1625 return NULL ;
1626 }
1627
1628 im_lx=cpl_image_get_size_x(im);
1629 im_ly=cpl_image_get_size_y(im);
1630 if ( llx < 0 || lly < 0 ||
1631 urx < 0 || ury < 0 ||
1632 llx > im_lx || lly > im_ly ||
1633 urx > im_lx || ury > im_ly ||
1634 ury <= lly || urx <= llx )
1635 {
1636 xsh_msg_error("sorry, wrong pixel coordinates of rectangle!") ;
1637 xsh_msg_error("llx < 0 || lly < 0 ||urx < 0 || ury < 0 ||llx > im_lx || lly > im_ly ||urx > im_lx || ury > im_ly || ury <= lly || urx <= llx");
1638 xsh_msg_error("llx=%d lly=%d urx=%d ury=%d im_lx=%d im_ly=%d",
1639 llx,lly,urx,ury,im_lx,im_ly);
1640 return NULL ;
1641 }
1642
1643 /* allocate memory */
1644 retstats = (Stats*) cpl_calloc(1, sizeof(Stats)) ;
1645 npix = (urx - llx + 1) * (ury - lly + 1) ;
1646 pix_array = (float*) cpl_calloc ( npix, sizeof(float) ) ;
1647
1648 /*-------------------------------------------------------------------------
1649 * go through the rectangle and copy the pixel values into an array.
1650 */
1651 n = 0 ;
1652 pim = cpl_image_get_data_float(im);
1653 int row_min=0;
1654 int row_max=0;
1655 int col_min=0;
1656 int col_max=0;
1657
1658 col_min = (llx>0) ? llx : 0;
1659 row_min = (lly>0) ? lly : 0;
1660 col_max = (urx<im_lx) ? urx : im_lx-1;
1661 row_max = (ury<im_ly) ? ury : im_ly-1;
1662
1663 for ( row = row_min ; row <= row_max ; row++ )
1664 {
1665 for ( col = col_min ; col <= col_max ; col++ )
1666 {
1667 if ( !isnan(pim[col + row*im_lx]) )
1668 {
1669 pix_array[n] = pim[col + row*im_lx] ;
1670 n++ ;
1671 }
1672 }
1673 }
1674
1675 npix = n;
1676 /*if (n != npix)
1677 {
1678 xsh_msg_error("the computed number of pixel equals "
1679 "not the counted number, impossible!") ;
1680 cpl_free(retstats) ;
1681 cpl_free(pix_array) ;
1682 return NULL ;
1683 }*/
1684
1685 /* determining the clean mean is already done in the recipes */
1686 if ( FLT_MAX == (retstats->cleanmean = xsh_clean_mean(pix_array,
1687 npix, loReject, hiReject)) )
1688 {
1689 xsh_msg_error("xsh_clean_mean() did not work!") ;
1690 cpl_free(retstats) ;
1691 cpl_free(pix_array) ;
1692 return NULL ;
1693 }
1694
1695 /* now the clean standard deviation must be calculated */
1696 /* initialize sums */
1697 lo_n = (int) (loReject / 100. * (float)npix) ;
1698 hi_n = (int) (hiReject / 100. * (float)npix) ;
1699 pix_sum = 0. ;
1700 sqr_sum = 0. ;
1701 n = 0 ;
1702 for ( i = lo_n ; i <= npix - hi_n ; i++ )
1703 {
1704 pix_sum += (double)pix_array[i] ;
1705 sqr_sum += ((double)pix_array[i] * (double)pix_array[i]) ;
1706 n++ ;
1707 }
1708
1709 if ( n == 0 )
1710 {
1711 xsh_msg_error("number of clean pixels is zero!") ;
1712 cpl_free(retstats) ;
1713 cpl_free(pix_array) ;
1714 return NULL ;
1715 }
1716 retstats -> npix = n ;
1717 pix_sum /= (double) n ;
1718 sqr_sum /= (double) n ;
1719 retstats -> cleanstdev = (float)sqrt(sqr_sum - pix_sum * pix_sum) ;
1720 cpl_free (pix_array) ;
1721 return retstats ;
1722}
1723
1724#define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }
1725#define PIX_STACK_SIZE 50
1726
1738void
1739xsh_pixel_qsort(pixelvalue *pix_arr, int npix)
1740{
1741 int i,
1742 ir,
1743 j,
1744 k,
1745 l;
1746 int i_stack[PIX_STACK_SIZE*sizeof(pixelvalue)] ;
1747 int j_stack ;
1748 pixelvalue a ;
1749
1750 ir = npix ;
1751 l = 1 ;
1752 j_stack = 0 ;
1753 for (;;) {
1754 if (ir-l < 7) {
1755 for (j=l+1 ; j<=ir ; j++) {
1756 a = pix_arr[j-1];
1757 for (i=j-1 ; i>=1 ; i--) {
1758 if (pix_arr[i-1] <= a) break;
1759 pix_arr[i] = pix_arr[i-1];
1760 }
1761 pix_arr[i] = a;
1762 }
1763 if (j_stack == 0) break;
1764 ir = i_stack[j_stack-- -1];
1765 l = i_stack[j_stack-- -1];
1766 } else {
1767 k = (l+ir) >> 1;
1768 PIX_SWAP(pix_arr[k-1], pix_arr[l])
1769 if (pix_arr[l] > pix_arr[ir-1]) {
1770 PIX_SWAP(pix_arr[l], pix_arr[ir-1])
1771 }
1772 if (pix_arr[l-1] > pix_arr[ir-1]) {
1773 PIX_SWAP(pix_arr[l-1], pix_arr[ir-1])
1774 }
1775 if (pix_arr[l] > pix_arr[l-1]) {
1776 PIX_SWAP(pix_arr[l], pix_arr[l-1])
1777 }
1778 i = l+1;
1779 j = ir;
1780 a = pix_arr[l-1];
1781 for (;;) {
1782 do i++; while (pix_arr[i-1] < a);
1783 do j--; while (pix_arr[j-1] > a);
1784 if (j < i) break;
1785 PIX_SWAP(pix_arr[i-1], pix_arr[j-1]);
1786 }
1787 pix_arr[l-1] = pix_arr[j-1];
1788 pix_arr[j-1] = a;
1789 j_stack += 2;
1790 if (j_stack > PIX_STACK_SIZE) {
1791 xsh_msg_error("stack too small : aborting");
1792 abort() ;
1793 }
1794 if (ir-i+1 >= j-l) {
1795 i_stack[j_stack-1] = ir;
1796 i_stack[j_stack-2] = i;
1797 ir = j-1;
1798 } else {
1799 i_stack[j_stack-1] = j-1;
1800 i_stack[j_stack-2] = l;
1801 l = i;
1802 }
1803 }
1804 }
1805}
1806#undef PIX_STACK_SIZE
1807#undef PIX_SWAP
1808
1825float xsh_clean_mean( float * array,
1826 int n_elements,
1827 float throwaway_low,
1828 float throwaway_high )
1829{
1830 int i, n ;
1831 int lo_n, hi_n ;
1832 float sum ;
1833
1834 if ( array == NULL )
1835 {
1836 xsh_msg_error(" no array given in xsh_clean_mean!") ;
1837 return FLT_MAX ;
1838 }
1839
1840 if ( n_elements <= 0 )
1841 {
1842 xsh_msg_error("wrong number of elements given") ;
1843 return FLT_MAX ;
1844 }
1845
1846 if ( throwaway_low < 0. || throwaway_high < 0. ||
1847 throwaway_low + throwaway_high >= 100. )
1848 {
1849 xsh_msg_error("wrong throw away percentage given!") ;
1850 return FLT_MAX ;
1851 }
1852
1853 lo_n = (int) (throwaway_low * (float)n_elements / 100.) ;
1854 hi_n = (int) (throwaway_high * (float)n_elements / 100.) ;
1855
1856 /* sort the array */
1857 xsh_pixel_qsort( array, n_elements ) ;
1858
1859 n = 0 ;
1860 sum = 0. ;
1861 for ( i = lo_n ; i < n_elements - hi_n ; i++ )
1862 {
1863 if ( !isnan(array[i]) )
1864 {
1865 sum += array[i] ;
1866 n++ ;
1867 }
1868 }
1869 if ( n == 0 )
1870 {
1871 return FLAG ;
1872 }
1873 else
1874 {
1875 return sum/(float)n ;
1876 }
1877}
1878
1879/*-------------------------------------------------------------------------*/
1893/*--------------------------------------------------------------------------*/
1894
1895cpl_image *
1896xsh_image_smooth_fft(cpl_image * inp, const int fx, const int fy)
1897{
1898
1899 int sx=0;
1900 int sy=0;
1901
1902 cpl_image* out=NULL;
1903 cpl_image* im_re=NULL;
1904 cpl_image* im_im=NULL;
1905 cpl_image* ifft_re=NULL;
1906 cpl_image* ifft_im=NULL;
1907 cpl_image* filter=NULL;
1908
1909
1910 cknull_msg(inp,"Null in put image, exit");
1911 check(im_re = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
1912 check(im_im = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
1913
1914 // Compute FFT
1915 check(cpl_image_fft(im_re,im_im,CPL_FFT_DEFAULT));
1916 check(sx=cpl_image_get_size_x(inp));
1917 check(sy=cpl_image_get_size_y(inp));
1918
1919
1920 //Generates filter image
1921 check(filter = xsh_gen_lowpass(sx,sy,fx,fy));
1922
1923 //Apply filter
1924 cpl_image_multiply(im_re,filter);
1925 cpl_image_multiply(im_im,filter);
1926
1928
1929 check(ifft_re = cpl_image_duplicate(im_re));
1930 check(ifft_im = cpl_image_duplicate(im_im));
1931
1932 xsh_free_image(&im_re);
1933 xsh_free_image(&im_im);
1934
1935 //Computes FFT-INVERSE
1936 check(cpl_image_fft(ifft_re,ifft_im,CPL_FFT_INVERSE));
1937 check(out = cpl_image_cast(ifft_re, CPL_TYPE_FLOAT));
1938
1939 cleanup:
1940
1941 xsh_free_image(&ifft_re);
1942 xsh_free_image(&ifft_im);
1944 xsh_free_image(&im_re);
1945 xsh_free_image(&im_im);
1946
1947 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1948 return NULL;
1949 } else {
1950 return out;
1951 }
1952
1953}
1954
1955/*-------------------------------------------------------------------------*/
1971/*--------------------------------------------------------------------------*/
1972static cpl_image *
1973xsh_gen_lowpass(const int xs,
1974 const int ys,
1975 const double sigma_x,
1976 const double sigma_y)
1977{
1978
1979 int i= 0.0;
1980 int j= 0.0;
1981 int hlx= 0.0;
1982 int hly = 0.0;
1983 double x= 0.0;
1984 double y= 0.0;
1985 double gaussval= 0.0;
1986 double inv_sigma_x=1./sigma_x;
1987 double inv_sigma_y=1./sigma_y;
1988
1989 float *data;
1990
1991 cpl_image *lowpass_image=NULL;
1992 int err_no=0;
1993
1994
1995 lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
1996 if (lowpass_image == NULL) {
1997 xsh_msg_error("Cannot generate lowpass filter <%s>",
1998 cpl_error_get_message());
1999 return NULL;
2000 }
2001
2002 hlx = xs/2;
2003 hly = ys/2;
2004
2005 data = cpl_image_get_data_float(lowpass_image);
2006
2007/* Given an image with pixels 0<=i<N, 0<=j<M then the convolution image
2008 has the following properties:
2009
2010 ima[0][0] = 1
2011 ima[i][0] = ima[N-i][0] = exp (-0.5 * (i/sig_i)^2) 1<=i<N/2
2012 ima[0][j] = ima[0][M-j] = exp (-0.5 * (j/sig_j)^2) 1<=j<M/2
2013 ima[i][j] = ima[N-i][j] = ima[i][M-j] = ima[N-i][M-j]
2014 = exp (-0.5 * ((i/sig_i)^2 + (j/sig_j)^2))
2015*/
2016
2017 data[0] = 1.0;
2018
2019 /* first row */
2020 for (i=1 ; i<=hlx ; i++) {
2021 x = i * inv_sigma_x;
2022 gaussval = exp(-0.5*x*x);
2023 data[i] = gaussval;
2024 data[xs-i] = gaussval;
2025 }
2026
2027 for (j=1; j<=hly ; j++) {
2028 y = j * inv_sigma_y;
2029 /* first column */
2030 data[j*xs] = exp(-0.5*y*y);
2031 data[(ys-j)*xs] = exp(-0.5*y*y);
2032
2033 for (i=1 ; i<=hlx ; i++) {
2034 /* Use internal symetries */
2035 x = i * inv_sigma_x;
2036 gaussval = exp (-0.5*(x*x+y*y));
2037 data[j*xs+i] = gaussval;
2038 data[(j+1)*xs-i] = gaussval;
2039 data[(ys-j)*xs+i] = gaussval;
2040 data[(ys+1-j)*xs-i] = gaussval;
2041
2042 }
2043 }
2044
2045 /* FIXME: for the moment, reset err_no which is coming from exp()
2046 in first for-loop at i=348. This is causing cfitsio to
2047 fail when loading an extension image (bug in cfitsio too).
2048 */
2049 if(err_no != 0)
2050 err_no = 0;
2051
2052 return lowpass_image;
2053}
2054
2055
2056/*-------------------------------------------------------------------------*/
2070/*--------------------------------------------------------------------------*/
2071
2072cpl_image *
2073xsh_image_smooth_mean_y(cpl_image * inp, const int r)
2074{
2075
2076
2077 double* pinp = NULL;
2078 double* pout = NULL;
2079 int sx = 0;
2080 int sy = 0;
2081 register int i = 0;
2082 register int j = 0;
2083 register int k = 0;
2084 register int pix=0;
2085 cpl_image* out=NULL;
2086
2087 XSH_ASSURE_NOT_NULL( inp);
2088 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
2089 check(sx = cpl_image_get_size_x(inp));
2090 check(sy = cpl_image_get_size_y(inp));
2091 check(pinp = cpl_image_get_data_double(inp));
2092 check(pout = cpl_image_get_data_double(out));
2093 for( j=r; j<sy-r; j++) {
2094 pix=j*sx+i;
2095 for( i=0; i<sx; i++) {
2096 for( k=-r; k<r; k++) {
2097 pout[pix] += pinp[pix+k*sx];
2098 }
2099 pout[pix]/=(2*r);
2100 }
2101 }
2102
2103 cleanup:
2104 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2105 xsh_free_image( &out);
2106 }
2107 return out;
2108}
2109
2110
2111/*-------------------------------------------------------------------------*/
2125/*--------------------------------------------------------------------------*/
2126
2127cpl_image *
2128xsh_image_smooth_median_y(cpl_image * inp, const int r)
2129{
2130
2131
2132 double* pout=NULL;
2133 int sx=0;
2134 int sy=0;
2135 int i=0;
2136 int j=0;
2137
2138 cpl_image* out=NULL;
2139
2140
2141 cknull_msg(inp,"Null in put image, exit");
2142
2143 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
2144 check(sx=cpl_image_get_size_x(inp));
2145 check(sy=cpl_image_get_size_y(inp));
2146 check(pout=cpl_image_get_data_double(out));
2147
2148 for(j=r+1;j<sy-r;j++) {
2149 for(i=1;i<sx;i++) {
2150 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i,j+r);
2151 }
2152 }
2153
2154 cleanup:
2155
2156 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2157 return NULL;
2158 } else {
2159 return out;
2160
2161 }
2162
2163}
2164
2165
2166/*-------------------------------------------------------------------------*/
2180/*--------------------------------------------------------------------------*/
2181
2182cpl_image *
2183xsh_image_smooth_mean_x( cpl_image * inp, const int r)
2184{
2185
2186 double* pinp=NULL;
2187 double* pout=NULL;
2188 int sx=0;
2189 int sy=0;
2190 int i=0;
2191 int j=0;
2192 int k=0;
2193
2194 cpl_image* out=NULL;
2195
2196
2197 XSH_ASSURE_NOT_NULL( inp);
2198 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
2199 check( sx=cpl_image_get_size_x(inp));
2200 check( sy=cpl_image_get_size_y(inp));
2201 check( pinp=cpl_image_get_data_double(inp));
2202 check( pout=cpl_image_get_data_double(out));
2203 for(j=0;j<sy;j++) {
2204 for(i=r;i<sx-r;i++) {
2205 for(k=-r;k<r;k++) {
2206 pout[j*sx+i]+=pinp[j*sx+i+k];
2207 }
2208 pout[j*sx+i]/=2*r;
2209 }
2210 }
2211
2212 cleanup:
2213
2214 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2215 return NULL;
2216 } else {
2217 return out;
2218
2219 }
2220
2221}
2222
2223
2224/*-------------------------------------------------------------------------*/
2238/*--------------------------------------------------------------------------*/
2239
2240cpl_image *
2241xsh_image_smooth_median_x(cpl_image * inp, const int r)
2242{
2243
2244 /*
2245 @param xp x-value to interpolate
2246 @param x x-values
2247 @param y y-values
2248 @param n array length
2249 @param istart (input/output) initial row (set to 0 to search all row)
2250
2251 */
2252 float* pout=NULL;
2253 int sx=0;
2254 int sy=0;
2255 int i=0;
2256 int j=0;
2257
2258 cpl_image* out=NULL;
2259
2260
2261 cknull_msg(inp,"Null in put image, exit");
2262
2263 check(out=cpl_image_cast(inp,CPL_TYPE_FLOAT));
2264 check(sx=cpl_image_get_size_x(inp));
2265 check(sy=cpl_image_get_size_y(inp));
2266 check(pout=cpl_image_get_data_float(out));
2267
2268 for(j=1;j<sy;j++) {
2269 for(i=r+1;i<sx-r;i++) {
2270 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j);
2271 }
2272 }
2273
2274 cleanup:
2275
2276 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2277 return NULL;
2278 } else {
2279 return out;
2280
2281 }
2282
2283}
2284
2285
2286
2287/*-------------------------------------------------------------------------*/
2301/*--------------------------------------------------------------------------*/
2302
2303cpl_image *
2304xsh_image_smooth_median_xy(cpl_image * inp, const int r)
2305{
2306
2307 /*
2308 @param xp x-value to interpolate
2309 @param x x-values
2310 @param y y-values
2311 @param n array length
2312 @param istart (input/output) initial row (set to 0 to search all row)
2313
2314 */
2315 double* pout=NULL;
2316 int sx=0;
2317 int sy=0;
2318 int i=0;
2319 int j=0;
2320
2321 cpl_image* out=NULL;
2322
2323
2324 cknull_msg(inp,"Null in put image, exit");
2325
2326 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
2327 check(sx=cpl_image_get_size_x(inp));
2328 check(sy=cpl_image_get_size_y(inp));
2329 check(pout=cpl_image_get_data_double(out));
2330
2331 for(j=r+1;j<sy-r;j++) {
2332 for(i=r+1;i<sx-r;i++) {
2333 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j+r);
2334 }
2335 }
2336
2337 cleanup:
2338
2339 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2340 return NULL;
2341 } else {
2342 return out;
2343
2344 }
2345
2346}
2347
2348/*-------------------------------------------------------------------------*/
2358/*--------------------------------------------------------------------------*/
2359
2360cpl_error_code
2362{
2363
2364
2365 cpl_image* ima=NULL;
2366 cpl_image* err=NULL;
2367 cpl_image* qua=NULL;
2368 cpl_propertylist* hima=NULL;
2369 cpl_propertylist* herr=NULL;
2370 cpl_propertylist* hqua=NULL;
2371
2372
2373 const char* name=NULL;
2374 double* pima=NULL;
2375 int* pqua=NULL;
2376 int nx=0;
2377 int ny=0;
2378 int i=0;
2379 int j=0;
2380 int rx=5;
2381 int ry=5;
2382
2383 name=cpl_frame_get_filename(in);
2384 hima=cpl_propertylist_load(name,0);
2385 herr=cpl_propertylist_load(name,1);
2386 hqua=cpl_propertylist_load(name,2);
2387 ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0);
2388 err=cpl_image_load(name,CPL_TYPE_DOUBLE,0,1);
2389 qua=cpl_image_load(name,CPL_TYPE_INT,0,2);
2390
2391 nx=cpl_image_get_size_x(ima);
2392 ny=cpl_image_get_size_y(ima);
2393
2394 pima=cpl_image_get_data_double(ima);
2395 pqua=cpl_image_get_data_int(qua);
2396
2397 for(j=ry;j<ny-ry;j++) {
2398 for(i=rx;i<nx-rx;i++) {
2399 if(pqua[i+j*nx]!=0) {
2400 pima[i+j*nx]=cpl_image_get_median_window(ima,i-rx,j-ry,i+rx,j+ry);
2401 }
2402 }
2403 }
2404 check(cpl_image_save(ima,name,XSH_PRE_DATA_BPP,hima,CPL_IO_DEFAULT));
2405 check(cpl_image_save(err,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
2406 check(cpl_image_save(qua,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
2407
2408 cleanup:
2409 xsh_free_image(&ima);
2410 xsh_free_image(&err);
2411 xsh_free_image(&qua);
2412 xsh_free_propertylist(&hima);
2413 xsh_free_propertylist(&herr);
2414 xsh_free_propertylist(&hqua);
2415
2416 return cpl_error_get_code();
2417
2418}
2419
2420
2421/*-------------------------------------------------------------------------*/
2435/*--------------------------------------------------------------------------*/
2436
2437double
2439 const int llx,
2440 const int urx,
2441 const int ypos)
2442{
2443
2444
2445 XSH_GAUSSIAN_FIT fit_res;
2446 int i=0;
2447 int nelem=0;
2448 int ix=0;
2449 int iy=ypos;
2450
2451 double dy=0;
2452 cpl_vector* pix_pos=NULL;
2453 cpl_vector* pix_val=NULL;
2454 double x_centroid=0;
2455
2456
2457 nelem=urx-llx+1;
2458 check( pix_pos = cpl_vector_new( nelem ) ) ;
2459 check( pix_val = cpl_vector_new( nelem ) ) ;
2460
2461
2462 for( i = 0, ix = llx ; ix <= urx ; ix++, i++, dy += 1. ) {
2463 int rej ;
2464 double value ;
2465
2466 cpl_error_reset() ;
2467 value = cpl_image_get(ima , ix, iy, &rej ) ;
2468 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
2469 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
2470 cpl_error_reset() ;
2471 continue ;
2472 }
2473 cpl_vector_set( pix_val, i, value ) ;
2474 cpl_vector_set( pix_pos, i, dy ) ;
2475 }
2476
2477 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
2478 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
2479 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
2480 cpl_error_reset() ;
2481 x_centroid=cpl_image_get_centroid_x_window(ima,llx,ypos,urx,ypos);
2482 //xsh_msg("x_centroid=%g",x_centroid);
2483
2484 } else {
2485 //x_centroid=cpl_image_get_centroid_x_window(ima,llx,ypos,urx,ypos);
2486 x_centroid=llx+fit_res.peakpos;
2487 }
2488
2489 cleanup:
2490 xsh_free_vector(&pix_pos);
2491 xsh_free_vector(&pix_val);
2492
2493 return x_centroid;
2494}
2495
2496/*-------------------------------------------------------------------------*/
2510/*--------------------------------------------------------------------------*/
2511
2512static double
2514 const int lly,
2515 const int ury,
2516 const int xpos)
2517{
2518
2519
2520 XSH_GAUSSIAN_FIT fit_res;
2521 int j=0;
2522 int nelem=0;
2523 int jy=0;
2524 int jx=xpos;
2525
2526 double dy=0;
2527 cpl_vector* pix_pos=NULL;
2528 cpl_vector* pix_val=NULL;
2529 double y_centroid=0;
2530
2531
2532 nelem=ury-lly+1;
2533 check( pix_pos = cpl_vector_new( nelem ) ) ;
2534 check( pix_val = cpl_vector_new( nelem ) ) ;
2535
2536
2537 for( j = 0, jy = lly ; jy <= ury ; jy++, j++, dy += 1. ) {
2538 int rej ;
2539 double value ;
2540
2541 cpl_error_reset() ;
2542 value = cpl_image_get(ima , jx, jy, &rej ) ;
2543 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
2544 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
2545 cpl_error_reset() ;
2546 continue ;
2547 }
2548 cpl_vector_set( pix_val, j, value ) ;
2549 cpl_vector_set( pix_pos, j, dy ) ;
2550 }
2551
2552 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
2553 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
2554 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
2555 cpl_error_reset() ;
2556 y_centroid=cpl_image_get_centroid_y_window(ima,xpos,lly,xpos,ury);
2557 //xsh_msg("y_centroid=%g",y_centroid);
2558
2559 } else {
2560 //y_centroid=cpl_image_get_centroid_y_window(ima,xpos,lly,xpos,ury);
2561 y_centroid=lly+fit_res.peakpos;
2562 }
2563
2564 cleanup:
2565 xsh_free_vector(&pix_pos);
2566 xsh_free_vector(&pix_val);
2567
2568 return y_centroid;
2569}
2570
2571
2572
2589/*---------------------------------------------------------------------------*/
2590
2591static cpl_table*
2592xsh_image_qc_trace_window(cpl_image* data_ima,cpl_propertylist* head,
2593const int hsize, const int method)
2594{
2595
2596 cpl_table* table=NULL;
2597 int i=0;
2598
2599 int naxis1=0;
2600 int naxis2=0;
2601 cpl_size mx=0;
2602 cpl_size my=0;
2603
2604 int lly=0;
2605 int ury=0;
2606 int llx=0;
2607 int* px=NULL;
2608 double* pcy=NULL;
2609 double* pwav=NULL;
2610 double crval1=0;
2611 double cdelt1=0;
2612
2613 crval1=xsh_pfits_get_crval1(head);
2614 cdelt1=xsh_pfits_get_cdelt1(head);
2615
2616 naxis1=cpl_image_get_size_x(data_ima);
2617 naxis2=cpl_image_get_size_y(data_ima);
2618
2619 table=cpl_table_new(naxis1);
2620 cpl_table_new_column(table,"X",CPL_TYPE_INT);
2621 cpl_table_new_column(table,"WAVELENGTH",CPL_TYPE_DOUBLE);
2622 cpl_table_new_column(table,"POS",CPL_TYPE_DOUBLE);
2623
2624 cpl_table_fill_column_window_int(table,"X",0,naxis1,0);
2625 cpl_table_fill_column_window_double(table,"WAVELENGTH",0,naxis1,0.);
2626 cpl_table_fill_column_window_double(table,"POS",0,naxis1,0.);
2627
2628 px=cpl_table_get_data_int(table,"X");
2629 pwav=cpl_table_get_data_double(table,"WAVELENGTH");
2630 pcy=cpl_table_get_data_double(table,"POS");
2631
2632 for(i=0;i<naxis1;i++) {
2633 px[i]=i;
2634 pwav[i]=crval1+cdelt1*i;
2635 llx=i+1;
2636 check(cpl_image_get_maxpos_window(data_ima,llx,1,llx,naxis2,&mx,&my));
2637 lly=(my-hsize>0) ? my-hsize:1;
2638 ury=(my+hsize<=naxis2) ? my+hsize:naxis2;
2639 if(method == 0 ) {
2641 } else {
2642 check(pcy[i]=cpl_image_get_centroid_y_window(data_ima,llx,lly,llx,ury));
2643 }
2644 }
2645
2646 cleanup:
2647
2648 return table;
2649}
2650
2669/*---------------------------------------------------------------------------*/
2670
2671cpl_frame*
2673 const char* suffix,const int hsize, const int method)
2674{
2675
2676 cpl_frame* result=NULL;
2677 cpl_table* table=NULL;
2678 cpl_image* data_ima=NULL;
2679 const char* name=NULL;
2680
2681 cpl_propertylist* plist=NULL;
2682 char fname[256];
2683 char tag[50];
2684
2685 check(name=cpl_frame_get_filename(frm_ima));
2686/* load data */
2687 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0));
2688 plist=cpl_propertylist_load(name,0);
2689
2690
2691 check(table=xsh_image_qc_trace_window(data_ima,plist,hsize,method));
2692
2693 sprintf(tag,"MERGE3D_TRACE_OBJ_%s_%s",
2695 sprintf(fname,"%s.fits",tag);
2696
2697 check(cpl_table_save(table,plist,NULL,fname,CPL_IO_DEFAULT));
2698
2699 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
2700 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
2701
2702 cleanup:
2703
2704 xsh_free_propertylist(&plist);
2705 xsh_free_table(&table);
2706 xsh_free_image(&data_ima);
2707
2708 return result;
2709}
2710
2729/*---------------------------------------------------------------------------*/
2730
2731cpl_frame*
2734 const char* suffix,
2735 const int hsize,
2736 const int method)
2737{
2738
2739 cpl_frame* result=NULL;
2740 cpl_table* table=NULL;
2741 cpl_table* table_tot=NULL;
2742
2743 cpl_image* data_ima=NULL;
2744 const char* name=NULL;
2745
2746 cpl_propertylist* phead=NULL;
2747 cpl_propertylist* xhead=NULL;
2748
2749 char fname[256];
2750 char tag[50];
2751 int nbext=0;
2752 int k=0;
2753 int nrow=0;
2754 xsh_msg("Trace object position");
2755 check(name=cpl_frame_get_filename(frm_ima));
2756 nbext=cpl_frame_get_nextensions( frm_ima);
2757 /* load data */
2758 table_tot=cpl_table_new(0);
2759 phead=cpl_propertylist_load(name,0);
2760 for(k=0;k<nbext;k+=3){
2761 nrow=cpl_table_get_nrow(table_tot);
2762 //xsh_msg("nrow=%d",nrow);
2763 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,k));
2764 xhead=cpl_propertylist_load(name,k);
2765
2766 check(table=xsh_image_qc_trace_window(data_ima,xhead,hsize,method));
2767 if(k==0) check(cpl_table_copy_structure(table_tot,table));
2768 cpl_table_insert(table_tot,table,nrow);
2769 xsh_free_propertylist(&xhead);
2770 xsh_free_table(&table);
2771 xsh_free_image(&data_ima);
2772 }
2773 sprintf(tag,"OBJ_POS_ORD_%s_%s",
2775 sprintf(fname,"%s.fits",tag);
2776
2777 check(cpl_table_save(table_tot,phead,NULL,fname,CPL_IO_DEFAULT));
2778
2779 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
2780 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
2781
2782 cleanup:
2783
2784 xsh_free_propertylist(&phead);
2785 xsh_free_propertylist(&xhead);
2786 xsh_free_table(&table);
2787 xsh_free_table(&table_tot);
2788 xsh_free_image(&data_ima);
2789
2790 return result;
2791}
2792
2793
2807/*---------------------------------------------------------------------------*/
2808
2809static cpl_error_code
2812 cpl_propertylist* plist)
2813{
2814 cpl_table* qc_table=NULL;
2815 double res_min=0;
2816 double res_max=0;
2817 double res_med=0;
2818 double res_avg=0;
2819 double res_rms=0;
2820 double wmin=0;
2821 double wmax=0;
2822
2824 wmin=350;
2825 wmax=540;
2827 wmin=580;
2828 wmax=950;
2829 } else {
2830 wmin=1000;
2831 wmax=2200;
2832 }
2833
2834 check(cpl_table_and_selected_double(table,"WAVELENGTH",CPL_GREATER_THAN,wmin));
2835 check(cpl_table_and_selected_double(table,"WAVELENGTH",CPL_LESS_THAN,wmax));
2836 check(qc_table=cpl_table_extract_selected(table));
2837 check(cpl_table_select_all(table));
2838
2839
2840 check(res_min=cpl_table_get_column_min(qc_table,"RES12"));
2841 check(res_max=cpl_table_get_column_max(qc_table,"RES12"));
2842 check(res_avg=cpl_table_get_column_mean(qc_table,"RES12"));
2843 check(res_med=cpl_table_get_column_median(qc_table,"RES12"));
2844 check(res_rms=cpl_table_get_column_stdev(qc_table,"RES12"));
2845
2846 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MIN,res_min);
2847 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MIN,"Minimum residuals");
2848 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MAX,res_max);
2849 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MAX,"Maximum residuals");
2850 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_AVG,res_avg);
2851 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_AVG,"Mean residuals");
2852
2853 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MED,res_med);
2854 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MED,"Median residuals");
2855 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_RMS,res_rms);
2856 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_RMS,"Stdev residuals");
2857
2858 res_min=cpl_table_get_column_min(qc_table,"RES32");
2859 res_max=cpl_table_get_column_max(qc_table,"RES32");
2860 res_avg=cpl_table_get_column_mean(qc_table,"RES32");
2861 res_med=cpl_table_get_column_median(qc_table,"RES32");
2862 res_rms=cpl_table_get_column_stdev(qc_table,"RES32");
2863
2864 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MIN,res_min);
2865 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MIN,"Minimum residuals");
2866 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MAX,res_max);
2867 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MAX,"Maximum residuals");
2868 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_AVG,res_avg);
2869 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_AVG,"Mean residuals");
2870
2871 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MED,res_med);
2872 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MED,"Median residuals");
2873 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_RMS,res_rms);
2874 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_RMS,"Stdev residuals");
2875
2876 res_min=cpl_table_get_column_min(qc_table,"RES13");
2877 res_max=cpl_table_get_column_max(qc_table,"RES13");
2878 res_avg=cpl_table_get_column_mean(qc_table,"RES13");
2879 res_med=cpl_table_get_column_median(qc_table,"RES13");
2880 res_rms=cpl_table_get_column_stdev(qc_table,"RES13");
2881
2882 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MIN,res_min);
2883 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MIN,"Minimum residuals");
2884 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MAX,res_max);
2885 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MAX,"Maximum residuals");
2886 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_AVG,res_avg);
2887 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_AVG,"Mean residuals");
2888
2889 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MED,res_med);
2890 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MED,"Median residuals");
2891 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_RMS,res_rms);
2892 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_RMS,"Stdev residuals");
2893
2894 cleanup:
2896 return cpl_error_get_code();
2897
2898}
2899
2900
2920/*---------------------------------------------------------------------------*/
2921
2922static cpl_error_code
2923xsh_cube_trace_fit(cpl_table** table,
2924 const char* col_wav,
2925 const char* col_ref,
2926 const char* col_fit,
2927 const char* qualifier,
2928 cpl_propertylist* plist)
2929{
2930 int nrow=0;
2931 int k=0;
2932 cpl_polynomial* pol=NULL;
2933 cpl_vector* vx=NULL;
2934 cpl_vector* vy=NULL;
2935
2936 double* px=NULL;
2937 double* py=NULL;
2938 double* pf=NULL;
2939 int order=2;
2940 char key_name[25];
2941 cpl_size power=0;
2942 double coeff=0;
2943
2944
2945 nrow=cpl_table_get_nrow(*table);
2946 cpl_table_new_column(*table,col_fit,CPL_TYPE_DOUBLE);
2947 cpl_table_fill_column_window_double(*table,col_fit,0,nrow,0.);
2948
2949 px=cpl_table_get_data_double(*table,col_wav);
2950 py=cpl_table_get_data_double(*table,col_ref);
2951 pf=cpl_table_get_data_double(*table,col_fit);
2952
2953 vx = cpl_vector_wrap( nrow, px );
2954 vy = cpl_vector_wrap( nrow, py );
2955
2956 pol=xsh_polynomial_fit_1d_create(vx,vy,order,NULL);
2957
2958 for(k=0; k< nrow; k++){
2959 check( pf[k] = cpl_polynomial_eval_1d(pol,px[k],NULL));
2960 }
2961
2962 /* stores fit coeffs to be used later */
2963 power=0;
2964 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,qualifier);
2965 coeff = cpl_polynomial_get_coeff(pol, &power);
2966 cpl_propertylist_append_double(plist,key_name,coeff);
2967 cpl_propertylist_set_comment(plist,key_name,"order 0 fit coeff");
2968
2969 power=1;
2970 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,qualifier);
2971 coeff = cpl_polynomial_get_coeff(pol, &power);
2972 cpl_propertylist_append_double(plist,key_name,coeff);
2973 cpl_propertylist_set_comment(plist,key_name,"order 1 fit coeff");
2974
2975 power=2;
2976 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,qualifier);
2977 coeff = cpl_polynomial_get_coeff(pol, &power);
2978 cpl_propertylist_append_double(plist,key_name,coeff);
2979 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff");
2980
2981
2982 cleanup:
2983 cpl_vector_unwrap(vx);
2984 cpl_vector_unwrap(vy);
2985 xsh_free_polynomial(&pol);
2986 return cpl_error_get_code();
2987}
2988
3005/*---------------------------------------------------------------------------*/
3006
3007static cpl_error_code
3008xsh_cube_trace_diff(const cpl_table* table,
3009 const char* col_comp,
3010 const char* col_ref,
3011 cpl_propertylist* plist)
3012{
3013 char key_name[25];
3014
3015 double cmp_c0=0;
3016 double ref_c0=0;
3017 double dif_c0=0;
3018
3019 double cmp_c1=0;
3020 double ref_c1=0;
3021 double dif_c1=0;
3022
3023 double cmp_c2=0;
3024 double ref_c2=0;
3025 double dif_c2=0;
3026
3027 const double* pw=NULL;
3028 double wav=0;
3029 double cmp_pos=0;
3030 double ref_pos=0;
3031 double dif_pos=0;
3032
3033 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_comp);
3034 check(cmp_c0=cpl_propertylist_get_double(plist,key_name));
3035 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_comp);
3036 cmp_c1=cpl_propertylist_get_double(plist,key_name);
3037 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_comp);
3038 cmp_c2=cpl_propertylist_get_double(plist,key_name);
3039
3040 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_ref);
3041 ref_c0=cpl_propertylist_get_double(plist,key_name);
3042 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_ref);
3043 ref_c1=cpl_propertylist_get_double(plist,key_name);
3044 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_ref);
3045 ref_c2=cpl_propertylist_get_double(plist,key_name);
3046
3047
3048 dif_c0=cmp_c0-ref_c0;
3049 dif_c1=cmp_c1-ref_c1;
3050 dif_c2=cmp_c2-ref_c2;
3051
3052
3053 pw=cpl_table_get_data_double_const(table,"WAVELENGTH");
3054
3055 wav=pw[0];
3056 cmp_pos=cmp_c0+cmp_c1*wav+cmp_c2*wav*wav;
3057 ref_pos=ref_c0+ref_c1*wav+ref_c2*wav*wav;
3058
3059 dif_pos=cmp_pos-ref_pos;
3060
3061
3062 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C0,dif_c0);
3063 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C0,"order 0 fit coeff diff");
3064
3065 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c1);
3066 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C1,"order 1 fit coeff diff");
3067
3068 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c2);
3069 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff diff");
3070
3071 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_POS,dif_pos);
3072 cpl_propertylist_set_comment(plist,key_name,"fit trace diff pos");
3073
3074 cleanup:
3075 return cpl_error_get_code();
3076
3077}
3078
3105/*---------------------------------------------------------------------------*/
3106
3107
3108cpl_frame*
3110 const char* suffix,const char* rec_prefix,
3111 const int win_min, const int win_max,
3112 const int hsize,
3113 const int method,const int compute_qc)
3114{
3115 cpl_frame* result=NULL;
3116 cpl_table* table=NULL;
3117 cpl_image* data_ima=NULL;
3118 //cpl_image* errs_ima=NULL;
3119 cpl_imagelist* data_iml=NULL;
3120 cpl_imagelist* errs_iml=NULL;
3121 cpl_imagelist* swap1=NULL;
3122 cpl_imagelist* swap2=NULL;
3123 cpl_imagelist* data_swap=NULL;
3124 cpl_imagelist* errs_swap=NULL;
3125
3126 const char* name=NULL;
3127
3128 int k=0;
3129
3130 int j=0;
3131
3132 int naxis2=0;
3133 int naxis3=0;
3134
3135
3136 cpl_size mx=0;
3137 cpl_size my=0;
3138 double cx=0;
3139 //double cy=0;
3140
3141 //double max=0;
3142 int llx=0;
3143 int urx=0;
3144
3145 double* pcx1=NULL;
3146 double* pcx2=NULL;
3147 double* pcx3=NULL;
3148 double* pwav=NULL;
3149 double crval3=0;
3150 double cdelt3=0;
3151 cpl_propertylist* plist=NULL;
3152 char fname[256];
3153 char tag[256];
3154
3155 check(name=cpl_frame_get_filename(frm_cube));
3156
3157/* load data */
3158 check(data_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
3159 plist=cpl_propertylist_load(name,0);
3160 crval3=xsh_pfits_get_crval3(plist);
3161 cdelt3=xsh_pfits_get_cdelt3(plist);
3162
3163 swap1=cpl_imagelist_swap_axis_create(data_iml,CPL_SWAP_AXIS_XZ);
3164 xsh_free_imagelist(&data_iml);
3165 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
3166 xsh_free_imagelist(&swap1);
3167 data_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
3168 xsh_free_imagelist(&swap2);
3169
3170/* load errs */
3171 check(errs_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
3172
3173 swap1=cpl_imagelist_swap_axis_create(errs_iml,CPL_SWAP_AXIS_XZ);
3174 xsh_free_imagelist(&data_iml);
3175 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
3176 xsh_free_imagelist(&swap1);
3177 errs_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
3178 xsh_free_imagelist(&swap2);
3179
3180/* get sizes */
3181 check(naxis3=cpl_imagelist_get_size(data_swap));
3182 data_ima=cpl_imagelist_get(data_swap,0);
3183
3184 naxis2=cpl_image_get_size_y(data_ima);
3185 //xsh_msg("size=%d",naxis3);
3186 table=cpl_table_new(naxis3);
3187 cpl_table_new_column(table,"WAVELENGTH",CPL_TYPE_DOUBLE);
3188
3189 cpl_table_new_column(table,"POS_1",CPL_TYPE_DOUBLE);
3190 cpl_table_new_column(table,"POS_2",CPL_TYPE_DOUBLE);
3191 cpl_table_new_column(table,"POS_3",CPL_TYPE_DOUBLE);
3192
3193 pwav=cpl_table_get_data_double(table,"WAVELENGTH");
3194 pcx1=cpl_table_get_data_double(table,"POS_1");
3195 pcx2=cpl_table_get_data_double(table,"POS_2");
3196 pcx3=cpl_table_get_data_double(table,"POS_3");
3197
3198 cpl_table_fill_column_window_double(table,"WAVELENGTH",0,naxis3,0.);
3199 cpl_table_fill_column_window_double(table,"POS_1",0,naxis3,0.);
3200 cpl_table_fill_column_window_double(table,"POS_2",0,naxis3,0.);
3201 cpl_table_fill_column_window_double(table,"POS_3",0,naxis3,0.);
3202
3203
3204 for(k=0;k<naxis3;k++) {
3205
3206 check(data_ima=cpl_imagelist_get(data_swap,k));
3207 //check(errs_ima=cpl_imagelist_get(data_swap,k));
3208 pwav[k]=crval3+cdelt3*k;
3209
3210 for(j=1;j<=naxis2;j++) {
3211 check(cpl_image_get_maxpos_window(data_ima,
3212 win_min,j,win_max,j,&mx,&my));
3213 llx=(mx-hsize>win_min) ? mx-hsize:win_min;
3214 urx=(mx+hsize<win_max) ? mx+hsize:win_max;
3215 if(method == 0 ) {
3217 } else {
3218 check(cx=cpl_image_get_centroid_x_window(data_ima,llx,j,urx,j));
3219 //check(max=cpl_image_get_max_window(data_ima,llx,j,urx,j));
3220 }
3221 //xsh_msg("raw=%d, max[%d,%d]=%g cx=%g cy=%g",k,mx,j,max,cx,cy);
3222 switch(j){
3223 case 1: pcx1[k]=cx;break;
3224 case 2: pcx2[k]=cx;break;
3225 case 3: pcx3[k]=cx;break;
3226 }
3227 }
3228
3229 }
3230
3231 /* for QC compute residuals */
3232 cpl_table_duplicate_column(table,"RES12",table,"POS_1");
3233 cpl_table_subtract_columns(table,"RES12","POS_2");
3234
3235 cpl_table_duplicate_column(table,"RES32",table,"POS_3");
3236 cpl_table_subtract_columns(table,"RES32","POS_2");
3237
3238 cpl_table_duplicate_column(table,"RES13",table,"POS_1");
3239 cpl_table_subtract_columns(table,"RES13","POS_3");
3240
3241 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_1","FPOS_1","T1",plist);
3242 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_2","FPOS_2","T2",plist);
3243 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_3","FPOS_3","T3",plist);
3244
3245 xsh_cube_trace_diff(table,"T3","T2",plist);
3246 xsh_cube_trace_diff(table,"T1","T2",plist);
3247
3248 if(compute_qc) {
3250 }
3251
3252
3253
3254 sprintf(tag,"%s_%s_TRACE_OBJ_%s",
3255 rec_prefix,suffix,xsh_instrument_arm_tostring( instrument));
3256 sprintf(fname,"%s.fits",tag);
3257 check(cpl_table_save(table,plist,NULL,fname,CPL_IO_DEFAULT));
3258 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
3259 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
3260
3261
3262 cleanup:
3263 //xsh_msg("llx=%d urx=%d",llx,urx);
3264 xsh_free_table(&table);
3265 xsh_free_imagelist(&swap1);
3266 xsh_free_imagelist(&swap2);
3267 xsh_free_imagelist(&data_swap);
3268 xsh_free_imagelist(&errs_swap);
3269 xsh_free_imagelist(&data_iml);
3270 xsh_free_imagelist(&errs_iml);
3271 xsh_free_propertylist(&plist);
3272
3273 return result;
3274}
3284cpl_error_code
3285xsh_iml_merge_avg(cpl_imagelist** data,
3286 cpl_imagelist** mask,
3287 const cpl_image* data_ima,
3288 const cpl_image* mask_ima,
3289 const int mk)
3290{
3291 cpl_image* data_tmp=NULL;
3292 cpl_image* mask_tmp=NULL;
3293 int* pmsk=NULL;
3294 double norm=0;
3295
3296 int size=0;
3297 check(size=cpl_imagelist_get_size(*mask));
3298 if(mk<size) {
3299 check(data_tmp=cpl_imagelist_get(*data,mk));
3300 check(mask_tmp=cpl_imagelist_get(*mask,mk));
3301 check(pmsk=cpl_image_get_data_int(mask_tmp));
3302
3303 check(norm=pmsk[1]+1);
3304 check(cpl_image_add(data_tmp,data_ima));
3305 check(cpl_image_divide_scalar(data_tmp,norm));
3306 check(cpl_image_add_scalar(mask_tmp,1));
3307 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
3308 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_tmp),mk));
3309
3310 } else {
3311 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
3312 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_ima),mk));
3313 }
3314
3315 cleanup:
3316
3317 //xsh_free_image(&data_tmp);
3318 //xsh_free_image(&mask_tmp);
3319
3320 return cpl_error_get_code();
3321
3322}
3332cpl_error_code
3333xsh_iml_merge_wgt(cpl_imagelist** data,
3334 cpl_imagelist** errs,
3335 cpl_imagelist** qual,
3336 const cpl_image* flux_b,
3337 const cpl_image* errs_b,
3338 const cpl_image* qual_b,
3339 const int mk,const int decode_bp)
3340{
3341
3342 cpl_image* flux_a=NULL;
3343 cpl_image* errs_a=NULL;
3344 cpl_image* qual_a=NULL;
3345 //cpl_image* mask_tmp=NULL;
3346
3347 cpl_image* flux_r=NULL;
3348 cpl_image* errs_r=NULL;
3349 cpl_image* qual_r=NULL;
3350 cpl_image* weight_a=NULL;
3351 cpl_image* weight_b=NULL;
3352
3353 //double norm=0;
3354
3355 int size=0;
3356 check(size=cpl_imagelist_get_size(*data));
3357
3358 if(mk<size) {
3359 check(flux_a=cpl_imagelist_get(*data,mk));
3360 check(errs_a=cpl_imagelist_get(*errs,mk));
3361 check(qual_a=cpl_imagelist_get(*qual,mk));
3362
3363
3364 /*
3365 * weight_a = 1.0 / (err_a * err_a);
3366 * weight_b = 1.0 / (err_b * err_b);
3367 * double tmp_val = 1.0/(weight_a+weight_b);
3368 * flux_res = (weight_a*flux_a+weight_b*flux_b) * tmp_val;
3369 * err_res = sqrt(tmp_val);
3370 */
3371 weight_a = cpl_image_duplicate(errs_a);
3372 weight_b = cpl_image_duplicate(errs_b);
3373
3374 cpl_image_power(weight_a,-2);
3375 cpl_image_power(weight_b,-2);
3376
3377 cpl_image* tmp_ima=cpl_image_duplicate(weight_a);
3378 cpl_image_add(tmp_ima,weight_b);
3379 cpl_image_power(tmp_ima,-1);
3380 errs_r = cpl_image_duplicate(tmp_ima);
3381 cpl_image_power(errs_r,0.5);
3382
3383 cpl_image_multiply(weight_a,flux_a);
3384 cpl_image_multiply(weight_b,flux_b);
3385
3386 cpl_image_add(weight_a,weight_b);
3387
3388 flux_r=cpl_image_duplicate(weight_a);
3389
3390 cpl_image_multiply(flux_r,tmp_ima);
3391
3392 qual_r = cpl_image_duplicate(qual_a);
3393 /* OR combine qualifiers */
3394
3395 xsh_badpixelmap_image_coadd(&qual_r,qual_b,1);
3396 xsh_free_image(&weight_a);
3397 xsh_free_image(&weight_b);
3398 xsh_free_image(&tmp_ima);
3399
3400 check(cpl_imagelist_set(*data,cpl_image_duplicate(flux_r),mk));
3401 check(cpl_imagelist_set(*errs,cpl_image_duplicate(errs_r),mk));
3402 check(cpl_imagelist_set(*qual,cpl_image_duplicate(qual_r),mk));
3403
3404 xsh_free_image(&errs_r);
3405 xsh_free_image(&flux_r);
3406 xsh_free_image(&qual_r);
3407 } else {
3408 //xsh_msg("mk=%d size=%d",mk,size);
3409 check(cpl_imagelist_set(*data,cpl_image_duplicate(flux_b),mk));
3410 check(cpl_imagelist_set(*errs,cpl_image_duplicate(errs_b),mk));
3411 check(cpl_imagelist_set(*qual,cpl_image_duplicate(qual_b),mk));
3412 }
3413
3414 cleanup:
3415
3416 return cpl_error_get_code();
3417
3418}
3419/*-------------------------------------------------------------------------*/
3427/*--------------------------------------------------------------------------*/
3428cpl_error_code
3431{
3432
3433 cpl_image* diff=NULL;
3434 cpl_image* flat_smooth=NULL;
3435 cpl_array* val=NULL;
3436 cpl_matrix* mx=NULL;
3437 xsh_pre* mflat=NULL;
3438
3439 int binx=0;
3440 int biny=0;
3441 int sx=0;
3442 int sy=0;
3443 int i=0;
3444 int j=0;
3445 int filter_width_x=7; //7
3446 int filter_width_y=7;
3447
3448 double kappa=40.;
3449
3450 float* pima=NULL;
3451 int* pqual=NULL;
3452
3453 int npixs=0;
3454 const char* filename;
3455 const char* tag;
3456 /* check input is valid */
3457 XSH_ASSURE_NOT_NULL_MSG(flat_frame, "NULL input flat ");
3458
3459 filename=cpl_frame_get_filename(flat_frame);
3460 tag=cpl_frame_get_tag(flat_frame);
3461
3462 check(mflat=xsh_pre_load(flat_frame,instrument));
3463 /* get image and bin sizes */
3464 sx=mflat->nx;
3465 sy=mflat->ny;
3466 binx=mflat->binx;
3467 biny=mflat->biny;
3468 npixs=sx*sy;
3469
3470 /* set proper x/y filter width. Start values are 3 */
3471 if (binx>1) filter_width_x=5;
3472 if (biny>1) filter_width_y=5;
3473
3474
3475 /* create residuals image from smoothed flat */
3476 check(mx=cpl_matrix_new(filter_width_x,filter_width_y));
3477
3478 for(j=0; j< filter_width_y; j++){
3479 for(i=0; i< filter_width_x; i++){
3480 cpl_matrix_set( mx, i,j,1.0);
3481 }
3482 }
3483
3484 /* smooth master flat */
3485 check(diff=cpl_image_duplicate(mflat->data));
3486 check(flat_smooth=xsh_image_filter_median(mflat->data,mx));
3487 /*
3488 check(cpl_image_save(flat_smooth,"flat_smooth.fits",
3489 CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
3490 */
3491
3492 /* subtract smoothed data */
3493 check(cpl_image_subtract(diff,flat_smooth));
3494
3495 /*
3496 check(cpl_image_save(diff,"diff.fits",
3497 CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
3498 */
3499
3500 check(cpl_image_divide(diff,mflat->errs));
3501 /*
3502 check(cpl_image_save(diff,"norm.fits",
3503 CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
3504 */
3505 check(pqual=cpl_image_get_data_int(mflat->qual));
3506 check(pima=cpl_image_get_data_float(diff));
3507
3508 for(i=0;i<npixs;i++) {
3509 if(fabs(pima[i])>kappa) {
3510 pqual[i] |= QFLAG_OTHER_BAD_PIXEL;
3511 }
3512 }
3513
3514 /* save mask to debug: NB if you leave it remember to clean memory */
3515 cpl_frame* frm=NULL;
3516 check(frm=xsh_pre_save(mflat,filename,tag,0));
3517 xsh_free_frame(&frm);
3518
3519
3520 cleanup:
3521
3522 xsh_free_array(&val);
3523 xsh_free_image(&diff);
3524 xsh_free_image(&flat_smooth);
3525 xsh_free_matrix(&mx);
3526 xsh_pre_free(&mflat);
3527 return cpl_error_get_code();
3528}
3529
3539cpl_error_code
3540xsh_collapse_errs(cpl_image * errs, cpl_imagelist * list,const int mode)
3541{
3542 int nx = 0, ny = 0, nimg = 0, i = 0;
3543 float **pdata = NULL;
3544 cpl_binary ** pbinary = NULL;
3545 float* errsdata = NULL;
3546 double mpi_2=0.5*M_PI;
3547 check(nimg = cpl_imagelist_get_size (list));
3548 assure(nimg > 0,CPL_ERROR_ILLEGAL_INPUT,"you must have image to collapse");
3549
3550 /* create the array of pointers to errs data */
3551 pdata = cpl_malloc (nimg * sizeof (float *));
3552 assure (pdata != NULL, cpl_error_get_code (),
3553 "Cant allocate memory for data pointers");
3554 /* create the array of pointers to errs binary */
3555 pbinary = cpl_malloc (nimg * sizeof (cpl_binary *));
3556 assure (pbinary != NULL, cpl_error_get_code (),
3557 "Cant allocate memory for binary pointers");
3558
3559 /* Populate images pointer array */
3560 for (i = 0; i < nimg; i++) {
3561 check( pdata[i] = cpl_image_get_data_float(cpl_imagelist_get (list, i)));
3562 check( pbinary[i] = cpl_mask_get_data(cpl_image_get_bpm(
3563 cpl_imagelist_get(list, i))));
3564 }
3565
3566 /* get size and from first image */
3567 check(nx = cpl_image_get_size_x (cpl_imagelist_get (list, 0)));
3568 check(ny = cpl_image_get_size_y (cpl_imagelist_get (list, 0)));
3569 check(errsdata = cpl_image_get_data_float(errs));
3570
3571 /* Loop over all pixels */
3572 for (i = 0; i < nx * ny; i++){
3573 int count = 0;
3574 int k = 0;
3575 double errval = 0.0;
3576 /* loop over error images */
3577 for (count = 0, k = 0; k < nimg; k++) {
3578 /* check if good pixel */
3579 if ( ((pbinary[k])[i] == CPL_BINARY_0) ) {
3580 errval += (pdata[k])[i] * (pdata[k])[i];
3581 count++;
3582 }
3583 }
3584 /* convert variance to error */
3585 if (count > 1) {
3586
3587 if (mode==1){
3588 /* mean */
3589 errsdata[i] = sqrt (errval)/((double)count);
3590 } else if (mode==0){
3591 /* median */
3592 if(count <=2 ) {
3593 errsdata[i] = sqrt (errval)/((double)count);
3594 } else {
3595 errsdata[i] = sqrt ( mpi_2*errval / ((double)(count*(count- 1.))) );
3596 }
3597 }
3598 } else if ( count == 1 ) {
3599 errsdata[i] = sqrt (errval);
3600 }
3601 }
3602 cleanup:
3603 cpl_free(pdata);
3604 cpl_free(pbinary);
3605 return cpl_error_get_code();
3606}
3607/*----------------------------------------------------------------------------*/
3622cpl_image*
3624 cpl_image* ima1_in,
3625 cpl_image* ima2_in,
3626 xsh_order_list* qth_list,
3627 xsh_order_list* d2_list,
3628 const int xrad,
3629 const int yrad)
3630{
3631
3632 cpl_image* ima_comb=NULL;
3633 cpl_image* ima_mask=NULL;
3634
3635 int sx=0;
3636 int sy=0;
3637 int j=0;
3638 int i=0;
3639
3640 double* point_mask=NULL;
3641
3642 double xpos=0;
3643
3644 int xpos_min=0;
3645 int xpos_max=0;
3646 int xpos_cen=0;
3647 int ypos_cen=0;
3648
3649 int oref_qth=7;
3650 int oref_d2=0;
3651
3652 int llx=0;
3653 int lly=0;
3654 int urx=0;
3655 int ury=0;
3656 double dflux=0;
3657 double fflux=0;
3658 double scale=0;
3659 cpl_image* ima1=NULL;
3660 cpl_image* ima2=NULL;
3661
3662 cpl_table *ordertable = NULL;
3663 cpl_propertylist *otab_header = NULL;
3664 cpl_polynomial *otab_traces = NULL;
3665
3666 ima1=cpl_image_cast(ima1_in,CPL_TYPE_DOUBLE);
3667 ima2=cpl_image_cast(ima2_in,CPL_TYPE_DOUBLE);
3668 xsh_msg("list size=%d ord_min=%d ord_max=%d",
3669 qth_list->size,qth_list->absorder_min,qth_list->absorder_max);
3670 /*
3671 cpl_image_save(ima1,"ima1_qth.fits", CPL_BPP_IEEE_FLOAT,NULL,
3672 CPL_IO_DEFAULT);
3673 cpl_image_save(ima2,"ima2_d2.fits", CPL_BPP_IEEE_FLOAT,NULL,
3674 CPL_IO_DEFAULT);
3675 */
3676 /*
3677for(i=0;i<qth_list->size;i++){
3678xsh_msg("i=%d abs order=%d rel order=%d",i,qth_list->list[i].absorder,qth_list->list[i].order);
3679y=(double)qth_list->list[i].starty;
3680x1=xsh_order_list_eval( qth_list, qth_list->list[i].cenpoly,y);
3681y=(double)qth_list->list[i].endy;
3682x2=xsh_order_list_eval( qth_list, qth_list->list[i].cenpoly,y);
3683
3684xsh_msg("x1=%g x2=%g",x1,x2);
3685}
3686*/
3687
3688 /*
3689for(i=0;i<qth_list->size;i++){
3690xsh_msg("i=%d abs order=%d rel order=%d",i,qth_list->list[i].absorder,qth_list->list[i].order);
3691llx=xsh_order_list_eval_int( qth_list, qth_list->list[i].cenpoly,qth_list->list[i].starty);
3692urx=xsh_order_list_eval_int( qth_list, qth_list->list[i].cenpoly,qth_list->list[i].endy);
3693
3694xsh_msg("llx=%d urx=%d",llx,urx);
3695}
3696*/
3697 /* check size flat is same as size dflat */
3698 sx=cpl_image_get_size_x(ima1);
3699 sy=cpl_image_get_size_y(ima1);
3700 assure(sx==cpl_image_get_size_x(ima2),CPL_ERROR_ILLEGAL_INPUT,
3701 "illagal x size");
3702 assure(sy==cpl_image_get_size_y(ima2),CPL_ERROR_ILLEGAL_INPUT,
3703 "illagal y size");
3704
3705 /* Do real job */
3706 /* get min x position of overlapping region: d2 trace */
3707 //ypos=cpl_polynomial_evaluate_2d(otab_traces,0,order_ref);
3708 llx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].starty);
3709 //xpos+=cpl_polynomial_evaluate_2d(otab_traces,0,order_ref+1);
3710 urx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].endy);
3711 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
3712 xpos= ( llx < urx ) ? llx: urx;
3713 xpos_min=(int)xpos;
3714
3715 /* get max x position of overlapping region: qth trace */
3716 //ypos=cpl_polynomial_evaluate_2d(otab_traces,(double)sx,order_ref);
3717 llx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, 0);
3718 //ypos+=cpl_polynomial_evaluate_2d(otab_traces,(double)sx,order_ref+1);
3719 urx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, sy);
3720 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
3721 xpos= ( llx > urx ) ? llx: urx;
3722 xpos_max=(int)xpos;
3723
3724 xsh_msg("xpos min=%d max=%d",xpos_min,xpos_max);
3725 ima_mask = cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
3726 point_mask=cpl_image_get_data_double(ima_mask);
3727 /* set right hand side part of mask to 1 */
3728 for(j=0;j<sy;j++) {
3729 for(i=xpos_max;i<sx;i++) {
3730 point_mask[j*sx+i]=1.;
3731 }
3732 }
3733 /*
3734 cpl_image_save(ima_mask,"ima_mask_ord1.fits", CPL_BPP_IEEE_FLOAT,NULL,
3735 CPL_IO_DEFAULT);
3736 */
3737 /* in transition region (only) make the check */
3738 for(j=0;j<sy;j++) {
3739
3740 for(i=xpos_min;i<xpos_max;i++) {
3741
3742 /* Here the order trace pass through the order center
3743 but we want to have the trace in the inter order region
3744 x=(xd2_upp+xqth_low)/2; where yc1 and yc2 are the two position at
3745 order center and order+1 center
3746 */
3747 //ypos= cpl_polynomial_evaluate_2d(otab_traces,xpos,order_ref);
3748 llx= xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly, j);
3749 //ypos+=cpl_polynomial_evaluate_2d(otab_traces,xpos,order_ref+1);
3750 urx= xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly,j);
3751 xpos=0.5*(llx+urx);
3752
3753 if(i > xpos) {
3754 //xsh_msg("pix[%d,%d]: llx=%d urx=%d xpos=%g",i,j,llx,urx,xpos);
3755 point_mask[j*sx+i] = 1.;
3756 }
3757 }
3758 }
3759 /*
3760 cpl_image_save(ima_mask,"ima_mask_ord2.fits", CPL_BPP_IEEE_FLOAT,NULL,
3761 CPL_IO_DEFAULT);
3762 */
3763
3764 /*determine ref flux on d2-flat (oref_d2) */
3765 ypos_cen=sy/2;
3766 lly=ypos_cen-yrad;
3767 ury=ypos_cen+yrad;
3768
3769 //ypos= cpl_polynomial_evaluate_2d(otab_traces,(double)xpos_cen,order_ref+1);
3770
3771 xpos = xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].cenpoly, ypos_cen);
3772
3773 xpos_cen=(int)xpos;
3774 llx=xpos_cen-yrad;
3775 urx=xpos_cen+yrad;
3776 fflux=cpl_image_get_median_window(ima1,llx,lly,urx,ury);
3777
3778
3779
3780 /*determine ref flux on qth-flat2 (oref_qth): on the same x-y pos! */
3781 //xpos = xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].cenpoly, ypos_cen);
3782 //ypos=cpl_polynomial_evaluate_2d(otab_traces,(double)xpos_cen,order_ref);
3783 //xpos_cen=(int)xpos;
3784 //llx=xpos_cen-xrad;
3785 //urx=xpos_cen+xrad;
3786
3787 dflux=cpl_image_get_median_window(ima2,llx,lly,urx,ury);
3788
3789 scale=fflux/dflux;
3790
3791 xsh_msg("flux: n=%g d=%g s=%g",fflux,dflux,scale);
3792
3793 /* combine images */
3794 ima_comb=cpl_image_duplicate(ima1);
3795 cpl_image_multiply(ima_comb,ima_mask);
3796 cpl_image_multiply_scalar(ima_mask,-1.);
3797 cpl_image_add_scalar(ima_mask,1.);
3798 cpl_image_multiply(ima2,ima_mask);
3799 cpl_image_multiply_scalar(ima2,scale);
3800 cpl_image_add(ima_comb,ima2);
3801 /*
3802 cpl_image_save(ima_comb,"ima_comb.fits", CPL_BPP_IEEE_FLOAT,NULL,
3803 CPL_IO_DEFAULT);
3804 */
3805 cleanup:
3806
3807 xsh_free_table(&ordertable);
3808 xsh_free_propertylist(&otab_header);
3809 xsh_free_polynomial(&otab_traces);
3810 xsh_free_image(&ima1);
3811 xsh_free_image(&ima2);
3812 xsh_free_image(&ima_mask);
3813
3814 return ima_comb;
3815}
3816
3817
3818cpl_error_code xsh_frame_image_save2ext(cpl_frame* frm,
3819 const char* name_o, const int ext_i,
3820 const int ext_o) {
3821 const char* name = NULL;
3822 cpl_image* ima = NULL;
3823 cpl_propertylist* plist = NULL;
3824
3825 name = cpl_frame_get_filename(frm);
3826 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, ext_i);
3827
3828 if (ext_o == 0) {
3829 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
3830 } else {
3831 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, NULL, CPL_IO_EXTEND);
3832 }
3833
3834 xsh_free_image(&ima);
3835 xsh_free_propertylist(&plist);
3836 return cpl_error_get_code();
3837
3838}
3839
3840cpl_error_code xsh_frame_image_add_double(cpl_frame* frm, const double value) {
3841 const char* name = NULL;
3842 name = cpl_frame_get_filename(frm);
3843 cpl_image* ima = NULL;
3844 cpl_propertylist* plist = NULL;
3845
3846 name=cpl_frame_get_filename(frm);
3847 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, 0);
3848 plist=cpl_propertylist_load(name,0);
3849
3850 cpl_image_add_scalar(ima,value);
3851 cpl_image_save(ima, name, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
3852
3853 xsh_free_image(&ima);
3854 xsh_free_propertylist(&plist);
3855 return cpl_error_get_code();
3856
3857}
3858
3859static cpl_error_code
3860xsh_key_scan_mult_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
3861{
3862
3863 int value=0;
3864 if(cpl_propertylist_has(*plist,kname) > 0) {
3865 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
3866 if(value>1) {
3867 check(cpl_propertylist_set_int(*plist,kname,value*fct));
3868 }
3869 } else {
3870 if(value>1) {
3871 cpl_propertylist_append_int(*plist,kname,1);
3872 }
3873 }
3874
3875 cleanup:
3876 return cpl_error_get_code();
3877}
3878
3879static cpl_error_code
3880xsh_key_bin_div_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
3881{
3882
3883 int value=0;
3884 if(cpl_propertylist_has(*plist,kname) > 0) {
3885 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
3886 if(value>1) {
3887 check(cpl_propertylist_set_int(*plist,kname,value/fct));
3888 }
3889 } else {
3890 if(fct>1) {
3891 cpl_propertylist_append_int(*plist,kname,1);
3892 }
3893 }
3894
3895 cleanup:
3896 return cpl_error_get_code();
3897}
3898
3899
3900static cpl_error_code
3901xsh_plist_mult_by_fct(cpl_propertylist** plist,const int fctx,const int fcty)
3902{
3903
3910
3911 return cpl_error_get_code();
3912}
3913
3914
3915
3916
3917
3918
3919
3920static cpl_image*
3921xsh_image_div_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
3922{
3923 int sx=0;
3924 int sy=0;
3925 int nx=0;
3926 int ny=0;
3927
3928 cpl_image* ima_datr=NULL;
3929
3930 const float* pdat=NULL;
3931 float* pdatr=NULL;
3932
3933 int i=0;
3934 int j=0;
3935 int k=0;
3936 int m=0;
3937
3938 check(sx=cpl_image_get_size_x(ima_dat));
3939 check(sy=cpl_image_get_size_y(ima_dat));
3940
3941 xsh_msg("org image size dat: %d %d",sx,sy);
3942 nx=sx/fctx;
3943 ny=sy/fcty;
3944
3945 check(ima_datr=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
3946 xsh_msg("new image size dat: %d %d",nx,ny);
3947 check(pdat=cpl_image_get_data_float_const(ima_dat));
3948 check(pdatr=cpl_image_get_data_float(ima_datr));
3949
3950
3951 for (j = 0; j < ny; j++) {
3952 for (m = 0; m < fcty; m++) {
3953 for (i = 0; i < nx; i++) {
3954 for (k = 0; k < fctx; k++) {
3955 /*
3956 xsh_msg("j=%d m=%d i=%d k=%d index=%d int=%f",j,m,i,k,
3957 i*fctx+k+(j*fcty+m)*fctx*nx,pdat[i+j*nx]);
3958 */
3959 pdatr[i + j * nx] += pdat[i * fctx + k + (j * fcty + m) * fctx * nx];
3960 }
3961 }
3962 }
3963 /* HERE ONE SHOULD RE-SCALE */
3964 pdatr[i + j * nx] /= (fctx * fcty);
3965
3966 }
3967
3968 cleanup:
3969 return ima_datr;
3970
3971}
3972
3973
3974
3975
3976static cpl_image*
3977xsh_image_mult_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
3978{
3979
3980 int nx=0;
3981 int ny=0;
3982
3983 cpl_image* ima_datr=NULL;
3984
3985 const float* pdat=NULL;
3986 float* pdatr=NULL;
3987
3988 int i=0;
3989 int j=0;
3990 int k=0;
3991 int m=0;
3992
3993 check(nx=cpl_image_get_size_x(ima_dat));
3994 check(ny=cpl_image_get_size_y(ima_dat));
3995
3996 xsh_msg("org image size dat: %d %d",nx,ny);
3997 check(ima_datr=cpl_image_new(fctx*nx,fcty*ny,CPL_TYPE_FLOAT));
3998 xsh_msg("new image size dat: %d %d",fctx*nx,fcty*ny);
3999
4000 check(pdat=cpl_image_get_data_float_const(ima_dat));
4001 check(pdatr=cpl_image_get_data_float(ima_datr));
4002
4003 for(j=0;j<ny;j++) {
4004 for(m=0;m<fcty;m++) {
4005 for(i=0;i<nx;i++) {
4006 for(k=0;k<fctx;k++) {
4007 //xsh_msg("j=%d m=%d i=%d k=%d index=%d int=%f",j,m,i,k,
4008 // i*fctx+k+(j*fcty+m)*fctx*nx,pdat[i+j*nx]);
4009 pdatr[i*fctx+k+(j*fcty+m)*fctx*nx]=pdat[i+j*nx];
4010 }
4011 }
4012 }
4013 }
4014
4015 cleanup:
4016 return ima_datr;
4017}
4018
4019
4020cpl_frame*
4021xsh_frame_image_div_by_fct(cpl_frame* frm,const int fctx, const int fcty)
4022{
4023
4024 const char* name=NULL;
4025 cpl_propertylist* plist=NULL;
4026 cpl_propertylist* hext=NULL;
4027 cpl_image* ima_dat=NULL;
4028 cpl_image* ima_datr=NULL;
4029
4030 int next=0;
4031
4032 int prscx=0;
4033 int prscy=0;
4034 int ovscx=0;
4035 int ovscy=0;
4036 int kk=0;
4037 cpl_frame* frm_cor=NULL;
4038 const char* tag=NULL;
4039
4040 const char* basename=NULL;
4041 char new_name[256];
4042
4043 check(name=cpl_frame_get_filename(frm));
4044 check(tag=cpl_frame_get_tag(frm));
4045 next=cpl_frame_get_nextensions(frm);
4046 check(plist=cpl_propertylist_load(name,0));
4047
4048 check(prscx=xsh_pfits_get_prscx(plist));
4049 check(prscy=xsh_pfits_get_prscy(plist));
4050 check(ovscx=xsh_pfits_get_ovscx(plist));
4051 check(ovscy=xsh_pfits_get_ovscy(plist));
4052 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
4053
4054 xsh_plist_div_by_fct(&plist,fctx,fcty);
4055
4056 check(basename=xsh_get_basename(name));
4057 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
4058 xsh_msg("new_name=%s",new_name);
4059
4060 for(kk=0;kk<=next;kk++) {
4061
4062 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
4063 check(hext=cpl_propertylist_load(name,kk));
4064 ima_datr=xsh_image_div_by_fct(ima_dat,fctx,fcty);
4065
4066 if(kk==0) {
4067 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
4068 CPL_IO_DEFAULT));
4069 } else if (kk==1) {
4070 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
4071 CPL_IO_EXTEND));
4072 } else if (kk==2) {
4073 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
4074 CPL_IO_EXTEND));
4075 }
4076
4077 xsh_free_image(&ima_dat);
4078 xsh_free_image(&ima_datr);
4079 xsh_free_propertylist(&plist);
4080 xsh_free_propertylist(&hext);
4081 } /* end loop over extensions */
4082 frm_cor=cpl_frame_new();
4083 cpl_frame_set_filename(frm_cor,new_name);
4084 check(cpl_frame_set_tag(frm_cor,tag));
4085 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
4086 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
4087 xsh_add_temporary_file(new_name);
4088
4089 cleanup:
4090
4091 xsh_free_image(&ima_dat);
4092 xsh_free_image(&ima_datr);
4093 xsh_free_propertylist(&plist);
4094 xsh_free_propertylist(&hext);
4095
4096 return frm_cor;
4097}
4098
4099cpl_frame*
4100xsh_frame_image_mult_by_fct(cpl_frame* frm,const int fctx, const int fcty)
4101{
4102
4103 const char* name=NULL;
4104 cpl_propertylist* plist=NULL;
4105 cpl_propertylist* hext=NULL;
4106 cpl_image* ima_dat=NULL;
4107 cpl_image* ima_datr=NULL;
4108
4109 int next=0;
4110
4111 int prscx=0;
4112 int prscy=0;
4113 int ovscx=0;
4114 int ovscy=0;
4115 int kk=0;
4116 cpl_frame* frm_cor=NULL;
4117 const char* tag=NULL;
4118 const char* basename=NULL;
4119 char new_name[256];
4120
4121 check(name=cpl_frame_get_filename(frm));
4122 check(tag=cpl_frame_get_tag(frm));
4123 next=cpl_frame_get_nextensions(frm);
4124 check(plist=cpl_propertylist_load(name,0));
4125
4126 check(prscx=xsh_pfits_get_prscx(plist));
4127 check(prscy=xsh_pfits_get_prscy(plist));
4128 check(ovscx=xsh_pfits_get_ovscx(plist));
4129 check(ovscy=xsh_pfits_get_ovscy(plist));
4130
4131 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
4132 check(basename=xsh_get_basename(name));
4133 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
4134 xsh_msg("new_name=%s",new_name);
4135
4136 xsh_plist_mult_by_fct(&plist,fctx,fcty);
4137 for(kk=0;kk<=next;kk++) {
4138
4139 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
4140 check(hext=cpl_propertylist_load(name,kk));
4141 ima_datr=xsh_image_mult_by_fct(ima_dat,fctx,fcty);
4142 if(kk==0) {
4143 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
4144 CPL_IO_DEFAULT));
4145 } else if (kk==1) {
4146 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
4147 CPL_IO_EXTEND));
4148 } else if (kk==2) {
4149 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
4150 CPL_IO_EXTEND));
4151 }
4152
4153 xsh_free_image(&ima_dat);
4154 xsh_free_image(&ima_datr);
4155 xsh_free_propertylist(&plist);
4156 xsh_free_propertylist(&hext);
4157
4158 }
4159
4160 frm_cor=cpl_frame_new();
4161 cpl_frame_set_filename(frm_cor,new_name);
4162 cpl_frame_set_tag(frm_cor,tag);
4163 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
4164 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
4165 xsh_add_temporary_file(new_name);
4166cleanup:
4167 return frm_cor;
4168
4169}
4170cpl_error_code xsh_image_cut_dichroic_uvb(cpl_frame* frame1d)
4171{
4172
4173 cpl_propertylist* phead=NULL;
4174 cpl_propertylist* dhead=NULL;
4175 cpl_propertylist* ehead=NULL;
4176 cpl_propertylist* qhead=NULL;
4177 cpl_image* org_data_ima=NULL;
4178 cpl_image* cut_data_ima=NULL;
4179 cpl_image* org_errs_ima=NULL;
4180 cpl_image* cut_errs_ima=NULL;
4181 cpl_image* org_qual_ima=NULL;
4182 cpl_image* cut_qual_ima=NULL;
4183
4184 const char* fname=NULL;
4185 char oname[128];
4186 int next=0;
4187
4188 int i=0;
4189 int naxis1=0;
4190 int naxis2=0;
4191 int xcut=0;
4192
4193 double crval1=0;
4194 double cdelt1=0;
4195 double wave_cut=XSH_UVB_DICHROIC_WAVE_CUT; /* 556 nm dichroic cut */
4196 double wave_min=0;
4197 double wave_max=0;
4198 char cmd[256];
4199 fname=cpl_frame_get_filename(frame1d);
4200 next=cpl_frame_get_nextensions(frame1d);
4201 phead = cpl_propertylist_load(fname, 0);
4202
4203 xsh_msg("fname=%s",fname);
4204 check(org_data_ima=cpl_image_load( fname, XSH_PRE_DATA_TYPE, 0,0 ));
4205 check(naxis1=cpl_image_get_size_x(org_data_ima));
4206 check(naxis2=cpl_image_get_size_y(org_data_ima));
4207 xsh_free_image(&org_data_ima);
4208
4209 crval1=xsh_pfits_get_crval1(phead);
4210 cdelt1=xsh_pfits_get_cdelt1(phead);
4211
4212 wave_min = crval1;
4213 wave_max = wave_min + cdelt1*naxis1;
4214 cpl_ensure_code(wave_max > wave_cut, CPL_ERROR_ILLEGAL_INPUT);
4215 xcut = (int) ( (wave_cut-wave_min) / cdelt1 + 0.5 );
4216 cpl_ensure_code(xcut <= naxis1, CPL_ERROR_ILLEGAL_INPUT);
4217
4218 if (xcut == naxis1) {
4219 return CPL_ERROR_NONE;
4220 }
4221 sprintf(oname,"tmp_%s",fname);
4222 /* loop over each frame extensions */
4223 for(i=0;i<next;i+=3) {
4224
4225 org_data_ima=cpl_image_load( fname, XSH_PRE_DATA_TYPE, 0,i );
4226 org_errs_ima=cpl_image_load( fname, XSH_PRE_ERRS_TYPE, 0,i+1 );
4227 org_qual_ima=cpl_image_load( fname, XSH_PRE_QUAL_TYPE, 0,i+2 );
4228 dhead = cpl_propertylist_load(fname, i);
4229 ehead = cpl_propertylist_load(fname, i+1);
4230 qhead = cpl_propertylist_load(fname, i+2);
4231 if(i==0) {
4232 cut_data_ima=cpl_image_extract(org_data_ima,1,1,xcut,naxis2);
4233 cut_errs_ima=cpl_image_extract(org_errs_ima,1,1,xcut,naxis2);
4234 cut_qual_ima=cpl_image_extract(org_qual_ima,1,1,xcut,naxis2);
4235
4236 cpl_image_save( cut_data_ima, oname, CPL_BPP_IEEE_FLOAT, phead,
4237 CPL_IO_DEFAULT ) ;
4238 cpl_image_save( cut_errs_ima, oname, CPL_BPP_IEEE_FLOAT, ehead,
4239 CPL_IO_EXTEND ) ;
4240 cpl_image_save( cut_qual_ima, oname, CPL_BPP_IEEE_FLOAT, qhead,
4241 CPL_IO_EXTEND ) ;
4242
4243 xsh_free_image(&cut_data_ima);
4244 xsh_free_image(&cut_errs_ima);
4245 xsh_free_image(&cut_qual_ima);
4246
4247
4248 } else {
4249 cpl_image_save( org_data_ima, oname, CPL_BPP_IEEE_FLOAT, dhead,
4250 CPL_IO_EXTEND ) ;
4251 cpl_image_save( org_errs_ima, oname, CPL_BPP_IEEE_FLOAT, ehead,
4252 CPL_IO_EXTEND ) ;
4253 cpl_image_save( org_qual_ima, oname, CPL_BPP_IEEE_FLOAT, qhead,
4254 CPL_IO_EXTEND ) ;
4255 }
4256
4257 xsh_free_image(&org_data_ima);
4258 xsh_free_image(&org_errs_ima);
4259 xsh_free_image(&org_qual_ima);
4260 xsh_free_propertylist(&dhead);
4261 xsh_free_propertylist(&ehead);
4262 xsh_free_propertylist(&qhead);
4263
4264 }
4265 sprintf(cmd,"mv %s %s",oname,fname);
4266 assure(system(cmd)==0,CPL_ERROR_UNSPECIFIED,"unable to mv file");
4267 //cpl_frame_set_filename(frame1d,oname);
4268 cleanup:
4269 xsh_free_propertylist(&phead);
4270 if(cpl_error_get_code() != CPL_ERROR_NONE) {
4272 }
4273 return cpl_error_get_code();
4274}
4275
4276
4277cpl_image*
4278xsh_compute_scale(cpl_imagelist* iml_data, cpl_mask* bpm,
4279 const int mode, const int win_hsz)
4280{
4281 cpl_image* res;
4282 int sx_j;
4283 int pix;
4284 int win_hsx;
4285 int win_hsy;
4286 if(mode==0) {
4287 win_hsx=0;
4288 win_hsy=win_hsz;
4289 } else {
4290 win_hsx=win_hsz;
4291 win_hsy=0;
4292 }
4293 int win_sx=2*win_hsx+1;
4294 int win_sy=2*win_hsy+1;
4295 int sz=cpl_imagelist_get_size(iml_data);
4296 double sum_all;
4297 double sum_good;
4298 double sum_good_pix;
4299 double sum_tot_pix;
4300 float* pdata;
4301
4302 double scale;
4303
4304 cpl_image* ima_tmp;
4305
4306 cpl_imagelist* iml_good;
4307 cpl_imagelist* iml_all;
4308 cpl_binary* pbpm;
4309 cpl_binary* pbpm_tmp;
4310
4311 cpl_mask* not=cpl_mask_duplicate(bpm);
4312 cpl_mask_not(not);
4313 cpl_binary* pnot=cpl_mask_get_data(not);
4314 cpl_mask* bpm_tmp;
4315 ima_tmp=cpl_imagelist_get(iml_data,0);
4316 cpl_imagelist* iml_copy=cpl_imagelist_duplicate(iml_data);
4317
4318 int sx=cpl_image_get_size_x(ima_tmp);
4319 int sy=cpl_image_get_size_y(ima_tmp);
4320 float* pres;
4321 res=cpl_image_new(sx,sy,CPL_TYPE_FLOAT);
4322 cpl_image_add_scalar(res,1.);
4323 pres=cpl_image_get_data(res);
4324 pbpm=cpl_mask_get_data(bpm);
4325 int point;
4326 int num_good_pix;
4327 int num_tot_pix;
4328
4329 int frame_bad;
4330 int x,y;
4331
4332 for(int j=0;j<sy;j++) {
4333 //xsh_msg("j=%d",j);
4334
4335 sx_j=sx*j;
4336 for(int i=0;i<sx;i++) {
4337 //xsh_msg("i=%d",i);
4338
4339 pix=sx_j+i;
4340 frame_bad=0;
4341 //xsh_msg("pix=%d",pix);
4342 if ( pbpm[pix] == CPL_BINARY_0 ) {
4343 /* if the pixel was not flagged the scaling factor is 1 */
4344 pres[pix] = 1;
4345
4346 } else if ( pbpm[pix] == CPL_BINARY_1 ) {
4347 sum_good_pix=0;
4348 num_good_pix=0;
4349 sum_tot_pix=0;
4350 num_tot_pix=0;
4351 //xsh_msg("found bad pix at pos[%d,%d]",i,j);
4352 /* if the pixel is flagged we compute the scaling factor */
4353 int y_min=j-win_hsy, y_max=j+win_hsy;
4354 //xsh_msg("init y_min=%d y_max=%d",y_min,y_max);
4355 /* Not to hit image edges use asymmetric interval at image edges */
4356 if (y_min < 0) {
4357 //xsh_msg("y case1");
4358 y_min = 0;
4359 y_max = win_sy;
4360 } else if ( y_max > sy) {
4361 //xsh_msg("y case2 j=%d j+y_max=%d,sy=%d",j,j+y_max,sy);
4362 y_max=sy;
4363 y_min=y_max-win_sy;
4364 }
4365 //xsh_msg("corrected y_min=%d y_max=%d",y_min,y_max);
4366 int x_min=i-win_hsx, x_max=i+win_hsx;
4367 //xsh_msg("init x_min=%d x_max=%d",x_min,x_max);
4368 if (x_min < 0) {
4369 //xsh_msg("x case1")/;
4370 x_min = 0;
4371 x_max = win_sx;
4372 } else if ( x_max > sx) {
4373 //xsh_msg("x case2 i=%d i+x_max=%d,sx=%d",i,i+x_max,sx);
4374 x_max=sx;
4375 x_min=x_max-win_sx;
4376 }
4377 //xsh_msg("corrected x_min=%d x_max=%d",x_min,x_max);
4378 sum_all=0;
4379 sum_good=0;
4380 //sum_bad=0;
4381 //good=0;
4382
4383 /* copy data to accessory imagelist (because we will unset only
4384 * on the wrapped imagelist the frame at which we found a bad
4385 * pixel in the original list */
4386 iml_all = cpl_imagelist_new();
4387 iml_good = cpl_imagelist_new();
4388 //iml_all=cpl_imagelist_duplicate(iml_data);
4389 //iml_good=cpl_imagelist_duplicate(iml_data);
4390
4391 for(int k=0;k<sz;k++) {
4392 ima_tmp=cpl_imagelist_get(iml_copy,k);
4393
4394 cpl_imagelist_set(iml_good,cpl_image_duplicate(ima_tmp),k);
4395 cpl_imagelist_set(iml_all,cpl_image_duplicate(ima_tmp),k);
4396
4397 }
4398
4399 /* we search now on which frame image of the original list was
4400 * present the flagged pixel and we un-set that frame in the
4401 * wrapped list
4402 */
4403
4404 for(int k=0;k<sz-frame_bad;k++) {
4405
4406 ima_tmp=cpl_imagelist_get(iml_good,k);
4407 pdata=cpl_image_get_data_float(ima_tmp);
4408 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4409 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4410
4411 if(pbpm_tmp[pix] == CPL_BINARY_1) {
4412 //xsh_msg("found bad pix unset frame %d",k);
4413 ima_tmp=cpl_imagelist_unset(iml_good,k);
4414 bpm_tmp=cpl_image_unset_bpm(ima_tmp);
4415 cpl_mask_delete(bpm_tmp);
4416 cpl_image_delete(ima_tmp);
4417
4418 //sum_bad = pdata[pix];
4419 frame_bad++;
4420 }
4421 }
4422
4423 //xsh_msg("Found bad pix=%d",frame_bad);
4424
4425 /* to sum only over good pixels we flag the bad ones */
4426 for(int k=0;k<sz-frame_bad;k++) {
4427 ima_tmp=cpl_imagelist_get(iml_good,k);
4428 bpm_tmp=cpl_image_set_bpm(ima_tmp,cpl_mask_duplicate(bpm));
4429 cpl_mask_delete(bpm_tmp);
4430 }
4431
4432 /* to sum only over good pixels we flag the bad ones */
4433 for(int k=0;k<sz;k++) {
4434 ima_tmp=cpl_imagelist_get(iml_all,k);
4435 bpm_tmp=cpl_image_set_bpm(ima_tmp,cpl_mask_duplicate(bpm));
4436 cpl_mask_delete(bpm_tmp);
4437
4438 }
4439
4440 /* now search for the good pixels in the remaining images of
4441 * the wrapped imagelist around the bad pixel to compute the sum
4442 * of good and the sum of all pixels
4443 */
4444 //xsh_msg("Compute sums");
4445
4446 for(y=y_min; y <= y_max; y++) {
4447 //xsh_msg("y=%d",y);
4448 for(x=x_min; x <= x_max; x++) {
4449 //xsh_msg("x=%d",x);
4450 point=y*sx+x;
4451
4452 //xsh_msg("compute sum on all %d frames",sz);
4453 for(int k=0;k<sz;k++) {
4454 ima_tmp=cpl_imagelist_get(iml_all,k);
4455 pdata=cpl_image_get_data_float(ima_tmp);
4456 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4457 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4458 //xsh_msg("scan point %d at x=%d y=%d i=%d,j=%d",point,x,y,i,j);
4459 if(pbpm_tmp[point] == CPL_BINARY_0) {
4460 sum_all += pdata[point];
4461 }
4462
4463
4464 }
4465
4466 //xsh_msg("compute sum on %d left frames",sz-frame_bad);
4467 for(int k=0;k<sz-frame_bad;k++) {
4468 ima_tmp=cpl_imagelist_get(iml_good,k);
4469 pdata=cpl_image_get_data_float(ima_tmp);
4470 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4471 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4472 //xsh_msg("scan point %d at %d,%d",point,i,j);
4473 if( pbpm[point] == CPL_BINARY_0 ) {
4474 sum_good += pdata[point];
4475 }
4476 }
4477
4478 // determine the sum of good pixel at pos of bad pix
4479 for(int k=0;k<sz-frame_bad;k++) {
4480 ima_tmp=cpl_imagelist_get(iml_good,k);
4481 pdata=cpl_image_get_data_float(ima_tmp);
4482
4483 if( pnot[pix] == CPL_BINARY_0 && pix != point) {
4484 sum_good_pix += pdata[pix];
4485 num_good_pix++;
4486 }
4487
4488 if( pnot[pix] == CPL_BINARY_0 && pix == point) {
4489 sum_tot_pix += pdata[pix];
4490 num_tot_pix++;
4491 }
4492 }
4493
4494 }
4495 } //end loop to compute sum
4496
4497 scale = sum_all / sum_good;
4498 //pres[pix] = scale*num_tot_pix/sz;
4499 //pres[pix] = scale*sum_tot_pix/sz;
4500 pres[pix]=scale*num_tot_pix/sz; //good for uniform images case
4501 if( isnan( pres[pix] ) ) {
4502 pres[pix]=1;
4503 }
4504 //pres[pix]=1;
4505 /*
4506 xsh_msg("sum all %g good %g good_pix %g num_good %d sum_tot_pix %g num_tot_pix %d scale %g res: %g",
4507 sum_all,sum_good,sum_good_pix, num_good_pix, sum_tot_pix, num_tot_pix, scale, pres[pix]);
4508 */
4509
4510 int n=cpl_imagelist_get_size(iml_good);
4511
4512 for(int k=0;k<n;k++) {
4513 ima_tmp=cpl_imagelist_get(iml_good,k);
4514 cpl_image_delete(ima_tmp);
4515 }
4516 for(int k=0;k<sz;k++) {
4517 ima_tmp=cpl_imagelist_get(iml_all,k);
4518 cpl_image_delete(ima_tmp);
4519 }
4520
4521 cpl_imagelist_unwrap(iml_good);
4522 cpl_imagelist_unwrap(iml_all);
4523 }
4524 }
4525 }
4526 cpl_imagelist_delete(iml_copy);
4527 cpl_mask_delete(not);
4528 return res;
4529}
4530
4531cpl_image*
4532xsh_compute_scale_tab(cpl_imagelist* iml_data, cpl_mask* bpm, cpl_table* tab_bpm,
4533 const int mode, const int win_hsz)
4534{
4535 cpl_image* res;
4536 int sx_j;
4537 int pix;
4538 int win_hsx;
4539 int win_hsy;
4540 if(mode==0) {
4541 win_hsx=0;
4542 win_hsy=win_hsz;
4543 } else {
4544 win_hsx=win_hsz;
4545 win_hsy=0;
4546 }
4547 int win_sx=2*win_hsx+1;
4548 int win_sy=2*win_hsy+1;
4549 int sz=cpl_imagelist_get_size(iml_data);
4550 double sum_all;
4551 double sum_good;
4552 double sum_good_pix;
4553 double sum_tot_pix;
4554 float* pdata;
4555 //double sum_bad;
4556 double scale;
4557
4558 cpl_image* ima_tmp;
4559
4560 //cpl_imagelist* iml_tmp;
4561 cpl_imagelist* iml_good;
4562 cpl_imagelist* iml_all;
4563 cpl_binary* pbpm;
4564 cpl_binary* pbpm_tmp;
4565
4566 cpl_mask* not=cpl_mask_duplicate(bpm);
4567 cpl_mask_not(not);
4568 cpl_binary* pnot=cpl_mask_get_data(not);
4569 cpl_mask* bpm_tmp;
4570 ima_tmp=cpl_imagelist_get(iml_data,0);
4571 cpl_imagelist* iml_copy=cpl_imagelist_duplicate(iml_data);
4572
4573 int sx=cpl_image_get_size_x(ima_tmp);
4574 int sy=cpl_image_get_size_y(ima_tmp);
4575 double* pres;
4576 res=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
4577 cpl_image_add_scalar(res,1.);
4578 pres=cpl_image_get_data(res);
4579
4580 int* px=cpl_table_get_data_int(tab_bpm,"x");
4581 int* py=cpl_table_get_data_int(tab_bpm,"y");
4582 int size=cpl_table_get_nrow(tab_bpm);
4583 pbpm=cpl_mask_get_data(bpm);
4584 int point;
4585 int num_good_pix;
4586 int num_tot_pix;
4587 //int good;
4588 int frame_bad;
4589 int x,y;
4590 //xsh_msg("total frames: %d",sz);
4591 int i,j,m;
4592 for(m=0;m<size;m++) {
4593
4594 i=px[m];
4595 j=py[m];
4596 //xsh_msg("j=%d",j);
4597 //xsh_msg("i=%d",i);
4598 sx_j=sx*j;
4599 pix=sx_j+i;
4600
4601 frame_bad=0;
4602 //xsh_msg("pix=%d",pix);
4603
4604 sum_good_pix=0;
4605 num_good_pix=0;
4606 sum_tot_pix=0;
4607 num_tot_pix=0;
4608 //xsh_msg("found bad pix at pos[%d,%d]",i,j);
4609 /* if the pixel is flagged we compute the scaling factor */
4610 int y_min=j-win_hsy, y_max=j+win_hsy;
4611 //xsh_msg("init y_min=%d y_max=%d",y_min,y_max);
4612 /* Not to hit image edges use asymmetric interval at image edges */
4613 if (y_min < 0) {
4614 //xsh_msg("y case1");
4615 y_min = 0;
4616 y_max = win_sy;
4617 } else if ( y_max > sy) {
4618 //xsh_msg("y case2 j=%d j+y_max=%d,sy=%d",j,j+y_max,sy);
4619 y_max=sy;
4620 y_min=y_max-win_sy;
4621 }
4622 //xsh_msg("corrected y_min=%d y_max=%d",y_min,y_max);
4623 int x_min=i-win_hsx, x_max=i+win_hsx;
4624 //xsh_msg("init x_min=%d x_max=%d",x_min,x_max);
4625 if (x_min < 0) {
4626 //xsh_msg("x case1")/;
4627 x_min = 0;
4628 x_max = win_sx;
4629 } else if ( x_max > sx) {
4630 //xsh_msg("x case2 i=%d i+x_max=%d,sx=%d",i,i+x_max,sx);
4631 x_max=sx;
4632 x_min=x_max-win_sx;
4633 }
4634 //xsh_msg("corrected x_min=%d x_max=%d",x_min,x_max);
4635 sum_all=0;
4636 sum_good=0;
4637 //sum_bad=0;
4638 //good=0;
4639
4640 /* copy data to accessory imagelist (because we will unset only
4641 * on the wrapped imagelist the frame at which we found a bad
4642 * pixel in the original list */
4643 iml_all = cpl_imagelist_new();
4644 iml_good = cpl_imagelist_new();
4645 //iml_all=cpl_imagelist_duplicate(iml_data);
4646 //iml_good=cpl_imagelist_duplicate(iml_data);
4647
4648 for(int k=0;k<sz;k++) {
4649 ima_tmp=cpl_imagelist_get(iml_copy,k);
4650
4651 cpl_imagelist_set(iml_good,cpl_image_duplicate(ima_tmp),k);
4652 cpl_imagelist_set(iml_all,cpl_image_duplicate(ima_tmp),k);
4653
4654 }
4655
4656 /* we search now on which frame image of the original list was
4657 * present the flagged pixel and we un-set that frame in the
4658 * wrapped list
4659 */
4660
4661 for(int k=0;k<sz-frame_bad;k++) {
4662
4663 ima_tmp=cpl_imagelist_get(iml_good,k);
4664 pdata=cpl_image_get_data_float(ima_tmp);
4665 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4666 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4667
4668 if(pbpm_tmp[pix] == CPL_BINARY_1) {
4669 //xsh_msg("found bad pix unset frame %d",k);
4670 ima_tmp=cpl_imagelist_unset(iml_good,k);
4671 bpm_tmp=cpl_image_unset_bpm(ima_tmp);
4672 cpl_mask_delete(bpm_tmp);
4673 cpl_image_delete(ima_tmp);
4674
4675 //sum_bad = pdata[pix];
4676 frame_bad++;
4677 }
4678 }
4679
4680 //xsh_msg("Found bad pix=%d",frame_bad);
4681
4682 /* to sum only over good pixels we flag the bad ones */
4683 for(int k=0;k<sz-frame_bad;k++) {
4684 ima_tmp=cpl_imagelist_get(iml_good,k);
4685 bpm_tmp=cpl_image_set_bpm(ima_tmp,cpl_mask_duplicate(bpm));
4686 cpl_mask_delete(bpm_tmp);
4687 }
4688
4689 /* to sum only over good pixels we flag the bad ones */
4690 for(int k=0;k<sz;k++) {
4691 ima_tmp=cpl_imagelist_get(iml_all,k);
4692 bpm_tmp=cpl_image_set_bpm(ima_tmp,cpl_mask_duplicate(bpm));
4693 cpl_mask_delete(bpm_tmp);
4694
4695 }
4696
4697 /* now search for the good pixels in the remaining images of
4698 * the wrapped imagelist around the bad pixel to compute the sum
4699 * of good and the sum of all pixels
4700 */
4701
4702 for(y=y_min; y <= y_max; y++) {
4703 //xsh_msg("y=%d",y);
4704 for(x=x_min; x <= x_max; x++) {
4705 //xsh_msg("x=%d",x);
4706 point=y*sx+x;
4707
4708 //xsh_msg("compute sum on all %d frames",sz);
4709 for(int k=0;k<sz;k++) {
4710 ima_tmp=cpl_imagelist_get(iml_all,k);
4711 pdata=cpl_image_get_data_float(ima_tmp);
4712 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4713 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4714 if(pbpm_tmp[point] == CPL_BINARY_0) {
4715 sum_all += pdata[point];
4716 }
4717 //xsh_msg("scan point %d at %d,%d",point,i,j);
4718
4719 }
4720
4721 //xsh_msg("compute sum on %d left frames",sz-frame_bad);
4722 for(int k=0;k<sz-frame_bad;k++) {
4723 ima_tmp=cpl_imagelist_get(iml_good,k);
4724 pdata=cpl_image_get_data_float(ima_tmp);
4725 bpm_tmp=cpl_image_get_bpm(ima_tmp);
4726 pbpm_tmp=cpl_mask_get_data(bpm_tmp);
4727 //xsh_msg("scan point %d at %d,%d",point,i,j);
4728 if( pbpm[point] == CPL_BINARY_0 ) {
4729 sum_good += pdata[point];
4730 }
4731 }
4732
4733 // determine the sum of good pixel at pos of bad pix
4734 for(int k=0;k<sz-frame_bad;k++) {
4735 ima_tmp=cpl_imagelist_get(iml_good,k);
4736 pdata=cpl_image_get_data_float(ima_tmp);
4737
4738 if( pnot[pix] == CPL_BINARY_0 && pix != point) {
4739 sum_good_pix += pdata[pix];
4740 num_good_pix++;
4741 }
4742
4743 if( pnot[pix] == CPL_BINARY_0 && pix == point) {
4744 sum_tot_pix += pdata[pix];
4745 num_tot_pix++;
4746 }
4747 }
4748
4749 }
4750 } //end loop to compute sum
4751
4752 scale = sum_all / sum_good;
4753 //scale = sum_tot_pix / num_tot_pix * num_good_pix / sum_good_pix;
4754 //pres[pix] = scale*num_tot_pix/num_good_pix;
4755 //pres[pix] = scale;
4756 pres[pix]=scale*num_tot_pix/sz; //good for uniform images case
4757 //pres[pix]=1;
4758
4759 xsh_msg("sum all %g good %g good_pix %g num_good %d sum_tot_pix %g num_tot_pix %d scale %g res: %g",
4760 sum_all,sum_good,sum_good_pix, num_good_pix, sum_tot_pix, num_tot_pix, scale, pres[pix]);
4761
4762
4763 int n=cpl_imagelist_get_size(iml_good);
4764 //sxsh_msg("ok1 sz=%d n=%d",sz,n);
4765 for(int k=0;k<n;k++) {
4766 ima_tmp=cpl_imagelist_get(iml_good,k);
4767 cpl_image_delete(ima_tmp);
4768 }
4769 for(int k=0;k<sz;k++) {
4770 ima_tmp=cpl_imagelist_get(iml_all,k);
4771 cpl_image_delete(ima_tmp);
4772 }
4773
4774 //cpl_imagelist_delete(iml_good);
4775 //cpl_imagelist_delete(iml_all);
4776 //cpl_imagelist_empty(iml_good);
4777 //cpl_imagelist_empty(iml_all);
4778 cpl_imagelist_unwrap(iml_good);
4779 cpl_imagelist_unwrap(iml_all);
4780
4781 }
4782
4783 cpl_imagelist_delete(iml_copy);
4784 cpl_mask_delete(not);
4785 return res;
4786}
4787
4788
4789cpl_image*
4790xsh_compute_scale_tab2(cpl_imagelist* iml_data, cpl_imagelist* iml_qual,
4791 cpl_mask* bpm, cpl_table* tab_bpm, const int mode,
4792 const int win_hsz, const int decode_bp)
4793{
4794 cpl_image* res;
4795 int sx_j;
4796 int pix;
4797 int win_hsx;
4798 int win_hsy;
4799 if(mode==0) {
4800 win_hsx=0;
4801 win_hsy=win_hsz;
4802 } else {
4803 win_hsx=win_hsz;
4804 win_hsy=0;
4805 }
4806 int win_sx=2*win_hsx+1;
4807 int win_sy=2*win_hsy+1;
4808 int sz=cpl_imagelist_get_size(iml_data);
4809 double sum_all;
4810 double sum_good;
4811 double sum_good_pix;
4812 double sum_tot_pix;
4813 float* pdata;
4814 int* pqual;
4815 cpl_mask* bpm_tmp;
4816 //double sum_bad;
4817 double scale;
4818
4819 cpl_image* ima_data_tmp;
4820 cpl_image* ima_qual_tmp;
4821
4822 //cpl_imagelist* iml_tmp;
4823 cpl_imagelist* iml_data_good;
4824 cpl_imagelist* iml_data_all;
4825 cpl_imagelist* iml_qual_good;
4826 cpl_imagelist* iml_qual_all;
4827
4828 ima_data_tmp=cpl_imagelist_get(iml_data,0);
4829 cpl_imagelist* iml_data_copy=cpl_imagelist_duplicate(iml_data);
4830 cpl_imagelist* iml_qual_copy=cpl_imagelist_duplicate(iml_qual);
4831 int sx=cpl_image_get_size_x(ima_data_tmp);
4832 int sy=cpl_image_get_size_y(ima_data_tmp);
4833 double* pres;
4834 res=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
4835 cpl_image_add_scalar(res,1.);
4836 pres=cpl_image_get_data(res);
4837
4838 int* px=cpl_table_get_data_int(tab_bpm,"x");
4839 int* py=cpl_table_get_data_int(tab_bpm,"y");
4840 int size=cpl_table_get_nrow(tab_bpm);
4841
4842 int point;
4843 int num_good_pix;
4844 int num_tot_pix;
4845 //int good;
4846 int frame_bad;
4847 int x,y;
4848 //xsh_msg("sx=%d sy=%d",sx,sy);
4849
4850 //xsh_msg("total frames: %d",sz);
4851 int i,j,m;
4852 for(m=0;m<size;m++) {
4853
4854 i=px[m];
4855 j=py[m];
4856 //xsh_msg("j=%d",j);
4857 //xsh_msg("i=%d",i);
4858 sx_j=sx*j;
4859 pix=sx_j+i;
4860
4861 frame_bad=0;
4862 //xsh_msg("pix=%d",pix);
4863
4864 sum_good_pix=0;
4865 num_good_pix=0;
4866 sum_tot_pix=0;
4867 num_tot_pix=0;
4868 //xsh_msg("found bad pix at pos[%d,%d]",i,j);
4869 /* if the pixel is flagged we compute the scaling factor */
4870 int y_min=j-win_hsy, y_max=j+win_hsy;
4871 //xsh_msg("init y_min=%d y_max=%d",y_min,y_max);
4872 /* Not to hit image edges use asymmetric interval at image edges */
4873 if (y_min < 0) {
4874 //xsh_msg("y case1");
4875 y_min = 0;
4876 y_max = win_sy;
4877 } else if ( y_max >= sy) {
4878 //xsh_msg("y case2 j=%d j+y_max=%d,sy=%d",j,j+y_max,sy);
4879 y_max=sy-1;
4880 y_min=y_max-win_sy;
4881 }
4882 //xsh_msg("corrected y_min=%d y_max=%d",y_min,y_max);
4883 int x_min=i-win_hsx, x_max=i+win_hsx;
4884 //xsh_msg("init x_min=%d x_max=%d",x_min,x_max);
4885 if (x_min < 0) {
4886 //xsh_msg("x case1")/;
4887 x_min = 0;
4888 x_max = win_sx;
4889 } else if ( x_max >= sx) {
4890 //xsh_msg("x case2 i=%d i+x_max=%d,sx=%d",i,i+x_max,sx);
4891 x_max=sx-1;
4892 x_min=x_max-win_sx;
4893 }
4894 //xsh_msg("corrected x_min=%d x_max=%d",x_min,x_max);
4895 sum_all=0;
4896 sum_good=0;
4897 //sum_bad=0;
4898 //good=0;
4899
4900 /* copy data to accessory imagelist (because we will unset only
4901 * on the wrapped imagelist the frame at which we found a bad
4902 * pixel in the original list */
4903 iml_data_all = cpl_imagelist_new();
4904 iml_data_good = cpl_imagelist_new();
4905 iml_qual_all = cpl_imagelist_new();
4906 iml_qual_good = cpl_imagelist_new();
4907 //iml_data_all=cpl_imagelist_duplicate(iml_data);
4908 //iml_data_good=cpl_imagelist_duplicate(iml_data);
4909
4910 for(int k=0;k<sz;k++) {
4911 ima_data_tmp=cpl_imagelist_get(iml_data_copy,k);
4912
4913 cpl_imagelist_set(iml_data_good,cpl_image_duplicate(ima_data_tmp),k);
4914 cpl_imagelist_set(iml_data_all,cpl_image_duplicate(ima_data_tmp),k);
4915
4916
4917
4918 ima_qual_tmp=cpl_imagelist_get(iml_qual_copy,k);
4919
4920 cpl_imagelist_set(iml_qual_good,cpl_image_duplicate(ima_qual_tmp),k);
4921 cpl_imagelist_set(iml_qual_all,cpl_image_duplicate(ima_qual_tmp),k);
4922
4923 }
4924
4925 /* we search now on which frame image of the original list was
4926 * present the flagged pixel and we un-set that frame in the
4927 * wrapped list
4928 */
4929
4930 for(int k=0;k<sz-frame_bad;k++) {
4931
4932 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
4933 pdata=cpl_image_get_data_float(ima_data_tmp);
4934
4935
4936 ima_qual_tmp=cpl_imagelist_get(iml_qual_good,k);
4937 pqual=cpl_image_get_data_int(ima_qual_tmp);
4938
4939
4940 if( (pqual[pix] & decode_bp) > 0) {
4941 //xsh_msg("found bad pix unset frame %d",k);
4942 ima_data_tmp=cpl_imagelist_unset(iml_data_good,k);
4943 cpl_image_delete(ima_data_tmp);
4944
4945 ima_qual_tmp=cpl_imagelist_unset(iml_qual_good,k);
4946 cpl_image_delete(ima_qual_tmp);
4947
4948 //sum_bad = pdata[pix];
4949 frame_bad++;
4950 }
4951 }
4952
4953 //xsh_msg("Found bad pix=%d",frame_bad);
4954
4955 /* to sum only over good pixels we flag the bad ones */
4956 for(int k=0;k<sz-frame_bad;k++) {
4957 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
4958 bpm_tmp=cpl_image_set_bpm(ima_data_tmp,cpl_mask_duplicate(bpm));
4959 cpl_mask_delete(bpm_tmp);
4960 }
4961
4962 /* to sum only over good pixels we flag the bad ones */
4963 for(int k=0;k<sz;k++) {
4964 ima_data_tmp=cpl_imagelist_get(iml_data_all,k);
4965 bpm_tmp=cpl_image_set_bpm(ima_data_tmp,cpl_mask_duplicate(bpm));
4966 cpl_mask_delete(bpm_tmp);
4967
4968 }
4969
4970 /* now search for the good pixels in the remaining images of
4971 * the wrapped imagelist around the bad pixel to compute the sum
4972 * of good and the sum of all pixels
4973 */
4974 //xsh_msg("y_min=%d y_max=%d",y_min,y_max);
4975 for(y=y_min; y <= y_max; y++) {
4976 //xsh_msg("y=%d",y);
4977 for(x=x_min; x <= x_max; x++) {
4978 //xsh_msg("x=%d",x);
4979 point=y*sx+x;
4980
4981 //xsh_msg("compute sum on all %d frames",sz);
4982 for(int k=0;k<sz;k++) {
4983 ima_data_tmp=cpl_imagelist_get(iml_data_all,k);
4984 pdata=cpl_image_get_data_float(ima_data_tmp);
4985 //xsh_msg("k=%d",k);
4986 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
4987 pqual=cpl_image_get_data_int(ima_qual_tmp);
4988
4989 if((pqual[point] & decode_bp) == 0) {
4990 sum_all += pdata[point];
4991 }
4992 //xsh_msg("scan point %d at %d,%d",point,i,j);
4993
4994 }
4995
4996 //xsh_msg("compute sum on %d left frames",sz-frame_bad);
4997 for(int k=0;k<sz-frame_bad;k++) {
4998 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
4999 pdata=cpl_image_get_data_float(ima_data_tmp);
5000
5001 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5002 pqual=cpl_image_get_data_int(ima_qual_tmp);
5003
5004 //xsh_msg("scan point %d at %d,%d",point,i,j);
5005 if( (pqual[point] & decode_bp) == 0 ) {
5006 sum_good += pdata[point];
5007 }
5008 }
5009
5010 // determine the sum of good pixel at pos of bad pix
5011 for(int k=0;k<sz-frame_bad;k++) {
5012 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5013 pdata=cpl_image_get_data_float(ima_data_tmp);
5014
5015 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5016 pqual=cpl_image_get_data_int(ima_qual_tmp);
5017
5018 if( ( (pqual[point] & decode_bp) == 0) && pix != point) {
5019 sum_good_pix += pdata[pix];
5020 num_good_pix++;
5021 }
5022
5023 if( ( (pqual[point] & decode_bp) == 0) && pix == point) {
5024 sum_tot_pix += pdata[pix];
5025 num_tot_pix++;
5026 }
5027 }
5028
5029 }
5030 } //end loop to compute sum
5031
5032 scale = sum_all / sum_good;
5033 //scale = sum_tot_pix / num_tot_pix * num_good_pix / sum_good_pix;
5034 //pres[pix] = scale*num_tot_pix/num_good_pix;
5035 //pres[pix] = scale;
5036 pres[pix]=scale*num_tot_pix/sz; //good for uniform images case
5037 //pres[pix]=1;
5038
5039 xsh_msg("sum all %g good %g good_pix %g num_good %d sum_tot_pix %g num_tot_pix %d scale %g res: %g",
5040 sum_all,sum_good,sum_good_pix, num_good_pix, sum_tot_pix, num_tot_pix, scale, pres[pix]);
5041
5042
5043 int n=cpl_imagelist_get_size(iml_data_good);
5044 //sxsh_msg("ok1 sz=%d n=%d",sz,n);
5045 for(int k=0;k<n;k++) {
5046 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5047 cpl_image_delete(ima_data_tmp);
5048 }
5049 for(int k=0;k<sz;k++) {
5050 ima_data_tmp=cpl_imagelist_get(iml_data_all,k);
5051 cpl_image_delete(ima_data_tmp);
5052 }
5053
5054 for(int k=0;k<n;k++) {
5055 ima_qual_tmp=cpl_imagelist_get(iml_qual_good,k);
5056 cpl_image_delete(ima_qual_tmp);
5057 }
5058 for(int k=0;k<sz;k++) {
5059 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5060 cpl_image_delete(ima_qual_tmp);
5061 }
5062
5063 //cpl_imagelist_delete(iml_data_good);
5064 //cpl_imagelist_delete(iml_data_all);
5065 //cpl_imagelist_empty(iml_data_good);
5066 //cpl_imagelist_empty(iml_data_all);
5067 cpl_imagelist_unwrap(iml_data_good);
5068 cpl_imagelist_unwrap(iml_data_all);
5069
5070 }
5071
5072 cpl_imagelist_delete(iml_data_copy);
5073 cpl_imagelist_delete(iml_qual_copy);
5074
5075 return res;
5076}
5077
5078cpl_image*
5079xsh_compute_scale_tab3(cpl_imagelist* iml_data, cpl_imagelist* iml_qual,
5080 cpl_mask* bpm, cpl_table* tab_bpm, const int mode,
5081 const int win_hsz, const int decode_bp)
5082{
5083 cpl_image* res;
5084 int sx_j;
5085 int pix;
5086 int win_hsx;
5087 int win_hsy;
5088 if(mode==0) {
5089 win_hsx=0;
5090 win_hsy=win_hsz;
5091 } else {
5092 win_hsx=win_hsz;
5093 win_hsy=0;
5094 }
5095 int win_sx=2*win_hsx+1;
5096 int win_sy=2*win_hsy+1;
5097 int sz=cpl_imagelist_get_size(iml_data);
5098 double sum_all;
5099 double sum_good;
5100 double sum_good_pix;
5101 double sum_tot_pix;
5102 float* pdata;
5103 int* pqual;
5104 cpl_mask* bpm_tmp;
5105 //double sum_bad;
5106 double scale;
5107
5108 cpl_image* ima_data_tmp;
5109 cpl_image* ima_qual_tmp;
5110
5111 //cpl_imagelist* iml_tmp;
5112 cpl_imagelist* iml_data_good;
5113 cpl_imagelist* iml_data_all;
5114 cpl_imagelist* iml_qual_good;
5115 cpl_imagelist* iml_qual_all;
5116
5117 ima_data_tmp=cpl_imagelist_get(iml_data,0);
5118 cpl_imagelist* iml_data_copy=cpl_imagelist_duplicate(iml_data);
5119 cpl_imagelist* iml_qual_copy=cpl_imagelist_duplicate(iml_qual);
5120 int sx=cpl_image_get_size_x(ima_data_tmp);
5121 int sy=cpl_image_get_size_y(ima_data_tmp);
5122 double* pres;
5123 res=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
5124 cpl_image_add_scalar(res,1.);
5125 pres=cpl_image_get_data(res);
5126
5127 int* px=cpl_table_get_data_int(tab_bpm,"x");
5128 int* py=cpl_table_get_data_int(tab_bpm,"y");
5129 int size=cpl_table_get_nrow(tab_bpm);
5130
5131 int point;
5132 int num_good_pix;
5133 int num_tot_pix;
5134 //int good;
5135 int frame_bad;
5136 int x,y;
5137 //xsh_msg("sx=%d sy=%d",sx,sy);
5138
5139 //xsh_msg("total frames: %d",sz);
5140 int i,j,m;
5141 for(m=0;m<size;m++) {
5142
5143 i=px[m];
5144 j=py[m];
5145 //xsh_msg("j=%d",j);
5146 //xsh_msg("i=%d",i);
5147 sx_j=sx*j;
5148 pix=sx_j+i;
5149
5150 frame_bad=0;
5151 //xsh_msg("pix=%d",pix);
5152
5153 sum_good_pix=0;
5154 num_good_pix=0;
5155 sum_tot_pix=0;
5156 num_tot_pix=0;
5157 //xsh_msg("found bad pix at pos[%d,%d]",i,j);
5158 /* if the pixel is flagged we compute the scaling factor */
5159 int y_min=j-win_hsy, y_max=j+win_hsy;
5160 //xsh_msg("init y_min=%d y_max=%d",y_min,y_max);
5161 /* Not to hit image edges use asymmetric interval at image edges */
5162 if (y_min < 0) {
5163 //xsh_msg("y case1");
5164 y_min = 0;
5165 y_max = win_sy;
5166 } else if ( y_max >= sy) {
5167 //xsh_msg("y case2 j=%d j+y_max=%d,sy=%d",j,j+y_max,sy);
5168 y_max=sy-1;
5169 y_min=y_max-win_sy;
5170 }
5171 //xsh_msg("corrected y_min=%d y_max=%d",y_min,y_max);
5172 int x_min=i-win_hsx, x_max=i+win_hsx;
5173 //xsh_msg("init x_min=%d x_max=%d",x_min,x_max);
5174 if (x_min < 0) {
5175 //xsh_msg("x case1")/;
5176 x_min = 0;
5177 x_max = win_sx;
5178 } else if ( x_max >= sx) {
5179 //xsh_msg("x case2 i=%d i+x_max=%d,sx=%d",i,i+x_max,sx);
5180 x_max=sx-1;
5181 x_min=x_max-win_sx;
5182 }
5183 //xsh_msg("corrected x_min=%d x_max=%d",x_min,x_max);
5184 sum_all=0;
5185 sum_good=0;
5186 //sum_bad=0;
5187 //good=0;
5188
5189 /* copy data to accessory imagelist (because we will unset only
5190 * on the wrapped imagelist the frame at which we found a bad
5191 * pixel in the original list */
5192 iml_data_all = cpl_imagelist_new();
5193 iml_data_good = cpl_imagelist_new();
5194 iml_qual_all = cpl_imagelist_new();
5195 iml_qual_good = cpl_imagelist_new();
5196 //iml_data_all=cpl_imagelist_duplicate(iml_data);
5197 //iml_data_good=cpl_imagelist_duplicate(iml_data);
5198
5199 for(int k=0;k<sz;k++) {
5200 ima_data_tmp=cpl_imagelist_get(iml_data_copy,k);
5201
5202 cpl_imagelist_set(iml_data_good,ima_data_tmp,k);
5203 cpl_imagelist_set(iml_data_all,ima_data_tmp,k);
5204
5205
5206
5207 ima_qual_tmp=cpl_imagelist_get(iml_qual_copy,k);
5208
5209 cpl_imagelist_set(iml_qual_good,ima_qual_tmp,k);
5210 cpl_imagelist_set(iml_qual_all,ima_qual_tmp,k);
5211
5212 }
5213
5214 /* we search now on which frame image of the original list was
5215 * present the flagged pixel and we un-set that frame in the
5216 * wrapped list
5217 */
5218
5219 for(int k=0;k<sz-frame_bad;k++) {
5220
5221 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5222 pdata=cpl_image_get_data_float(ima_data_tmp);
5223
5224
5225 ima_qual_tmp=cpl_imagelist_get(iml_qual_good,k);
5226 pqual=cpl_image_get_data_int(ima_qual_tmp);
5227
5228
5229 if( (pqual[pix] & decode_bp) > 0) {
5230 //xsh_msg("found bad pix unset frame %d",k);
5231 ima_data_tmp=cpl_imagelist_unset(iml_data_good,k);
5232 //cpl_image_delete(ima_data_tmp);
5233
5234 ima_qual_tmp=cpl_imagelist_unset(iml_qual_good,k);
5235 //cpl_image_delete(ima_qual_tmp);
5236
5237 //sum_bad = pdata[pix];
5238 frame_bad++;
5239 }
5240 }
5241
5242 //xsh_msg("Found bad pix=%d",frame_bad);
5243
5244 /* to sum only over good pixels we flag the bad ones */
5245 for(int k=0;k<sz-frame_bad;k++) {
5246 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5247 bpm_tmp=cpl_image_set_bpm(ima_data_tmp,bpm);
5248
5249 if(bpm_tmp != NULL) { cpl_mask_delete(bpm_tmp); }
5250 }
5251
5252 /* to sum only over good pixels we flag the bad ones */
5253 for(int k=0;k<sz;k++) {
5254 ima_data_tmp=cpl_imagelist_get(iml_data_all,k);
5255 bpm_tmp=cpl_image_set_bpm(ima_data_tmp,bpm);
5256
5257 if(bpm_tmp != NULL) { cpl_mask_delete(bpm_tmp); }
5258
5259 }
5260
5261 /* now search for the good pixels in the remaining images of
5262 * the wrapped imagelist around the bad pixel to compute the sum
5263 * of good and the sum of all pixels
5264 */
5265 //xsh_msg("y_min=%d y_max=%d",y_min,y_max);
5266 for(y=y_min; y <= y_max; y++) {
5267 //xsh_msg("y=%d",y);
5268 for(x=x_min; x <= x_max; x++) {
5269 //xsh_msg("x=%d",x);
5270 point=y*sx+x;
5271
5272 //xsh_msg("compute sum on all %d frames",sz);
5273 for(int k=0;k<sz;k++) {
5274 ima_data_tmp=cpl_imagelist_get(iml_data_all,k);
5275 pdata=cpl_image_get_data_float(ima_data_tmp);
5276 //xsh_msg("k=%d",k);
5277 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5278 pqual=cpl_image_get_data_int(ima_qual_tmp);
5279
5280 if((pqual[point] & decode_bp) == 0) {
5281 sum_all += pdata[point];
5282 }
5283 //xsh_msg("scan point %d at %d,%d",point,i,j);
5284
5285 }
5286
5287 //xsh_msg("compute sum on %d left frames",sz-frame_bad);
5288 for(int k=0;k<sz-frame_bad;k++) {
5289 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5290 pdata=cpl_image_get_data_float(ima_data_tmp);
5291
5292 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5293 pqual=cpl_image_get_data_int(ima_qual_tmp);
5294
5295 //xsh_msg("scan point %d at %d,%d",point,i,j);
5296 if( (pqual[point] & decode_bp) == 0 ) {
5297 sum_good += pdata[point];
5298 }
5299 }
5300
5301 // determine the sum of good pixel at pos of bad pix
5302 for(int k=0;k<sz-frame_bad;k++) {
5303 ima_data_tmp=cpl_imagelist_get(iml_data_good,k);
5304 pdata=cpl_image_get_data_float(ima_data_tmp);
5305
5306 ima_qual_tmp=cpl_imagelist_get(iml_qual_all,k);
5307 pqual=cpl_image_get_data_int(ima_qual_tmp);
5308
5309 if( ( (pqual[point] & decode_bp) == 0) && pix != point) {
5310 sum_good_pix += pdata[pix];
5311 num_good_pix++;
5312 }
5313
5314 if( ( (pqual[point] & decode_bp) == 0) && pix == point) {
5315 sum_tot_pix += pdata[pix];
5316 num_tot_pix++;
5317 }
5318 }
5319
5320 }
5321 } //end loop to compute sum
5322
5323 scale = sum_all / sum_good;
5324 //scale = sum_tot_pix / num_tot_pix * num_good_pix / sum_good_pix;
5325 //pres[pix] = scale*num_tot_pix/num_good_pix;
5326 //pres[pix] = scale;
5327 pres[pix]=scale*num_tot_pix/sz; //good for uniform images case
5328 //pres[pix]=1;
5329
5330 xsh_msg("sum all %g good %g good_pix %g num_good %d sum_tot_pix %g num_tot_pix %d scale %g res: %g",
5331 sum_all,sum_good,sum_good_pix, num_good_pix, sum_tot_pix, num_tot_pix, scale, pres[pix]);
5332
5333
5334 int n=cpl_imagelist_get_size(iml_data_good);
5335 //sxsh_msg("ok1 sz=%d n=%d",sz,n);
5336 for(int k=0;k<n;k++) {
5337 ima_data_tmp=cpl_imagelist_unset(iml_data_good,k);
5338 //cpl_image_delete(ima_data_tmp);
5339 }
5340 for(int k=0;k<sz;k++) {
5341 ima_data_tmp=cpl_imagelist_unset(iml_data_all,k);
5342 //cpl_image_delete(ima_data_tmp);
5343 }
5344
5345 for(int k=0;k<n;k++) {
5346 ima_qual_tmp=cpl_imagelist_unset(iml_qual_good,k);
5347 //cpl_image_delete(ima_qual_tmp);
5348 }
5349 for(int k=0;k<sz;k++) {
5350 ima_qual_tmp=cpl_imagelist_unset(iml_qual_all,k);
5351 //cpl_image_delete(ima_qual_tmp);
5352 }
5353
5354 //cpl_imagelist_delete(iml_data_good);
5355 //cpl_imagelist_delete(iml_data_all);
5356 //cpl_imagelist_empty(iml_data_good);
5357 //cpl_imagelist_empty(iml_data_all);
5358 cpl_imagelist_unwrap(iml_data_good);
5359 cpl_imagelist_unwrap(iml_data_all);
5360
5361 }
5362
5363 cpl_imagelist_delete(iml_data_copy);
5364 cpl_imagelist_delete(iml_qual_copy);
5365
5366 return res;
5367}
5368
5369cpl_table*
5370xsh_qual2tab(cpl_image* qual, const int code)
5371{
5372 int sx=cpl_image_get_size_x(qual);
5373 int sy=cpl_image_get_size_y(qual);
5374 const int size=sx*sy;
5375 cpl_table* xy_pos=cpl_table_new(size);
5376 cpl_table_new_column(xy_pos,"x",CPL_TYPE_INT);
5377 cpl_table_new_column(xy_pos,"y",CPL_TYPE_INT);
5378 int* px=cpl_table_get_data_int(xy_pos,"x");
5379 int* py=cpl_table_get_data_int(xy_pos,"y");
5380
5381 int* pqual=cpl_image_get_data_int(qual);
5382 int j_nx;
5383 int pix;
5384 int k=0;
5385 //xsh_msg("copy bad pixels in table");
5386 for(int j=0;j<sy;j++){
5387 j_nx=j*sx;
5388 for(int i=0;i<sx;i++){
5389 pix=j_nx+i;
5390 if ( (pqual[pix] & code) > 0) {
5391 //xsh_msg("found bad pixel at [%d,%d]",i,j);
5392 px[k]=i;
5393 py[k]=j;
5394 k++;
5395 }
5396 }
5397 }
5398 cpl_table_set_size(xy_pos,k);
5399 return xy_pos;
5400}
5401
static int width
static char mode[32]
static xsh_instrument * instrument
int binx
int biny
cpl_error_code xsh_badpixelmap_image_coadd(cpl_image **self, const cpl_image *right, const int mode)
int xsh_order_list_eval_int(xsh_order_list *list, cpl_polynomial *poly, double y)
Evaluate an order list poly but return the central pixel position rounding the polynomial.
xsh_pre * xsh_pre_load(cpl_frame *frame, xsh_instrument *instr)
Load a xsh_pre structure from a frame.
Definition: xsh_data_pre.c:849
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
Definition: xsh_data_pre.c:823
cpl_frame * xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag, int temp)
Save PRE on disk.
#define XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define xsh_error_msg(...)
Definition: xsh_error.h:94
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
#define cknull_msg(NULLEXP,...)
Definition: xsh_error.h:73
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
int size
int * y
int * x
#define xsh_msg_error(...)
Print an error message.
Definition: xsh_msg.h:62
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_high(...)
Definition: xsh_msg.h:40
int xsh_pfits_get_ovscx(const cpl_propertylist *plist)
find out the OVSCX value
Definition: xsh_pfits.c:391
double xsh_pfits_get_cdelt3(const cpl_propertylist *plist)
find out the cdelt3
Definition: xsh_pfits.c:2235
int xsh_pfits_get_ovscy(const cpl_propertylist *plist)
find out the OVSCY value
Definition: xsh_pfits.c:408
cpl_error_code xsh_plist_div_by_fct(cpl_propertylist **plist, const int fctx, const int fcty)
Definition: xsh_pfits.c:4417
double xsh_pfits_get_cdelt1(const cpl_propertylist *plist)
find out the cdelt1
Definition: xsh_pfits.c:2196
int xsh_pfits_get_prscx(const cpl_propertylist *plist)
find out the PRSCX value
Definition: xsh_pfits.c:425
double xsh_pfits_get_crval1(const cpl_propertylist *plist)
find out the crval1
Definition: xsh_pfits.c:1907
int xsh_pfits_get_prscy(const cpl_propertylist *plist)
find out the PRSCY value
Definition: xsh_pfits.c:442
double xsh_pfits_get_crval3(const cpl_propertylist *plist)
find out the crval3
Definition: xsh_pfits.c:1946
void xsh_pfits_set_qc_ron1(cpl_propertylist *plist, double value)
Definition: xsh_pfits_qc.c:509
void xsh_pfits_set_qc_ron1_err(cpl_propertylist *plist, double value)
Definition: xsh_pfits_qc.c:554
void xsh_pfits_set_qc_ron2_err(cpl_propertylist *plist, double value)
Definition: xsh_pfits_qc.c:576
void xsh_pfits_set_qc_ron2(cpl_propertylist *plist, double value)
Definition: xsh_pfits_qc.c:531
void xsh_vector_fit_gaussian(cpl_vector *x, cpl_vector *y, XSH_GAUSSIAN_FIT *result)
set debug level
Definition: xsh_utils.c:3101
void xsh_free_polynomial(cpl_polynomial **p)
Deallocate a polynomial and set the pointer to NULL.
Definition: xsh_utils.c:2194
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
Definition: xsh_utils.c:2116
cpl_error_code xsh_get_property_value(const cpl_propertylist *plist, const char *keyword, cpl_type keywordtype, void *result)
Read a property value from a property list.
Definition: xsh_utils.c:1600
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
void xsh_free_array(cpl_array **m)
Deallocate an array and set the pointer to NULL.
Definition: xsh_utils.c:2299
void xsh_free_mask(cpl_mask **m)
Deallocate an image mask and set the pointer to NULL.
Definition: xsh_utils.c:2149
char * xsh_get_basename(const char *filename)
Return base filename.
Definition: xsh_utils.c:1175
void xsh_free_matrix(cpl_matrix **m)
Deallocate a matrix and set the pointer to NULL.
Definition: xsh_utils.c:2209
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
void xsh_free_imagelist(cpl_imagelist **i)
Deallocate an image list and set the pointer to NULL.
Definition: xsh_utils.c:2164
void xsh_add_temporary_file(const char *name)
Add temporary file to temprary files list.
Definition: xsh_utils.c:1432
float cleanstdev
float cleanmean
xsh_order * list
cpl_polynomial * edguppoly
cpl_polynomial * edglopoly
cpl_polynomial * cenpoly
cpl_image * qual
Definition: xsh_data_pre.h:71
cpl_image * data
Definition: xsh_data_pre.h:65
int biny
Definition: xsh_data_pre.h:80
int binx
Definition: xsh_data_pre.h:80
cpl_image * errs
Definition: xsh_data_pre.h:68
#define QFLAG_OTHER_BAD_PIXEL
#define QFLAG_HOT_PIXEL
@ XSH_ARM_UVB
@ XSH_ARM_VIS
#define XSH_PRE_DATA_TYPE
Definition: xsh_data_pre.h:42
#define XSH_PRE_QUAL_TYPE
Definition: xsh_data_pre.h:46
#define XSH_PRE_ERRS_BPP
Definition: xsh_data_pre.h:45
#define XSH_PRE_QUAL_BPP
Definition: xsh_data_pre.h:47
#define XSH_PRE_ERRS_TYPE
Definition: xsh_data_pre.h:44
#define XSH_PRE_DATA_BPP
Definition: xsh_data_pre.h:43
int nx
double kappa
Definition: xsh_detmon_lg.c:81
int lly
Definition: xsh_detmon_lg.c:86
int llx
Definition: xsh_detmon_lg.c:85
int m
Definition: xsh_detmon_lg.c:91
int n
Definition: xsh_detmon_lg.c:92
const char * method
Definition: xsh_detmon_lg.c:78
int urx
Definition: xsh_detmon_lg.c:87
int ury
Definition: xsh_detmon_lg.c:88
int ny
int order
Definition: xsh_detmon_lg.c:80
int filter
int xsh_print_rec_status(const int val)
Check if an error has happened and returns error kind and location.
Definition: xsh_dfs.c:877
cpl_frame * xsh_frame_product(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level)
Creates a frame with given characteristics.
Definition: xsh_dfs.c:930
#define XSH_UVB_DICHROIC_WAVE_CUT
Definition: xsh_globals.h:38
#define XSH_OVSCX
Definition: xsh_pfits.h:157
#define XSH_PCATG
Definition: xsh_pfits.h:185
#define XSH_PRSCX
Definition: xsh_pfits.h:159
#define XSH_PRSCY
Definition: xsh_pfits.h:160
#define XSH_OVSCY
Definition: xsh_pfits.h:158
#define XSH_WIN_BINY
Definition: xsh_pfits.h:156
#define XSH_WIN_BINX
Definition: xsh_pfits.h:155
#define XSH_QC_TRACE12_AVG
Definition: xsh_pfits_qc.h:76
#define XSH_QC_TRACE_FIT_DIFF_C0
Definition: xsh_pfits_qc.h:67
#define XSH_QC_TRACE32_MAX
Definition: xsh_pfits_qc.h:81
#define XSH_QC_TRACE13_MED
Definition: xsh_pfits_qc.h:89
#define XSH_QC_TRACE32_MIN
Definition: xsh_pfits_qc.h:80
#define XSH_QC_TRACE13_MIN
Definition: xsh_pfits_qc.h:86
#define XSH_QC_TRACE12_MAX
Definition: xsh_pfits_qc.h:75
#define XSH_QC_TRACE32_RMS
Definition: xsh_pfits_qc.h:84
#define XSH_QC_TRACE12_MED
Definition: xsh_pfits_qc.h:77
#define XSH_QC_TRACE13_AVG
Definition: xsh_pfits_qc.h:88
#define XSH_QC_TRACE12_RMS
Definition: xsh_pfits_qc.h:78
#define XSH_QC_TRACE_FIT_DIFF_POS
Definition: xsh_pfits_qc.h:71
#define XSH_QC_TRACE32_MED
Definition: xsh_pfits_qc.h:83
#define XSH_QC_TRACE_FIT_C0
Definition: xsh_pfits_qc.h:53
#define XSH_QC_TRACE_FIT_C2
Definition: xsh_pfits_qc.h:55
#define XSH_QC_TRACE_FIT_DIFF_C1
Definition: xsh_pfits_qc.h:68
#define XSH_QC_TRACE32_AVG
Definition: xsh_pfits_qc.h:82
#define XSH_QC_TRACE13_RMS
Definition: xsh_pfits_qc.h:90
#define XSH_QC_TRACE_FIT_C1
Definition: xsh_pfits_qc.h:54
#define XSH_QC_TRACE13_MAX
Definition: xsh_pfits_qc.h:87
#define XSH_QC_TRACE12_MIN
Definition: xsh_pfits_qc.h:74
static const qc_description qc_table[]
#define M_PI
Definition: xsh_utils.h:43
cpl_image * xsh_image_smooth_median_y(cpl_image *inp, const int r)
double * xsh_generate_interpolation_kernel(const char *kernel_type)
void xsh_show_interpolation_kernel(char *kernel_name)
double xsh_image_get_stdev_robust(const cpl_image *image, double cut, double *dstdev)
Get robust empirical stdev of data.
cpl_error_code xsh_image_mflat_detect_blemishes(cpl_frame *flat_frame, xsh_instrument *instrument)
Flag blemishes in a flat image.
cpl_image * xsh_compute_scale_tab3(cpl_imagelist *iml_data, cpl_imagelist *iml_qual, cpl_mask *bpm, cpl_table *tab_bpm, const int mode, const int win_hsz, const int decode_bp)
cpl_table * xsh_qual2tab(cpl_image *qual, const int code)
cpl_error_code xsh_image_warp_polynomial_scale(cpl_image *out, const cpl_polynomial *poly_x, const cpl_polynomial *poly_y)
Compute area change ratio for a 2D polynomial transformation.
double xsh_fixed_pattern_noise_bias(const cpl_image *first_raw, const cpl_image *second_raw, double ron)
Compute fixed pattern noise in bias.
static cpl_image * xsh_image_mult_by_fct(const cpl_image *ima_dat, const int fctx, const int fcty)
cpl_image * xsh_warp_image_generic(cpl_image *image_in, char *kernel_type, cpl_polynomial *poly_u, cpl_polynomial *poly_v)
static double xsh_sinc(double x)
cpl_error_code xsh_image_cut_dichroic_uvb(cpl_frame *frame1d)
static cpl_error_code xsh_cube_trace_fit(cpl_table **table, const char *col_wav, const char *col_ref, const char *col_fit, const char *qualifier, cpl_propertylist *plist)
Fit cube traces and compute fit coeffs differences.
cpl_image * xsh_compute_scale_tab(cpl_imagelist *iml_data, cpl_mask *bpm, cpl_table *tab_bpm, const int mode, const int win_hsz)
cpl_image * xsh_sobel_lx(cpl_image *in)
Compute X Sobel filter transformation.
static void reverse_tanh_kernel(double *data, int nn)
void xsh_pixel_qsort(pixelvalue *pix_arr, int npix)
cpl_image * xsh_scharr_y(cpl_image *in)
Compute Y Scharr filter transformation.
static cpl_error_code xsh_key_scan_mult_by_fct(cpl_propertylist **plist, const char *kname, const int fct)
cpl_frame * xsh_frame_image_mult_by_fct(cpl_frame *frm, const int fctx, const int fcty)
double xsh_image_fit_gaussian_max_pos_x_window(const cpl_image *ima, const int llx, const int urx, const int ypos)
static cpl_image * xsh_image_crop(const cpl_image *image, int xlo, int ylo, int xhi, int yhi)
Crop image.
double xsh_fixed_pattern_noise(const cpl_image *master, double convert_ADU, double master_noise)
Compute fixed pattern noise in flat field.
cpl_image * xsh_image_smooth_fft(cpl_image *inp, const int fx, const int fy)
static cpl_error_code xsh_key_bin_div_by_fct(cpl_propertylist **plist, const char *kname, const int fct)
cpl_image * xsh_image_smooth_mean_y(cpl_image *inp, const int r)
cpl_error_code xsh_iml_merge_avg(cpl_imagelist **data, cpl_imagelist **mask, const cpl_image *data_ima, const cpl_image *mask_ima, const int mk)
merge imagelist via average
cpl_frame * xsh_frame_image_qc_trace_window(cpl_frame *frm_ima, xsh_instrument *instrument, const char *suffix, const int hsize, const int method)
Trace object position in an image.
static cpl_table * xsh_image_qc_trace_window(cpl_image *data_ima, cpl_propertylist *head, const int hsize, const int method)
Trace object position in an image.
cpl_image * xsh_image_smooth_mean_x(cpl_image *inp, const int r)
static cpl_error_code xsh_compute_geom_corr(const double dxdu, const double dydv, const double dxdv, const double dydu, const double du, const double dv, double *dA)
Pixel area geometric trasformation computation.
static cpl_error_code xsh_util_compute_qc_residuals(cpl_table *table, xsh_instrument *instrument, cpl_propertylist *plist)
Computes residuals statistics on given wave ranges.
cpl_image * xsh_image_search_bad_pixels_via_noise(cpl_imagelist *darks, float thresh_sigma_factor, float low_threshold, float high_threshold, int llx, int lly, int urx, int ury)
search bad pixels
#define KERNEL_SW(a, b)
cpl_error_code xsh_frame_image_save2ext(cpl_frame *frm, const char *name_o, const int ext_i, const int ext_o)
cpl_image * xsh_sobel_ly(cpl_image *in)
Compute Y Sobel filter transformation.
cpl_frame * xsh_frame_image_ext_qc_trace_window(cpl_frame *frm_ima, xsh_instrument *instrument, const char *suffix, const int hsize, const int method)
Trace object position in an image.
cpl_image * xsh_compute_scale_tab2(cpl_imagelist *iml_data, cpl_imagelist *iml_qual, cpl_mask *bpm, cpl_table *tab_bpm, const int mode, const int win_hsz, const int decode_bp)
#define PIX_SWAP(a, b)
cpl_error_code xsh_collapse_errs(cpl_image *errs, cpl_imagelist *list, const int mode)
static cpl_image * xsh_gen_lowpass(const int xs, const int ys, const double sigma_x, const double sigma_y)
Generate a low pass filter for FFT convolution .
cpl_image * xsh_image_smooth_median_x(cpl_image *inp, const int r)
cpl_image * xsh_combine_flats(cpl_image *ima1_in, cpl_image *ima2_in, xsh_order_list *qth_list, xsh_order_list *d2_list, const int xrad, const int yrad)
Combine flat frames line adjusting illumination level to merge them smoothly.
static Stats * xsh_image_stats_on_rectangle(cpl_image *im, float loReject, float hiReject, int llx, int lly, int urx, int ury)
cpl_image * xsh_compute_scale(cpl_imagelist *iml_data, cpl_mask *bpm, const int mode, const int win_hsz)
static cpl_error_code xsh_cube_trace_diff(const cpl_table *table, const char *col_comp, const char *col_ref, cpl_propertylist *plist)
Computes differences between cube fit trace coefficients.
cpl_error_code xsh_compute_ron(cpl_frameset *frames, int llx, int lly, int urx, int ury, int nsampl, int hsize, const int reg_id, double *ron, double *ron_err)
compute ron taking random windows of given size in a given region on 2 frames difference
double * xsh_generate_tanh_kernel(double steep)
cpl_frame * xsh_frame_image_div_by_fct(cpl_frame *frm, const int fctx, const int fcty)
cpl_image * xsh_image_compute_geom_corr(cpl_image *in)
Pixel area geometric trasformation computation.
cpl_error_code xsh_frame_image_add_double(cpl_frame *frm, const double value)
#define PIX_STACK_SIZE
static float xsh_clean_mean(float *array, int n_elements, float throwaway_low, float throwaway_high)
cpl_image * xsh_scharr_x(cpl_image *in)
Compute X Scharr filter transformation.
cpl_image * xsh_image_smooth_median_xy(cpl_image *inp, const int r)
cpl_frame * xsh_cube_qc_trace_window(cpl_frame *frm_cube, xsh_instrument *instrument, const char *suffix, const char *rec_prefix, const int win_min, const int win_max, const int hsize, const int method, const int compute_qc)
Trace object position in a cube.
#define hk_gen(x, s)
static cpl_image * xsh_image_div_by_fct(const cpl_image *ima_dat, const int fctx, const int fcty)
cpl_error_code xsh_iml_merge_wgt(cpl_imagelist **data, cpl_imagelist **errs, cpl_imagelist **qual, const cpl_image *flux_b, const cpl_image *errs_b, const cpl_image *qual_b, const int mk, const int decode_bp)
merge imagelist via average
cpl_error_code xsh_image_clean_badpixel(cpl_frame *in)
double xsh_image_get_stdev_clean(const cpl_image *image, double *dstdev)
Get clean (3*sigma clip) empirical stdev of data.
static cpl_error_code xsh_plist_mult_by_fct(cpl_propertylist **plist, const int fctx, const int fcty)
#define FLAG
static double xsh_image_fit_gaussian_max_pos_y_window(const cpl_image *ima, const int lly, const int ury, const int xpos)
#define KERNEL_SAMPLES
#define TANH_STEEPNESS
float pixelvalue
#define KERNEL_WIDTH
#define TABSPERPIX
cpl_image * xsh_image_filter_median(const cpl_image *img, const cpl_matrix *mx)
cpl_polynomial * xsh_polynomial_fit_1d_create(const cpl_vector *x_pos, const cpl_vector *values, int degree, double *mse)