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 float* pdata=NULL;
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 pdata=cpl_image_get_data_float(out);
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 for ( row = lly ; row <= ury ; row++ )
01654 {
01655 for ( col = llx ; col <= urx ; col++ )
01656 {
01657 if ( !isnan(pim[col + row*im_lx]) )
01658 {
01659 pix_array[n] = pim[col + row*im_lx] ;
01660 n++ ;
01661 }
01662 }
01663 }
01664
01665 npix = n;
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676 if ( FLT_MAX == (retstats->cleanmean = xsh_clean_mean(pix_array,
01677 npix, loReject, hiReject)) )
01678 {
01679 xsh_msg_error("xsh_clean_mean() did not work!") ;
01680 cpl_free(retstats) ;
01681 cpl_free(pix_array) ;
01682 return NULL ;
01683 }
01684
01685
01686
01687 lo_n = (int) (loReject / 100. * (float)npix) ;
01688 hi_n = (int) (hiReject / 100. * (float)npix) ;
01689 pix_sum = 0. ;
01690 sqr_sum = 0. ;
01691 n = 0 ;
01692 for ( i = lo_n ; i <= npix - hi_n ; i++ )
01693 {
01694 pix_sum += (double)pix_array[i] ;
01695 sqr_sum += ((double)pix_array[i] * (double)pix_array[i]) ;
01696 n++ ;
01697 }
01698
01699 if ( n == 0 )
01700 {
01701 xsh_msg_error("number of clean pixels is zero!") ;
01702 cpl_free(retstats) ;
01703 cpl_free(pix_array) ;
01704 return NULL ;
01705 }
01706 retstats -> npix = n ;
01707 pix_sum /= (double) n ;
01708 sqr_sum /= (double) n ;
01709 retstats -> cleanstdev = (float)sqrt(sqr_sum - pix_sum * pix_sum) ;
01710 cpl_free (pix_array) ;
01711 return retstats ;
01712 }
01713
01714 #define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }
01715 #define PIX_STACK_SIZE 50
01716
01728 void
01729 xsh_pixel_qsort(pixelvalue *pix_arr, int npix)
01730 {
01731 int i,
01732 ir,
01733 j,
01734 k,
01735 l;
01736 int i_stack[PIX_STACK_SIZE*sizeof(pixelvalue)] ;
01737 int j_stack ;
01738 pixelvalue a ;
01739
01740 ir = npix ;
01741 l = 1 ;
01742 j_stack = 0 ;
01743 for (;;) {
01744 if (ir-l < 7) {
01745 for (j=l+1 ; j<=ir ; j++) {
01746 a = pix_arr[j-1];
01747 for (i=j-1 ; i>=1 ; i--) {
01748 if (pix_arr[i-1] <= a) break;
01749 pix_arr[i] = pix_arr[i-1];
01750 }
01751 pix_arr[i] = a;
01752 }
01753 if (j_stack == 0) break;
01754 ir = i_stack[j_stack-- -1];
01755 l = i_stack[j_stack-- -1];
01756 } else {
01757 k = (l+ir) >> 1;
01758 PIX_SWAP(pix_arr[k-1], pix_arr[l])
01759 if (pix_arr[l] > pix_arr[ir-1]) {
01760 PIX_SWAP(pix_arr[l], pix_arr[ir-1])
01761 }
01762 if (pix_arr[l-1] > pix_arr[ir-1]) {
01763 PIX_SWAP(pix_arr[l-1], pix_arr[ir-1])
01764 }
01765 if (pix_arr[l] > pix_arr[l-1]) {
01766 PIX_SWAP(pix_arr[l], pix_arr[l-1])
01767 }
01768 i = l+1;
01769 j = ir;
01770 a = pix_arr[l-1];
01771 for (;;) {
01772 do i++; while (pix_arr[i-1] < a);
01773 do j--; while (pix_arr[j-1] > a);
01774 if (j < i) break;
01775 PIX_SWAP(pix_arr[i-1], pix_arr[j-1]);
01776 }
01777 pix_arr[l-1] = pix_arr[j-1];
01778 pix_arr[j-1] = a;
01779 j_stack += 2;
01780 if (j_stack > PIX_STACK_SIZE) {
01781 xsh_msg_error("stack too small : aborting");
01782 exit(-2001) ;
01783 }
01784 if (ir-i+1 >= j-l) {
01785 i_stack[j_stack-1] = ir;
01786 i_stack[j_stack-2] = i;
01787 ir = j-1;
01788 } else {
01789 i_stack[j_stack-1] = j-1;
01790 i_stack[j_stack-2] = l;
01791 l = i;
01792 }
01793 }
01794 }
01795 }
01796 #undef PIX_STACK_SIZE
01797 #undef PIX_SWAP
01798
01815 float xsh_clean_mean( float * array,
01816 int n_elements,
01817 float throwaway_low,
01818 float throwaway_high )
01819 {
01820 int i, n ;
01821 int lo_n, hi_n ;
01822 float sum ;
01823
01824 if ( array == NULL )
01825 {
01826 xsh_msg_error(" no array given in xsh_clean_mean!") ;
01827 return FLT_MAX ;
01828 }
01829
01830 if ( n_elements <= 0 )
01831 {
01832 xsh_msg_error("wrong number of elements given") ;
01833 return FLT_MAX ;
01834 }
01835
01836 if ( throwaway_low < 0. || throwaway_high < 0. ||
01837 throwaway_low + throwaway_high >= 100. )
01838 {
01839 xsh_msg_error("wrong throw away percentage given!") ;
01840 return FLT_MAX ;
01841 }
01842
01843 lo_n = (int) (throwaway_low * (float)n_elements / 100.) ;
01844 hi_n = (int) (throwaway_high * (float)n_elements / 100.) ;
01845
01846
01847 xsh_pixel_qsort( array, n_elements ) ;
01848
01849 n = 0 ;
01850 sum = 0. ;
01851 for ( i = lo_n ; i < n_elements - hi_n ; i++ )
01852 {
01853 if ( !isnan(array[i]) )
01854 {
01855 sum += array[i] ;
01856 n++ ;
01857 }
01858 }
01859 if ( n == 0 )
01860 {
01861 return FLAG ;
01862 }
01863 else
01864 {
01865 return sum/(float)n ;
01866 }
01867 }
01868
01869
01883
01884
01885 cpl_image *
01886 xsh_image_smooth_fft(cpl_image * inp, const int fx, const int fy)
01887 {
01888
01889 int sx=0;
01890 int sy=0;
01891
01892 cpl_image* out=NULL;
01893 cpl_image* im_re=NULL;
01894 cpl_image* im_im=NULL;
01895 cpl_image* ifft_re=NULL;
01896 cpl_image* ifft_im=NULL;
01897 cpl_image* filter=NULL;
01898
01899
01900 cknull_msg(inp,"Null in put image, exit");
01901 check(im_re = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
01902 check(im_im = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
01903
01904
01905 check(cpl_image_fft(im_re,im_im,CPL_FFT_DEFAULT));
01906 check(sx=cpl_image_get_size_x(inp));
01907 check(sy=cpl_image_get_size_y(inp));
01908
01909
01910
01911 check(filter = xsh_gen_lowpass(sx,sy,fx,fy));
01912
01913
01914 cpl_image_multiply(im_re,filter);
01915 cpl_image_multiply(im_im,filter);
01916
01917 xsh_free_image(&filter);
01918
01919 check(ifft_re = cpl_image_duplicate(im_re));
01920 check(ifft_im = cpl_image_duplicate(im_im));
01921
01922 xsh_free_image(&im_re);
01923 xsh_free_image(&im_im);
01924
01925
01926 check(cpl_image_fft(ifft_re,ifft_im,CPL_FFT_INVERSE));
01927 check(out = cpl_image_cast(ifft_re, CPL_TYPE_FLOAT));
01928
01929 cleanup:
01930
01931 xsh_free_image(&ifft_re);
01932 xsh_free_image(&ifft_im);
01933 xsh_free_image(&filter);
01934 xsh_free_image(&im_re);
01935 xsh_free_image(&im_im);
01936
01937 if(cpl_error_get_code() != CPL_ERROR_NONE) {
01938 return NULL;
01939 } else {
01940 return out;
01941 }
01942
01943 }
01944
01945
01961
01962 static cpl_image *
01963 xsh_gen_lowpass(const int xs,
01964 const int ys,
01965 const double sigma_x,
01966 const double sigma_y)
01967 {
01968
01969 int i= 0.0;
01970 int j= 0.0;
01971 int hlx= 0.0;
01972 int hly = 0.0;
01973 double x= 0.0;
01974 double y= 0.0;
01975 double gaussval= 0.0;
01976 double inv_sigma_x=1./sigma_x;
01977 double inv_sigma_y=1./sigma_y;
01978
01979 float *data;
01980
01981 cpl_image *lowpass_image=NULL;
01982 int err_no=0;
01983
01984
01985 lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
01986 if (lowpass_image == NULL) {
01987 xsh_msg_error("Cannot generate lowpass filter <%s>",
01988 cpl_error_get_message());
01989 return NULL;
01990 }
01991
01992 hlx = xs/2;
01993 hly = ys/2;
01994
01995 data = cpl_image_get_data_float(lowpass_image);
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 data[0] = 1.0;
02008
02009
02010 for (i=1 ; i<=hlx ; i++) {
02011 x = i * inv_sigma_x;
02012 gaussval = exp(-0.5*x*x);
02013 data[i] = gaussval;
02014 data[xs-i] = gaussval;
02015 }
02016
02017 for (j=1; j<=hly ; j++) {
02018 y = j * inv_sigma_y;
02019
02020 data[j*xs] = exp(-0.5*y*y);
02021 data[(ys-j)*xs] = exp(-0.5*y*y);
02022
02023 for (i=1 ; i<=hlx ; i++) {
02024
02025 x = i * inv_sigma_x;
02026 gaussval = exp (-0.5*(x*x+y*y));
02027 data[j*xs+i] = gaussval;
02028 data[(j+1)*xs-i] = gaussval;
02029 data[(ys-j)*xs+i] = gaussval;
02030 data[(ys+1-j)*xs-i] = gaussval;
02031
02032 }
02033 }
02034
02035
02036
02037
02038
02039 if(err_no != 0)
02040 err_no = 0;
02041
02042 return lowpass_image;
02043 }
02044
02045
02046
02060
02061
02062 cpl_image *
02063 xsh_image_smooth_mean_y(cpl_image * inp, const int r)
02064 {
02065
02066
02067 double* pinp = NULL;
02068 double* pout = NULL;
02069 int sx = 0;
02070 int sy = 0;
02071 register int i = 0;
02072 register int j = 0;
02073 register int k = 0;
02074 register int pix=0;
02075 cpl_image* out=NULL;
02076
02077 XSH_ASSURE_NOT_NULL( inp);
02078 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
02079 check(sx = cpl_image_get_size_x(inp));
02080 check(sy = cpl_image_get_size_y(inp));
02081 check(pinp = cpl_image_get_data_double(inp));
02082 check(pout = cpl_image_get_data_double(out));
02083 for( j=r; j<sy-r; j++) {
02084 pix=j*sx+i;
02085 for( i=0; i<sx; i++) {
02086 for( k=-r; k<r; k++) {
02087 pout[pix] += pinp[pix+k*sx];
02088 }
02089 pout[pix]/=(2*r);
02090 }
02091 }
02092
02093 cleanup:
02094 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02095 xsh_free_image( &out);
02096 }
02097 return out;
02098 }
02099
02100
02101
02115
02116
02117 cpl_image *
02118 xsh_image_smooth_median_y(cpl_image * inp, const int r)
02119 {
02120
02121
02122 double* pout=NULL;
02123 int sx=0;
02124 int sy=0;
02125 int i=0;
02126 int j=0;
02127
02128 cpl_image* out=NULL;
02129
02130
02131 cknull_msg(inp,"Null in put image, exit");
02132
02133 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
02134 check(sx=cpl_image_get_size_x(inp));
02135 check(sy=cpl_image_get_size_y(inp));
02136 check(pout=cpl_image_get_data_double(out));
02137
02138 for(j=r+1;j<sy-r;j++) {
02139 for(i=1;i<sx;i++) {
02140 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i,j+r);
02141 }
02142 }
02143
02144 cleanup:
02145
02146 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02147 return NULL;
02148 } else {
02149 return out;
02150
02151 }
02152
02153 }
02154
02155
02156
02170
02171
02172 cpl_image *
02173 xsh_image_smooth_mean_x( cpl_image * inp, const int r)
02174 {
02175
02176 double* pinp=NULL;
02177 double* pout=NULL;
02178 int sx=0;
02179 int sy=0;
02180 int i=0;
02181 int j=0;
02182 int k=0;
02183
02184 cpl_image* out=NULL;
02185
02186
02187 XSH_ASSURE_NOT_NULL( inp);
02188 check( out = cpl_image_cast( inp, CPL_TYPE_DOUBLE));
02189 check( sx=cpl_image_get_size_x(inp));
02190 check( sy=cpl_image_get_size_y(inp));
02191 check( pinp=cpl_image_get_data_double(inp));
02192 check( pout=cpl_image_get_data_double(out));
02193 for(j=0;j<sy;j++) {
02194 for(i=r;i<sx-r;i++) {
02195 for(k=-r;k<r;k++) {
02196 pout[j*sx+i]+=pinp[j*sx+i+k];
02197 }
02198 pout[j*sx+i]/=2*r;
02199 }
02200 }
02201
02202 cleanup:
02203
02204 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02205 return NULL;
02206 } else {
02207 return out;
02208
02209 }
02210
02211 }
02212
02213
02214
02228
02229
02230 cpl_image *
02231 xsh_image_smooth_median_x(cpl_image * inp, const int r)
02232 {
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242 float* pout=NULL;
02243 int sx=0;
02244 int sy=0;
02245 int i=0;
02246 int j=0;
02247
02248 cpl_image* out=NULL;
02249
02250
02251 cknull_msg(inp,"Null in put image, exit");
02252
02253 check(out=cpl_image_cast(inp,CPL_TYPE_FLOAT));
02254 check(sx=cpl_image_get_size_x(inp));
02255 check(sy=cpl_image_get_size_y(inp));
02256 check(pout=cpl_image_get_data_float(out));
02257
02258 for(j=1;j<sy;j++) {
02259 for(i=r+1;i<sx-r;i++) {
02260 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j);
02261 }
02262 }
02263
02264 cleanup:
02265
02266 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02267 return NULL;
02268 } else {
02269 return out;
02270
02271 }
02272
02273 }
02274
02275
02276
02277
02291
02292
02293 cpl_image *
02294 xsh_image_smooth_median_xy(cpl_image * inp, const int r)
02295 {
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305 double* pout=NULL;
02306 int sx=0;
02307 int sy=0;
02308 int i=0;
02309 int j=0;
02310
02311 cpl_image* out=NULL;
02312
02313
02314 cknull_msg(inp,"Null in put image, exit");
02315
02316 check(out=cpl_image_cast(inp,CPL_TYPE_DOUBLE));
02317 check(sx=cpl_image_get_size_x(inp));
02318 check(sy=cpl_image_get_size_y(inp));
02319 check(pout=cpl_image_get_data_double(out));
02320
02321 for(j=r+1;j<sy-r;j++) {
02322 for(i=r+1;i<sx-r;i++) {
02323 pout[j*sx+i]=cpl_image_get_median_window(inp,i,j,i+r,j+r);
02324 }
02325 }
02326
02327 cleanup:
02328
02329 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02330 return NULL;
02331 } else {
02332 return out;
02333
02334 }
02335
02336 }
02337
02338
02348
02349
02350 cpl_error_code
02351 xsh_image_clean_badpixel(cpl_frame* in)
02352 {
02353
02354
02355 cpl_image* ima=NULL;
02356 cpl_image* err=NULL;
02357 cpl_image* qua=NULL;
02358 cpl_propertylist* hima=NULL;
02359 cpl_propertylist* herr=NULL;
02360 cpl_propertylist* hqua=NULL;
02361
02362
02363 const char* name=NULL;
02364 double* pima=NULL;
02365 int* pqua=NULL;
02366 int nx=0;
02367 int ny=0;
02368 int i=0;
02369 int j=0;
02370 int rx=5;
02371 int ry=5;
02372 int ip=0;
02373 int jp=0;
02374
02375 name=cpl_frame_get_filename(in);
02376 hima=cpl_propertylist_load(name,0);
02377 herr=cpl_propertylist_load(name,1);
02378 hqua=cpl_propertylist_load(name,2);
02379 ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0);
02380 err=cpl_image_load(name,CPL_TYPE_DOUBLE,0,1);
02381 qua=cpl_image_load(name,CPL_TYPE_INT,0,2);
02382
02383 nx=cpl_image_get_size_x(ima);
02384 ny=cpl_image_get_size_y(ima);
02385
02386 pima=cpl_image_get_data_double(ima);
02387 pqua=cpl_image_get_data_int(qua);
02388
02389 for(j=ry;j<ny-ry;j++) {
02390 jp=j++;
02391 for(i=rx;i<nx-rx;i++) {
02392 ip=i++;
02393 if(pqua[i+j*nx]!=0) {
02394 pima[i+j*nx]=cpl_image_get_median_window(ima,i-rx,j-ry,i+rx,j+ry);
02395 }
02396 }
02397 }
02398 check(cpl_image_save(ima,name,XSH_PRE_DATA_BPP,hima,CPL_IO_DEFAULT));
02399 check(cpl_image_save(err,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
02400 check(cpl_image_save(qua,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
02401
02402 cleanup:
02403 xsh_free_image(&ima);
02404 xsh_free_image(&err);
02405 xsh_free_image(&qua);
02406 xsh_free_propertylist(&hima);
02407 xsh_free_propertylist(&herr);
02408 xsh_free_propertylist(&hqua);
02409
02410 return cpl_error_get_code();
02411
02412 }
02413
02414
02415
02429
02430
02431 double
02432 xsh_image_fit_gaussian_max_pos_x_window(const cpl_image* ima,
02433 const int llx,
02434 const int urx,
02435 const int ypos)
02436 {
02437
02438
02439 XSH_GAUSSIAN_FIT fit_res;
02440 int i=0;
02441 int nelem=0;
02442 int ix=0;
02443 int iy=ypos;
02444
02445 double dy=0;
02446 cpl_vector* pix_pos=NULL;
02447 cpl_vector* pix_val=NULL;
02448 double x_centroid=0;
02449
02450
02451 nelem=urx-llx+1;
02452 check( pix_pos = cpl_vector_new( nelem ) ) ;
02453 check( pix_val = cpl_vector_new( nelem ) ) ;
02454
02455
02456 for( i = 0, ix = llx ; ix <= urx ; ix++, i++, dy += 1. ) {
02457 int rej ;
02458 double value ;
02459
02460 cpl_error_reset() ;
02461 value = cpl_image_get(ima , ix, iy, &rej ) ;
02462 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02463 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
02464 cpl_error_reset() ;
02465 continue ;
02466 }
02467 cpl_vector_set( pix_val, i, value ) ;
02468 cpl_vector_set( pix_pos, i, dy ) ;
02469 }
02470
02471 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
02472 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02473 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, iy ) ;
02474 cpl_error_reset() ;
02475 x_centroid=cpl_image_get_centroid_x_window(ima,llx,ypos,urx,ypos);
02476
02477
02478 } else {
02479
02480 x_centroid=llx+fit_res.peakpos;
02481 }
02482
02483 cleanup:
02484 xsh_free_vector(&pix_pos);
02485 xsh_free_vector(&pix_val);
02486
02487 return x_centroid;
02488 }
02489
02490
02504
02505
02506 static double
02507 xsh_image_fit_gaussian_max_pos_y_window(const cpl_image* ima,
02508 const int lly,
02509 const int ury,
02510 const int xpos)
02511 {
02512
02513
02514 XSH_GAUSSIAN_FIT fit_res;
02515 int j=0;
02516 int nelem=0;
02517 int jy=0;
02518 int jx=xpos;
02519
02520 double dy=0;
02521 cpl_vector* pix_pos=NULL;
02522 cpl_vector* pix_val=NULL;
02523 double y_centroid=0;
02524
02525
02526 nelem=ury-lly+1;
02527 check( pix_pos = cpl_vector_new( nelem ) ) ;
02528 check( pix_val = cpl_vector_new( nelem ) ) ;
02529
02530
02531 for( j = 0, jy = lly ; jy <= ury ; jy++, j++, dy += 1. ) {
02532 int rej ;
02533 double value ;
02534
02535 cpl_error_reset() ;
02536 value = cpl_image_get(ima , jx, jy, &rej ) ;
02537 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02538 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
02539 cpl_error_reset() ;
02540 continue ;
02541 }
02542 cpl_vector_set( pix_val, j, value ) ;
02543 cpl_vector_set( pix_pos, j, dy ) ;
02544 }
02545
02546 xsh_vector_fit_gaussian( pix_pos, pix_val, &fit_res );
02547 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
02548 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", jx, jy ) ;
02549 cpl_error_reset() ;
02550 y_centroid=cpl_image_get_centroid_y_window(ima,xpos,lly,xpos,ury);
02551
02552
02553 } else {
02554
02555 y_centroid=lly+fit_res.peakpos;
02556 }
02557
02558 cleanup:
02559 xsh_free_vector(&pix_pos);
02560 xsh_free_vector(&pix_val);
02561
02562 return y_centroid;
02563 }
02564
02565
02566
02583
02584
02585 static cpl_table*
02586 xsh_image_qc_trace_window(cpl_image* data_ima,cpl_propertylist* head,
02587 const int hsize, const int method)
02588 {
02589
02590 cpl_table* table=NULL;
02591 int i=0;
02592
02593 int naxis1=0;
02594 int naxis2=0;
02595 cpl_size mx=0;
02596 cpl_size my=0;
02597
02598 int lly=0;
02599 int ury=0;
02600 int llx=0;
02601 int* px=NULL;
02602 double* pcy=NULL;
02603 double* pwav=NULL;
02604 double crval1=0;
02605 double cdelt1=0;
02606
02607 crval1=xsh_pfits_get_crval1(head);
02608 cdelt1=xsh_pfits_get_cdelt1(head);
02609
02610 naxis1=cpl_image_get_size_x(data_ima);
02611 naxis2=cpl_image_get_size_y(data_ima);
02612
02613 table=cpl_table_new(naxis1);
02614 cpl_table_new_column(table,"X",CPL_TYPE_INT);
02615 cpl_table_new_column(table,"WAVELENGTH",CPL_TYPE_DOUBLE);
02616 cpl_table_new_column(table,"POS",CPL_TYPE_DOUBLE);
02617
02618 cpl_table_fill_column_window_int(table,"X",0,naxis1,0);
02619 cpl_table_fill_column_window_double(table,"WAVELENGTH",0,naxis1,0.);
02620 cpl_table_fill_column_window_double(table,"POS",0,naxis1,0.);
02621
02622 px=cpl_table_get_data_int(table,"X");
02623 pwav=cpl_table_get_data_double(table,"WAVELENGTH");
02624 pcy=cpl_table_get_data_double(table,"POS");
02625
02626 for(i=0;i<naxis1;i++) {
02627 px[i]=i;
02628 pwav[i]=crval1+cdelt1*i;
02629 llx=i+1;
02630 check(cpl_image_get_maxpos_window(data_ima,llx,1,llx,naxis2,&mx,&my));
02631 lly=(my-hsize>0) ? my-hsize:1;
02632 ury=(my+hsize<=naxis2) ? my+hsize:naxis2;
02633 if(method == 0 ) {
02634 pcy[i]=xsh_image_fit_gaussian_max_pos_y_window(data_ima,lly,ury,llx);
02635 } else {
02636 check(pcy[i]=cpl_image_get_centroid_y_window(data_ima,llx,lly,llx,ury));
02637 }
02638 }
02639
02640 cleanup:
02641
02642 return table;
02643 }
02644
02663
02664
02665 cpl_frame*
02666 xsh_frame_image_qc_trace_window(cpl_frame* frm_ima,xsh_instrument* instrument,
02667 const char* suffix,const int hsize, const int method)
02668 {
02669
02670 cpl_frame* result=NULL;
02671 cpl_table* table=NULL;
02672 cpl_image* data_ima=NULL;
02673 const char* name=NULL;
02674
02675 cpl_propertylist* plist=NULL;
02676 char fname[80];
02677 char tag[50];
02678
02679 check(name=cpl_frame_get_filename(frm_ima));
02680
02681 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0));
02682 plist=cpl_propertylist_load(name,0);
02683
02684
02685 check(table=xsh_image_qc_trace_window(data_ima,plist,hsize,method));
02686
02687 sprintf(tag,"MERGE3D_TRACE_OBJ_%s_%s",
02688 xsh_instrument_arm_tostring( instrument),suffix);
02689 sprintf(fname,"%s.fits",tag);
02690
02691 check(cpl_table_save(table,plist,NULL,fname,CPL_IO_DEFAULT));
02692
02693 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
02694 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
02695
02696 cleanup:
02697
02698 xsh_free_propertylist(&plist);
02699 xsh_free_table(&table);
02700 xsh_free_image(&data_ima);
02701
02702 return result;
02703 }
02704
02723
02724
02725 cpl_frame*
02726 xsh_frame_image_ext_qc_trace_window(cpl_frame* frm_ima,
02727 xsh_instrument* instrument,
02728 const char* suffix,
02729 const int hsize,
02730 const int method)
02731 {
02732
02733 cpl_frame* result=NULL;
02734 cpl_table* table=NULL;
02735 cpl_table* table_tot=NULL;
02736
02737 cpl_image* data_ima=NULL;
02738 const char* name=NULL;
02739
02740 cpl_propertylist* phead=NULL;
02741 cpl_propertylist* xhead=NULL;
02742
02743 char fname[80];
02744 char tag[50];
02745 int nbext=0;
02746 int k=0;
02747 int nrow=0;
02748 xsh_msg("Trace object position");
02749 check(name=cpl_frame_get_filename(frm_ima));
02750 nbext=cpl_frame_get_nextensions( frm_ima);
02751
02752 table_tot=cpl_table_new(0);
02753 phead=cpl_propertylist_load(name,0);
02754 for(k=0;k<nbext;k+=3){
02755 nrow=cpl_table_get_nrow(table_tot);
02756
02757 check(data_ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,k));
02758 xhead=cpl_propertylist_load(name,k);
02759
02760 check(table=xsh_image_qc_trace_window(data_ima,xhead,hsize,method));
02761 if(k==0) check(cpl_table_copy_structure(table_tot,table));
02762 cpl_table_insert(table_tot,table,nrow);
02763 xsh_free_propertylist(&xhead);
02764 xsh_free_table(&table);
02765 xsh_free_image(&data_ima);
02766 }
02767 sprintf(tag,"OBJ_POS_ORD_%s_%s",
02768 xsh_instrument_arm_tostring( instrument),suffix);
02769 sprintf(fname,"%s.fits",tag);
02770
02771 check(cpl_table_save(table_tot,phead,NULL,fname,CPL_IO_DEFAULT));
02772
02773 result=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
02774 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
02775
02776 cleanup:
02777
02778 xsh_free_propertylist(&phead);
02779 xsh_free_propertylist(&xhead);
02780 xsh_free_table(&table);
02781 xsh_free_table(&table_tot);
02782 xsh_free_image(&data_ima);
02783
02784 return result;
02785 }
02786
02787
02801
02802
02803 static cpl_error_code
02804 xsh_util_compute_qc_residuals(cpl_table* table,
02805 xsh_instrument* instrument,
02806 cpl_propertylist* plist)
02807 {
02808 cpl_table* qc_table=NULL;
02809 double res_min=0;
02810 double res_max=0;
02811 double res_med=0;
02812 double res_avg=0;
02813 double res_rms=0;
02814 double wmin=0;
02815 double wmax=0;
02816 int nsel=0;
02817
02818 if( xsh_instrument_get_arm(instrument) == XSH_ARM_UVB) {
02819 wmin=350;
02820 wmax=540;
02821 } else if( xsh_instrument_get_arm(instrument) == XSH_ARM_VIS){
02822 wmin=580;
02823 wmax=950;
02824 } else {
02825 wmin=1000;
02826 wmax=2200;
02827 }
02828
02829 check(nsel=cpl_table_and_selected_double(table,"WAVELENGTH",CPL_GREATER_THAN,wmin));
02830 check(nsel=cpl_table_and_selected_double(table,"WAVELENGTH",CPL_LESS_THAN,wmax));
02831 check(qc_table=cpl_table_extract_selected(table));
02832 check(cpl_table_select_all(table));
02833
02834
02835 check(res_min=cpl_table_get_column_min(qc_table,"RES12"));
02836 check(res_max=cpl_table_get_column_max(qc_table,"RES12"));
02837 check(res_avg=cpl_table_get_column_mean(qc_table,"RES12"));
02838 check(res_med=cpl_table_get_column_median(qc_table,"RES12"));
02839 check(res_rms=cpl_table_get_column_stdev(qc_table,"RES12"));
02840
02841 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MIN,res_min);
02842 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MIN,"Minimum residuals");
02843 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MAX,res_max);
02844 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MAX,"Maximum residuals");
02845 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_AVG,res_avg);
02846 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_AVG,"Mean residuals");
02847
02848 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_MED,res_med);
02849 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_MED,"Median residuals");
02850 cpl_propertylist_append_double(plist,XSH_QC_TRACE12_RMS,res_rms);
02851 cpl_propertylist_set_comment(plist,XSH_QC_TRACE12_RMS,"Stdev residuals");
02852
02853 res_min=cpl_table_get_column_min(qc_table,"RES32");
02854 res_max=cpl_table_get_column_max(qc_table,"RES32");
02855 res_avg=cpl_table_get_column_mean(qc_table,"RES32");
02856 res_med=cpl_table_get_column_median(qc_table,"RES32");
02857 res_rms=cpl_table_get_column_stdev(qc_table,"RES32");
02858
02859 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MIN,res_min);
02860 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MIN,"Minimum residuals");
02861 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MAX,res_max);
02862 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MAX,"Maximum residuals");
02863 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_AVG,res_avg);
02864 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_AVG,"Mean residuals");
02865
02866 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_MED,res_med);
02867 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_MED,"Median residuals");
02868 cpl_propertylist_append_double(plist,XSH_QC_TRACE32_RMS,res_rms);
02869 cpl_propertylist_set_comment(plist,XSH_QC_TRACE32_RMS,"Stdev residuals");
02870
02871 res_min=cpl_table_get_column_min(qc_table,"RES13");
02872 res_max=cpl_table_get_column_max(qc_table,"RES13");
02873 res_avg=cpl_table_get_column_mean(qc_table,"RES13");
02874 res_med=cpl_table_get_column_median(qc_table,"RES13");
02875 res_rms=cpl_table_get_column_stdev(qc_table,"RES13");
02876
02877 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MIN,res_min);
02878 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MIN,"Minimum residuals");
02879 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MAX,res_max);
02880 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MAX,"Maximum residuals");
02881 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_AVG,res_avg);
02882 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_AVG,"Mean residuals");
02883
02884 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_MED,res_med);
02885 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_MED,"Median residuals");
02886 cpl_propertylist_append_double(plist,XSH_QC_TRACE13_RMS,res_rms);
02887 cpl_propertylist_set_comment(plist,XSH_QC_TRACE13_RMS,"Stdev residuals");
02888
02889 cleanup:
02890 xsh_free_table(&qc_table);
02891 return cpl_error_get_code();
02892
02893 }
02894
02895
02915
02916
02917 static cpl_error_code
02918 xsh_cube_trace_fit(cpl_table** table,
02919 const char* col_wav,
02920 const char* col_ref,
02921 const char* col_fit,
02922 const char* qualifier,
02923 cpl_propertylist* plist)
02924 {
02925 int nrow=0;
02926 int k=0;
02927 cpl_polynomial* pol=NULL;
02928 cpl_vector* vx=NULL;
02929 cpl_vector* vy=NULL;
02930
02931 double* px=NULL;
02932 double* py=NULL;
02933 double* pf=NULL;
02934 int order=2;
02935 char key_name[25];
02936 cpl_size power=0;
02937 double coeff=0;
02938
02939
02940 nrow=cpl_table_get_nrow(*table);
02941 cpl_table_new_column(*table,col_fit,CPL_TYPE_DOUBLE);
02942 cpl_table_fill_column_window_double(*table,col_fit,0,nrow,0.);
02943
02944 px=cpl_table_get_data_double(*table,col_wav);
02945 py=cpl_table_get_data_double(*table,col_ref);
02946 pf=cpl_table_get_data_double(*table,col_fit);
02947
02948 vx = cpl_vector_wrap( nrow, px );
02949 vy = cpl_vector_wrap( nrow, py );
02950
02951 pol=xsh_polynomial_fit_1d_create(vx,vy,order,NULL);
02952
02953 for(k=0; k< nrow; k++){
02954 check( pf[k] = cpl_polynomial_eval_1d(pol,px[k],NULL));
02955 }
02956
02957
02958 power=0;
02959 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,qualifier);
02960 coeff = cpl_polynomial_get_coeff(pol, &power);
02961 cpl_propertylist_append_double(plist,key_name,coeff);
02962 cpl_propertylist_set_comment(plist,key_name,"order 0 fit coeff");
02963
02964 power=1;
02965 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,qualifier);
02966 coeff = cpl_polynomial_get_coeff(pol, &power);
02967 cpl_propertylist_append_double(plist,key_name,coeff);
02968 cpl_propertylist_set_comment(plist,key_name,"order 1 fit coeff");
02969
02970 power=2;
02971 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,qualifier);
02972 coeff = cpl_polynomial_get_coeff(pol, &power);
02973 cpl_propertylist_append_double(plist,key_name,coeff);
02974 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff");
02975
02976
02977 cleanup:
02978 cpl_vector_unwrap(vx);
02979 cpl_vector_unwrap(vy);
02980 xsh_free_polynomial(&pol);
02981 return cpl_error_get_code();
02982 }
02983
03000
03001
03002 static cpl_error_code
03003 xsh_cube_trace_diff(const cpl_table* table,
03004 const char* col_comp,
03005 const char* col_ref,
03006 cpl_propertylist* plist)
03007 {
03008 char key_name[25];
03009
03010 double cmp_c0=0;
03011 double ref_c0=0;
03012 double dif_c0=0;
03013
03014 double cmp_c1=0;
03015 double ref_c1=0;
03016 double dif_c1=0;
03017
03018 double cmp_c2=0;
03019 double ref_c2=0;
03020 double dif_c2=0;
03021
03022 const double* pw=NULL;
03023 int nrows=0;
03024 double wav=0;
03025 double cmp_pos=0;
03026 double ref_pos=0;
03027 double dif_pos=0;
03028
03029 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_comp);
03030 check(cmp_c0=cpl_propertylist_get_double(plist,key_name));
03031 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_comp);
03032 cmp_c1=cpl_propertylist_get_double(plist,key_name);
03033 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_comp);
03034 cmp_c2=cpl_propertylist_get_double(plist,key_name);
03035
03036 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C0,col_ref);
03037 ref_c0=cpl_propertylist_get_double(plist,key_name);
03038 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C1,col_ref);
03039 ref_c1=cpl_propertylist_get_double(plist,key_name);
03040 sprintf(key_name,"%s_%s",XSH_QC_TRACE_FIT_C2,col_ref);
03041 ref_c2=cpl_propertylist_get_double(plist,key_name);
03042
03043
03044 dif_c0=cmp_c0-ref_c0;
03045 dif_c1=cmp_c1-ref_c1;
03046 dif_c2=cmp_c2-ref_c2;
03047
03048
03049 nrows=cpl_table_get_nrow(table);
03050 pw=cpl_table_get_data_double_const(table,"WAVELENGTH");
03051
03052 wav=pw[0];
03053 cmp_pos=cmp_c0+cmp_c1*wav+cmp_c2*wav*wav;
03054 ref_pos=ref_c0+ref_c1*wav+ref_c2*wav*wav;
03055
03056 dif_pos=cmp_pos-ref_pos;
03057
03058
03059 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C0,dif_c0);
03060 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C0,"order 0 fit coeff diff");
03061
03062 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c1);
03063 cpl_propertylist_set_comment(plist,XSH_QC_TRACE_FIT_DIFF_C1,"order 1 fit coeff diff");
03064
03065 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_C1,dif_c2);
03066 cpl_propertylist_set_comment(plist,key_name,"order 2 fit coeff diff");
03067
03068 cpl_propertylist_append_double(plist,XSH_QC_TRACE_FIT_DIFF_POS,dif_pos);
03069 cpl_propertylist_set_comment(plist,key_name,"fit trace diff pos");
03070
03071 cleanup:
03072 return cpl_error_get_code();
03073
03074 }
03075
03102
03103
03104
03105 cpl_frame*
03106 xsh_cube_qc_trace_window(cpl_frame* frm_cube,xsh_instrument* instrument,
03107 const char* suffix,const char* rec_prefix,
03108 const int win_min, const int win_max,
03109 const int hsize,
03110 const int method,const int compute_qc)
03111 {
03112 cpl_frame* result=NULL;
03113 cpl_table* table=NULL;
03114 cpl_image* data_ima=NULL;
03115 cpl_image* errs_ima=NULL;
03116 cpl_imagelist* data_iml=NULL;
03117 cpl_imagelist* errs_iml=NULL;
03118 cpl_imagelist* swap1=NULL;
03119 cpl_imagelist* swap2=NULL;
03120 cpl_imagelist* data_swap=NULL;
03121 cpl_imagelist* errs_swap=NULL;
03122
03123 const char* name=NULL;
03124
03125 int k=0;
03126
03127 int j=0;
03128
03129 int naxis1=0;
03130 int naxis2=0;
03131 int naxis3=0;
03132
03133
03134 cpl_size mx=0;
03135 cpl_size my=0;
03136 double cx=0;
03137
03138
03139
03140 int llx=0;
03141 int urx=0;
03142
03143 double* pcx1=NULL;
03144 double* pcx2=NULL;
03145 double* pcx3=NULL;
03146 double* pwav=NULL;
03147 double crval3=0;
03148 double cdelt3=0;
03149 cpl_propertylist* plist=NULL;
03150 char fname[80];
03151 char tag[80];
03152
03153 check(name=cpl_frame_get_filename(frm_cube));
03154
03155
03156 check(data_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
03157 plist=cpl_propertylist_load(name,0);
03158 crval3=xsh_pfits_get_crval3(plist);
03159 cdelt3=xsh_pfits_get_cdelt3(plist);
03160
03161 swap1=cpl_imagelist_swap_axis_create(data_iml,CPL_SWAP_AXIS_XZ);
03162 xsh_free_imagelist(&data_iml);
03163 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
03164 xsh_free_imagelist(&swap1);
03165 data_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
03166 xsh_free_imagelist(&swap2);
03167
03168
03169 check(errs_iml=cpl_imagelist_load(name,CPL_TYPE_DOUBLE,0));
03170
03171 swap1=cpl_imagelist_swap_axis_create(errs_iml,CPL_SWAP_AXIS_XZ);
03172 xsh_free_imagelist(&data_iml);
03173 swap2=cpl_imagelist_swap_axis_create(swap1,CPL_SWAP_AXIS_YZ);
03174 xsh_free_imagelist(&swap1);
03175 errs_swap=cpl_imagelist_swap_axis_create(swap2,CPL_SWAP_AXIS_XZ);
03176 xsh_free_imagelist(&swap2);
03177
03178
03179 check(naxis3=cpl_imagelist_get_size(data_swap));
03180 data_ima=cpl_imagelist_get(data_swap,0);
03181
03182 naxis1=cpl_image_get_size_x(data_ima);
03183 naxis2=cpl_image_get_size_y(data_ima);
03184
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 check(errs_ima=cpl_imagelist_get(data_swap,k));
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 int naxis1=0;
03296 int naxis2=0;
03297
03298 int size=0;
03299 check(size=cpl_imagelist_get_size(*mask));
03300 if(mk<size) {
03301 check(data_tmp=cpl_imagelist_get(*data,mk));
03302 check(mask_tmp=cpl_imagelist_get(*mask,mk));
03303 check(pmsk=cpl_image_get_data_int(mask_tmp));
03304 check(naxis1=cpl_image_get_size_x(mask_tmp));
03305 check(naxis2=cpl_image_get_size_y(mask_tmp));
03306
03307 check(norm=pmsk[1]+1);
03308 check(cpl_image_add(data_tmp,data_ima));
03309 check(cpl_image_divide_scalar(data_tmp,norm));
03310 check(cpl_image_add_scalar(mask_tmp,1));
03311 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
03312 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_tmp),mk));
03313
03314 } else {
03315 check(cpl_imagelist_set(*mask,cpl_image_duplicate(mask_ima),mk));
03316 check(cpl_imagelist_set(*data,cpl_image_duplicate(data_ima),mk));
03317 }
03318
03319 cleanup:
03320
03321
03322
03323
03324 return cpl_error_get_code();
03325
03326 }
03327
03328
03336
03337 cpl_image*
03338 xsh_image_mflat_detect_blemishes(cpl_frame* flat_frame,
03339 xsh_instrument* instrument)
03340 {
03341
03342 cpl_image* result=NULL;
03343 cpl_image* diff=NULL;
03344 cpl_image* flat_smooth=NULL;
03345 cpl_array* val=NULL;
03346 cpl_matrix* mx=NULL;
03347 cpl_image* flat_image=NULL;
03348 cpl_propertylist* head=NULL;
03349
03350 int binx=0;
03351 int biny=0;
03352 int sx=0;
03353 int sy=0;
03354 int size=0;
03355 int i=0;
03356 int j=0;
03357 int k=0;
03358 int niter=3;
03359 int filter_width_x=1;
03360 int filter_width_y=3;
03361
03362 double kappa=10.;
03363 double mean=0;
03364 double stdev=0;
03365 double stdev_x_kappa=0;
03366
03367 double med_flat=0;
03368
03369 double* pres=NULL;
03370 double* pima=NULL;
03371 double* pval=NULL;
03372 double* pdif=NULL;
03373 int npixs=0;
03374 const char* name=NULL;
03375 char filename[80];
03376
03377
03378 passure( flat_frame !=NULL , "NULL input flat ");
03379 name=cpl_frame_get_filename(flat_frame);
03380 flat_image=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0);
03381 head=cpl_propertylist_load(name,0);
03382
03383 sx=cpl_image_get_size_x(flat_image);
03384 sy=cpl_image_get_size_y(flat_image);
03385 npixs=sx*sy;
03386 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
03387 binx=1;
03388 biny=1;
03389 } else {
03390 binx=xsh_pfits_get_binx(head);
03391 biny=xsh_pfits_get_biny(head);
03392 }
03393
03394 if (binx>1) filter_width_x=5;
03395 if (biny>1) filter_width_y=5;
03396
03397
03398
03399 check(mx=cpl_matrix_new(filter_width_x,filter_width_y));
03400
03401 for(j=0; j< filter_width_y; j++){
03402 for(i=0; i< filter_width_x; i++){
03403 cpl_matrix_set( mx, i,j,1.0);
03404 }
03405 }
03406
03407 check(diff=cpl_image_duplicate(flat_image));
03408
03409 check(flat_smooth=xsh_image_filter_median(flat_image,mx));
03410
03411
03412
03413
03414 check(cpl_image_subtract(diff,flat_smooth));
03415
03416
03417
03418
03419
03420 check(med_flat=cpl_image_get_median(flat_image));
03421
03422
03423 val=cpl_array_new(npixs,CPL_TYPE_DOUBLE);
03424 check(cpl_array_fill_window_double(val,0,npixs,0));
03425 check(pval=cpl_array_get_data_double(val));
03426 check(pima=cpl_image_get_data_double(flat_image));
03427 check(pdif=cpl_image_get_data_double(diff));
03428 k=0;
03429 for(i=0;i<npixs;i++) {
03430 if(pima[i]>med_flat) {
03431 pval[k]=pdif[i];
03432 k++;
03433 }
03434 }
03435
03436 check(cpl_array_set_size(val,k));
03437
03438
03439 check(mean=cpl_array_get_mean(val));
03440 check(stdev=cpl_array_get_stdev(val));
03441 stdev_x_kappa=stdev*kappa;
03442 check(size=cpl_array_get_size(val));
03443
03444 for(i=0;i<niter;i++) {
03445 for(k=0;k<size;k++) {
03446 if(fabs(pval[k]-mean)>stdev_x_kappa) {
03447 cpl_array_set_invalid(val,k);
03448 }
03449 }
03450 mean=cpl_array_get_mean(val);
03451 stdev=cpl_array_get_stdev(val);
03452 stdev_x_kappa=stdev*kappa;
03453 }
03454
03455
03456 result=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
03457 pres=cpl_image_get_data_double(result);
03458 for(i=0;i<npixs;i++) {
03459 if(fabs(pdif[i])<stdev_x_kappa) {
03460 pres[i]=1.;
03461 }
03462 }
03463
03464 sprintf(filename,"blemish_%s.fits",xsh_instrument_arm_tostring(instrument));
03465
03466 check(cpl_image_save(result,filename,CPL_BPP_IEEE_FLOAT,NULL,
03467 CPL_IO_DEFAULT));
03468
03469
03470 cleanup:
03471 xsh_free_array(&val);
03472 xsh_free_image(&diff);
03473 xsh_free_image(&flat_smooth);
03474 xsh_free_matrix(&mx);
03475 xsh_free_image(&flat_image);
03476 xsh_free_propertylist(&head);
03477 return result;
03478 }
03479
03480
03481
03490
03491 cpl_frame*
03492 xsh_image_mflat_detect_hotcold(cpl_frame* flat_frame,
03493 xsh_instrument* instrument,
03494 const int mode)
03495 {
03496 cpl_frame* msk_frm=NULL;
03497 cpl_image* mask=NULL;
03498 cpl_image* diff=NULL;
03499 cpl_image* flat_smooth=NULL;
03500 cpl_array* val=NULL;
03501 cpl_matrix* mx=NULL;
03502 cpl_image* flat_image=NULL;
03503 cpl_propertylist* head=NULL;
03504
03505 int binx=0;
03506 int biny=0;
03507 int sx=0;
03508 int sy=0;
03509 int size=0;
03510 int i=0;
03511 int j=0;
03512 int k=0;
03513 int niter=3;
03514 int filter_width_x=1;
03515 int filter_width_y=3;
03516
03517 double kappa=10.;
03518 double mean=0;
03519 double stdev=0;
03520 double stdev_x_kappa=0;
03521
03522 double med_flat=0;
03523
03524 double* pmsk=NULL;
03525 double* pima=NULL;
03526 double* pval=NULL;
03527 double* pdif=NULL;
03528 int npixs=0;
03529 const char* name=NULL;
03530 char filename[80];
03531 char tag[80];
03532
03533
03534 passure( flat_frame !=NULL , "NULL input flat ");
03535 name=cpl_frame_get_filename(flat_frame);
03536 flat_image=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0);
03537 head=cpl_propertylist_load(name,0);
03538
03539 sx=cpl_image_get_size_x(flat_image);
03540 sy=cpl_image_get_size_y(flat_image);
03541 npixs=sx*sy;
03542 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
03543 binx=1;
03544 biny=1;
03545 } else {
03546 binx=xsh_pfits_get_binx(head);
03547 biny=xsh_pfits_get_biny(head);
03548 }
03549
03550 if (binx>1) filter_width_x=5;
03551 if (biny>1) filter_width_y=5;
03552
03553
03554
03555 check(mx=cpl_matrix_new(filter_width_x,filter_width_y));
03556
03557 for(j=0; j< filter_width_y; j++){
03558 for(i=0; i< filter_width_x; i++){
03559 cpl_matrix_set( mx, i,j,1.0);
03560 }
03561 }
03562
03563 check(diff=cpl_image_duplicate(flat_image));
03564
03565 check(flat_smooth=xsh_image_filter_median(flat_image,mx));
03566
03567
03568
03569
03570 check(cpl_image_subtract(diff,flat_smooth));
03571
03572
03573
03574
03575
03576 check(med_flat=cpl_image_get_median(flat_image));
03577
03578
03579 val=cpl_array_new(npixs,CPL_TYPE_DOUBLE);
03580 check(cpl_array_fill_window_double(val,0,npixs,0));
03581 check(pval=cpl_array_get_data_double(val));
03582 check(pima=cpl_image_get_data_double(flat_image));
03583 check(pdif=cpl_image_get_data_double(diff));
03584 k=0;
03585 for(i=0;i<npixs;i++) {
03586 if(pima[i]>med_flat) {
03587 pval[k]=pdif[i];
03588 k++;
03589 }
03590 }
03591
03592 check(cpl_array_set_size(val,k));
03593
03594
03595 check(mean=cpl_array_get_mean(val));
03596 check(stdev=cpl_array_get_stdev(val));
03597 stdev_x_kappa=stdev*kappa;
03598 check(size=cpl_array_get_size(val));
03599
03600 for(i=0;i<niter;i++) {
03601 for(k=0;k<size;k++) {
03602 if(fabs(pval[k]-mean)>stdev_x_kappa) {
03603 cpl_array_set_invalid(val,k);
03604 }
03605 }
03606 mean=cpl_array_get_mean(val);
03607 stdev=cpl_array_get_stdev(val);
03608 stdev_x_kappa=stdev*kappa;
03609 }
03610
03611
03612 mask=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
03613 pmsk=cpl_image_get_data_double(mask);
03614
03615 if(mode==1) {
03616 for(i=0;i<npixs;i++) {
03617 if(pdif[i]>stdev_x_kappa) {
03618 pmsk[i]=QFLAG_WELL_SATURATION;
03619 }
03620 }
03621 } else {
03622 for(i=0;i<npixs;i++) {
03623 if(pdif[i]<-stdev_x_kappa) {
03624 pmsk[i]=QFLAG_LOW_QE_PIXEL;
03625 }
03626 }
03627 }
03628
03629 if(mode==1) {
03630 sprintf(tag,"%s_%s",XSH_BP_MAP_SP,xsh_instrument_arm_tostring(instrument));
03631 sprintf(filename,"%s.fits",tag);
03632 } else {
03633 sprintf(tag,"%s_%s",XSH_BP_MAP_DP,xsh_instrument_arm_tostring(instrument));
03634 sprintf(filename,"%s.fits",tag);
03635 }
03636
03637 check(cpl_image_save(mask,filename,XSH_PRE_DATA_BPP,NULL,
03638 CPL_IO_DEFAULT));
03639
03640 xsh_add_temporary_file(filename);
03641 check(msk_frm=xsh_frame_product(filename,tag,CPL_FRAME_TYPE_IMAGE,
03642 CPL_FRAME_GROUP_PRODUCT,
03643 CPL_FRAME_LEVEL_FINAL));
03644
03645 cleanup:
03646 xsh_free_array(&val);
03647 xsh_free_image(&mask);
03648 xsh_free_image(&diff);
03649 xsh_free_image(&flat_smooth);
03650 xsh_free_matrix(&mx);
03651 xsh_free_image(&flat_image);
03652 xsh_free_propertylist(&head);
03653 return msk_frm;
03654 }
03655
03666 cpl_error_code
03667 xsh_collapse_errs(cpl_image * errs, cpl_imagelist * list,
03668 cpl_mask* mask,const int mode)
03669 {
03670 int nx = 0, ny = 0, nimg = 0, i = 0;
03671 float **pdata = NULL;
03672 cpl_binary ** pbinary = NULL;
03673 cpl_binary * binary = NULL;
03674 float* errsdata = NULL;
03675 double mpi_2=0.5*M_PI;
03676 check(nimg = cpl_imagelist_get_size (list));
03677 assure(nimg > 0,CPL_ERROR_ILLEGAL_INPUT,"you must have image to collapse");
03678
03679
03680 pdata = cpl_malloc (nimg * sizeof (float *));
03681 assure (pdata != NULL, cpl_error_get_code (),
03682 "Cant allocate memory for data pointers");
03683
03684 pbinary = cpl_malloc (nimg * sizeof (cpl_binary *));
03685 assure (pbinary != NULL, cpl_error_get_code (),
03686 "Cant allocate memory for binary pointers");
03687
03688
03689 for (i = 0; i < nimg; i++) {
03690 check( pdata[i] = cpl_image_get_data_float(cpl_imagelist_get (list, i)));
03691 check( pbinary[i] = cpl_mask_get_data(cpl_image_get_bpm(
03692 cpl_imagelist_get(list, i))));
03693 }
03694
03695
03696 check(nx = cpl_image_get_size_x (cpl_imagelist_get (list, 0)));
03697 check(ny = cpl_image_get_size_y (cpl_imagelist_get (list, 0)));
03698 check(errsdata = cpl_image_get_data_float(errs));
03699
03700
03701 check(binary = cpl_mask_get_data(mask));
03702
03703
03704 for (i = 0; i < nx * ny; i++){
03705 int count = 0;
03706 int k = 0;
03707 double errval = 0.0;
03708
03709 for (count = 0, k = 0; k < nimg; k++) {
03710
03711 if ( (binary[i] == CPL_BINARY_0) && ((pbinary[k])[i] == CPL_BINARY_0)) {
03712 errval += (pdata[k])[i] * (pdata[k])[i];
03713 count++;
03714 }
03715 }
03716
03717 if (count > 1) {
03718
03719 if (mode==1){
03720
03721 errsdata[i] = sqrt (errval)/((double)count);
03722 } else if (mode==0){
03723
03724 if(count <=2 ) {
03725 errsdata[i] = sqrt (errval)/((double)count);
03726 } else {
03727 errsdata[i] = sqrt ( mpi_2*errval / ((double)(count*(count- 1.))) );
03728 }
03729 }
03730 }
03731 }
03732 cleanup:
03733 cpl_free(pdata);
03734 cpl_free(pbinary);
03735 return cpl_error_get_code();
03736 }
03737
03752 cpl_image*
03753 xsh_combine_flats(
03754 cpl_image* ima1_in,
03755 cpl_image* ima2_in,
03756 xsh_order_list* qth_list,
03757 xsh_order_list* d2_list,
03758 const int xrad,
03759 const int yrad)
03760 {
03761
03762 cpl_image* ima_comb=NULL;
03763 cpl_image* ima_mask=NULL;
03764
03765 int sx=0;
03766 int sy=0;
03767 int j=0;
03768 int i=0;
03769
03770 double* point_mask=NULL;
03771
03772 double xpos=0;
03773
03774 int xpos_min=0;
03775 int xpos_max=0;
03776 int xpos_cen=0;
03777 int ypos_cen=0;
03778
03779 int oref_qth=7;
03780 int oref_d2=0;
03781
03782 int llx=0;
03783 int lly=0;
03784 int urx=0;
03785 int ury=0;
03786 double dflux=0;
03787 double fflux=0;
03788 double scale=0;
03789 cpl_image* ima1=NULL;
03790 cpl_image* ima2=NULL;
03791
03792 cpl_table *ordertable = NULL;
03793 cpl_propertylist *otab_header = NULL;
03794 cpl_polynomial *otab_traces = NULL;
03795
03796 ima1=cpl_image_cast(ima1_in,CPL_TYPE_DOUBLE);
03797 ima2=cpl_image_cast(ima2_in,CPL_TYPE_DOUBLE);
03798 xsh_msg("list size=%d ord_min=%d ord_max=%d",
03799 qth_list->size,qth_list->absorder_min,qth_list->absorder_max);
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828 sx=cpl_image_get_size_x(ima1);
03829 sy=cpl_image_get_size_y(ima1);
03830 assure(sx==cpl_image_get_size_x(ima2),CPL_ERROR_ILLEGAL_INPUT,
03831 "illagal x size");
03832 assure(sy==cpl_image_get_size_y(ima2),CPL_ERROR_ILLEGAL_INPUT,
03833 "illagal y size");
03834
03835
03836
03837
03838 llx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].starty);
03839
03840 urx=xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly,d2_list->list[oref_d2].endy);
03841 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
03842 xpos= ( llx < urx ) ? llx: urx;
03843 xpos_min=(int)xpos;
03844
03845
03846
03847 llx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, 0);
03848
03849 urx=xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly, sy);
03850 xsh_msg("llx=%d urx=%d sx=%d sy=%d",llx,urx,sx,sy);
03851 xpos= ( llx > urx ) ? llx: urx;
03852 xpos_max=(int)xpos;
03853
03854 xsh_msg("xpos min=%d max=%d",xpos_min,xpos_max);
03855 ima_mask = cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
03856 point_mask=cpl_image_get_data_double(ima_mask);
03857
03858 for(j=0;j<sy;j++) {
03859 for(i=xpos_max;i<sx;i++) {
03860 point_mask[j*sx+i]=1.;
03861 }
03862 }
03863
03864
03865
03866
03867
03868 for(j=0;j<sy;j++) {
03869
03870 for(i=xpos_min;i<xpos_max;i++) {
03871
03872
03873
03874
03875
03876
03877
03878 llx= xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].edglopoly, j);
03879
03880 urx= xsh_order_list_eval_int( qth_list, qth_list->list[oref_qth].edguppoly,j);
03881 xpos=0.5*(llx+urx);
03882
03883 if(i > xpos) {
03884
03885 point_mask[j*sx+i] = 1.;
03886 }
03887 }
03888 }
03889
03890
03891
03892
03893
03894
03895 ypos_cen=sy/2;
03896 lly=ypos_cen-yrad;
03897 ury=ypos_cen+yrad;
03898
03899
03900
03901 xpos = xsh_order_list_eval_int( d2_list, d2_list->list[oref_d2].cenpoly, ypos_cen);
03902
03903 xpos_cen=(int)xpos;
03904 llx=xpos_cen-yrad;
03905 urx=xpos_cen+yrad;
03906 fflux=cpl_image_get_median_window(ima1,llx,lly,urx,ury);
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917 dflux=cpl_image_get_median_window(ima2,llx,lly,urx,ury);
03918
03919 scale=fflux/dflux;
03920
03921 xsh_msg("flux: n=%g d=%g s=%g",fflux,dflux,scale);
03922
03923
03924 ima_comb=cpl_image_duplicate(ima1);
03925 cpl_image_multiply(ima_comb,ima_mask);
03926 cpl_image_multiply_scalar(ima_mask,-1.);
03927 cpl_image_add_scalar(ima_mask,1.);
03928 cpl_image_multiply(ima2,ima_mask);
03929 cpl_image_multiply_scalar(ima2,scale);
03930 cpl_image_add(ima_comb,ima2);
03931
03932
03933
03934
03935 cleanup:
03936
03937 xsh_free_table(&ordertable);
03938 xsh_free_propertylist(&otab_header);
03939 xsh_free_polynomial(&otab_traces);
03940 xsh_free_image(&ima1);
03941 xsh_free_image(&ima2);
03942 xsh_free_image(&ima_mask);
03943
03944 return ima_comb;
03945 }
03946
03947
03948 cpl_error_code xsh_frame_image_save2ext(cpl_frame* frm,
03949 const char* name_o, const int ext_i,
03950 const int ext_o) {
03951 const char* name = NULL;
03952 cpl_image* ima = NULL;
03953 cpl_propertylist* plist = NULL;
03954
03955 name = cpl_frame_get_filename(frm);
03956 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, ext_i);
03957
03958 if (ext_o == 0) {
03959 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
03960 } else {
03961 cpl_image_save(ima, name_o, XSH_PRE_DATA_BPP, NULL, CPL_IO_EXTEND);
03962 }
03963
03964 xsh_free_image(&ima);
03965 xsh_free_propertylist(&plist);
03966 return cpl_error_get_code();
03967
03968 }
03969
03970 cpl_error_code xsh_frame_image_add_double(cpl_frame* frm, const double value) {
03971 const char* name = NULL;
03972 name = cpl_frame_get_filename(frm);
03973 cpl_image* ima = NULL;
03974 cpl_propertylist* plist = NULL;
03975
03976 name=cpl_frame_get_filename(frm);
03977 ima = cpl_image_load(name, XSH_PRE_DATA_TYPE, 0, 0);
03978 plist=cpl_propertylist_load(name,0);
03979
03980 cpl_image_add_scalar(ima,value);
03981 cpl_image_save(ima, name, XSH_PRE_DATA_BPP, plist, CPL_IO_DEFAULT);
03982
03983 xsh_free_image(&ima);
03984 xsh_free_propertylist(&plist);
03985 return cpl_error_get_code();
03986
03987 }
03988
03989 static cpl_error_code
03990 xsh_key_scan_mult_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
03991 {
03992
03993 int value=0;
03994 if(cpl_propertylist_has(*plist,kname) > 0) {
03995 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
03996 if(value>1) {
03997 check(cpl_propertylist_set_int(*plist,kname,value*fct));
03998 }
03999 } else {
04000 if(value>1) {
04001 cpl_propertylist_append_int(*plist,kname,1);
04002 }
04003 }
04004
04005 cleanup:
04006 return cpl_error_get_code();
04007 }
04008
04009 static cpl_error_code
04010 xsh_key_bin_div_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
04011 {
04012
04013 int value=0;
04014 if(cpl_propertylist_has(*plist,kname) > 0) {
04015 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
04016 if(value>1) {
04017 check(cpl_propertylist_set_int(*plist,kname,value/fct));
04018 }
04019 } else {
04020 if(fct>1) {
04021 cpl_propertylist_append_int(*plist,kname,1);
04022 }
04023 }
04024
04025 cleanup:
04026 return cpl_error_get_code();
04027 }
04028
04029
04030 static cpl_error_code
04031 xsh_plist_mult_by_fct(cpl_propertylist** plist,const int fctx,const int fcty)
04032 {
04033
04034 xsh_key_bin_div_by_fct(plist,XSH_WIN_BINX,fctx);
04035 xsh_key_bin_div_by_fct(plist,XSH_WIN_BINY,fcty);
04036 xsh_key_scan_mult_by_fct(plist,XSH_PRSCX,fctx);
04037 xsh_key_scan_mult_by_fct(plist,XSH_PRSCY,fcty);
04038 xsh_key_scan_mult_by_fct(plist,XSH_OVSCX,fctx);
04039 xsh_key_scan_mult_by_fct(plist,XSH_OVSCY,fcty);
04040
04041 return cpl_error_get_code();
04042 }
04043
04044 static cpl_error_code
04045 xsh_key_scan_div_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
04046 {
04047
04048 int value=0;
04049 if(cpl_propertylist_has(*plist,kname) > 0) {
04050 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
04051 if(value<2) {
04052 check(cpl_propertylist_set_int(*plist,kname,value/fct));
04053 }
04054 } else {
04055 if(value>1) {
04056 cpl_propertylist_append_int(*plist,kname,1);
04057 }
04058 }
04059
04060 cleanup:
04061 return cpl_error_get_code();
04062 }
04063
04064
04065 static cpl_error_code
04066 xsh_key_bin_mult_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
04067 {
04068
04069 int value=0;
04070 if(cpl_propertylist_has(*plist,kname) > 0) {
04071 xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
04072 if(value<2) {
04073 check(cpl_propertylist_set_int(*plist,kname,value*fct));
04074 }
04075 } else {
04076 if(fct>1) {
04077 cpl_propertylist_append_int(*plist,kname,1);
04078 }
04079 }
04080
04081 cleanup:
04082 return cpl_error_get_code();
04083 }
04084
04085 static cpl_error_code
04086 xsh_plist_div_by_fct(cpl_propertylist** plist,const int fctx,const int fcty)
04087 {
04088 xsh_key_bin_mult_by_fct(plist,XSH_WIN_BINX,fctx);
04089 xsh_key_bin_mult_by_fct(plist,XSH_WIN_BINY,fcty);
04090
04091 xsh_key_scan_div_by_fct(plist,XSH_PRSCX,fctx);
04092 xsh_key_scan_div_by_fct(plist,XSH_PRSCY,fcty);
04093 xsh_key_scan_div_by_fct(plist,XSH_OVSCX,fctx);
04094 xsh_key_scan_div_by_fct(plist,XSH_OVSCY,fcty);
04095
04096 return cpl_error_get_code();
04097 }
04098
04099 static cpl_image*
04100 xsh_image_div_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
04101 {
04102 int sx=0;
04103 int sy=0;
04104 int nx=0;
04105 int ny=0;
04106
04107 cpl_image* ima_datr=NULL;
04108
04109 const float* pdat=NULL;
04110 float* pdatr=NULL;
04111
04112 int i=0;
04113 int j=0;
04114 int k=0;
04115 int m=0;
04116
04117 check(sx=cpl_image_get_size_x(ima_dat));
04118 check(sy=cpl_image_get_size_y(ima_dat));
04119
04120 xsh_msg("org image size dat: %d %d",sx,sy);
04121 nx=sx/fctx;
04122 ny=sy/fcty;
04123
04124 check(ima_datr=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
04125 xsh_msg("new image size dat: %d %d",nx,ny);
04126 check(pdat=cpl_image_get_data_float_const(ima_dat));
04127 check(pdatr=cpl_image_get_data_float(ima_datr));
04128
04129 for(j=0;j<ny;j++) {
04130 for(m=0;m<fcty;m++) {
04131 for(i=0;i<nx;i++) {
04132 for(k=0;k<fctx;k++) {
04133
04134
04135
04136
04137 pdatr[i+j*nx]+=pdat[i*fctx+k+(j*fcty+m)*fctx*nx];
04138 }
04139 }
04140 }
04141
04142 pdatr[i+j*nx]/=(fctx*fcty);
04143
04144 }
04145
04146 cleanup:
04147 return ima_datr;
04148
04149 }
04150
04151
04152
04153
04154 static cpl_image*
04155 xsh_image_mult_by_fct(const cpl_image* ima_dat,const int fctx,const int fcty)
04156 {
04157
04158 int nx=0;
04159 int ny=0;
04160
04161 cpl_image* ima_datr=NULL;
04162
04163 const float* pdat=NULL;
04164 float* pdatr=NULL;
04165
04166 int i=0;
04167 int j=0;
04168 int k=0;
04169 int m=0;
04170
04171 check(nx=cpl_image_get_size_x(ima_dat));
04172 check(ny=cpl_image_get_size_y(ima_dat));
04173
04174 xsh_msg("org image size dat: %d %d",nx,ny);
04175 check(ima_datr=cpl_image_new(fctx*nx,fcty*ny,CPL_TYPE_FLOAT));
04176 xsh_msg("new image size dat: %d %d",fctx*nx,fcty*ny);
04177
04178 check(pdat=cpl_image_get_data_float_const(ima_dat));
04179 check(pdatr=cpl_image_get_data_float(ima_datr));
04180
04181 for(j=0;j<ny;j++) {
04182 for(m=0;m<fcty;m++) {
04183 for(i=0;i<nx;i++) {
04184 for(k=0;k<fctx;k++) {
04185
04186
04187 pdatr[i*fctx+k+(j*fcty+m)*fctx*nx]=pdat[i+j*nx];
04188 }
04189 }
04190 }
04191 }
04192
04193 cleanup:
04194 return ima_datr;
04195 }
04196
04197 cpl_frame*
04198 xsh_frame_image_div_by_fct(cpl_frame* frm,const int fctx, const int fcty)
04199 {
04200
04201 const char* name=NULL;
04202 cpl_propertylist* plist=NULL;
04203 cpl_propertylist* hext=NULL;
04204 cpl_image* ima_dat=NULL;
04205 cpl_image* ima_datr=NULL;
04206
04207 int next=0;
04208
04209 int prscx=0;
04210 int prscy=0;
04211 int ovscx=0;
04212 int ovscy=0;
04213 int kk=0;
04214 cpl_frame* frm_cor=NULL;
04215 const char* tag=NULL;
04216
04217 const char* basename=NULL;
04218 char new_name[80];
04219
04220 check(name=cpl_frame_get_filename(frm));
04221 check(tag=cpl_frame_get_tag(frm));
04222 next=cpl_frame_get_nextensions(frm);
04223 check(plist=cpl_propertylist_load(name,0));
04224
04225 check(prscx=xsh_pfits_get_prscx(plist));
04226 check(prscy=xsh_pfits_get_prscy(plist));
04227 check(ovscx=xsh_pfits_get_ovscx(plist));
04228 check(ovscy=xsh_pfits_get_ovscy(plist));
04229 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
04230
04231 xsh_plist_div_by_fct(&plist,fctx,fcty);
04232
04233 check(basename=xsh_get_basename(name));
04234 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
04235 xsh_msg("new_name=%s",new_name);
04236
04237 for(kk=0;kk<=next;kk++) {
04238
04239 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
04240 check(hext=cpl_propertylist_load(name,kk));
04241 ima_datr=xsh_image_div_by_fct(ima_dat,fctx,fcty);
04242
04243 if(kk==0) {
04244 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
04245 CPL_IO_DEFAULT));
04246 } else if (kk==1) {
04247 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
04248 CPL_IO_EXTEND));
04249 } else if (kk==2) {
04250 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
04251 CPL_IO_EXTEND));
04252 }
04253
04254 xsh_free_image(&ima_dat);
04255 xsh_free_image(&ima_datr);
04256 xsh_free_propertylist(&plist);
04257 xsh_free_propertylist(&hext);
04258 }
04259 frm_cor=cpl_frame_new();
04260 cpl_frame_set_filename(frm_cor,new_name);
04261 check(cpl_frame_set_tag(frm_cor,tag));
04262 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
04263 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
04264 xsh_add_temporary_file(new_name);
04265
04266 cleanup:
04267
04268 xsh_free_image(&ima_dat);
04269 xsh_free_image(&ima_datr);
04270 xsh_free_propertylist(&plist);
04271 xsh_free_propertylist(&hext);
04272
04273 return frm_cor;
04274 }
04275
04276 cpl_frame*
04277 xsh_frame_image_mult_by_fct(cpl_frame* frm,const int fctx, const int fcty)
04278 {
04279
04280 const char* name=NULL;
04281 cpl_propertylist* plist=NULL;
04282 cpl_propertylist* hext=NULL;
04283 cpl_image* ima_dat=NULL;
04284 cpl_image* ima_datr=NULL;
04285
04286 int next=0;
04287
04288 int prscx=0;
04289 int prscy=0;
04290 int ovscx=0;
04291 int ovscy=0;
04292 int kk=0;
04293 cpl_frame* frm_cor=NULL;
04294 const char* tag=NULL;
04295 const char* basename=NULL;
04296 char new_name[80];
04297
04298 check(name=cpl_frame_get_filename(frm));
04299 check(tag=cpl_frame_get_tag(frm));
04300 next=cpl_frame_get_nextensions(frm);
04301 check(plist=cpl_propertylist_load(name,0));
04302
04303 check(prscx=xsh_pfits_get_prscx(plist));
04304 check(prscy=xsh_pfits_get_prscy(plist));
04305 check(ovscx=xsh_pfits_get_ovscx(plist));
04306 check(ovscy=xsh_pfits_get_ovscy(plist));
04307
04308 xsh_msg("Prescan: %d,%d Overscan: %d,%d",prscx,prscy,ovscx,ovscy);
04309 check(basename=xsh_get_basename(name));
04310 sprintf(new_name,"fctx%d_fcty%d_%s",fctx,fcty,basename);
04311 xsh_msg("new_name=%s",new_name);
04312
04313 xsh_plist_mult_by_fct(&plist,fctx,fcty);
04314 for(kk=0;kk<=next;kk++) {
04315
04316 check(ima_dat=cpl_image_load(name,CPL_TYPE_FLOAT,0,kk));
04317 check(hext=cpl_propertylist_load(name,kk));
04318 ima_datr=xsh_image_mult_by_fct(ima_dat,fctx,fcty);
04319 if(kk==0) {
04320 check(cpl_image_save(ima_datr,new_name,XSH_PRE_DATA_BPP,plist,
04321 CPL_IO_DEFAULT));
04322 } else if (kk==1) {
04323 check(cpl_image_save(ima_datr,new_name,XSH_PRE_ERRS_BPP,hext,
04324 CPL_IO_EXTEND));
04325 } else if (kk==2) {
04326 check(cpl_image_save(ima_datr,new_name,XSH_PRE_QUAL_BPP,hext,
04327 CPL_IO_EXTEND));
04328 }
04329
04330 xsh_free_image(&ima_dat);
04331 xsh_free_image(&ima_datr);
04332 xsh_free_propertylist(&plist);
04333 xsh_free_propertylist(&hext);
04334
04335 }
04336
04337 frm_cor=cpl_frame_new();
04338 cpl_frame_set_filename(frm_cor,new_name);
04339 cpl_frame_set_tag(frm_cor,tag);
04340 cpl_frame_set_type(frm_cor,CPL_FRAME_TYPE_IMAGE);
04341 cpl_frame_set_group(frm_cor,CPL_FRAME_GROUP_CALIB);
04342 xsh_add_temporary_file(new_name);
04343 cleanup:
04344 return frm_cor;
04345
04346 }
04347