00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <xsh_utils_wrappers.h>
00028 #include <xsh_utils_image.h>
00029 #include <xsh_error.h>
00030 #include <xsh_utils.h>
00031 #include <xsh_pfits_qc.h>
00032 #include <xsh_pfits.h>
00033 #include <xsh_dfs.h>
00034 #include <xsh_data_pre.h>
00035 #include <xsh_data_instrument.h>
00036 #include <math.h>
00037 #include <string.h>
00038 #include <float.h>
00039 #define FLAG -1.e+9
00040
00041
00042
00043
00044
00045
00046
00047 static Stats *
00048 xsh_image_stats_on_rectangle ( cpl_image * im,
00049 float loReject,
00050 float hiReject,
00051 int llx,
00052 int lly,
00053 int urx,
00054 int ury );
00055
00056
00057
00058
00059
00060 static cpl_image*
00061 xsh_image_crop(const cpl_image *image,
00062 int xlo, int ylo,
00063 int xhi, int yhi);
00064
00065 static float
00066 xsh_clean_mean( float * array,
00067 int n_elements,
00068 float throwaway_low,
00069 float throwaway_high ) ;
00070
00071
00072 static cpl_error_code
00073 xsh_compute_geom_corr(
00074 const double dxdu,
00075 const double dydv,
00076 const double dxdv,
00077 const double dydu,
00078 const double du,
00079 const double dv,
00080 double* dA);
00081
00082
00083 static double xsh_sinc(double x);
00084 static void reverse_tanh_kernel(double * data, int nn);
00085
00086 static cpl_image *
00087 xsh_gen_lowpass(const int xs,
00088 const int ys,
00089 const double sigma_x,
00090 const double sigma_y);
00091
00108 static cpl_error_code
00109 xsh_compute_geom_corr(
00110 const double dxdu,
00111 const double dydv,
00112 const double dxdv,
00113 const double dydu,
00114 const double du,
00115 const double dv,
00116 double* dA)
00117 {
00118
00119
00120 *dA=fabs(dxdu*dydv-dxdv*dydu)*du*dv;
00121 return cpl_error_get_code();
00122
00123 }
00124
00125
00133 cpl_image*
00134 xsh_image_compute_geom_corr(cpl_image* in)
00135 {
00136
00137 cpl_image* out=NULL;
00138
00139 int sx=0;
00140 int sy=0;
00141 register int i=0;
00142 register int j=0;
00143 double dxdu=0;
00144 double dydv=0;
00145 double dxdv=0;
00146 double dydu=0;
00147 double du=0;
00148 double dv=0;
00149 double dA=0;
00150
00151 assure (in != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
00152 check(sx=cpl_image_get_size_x(in));
00153 check(sy=cpl_image_get_size_y(in));
00154
00155
00156 for(j=0;j<sy;j++) {
00157 for(i=0;i<sx;i++) {
00158
00159
00160
00161 check(xsh_compute_geom_corr(dxdu,dydv,dxdv,dydu,du,dv,&dA));
00162 }
00163 }
00164
00165 cleanup:
00166
00167 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00168 xsh_free_image(&out);
00169 return NULL;
00170 } else {
00171 return out;
00172 }
00173 }
00174
00175
00176
00177
00178
00202
00203
00204 double *
00205 xsh_generate_interpolation_kernel(const char * kernel_type)
00206 {
00207 double * tab ;
00208 int i ;
00209 double x ;
00210 double alpha ;
00211 double inv_norm ;
00212 int samples = KERNEL_SAMPLES ;
00213
00214 if (kernel_type==NULL) {
00215 tab = xsh_generate_interpolation_kernel("tanh") ;
00216 } else if (!strcmp(kernel_type, "default")) {
00217 tab = xsh_generate_interpolation_kernel("tanh") ;
00218 } else if (!strcmp(kernel_type, "sinc")) {
00219 tab = cpl_malloc(samples * sizeof(double)) ;
00220 tab[0] = 1.0 ;
00221 tab[samples-1] = 0.0 ;
00222 for (i=1 ; i<samples ; i++) {
00223 x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
00224 tab[i] = xsh_sinc(x) ;
00225 }
00226 } else if (!strcmp(kernel_type, "sinc2")) {
00227 tab = cpl_malloc(samples * sizeof(double)) ;
00228 tab[0] = 1.0 ;
00229 tab[samples-1] = 0.0 ;
00230 for (i=1 ; i<samples ; i++) {
00231 x = 2.0 * (double)i/(double)(samples-1) ;
00232 tab[i] = xsh_sinc(x) ;
00233 tab[i] *= tab[i] ;
00234 }
00235 } else if (!strcmp(kernel_type, "lanczos")) {
00236 tab = cpl_malloc(samples * sizeof(double)) ;
00237 for (i=0 ; i<samples ; i++) {
00238 x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
00239 if (fabs(x)<2) {
00240 tab[i] = xsh_sinc(x) * xsh_sinc(x/2) ;
00241 } else {
00242 tab[i] = 0.00 ;
00243 }
00244 }
00245 } else if (!strcmp(kernel_type, "hamming")) {
00246 tab = cpl_malloc(samples * sizeof(double)) ;
00247 alpha = 0.54 ;
00248 inv_norm = 1.00 / (double)(samples - 1) ;
00249 for (i=0 ; i<samples ; i++) {
00250 x = (double)i ;
00251 if (i<(samples-1)/2) {
00252 tab[i] = alpha + (1-alpha) * cos(2.0*M_PI*x*inv_norm) ;
00253 } else {
00254 tab[i] = 0.0 ;
00255 }
00256 }
00257 } else if (!strcmp(kernel_type, "hann")) {
00258 tab = cpl_malloc(samples * sizeof(double)) ;
00259 alpha = 0.50 ;
00260 inv_norm = 1.00 / (double)(samples - 1) ;
00261 for (i=0 ; i<samples ; i++) {
00262 x = (double)i ;
00263 if (i<(samples-1)/2) {
00264 tab[i] = alpha + (1-alpha) * cos(2.0*M_PI*x*inv_norm) ;
00265 } else {
00266 tab[i] = 0.0 ;
00267 }
00268 }
00269 } else if (!strcmp(kernel_type, "tanh")) {
00270 tab = xsh_generate_tanh_kernel(TANH_STEEPNESS) ;
00271 } else {
00272 xsh_msg_error("unrecognized kernel type [%s]: aborting generation",
00273 kernel_type) ;
00274 return NULL ;
00275 }
00276
00277 return tab ;
00278 }
00279
00280
00281
00292
00293
00294 static double
00295 xsh_sinc(double x)
00296 {
00297 if (fabs(x)<1e-4)
00298 return (double)1.00 ;
00299 else
00300 return ((sin(x * (double)M_PI)) / (x * (double)M_PI)) ;
00301 }
00302
00303
00304
00305
00341
00342
00343 cpl_image *
00344 xsh_warp_image_generic(
00345 cpl_image * image_in,
00346 char * kernel_type,
00347 cpl_polynomial * poly_u,
00348 cpl_polynomial * poly_v
00349 )
00350 {
00351 cpl_image * image_out ;
00352 int i, j, k ;
00353 int lx_out, ly_out ;
00354 double cur ;
00355 double neighbors[16] ;
00356 double rsc[8],
00357 sumrs ;
00358 double x, y ;
00359 int px, py ;
00360 int pos ;
00361 int tabx, taby ;
00362 double * kernel ;
00363 int leaps[16] ;
00364 int ilx=0;
00365 int ily=0;
00366 float* pidata=NULL;
00367 float* podata=NULL;
00368 cpl_vector* vx=NULL;
00369 if (image_in == NULL) return NULL ;
00370
00371
00372
00373 kernel = xsh_generate_interpolation_kernel(kernel_type) ;
00374 if (kernel == NULL) {
00375 xsh_msg_error("cannot generate kernel: aborting resampling") ;
00376 return NULL ;
00377 }
00378 ilx=cpl_image_get_size_x(image_in);
00379 ily=cpl_image_get_size_y(image_in);
00380 pidata=cpl_image_get_data_float(image_in);
00381
00382
00383 lx_out = (int)ilx ;
00384 ly_out = (int)ily ;
00385
00386 image_out = cpl_image_new(lx_out, ly_out,CPL_TYPE_FLOAT) ;
00387 podata=cpl_image_get_data_float(image_out);
00388
00389
00390
00391 leaps[0] = -1 - ilx ;
00392 leaps[1] = - ilx ;
00393 leaps[2] = 1 - ilx ;
00394 leaps[3] = 2 - ilx ;
00395
00396 leaps[4] = -1 ;
00397 leaps[5] = 0 ;
00398 leaps[6] = 1 ;
00399 leaps[7] = 2 ;
00400
00401 leaps[8] = -1 + ilx ;
00402 leaps[9] = ilx ;
00403 leaps[10]= 1 + ilx ;
00404 leaps[11]= 2 + ilx ;
00405
00406 leaps[12]= -1 + 2*ilx ;
00407 leaps[13]= 2*ilx ;
00408 leaps[14]= 1 + 2*ilx ;
00409 leaps[15]= 2 + 2*ilx ;
00410
00411 vx=cpl_vector_new(2);
00412
00413 for (j=0 ; j < ly_out ; j++) {
00414 for (i=0 ; i< lx_out ; i++) {
00415
00416 cpl_vector_set(vx,0,(double)i);
00417 cpl_vector_set(vx,1,(double)j);
00418 x = cpl_polynomial_eval(poly_u, vx);
00419 y = cpl_polynomial_eval(poly_v, vx);
00420
00421
00422 px = (int)x ;
00423 py = (int)y ;
00424
00425 if ((px < 1) ||
00426 (px > (ilx-3)) ||
00427 (py < 1) ||
00428 (py > (ily-3)))
00429 podata[i+j*lx_out] = (pixelvalue)0.0/0.0 ;
00430 else {
00431
00432 pos = px + py * ilx ;
00433 for (k=0 ; k<16 ; k++)
00434 neighbors[k] = (double)(pidata[(int)(pos+leaps[k])]) ;
00435
00436
00437 tabx = (x - (double)px) * (double)(TABSPERPIX) ;
00438 taby = (y - (double)py) * (double)(TABSPERPIX) ;
00439
00440
00441
00442
00443 rsc[0] = kernel[TABSPERPIX + tabx] ;
00444 rsc[1] = kernel[tabx] ;
00445 rsc[2] = kernel[TABSPERPIX - tabx] ;
00446 rsc[3] = kernel[2 * TABSPERPIX - tabx] ;
00447 rsc[4] = kernel[TABSPERPIX + taby] ;
00448 rsc[5] = kernel[taby] ;
00449 rsc[6] = kernel[TABSPERPIX - taby] ;
00450 rsc[7] = kernel[2 * TABSPERPIX - taby] ;
00451
00452 sumrs = (rsc[0]+rsc[1]+rsc[2]+rsc[3]) *
00453 (rsc[4]+rsc[5]+rsc[6]+rsc[7]) ;
00454
00455
00456 cur = rsc[4] * ( rsc[0]*neighbors[0] +
00457 rsc[1]*neighbors[1] +
00458 rsc[2]*neighbors[2] +
00459 rsc[3]*neighbors[3] ) +
00460 rsc[5] * ( rsc[0]*neighbors[4] +
00461 rsc[1]*neighbors[5] +
00462 rsc[2]*neighbors[6] +
00463 rsc[3]*neighbors[7] ) +
00464 rsc[6] * ( rsc[0]*neighbors[8] +
00465 rsc[1]*neighbors[9] +
00466 rsc[2]*neighbors[10] +
00467 rsc[3]*neighbors[11] ) +
00468 rsc[7] * ( rsc[0]*neighbors[12] +
00469 rsc[1]*neighbors[13] +
00470 rsc[2]*neighbors[14] +
00471 rsc[3]*neighbors[15] ) ;
00472
00473
00474 podata[i+j*lx_out] = (pixelvalue)(cur/sumrs) ;
00475
00476 }
00477 }
00478 }
00479 cpl_vector_delete(vx);
00480 cpl_free(kernel) ;
00481 return image_out ;
00482 }
00483
00484
00485 #define hk_gen(x,s) (((tanh(s*(x+0.5))+1)/2)*((tanh(s*(-x+0.5))+1)/2))
00486
00487
00508
00509
00510 double * xsh_generate_tanh_kernel(double steep)
00511 {
00512 double * kernel ;
00513 double * x ;
00514 double width ;
00515 double inv_np ;
00516 double ind ;
00517 int i ;
00518 int np ;
00519 int samples ;
00520
00521 width = (double)TABSPERPIX / 2.0 ;
00522 samples = KERNEL_SAMPLES ;
00523 np = 32768 ;
00524 inv_np = 1.00 / (double)np ;
00525
00526
00527
00528
00529
00530 x = cpl_malloc((2*np+1)*sizeof(double)) ;
00531 for (i=0 ; i<np/2 ; i++) {
00532 ind = (double)i * 2.0 * width * inv_np ;
00533 x[2*i] = hk_gen(ind, steep) ;
00534 x[2*i+1] = 0.00 ;
00535 }
00536 for (i=np/2 ; i<np ; i++) {
00537 ind = (double)(i-np) * 2.0 * width * inv_np ;
00538 x[2*i] = hk_gen(ind, steep) ;
00539 x[2*i+1] = 0.00 ;
00540 }
00541
00542
00543
00544
00545 reverse_tanh_kernel(x, np) ;
00546
00547
00548
00549
00550 kernel = cpl_malloc(samples * sizeof(double)) ;
00551 for (i=0 ; i<samples ; i++) {
00552 kernel[i] = 2.0 * width * x[2*i] * inv_np ;
00553 }
00554 cpl_free(x) ;
00555 return kernel ;
00556 }
00557
00558
00559 #define KERNEL_SW(a,b) tempr=(a);(a)=(b);(b)=tempr
00560
00572
00573
00574 static void
00575 reverse_tanh_kernel(double * data, int nn)
00576 {
00577 unsigned long n,
00578 mmax,
00579 m,
00580 i, j,
00581 istep ;
00582 double wtemp,
00583 wr,
00584 wpr,
00585 wpi,
00586 wi,
00587 theta;
00588 double tempr,
00589 tempi;
00590
00591 n = (unsigned long)nn << 1;
00592 j = 1;
00593 for (i=1 ; i<n ; i+=2) {
00594 if (j > i) {
00595 KERNEL_SW(data[j-1],data[i-1]);
00596 KERNEL_SW(data[j],data[i]);
00597 }
00598 m = n >> 1;
00599 while (m>=2 && j>m) {
00600 j -= m;
00601 m >>= 1;
00602 }
00603 j += m;
00604 }
00605 mmax = 2;
00606 while (n > mmax) {
00607 istep = mmax << 1;
00608 theta = 2 * M_PI / mmax;
00609 wtemp = sin(0.5 * theta);
00610 wpr = -2.0 * wtemp * wtemp;
00611 wpi = sin(theta);
00612 wr = 1.0;
00613 wi = 0.0;
00614 for (m=1 ; m<mmax ; m+=2) {
00615 for (i=m ; i<=n ; i+=istep) {
00616 j = i + mmax;
00617 tempr = wr * data[j-1] - wi * data[j];
00618 tempi = wr * data[j] + wi * data[j-1];
00619 data[j-1] = data[i-1] - tempr;
00620 data[j] = data[i] - tempi;
00621 data[i-1] += tempr;
00622 data[i] += tempi;
00623 }
00624 wr = (wtemp = wr) * wpr - wi * wpi + wr;
00625 wi = wi * wpr + wtemp * wpi + wi;
00626 }
00627 mmax = istep;
00628 }
00629 }
00630 #undef KERNEL_SW
00631
00632
00633
00634
00647
00648
00649 void xsh_show_interpolation_kernel(char * kernel_name)
00650 {
00651 double * ker ;
00652 int i ;
00653 double x ;
00654
00655
00656 ker = xsh_generate_interpolation_kernel(kernel_name) ;
00657 if (ker == NULL)
00658 return ;
00659
00660 (void)fprintf(stdout, "# Kernel is %s\n", kernel_name) ;
00661 x = 0.00 ;
00662 for (i=0 ; i<KERNEL_SAMPLES ; i++) {
00663 (void)fprintf(stdout, "%g %g\n", x, ker[i]) ;
00664 x += 1.00 / (double)TABSPERPIX ;
00665 }
00666 cpl_free(ker) ;
00667 return ;
00668 }
00669
00677 double
00678 xsh_image_get_stdev_robust(const cpl_image *image,
00679 double cut,
00680 double *dstdev)
00681 {
00682 cpl_mask *rejected = NULL;
00683 cpl_image *im = NULL;
00684 double median = 0;
00685 double robust_stdev = 0;
00686
00687 assure (image != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
00688 assure( cut > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal cut: %f", cut );
00689 assure( dstdev == NULL, CPL_ERROR_ILLEGAL_INPUT, "Unsupported");
00690
00691 median = cpl_image_get_median(image);
00692
00693 im = cpl_image_duplicate(image);
00694 cpl_image_subtract_scalar(im, median);
00695 cpl_image_power(im, 2);
00696
00697
00698 rejected = cpl_mask_threshold_image_create(image,median - cut,
00699 median + cut);
00700 cpl_mask_not(rejected);
00701 cpl_image_reject_from_mask(im, rejected);
00702
00703 robust_stdev = sqrt(cpl_image_get_mean(im));
00704
00705 cleanup:
00706 xsh_free_image(&im);
00707 xsh_free_mask(&rejected);
00708
00709 return robust_stdev;
00710 }
00711
00718 double xsh_image_get_stdev_clean(const cpl_image *image,
00719 double *dstdev)
00720 {
00721 cpl_mask *rejected = NULL;
00722 cpl_image *im = NULL;
00723 double median = 0;
00724 double stdev = 0;
00725 double robust_stdev = 0;
00726 double kappa=3.0;
00727 double cut=0;
00728
00729 assure (image != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
00730 assure( dstdev == NULL, CPL_ERROR_ILLEGAL_INPUT, "Unsupported");
00731
00732 median = cpl_image_get_median(image);
00733 stdev=cpl_image_get_stdev(image);
00734 cut=kappa*stdev;
00735
00736 im = cpl_image_duplicate(image);
00737 cpl_image_subtract_scalar(im, median);
00738 cpl_image_power(im, 2);
00739
00740
00741 rejected = cpl_mask_threshold_image_create(image,median - cut,
00742 median + cut);
00743 cpl_mask_not(rejected);
00744 cpl_image_reject_from_mask(im, rejected);
00745
00746 robust_stdev = sqrt(cpl_image_get_mean(im));
00747
00748 cleanup:
00749 xsh_free_image(&im);
00750 xsh_free_mask(&rejected);
00751
00752 return robust_stdev;
00753 }
00754
00755
00756
00764 double
00765 xsh_fixed_pattern_noise(const cpl_image *master,
00766 double convert_ADU,
00767 double master_noise)
00768 {
00769 double master_fixed_pattern_noise=0;
00770 cpl_image *image1 = NULL;
00771 cpl_image *image2 = NULL;
00772
00773 assure (master != NULL, CPL_ERROR_NULL_INPUT,"NULL input frame");
00774
00775
00776
00777
00778 if (cpl_image_get_size_x(master) >= 121 &&
00779 cpl_image_get_size_y(master) >= 121) {
00780
00781 int mid_x = (cpl_image_get_size_x(master) + 1) / 2;
00782 int mid_y = (cpl_image_get_size_y(master) + 1) / 2;
00783
00784
00785 image1=xsh_image_crop(master,
00786 mid_x - 50, mid_y - 50,
00787 mid_x + 50, mid_y + 50);
00788
00789
00790 image2=xsh_image_crop(master,
00791 mid_x + 10 - 50, mid_y + 10 - 50,
00792 mid_x + 10 + 50, mid_y + 10 + 50);
00793
00794 cpl_image_subtract(image1, image2);
00795
00796 master_fixed_pattern_noise = cpl_image_get_stdev(image1) / sqrt(2);
00797
00798
00799 master_fixed_pattern_noise *= convert_ADU;
00800
00801
00802 if (master_fixed_pattern_noise >= master_noise) {
00803
00804 master_fixed_pattern_noise = sqrt(master_fixed_pattern_noise*
00805 master_fixed_pattern_noise
00806 -
00807 master_noise*
00808 master_noise);
00809 }
00810 else {
00811 cpl_msg_warning(cpl_func,
00812 "Zero-shift noise (%f ADU) is greater than "
00813 "accumulated zero-shift and fixed pattern noise (%f ADU), "
00814 "setting fixed pattern noise to zero",
00815 master_noise,
00816 master_fixed_pattern_noise);
00817 master_fixed_pattern_noise = 0;
00818 }
00819 }
00820 else {
00821 cpl_msg_warning(cpl_func,
00822 "Master flat too small (%" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT "), "
00823 "need size 121x121 to compute master flat "
00824 "fixed pattern noise",
00825 cpl_image_get_size_x(master),
00826 cpl_image_get_size_y(master));
00827 master_fixed_pattern_noise = -1;
00828 }
00829
00830 cleanup:
00831 xsh_free_image(&image1);
00832 xsh_free_image(&image2);
00833
00834 return master_fixed_pattern_noise;
00835 }
00836
00844 double
00845 xsh_fixed_pattern_noise_bias(const cpl_image *first_raw,
00846 const cpl_image *second_raw,
00847 double ron)
00848 {
00849 double bias_fixed_pattern_noise=0;
00850 cpl_image *image1 = NULL;
00851 cpl_image *image2 = NULL;
00852 int nx, ny;
00853
00854 assure (first_raw != NULL, CPL_ERROR_NULL_INPUT,"NULL input image");
00855 assure (second_raw != NULL, CPL_ERROR_NULL_INPUT,"NULL input image");
00856
00857
00858
00859
00860
00861 nx = cpl_image_get_size_x(first_raw);
00862 ny = cpl_image_get_size_y(first_raw);
00863
00864
00865 image1=xsh_image_crop(first_raw, 1, 1,nx - 10, ny - 10);
00866
00867
00868 image2=xsh_image_crop(second_raw, 11, 11,nx, ny);
00869
00870 cpl_image_subtract(image1, image2);
00871
00872 bias_fixed_pattern_noise = xsh_image_get_stdev_robust(image1, 50, NULL)
00873 / sqrt(2);
00874
00875
00876
00877
00878
00879 if (bias_fixed_pattern_noise > ron) {
00880
00881 bias_fixed_pattern_noise = sqrt(bias_fixed_pattern_noise *
00882 bias_fixed_pattern_noise
00883 -
00884 ron * ron);
00885 }
00886 else {
00887 cpl_msg_warning(cpl_func,
00888 "Zero-shift noise (%f ADU) is greater than "
00889 "accumulated zero-shift and fixed pattern "
00890 "noise (%f ADU), "
00891 "setting fixed pattern noise to zero",
00892 ron,
00893 bias_fixed_pattern_noise);
00894 bias_fixed_pattern_noise = 0;
00895 }
00896
00897 cleanup:
00898 xsh_free_image(&image1);
00899 xsh_free_image(&image2);
00900
00901 return bias_fixed_pattern_noise;
00902 }
00903
00904
00919 static cpl_image*
00920 xsh_image_crop(const cpl_image *image,
00921 int xlo, int ylo,
00922 int xhi, int yhi)
00923 {
00924
00925
00926 cpl_image *image_crop = NULL;
00927 assure( image != NULL, CPL_ERROR_ILLEGAL_INPUT, "Null input image" );
00928 assure( 1 <= xlo && xlo <= xhi && xhi <= cpl_image_get_size_x(image) &&
00929 1 <= ylo && ylo <= yhi && yhi <= cpl_image_get_size_y(image),
00930 CPL_ERROR_ILLEGAL_INPUT,
00931 "Cannot extraction region (%d, %d) - (%d, %d) of %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " image",
00932 xlo, ylo, xhi, yhi,
00933 cpl_image_get_size_x(image),
00934 cpl_image_get_size_y(image));
00935
00936
00937
00938 check(image_crop = cpl_image_extract(image,xlo, ylo,xhi, yhi));
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 cleanup:
00953 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00954 return NULL;
00955 } else {
00956 return image_crop;
00957 }
00958 }
00959
00960
00961
01012 cpl_error_code xsh_image_warp_polynomial_scale(cpl_image *out,
01013 const cpl_polynomial *poly_x,
01014 const cpl_polynomial *poly_y)
01015 {
01016 cpl_polynomial *dxdu=NULL;
01017 cpl_polynomial *dxdv=NULL;
01018 cpl_polynomial *dydu=NULL;
01019 cpl_polynomial *dydv=NULL;
01020
01021 cpl_vector *val=NULL;
01022 double *pval=NULL;
01023
01024 double *ddata=NULL;
01025 float *fdata=NULL;
01026
01027 int nx, ny;
01028 int i, j;
01029
01030
01031 if (out == NULL || poly_x == NULL || poly_y == NULL)
01032 return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01033
01034 if (cpl_polynomial_get_dimension(poly_x) != 2 ||
01035 cpl_polynomial_get_dimension(poly_y) != 2)
01036 return cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
01037
01038 if (cpl_image_get_type(out) != CPL_TYPE_FLOAT &&
01039 cpl_image_get_type(out) != CPL_TYPE_DOUBLE)
01040 return cpl_error_set(cpl_func, CPL_ERROR_INVALID_TYPE);
01041
01042
01043
01044
01045
01046
01047 dxdu = cpl_polynomial_duplicate(poly_x);
01048 dxdv = cpl_polynomial_duplicate(poly_x);
01049 dydu = cpl_polynomial_duplicate(poly_y);
01050 dydv = cpl_polynomial_duplicate(poly_y);
01051
01052 cpl_polynomial_derivative(dxdu, 0);
01053 cpl_polynomial_derivative(dxdv, 1);
01054 cpl_polynomial_derivative(dydu, 0);
01055 cpl_polynomial_derivative(dydv, 1);
01056
01057
01058
01059
01060
01061
01062
01063 nx = cpl_image_get_size_x(out);
01064 ny = cpl_image_get_size_y(out);
01065
01066 val = cpl_vector_new(2);
01067 pval = cpl_vector_get_data(val);
01068
01069 switch (cpl_image_get_type(out)) {
01070 case CPL_TYPE_FLOAT:
01071 fdata = cpl_image_get_data_float(out);
01072 for (j=0; j < ny; j++) {
01073 pval[1] = j + 1;
01074 for (i=0; i < nx; i++) {
01075 pval[0] = i + 1;
01076 *fdata++ = cpl_polynomial_eval(dxdu, val)
01077 * cpl_polynomial_eval(dydv, val)
01078 - cpl_polynomial_eval(dxdv, val)
01079 * cpl_polynomial_eval(dydu, val);
01080 }
01081 }
01082 break;
01083 case CPL_TYPE_DOUBLE:
01084 ddata = cpl_image_get_data_double(out);
01085 for (j=0; j < ny; j++) {
01086 pval[1] = j + 1;
01087 for (i=0; i < nx; i++) {
01088 pval[0] = i + 1;
01089 *ddata++ = cpl_polynomial_eval(dxdu, val)
01090 * cpl_polynomial_eval(dydv, val)
01091 - cpl_polynomial_eval(dxdv, val)
01092 * cpl_polynomial_eval(dydu, val);
01093 }
01094 }
01095 break;
01096 default:
01097
01098
01099
01100
01101
01102
01103 break;
01104 }
01105
01106 cpl_vector_delete(val);
01107 cpl_polynomial_delete(dxdu);
01108 cpl_polynomial_delete(dxdv);
01109 cpl_polynomial_delete(dydu);
01110 cpl_polynomial_delete(dydv);
01111
01112
01113
01114
01115
01116
01117 cpl_image_abs(out);
01118
01119 return CPL_ERROR_NONE;
01120
01121 }
01122
01123
01130 cpl_image*
01131 xsh_scharr_x(cpl_image* in) {
01132
01133 cpl_image* scharr_x=NULL;
01134 float* pscharr_x=NULL;
01135 float* pin=NULL;
01136 int sx=0;
01137 int sy=0;
01138 int i=0;
01139 int j=0;
01140
01141
01142 check(scharr_x=cpl_image_duplicate(in));
01143 check(pscharr_x=cpl_image_get_data_float(scharr_x));
01144 check(pin=cpl_image_get_data_float(in));
01145 check(sx=cpl_image_get_size_x(in));
01146 check(sy=cpl_image_get_size_y(in));
01147
01148 for(i=1;i<sx-1;i++) {
01149 for(j=1;j<sy-1;j++) {
01150 pscharr_x[i+j*sx]=3*pin[i-1+(j+1)*sx]-3*pin[i+1+(j+1)*sx]+
01151 10*pin[i-1+j*sx]-10*pin[i+1+j*sx]+
01152 3*pin[i-1+(j-1)*sx]-3*pin[i+1+(j-1)*sx];
01153 }
01154 }
01155
01156 cleanup:
01157 return scharr_x;
01158
01159 }
01160
01161
01162
01169 cpl_image*
01170 xsh_scharr_y(cpl_image* in) {
01171
01172 cpl_image* scharr_y=NULL;
01173 float* pscharr_y=NULL;
01174 float* pin=NULL;
01175 int sx=0;
01176 int sy=0;
01177 int i=0;
01178 int j=0;
01179
01180
01181 check(scharr_y=cpl_image_duplicate(in));
01182 check(pscharr_y=cpl_image_get_data_float(scharr_y));
01183 check(pin=cpl_image_get_data_float(in));
01184 check(sx=cpl_image_get_size_x(in));
01185 check(sy=cpl_image_get_size_y(in));
01186
01187 for(i=1;i<sx-1;i++) {
01188 for(j=1;j<sy-1;j++) {
01189 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]+
01190 -3*pin[i-1+(j-1)*sx]-10*pin[i+(j-1)*sx]-3*pin[i+1+(j-1)*sx];
01191 }
01192 }
01193
01194 cleanup:
01195 return scharr_y;
01196
01197 }
01198
01199
01207 cpl_image*
01208 xsh_sobel_lx(cpl_image* in) {
01209
01210 cpl_image* lx=NULL;
01211 float* plx=NULL;
01212 float* pin=NULL;
01213 int sx=0;
01214 int sy=0;
01215 int i=0;
01216 int j=0;
01217
01218
01219 check(lx=cpl_image_duplicate(in));
01220 check(plx=cpl_image_get_data_float(lx));
01221 check(pin=cpl_image_get_data_float(in));
01222 check(sx=cpl_image_get_size_x(in));
01223 check(sy=cpl_image_get_size_y(in));
01224
01225 for(i=1;i<sx-1;i++) {
01226 for(j=1;j<sy-1;j++) {
01227 plx[i+j*sx]=pin[i-1+(j+1)*sx]-pin[i+1+(j+1)*sx]+
01228 2*pin[i-1+j*sx]-2*pin[i+1+j*sx]+
01229 pin[i-1+(j-1)*sx]-pin[i+1+(j-1)*sx];
01230 }
01231 }
01232
01233 cleanup:
01234 return lx;
01235
01236 }
01237
01238
01239
01247 cpl_image*
01248 xsh_sobel_ly(cpl_image* in) {
01249
01250
01251
01252 cpl_image* ly=NULL;
01253 float* ply=NULL;
01254 float* pin=NULL;
01255 int sx=0;
01256 int sy=0;
01257 int i=0;
01258 int j=0;
01259
01260
01261 check(ly=cpl_image_duplicate(in));
01262 check(ply=cpl_image_get_data_float(ly));
01263 check(pin=cpl_image_get_data_float(in));
01264 check(sx=cpl_image_get_size_x(in));
01265 check(sy=cpl_image_get_size_y(in));
01266
01267 for(i=1;i<sx-1;i++) {
01268 for(j=1;j<sy-1;j++) {
01269 ply[i+j*sx]=pin[i-1+(j+1)*sx]+2*pin[i+(j+1)*sx]+pin[i+1+(j+1)*sx]+
01270 -pin[i-1+(j-1)*sx]-2*pin[i+(j-1)*sx]-pin[i+1+(j-1)*sx];
01271 }
01272 }
01273 cleanup:
01274 return ly;
01275
01276 }
01277
01293 cpl_error_code
01294 xsh_compute_ron(cpl_frameset* frames,
01295 int llx,
01296 int lly,
01297 int urx,
01298 int ury,
01299 int nsampl,
01300 int hsize,
01301 const int reg_id,
01302 double* ron,
01303 double* ron_err)
01304 {
01305
01306 cpl_frame* bias1=NULL;
01307 cpl_frame* bias2=NULL;
01308
01309 cpl_image* ima1=NULL;
01310 cpl_image* ima2=NULL;
01311 cpl_image* imad=NULL;
01312
01313 const char* name1=NULL;
01314 const char* name2=NULL;
01315 int nx1=0;
01316 int ny1=0;
01317 int nx2=0;
01318 int ny2=0;
01319 cpl_size zone[4];
01320 int nfrm=0;
01321 cpl_propertylist* plist=NULL;
01322
01323
01324
01325 check(nfrm=cpl_frameset_get_size(frames));
01326
01327 if ( nfrm < 2 ) goto cleanup;
01328
01329 check(bias1=cpl_frameset_get_first(frames));
01330 check(bias2=cpl_frameset_get_next(frames));
01331 check(name1=cpl_frame_get_filename(bias1));
01332 check(name2=cpl_frame_get_filename(bias2));
01333 check(ima1=cpl_image_load(name1,CPL_TYPE_FLOAT,0,0));
01334 check(ima2=cpl_image_load(name2,CPL_TYPE_FLOAT,0,0));
01335
01336 check(nx1=cpl_image_get_size_x(ima1));
01337 check(nx2=cpl_image_get_size_x(ima2));
01338
01339 check(ny1=cpl_image_get_size_y(ima1));
01340 check(ny2=cpl_image_get_size_y(ima2));
01341
01342 if((nx1 != nx2) || (ny1 != ny2)) {
01343 xsh_error_msg("image1's size: [%d,%d] != from image2's size [%d,%d]",
01344 nx1,ny1,nx2,ny2);
01345 goto cleanup;
01346 }
01347
01348 check(plist=cpl_propertylist_load(name1,0));
01349
01350 if(llx == -1) llx=1;
01351 if(lly == -1) lly=1;
01352
01353 if(urx == -1) urx=nx1;
01354 if(ury == -1) ury=ny1;
01355
01356 zone[0]=llx;
01357 zone[1]=urx;
01358 zone[2]=lly;
01359 zone[3]=ury;
01360
01361 check(imad=cpl_image_duplicate(ima1));
01362 check(cpl_image_subtract(imad,ima2));
01363
01364 check(cpl_flux_get_noise_window(imad, zone,hsize,nsampl,ron,ron_err));
01365
01366
01367 *ron/=sqrt(2);
01368 *ron_err/=sqrt(2);
01369
01370
01371
01372 if(reg_id==1) {
01373 xsh_pfits_set_qc_ron1(plist,*ron);
01374 xsh_pfits_set_qc_ron1_err(plist,*ron_err);
01375 } else{
01376 xsh_pfits_set_qc_ron2(plist,*ron);
01377 xsh_pfits_set_qc_ron2_err(plist,*ron_err);
01378 }
01379 check(cpl_propertylist_append_string(plist,XSH_PCATG,"BIAS_PAIR_DIFF"));
01380
01381
01382 cleanup:
01383 xsh_free_image(&ima1);
01384 xsh_free_image(&ima2);
01385 xsh_free_image(&imad);
01386 xsh_free_propertylist(&plist);
01387
01388
01389
01390 if (cpl_error_get_code()) {
01391 return -1 ;
01392 } else {
01393 return 0 ;
01394 }
01395
01396
01397 }
01398
01428 cpl_image *
01429 xsh_image_search_bad_pixels_via_noise(cpl_imagelist * darks,
01430 float thresh_sigma_factor,
01431 float low_threshold,
01432 float high_threshold,
01433 int llx,
01434 int lly,
01435 int urx,
01436 int ury)
01437 {
01438 cpl_image * bp_map =NULL;
01439 int z, n, i ;
01440 int lx, ly ;
01441 int row, col ;
01442 int low_n, high_n ;
01443 float * spectrum =NULL;
01444 double pix_sum ;
01445 double sqr_sum ;
01446 Stats * stats =NULL;
01447 cpl_image* img_src=NULL;
01448
01449 float* psrcdata=NULL;
01450 float* pbpdata=NULL;
01451
01452 int lz=0;
01453
01454 if ( NULL == darks )
01455 {
01456 xsh_msg_error("no input cube given!\n") ;
01457 return NULL ;
01458 }
01459
01460 if ( thresh_sigma_factor <= 0. )
01461 {
01462 xsh_msg_error("factor is smaller or equal zero!\n") ;
01463 return NULL ;
01464 }
01465 if ( low_threshold < 0. || high_threshold < 0. || (low_threshold + high_threshold) >= 100. )
01466 {
01467 xsh_msg_error("wrong reject percentage values!\n") ;
01468 return NULL ;
01469 }
01470
01471 lz=cpl_imagelist_get_size(darks);
01472 if ( lz < 1 )
01473 {
01474 xsh_msg_error("not enough dark frames given for good statistics!") ;
01475 return NULL ;
01476 }
01477 img_src=cpl_imagelist_get(darks,0);
01478
01479 lx = cpl_image_get_size_x(img_src) ;
01480 ly = cpl_image_get_size_y(img_src) ;
01481
01482 if (llx == -1) llx=1;
01483 if (lly == -1) lly=1;
01484
01485 if (urx == -1) urx=lx;
01486 if (ury == -1) ury=ly;
01487
01488 llx = (llx<1) ? 1 : llx;
01489 lly = (lly<1) ? 1 : lly;
01490
01491 urx = (urx>lx) ? lx : urx;
01492 ury = (ury>ly) ? lx : ury;
01493
01494
01495
01496 low_n = (int)(low_threshold/100. *(float)lz) ;
01497 high_n = (int)(high_threshold/100. *(float)lz) ;
01498
01499 if (NULL == (bp_map = cpl_image_new (lx, ly,CPL_TYPE_FLOAT) ) )
01500 {
01501 xsh_msg_error("could not allocate new memory!\n") ;
01502 return NULL ;
01503 }
01504 pbpdata=cpl_image_get_data(bp_map);
01505 if (NULL == (spectrum = (float*) cpl_calloc(lz, sizeof(float)) ) )
01506 {
01507 xsh_msg_error("could not allocate new memory!\n") ;
01508 return NULL ;
01509 }
01510
01511
01512 for ( row = 0 ; row < ly ; row++ ) {
01513
01514 for ( col = 0 ; col < lx ; col++ ) {
01515
01516 for ( z = 0 ; z < lz ; z++ ) {
01517 img_src=cpl_imagelist_get(darks,z);
01518 psrcdata=cpl_image_get_data(img_src);
01519 spectrum[z] = psrcdata[col+lx*row] ;
01520 }
01521 xsh_pixel_qsort(spectrum, lz) ;
01522 n = 0 ;
01523 pix_sum = 0.;
01524 sqr_sum = 0.;
01525 for ( i = low_n ; i < lz - high_n ; i++ ) {
01526 pix_sum += (double)spectrum[i] ;
01527 sqr_sum += ((double)spectrum[i]*(double)spectrum[i]) ;
01528 n++ ;
01529 }
01530
01531 pix_sum /= (double)n ;
01532 sqr_sum /= (double)n ;
01533
01534 pbpdata[col+lx*row] = (float)sqrt(sqr_sum - pix_sum*pix_sum) ;
01535 }
01536 }
01537
01538 cpl_free(spectrum) ;
01539 if ( NULL == (stats = xsh_image_stats_on_rectangle(bp_map,
01540 low_threshold,
01541 high_threshold,
01542 llx, lly,urx,ury)))
01543 {
01544 xsh_msg_error("could not get image statistics!\n") ;
01545 cpl_image_delete (bp_map) ;
01546 return NULL ;
01547 }
01548
01549
01550
01551 for ( row = 0 ; row < ly ; row++ ) {
01552 for ( col = 0 ; col < lx ; col++ ) {
01553 if (pbpdata[col+lx*row] >
01554 stats->cleanmean+thresh_sigma_factor*stats->cleanstdev ||
01555 pbpdata[col+lx*row] <
01556 stats->cleanmean-thresh_sigma_factor*stats->cleanstdev)
01557 {
01558 pbpdata[col+lx*row] = 0. ;
01559 }
01560 else
01561 {
01562 pbpdata[col+lx*row] = QFLAG_HOT_PIXEL ;
01563 }
01564 }
01565 }
01566
01567 cpl_free (stats) ;
01568 return bp_map ;
01569 }
01570
01571
01588 Stats * xsh_image_stats_on_rectangle ( cpl_image * im,
01589 float loReject,
01590 float hiReject,
01591 int llx,
01592 int lly,
01593 int urx,
01594 int ury )
01595 {
01596 Stats * retstats=NULL;
01597 int i=0 ;
01598 int row=0;
01599 int col=0;
01600 int n=0;
01601 int npix=0;
01602 int lo_n=0;
01603 int hi_n=0;
01604 double pix_sum=0;
01605 double sqr_sum=0;
01606 float * pix_array=NULL;
01607 int im_lx=0;
01608 int im_ly=0;
01609 float* pim=NULL;
01610
01611 if ( NULL == im )
01612 {
01613 xsh_msg_error("sorry, no input image given!") ;
01614 return NULL ;
01615 }
01616 if ( loReject+hiReject >= 100. )
01617 {
01618 xsh_msg_error("sorry, too much pixels rejected!") ;
01619 return NULL ;
01620 }
01621 if ( loReject < 0. || loReject >= 100. ||
01622 hiReject < 0. || hiReject >= 100. )
01623 {
01624 xsh_msg_error("sorry, negative reject values!") ;
01625 return NULL ;
01626 }
01627
01628 im_lx=cpl_image_get_size_x(im);
01629 im_ly=cpl_image_get_size_y(im);
01630 if ( llx < 0 || lly < 0 ||
01631 urx < 0 || ury < 0 ||
01632 llx > im_lx || lly > im_ly ||
01633 urx > im_lx || ury > im_ly ||
01634 ury <= lly || urx <= llx )
01635 {
01636 xsh_msg_error("sorry, wrong pixel coordinates of rectangle!") ;
01637 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");
01638 xsh_msg_error("llx=%d lly=%d urx=%d ury=%d im_lx=%d im_ly=%d",
01639 llx,lly,urx,ury,im_lx,im_ly);
01640 return NULL ;
01641 }
01642
01643
01644 retstats = (Stats*) cpl_calloc(1, sizeof(Stats)) ;
01645 npix = (urx - llx + 1) * (ury - lly + 1) ;
01646 pix_array = (float*) cpl_calloc ( npix, sizeof(float) ) ;
01647
01648
01649
01650
01651 n = 0 ;
01652 pim = cpl_image_get_data_float(im);
01653 int row_min=0;
01654 int row_max=0;
01655 int col_min=0;
01656 int col_max=0;
01657
01658 col_min = (llx>0) ? llx : 0;
01659 row_min = (lly>0) ? lly : 0;
01660 col_max = (urx<im_lx) ? urx : im_lx-1;
01661 row_max = (ury<im_ly) ? ury : im_ly-1;
01662
01663 for ( row = row_min ; row <= row_max ; row++ )
01664 {
01665 for ( col = col_min ; col <= col_max ; col++ )
01666 {
01667 if ( !isnan(pim[col + row*im_lx]) )
01668 {
01669 pix_array[n] = pim[col + row*im_lx] ;
01670 n++ ;
01671 }
01672 }
01673 }
01674
01675 npix = n;
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 if ( FLT_MAX == (retstats->cleanmean = xsh_clean_mean(pix_array,
01687 npix, loReject, hiReject)) )
01688 {
01689 xsh_msg_error("xsh_clean_mean() did not work!") ;
01690 cpl_free(retstats) ;
01691 cpl_free(pix_array) ;
01692 return NULL ;
01693 }
01694
01695
01696
01697 lo_n = (int) (loReject / 100. * (float)npix) ;
01698 hi_n = (int) (hiReject / 100. * (float)npix) ;
01699 pix_sum = 0. ;
01700 sqr_sum = 0. ;
01701 n = 0 ;
01702 for ( i = lo_n ; i <= npix - hi_n ; i++ )
01703 {
01704 pix_sum += (double)pix_array[i] ;
01705 sqr_sum += ((double)pix_array[i] * (double)pix_array[i]) ;
01706 n++ ;
01707 }
01708
01709 if ( n == 0 )
01710 {
01711 xsh_msg_error("number of clean pixels is zero!") ;
01712 cpl_free(retstats) ;
01713 cpl_free(pix_array) ;
01714 return NULL ;
01715 }
01716 retstats -> npix = n ;
01717 pix_sum /= (double) n ;
01718 sqr_sum /= (double) n ;
01719 retstats -> cleanstdev = (float)sqrt(sqr_sum - pix_sum * pix_sum) ;
01720 cpl_free (pix_array) ;
01721 return retstats ;
01722 }
01723
01724 #define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }
01725 #define PIX_STACK_SIZE 50
01726
01738 void
01739 xsh_pixel_qsort(pixelvalue *pix_arr, int npix)
01740 {
01741 int i,
01742 ir,
01743 j,
01744 k,
01745 l;
01746 int i_stack[PIX_STACK_SIZE*sizeof(pixelvalue)] ;
01747 int j_stack ;
01748 pixelvalue a ;
01749
01750 ir = npix ;
01751 l = 1 ;
01752 j_stack = 0 ;
01753 for (;;) {
01754 if (ir-l < 7) {
01755 for (j=l+1 ; j<=ir ; j++) {
01756 a = pix_arr[j-1];
01757 for (i=j-1 ; i>=1 ; i--) {
01758 if (pix_arr[i-1] <= a) break;
01759 pix_arr[i] = pix_arr[i-1];
01760 }
01761 pix_arr[i] = a;
01762 }
01763 if (j_stack == 0) break;
01764 ir = i_stack[j_stack-- -1];
01765 l = i_stack[j_stack-- -1];
01766 } else {
01767 k = (l+ir) >> 1;
01768 PIX_SWAP(pix_arr[k-1], pix_arr[l])
01769 if (pix_arr[l] > pix_arr[ir-1]) {
01770 PIX_SWAP(pix_arr[l], pix_arr[ir-1])
01771 }
01772 if (pix_arr[l-1] > pix_arr[ir-1]) {
01773 PIX_SWAP(pix_arr[l-1], pix_arr[ir-1])
01774 }
01775 if (pix_arr[l] > pix_arr[l-1]) {
01776 PIX_SWAP(pix_arr[l], pix_arr[l-1])
01777 }
01778 i = l+1;
01779 j = ir;
01780 a = pix_arr[l-1];
01781 for (;;) {
01782 do i++; while (pix_arr[i-1] < a);
01783 do j--; while (pix_arr[j-1] > a);
01784 if (j < i) break;
01785 PIX_SWAP(pix_arr[i-1], pix_arr[j-1]);
01786 }
01787 pix_arr[l-1] = pix_arr[j-1];
01788 pix_arr[j-1] = a;
01789 j_stack += 2;
01790 if (j_stack > PIX_STACK_SIZE) {
01791 xsh_msg_error("stack too small : aborting");
01792 exit(-2001) ;
01793 }
01794 if (ir-i+1 >= j-l) {
01795 i_stack[j_stack-1] = ir;
01796 i_stack[j_stack-2] = i;
01797 ir = j-1;
01798 } else {
01799 i_stack[j_stack-1] = j-1;
01800 i_stack[j_stack-2] = l;
01801 l = i;
01802 }
01803 }
01804 }
01805 }
01806 #undef PIX_STACK_SIZE
01807 #undef PIX_SWAP
01808
01825 float xsh_clean_mean( float * array,
01826 int n_elements,
01827 float throwaway_low,
01828 float throwaway_high )
01829 {
01830 int i, n ;
01831 int lo_n, hi_n ;
01832 float sum ;
01833
01834 if ( array == NULL )
01835 {
01836 xsh_msg_error(" no array given in xsh_clean_mean!") ;
01837 return FLT_MAX ;
01838 }
01839
01840 if ( n_elements <= 0 )
01841 {
01842 xsh_msg_error("wrong number of elements given") ;
01843 return FLT_MAX ;
01844 }
01845
01846 if ( throwaway_low < 0. || throwaway_high < 0. ||
01847 throwaway_low + throwaway_high >= 100. )
01848 {
01849 xsh_msg_error("wrong throw away percentage given!") ;
01850 return FLT_MAX ;
01851 }
01852
01853 lo_n = (int) (throwaway_low * (float)n_elements / 100.) ;
01854 hi_n = (int) (throwaway_high * (float)n_elements / 100.) ;
01855
01856
01857 xsh_pixel_qsort( array, n_elements ) ;
01858
01859 n = 0 ;
01860 sum = 0. ;
01861 for ( i = lo_n ; i < n_elements - hi_n ; i++ )
01862 {
01863 if ( !isnan(array[i]) )
01864 {
01865 sum += array[i] ;
01866 n++ ;
01867 }
01868 }
01869 if ( n == 0 )
01870 {
01871 return FLAG ;
01872 }
01873 else
01874 {
01875 return sum/(float)n ;
01876 }
01877 }
01878
01879
01893
01894
01895 cpl_image *
01896 xsh_image_smooth_fft(cpl_image * inp, const int fx, const int fy)
01897 {
01898
01899 int sx=0;
01900 int sy=0;
01901
01902 cpl_image* out=NULL;
01903 cpl_image* im_re=NULL;
01904 cpl_image* im_im=NULL;
01905 cpl_image* ifft_re=NULL;
01906 cpl_image* ifft_im=NULL;
01907 cpl_image* filter=NULL;
01908
01909
01910 cknull_msg(inp,"Null in put image, exit");
01911 check(im_re = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
01912 check(im_im = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
01913
01914
01915 check(cpl_image_fft(im_re,im_im,CPL_FFT_DEFAULT));
01916 check(sx=cpl_image_get_size_x(inp));
01917 check(sy=cpl_image_get_size_y(inp));
01918
01919
01920
01921 check(filter = xsh_gen_lowpass(sx,sy,fx,fy));
01922
01923
01924 cpl_image_multiply(im_re,filter);
01925 cpl_image_multiply(im_im,filter);
01926
01927 xsh_free_image(&filter);
01928
01929 check(ifft_re = cpl_image_duplicate(im_re));
01930 check(ifft_im = cpl_image_duplicate(im_im));
01931
01932 xsh_free_image(&im_re);
01933 xsh_free_image(&im_im);
01934
01935
01936 check(cpl_image_fft(ifft_re,ifft_im,CPL_FFT_INVERSE));
01937 check(out = cpl_image_cast(ifft_re, CPL_TYPE_FLOAT));
01938
01939 cleanup:
01940
01941 xsh_free_image(&ifft_re);
01942 xsh_free_image(&ifft_im);
01943 xsh_free_image(&filter);
01944 xsh_free_image(&im_re);
01945 xsh_free_image(&im_im);
01946
01947 if(cpl_error_get_code() != CPL_ERROR_NONE) {
01948 return NULL;
01949 } else {
01950 return out;
01951 }
01952
01953 }
01954
01955
01971
01972 static cpl_image *
01973 xsh_gen_lowpass(const int xs,
01974 const int ys,
01975 const double sigma_x,
01976 const double sigma_y)
01977 {
01978
01979 int i= 0.0;
01980 int j= 0.0;
01981 int hlx= 0.0;
01982 int hly = 0.0;
01983 double x= 0.0;
01984 double y= 0.0;
01985 double gaussval= 0.0;
01986 double inv_sigma_x=1./sigma_x;
01987 double inv_sigma_y=1./sigma_y;
01988
01989 float *data;
01990
01991 cpl_image *lowpass_image=NULL;
01992 int err_no=0;
01993
01994
01995 lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
01996 if (lowpass_image == NULL) {
01997 xsh_msg_error("Cannot generate lowpass filter <%s>",
01998 cpl_error_get_message());
01999 return NULL;
02000 }
02001
02002 hlx = xs/2;
02003 hly = ys/2;
02004
02005 data = cpl_image_get_data_float(lowpass_image);
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017 data[0] = 1.0;
02018
02019
02020 for (i=1 ; i<=hlx ; i++) {
02021 x = i * inv_sigma_x;
02022 gaussval = exp(-0.5*x*x);
02023 data[i] = gaussval;
02024 data[xs-i] = gaussval;
02025 }
02026
02027 for (j=1; j<=hly ; j++) {
02028 y = j * inv_sigma_y;
02029
02030 data[j*xs] = exp(-0.5*y*y);
02031 data[(ys-j)*xs] = exp(-0.5*y*y);
02032
02033 for (i=1 ; i<=hlx ; i++) {
02034
02035 x = i * inv_sigma_x;
02036 gaussval = exp (-0.5*(x*x+y*y));
02037 data[j*xs+i] = gaussval;
02038 data[(j+1)*xs-i] = gaussval;
02039 data[(ys-j)*xs+i] = gaussval;
02040 data[(ys+1-j)*xs-i] = gaussval;
02041
02042 }
02043 }
02044
02045
02046
02047
02048
02049 if(err_no != 0)
02050 err_no = 0;
02051
02052 return lowpass_image;
02053 }
02054
02055
02056
02070
02071
02072 cpl_image *
02073 xsh_image_smooth_mean_y(cpl_image * inp, const int r)
02074 {
02075
02076
02077 double* pinp = NULL;
02078 double* pout = NULL;
02079 int sx = 0;
02080 int sy = 0;
02081 register int i = 0;
02082 register int j = 0;
02083 register int k = 0;
02084 register int pix=0;
02085 cpl_image* out=NULL;
02086
02087 XSH_ASSURE_NOT_NULL( inp);
02088 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
02089 check(sx = cpl_image_get_size_x(inp));
02090 check(sy = cpl_image_get_size_y(inp));
02091 check(pinp = cpl_image_get_data_double(inp));
02092 check(pout = cpl_image_get_data_double(out));
02093 for( j=r; j<sy-r; j++) {
02094 pix=j*sx+i;
02095 for( i=0; i<sx; i++) {
02096 for( k=-r; k<r; k++) {
02097 pout[pix] += pinp[pix+k*sx];
02098 }
02099 pout[pix]/=(2*r);
02100 }
02101 }
02102
02103 cleanup:
02104 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02105 xsh_free_image( &out);
02106 }
02107 return out;
02108 }
02109
02110
02111
02125
02126
02127 cpl_image *
02128 xsh_image_smooth_median_y(cpl_image * inp, const int r)
02129 {
02130
02131
02132 double* pout=NULL;
02133 int sx=0;
02134 int sy=0;
02135 int i=0;
02136 int j=0;
02137
02138 cpl_image* out=NULL;
02139
02140
02141 cknull_msg(inp,"Null in put image, exit");
02142
02143 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
02144 check(sx=cpl_image_get_size_x(inp));
02145 check(sy=cpl_image_get_size_y(inp));
02146 check(pout=cpl_image_get_data_double(out));
02147
02148 for(j=r+1;j<sy-r;j++) {
02149 for(i=1;i<sx;i++) {
02150 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i,j+r);
02151 }
02152 }
02153
02154 cleanup:
02155
02156 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02157 return NULL;
02158 } else {
02159 return out;
02160
02161 }
02162
02163 }
02164
02165
02166
02180
02181
02182 cpl_image *
02183 xsh_image_smooth_mean_x( cpl_image * inp, const int r)
02184 {
02185
02186 double* pinp=NULL;
02187 double* pout=NULL;
02188 int sx=0;
02189 int sy=0;
02190 int i=0;
02191 int j=0;
02192 int k=0;
02193
02194 cpl_image* out=NULL;
02195
02196
02197 XSH_ASSURE_NOT_NULL( inp);
02198 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
02199 check( sx=cpl_image_get_size_x(inp));
02200 check( sy=cpl_image_get_size_y(inp));
02201 check( pinp=cpl_image_get_data_double(inp));
02202 check( pout=cpl_image_get_data_double(out));
02203 for(j=0;j<sy;j++) {
02204 for(i=r;i<sx-r;i++) {
02205 for(k=-r;k<r;k++) {
02206 pout[j*sx+i]+=pinp[j*sx+i+k];
02207 }
02208 pout[j*sx+i]/=2*r;
02209 }
02210 }
02211
02212 cleanup:
02213
02214 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02215 return NULL;
02216 } else {
02217 return out;
02218
02219 }
02220
02221 }
02222
02223
02224
02238
02239
02240 cpl_image *
02241 xsh_image_smooth_median_x(cpl_image * inp, const int r)
02242 {
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252 float* pout=NULL;
02253 int sx=0;
02254 int sy=0;
02255 int i=0;
02256 int j=0;
02257
02258 cpl_image* out=NULL;
02259
02260
02261 cknull_msg(inp,"Null in put image, exit");
02262
02263 check(out=cpl_image_cast(inp,CPL_TYPE_FLOAT));
02264 check(sx=cpl_image_get_size_x(inp));
02265 check(sy=cpl_image_get_size_y(inp));
02266 check(pout=cpl_image_get_data_float(out));
02267
02268 for(j=1;j<sy;j++) {
02269 for(i=r+1;i<sx-r;i++) {
02270 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j);
02271 }
02272 }
02273
02274 cleanup:
02275
02276 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02277 return NULL;
02278 } else {
02279 return out;
02280
02281 }
02282
02283 }
02284
02285
02286
02287
02301
02302
02303 cpl_image *
02304 xsh_image_smooth_median_xy(cpl_image * inp, const int r)
02305 {
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315 double* pout=NULL;
02316 int sx=0;
02317 int sy=0;
02318 int i=0;
02319 int j=0;
02320
02321 cpl_image* out=NULL;
02322
02323
02324 cknull_msg(inp,"Null in put image, exit");
02325
02326 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
02327 check(sx=cpl_image_get_size_x(inp));
02328 check(sy=cpl_image_get_size_y(inp));
02329 check(pout=cpl_image_get_data_double(out));
02330
02331 for(j=r+1;j<sy-r;j++) {
02332 for(i=r+1;i<sx-r;i++) {
02333 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j+r);
02334 }
02335 }
02336
02337 cleanup:
02338
02339 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02340 return NULL;
02341 } else {
02342 return out;
02343
02344 }
02345
02346 }
02347
02348
02358
02359
02360 cpl_error_code
02361 xsh_image_clean_badpixel(cpl_frame* in)
02362 {
02363
02364
02365 cpl_image* ima=NULL;
02366 cpl_image* err=NULL;
02367 cpl_image* qua=NULL;
02368 cpl_propertylist* hima=NULL;
02369 cpl_propertylist* herr=NULL;
02370 cpl_propertylist* hqua=NULL;
02371
02372
02373 const char* name=NULL;
02374 double* pima=NULL;
02375 int* pqua=NULL;
02376 int nx=0;
02377 int ny=0;
02378 int i=0;
02379 int j=0;
02380 int rx=5;
02381 int ry=5;
02382
02383 name=cpl_frame_get_filename(in);
02384 hima=cpl_propertylist_load(name,0);
02385 herr=cpl_propertylist_load(name,1);
02386 hqua=cpl_propertylist_load(name,2);
02387 ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0);
02388 err=cpl_image_load(name,CPL_TYPE_DOUBLE,0,1);
02389 qua=cpl_image_load(name,CPL_TYPE_INT,0,2);
02390
02391 nx=cpl_image_get_size_x(ima);
02392 ny=cpl_image_get_size_y(ima);
02393
02394 pima=cpl_image_get_data_double(ima);
02395 pqua=cpl_image_get_data_int(qua);
02396
02397 for(j=ry;j<ny-ry;j++) {
02398 for(i=rx;i<nx-rx;i++) {
02399 if(pqua[i+j*nx]!=0) {
02400 pima[i+j*nx]=cpl_image_get_median_window(ima,i-rx,j-ry,i+rx,j+ry);
02401 }
02402 }
02403 }
02404 check(cpl_image_save(ima,name,XSH_PRE_DATA_BPP,hima,CPL_IO_DEFAULT));
02405 check(cpl_image_save(err,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
02406 check(cpl_image_save(qua,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
02407
02408 cleanup:
02409 xsh_free_image(&ima);
02410 xsh_free_image(&err);
02411 xsh_free_image(&qua);
02412 xsh_free_propertylist(&hima);
02413 xsh_free_propertylist(&herr);
02414 xsh_free_propertylist(&hqua);
02415
02416 return cpl_error_get_code();
02417
02418 }
02419
02420
02421
02435
02436
02437 double
02438 xsh_image_fit_gaussian_max_pos_x_window(const cpl_image* ima,
02439 const int llx,
02440 const int urx,
02441 const int ypos)
02442 {
02443
02444
02445 XSH_GAUSSIAN_FIT fit_res;
02446 int i=0;
02447 int nelem=0;
02448 int ix=0;
02449 int iy=ypos;
02450
02451 double dy=0;
02452 cpl_vector* pix_pos=NULL;
02453 cpl_vector* pix_val=NULL;
02454 double x_centroid=0;
02455
02456
02457 nelem=urx-llx+1;
02458 check( pix_pos = cpl_vector_new( nelem ) ) ;
02459 check( pix_val = cpl_vector_new( nelem ) ) ;
02460
02461
02462 for( i = 0, ix = llx ; ix <= urx ; ix++, i++, dy += 1. ) {
02463 int rej ;
02464 double value ;
02465
02466 cpl_error_reset() ;
02467 value = cpl_image_get(ima , ix, iy, &rej ) ;
02468 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02469 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
02470 cpl_error_reset() ;
02471 continue ;
02472 }
02473 cpl_vector_set( pix_val, i, value ) ;
02474 cpl_vector_set( pix_pos, i, dy ) ;
02475 }
02476
02477 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
02478 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02479 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
02480 cpl_error_reset() ;
02481 x_centroid=cpl_image_get_centroid_x_window(ima,llx,ypos,urx,ypos);
02482
02483
02484 } else {
02485
02486 x_centroid=llx+fit_res.peakpos;
02487 }
02488
02489 cleanup:
02490 xsh_free_vector(&pix_pos);
02491 xsh_free_vector(&pix_val);
02492
02493 return x_centroid;
02494 }
02495
02496
02510
02511
02512 static double
02513 xsh_image_fit_gaussian_max_pos_y_window(const cpl_image* ima,
02514 const int lly,
02515 const int ury,
02516 const int xpos)
02517 {
02518
02519
02520 XSH_GAUSSIAN_FIT fit_res;
02521 int j=0;
02522 int nelem=0;
02523 int jy=0;
02524 int jx=xpos;
02525
02526 double dy=0;
02527 cpl_vector* pix_pos=NULL;
02528 cpl_vector* pix_val=NULL;
02529 double y_centroid=0;
02530
02531
02532 nelem=ury-lly+1;
02533 check( pix_pos = cpl_vector_new( nelem ) ) ;
02534 check( pix_val = cpl_vector_new( nelem ) ) ;
02535
02536
02537 for( j = 0, jy = lly ; jy <= ury ; jy++, j++, dy += 1. ) {
02538 int rej ;
02539 double value ;
02540
02541 cpl_error_reset() ;
02542 value = cpl_image_get(ima , jx, jy, &rej ) ;
02543 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02544 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
02545 cpl_error_reset() ;
02546 continue ;
02547 }
02548 cpl_vector_set( pix_val, j, value ) ;
02549 cpl_vector_set( pix_pos, j, dy ) ;
02550 }
02551
02552 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
02553 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02554 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
02555 cpl_error_reset() ;
02556 y_centroid=cpl_image_get_centroid_y_window(ima,xpos,lly,xpos,ury);
02557
02558
02559 } else {
02560
02561 y_centroid=lly+fit_res.peakpos;
02562 }
02563
02564 cleanup:
02565 xsh_free_vector(&pix_pos);
02566 xsh_free_vector(&pix_val);
02567
02568 return y_centroid;
02569 }
02570
02571
02572
02589
02590
02591 static cpl_table*
02592 xsh_image_qc_trace_window(cpl_image* data_ima,cpl_propertylist* head,
02593 const int hsize, const int method)
02594 {
02595
02596 cpl_table* table=NULL;
02597 int i=0;
02598
02599 int naxis1=0;
02600 int naxis2=0;
02601 cpl_size mx=0;
02602 cpl_size my=0;
02603
02604 int lly=0;
02605 int ury=0;
02606 int llx=0;
02607 int* px=NULL;
02608 double* pcy=NULL;
02609 double* pwav=NULL;
02610 double crval1=0;
02611 double cdelt1=0;
02612
02613 crval1=xsh_pfits_get_crval1(head);
02614 cdelt1=xsh_pfits_get_cdelt1(head);
02615
02616 naxis1=cpl_image_get_size_x(data_ima);
02617 naxis2=cpl_image_get_size_y(data_ima);
02618
02619 table=cpl_table_new(naxis1);
02620 cpl_table_new_column(table,"X",CPL_TYPE_INT);
02621 cpl_table_new_column(table,"WAVELENGTH",CPL_TYPE_DOUBLE);
02622 cpl_table_new_column(table,"POS",CPL_TYPE_DOUBLE);
02623
02624 cpl_table_fill_column_window_int(table,"X",0,naxis1,0);
02625 cpl_table_fill_column_window_double(table,"WAVELENGTH",0,naxis1,0.);
02626 cpl_table_fill_column_window_double(table,"POS",0,naxis1,0.);
02627
02628 px=cpl_table_get_data_int(table,"X");
02629 pwav=cpl_table_get_data_double(table,"WAVELENGTH");
02630 pcy=cpl_table_get_data_double(table,"POS");
02631
02632 for(i=0;i<naxis1;i++) {
02633 px[i]=i;
02634 pwav[i]=crval1+cdelt1*i;
02635 llx=i+1;
02636 check(cpl_image_get_maxpos_window(data_ima,llx,1,llx,naxis2,&mx,&my));
02637 lly=(my-hsize>0) ? my-hsize:1;
02638 ury=(my+hsize<=naxis2) ? my+hsize:naxis2;
02639 if(method == 0 ) {
02640 pcy[i]=xsh_image_fit_gaussian_max_pos_y_window(data_ima,lly,ury,llx);
02641 } else {
02642 check(pcy[i]=cpl_image_get_centroid_y_window(data_ima,llx,lly,llx,ury));
02643 }
02644 }
02645
02646 cleanup:
02647
02648 return table;
02649 }
02650
02669
02670
02671 cpl_frame*
02672 xsh_frame_image_qc_trace_window(cpl_frame* frm_ima,xsh_instrument* instrument,
02673 const char* suffix,const int hsize, const int method)
02674 {
02675
02676 cpl_frame* result=NULL;
02677 cpl_table* table=NULL;
02678 cpl_image* data_ima=NULL;
02679 const char* name=NULL;
02680
02681 cpl_propertylist* plist=NULL;
02682 char fname[256];
02683 char tag[50];
02684
02685 check(name=cpl_frame_get_filename(frm_ima));
02686
02687 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0));
02688 plist=cpl_propertylist_load(name,0);
02689
02690
02691 check(table=xsh_image_qc_trace_window(data_ima,plist,hsize,method));
02692
02693 sprintf(tag,"MERGE3D_TRACE_OBJ_%s_%s",
02694 xsh_instrument_arm_tostring( instrument),suffix);
02695 sprintf(fname,"%s.fits",tag);
02696
02697 check(cpl_table_save(table,plist,NULL,fname,CPL_IO_DEFAULT));
02698
02699 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
02700 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
02701
02702 cleanup:
02703
02704 xsh_free_propertylist(&plist);
02705 xsh_free_table(&table);
02706 xsh_free_image(&data_ima);
02707
02708 return result;
02709 }
02710
02729
02730
02731 cpl_frame*
02732 xsh_frame_image_ext_qc_trace_window(cpl_frame* frm_ima,
02733 xsh_instrument* instrument,
02734 const char* suffix,
02735 const int hsize,
02736 const int method)
02737 {
02738
02739 cpl_frame* result=NULL;
02740 cpl_table* table=NULL;
02741 cpl_table* table_tot=NULL;
02742
02743 cpl_image* data_ima=NULL;
02744 const char* name=NULL;
02745
02746 cpl_propertylist* phead=NULL;
02747 cpl_propertylist* xhead=NULL;
02748
02749 char fname[256];
02750 char tag[50];
02751 int nbext=0;
02752 int k=0;
02753 int nrow=0;
02754 xsh_msg("Trace object position");
02755 check(name=cpl_frame_get_filename(frm_ima));
02756 nbext=cpl_frame_get_nextensions( frm_ima);
02757
02758 table_tot=cpl_table_new(0);
02759 phead=cpl_propertylist_load(name,0);
02760 for(k=0;k<nbext;k+=3){
02761 nrow=cpl_table_get_nrow(table_tot);
02762
02763 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,k));
02764 xhead=cpl_propertylist_load(name,k);
02765
02766 check(table=xsh_image_qc_trace_window(data_ima,xhead,hsize,method));
02767 if(k==0) check(cpl_table_copy_structure(table_tot,table));
02768 cpl_table_insert(table_tot,table,nrow);
02769 xsh_free_propertylist(&xhead);
02770 xsh_free_table(&table);
02771 xsh_free_image(&data_ima);
02772 }
02773 sprintf(tag,"OBJ_POS_ORD_%s_%s",
02774 xsh_instrument_arm_tostring( instrument),suffix);
02775 sprintf(fname,"%s.fits",tag);
02776
02777 check(cpl_table_save(table_tot,phead,NULL,fname,CPL_IO_DEFAULT));
02778
02779 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
02780 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
02781
02782 cleanup:
02783
02784 xsh_free_propertylist(&phead);
02785 xsh_free_propertylist(&xhead);
02786 xsh_free_table(&table);
02787 xsh_free_table(&table_tot);
02788 xsh_free_image(&data_ima);
02789
02790 return result;
02791 }
02792
02793
02807
02808
02809 static cpl_error_code
02810 xsh_util_compute_qc_residuals(cpl_table* table,
02811 xsh_instrument* instrument,
02812 cpl_propertylist* plist)
02813 {
02814 cpl_table* qc_table=NULL;
02815 double res_min=0;
02816 double res_max=0;
02817 double res_med=0;
02818 double res_avg=0;
02819 double res_rms=0;
02820 double wmin=0;
02821 double wmax=0;
02822
02823 if( xsh_instrument_get_arm(instrument) == XSH_ARM_UVB) {
02824 wmin=350;
02825 wmax=540;
02826 } else if( xsh_instrument_get_arm(instrument) == XSH_ARM_VIS){
02827 wmin=580;
02828 wmax=950;
02829 } else {
02830 wmin=1000;
02831 wmax=2200;
02832 }
02833
02834 check(cpl_table_and_selected_double(table,"WAVELENGTH",CPL_GREATER_THAN,wmin));
02835 check(cpl_table_and_selected_double(table,"WAVELENGTH",CPL_LESS_THAN,wmax));
02836 check(qc_table=cpl_table_extract_selected(table));
02837 check(cpl_table_select_all(table));
02838
02839
02840 check(res_min=cpl_table_get_column_min(qc_table,"RES12"));
02841 check(res_max=cpl_table_get_column_max(qc_table,"RES12"));
02842 check(res_avg=cpl_table_get_column_mean(qc_table,"RES12"));
02843 check(res_med=cpl_table_get_column_median(qc_table,"RES12"));
02844 check(res_rms=cpl_table_get_column_stdev(qc_table,"RES12"));
02845
02846 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MIN,res_min);
02847 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MIN,"Minimum residuals");
02848 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MAX,res_max);
02849 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MAX,"Maximum residuals");
02850 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_AVG,res_avg);
02851 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_AVG,"Mean residuals");
02852
02853 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MED,res_med);
02854 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MED,"Median residuals");
02855 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_RMS,res_rms);
02856 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_RMS,"Stdev residuals");
02857
02858 res_min=cpl_table_get_column_min(qc_table,"RES32");
02859 res_max=cpl_table_get_column_max(qc_table,"RES32");
02860 res_avg=cpl_table_get_column_mean(qc_table,"RES32");
02861 res_med=cpl_table_get_column_median(qc_table,"RES32");
02862 res_rms=cpl_table_get_column_stdev(qc_table,"RES32");
02863
02864 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MIN,res_min);
02865 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MIN,"Minimum residuals");
02866 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MAX,res_max);
02867 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MAX,"Maximum residuals");
02868 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_AVG,res_avg);
02869 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_AVG,"Mean residuals");
02870
02871 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MED,res_med);
02872 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MED,"Median residuals");
02873 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_RMS,res_rms);
02874 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_RMS,"Stdev residuals");
02875
02876 res_min=cpl_table_get_column_min(qc_table,"RES13");
02877 res_max=cpl_table_get_column_max(qc_table,"RES13");
02878 res_avg=cpl_table_get_column_mean(qc_table,"RES13");
02879 res_med=cpl_table_get_column_median(qc_table,"RES13");
02880 res_rms=cpl_table_get_column_stdev(qc_table,"RES13");
02881
02882 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MIN,res_min);
02883 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MIN,"Minimum residuals");
02884 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MAX,res_max);
02885 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MAX,"Maximum residuals");
02886 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_AVG,res_avg);
02887 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_AVG,"Mean residuals");
02888
02889 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MED,res_med);
02890 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MED,"Median residuals");
02891 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_RMS,res_rms);
02892 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_RMS,"Stdev residuals");
02893
02894 cleanup:
02895 xsh_free_table(&qc_table);
02896 return cpl_error_get_code();
02897
02898 }
02899
02900
02920
02921
02922 static cpl_error_code
02923 xsh_cube_trace_fit(cpl_table** table,
02924 const char* col_wav,
02925 const char* col_ref,
02926 const char* col_fit,
02927 const char* qualifier,
02928 cpl_propertylist* plist)
02929 {
02930 int nrow=0;
02931 int k=0;
02932 cpl_polynomial* pol=NULL;
02933 cpl_vector* vx=NULL;
02934 cpl_vector* vy=NULL;
02935
02936 double* px=NULL;
02937 double* py=NULL;
02938 double* pf=NULL;
02939 int order=2;
02940 char key_name[25];
02941 cpl_size power=0;
02942 double coeff=0;
02943
02944
02945 nrow=cpl_table_get_nrow(*table);
02946 cpl_table_new_column(*table,col_fit,CPL_TYPE_DOUBLE);
02947 cpl_table_fill_column_window_double(*table,col_fit,0,nrow,0.);
02948
02949 px=cpl_table_get_data_double(*table,col_wav);
02950 py=cpl_table_get_data_double(*table,col_ref);
02951 pf=cpl_table_get_data_double(*table,col_fit);
02952
02953 vx = cpl_vector_wrap( nrow, px );
02954 vy = cpl_vector_wrap( nrow, py );
02955
02956 pol=xsh_polynomial_fit_1d_create(vx,vy,order,NULL);
02957
02958 for(k=0; k< nrow; k++){
02959 check( pf[k] = cpl_polynomial_eval_1d(pol,px[k],NULL));
02960 }
02961
02962
02963 power=0;
02964 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,qualifier);
02965 coeff = cpl_polynomial_get_coeff(pol, &power);
02966 cpl_propertylist_append_double(plist,key_name,coeff);
02967 cpl_propertylist_set_comment(plist,key_name,"order 0 fit coeff");
02968
02969 power=1;
02970 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,qualifier);
02971 coeff = cpl_polynomial_get_coeff(pol, &power);
02972 cpl_propertylist_append_double(plist,key_name,coeff);
02973 cpl_propertylist_set_comment(plist,key_name,"order 1 fit coeff");
02974
02975 power=2;
02976 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,qualifier);
02977 coeff = cpl_polynomial_get_coeff(pol, &power);
02978 cpl_propertylist_append_double(plist,key_name,coeff);
02979 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff");
02980
02981
02982 cleanup:
02983 cpl_vector_unwrap(vx);
02984 cpl_vector_unwrap(vy);
02985 xsh_free_polynomial(&pol);
02986 return cpl_error_get_code();
02987 }
02988
03005
03006
03007 static cpl_error_code
03008 xsh_cube_trace_diff(const cpl_table* table,
03009 const char* col_comp,
03010 const char* col_ref,
03011 cpl_propertylist* plist)
03012 {
03013 char key_name[25];
03014
03015 double cmp_c0=0;
03016 double ref_c0=0;
03017 double dif_c0=0;
03018
03019 double cmp_c1=0;
03020 double ref_c1=0;
03021 double dif_c1=0;
03022
03023 double cmp_c2=0;
03024 double ref_c2=0;
03025 double dif_c2=0;
03026
03027 const double* pw=NULL;
03028 double wav=0;
03029 double cmp_pos=0;
03030 double ref_pos=0;
03031 double dif_pos=0;
03032
03033 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_comp);
03034 check(cmp_c0=cpl_propertylist_get_double(plist,key_name));
03035 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_comp);
03036 cmp_c1=cpl_propertylist_get_double(plist,key_name);
03037 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_comp);
03038 cmp_c2=cpl_propertylist_get_double(plist,key_name);
03039
03040 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_ref);
03041 ref_c0=cpl_propertylist_get_double(plist,key_name);
03042 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_ref);
03043 ref_c1=cpl_propertylist_get_double(plist,key_name);
03044 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_ref);
03045 ref_c2=cpl_propertylist_get_double(plist,key_name);
03046
03047
03048 dif_c0=cmp_c0-ref_c0;
03049 dif_c1=cmp_c1-ref_c1;
03050 dif_c2=cmp_c2-ref_c2;
03051
03052
03053 pw=cpl_table_get_data_double_const(table,"WAVELENGTH");
03054
03055 wav=pw[0];
03056 cmp_pos=cmp_c0+cmp_c1*wav+cmp_c2*wav*wav;
03057 ref_pos=ref_c0+ref_c1*wav+ref_c2*wav*wav;
03058
03059 dif_pos=cmp_pos-ref_pos;
03060
03061
03062 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C0,dif_c0);
03063 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C0,"order 0 fit coeff diff");
03064
03065 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c1);
03066 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C1,"order 1 fit coeff diff");
03067
03068 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c2);
03069 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff diff");
03070
03071 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_POS,dif_pos);
03072 cpl_propertylist_set_comment(plist,key_name,"fit trace diff pos");
03073
03074 cleanup:
03075 return cpl_error_get_code();
03076
03077 }
03078
03105
03106
03107
03108 cpl_frame*
03109 xsh_cube_qc_trace_window(cpl_frame* frm_cube,xsh_instrument* instrument,
03110 const char* suffix,const char* rec_prefix,
03111 const int win_min, const int win_max,
03112 const int hsize,
03113 const int method,const int compute_qc)
03114 {
03115 cpl_frame* result=NULL;
03116 cpl_table* table=NULL;
03117 cpl_image* data_ima=NULL;
03118
03119 cpl_imagelist* data_iml=NULL;
03120 cpl_imagelist* errs_iml=NULL;
03121 cpl_imagelist* swap1=NULL;
03122 cpl_imagelist* swap2=NULL;
03123 cpl_imagelist* data_swap=NULL;
03124 cpl_imagelist* errs_swap=NULL;
03125
03126 const char* name=NULL;
03127
03128 int k=0;
03129
03130 int j=0;
03131
03132 int naxis2=0;
03133 int naxis3=0;
03134
03135
03136 cpl_size mx=0;
03137 cpl_size my=0;
03138 double cx=0;
03139
03140
03141
03142 int llx=0;
03143 int urx=0;
03144
03145 double* pcx1=NULL;
03146 double* pcx2=NULL;
03147 double* pcx3=NULL;
03148 double* pwav=NULL;
03149 double crval3=0;
03150 double cdelt3=0;
03151 cpl_propertylist* plist=NULL;
03152 char fname[256];
03153 char tag[256];
03154
03155 check(name=cpl_frame_get_filename(frm_cube));
03156
03157
03158 check(data_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
03159 plist=cpl_propertylist_load(name,0);
03160 crval3=xsh_pfits_get_crval3(plist);
03161 cdelt3=xsh_pfits_get_cdelt3(plist);
03162
03163 swap1=cpl_imagelist_swap_axis_create(data_iml,CPL_SWAP_AXIS_XZ);
03164 xsh_free_imagelist(&data_iml);
03165 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
03166 xsh_free_imagelist(&swap1);
03167 data_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
03168 xsh_free_imagelist(&swap2);
03169
03170
03171 check(errs_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
03172
03173 swap1=cpl_imagelist_swap_axis_create(errs_iml,CPL_SWAP_AXIS_XZ);
03174 xsh_free_imagelist(&data_iml);
03175 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
03176 xsh_free_imagelist(&swap1);
03177 errs_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
03178 xsh_free_imagelist(&swap2);
03179
03180
03181 check(naxis3=cpl_imagelist_get_size(data_swap));
03182 data_ima=cpl_imagelist_get(data_swap,0);
03183
03184 naxis2=cpl_image_get_size_y(data_ima);
03185
03186 table=cpl_table_new(naxis3);
03187 cpl_table_new_column(table,"WAVELENGTH",CPL_TYPE_DOUBLE);
03188
03189 cpl_table_new_column(table,"POS_1",CPL_TYPE_DOUBLE);
03190 cpl_table_new_column(table,"POS_2",CPL_TYPE_DOUBLE);
03191 cpl_table_new_column(table,"POS_3",CPL_TYPE_DOUBLE);
03192
03193 pwav=cpl_table_get_data_double(table,"WAVELENGTH");
03194 pcx1=cpl_table_get_data_double(table,"POS_1");
03195 pcx2=cpl_table_get_data_double(table,"POS_2");
03196 pcx3=cpl_table_get_data_double(table,"POS_3");
03197
03198 cpl_table_fill_column_window_double(table,"WAVELENGTH",0,naxis3,0.);
03199 cpl_table_fill_column_window_double(table,"POS_1",0,naxis3,0.);
03200 cpl_table_fill_column_window_double(table,"POS_2",0,naxis3,0.);
03201 cpl_table_fill_column_window_double(table,"POS_3",0,naxis3,0.);
03202
03203
03204 for(k=0;k<naxis3;k++) {
03205
03206 check(data_ima=cpl_imagelist_get(data_swap,k));
03207
03208 pwav[k]=crval3+cdelt3*k;
03209
03210 for(j=1;j<=naxis2;j++) {
03211 check(cpl_image_get_maxpos_window(data_ima,
03212 win_min,j,win_max,j,&mx,&my));
03213 llx=(mx-hsize>win_min) ? mx-hsize:win_min;
03214 urx=(mx+hsize<win_max) ? mx+hsize:win_max;
03215 if(method == 0 ) {
03216 cx=xsh_image_fit_gaussian_max_pos_x_window(data_ima,llx,urx,j);
03217 } else {
03218 check(cx=cpl_image_get_centroid_x_window(data_ima,llx,j,urx,j));
03219
03220 }
03221
03222 switch(j){
03223 case 1: pcx1[k]=cx;
03224 case 2: pcx2[k]=cx;
03225 case 3: pcx3[k]=cx;
03226 }
03227 }
03228
03229 }
03230
03231
03232 cpl_table_duplicate_column(table,"RES12",table,"POS_1");
03233 cpl_table_subtract_columns(table,"RES12","POS_2");
03234
03235 cpl_table_duplicate_column(table,"RES32",table,"POS_3");
03236 cpl_table_subtract_columns(table,"RES32","POS_2");
03237
03238 cpl_table_duplicate_column(table,"RES13",table,"POS_1");
03239 cpl_table_subtract_columns(table,"RES13","POS_3");
03240
03241 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_1","FPOS_1","T1",plist);
03242 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_2","FPOS_2","T2",plist);
03243 xsh_cube_trace_fit(&table,"WAVELENGTH","POS_3","FPOS_3","T3",plist);
03244
03245 xsh_cube_trace_diff(table,"T3","T2",plist);
03246 xsh_cube_trace_diff(table,"T1","T2",plist);
03247
03248 if(compute_qc) {
03249 check(xsh_util_compute_qc_residuals(table, instrument,plist));
03250 }
03251
03252
03253
03254 sprintf(tag,"%s_%s_TRACE_OBJ_%s",
03255 rec_prefix,suffix,xsh_instrument_arm_tostring( instrument));
03256 sprintf(fname,"%s.fits",tag);
03257 check(cpl_table_save(table,plist,NULL,fname,CPL_IO_DEFAULT));
03258 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
03259 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
03260
03261
03262 cleanup:
03263
03264 xsh_free_table(&table);
03265 xsh_free_imagelist(&swap1);
03266 xsh_free_imagelist(&swap2);
03267 xsh_free_imagelist(&data_swap);
03268 xsh_free_imagelist(&errs_swap);
03269 xsh_free_imagelist(&data_iml);
03270 xsh_free_imagelist(&errs_iml);
03271 xsh_free_propertylist(&plist);
03272
03273 return result;
03274 }
03284 cpl_error_code
03285 xsh_iml_merge_avg(cpl_imagelist** data,
03286 cpl_imagelist** mask,
03287 const cpl_image* data_ima,
03288 const cpl_image* mask_ima,
03289 const int mk)
03290 {
03291 cpl_image* data_tmp=NULL;
03292 cpl_image* mask_tmp=NULL;
03293 int* pmsk=NULL;
03294 double norm=0;
03295
03296 int size=0;
03297 check(size=cpl_imagelist_get_size(*mask));
03298 if(mk<size) {
03299 check(data_tmp=cpl_imagelist_get(*data,mk));
03300 check(mask_tmp=cpl_imagelist_get(*mask,mk));
03301 check(pmsk=cpl_image_get_data_int(mask_tmp));
03302
03303 check(norm=pmsk[1]+1);
03304 check(cpl_image_add(data_tmp,data_ima));
03305 check(cpl_image_divide_scalar(data_tmp,norm));
03306 check(cpl_image_add_scalar(mask_tmp,1));
03307 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
03308 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_tmp),mk));
03309
03310 } else {
03311 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
03312 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_ima),mk));
03313 }
03314
03315 cleanup:
03316
03317
03318
03319
03320 return cpl_error_get_code();
03321
03322 }
03323
03324
03332
03333 cpl_error_code
03334 xsh_image_mflat_detect_blemishes(cpl_frame* flat_frame,
03335 xsh_instrument* instrument)
03336 {
03337
03338 cpl_image* diff=NULL;
03339 cpl_image* flat_smooth=NULL;
03340 cpl_array* val=NULL;
03341 cpl_matrix* mx=NULL;
03342 xsh_pre* mflat=NULL;
03343
03344 int binx=0;
03345 int biny=0;
03346 int sx=0;
03347 int sy=0;
03348 int i=0;
03349 int j=0;
03350 int filter_width_x=7;
03351 int filter_width_y=7;
03352
03353 double kappa=40.;
03354
03355 float* pima=NULL;
03356 int* pqual=NULL;
03357
03358 int npixs=0;
03359 const char* filename;
03360 const char* tag;
03361
03362 XSH_ASSURE_NOT_NULL_MSG(flat_frame, "NULL input flat ");
03363
03364 filename=cpl_frame_get_filename(flat_frame);
03365 tag=cpl_frame_get_tag(flat_frame);
03366
03367 check(mflat=xsh_pre_load(flat_frame,instrument));
03368
03369 sx=mflat->nx;
03370 sy=mflat->ny;
03371 binx=mflat->binx;
03372 biny=mflat->biny;
03373 npixs=sx*sy;
03374
03375
03376 if (binx>1) filter_width_x=5;
03377 if (biny>1) filter_width_y=5;
03378
03379
03380
03381 check(mx=cpl_matrix_new(filter_width_x,filter_width_y));
03382
03383 for(j=0; j< filter_width_y; j++){
03384 for(i=0; i< filter_width_x; i++){
03385 cpl_matrix_set( mx, i,j,1.0);
03386 }
03387 }
03388
03389
03390 check(diff=cpl_image_duplicate(mflat->data));
03391 check(flat_smooth=xsh_image_filter_median(mflat->data,mx));
03392
03393
03394
03395
03396
03397
03398 check(cpl_image_subtract(diff,flat_smooth));
03399
03400
03401
03402
03403
03404
03405 check(cpl_image_divide(diff,mflat->errs));
03406
03407
03408
03409
03410 check(pqual=cpl_image_get_data_int(mflat->qual));
03411 check(pima=cpl_image_get_data_float(diff));
03412
03413 for(i=0;i<npixs;i++) {
03414 if(fabs(pima[i])>kappa) {
03415 pqual[i] |= QFLAG_OTHER_BAD_PIXEL;
03416 }
03417 }
03418
03419
03420 cpl_frame* frm=NULL;
03421 check(frm=xsh_pre_save(mflat,filename,tag,0));
03422 xsh_free_frame(&frm);
03423
03424
03425 cleanup:
03426
03427 xsh_free_array(&val);
03428 xsh_free_image(&diff);
03429 xsh_free_image(&flat_smooth);
03430 xsh_free_matrix(&mx);
03431 xsh_pre_free(&mflat);
03432 return cpl_error_get_code();
03433 }
03434
03444 cpl_error_code
03445 xsh_collapse_errs(cpl_image * errs, cpl_imagelist * list,const int mode)
03446 {
03447 int nx = 0, ny = 0, nimg = 0, i = 0;
03448 float **pdata = NULL;
03449 cpl_binary ** pbinary = NULL;
03450 float* errsdata = NULL;
03451 double mpi_2=0.5*M_PI;
03452 check(nimg = cpl_imagelist_get_size (list));
03453 assure(nimg > 0,CPL_ERROR_ILLEGAL_INPUT,"you must have image to collapse");
03454
03455
03456 pdata = cpl_malloc (nimg * sizeof (float *));
03457 assure (pdata != NULL, cpl_error_get_code (),
03458 "Cant allocate memory for data pointers");
03459
03460 pbinary = cpl_malloc (nimg * sizeof (cpl_binary *));
03461 assure (pbinary != NULL, cpl_error_get_code (),
03462 "Cant allocate memory for binary pointers");
03463
03464
03465 for (i = 0; i < nimg; i++) {
03466 check( pdata[i] = cpl_image_get_data_float(cpl_imagelist_get (list, i)));
03467 check( pbinary[i] = cpl_mask_get_data(cpl_image_get_bpm(
03468 cpl_imagelist_get(list, i))));
03469 }
03470
03471
03472 check(nx = cpl_image_get_size_x (cpl_imagelist_get (list, 0)));
03473 check(ny = cpl_image_get_size_y (cpl_imagelist_get (list, 0)));
03474 check(errsdata = cpl_image_get_data_float(errs));
03475
03476
03477 for (i = 0; i < nx * ny; i++){
03478 int count = 0;
03479 int k = 0;
03480 double errval = 0.0;
03481
03482 for (count = 0, k = 0; k < nimg; k++) {
03483
03484 if ( ((pbinary[k])[i] == CPL_BINARY_0) ) {
03485 errval += (pdata[k])[i] * (pdata[k])[i];
03486 count++;
03487 }
03488 }
03489
03490 if (count > 1) {
03491
03492 if (mode==1){
03493
03494 errsdata[i] = sqrt (errval)/((double)count);
03495 } else if (mode==0){
03496
03497 if(count <=2 ) {
03498 errsdata[i] = sqrt (errval)/((double)count);
03499 } else {
03500 errsdata[i] = sqrt ( mpi_2*errval / ((double)(count*(count- 1.))) );
03501 }
03502 }
03503 } else if ( count == 1 ) {
03504 errsdata[i] = sqrt (errval);
03505 }
03506 }
03507 cleanup:
03508 cpl_free(pdata);
03509 cpl_free(pbinary);
03510 return cpl_error_get_code();
03511 }
03512
03527 cpl_image*
03528 xsh_combine_flats(
03529 cpl_image* ima1_in,
03530 cpl_image* ima2_in,
03531 xsh_order_list* qth_list,
03532 xsh_order_list* d2_list,
03533 const int xrad,
03534 const int yrad)
03535 {
03536
03537 cpl_image* ima_comb=NULL;
03538 cpl_image* ima_mask=NULL;
03539
03540 int sx=0;
03541 int sy=0;
03542 int j=0;
03543 int i=0;
03544
03545 double* point_mask=NULL;
03546
03547 double xpos=0;
03548
03549 int xpos_min=0;
03550 int xpos_max=0;
03551 int xpos_cen=0;
03552 int ypos_cen=0;
03553
03554 int oref_qth=7;
03555 int oref_d2=0;
03556
03557 int llx=0;
03558 int lly=0;
03559 int urx=0;
03560 int ury=0;
03561 double dflux=0;
03562 double fflux=0;
03563 double scale=0;
03564 cpl_image* ima1=NULL;
03565 cpl_image* ima2=NULL;
03566
03567 cpl_table *ordertable = NULL;
03568 cpl_propertylist *otab_header = NULL;
03569 cpl_polynomial *otab_traces = NULL;
03570
03571 ima1=cpl_image_cast(ima1_in,CPL_TYPE_DOUBLE);
03572 ima2=cpl_image_cast(ima2_in,CPL_TYPE_DOUBLE);
03573 xsh_msg("list size=%d ord_min=%d ord_max=%d",
03574 qth_list->size,qth_list->absorder_min,qth_list->absorder_max);
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603 sx=cpl_image_get_size_x(ima1);
03604 sy=cpl_image_get_size_y(ima1);
03605 assure(sx==cpl_image_get_size_x(ima2),CPL_ERROR_ILLEGAL_INPUT,
03606 "illagal x size");
03607 assure(sy==cpl_image_get_size_y(ima2),CPL_ERROR_ILLEGAL_INPUT,
03608 "illagal y size");
03609
03610
03611
03612
03613 llx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].starty);
03614
03615 urx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].endy);
03616 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
03617 xpos= ( llx < urx ) ? llx: urx;
03618 xpos_min=(int)xpos;
03619
03620
03621
03622 llx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, 0);
03623
03624 urx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, sy);
03625 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
03626 xpos= ( llx > urx ) ? llx: urx;
03627 xpos_max=(int)xpos;
03628
03629 xsh_msg("xpos min=%d max=%d",xpos_min,xpos_max);
03630 ima_mask = cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
03631 point_mask=cpl_image_get_data_double(ima_mask);
03632
03633 for(j=0;j<sy;j++) {
03634 for(i=xpos_max;i<sx;i++) {
03635 point_mask[j*sx+i]=1.;
03636 }
03637 }
03638
03639
03640
03641
03642
03643 for(j=0;j<sy;j++) {
03644
03645 for(i=xpos_min;i<xpos_max;i++) {
03646
03647
03648
03649
03650
03651
03652
03653 llx= xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly, j);
03654
03655 urx= xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly,j);
03656 xpos=0.5*(llx+urx);
03657
03658 if(i > xpos) {
03659
03660 point_mask[j*sx+i] = 1.;
03661 }
03662 }
03663 }
03664
03665
03666
03667
03668
03669
03670 ypos_cen=sy/2;
03671 lly=ypos_cen-yrad;
03672 ury=ypos_cen+yrad;
03673
03674
03675
03676 xpos = xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].cenpoly, ypos_cen);
03677
03678 xpos_cen=(int)xpos;
03679 llx=xpos_cen-yrad;
03680 urx=xpos_cen+yrad;
03681 fflux=cpl_image_get_median_window(ima1,llx,lly,urx,ury);
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692 dflux=cpl_image_get_median_window(ima2,llx,lly,urx,ury);
03693
03694 scale=fflux/dflux;
03695
03696 xsh_msg("flux: n=%g d=%g s=%g",fflux,dflux,scale);
03697
03698
03699 ima_comb=cpl_image_duplicate(ima1);
03700 cpl_image_multiply(ima_comb,ima_mask);
03701 cpl_image_multiply_scalar(ima_mask,-1.);
03702 cpl_image_add_scalar(ima_mask,1.);
03703 cpl_image_multiply(ima2,ima_mask);
03704 cpl_image_multiply_scalar(ima2,scale);
03705 cpl_image_add(ima_comb,ima2);
03706
03707
03708
03709
03710 cleanup:
03711
03712 xsh_free_table(&ordertable);
03713 xsh_free_propertylist(&otab_header);
03714 xsh_free_polynomial(&otab_traces);
03715 xsh_free_image(&ima1);
03716 xsh_free_image(&ima2);
03717 xsh_free_image(&ima_mask);
03718
03719 return ima_comb;
03720 }
03721
03722
03723 cpl_error_code xsh_frame_image_save2ext(cpl_frame* frm,
03724 const char* name_o, const int ext_i,
03725 const int ext_o) {
03726 const char* name = NULL;
03727 cpl_image* ima = NULL;
03728 cpl_propertylist* plist = NULL;
03729
03730 name = cpl_frame_get_filename(frm);
03731 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, ext_i);
03732
03733 if (ext_o == 0) {
03734 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
03735 } else {
03736 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, NULL, CPL_IO_EXTEND);
03737 }
03738
03739 xsh_free_image(&ima);
03740 xsh_free_propertylist(&plist);
03741 return cpl_error_get_code();
03742
03743 }
03744
03745 cpl_error_code xsh_frame_image_add_double(cpl_frame* frm, const double value) {
03746 const char* name = NULL;
03747 name = cpl_frame_get_filename(frm);
03748 cpl_image* ima = NULL;
03749 cpl_propertylist* plist = NULL;
03750
03751 name=cpl_frame_get_filename(frm);
03752 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, 0);
03753 plist=cpl_propertylist_load(name,0);
03754
03755 cpl_image_add_scalar(ima,value);
03756 cpl_image_save(ima, name, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
03757
03758 xsh_free_image(&ima);
03759 xsh_free_propertylist(&plist);
03760 return cpl_error_get_code();
03761
03762 }
03763
03764 static cpl_error_code
03765 xsh_key_scan_mult_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
03766 {
03767
03768 int value=0;
03769 if(cpl_propertylist_has(*plist,kname) > 0) {
03770 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
03771 if(value>1) {
03772 check(cpl_propertylist_set_int(*plist,kname,value*fct));
03773 }
03774 } else {
03775 if(value>1) {
03776 cpl_propertylist_append_int(*plist,kname,1);
03777 }
03778 }
03779
03780 cleanup:
03781 return cpl_error_get_code();
03782 }
03783
03784 static cpl_error_code
03785 xsh_key_bin_div_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
03786 {
03787
03788 int value=0;
03789 if(cpl_propertylist_has(*plist,kname) > 0) {
03790 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
03791 if(value>1) {
03792 check(cpl_propertylist_set_int(*plist,kname,value/fct));
03793 }
03794 } else {
03795 if(fct>1) {
03796 cpl_propertylist_append_int(*plist,kname,1);
03797 }
03798 }
03799
03800 cleanup:
03801 return cpl_error_get_code();
03802 }
03803
03804
03805 static cpl_error_code
03806 xsh_plist_mult_by_fct(cpl_propertylist** plist,const int fctx,const int fcty)
03807 {
03808
03809 xsh_key_bin_div_by_fct(plist,XSH_WIN_BINX,fctx);
03810 xsh_key_bin_div_by_fct(plist,XSH_WIN_BINY,fcty);
03811 xsh_key_scan_mult_by_fct(plist,XSH_PRSCX,fctx);
03812 xsh_key_scan_mult_by_fct(plist,XSH_PRSCY,fcty);
03813 xsh_key_scan_mult_by_fct(plist,XSH_OVSCX,fctx);
03814 xsh_key_scan_mult_by_fct(plist,XSH_OVSCY,fcty);
03815
03816 return cpl_error_get_code();
03817 }
03818
03819
03820
03821
03822
03823
03824
03825 static cpl_image*
03826 xsh_image_div_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
03827 {
03828 int sx=0;
03829 int sy=0;
03830 int nx=0;
03831 int ny=0;
03832
03833 cpl_image* ima_datr=NULL;
03834
03835 const float* pdat=NULL;
03836 float* pdatr=NULL;
03837
03838 int i=0;
03839 int j=0;
03840 int k=0;
03841 int m=0;
03842
03843 check(sx=cpl_image_get_size_x(ima_dat));
03844 check(sy=cpl_image_get_size_y(ima_dat));
03845
03846 xsh_msg("org image size dat: %d %d",sx,sy);
03847 nx=sx/fctx;
03848 ny=sy/fcty;
03849
03850 check(ima_datr=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
03851 xsh_msg("new image size dat: %d %d",nx,ny);
03852 check(pdat=cpl_image_get_data_float_const(ima_dat));
03853 check(pdatr=cpl_image_get_data_float(ima_datr));
03854
03855
03856 for (j = 0; j < ny; j++) {
03857 for (m = 0; m < fcty; m++) {
03858 for (i = 0; i < nx; i++) {
03859 for (k = 0; k < fctx; k++) {
03860
03861
03862
03863
03864 pdatr[i + j * nx] += pdat[i * fctx + k + (j * fcty + m) * fctx * nx];
03865 }
03866 }
03867 }
03868
03869 pdatr[i + j * nx] /= (fctx * fcty);
03870
03871 }
03872
03873 cleanup:
03874 return ima_datr;
03875
03876 }
03877
03878
03879
03880
03881 static cpl_image*
03882 xsh_image_mult_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
03883 {
03884
03885 int nx=0;
03886 int ny=0;
03887
03888 cpl_image* ima_datr=NULL;
03889
03890 const float* pdat=NULL;
03891 float* pdatr=NULL;
03892
03893 int i=0;
03894 int j=0;
03895 int k=0;
03896 int m=0;
03897
03898 check(nx=cpl_image_get_size_x(ima_dat));
03899 check(ny=cpl_image_get_size_y(ima_dat));
03900
03901 xsh_msg("org image size dat: %d %d",nx,ny);
03902 check(ima_datr=cpl_image_new(fctx*nx,fcty*ny,CPL_TYPE_FLOAT));
03903 xsh_msg("new image size dat: %d %d",fctx*nx,fcty*ny);
03904
03905 check(pdat=cpl_image_get_data_float_const(ima_dat));
03906 check(pdatr=cpl_image_get_data_float(ima_datr));
03907
03908 for(j=0;j<ny;j++) {
03909 for(m=0;m<fcty;m++) {
03910 for(i=0;i<nx;i++) {
03911 for(k=0;k<fctx;k++) {
03912
03913
03914 pdatr[i*fctx+k+(j*fcty+m)*fctx*nx]=pdat[i+j*nx];
03915 }
03916 }
03917 }
03918 }
03919
03920 cleanup:
03921 return ima_datr;
03922 }
03923
03924
03925 cpl_frame*
03926 xsh_frame_image_div_by_fct(cpl_frame* frm,const int fctx, const int fcty)
03927 {
03928
03929 const char* name=NULL;
03930 cpl_propertylist* plist=NULL;
03931 cpl_propertylist* hext=NULL;
03932 cpl_image* ima_dat=NULL;
03933 cpl_image* ima_datr=NULL;
03934
03935 int next=0;
03936
03937 int prscx=0;
03938 int prscy=0;
03939 int ovscx=0;
03940 int ovscy=0;
03941 int kk=0;
03942 cpl_frame* frm_cor=NULL;
03943 const char* tag=NULL;
03944
03945 const char* basename=NULL;
03946 char new_name[256];
03947
03948 check(name=cpl_frame_get_filename(frm));
03949 check(tag=cpl_frame_get_tag(frm));
03950 next=cpl_frame_get_nextensions(frm);
03951 check(plist=cpl_propertylist_load(name,0));
03952
03953 check(prscx=xsh_pfits_get_prscx(plist));
03954 check(prscy=xsh_pfits_get_prscy(plist));
03955 check(ovscx=xsh_pfits_get_ovscx(plist));
03956 check(ovscy=xsh_pfits_get_ovscy(plist));
03957 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
03958
03959 xsh_plist_div_by_fct(&plist,fctx,fcty);
03960
03961 check(basename=xsh_get_basename(name));
03962 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
03963 xsh_msg("new_name=%s",new_name);
03964
03965 for(kk=0;kk<=next;kk++) {
03966
03967 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
03968 check(hext=cpl_propertylist_load(name,kk));
03969 ima_datr=xsh_image_div_by_fct(ima_dat,fctx,fcty);
03970
03971 if(kk==0) {
03972 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
03973 CPL_IO_DEFAULT));
03974 } else if (kk==1) {
03975 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
03976 CPL_IO_EXTEND));
03977 } else if (kk==2) {
03978 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
03979 CPL_IO_EXTEND));
03980 }
03981
03982 xsh_free_image(&ima_dat);
03983 xsh_free_image(&ima_datr);
03984 xsh_free_propertylist(&plist);
03985 xsh_free_propertylist(&hext);
03986 }
03987 frm_cor=cpl_frame_new();
03988 cpl_frame_set_filename(frm_cor,new_name);
03989 check(cpl_frame_set_tag(frm_cor,tag));
03990 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
03991 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
03992 xsh_add_temporary_file(new_name);
03993
03994 cleanup:
03995
03996 xsh_free_image(&ima_dat);
03997 xsh_free_image(&ima_datr);
03998 xsh_free_propertylist(&plist);
03999 xsh_free_propertylist(&hext);
04000
04001 return frm_cor;
04002 }
04003
04004 cpl_frame*
04005 xsh_frame_image_mult_by_fct(cpl_frame* frm,const int fctx, const int fcty)
04006 {
04007
04008 const char* name=NULL;
04009 cpl_propertylist* plist=NULL;
04010 cpl_propertylist* hext=NULL;
04011 cpl_image* ima_dat=NULL;
04012 cpl_image* ima_datr=NULL;
04013
04014 int next=0;
04015
04016 int prscx=0;
04017 int prscy=0;
04018 int ovscx=0;
04019 int ovscy=0;
04020 int kk=0;
04021 cpl_frame* frm_cor=NULL;
04022 const char* tag=NULL;
04023 const char* basename=NULL;
04024 char new_name[256];
04025
04026 check(name=cpl_frame_get_filename(frm));
04027 check(tag=cpl_frame_get_tag(frm));
04028 next=cpl_frame_get_nextensions(frm);
04029 check(plist=cpl_propertylist_load(name,0));
04030
04031 check(prscx=xsh_pfits_get_prscx(plist));
04032 check(prscy=xsh_pfits_get_prscy(plist));
04033 check(ovscx=xsh_pfits_get_ovscx(plist));
04034 check(ovscy=xsh_pfits_get_ovscy(plist));
04035
04036 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
04037 check(basename=xsh_get_basename(name));
04038 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
04039 xsh_msg("new_name=%s",new_name);
04040
04041 xsh_plist_mult_by_fct(&plist,fctx,fcty);
04042 for(kk=0;kk<=next;kk++) {
04043
04044 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
04045 check(hext=cpl_propertylist_load(name,kk));
04046 ima_datr=xsh_image_mult_by_fct(ima_dat,fctx,fcty);
04047 if(kk==0) {
04048 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
04049 CPL_IO_DEFAULT));
04050 } else if (kk==1) {
04051 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
04052 CPL_IO_EXTEND));
04053 } else if (kk==2) {
04054 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
04055 CPL_IO_EXTEND));
04056 }
04057
04058 xsh_free_image(&ima_dat);
04059 xsh_free_image(&ima_datr);
04060 xsh_free_propertylist(&plist);
04061 xsh_free_propertylist(&hext);
04062
04063 }
04064
04065 frm_cor=cpl_frame_new();
04066 cpl_frame_set_filename(frm_cor,new_name);
04067 cpl_frame_set_tag(frm_cor,tag);
04068 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
04069 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
04070 xsh_add_temporary_file(new_name);
04071 cleanup:
04072 return frm_cor;
04073
04074 }
04075