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 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031
00032
00033
00034 #include <assert.h>
00035 #include <stdarg.h>
00036 #include <time.h>
00037 #include <math.h>
00038
00039 #include <fcntl.h>
00040 #include <sys/stat.h>
00041
00042 #include "xsh_utils.h"
00043 #include <xsh_utils_wrappers.h>
00044 #include <xsh_dfs.h>
00045 #include <xsh_data_pre.h>
00046 #include <xsh_dump.h>
00047 #include <xsh_error.h>
00048 #include <xsh_msg.h>
00049 #include <xsh_parameters.h>
00050 #include <xsh_data_spectrum.h>
00051 #include <xsh_data_atmos_ext.h>
00052 #include <xsh_pfits.h>
00053 #include <xsh_pfits_qc.h>
00054
00055 #include <cpl.h>
00056 #include <ctype.h>
00057 #include <stdbool.h>
00058
00059 #include <gsl/gsl_rng.h>
00060 #include <gsl/gsl_randist.h>
00061 #include <gsl/gsl_vector.h>
00062 #include <gsl/gsl_blas.h>
00063 #include <gsl/gsl_multifit_nlin.h>
00064
00065
00066
00067
00068 static int XshDebugLevel = XSH_DEBUG_LEVEL_NONE ;
00069 static int XshTimeStamp = FALSE ;
00070
00071
00072
00073
00074 #define MAXIMUM(x, y) ((x) > (y)) ? (x) : (y)
00075
00076
00077 #define DEV_BLOCKSIZE 4096
00078 #define XSH_ATM_EXT_UVB_WAV_MIN 310.
00079
00087
00088
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define CPL_TYPE float
00099 #define CPL_TYPE_T CPL_TYPE_FLOAT
00100 #define CPL_IMAGE_GET_DATA cpl_image_get_data_float
00101 #define CPL_IMAGE_GET_DATA_CONST cpl_image_get_data_float_const
00102 #define CPL_IMAGE_GET_MEDIAN cpl_tools_get_median_float
00103
00104
00105
00134
00135 cpl_image * xsh_imagelist_collapse_sigclip_iter_create(
00136 const cpl_imagelist * imlist,
00137 double sigma_low,
00138 double sigma_upp,
00139 const int niter)
00140
00141 {
00142 const cpl_image * cur_ima=NULL ;
00143 int ni, nx, ny ;
00144 cpl_table * time_line=NULL ;
00145 cpl_image * out_ima=NULL ;
00146 double out_val ;
00147
00148 double mean, stdev ;
00149 double low_thresh, high_thresh ;
00150 int i, j, k ;
00151
00152
00153 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
00154 cpl_ensure(cpl_imagelist_is_uniform(imlist)==0, CPL_ERROR_ILLEGAL_INPUT,
00155 NULL);
00156 cpl_ensure(sigma_low>1., CPL_ERROR_ILLEGAL_INPUT, NULL);
00157 cpl_ensure(sigma_upp>1., CPL_ERROR_ILLEGAL_INPUT, NULL);
00158 cpl_ensure(niter > 0, CPL_ERROR_NULL_INPUT, NULL);
00159
00160 ni = cpl_imagelist_get_size(imlist) ;
00161
00162 cur_ima = cpl_imagelist_get_const(imlist, 0) ;
00163 nx = cpl_image_get_size_x(cur_ima) ;
00164 ny = cpl_image_get_size_y(cur_ima) ;
00165
00166
00167
00168 time_line = cpl_table_new(ni) ;
00169
00170
00171
00172
00173
00174
00175 {
00176
00177 CPL_TYPE * pout_ima ;
00178 const CPL_TYPE * pcur_ima ;
00179 int n=0;
00180 int nbad=0;
00181 CPL_TYPE * ptime_line ;
00182
00183 cpl_table_new_column(time_line,"VAL",CPL_TYPE_T);
00184 cpl_table_fill_column_window(time_line,"VAL",0,ni,0);
00185 if (CPL_TYPE_T == CPL_TYPE_DOUBLE) {
00186 ptime_line = (CPL_TYPE*) cpl_table_get_data_double(time_line,"VAL") ;
00187 } else if (CPL_TYPE_T == CPL_TYPE_FLOAT) {
00188 ptime_line = (CPL_TYPE*) cpl_table_get_data_float(time_line,"VAL") ;
00189 } else {
00190 ptime_line = (CPL_TYPE*) cpl_table_get_data_int(time_line,"VAL") ;
00191 }
00192 out_ima = cpl_image_new(nx, ny, CPL_TYPE_T) ;
00193 pout_ima = CPL_IMAGE_GET_DATA(out_ima) ;
00194
00195 for (j=0 ; j<ny ; j++) {
00196 for (i=0 ; i<nx ; i++) {
00197
00198
00199 for (k=0 ; k<ni ; k++) {
00200 cur_ima = cpl_imagelist_get_const(imlist, k) ;
00201 pcur_ima = CPL_IMAGE_GET_DATA_CONST(cur_ima) ;
00202 ptime_line[k] = (CPL_TYPE)pcur_ima[i+j*nx] ;
00203 }
00204
00205
00206
00207 for(n=0, nbad=0;(n<niter) && (nbad<ni-1);n++) {
00208
00209 check(mean = cpl_table_get_column_mean(time_line,"VAL")) ;
00210 check(stdev = cpl_table_get_column_stdev(time_line,"VAL")) ;
00211 low_thresh = mean - sigma_low * stdev ;
00212 high_thresh = mean + sigma_upp * stdev ;
00213
00214
00215 out_val = 0.0 ;
00216
00217 for (k=0 ; k<ni ; k++) {
00218 if (ptime_line[k]<=high_thresh &&
00219 ptime_line[k]>=low_thresh) {
00220
00221 } else {
00222 cpl_table_set_invalid(time_line,"VAL",k);
00223 nbad++;
00224 }
00225 }
00226 }
00227
00228 out_val = cpl_table_get_column_mean(time_line,"VAL") ;
00229
00230 pout_ima[i+j*nx] = (CPL_TYPE)out_val ;
00231 }
00232 }
00233
00234 }
00235
00236 cleanup:
00237 cpl_table_delete(time_line) ;
00238
00239
00240
00241 return out_ima ;
00242 }
00243
00244
00245
00246
00253 double
00254 xsh_hms2deg(const double hms)
00255 {
00256 int hrs=0;
00257 int min=0;
00258 double sec=0;
00259 double deg=0;
00260 double rest=hms;
00261 int sign=1;
00262
00263 if(hms<0) {
00264 sign=-1;
00265 rest=-hms;
00266 }
00267
00268 hrs=(int)(rest/10000.);
00269 rest=rest-(double)(hrs*10000.);
00270 min=(int)(rest/100.);
00271 sec=rest-(double)(min*100.);
00272 deg=hrs*15+(double)(min/4.)+(double)(sec/240.);
00273 deg=sign*deg;
00274
00275 return deg;
00276
00277 }
00278
00279
00286 double
00287 xsh_sess2deg(const double sess)
00288 {
00289 int grad=0;
00290 int min=0;
00291 double sec=0;
00292 double deg=0;
00293 double rest=sess;
00294 int sign=1;
00295
00296 if(sess<0) {
00297 sign=-1;
00298 rest=-sess;
00299 }
00300 grad=(int)(rest/10000.);
00301 rest=rest-(double)(grad*10000.);
00302 min=(int)(rest/100.);
00303 sec=rest-(double)(min*100.);
00304 deg=grad+(double)(min/60.)+(double)(sec/3600.);
00305 deg=sign*deg;
00306
00307 return deg;
00308
00309 }
00310
00316 cpl_error_code
00317 xsh_check_input_is_unbinned(cpl_frame* in)
00318 {
00319
00320 cpl_propertylist* plist=NULL;
00321 const char* name=NULL;
00322 int binx=0;
00323 int biny=0;
00324
00325 if(in==NULL) {
00326 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
00327 return cpl_error_get_code();
00328 }
00329 name=cpl_frame_get_filename(in);
00330 plist=cpl_propertylist_load(name,0);
00331
00332 binx=xsh_pfits_get_binx(plist);
00333 biny=xsh_pfits_get_biny(plist);
00334
00335 xsh_free_propertylist(&plist);
00336 if(binx*biny > 1) {
00337 xsh_msg_error("This recipe expects unbinned input raw frames. Exit");
00338 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
00339 }
00340 return cpl_error_get_code();
00341
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 int xsh_fileutils_copy (const char * srcpath, const char * dstpath)
00372
00373 {
00374 char *buf;
00375
00376 int src, dst;
00377 int rbytes = 0;
00378 int wbytes = 0;
00379 int blksize = DEV_BLOCKSIZE;
00380
00381 struct stat sb, db;
00382
00383
00384
00385
00386 if ((stat(srcpath,&sb) == 0) && (stat(dstpath,&db) == 0))
00387 {
00388 if (sb.st_ino == db.st_ino)
00389 return 99;
00390 }
00391
00392 if ((src = open (srcpath, O_RDONLY)) == -1) return (-1);
00393
00394 if ((fstat (src, &sb) == -1) || (!S_ISREG (sb.st_mode)))
00395 {
00396 (void) close (src);
00397 return -2;
00398 }
00399
00400 if ((dst = open (dstpath, O_CREAT | O_WRONLY | O_TRUNC, sb.st_mode)) == -1)
00401 {
00402 (void) close (src);
00403 return -3;
00404 }
00405
00406 if ((fstat (dst, &db) == -1) || (!S_ISREG (db.st_mode)))
00407 {
00408 (void) close (src);
00409 (void) close (dst);
00410 (void) unlink (dstpath);
00411 return -4;
00412 }
00413
00414 #ifdef HAVE_ST_BLKSIZE
00415 blksize = db.st_blksize;
00416 #else
00417 # ifdef DEV_BSIZE
00418 blksize = DEV_BSIZE;
00419 # endif
00420 #endif
00421
00422 if ((buf = (char *) cpl_malloc ((size_t)blksize)) == NULL)
00423 {
00424 (void) close (src);
00425 (void) close (dst);
00426 (void) unlink (dstpath);
00427 return -5;
00428 }
00429
00430 while ((rbytes = (int) read (src, buf, (size_t)blksize)) > 0)
00431 {
00432 if ((wbytes = (int) write (dst, buf, (size_t)rbytes)) != rbytes)
00433 {
00434 wbytes = -1;
00435 break;
00436 }
00437 }
00438
00439 (void) close (src);
00440 (void) close (dst);
00441 cpl_free (buf);
00442
00443
00444 if ((rbytes == -1) || (wbytes == -1))
00445 {
00446 (void) unlink (dstpath);
00447 return -6;
00448 }
00449
00450 return 0;
00451
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 int xsh_fileutils_move (const char *srcpath, const char *dstpath)
00477
00478 {
00479 int ii;
00480
00481 struct stat sb;
00482
00483
00484
00485 if ((ii = xsh_fileutils_copy (srcpath, dstpath)) != 0)
00486 {
00487 if (ii == 99)
00488 return 99;
00489 else
00490 return (-2);
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 if (stat (srcpath, &sb) == -1 || !(sb.st_mode & S_IWUSR))
00500 {
00501 (void) unlink (dstpath);
00502 return -1;
00503 }
00504
00505 (void) unlink (srcpath);
00506 return 0;
00507
00508 }
00509
00510
00516
00517 const char*
00518 xsh_set_recipe_sky_file_prefix(char* rec_prefix)
00519 {
00520 const char* sky_prefix=NULL;
00521 if(strstr(rec_prefix,"SCI") != NULL) {
00522 sky_prefix="SKY_SLIT";
00523 } else if(strstr(rec_prefix,"TELL") != NULL) {
00524 sky_prefix="SKY_SLIT";
00525 } else if(strstr(rec_prefix,"FLUX") != NULL) {
00526 sky_prefix="SKY_SLIT";
00527 } else {
00528 sky_prefix="CAL_SLIT_SKY";
00529 }
00530
00531 return sky_prefix;
00532
00533 }
00534
00541
00542 char*
00543 xsh_set_recipe_file_prefix(cpl_frameset* raw,const char* recipe)
00544 {
00545
00546 cpl_frame* frm=NULL;
00547 cpl_propertylist* plist=NULL;
00548 const char* obj=NULL;
00549 char* prefix=NULL;
00550
00551 const char* dpr_catg=NULL;
00552
00553 const char* dpr_type=NULL;
00554 const char* filename=NULL;
00555
00556 check(frm=cpl_frameset_get_frame(raw,0));
00557 filename=cpl_frame_get_filename(frm);
00558 plist=cpl_propertylist_load(filename,0);
00559 dpr_catg=xsh_pfits_get_dpr_catg(plist);
00560
00561 dpr_type=xsh_pfits_get_dpr_type(plist);
00562
00563 if(strstr(dpr_catg,"SCIENCE")!=NULL) {
00564 if(strstr(dpr_type,"SKY")!=NULL) {
00565 obj="SKY";
00566 } else {
00567 obj="SCI";
00568 }
00569 } else if(strstr(dpr_catg,"CALIB")!=NULL) {
00570 if(strstr(dpr_type,"FLUX")!=NULL) {
00571 obj="FLUX";
00572 } else if(strstr(dpr_type,"TELLURIC")!=NULL) {
00573 obj="TELL";
00574 } else {
00575 obj="CAL";
00576 }
00577 } else {
00578 obj="OBJ";
00579 }
00580
00581 if(strstr(recipe,"respon_slit_stare")!=NULL) {
00582 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00583 } else if(strstr(recipe,"respon_slit_offset")!=NULL) {
00584 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00585 } else if(strstr(recipe,"respon_slit_nod")!=NULL) {
00586 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00587 } else if(strstr(recipe,"scired_slit_stare")!=NULL) {
00588 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00589 } else if(strstr(recipe,"scired_slit_offset")!=NULL) {
00590 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00591 } else if(strstr(recipe,"scired_slit_nod")!=NULL) {
00592 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00593 } else if(strstr(recipe,"scired_ifu_stare")!=NULL) {
00594 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00595 } else if(strstr(recipe,"scired_ifu_offset")!=NULL) {
00596 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00597 } else if(strstr(recipe,"geom_ifu")!=NULL) {
00598 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00599 } else {
00600 xsh_msg_warning("recipe %s not supported",recipe);
00601 prefix=xsh_stringcat_any(obj,"",NULL);
00602 }
00603
00604
00605 cleanup:
00606 xsh_free_propertylist(&plist);
00607
00608 return prefix;
00609 }
00610
00611
00617
00618 cpl_error_code xsh_set_cd_matrix(cpl_propertylist* plist)
00619 {
00620
00621 int naxis=0;
00622 naxis=xsh_pfits_get_naxis(plist);
00623 switch (naxis) {
00624
00625 case 1: xsh_set_cd_matrix1d(plist);break;
00626
00627 case 2: xsh_set_cd_matrix2d(plist);break;
00628
00629 case 3: xsh_set_cd_matrix3d(plist);break;
00630
00631 default: xsh_msg_error("Naxis: %d unsupported",naxis);
00632 }
00633
00634 return cpl_error_get_code();
00635 }
00636
00642
00643 cpl_error_code xsh_set_cd_matrix1d(cpl_propertylist* plist)
00644 {
00645 double cdelt1=xsh_pfits_get_cdelt1(plist);
00646 xsh_pfits_set_cd1(plist,cdelt1);
00647
00648 return cpl_error_get_code();
00649
00650 }
00651
00652
00653
00659
00660 cpl_error_code xsh_set_cd_matrix2d(cpl_propertylist* plist)
00661 {
00662 double cdelt1=0;
00663 double cdelt2=0;
00664
00665
00666 check(cdelt1=xsh_pfits_get_cdelt1(plist));
00667 check(cdelt2=xsh_pfits_get_cdelt2(plist));
00668 check(xsh_pfits_set_cd11(plist,cdelt1));
00669 check(xsh_pfits_set_cd12(plist,0.));
00670 check(xsh_pfits_set_cd21(plist,0.));
00671 check(xsh_pfits_set_cd22(plist,cdelt2));
00672
00673 cleanup:
00674
00675 return cpl_error_get_code();
00676
00677 }
00678
00679
00685
00686 cpl_error_code xsh_set_cd_matrix3d(cpl_propertylist* plist)
00687 {
00688
00689 double cdelt3=0;
00690 check(cdelt3=xsh_pfits_get_cdelt3(plist));
00691
00692 check(xsh_pfits_set_cd31(plist,0.));
00693 check(xsh_pfits_set_cd13(plist,0.));
00694 check(xsh_pfits_set_cd32(plist,0.));
00695 check(xsh_pfits_set_cd23(plist,0.));
00696 check(xsh_pfits_set_cd33(plist,cdelt3));
00697
00698 cleanup:
00699
00700 return cpl_error_get_code();
00701
00702 }
00703
00704
00710
00711
00712 cpl_parameterlist*
00713 xsh_parameterlist_duplicate(const cpl_parameterlist* pin){
00714
00715 cpl_parameter* p=NULL;
00716 cpl_parameterlist* pout=NULL;
00717
00718 pout=cpl_parameterlist_new();
00719 p=cpl_parameterlist_get_first((cpl_parameterlist*)pin);
00720 while (p != NULL)
00721 {
00722 cpl_parameterlist_append(pout,p);
00723 p=cpl_parameterlist_get_next((cpl_parameterlist*)pin);
00724 }
00725 return pout;
00726
00727 }
00728
00729
00730
00737
00738 static void
00739 xsh_property_dump(cpl_property *property)
00740 {
00741
00742 const char *name = cpl_property_get_name(property);
00743 const char *comment = cpl_property_get_comment(property);
00744
00745 char c;
00746
00747 long size = cpl_property_get_size(property);
00748
00749 cpl_type type = cpl_property_get_type(property);
00750
00751
00752 fprintf(stderr, "Property at address %p\n", property);
00753 fprintf(stderr, "\tname : %p '%s'\n", name, name);
00754 fprintf(stderr, "\tcomment: %p '%s'\n", comment, comment);
00755 fprintf(stderr, "\ttype : %#09x\n", type);
00756 fprintf(stderr, "\tsize : %ld\n", size);
00757 fprintf(stderr, "\tvalue : ");
00758
00759
00760 switch (type) {
00761 case CPL_TYPE_CHAR:
00762 c = cpl_property_get_char(property);
00763 if (!c)
00764 fprintf(stderr, "''");
00765 else
00766 fprintf(stderr, "'%c'", c);
00767 break;
00768
00769 case CPL_TYPE_BOOL:
00770 fprintf(stderr, "%d", cpl_property_get_bool(property));
00771 break;
00772
00773 case CPL_TYPE_INT:
00774 fprintf(stderr, "%d", cpl_property_get_int(property));
00775 break;
00776
00777 case CPL_TYPE_LONG:
00778 fprintf(stderr, "%ld", cpl_property_get_long(property));
00779 break;
00780
00781 case CPL_TYPE_FLOAT:
00782 fprintf(stderr, "%.7g", cpl_property_get_float(property));
00783 break;
00784
00785 case CPL_TYPE_DOUBLE:
00786 fprintf(stderr, "%.15g", cpl_property_get_double(property));
00787 break;
00788
00789 case CPL_TYPE_STRING:
00790 fprintf(stderr, "'%s'", cpl_property_get_string(property));
00791 break;
00792
00793 default:
00794 fprintf(stderr, "unknown.");
00795 break;
00796
00797 }
00798
00799 fprintf(stderr, "\n");
00800
00801 return;
00802
00803 }
00804
00805
00814
00815
00816 cpl_frame*
00817 xsh_frameset_average(cpl_frameset *set, const char* tag)
00818 {
00819 cpl_frame* result=NULL;
00820 cpl_frame* frame=NULL;
00821 cpl_image* image=NULL;
00822 cpl_imagelist* iml=NULL;
00823 cpl_propertylist* plist=NULL;
00824 char name_o[256];
00825 const char* name=NULL;
00826 int i=0;
00827 int size=0;
00828
00829 check(size=cpl_frameset_get_size(set));
00830 iml=cpl_imagelist_new();
00831 for(i=0;i<size;i++) {
00832 frame=cpl_frameset_get_frame(set,i);
00833 name=cpl_frame_get_filename(frame);
00834 image=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00835 cpl_imagelist_set(iml,cpl_image_duplicate(image),i);
00836 xsh_free_image(&image);
00837 }
00838 image=cpl_imagelist_collapse_create(iml);
00839 frame=cpl_frameset_get_frame(set,0);
00840 name=cpl_frame_get_filename(frame);
00841 plist=cpl_propertylist_load(name,0);
00842
00843 sprintf(name_o,"%s.fits",tag);
00844 cpl_image_save(image,name_o,CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT);
00845 result=xsh_frame_product(name_o,tag,CPL_FRAME_TYPE_IMAGE,
00846 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
00847
00848 cleanup:
00849 xsh_free_image(&image);
00850 xsh_free_imagelist(&iml);
00851 xsh_free_propertylist(&plist);
00852
00853 return result;
00854 }
00855
00856
00863 cpl_frame* xsh_frameset_add( cpl_frameset *set, xsh_instrument* instr,const int decode_bp)
00864 {
00865 int iset, i, j, set_size = 0;
00866 cpl_frame *result = NULL;
00867 xsh_pre **pre_list = NULL;
00868 xsh_pre *pre_res = NULL;
00869 float *res_flux = NULL;
00870 float *res_errs = NULL;
00871 int *res_qual = NULL;
00872 int nx, ny;
00873
00874 XSH_ASSURE_NOT_NULL( set);
00875
00876 check( set_size = cpl_frameset_get_size( set));
00877
00878 if (set_size > 0){
00879 XSH_CALLOC( pre_list, xsh_pre*, set_size);
00880
00881 for( iset=0; iset< set_size; iset++){
00882 xsh_pre* pre = NULL;
00883 cpl_frame *frame = NULL;
00884
00885 check( frame = cpl_frameset_get_frame( set, iset));
00886 check( pre = xsh_pre_load( frame, instr));
00887
00888 pre_list[iset] = pre;
00889 }
00890
00891 pre_res = xsh_pre_duplicate( pre_list[0]);
00892 nx = pre_res->nx;
00893 ny = pre_res->ny;
00894 check( res_flux = cpl_image_get_data_float( xsh_pre_get_data( pre_res)));
00895 check( res_errs = cpl_image_get_data_float( xsh_pre_get_errs( pre_res)));
00896 check( res_qual = cpl_image_get_data_int( xsh_pre_get_qual( pre_res)));
00897
00898 for( j=0; j< ny; j++){
00899 for( i=0; i< nx; i++){
00900 int good =0;
00901 float good_flux=0, bad_flux=0;
00902 float good_errs=0, bad_errs=0;
00903 int good_qual=QFLAG_GOOD_PIXEL, bad_qual=QFLAG_GOOD_PIXEL;
00904 int idx;
00905
00906 idx = i+j*nx;
00907
00908 for(iset = 0; iset < set_size; iset++){
00909 float *img_flux = NULL;
00910 float *img_errs = NULL;
00911 int *img_qual = NULL;
00912
00913 check( img_flux = cpl_image_get_data_float( xsh_pre_get_data( pre_list[iset])));
00914 check( img_errs = cpl_image_get_data_float( xsh_pre_get_errs( pre_list[iset])));
00915 check( img_qual = cpl_image_get_data_int( xsh_pre_get_qual( pre_list[iset])));
00916
00917 if ( (img_qual[idx] & decode_bp) == 0 ){
00918
00919 good++;
00920 good_qual|=img_qual[idx];
00921 good_flux += img_flux[idx];
00922 good_errs += img_errs[idx]*img_errs[idx];
00923 }
00924 else{
00925 bad_qual |= img_qual[idx];
00926 bad_flux += img_flux[idx];
00927 bad_errs += img_errs[idx]*img_errs[idx];
00928 }
00929 }
00930
00931 if ( good == 0){
00932 res_flux[idx] = bad_flux;
00933 res_errs[idx] = sqrt( bad_errs);
00934 res_qual[idx] |= bad_qual;
00935 }
00936 else{
00937 res_flux[idx] = good_flux*set_size/good;
00938 res_errs[idx] = sqrt( good_errs)*set_size/good;
00939 res_qual[idx] |= good_qual;
00940 }
00941 }
00942 }
00943 check( result = xsh_pre_save( pre_res, "COADD.fits", "COADD", 1));
00944
00945 }
00946 cleanup:
00947 if (cpl_error_get_code() != CPL_ERROR_NONE){
00948 xsh_free_frame( &result);
00949 }
00950 xsh_pre_free( &pre_res);
00951 for( i=0; i< set_size; i++){
00952 xsh_pre_free( &(pre_list[i]));
00953 }
00954 XSH_FREE( pre_list);
00955 return result;
00956 }
00957
00958
00959
00966
00967 void
00968 xsh_plist_dump(cpl_propertylist *plist)
00969 {
00970
00971 long i=0;
00972 long sz = cpl_propertylist_get_size(plist);
00973
00974
00975 fprintf(stderr, "Property list at address %p:\n", plist);
00976
00977 for (i = 0; i < sz; i++) {
00978 cpl_property *p = cpl_propertylist_get(plist, i);
00979 xsh_property_dump(p);
00980 }
00981
00982 return;
00983
00984 }
00985
00986
00987
00994
00995 cpl_error_code
00996 xsh_frameset_dump(cpl_frameset* set)
00997 {
00998
00999 const cpl_frame* f=NULL;
01000 int n=0;
01001 int i=0;
01002 const char* name=NULL;
01003 const char* tag=NULL;
01004 int group=0;
01005 n=cpl_frameset_get_size(set);
01006 xsh_msg("files present in set");
01007 for(i=0;i<n;i++) {
01008
01009 f=cpl_frameset_get_frame(set,i);
01010 name=cpl_frame_get_filename(f);
01011 tag=cpl_frame_get_tag(f);
01012 group=cpl_frame_get_group(f);
01013 xsh_msg("filename=%s tag=%s group=%d",name,tag,group);
01014
01015 }
01016
01017 return cpl_error_get_code();
01018
01019 }
01020
01021
01028
01029 cpl_error_code
01030 xsh_frameset_dump_nod_info(cpl_frameset* set)
01031 {
01032
01033 const cpl_frame* f=NULL;
01034 int n=0;
01035 int i=0;
01036 const char* name=NULL;
01037 const char* tag=NULL;
01038 cpl_propertylist* plist=NULL;
01039
01040 double cum_off_y=0;
01041 double nod_throw=0;
01042 double jitter_width=0;
01043
01044
01045 n=cpl_frameset_get_size(set);
01046 xsh_msg("files present in set");
01047 for(i=0;i<n;i++) {
01048
01049 f=cpl_frameset_get_frame(set,i);
01050 name=cpl_frame_get_filename(f);
01051 tag=cpl_frame_get_tag(f);
01052
01053
01054 plist=cpl_propertylist_load(name,0);
01055 if(cpl_propertylist_has(plist,XSH_NOD_CUMULATIVE_OFFSETY)) {
01056 cum_off_y=xsh_pfits_get_cumoffsety(plist);
01057 } else {
01058
01059 xsh_msg_warning("missing %s",XSH_NOD_CUMULATIVE_OFFSETY);
01060 }
01061
01062 if(cpl_propertylist_has(plist,XSH_NOD_THROW)) {
01063 nod_throw=xsh_pfits_get_nodthrow(plist);
01064 } else {
01065 xsh_msg_warning("missing %s",XSH_NOD_CUMULATIVE_OFFSETY);
01066 }
01067
01068
01069 if(cpl_propertylist_has(plist,XSH_NOD_JITTER_BOX)) {
01070 jitter_width= xsh_pfits_get_nod_jitterwidth(plist);
01071 } else {
01072 xsh_msg_warning("missing %s",XSH_NOD_JITTER_BOX);
01073 }
01074
01075
01076
01077
01078 xsh_msg("filename=%s tag=%s cum_off_y=%f nod_throw=%f jitter_width=%f",
01079 name,tag,cum_off_y,nod_throw,jitter_width);
01080 xsh_free_propertylist(&plist);
01081 }
01082
01083 return cpl_error_get_code();
01084
01085 }
01086
01087
01088
01089
01100
01101 void
01102 xsh_init (void)
01103 {
01104 xsh_error_reset ();
01105 xsh_msg_init ();
01106 }
01107
01108
01115
01116
01117 char * xsh_get_basename(const char *filename)
01118 {
01119 char *p ;
01120 p = strrchr (filename, '/');
01121 return p ? p + 1 : (char *) filename;
01122 }
01123
01124
01125
01133
01134 const char *
01135 xsh_get_license (void)
01136 {
01137 const char *xsh_license =
01138 "This file is part of the X-shooter Instrument Pipeline\n"
01139 "Copyright (C) 2006 European Southern Observatory\n"
01140 "\n"
01141 "This program is free software; you can redistribute it and/or modify\n"
01142 "it under the terms of the GNU General Public License as published by\n"
01143 "the Free Software Foundation; either version 2 of the License, or\n"
01144 "(at your option) any later version.\n"
01145 "\n"
01146 "This program is distributed in the hope that it will be useful,\n"
01147 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
01148 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
01149 "GNU General Public License for more details.\n"
01150 "\n"
01151 "You should have received a copy of the GNU General Public License\n"
01152 "along with this program; if not, write to the Free Software\n"
01153 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, \n"
01154 "MA 02111-1307 USA";
01155 return xsh_license;
01156 }
01157
01158
01184
01185 cpl_error_code
01186 xsh_begin (cpl_frameset * frames,
01187 const cpl_parameterlist * parameters,
01188 xsh_instrument ** instrument,
01189 cpl_frameset ** raws,
01190 cpl_frameset ** calib,
01191 const char * tag_list[],
01192 int tag_list_size,
01193 const char *recipe_id,
01194 unsigned int binary_version,
01195 const char *short_descr)
01196 {
01197 char *recipe_string = NULL;
01198 char *recipe_version = NULL;
01199 char *stars = NULL;
01200 char *spaces1 = NULL;
01201 char *spaces2 = NULL;
01202 char *spaces3 = NULL;
01203 char *spaces4 = NULL;
01204 int decode_bp=0;
01205 cpl_parameter* p=NULL;
01206 int nraws=0;
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222 {
01223 int lvl;
01224
01225
01226 lvl = xsh_parameters_get_temporary( recipe_id, parameters ) ;
01227 if ( lvl == 0 )
01228 xsh_msg( "Keep Temporary File = no" ) ;
01229 else
01230 xsh_msg( "Keep Temporary File = yes" ) ;
01231
01232 lvl = xsh_parameters_debug_level_get( recipe_id, parameters ) ;
01233 xsh_msg( "Xsh Debug Level = %s", xsh_debug_level_tostring() ) ;
01234
01235
01236 }
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249 {
01250 int version_string_length;
01251 int major_version, minor_version, micro_version;
01252
01253 major_version = binary_version / 10000;
01254 minor_version = (binary_version % 10000) / 100;
01255 micro_version = binary_version % 100;
01256
01257
01258 assure (major_version < 100, CPL_ERROR_UNSUPPORTED_MODE,
01259 "Major version: %d", major_version);
01260
01261 version_string_length = strlen ("XX.YY.ZZ");
01262 recipe_version = cpl_calloc (sizeof (char), version_string_length + 1);
01263
01264 snprintf (recipe_version, version_string_length + 1,
01265 "%d.%d.%d", major_version, minor_version, micro_version);
01266
01267 recipe_string =
01268 xsh_stringcat_4 ("Recipe: ", recipe_id, " ", recipe_version);
01269 }
01270
01271 {
01272 int field = MAXIMUM (strlen (PACKAGE_STRING), strlen (recipe_string));
01273 int nstars = 3 + 1 + field + 1 + 3;
01274 int nspaces1, nspaces2, nspaces3, nspaces4;
01275 int i;
01276
01277
01278 nspaces1 = (field - strlen (PACKAGE_STRING)) / 2;
01279 nspaces2 = field - strlen (PACKAGE_STRING) - nspaces1;
01280
01281 nspaces3 = (field - strlen (recipe_string)) / 2;
01282 nspaces4 = field - strlen (recipe_string) - nspaces3;
01283
01284 spaces1 = cpl_calloc (sizeof (char), nspaces1 + 1);
01285 for (i = 0; i < nspaces1; i++)
01286 spaces1[i] = ' ';
01287 spaces2 = cpl_calloc (sizeof (char), nspaces2 + 1);
01288 for (i = 0; i < nspaces2; i++)
01289 spaces2[i] = ' ';
01290 spaces3 = cpl_calloc (sizeof (char), nspaces3 + 1);
01291 for (i = 0; i < nspaces3; i++)
01292 spaces3[i] = ' ';
01293 spaces4 = cpl_calloc (sizeof (char), nspaces4 + 1);
01294 for (i = 0; i < nspaces4; i++)
01295 spaces4[i] = ' ';
01296
01297 stars = cpl_calloc (sizeof (char), nstars + 1);
01298 for (i = 0; i < nstars; i++)
01299 stars[i] = '*';
01300
01301 xsh_msg ("%s", stars);
01302 xsh_msg ("*** %s%s%s ***", spaces1, PACKAGE_STRING, spaces2);
01303 xsh_msg ("*** %s%s%s ***", spaces3, recipe_string, spaces4);
01304 xsh_msg ("%s", stars);
01305 }
01306
01307 xsh_msg (" %s", short_descr);
01308
01309 check( *instrument = xsh_dfs_set_groups( frames));
01310 check( xsh_instrument_set_recipe_id( *instrument, recipe_id));
01311 p=xsh_parameters_find((cpl_parameterlist *)parameters,recipe_id,"decode-bp");
01312 decode_bp=cpl_parameter_get_int(p);
01313 check( xsh_instrument_set_decode_bp( *instrument, decode_bp));
01314 XSH_NEW_FRAMESET( *raws);
01315 XSH_NEW_FRAMESET( *calib);
01316 check( xsh_dfs_split_in_group( frames, *raws, *calib));
01317 check( xsh_dfs_filter( *raws, tag_list, tag_list_size));
01318 XSH_ASSURE_NOT_NULL( *raws);
01319 XSH_ASSURE_NOT_NULL( *instrument);
01320 xsh_dfs_files_dont_exist(frames);
01321 nraws=cpl_frameset_get_size(*raws);
01322
01323
01324
01325 xsh_msg("RAW files");
01326 check( xsh_print_cpl_frameset( *raws));
01327 xsh_msg("CALIB files");
01328 check( xsh_print_cpl_frameset( *calib));
01329
01330 if ((strcmp(recipe_id, "xsh_util_physmod") != 0)
01331 && (strcmp(recipe_id, "xsh_util_compute_response") != 0)) {
01332
01333 XSH_ASSURE_NOT_ILLEGAL_MSG(nraws>0,
01334 "Provide at least a valid input raw frame");
01335
01336
01337 if (xsh_instrument_get_arm(*instrument) == XSH_ARM_NIR) {
01338 xsh_instrument_nir_corr_if_JH(*raws, *instrument);
01339 if ((strcmp(recipe_id, "xsh_lingain") != 0)
01340 && (strcmp(recipe_id, "xsh_mdark") != 0)) {
01341 check(
01342 xsh_instrument_nir_corr_if_spectral_format_is_JH(*calib,*instrument));
01343 }
01344 xsh_calib_nir_corr_if_JH(*calib, *instrument, recipe_id);
01345 }
01346
01347 }
01348 cleanup:
01349 cpl_free (recipe_string);
01350 cpl_free (recipe_version);
01351 cpl_free (stars);
01352 cpl_free (spaces1);
01353 cpl_free (spaces2);
01354 cpl_free (spaces3);
01355 cpl_free (spaces4);
01356 return cpl_error_get_code ();
01357 }
01358
01359
01360
01361 static char **TempFiles = NULL ;
01362 static int NbTemp = 0 ;
01363 static char **ProdFiles = NULL ;
01364 static int NbProducts = 0 ;
01365
01366
01373
01374 void xsh_add_temporary_file( const char *name)
01375 {
01376 if ( TempFiles == NULL ){
01377 TempFiles = cpl_malloc( sizeof( char*));
01378 }
01379 else {
01380 TempFiles = cpl_realloc( TempFiles, (NbTemp + 1)*sizeof( char *));
01381 }
01382 TempFiles[NbTemp] = cpl_malloc( strlen( name) + 1);
01383 strcpy( TempFiles[NbTemp], name);
01384 NbTemp++;
01385 }
01386
01387
01392
01393 void xsh_free_temporary_files( void)
01394 {
01395 int i;
01396
01397 for( i = 0 ; i<NbTemp ; i++){
01398 cpl_free( TempFiles[i]);
01399 }
01400 cpl_free( TempFiles);
01401 TempFiles = NULL;
01402 NbTemp=0;
01403 }
01404
01405
01412
01413 void xsh_add_product_file( const char *name)
01414 {
01415 if ( ProdFiles == NULL ){
01416 ProdFiles = cpl_malloc( sizeof( char*));
01417 }
01418 else {
01419 ProdFiles = cpl_realloc( ProdFiles, (NbProducts + 1)*sizeof( char *));
01420 }
01421 ProdFiles[NbProducts] = cpl_malloc( strlen( name) + 1);
01422 strcpy( ProdFiles[NbProducts], name);
01423 NbProducts++;
01424 }
01425
01426
01431
01432 void xsh_free_product_files( void)
01433 {
01434 int i;
01435
01436 for( i = 0 ; i<NbProducts ; i++){
01437 cpl_free( ProdFiles[i]);
01438 }
01439 cpl_free( ProdFiles);
01440 ProdFiles=NULL;
01441 NbProducts=0;
01442 }
01443
01444
01445
01458
01459 cpl_error_code
01460 xsh_end (const char *recipe_id,
01461 cpl_frameset * frames,
01462 cpl_parameterlist * parameters )
01463 {
01464 int i;
01465 int warnings = xsh_msg_get_warnings ();
01466
01467
01468 {
01469 cpl_frame * current = NULL;
01470 int nframes = 0, j;
01471
01472 nframes = cpl_frameset_get_size( frames ) ;
01473 for( j = 0 ; j<nframes ; j++ ) {
01474 current = cpl_frameset_get_frame( frames, j);
01475 if ( cpl_frame_get_group( current ) == CPL_FRAME_GROUP_PRODUCT ) {
01476 xsh_print_cpl_frame( current ) ;
01477 }
01478 }
01479 }
01480 frames = frames ;
01481
01482
01483
01484 if ( xsh_parameters_get_temporary( recipe_id, parameters ) == 0 ) {
01485 xsh_msg( "---- Deleting Temporary Files" ) ;
01486 for( i = 0 ; i<NbTemp ; i++ ) {
01487 xsh_msg( " '%s'", TempFiles[i] ) ;
01488 unlink( TempFiles[i] ) ;
01489
01490 }
01491 } else {
01492
01493
01494
01495
01496
01497
01498
01499 }
01500
01501
01502 if (warnings > 0) {
01503 xsh_msg_warning ("Recipe '%s' produced %d warning %s (excluding this one)",
01504 recipe_id, xsh_msg_get_warnings (),
01505 (warnings > 1) ? "s" : "");
01506 }
01507
01508
01509 xsh_free_temporary_files();
01510 xsh_free_product_files();
01511 return cpl_error_get_code ();
01512 }
01513
01514
01539
01540 cpl_error_code
01541 xsh_get_property_value (const cpl_propertylist * plist,
01542 const char *keyword,
01543 cpl_type keywordtype,
01544 void *result)
01545 {
01546 cpl_type t;
01547
01548
01549 assure (plist != NULL, CPL_ERROR_NULL_INPUT, "Null property list");
01550 assure (keyword != NULL, CPL_ERROR_NULL_INPUT, "Null keyword");
01551
01552 assure (cpl_propertylist_has (plist, keyword), CPL_ERROR_DATA_NOT_FOUND,
01553 "Keyword %s does not exist", keyword);
01554
01555 check_msg (t = cpl_propertylist_get_type (plist, keyword),
01556 "Could not read type of keyword '%s'", keyword);
01557 assure (t == keywordtype, CPL_ERROR_TYPE_MISMATCH,
01558 "Keyword '%s' has wrong type (%s). %s expected",
01559 keyword, xsh_tostring_cpl_type (t),
01560 xsh_tostring_cpl_type (keywordtype));
01561
01562 switch (keywordtype) {
01563 case CPL_TYPE_INT:
01564 check_msg (*((int *) result) = cpl_propertylist_get_int (plist, keyword),
01565 "Could not get (integer) value of %s", keyword);
01566 break;
01567 case CPL_TYPE_BOOL:
01568 check_msg (*((bool *) result) = cpl_propertylist_get_bool (plist, keyword),
01569 "Could not get (boolean) value of %s", keyword);
01570 break;
01571 case CPL_TYPE_DOUBLE:
01572 check_msg (*((double *) result) =
01573 cpl_propertylist_get_double (plist, keyword),
01574 "Could not get (double) value of %s", keyword);
01575 break;
01576 case CPL_TYPE_STRING:
01577 check_msg (*((const char **) result) =
01578 cpl_propertylist_get_string (plist, keyword),
01579 "Could not get (string) value of %s", keyword);
01580 break;
01581 default:
01582 assure (false, CPL_ERROR_INVALID_TYPE, "Unknown type");
01583 }
01584
01585 cleanup:
01586 return cpl_error_get_code ();
01587 }
01588
01589
01597
01598 char *
01599 xsh_stringdup (const char *s)
01600 {
01601 char *result = NULL;
01602
01603 assure (s != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01604
01605 result = cpl_calloc (sizeof (char), strlen (s) + 1);
01606 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01607 "Memory allocation failed");
01608
01609 sprintf (result, "%s", s);
01610
01611 cleanup:
01612 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01613 cpl_free (result);
01614 result = NULL;
01615 }
01616
01617 return result;
01618 }
01619
01631 char *
01632 xsh_sdate_utc( time_t *now )
01633 {
01634 char *date = NULL;
01635 struct tm ttm;
01636
01637 ttm = *gmtime( now ) ;
01638 XSH_CALLOC( date, char, 16);
01639
01640 sprintf( date, "%04d%02d%02d-%02d%02d%02d",
01641 ttm.tm_year+1900, ttm.tm_mon+1, ttm.tm_mday,
01642 ttm.tm_hour, ttm.tm_min, ttm.tm_sec ) ;
01643
01644 cleanup:
01645 return date ;
01646
01647 }
01648
01649
01658
01659 char *
01660 xsh_stringcat (const char *s1, const char *s2)
01661 {
01662 char *result = NULL;
01663
01664 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01665 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01666
01667 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + 1);
01668 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01669 "Memory allocation failed");
01670
01671 sprintf (result, "%s%s", s1, s2);
01672
01673 cleanup:
01674 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01675 cpl_free (result);
01676 result = NULL;
01677 }
01678
01679 return result;
01680 }
01681
01682
01692
01693 char *
01694 xsh_stringcat_3 (const char *s1, const char *s2, const char *s3)
01695 {
01696 char *result = NULL;
01697
01698 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01699 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01700 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01701
01702 result =
01703 cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + strlen (s3) + 1);
01704 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01705 "Memory allocation failed");
01706
01707 sprintf (result, "%s%s%s", s1, s2, s3);
01708
01709 cleanup:
01710 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01711 cpl_free (result);
01712 result = NULL;
01713 }
01714
01715 return result;
01716 }
01717
01718
01730
01731 char *
01732 xsh_stringcat_4 (const char *s1, const char *s2, const char *s3,const char *s4)
01733 {
01734 char *result = NULL;
01735
01736 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01737 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01738 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01739 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01740
01741 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01742 strlen (s3) + strlen (s4) + 1);
01743 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01744 "Memory allocation failed");
01745
01746 sprintf (result, "%s%s%s%s", s1, s2, s3, s4);
01747
01748 cleanup:
01749 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01750 cpl_free (result);
01751 result = NULL;
01752 }
01753
01754 return result;
01755 }
01756
01757
01770
01771 char *
01772 xsh_stringcat_5 (const char *s1, const char *s2, const char *s3,
01773 const char *s4, const char *s5)
01774 {
01775 char *result = NULL;
01776
01777 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01778 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01779 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01780 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01781 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01782
01783 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01784 strlen (s3) +strlen (s4) + strlen (s5) + 1);
01785 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01786 "Memory allocation failed");
01787
01788 sprintf (result, "%s%s%s%s%s", s1, s2, s3, s4, s5);
01789
01790 cleanup:
01791 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01792 cpl_free (result);
01793 result = NULL;
01794 }
01795
01796 return result;
01797 }
01798
01799
01814
01815 char *
01816 xsh_stringcat_6 (const char *s1, const char *s2, const char *s3,
01817 const char *s4, const char *s5, const char *s6)
01818 {
01819 char *result = NULL;
01820
01821 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01822 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01823 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01824 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01825 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01826 assure (s6 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01827
01828 result = cpl_calloc (sizeof (char),
01829 strlen (s1) + strlen (s2) + strlen (s3) +
01830 strlen (s4) + strlen (s5) + strlen (s6) + 1);
01831 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01832 "Memory allocation failed");
01833
01834 sprintf (result, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6);
01835
01836 cleanup:
01837 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01838 cpl_free (result);
01839 result = NULL;
01840 }
01841
01842 return result;
01843 }
01844
01857 char *
01858 xsh_stringcat_any (const char *s, ...)
01859 {
01860 char *result = NULL;
01861 int size = 2;
01862 va_list av;
01863
01864 va_start (av, s);
01865 result = cpl_malloc (2);
01866 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01867 "Memory allocation failed");
01868 result[0] = '\0';
01869 for (;;) {
01870 size += strlen (s) + 2;
01871 result = cpl_realloc (result, size);
01872 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01873 "Memory allocation failed");
01874 strcat (result, s);
01875 s = va_arg (av, char *);
01876 if (s == NULL || *s == '\0')
01877 break;
01878 }
01879
01880 cleanup:
01881 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01882 cpl_free (result);
01883 result = NULL;
01884 }
01885
01886 va_end (av);
01887 return result;
01888 }
01889
01890
01898
01899 int* xsh_sort(void* base, size_t nmemb, size_t size,
01900 int (*compar)(const void *, const void *)) {
01901
01902 int i = 0;
01903 int * idx = NULL;
01904 xsh_sort_data* sort = NULL;
01905
01906
01907 XSH_ASSURE_NOT_NULL(base);
01908 XSH_ASSURE_NOT_ILLEGAL(nmemb > 0);
01909 XSH_ASSURE_NOT_ILLEGAL(size > 0);
01910 XSH_ASSURE_NOT_NULL(compar);
01911
01912
01913 XSH_MALLOC(idx,int,nmemb);
01914 XSH_MALLOC(sort,xsh_sort_data,nmemb);
01915
01916
01917 for( i=0; i< (int)nmemb; i++) {
01918 sort[i].data = (void*)((size_t)base+i*size);
01919 sort[i].idx = i;
01920 }
01921
01922
01923 qsort(sort,nmemb,sizeof(xsh_sort_data),compar);
01924
01925
01926 for( i=0; i< (int)nmemb; i++) {
01927 idx[i] = sort[i].idx;
01928 }
01929
01930 cleanup:
01931 XSH_FREE(sort);
01932 return idx;
01933 }
01934
01941 void xsh_reindex(double* data, int* idx, int size) {
01942 int i;
01943
01944
01945 XSH_ASSURE_NOT_NULL(data);
01946 XSH_ASSURE_NOT_NULL(idx);
01947 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01948
01949 for(i=0; i< size; i++){
01950 int id;
01951 double temp;
01952
01953 id = idx[i];
01954 while (id < i){
01955 id = idx[id];
01956 }
01957 temp = data[i];
01958 data[i] = data[id];
01959 data[id] = temp;
01960 }
01961 cleanup:
01962 return;
01963 }
01964
01971 void xsh_reindex_float(float * data, int* idx, int size)
01972 {
01973 int i;
01974
01975
01976 XSH_ASSURE_NOT_NULL(data);
01977 XSH_ASSURE_NOT_NULL(idx);
01978 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01979
01980 for(i=0; i< size; i++){
01981 int id;
01982 float temp;
01983
01984 id = idx[i];
01985 while (id < i){
01986 id = idx[id];
01987 }
01988 temp = data[i];
01989 data[i] = data[id];
01990 data[id] = temp;
01991 }
01992 cleanup:
01993 return;
01994 }
01995
01996
02003 void xsh_reindex_int( int * data, int* idx, int size)
02004 {
02005 int i;
02006
02007
02008 XSH_ASSURE_NOT_NULL(data);
02009 XSH_ASSURE_NOT_NULL(idx);
02010 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
02011
02012 for(i=0; i< size; i++){
02013 int id;
02014 int temp;
02015
02016 id = idx[i];
02017 while (id < i){
02018 id = idx[id];
02019 }
02020 temp = data[i];
02021 data[i] = data[id];
02022 data[id] = temp;
02023 }
02024 cleanup:
02025 return;
02026 }
02027
02028
02029
02034
02035 void xsh_free(const void *mem)
02036 {
02037 cpl_free((void *)mem);
02038 return;
02039 }
02040
02041
02042
02047
02048 void
02049 xsh_free_image (cpl_image ** i)
02050 {
02051 if (i && *i) {
02052 cpl_image_delete (*i);
02053 *i = NULL;
02054 }
02055 }
02056
02057
02058
02059
02064
02065 void
02066 xsh_free_table (cpl_table ** t)
02067 {
02068 if (t && *t) {
02069 cpl_table_delete (*t);
02070 *t = NULL;
02071 }
02072 }
02073
02074
02075
02080
02081 void
02082 xsh_free_mask (cpl_mask ** m)
02083 {
02084 if (m && *m) {
02085 cpl_mask_delete (*m);
02086 *m = NULL;
02087 }
02088 }
02089
02090
02095
02096 void
02097 xsh_free_imagelist (cpl_imagelist ** i)
02098 {
02099 if (i && *i) {
02100 cpl_imagelist_delete (*i);
02101 *i = NULL;
02102 }
02103 }
02104
02105
02110
02111 void
02112 xsh_free_propertylist (cpl_propertylist ** p)
02113 {
02114 if (p && *p) {
02115 cpl_propertylist_delete (*p);
02116 *p = NULL;
02117 }
02118 }
02119
02120
02125
02126 void
02127 xsh_free_polynomial (cpl_polynomial ** p)
02128 {
02129 if (p && *p) {
02130 cpl_polynomial_delete (*p);
02131 *p = NULL;
02132 }
02133 }
02134
02135
02140
02141 void
02142 xsh_free_matrix (cpl_matrix ** m)
02143 {
02144 if (m && *m) {
02145 cpl_matrix_delete (*m);
02146 *m = NULL;
02147 }
02148 }
02149
02150
02155
02156 void
02157 xsh_free_parameterlist (cpl_parameterlist ** p)
02158 {
02159 if (p && *p) {
02160 cpl_parameterlist_delete (*p);
02161 *p = NULL;
02162 }
02163 }
02164
02165
02170
02171 void
02172 xsh_free_parameter (cpl_parameter ** p)
02173 {
02174 if (p && *p) {
02175 cpl_parameter_delete (*p);
02176 *p = NULL;
02177 }
02178 }
02179
02180
02185
02186 void
02187 xsh_free_frameset (cpl_frameset ** f)
02188 {
02189 if (f && *f) {
02190 cpl_frameset_delete (*f);
02191 *f = NULL;
02192 }
02193 }
02194
02195
02200
02201 void
02202 xsh_free_frame (cpl_frame ** f)
02203 {
02204 if (f && *f) {
02205 cpl_frame_delete (*f);
02206 *f = NULL;
02207 }
02208 }
02209
02210
02215
02216 void
02217 xsh_free_vector (cpl_vector ** v)
02218 {
02219 if (v && *v) {
02220 cpl_vector_delete (*v);
02221 *v = NULL;
02222 }
02223 }
02224
02225
02230
02231 void
02232 xsh_free_array (cpl_array ** m)
02233 {
02234 if (m && *m) {
02235 cpl_array_delete (*m);
02236 *m = NULL;
02237 }
02238 }
02239
02240
02245
02246 void
02247 xsh_free_stats (cpl_stats ** s)
02248 {
02249 if (s && *s) {
02250 cpl_stats_delete (*s);
02251 *s = NULL;
02252 }
02253 }
02254
02255
02262
02263 void xsh_unwrap_image( cpl_image **i)
02264 {
02265 if ( i && *i) {
02266 cpl_image_unwrap( *i);
02267 *i = NULL;
02268 }
02269 }
02270
02271
02276
02277 void
02278 xsh_unwrap_vector (cpl_vector ** v)
02279 {
02280 if (v && *v) {
02281 cpl_vector_unwrap (*v);
02282 *v = NULL;
02283 }
02284 }
02285
02286
02287
02292
02293 void
02294 xsh_unwrap_array (cpl_array ** a)
02295 {
02296 if (a && *a) {
02297 cpl_array_unwrap (*a);
02298 *a = NULL;
02299 }
02300 }
02301
02302
02307
02308 void
02309 xsh_unwrap_bivector_vectors (cpl_bivector ** b)
02310 {
02311 if (b && *b) {
02312 cpl_bivector_unwrap_vectors (*b);
02313 *b = NULL;
02314 }
02315 }
02316
02317
02322 void xsh_show_time( const char *comment )
02323 {
02324 struct rusage tm0 ;
02325
02326 getrusage( 0, &tm0 ) ;
02327 xsh_msg( "%s - User: %u.%06u - Syst: %u.%06u",
02328 comment, (unsigned)tm0.ru_utime.tv_sec,
02329 (unsigned)tm0.ru_utime.tv_usec,
02330 (unsigned)tm0.ru_stime.tv_sec,
02331 (unsigned)tm0.ru_stime.tv_usec ) ;
02332 return ;
02333 }
02334
02335
02336 #define XSH_DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
02337 #define XSH_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; }
02338 #define XSH_INT_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; }
02339
02340 #define XSH_PIX_STACK_SIZE 50
02341
02342
02343
02353 void
02354 xsh_tools_get_statistics(double* tab, int size, double* median,
02355 double* mean, double* stdev)
02356 {
02357 cpl_vector* tab_vec = NULL;
02358 int i = 0;
02359
02360
02361 XSH_ASSURE_NOT_NULL( tab);
02362 XSH_ASSURE_NOT_ILLEGAL( size >= 0);
02363 XSH_ASSURE_NOT_NULL( median);
02364 XSH_ASSURE_NOT_NULL( mean);
02365 XSH_ASSURE_NOT_NULL( stdev);
02366
02367
02368 check (tab_vec = cpl_vector_new( size));
02369 for( i=0; i< size; i++){
02370 check( cpl_vector_set( tab_vec, i, tab[i]));
02371 }
02372
02373 check( *median = cpl_vector_get_median( tab_vec));
02374 check( *stdev = cpl_vector_get_stdev( tab_vec));
02375 check( *mean = cpl_vector_get_mean( tab_vec));
02376
02377 cleanup:
02378 xsh_free_vector( &tab_vec);
02379 return;
02380 }
02392
02393 cpl_error_code
02394 xsh_tools_sort_double( double * pix_arr, int n )
02395 {
02396 int i, ir, j, k, l;
02397 int * i_stack ;
02398 int j_stack ;
02399 double a ;
02400
02401
02402 if ( pix_arr == NULL ) {
02403 return CPL_ERROR_NULL_INPUT ;
02404 }
02405
02406 ir = n ;
02407 l = 1 ;
02408 j_stack = 0 ;
02409 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02410 for (;;) {
02411 if (ir-l < 7) {
02412 for (j=l+1 ; j<=ir ; j++) {
02413 a = pix_arr[j-1];
02414 for (i=j-1 ; i>=1 ; i--) {
02415 if (pix_arr[i-1] <= a) break;
02416 pix_arr[i] = pix_arr[i-1];
02417 }
02418 pix_arr[i] = a;
02419 }
02420 if (j_stack == 0) break;
02421 ir = i_stack[j_stack-- -1];
02422 l = i_stack[j_stack-- -1];
02423 } else {
02424 k = (l+ir) >> 1;
02425 XSH_DOUBLE_SWAP(pix_arr[k-1], pix_arr[l])
02426 if (pix_arr[l] > pix_arr[ir-1]) {
02427 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[ir-1])
02428 }
02429 if (pix_arr[l-1] > pix_arr[ir-1]) {
02430 XSH_DOUBLE_SWAP(pix_arr[l-1], pix_arr[ir-1])
02431 }
02432 if (pix_arr[l] > pix_arr[l-1]) {
02433 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[l-1])
02434 }
02435 i = l+1;
02436 j = ir;
02437 a = pix_arr[l-1];
02438 for (;;) {
02439 do i++; while (pix_arr[i-1] < a);
02440 do j--; while (pix_arr[j-1] > a);
02441 if (j < i) break;
02442 XSH_DOUBLE_SWAP(pix_arr[i-1], pix_arr[j-1]);
02443 }
02444 pix_arr[l-1] = pix_arr[j-1];
02445 pix_arr[j-1] = a;
02446 j_stack += 2;
02447 if (j_stack > XSH_PIX_STACK_SIZE) {
02448
02449 cpl_free(i_stack);
02450 return CPL_ERROR_ILLEGAL_INPUT ;
02451 }
02452 if (ir-i+1 >= j-l) {
02453 i_stack[j_stack-1] = ir;
02454 i_stack[j_stack-2] = i;
02455 ir = j-1;
02456 } else {
02457 i_stack[j_stack-1] = j-1;
02458 i_stack[j_stack-2] = l;
02459 l = i;
02460 }
02461 }
02462 }
02463 cpl_free(i_stack) ;
02464 return CPL_ERROR_NONE ;
02465 }
02466
02467
02479
02480 cpl_error_code
02481 xsh_tools_sort_float( float * pix_arr, int n )
02482 {
02483 int i, ir, j, k, l;
02484 int * i_stack ;
02485 int j_stack ;
02486 float a ;
02487
02488
02489 if ( pix_arr == NULL ) {
02490 return CPL_ERROR_NULL_INPUT ;
02491 }
02492
02493 ir = n ;
02494 l = 1 ;
02495 j_stack = 0 ;
02496 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(float)) ;
02497 for (;;) {
02498 if (ir-l < 7) {
02499 for (j=l+1 ; j<=ir ; j++) {
02500 a = pix_arr[j-1];
02501 for (i=j-1 ; i>=1 ; i--) {
02502 if (pix_arr[i-1] <= a) break;
02503 pix_arr[i] = pix_arr[i-1];
02504 }
02505 pix_arr[i] = a;
02506 }
02507 if (j_stack == 0) break;
02508 ir = i_stack[j_stack-- -1];
02509 l = i_stack[j_stack-- -1];
02510 } else {
02511 k = (l+ir) >> 1;
02512 XSH_FLOAT_SWAP(pix_arr[k-1], pix_arr[l])
02513 if (pix_arr[l] > pix_arr[ir-1]) {
02514 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[ir-1])
02515 }
02516 if (pix_arr[l-1] > pix_arr[ir-1]) {
02517 XSH_FLOAT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02518 }
02519 if (pix_arr[l] > pix_arr[l-1]) {
02520 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[l-1])
02521 }
02522 i = l+1;
02523 j = ir;
02524 a = pix_arr[l-1];
02525 for (;;) {
02526 do i++; while (pix_arr[i-1] < a);
02527 do j--; while (pix_arr[j-1] > a);
02528 if (j < i) break;
02529 XSH_FLOAT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02530 }
02531 pix_arr[l-1] = pix_arr[j-1];
02532 pix_arr[j-1] = a;
02533 j_stack += 2;
02534 if (j_stack > XSH_PIX_STACK_SIZE) {
02535
02536 cpl_free(i_stack);
02537 return CPL_ERROR_ILLEGAL_INPUT ;
02538 }
02539 if (ir-i+1 >= j-l) {
02540 i_stack[j_stack-1] = ir;
02541 i_stack[j_stack-2] = i;
02542 ir = j-1;
02543 } else {
02544 i_stack[j_stack-1] = j-1;
02545 i_stack[j_stack-2] = l;
02546 l = i;
02547 }
02548 }
02549 }
02550 cpl_free(i_stack) ;
02551 return CPL_ERROR_NONE ;
02552 }
02553
02554
02565 cpl_error_code
02566 xsh_tools_sort_int( int * pix_arr, int n)
02567 {
02568 int i, ir, j, k, l;
02569 int * i_stack ;
02570 int j_stack ;
02571 int a ;
02572
02573
02574 if ( pix_arr == NULL ) {
02575 return CPL_ERROR_NULL_INPUT ;
02576 }
02577
02578 ir = n ;
02579 l = 1 ;
02580 j_stack = 0 ;
02581 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02582 for (;;) {
02583 if (ir-l < 7) {
02584 for (j=l+1 ; j<=ir ; j++) {
02585 a = pix_arr[j-1];
02586 for (i=j-1 ; i>=1 ; i--) {
02587 if (pix_arr[i-1] <= a) break;
02588 pix_arr[i] = pix_arr[i-1];
02589 }
02590 pix_arr[i] = a;
02591 }
02592 if (j_stack == 0) break;
02593 ir = i_stack[j_stack-- -1];
02594 l = i_stack[j_stack-- -1];
02595 } else {
02596 k = (l+ir) >> 1;
02597 XSH_INT_SWAP(pix_arr[k-1], pix_arr[l])
02598 if (pix_arr[l] > pix_arr[ir-1]) {
02599 XSH_INT_SWAP(pix_arr[l], pix_arr[ir-1])
02600 }
02601 if (pix_arr[l-1] > pix_arr[ir-1]) {
02602 XSH_INT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02603 }
02604 if (pix_arr[l] > pix_arr[l-1]) {
02605 XSH_INT_SWAP(pix_arr[l], pix_arr[l-1])
02606 }
02607 i = l+1;
02608 j = ir;
02609 a = pix_arr[l-1];
02610 for (;;) {
02611 do i++; while (pix_arr[i-1] < a);
02612 do j--; while (pix_arr[j-1] > a);
02613 if (j < i) break;
02614 XSH_INT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02615 }
02616 pix_arr[l-1] = pix_arr[j-1];
02617 pix_arr[j-1] = a;
02618 j_stack += 2;
02619 if (j_stack > XSH_PIX_STACK_SIZE) {
02620
02621 cpl_free(i_stack);
02622 return CPL_ERROR_ILLEGAL_INPUT ;
02623 }
02624 if (ir-i+1 >= j-l) {
02625 i_stack[j_stack-1] = ir;
02626 i_stack[j_stack-2] = i;
02627 ir = j-1;
02628 } else {
02629 i_stack[j_stack-1] = j-1;
02630 i_stack[j_stack-2] = l;
02631 l = i;
02632 }
02633 }
02634 }
02635 cpl_free(i_stack) ;
02636 return CPL_ERROR_NONE ;
02637 }
02638
02654 double xsh_tools_get_median_double( double *array, int size )
02655 {
02656 double result = 0. ;
02657
02658
02659 xsh_tools_sort_double( array, size ) ;
02660
02661
02662 if ( (size % 2) == 1 ) result = *(array+(size/2)) ;
02663 else {
02664 double min, max ;
02665
02666 min = *(array+(size/2)-1) ;
02667 max = *(array+(size/2) ) ;
02668 result = (min+max)/2. ;
02669 }
02670
02671 return result ;
02672 }
02673
02680 int
02681 xsh_tools_running_median_1d_get_max( double * tab, int size, int wsize )
02682 {
02683 int position = 0;
02684 int i ;
02685 double * wtab = NULL ;
02686 double max = -1000000. ;
02687
02688 XSH_ASSURE_NOT_NULL( tab ) ;
02689 XSH_MALLOC( wtab, double, (wsize*2)*2 ) ;
02690
02691
02692
02693
02694
02695
02696
02697
02698 for( i = wsize ; i<(size-wsize) ; i++ ) {
02699 int j, k ;
02700 double f_max;
02701
02702
02703 for( k=0, j = i-wsize ; j<=(i+wsize) ; j++, k++ ) {
02704 wtab[k] = tab[j] ;
02705
02706 }
02707 if ( (f_max=xsh_tools_get_median_double(wtab, (wsize*2) + 1)) > max ) {
02708 max = f_max ;
02709 position = i ;
02710 }
02711 }
02712
02713
02714 cleanup:
02715 XSH_FREE( wtab ) ;
02716 return position ;
02717 }
02718
02719
02720
02729
02730
02731
02732 void xsh_tools_min_max(int size, double *tab, double *min, double *max)
02733 {
02734
02735 int i;
02736
02737 XSH_ASSURE_NOT_NULL(tab);
02738 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02739 XSH_ASSURE_NOT_NULL(min);
02740 XSH_ASSURE_NOT_NULL(max);
02741
02742 *min = tab[0];
02743 *max = tab[0];
02744
02745 for(i=1; i < size; i++) {
02746 if (tab[i] < *min){
02747 *min = tab[i];
02748 }
02749 else if ( tab[i] > *max) {
02750 *max = tab[i];
02751 }
02752 }
02753
02754 cleanup:
02755 return;
02756 }
02757
02769 cpl_vector* xsh_tools_tchebitchev_poly_eval( int n, double X)
02770 {
02771 cpl_vector *result = NULL;
02772
02773 XSH_ASSURE_NOT_ILLEGAL( n >=0);
02774 check( result = cpl_vector_new( n+1));
02775 check( cpl_vector_set(result, 0, 1.0));
02776
02777 if (n > 0){
02778 int indice = 2;
02779 check( cpl_vector_set(result, 1, X));
02780 while( indice <= n){
02781 double T_indice = 0.0;
02782 double T_indice_1 = 0.0;
02783 double T_indice_2 = 0.0;
02784
02785 check( T_indice_1 = cpl_vector_get( result, indice-1));
02786 check( T_indice_2 = cpl_vector_get( result, indice-2));
02787 T_indice = 2*X*T_indice_1-T_indice_2;
02788 check( cpl_vector_set( result, indice, T_indice));
02789 indice++;
02790 }
02791 }
02792 cleanup:
02793 if ( cpl_error_get_code() != CPL_ERROR_NONE){
02794 xsh_free_vector( &result);
02795 }
02796 return result;
02797 }
02798
02799
02800
02810
02811
02812
02813 void
02814 xsh_tools_tchebitchev_transform_tab(int size, double* pos, double min,
02815 double max, double* tcheb_pos)
02816 {
02817 int i;
02818 double a,b;
02819
02820 XSH_ASSURE_NOT_NULL(pos);
02821 XSH_ASSURE_NOT_NULL(tcheb_pos);
02822 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02823 XSH_ASSURE_NOT_ILLEGAL(min < max);
02824
02825 a = 2/ (max-min);
02826 b = 1-2*max/(max-min);
02827
02828 for(i=0; i < size; i++) {
02829 tcheb_pos[i] = pos[i]*a+b;
02830 if ( tcheb_pos[i] < -1. ) tcheb_pos[i] = -1. ;
02831 if ( tcheb_pos[i] > 1. ) tcheb_pos[i] = 1. ;
02832 }
02833
02834 cleanup:
02835 return;
02836 }
02837
02838
02839
02847
02848
02849 double
02850 xsh_tools_tchebitchev_transform(double pos, double min, double max)
02851 {
02852 double a,b;
02853 double res = 0.0;
02854
02855 XSH_ASSURE_NOT_ILLEGAL(min < max);
02856
02857 a = 2/ (max-min);
02858 b = 1-2*max/(max-min);
02859
02860 res = pos*a+b;
02861 if(res <= -1.000001) {
02862 xsh_msg_dbg_medium("OUT_OF_RANGE res <= -1.000001 for %f [%f,%f]",
02863 pos, min , max);
02864 }
02865 if(res >= +1.000001) {
02866 xsh_msg_dbg_medium("OUT_OF_RANGE res >= +1.000001 for %f [%f,%f]",
02867 pos, min , max);
02868 }
02869
02870
02871
02872
02873 cleanup:
02874 return res;
02875 }
02876
02877
02885
02886 double
02887 xsh_tools_tchebitchev_reverse_transform(double pos, double min, double max)
02888 {
02889 double a,b;
02890 double res = 0.0;
02891
02892 XSH_ASSURE_NOT_ILLEGAL(min < max);
02893
02894 a = 2/ (max-min);
02895 b = 1-2*max/(max-min);
02896
02897 res = (pos-b)/a;
02898
02899 cleanup:
02900 return res;
02901 }
02902
02903
02904
02911
02912 void
02913 xsh_image_fit_spline(cpl_image* img, xsh_grid* grid)
02914 {
02915 int nx, ny;
02916 int i = 0, ja, jb, idx = 0, vxsize, size;
02917 double *data = NULL;
02918 int *ylines = NULL;
02919 int *xline = NULL;
02920 double *vline = NULL;
02921 int nbylines;
02922 xsh_grid_point *pointA = NULL;
02923 xsh_grid_point *pointB = NULL;
02924
02925
02926 XSH_ASSURE_NOT_NULL( img);
02927 XSH_ASSURE_NOT_NULL( grid);
02928 XSH_ASSURE_NOT_ILLEGAL( cpl_image_get_type(img) == CPL_TYPE_DOUBLE);
02929
02930 check( data = cpl_image_get_data_double(img));
02931 check( nx = cpl_image_get_size_x(img));
02932 check( ny = cpl_image_get_size_y(img));
02933 check( size = xsh_grid_get_index(grid));
02934
02935 ja = 0;
02936 jb = ja+1;
02937 nbylines = 0;
02938 vxsize = 0;
02939
02940 XSH_MALLOC( ylines, int, ny);
02941 XSH_MALLOC( xline, int, nx);
02942 XSH_MALLOC( vline, double, nx);
02943
02944
02945 while( jb < size) {
02946 double a = 0.0, b = 0.0;
02947 int cur_y;
02948
02949 nbylines++;
02950 vxsize = 1;
02951
02952 check( pointA = xsh_grid_point_get( grid, ja));
02953 check( pointB = xsh_grid_point_get( grid, jb));
02954
02955 cur_y = pointA->y-1;
02956 ylines[nbylines-1]= cur_y;
02957 xline[vxsize-1] = pointA->x-1;
02958 vline[vxsize-1] = pointA->v;
02959
02960 while( ( jb < size) && ( pointA->y == pointB->y) ){
02961 check( pointB = xsh_grid_point_get( grid, jb));
02962
02963 if ( (pointB->x-1) != xline[vxsize-1]){
02964 xline[vxsize] = pointB->x-1;
02965 vline[vxsize] = pointB->v;
02966 vxsize++;
02967 }
02968 jb++;
02969 }
02970 XSH_ASSURE_NOT_ILLEGAL( vxsize >=2);
02971
02972 for(idx=0; idx<vxsize-1; idx++){
02973 int nbpix = 0;
02974 int xa, xb;
02975 double va, vb;
02976
02977 xa = xline[idx];
02978 xb = xline[idx+1];
02979
02980 va = vline[idx];
02981 vb = vline[idx+1];
02982
02983 a = ( vb - va) / ( xb - xa);
02984 b = va-a*xa;
02985
02986 nbpix = xb-xa;
02987
02988 for(i=0; i<= nbpix; i++){
02989 data[xa+i+cur_y*nx] = a*(xa+i)+b;
02990 }
02991 }
02992 ja=jb;
02993 jb=ja+1;
02994 }
02995
02996
02997 xsh_msg("interpolate in Y ");
02998
02999 for( ja=0; ja< nbylines-1; ja++) {
03000 int line1 = ylines[ja];
03001 int line2 = ylines[ja+1];
03002
03003 for(i=0; i< nx; i++){
03004 double val1 = data[i+line1*nx];
03005 double val2 = data[i+line2*nx];
03006 double a = (val2-val1)/(line2-line1);
03007 double b = val1;
03008 int k;
03009
03010 for(k=line1+1; k < line2; k++){
03011 data[i+k*nx] = a*(k-line1)+b;
03012 }
03013 }
03014 }
03015
03016 cleanup:
03017 XSH_FREE( ylines);
03018 XSH_FREE( xline);
03019 XSH_FREE( vline);
03020 return;
03021 }
03022
03023
03032
03033 void
03034 xsh_vector_fit_gaussian( cpl_vector * x,
03035 cpl_vector * y,
03036 XSH_GAUSSIAN_FIT * result )
03037 {
03038 XSH_ASSURE_NOT_NULL( x ) ;
03039 XSH_ASSURE_NOT_NULL( y ) ;
03040 XSH_ASSURE_NOT_NULL( result ) ;
03041
03042 cpl_vector_fit_gaussian( x, NULL, y, NULL, CPL_FIT_ALL, &result->peakpos,
03043 &result->sigma,
03044 &result->area, &result->offset, &result->mse,
03045 NULL, NULL ) ;
03046 cleanup:
03047 return ;
03048 }
03049
03050
03057
03058 int xsh_debug_level_set( int level )
03059 {
03060 int prev = XshDebugLevel ;
03061
03062 XshDebugLevel = level ;
03063
03064 return prev ;
03065 }
03066
03067
03073
03074 int
03075 xsh_debug_level_get( void )
03076 {
03077 return XshDebugLevel ;
03078 }
03079
03080
03086
03087 const char *
03088 xsh_debug_level_tostring( void )
03089 {
03090 switch ( XshDebugLevel ) {
03091 case XSH_DEBUG_LEVEL_NONE:
03092 return "none" ;
03093 case XSH_DEBUG_LEVEL_LOW:
03094 return "low" ;
03095 case XSH_DEBUG_LEVEL_MEDIUM:
03096 return "medium" ;
03097 case XSH_DEBUG_LEVEL_HIGH:
03098 return "high" ;
03099 default:
03100 return "unknown" ;
03101 }
03102 }
03103
03110
03111 int
03112 xsh_time_stamp_set( int ts )
03113 {
03114 int prev = XshTimeStamp ;
03115
03116 XshTimeStamp = ts ;
03117
03118 return prev ;
03119 }
03120
03121
03127
03128 int
03129 xsh_time_stamp_get( void )
03130 {
03131 return XshTimeStamp ;
03132 }
03133
03140 void
03141 xsh_mem_dump( const char * prompt)
03142 {
03143 fprintf( stderr, "\n******** %s *******\n", prompt ) ;
03144 cpl_memory_dump() ;
03145 }
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160 double
03161 convert_bin_to_data( double bin_data, int binning)
03162 {
03163 return (bin_data*binning-0.5*(binning-1));
03164 }
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178 double
03179 convert_data_to_bin( double data, int binning)
03180 {
03181 return (data+0.5*(binning-1))/binning;
03182 }
03183
03184
03185
03186
03187 static double
03188 date_to_double( const char * the_date )
03189 {
03190 int yy, mm, dd, hh, min, sec, millis ;
03191 int date, temps ;
03192 double fdate = 0 ;
03193
03194
03195 XSH_ASSURE_NOT_NULL( the_date ) ;
03196
03197 sscanf( the_date, "%d%*c%d%*c%d%*c%d%*c%d%*c%d%*c%d",
03198 &yy, &mm, &dd, &hh, &min, &sec, &millis ) ;
03199
03200 date = yy*10000 + mm*100 + dd ;
03201 temps = hh*10000000 + min*100000 + sec*1000 + millis ;
03202 fdate = (double)date + (double)temps/1000000000. ;
03203
03204 cleanup:
03205 return fdate ;
03206
03207 }
03208
03209 typedef struct {
03210 double frame_date ;
03211 int frame_idx ;
03212 cpl_frame * frame ;
03213 const char * frame_name ;
03214 } FRAME_DATE_IDX ;
03215
03216 static int
03217 compare_frame_date( const void * one, const void * two )
03218 {
03219 FRAME_DATE_IDX * first = (FRAME_DATE_IDX *)one,
03220 * scnd = (FRAME_DATE_IDX *)two ;
03221
03222 if ( first->frame_date > scnd->frame_date ) return 1 ;
03223 else if ( first->frame_date == scnd->frame_date ) return 0 ;
03224 else return -1 ;
03225 }
03226
03227
03228
03229
03230
03237
03238 cpl_frameset*
03239 xsh_order_frameset_by_date( cpl_frameset *frameset)
03240 {
03241 int nb, i ;
03242 FRAME_DATE_IDX *frame_date = NULL;
03243 cpl_frameset *result = NULL ;
03244 cpl_propertylist *header = NULL;
03245
03246 XSH_ASSURE_NOT_NULL( frameset);
03247
03248 check( nb = cpl_frameset_get_size( frameset));
03249 if ( nb <= 1 ) {
03250 check( result = cpl_frameset_duplicate( frameset));
03251 }
03252 else{
03253 XSH_CALLOC( frame_date, FRAME_DATE_IDX, nb);
03254
03255
03256 for( i = 0 ; i < nb ; i++){
03257 const char *fname = NULL ;
03258 cpl_frame *frame = NULL ;
03259 const char *the_date = NULL;
03260
03261
03262 check( frame = cpl_frameset_get_frame( frameset, i));
03263 check( fname = cpl_frame_get_filename( frame));
03264
03265
03266 check( header = cpl_propertylist_load( fname, 0));
03267
03268 check( the_date = xsh_pfits_get_date_obs( header));
03269
03270 frame_date[i].frame_date = date_to_double( the_date);
03271 frame_date[i].frame_idx = i;
03272 frame_date[i].frame = frame;
03273 frame_date[i].frame_name = fname;
03274
03275 xsh_free_propertylist( &header);
03276 }
03277
03278 qsort( frame_date, nb, sizeof( FRAME_DATE_IDX ), compare_frame_date ) ;
03279
03280 if ( xsh_debug_level_get() > XSH_DEBUG_LEVEL_NONE ) {
03281 for( i = 0 ; i<nb ; i++ ) {
03282 xsh_msg( "%d: %.9lf '%s'", frame_date[i].frame_idx,
03283 frame_date[i].frame_date, frame_date[i].frame_name);
03284 }
03285 }
03286
03287 check( result = cpl_frameset_new() ) ;
03288
03289
03290 for( i = 0 ; i <nb ; i++ ){
03291 check( cpl_frameset_insert( result,
03292 cpl_frame_duplicate(frame_date[i].frame)));
03293 }
03294 }
03295 cleanup:
03296 if ( cpl_error_get_code() != CPL_ERROR_NONE){
03297 xsh_free_frameset( &result);
03298 }
03299 xsh_free_propertylist( &header);
03300 XSH_FREE( frame_date);
03301 return result;
03302 }
03303
03304
03305
03353
03354
03355 polynomial *
03356 xsh_polynomial_regression_2d(cpl_table *t, const char *X1, const char *X2,
03357 const char *Y, const char *sigmaY, int degree1, int degree2,
03358 const char *polynomial_fit, const char *residual_square,
03359 const char *variance_fit, double *mse, double *red_chisq,
03360 polynomial **variance, double kappa, double min_reject) {
03361 int N;
03362 int rejected;
03363 int total_rejected;
03364 double *x1 = NULL;
03365 double *x2 = NULL;
03366 double *y = NULL;
03367 double *res = NULL;
03368 double *sy = NULL;
03369 polynomial *p = NULL;
03370 polynomial *variance_local = NULL;
03371 cpl_vector *vx1 = NULL;
03372 cpl_vector *vx2 = NULL;
03373 cpl_bivector *vx = NULL;
03374 cpl_vector *vy = NULL;
03375 cpl_vector *vsy = NULL;
03376 cpl_type type;
03377
03378
03379 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03380 assure( cpl_table_has_column(t, X1), CPL_ERROR_ILLEGAL_INPUT,
03381 "No such column: %s", X1);
03382 assure( cpl_table_has_column(t, X2), CPL_ERROR_ILLEGAL_INPUT,
03383 "No such column: %s", X2);
03384 assure( cpl_table_has_column(t, Y), CPL_ERROR_ILLEGAL_INPUT,
03385 "No such column: %s", Y);
03386 assure( (variance == NULL && variance_fit == NULL) || sigmaY != NULL,
03387 CPL_ERROR_INCOMPATIBLE_INPUT,
03388 "Cannot calculate variances without sigmaY");
03389 if (sigmaY != NULL) {
03390 assure( cpl_table_has_column(t, sigmaY), CPL_ERROR_ILLEGAL_INPUT,
03391 "No such column: %s", sigmaY);
03392 }
03393 if (polynomial_fit != NULL) {
03394 assure( !cpl_table_has_column(t, polynomial_fit), CPL_ERROR_ILLEGAL_INPUT,
03395 "Table already has '%s' column", polynomial_fit);
03396 }
03397 if (residual_square != NULL) {
03398 assure( !cpl_table_has_column(t, residual_square), CPL_ERROR_ILLEGAL_INPUT,
03399 "Table already has '%s' column", residual_square);
03400 }
03401 if (variance_fit != NULL) {
03402 assure( !cpl_table_has_column(t, variance_fit), CPL_ERROR_ILLEGAL_INPUT,
03403 "Table already has '%s' column", variance_fit);
03404 }
03405
03406
03407 type = cpl_table_get_column_type(t, X1);
03408 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE,
03409 CPL_ERROR_INVALID_TYPE,
03410 "Input column '%s' has wrong type (%s)", X1, xsh_tostring_cpl_type(type));
03411 type = cpl_table_get_column_type(t, X2);
03412 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE,
03413 CPL_ERROR_INVALID_TYPE,
03414 "Input column '%s' has wrong type (%s)", X2, xsh_tostring_cpl_type(type));
03415 type = cpl_table_get_column_type(t, Y);
03416 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE,
03417 CPL_ERROR_INVALID_TYPE,
03418 "Input column '%s' has wrong type (%s)", Y, xsh_tostring_cpl_type(type));
03419 if (sigmaY != NULL) {
03420 type = cpl_table_get_column_type(t, sigmaY);
03421 assure(
03422 type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE,
03423 CPL_ERROR_INVALID_TYPE,
03424 "Input column '%s' has wrong type (%s)", sigmaY, xsh_tostring_cpl_type(type));
03425 }
03426
03427
03428 check_msg( cpl_table_cast_column(t, X1, "_X1_double", CPL_TYPE_DOUBLE),
03429 "Could not cast table column to double");
03430 check_msg( cpl_table_cast_column(t, X2, "_X2_double", CPL_TYPE_DOUBLE),
03431 "Could not cast table column to double");
03432 check_msg( cpl_table_cast_column(t, Y, "_Y_double", CPL_TYPE_DOUBLE),
03433 "Could not cast table column to double");
03434 if (sigmaY != NULL) {
03435 check_msg( cpl_table_cast_column(t, sigmaY, "_sY_double", CPL_TYPE_DOUBLE),
03436 "Could not cast table column to double");
03437 }
03438
03439 total_rejected = 0;
03440 rejected = 0;
03441 check_msg( cpl_table_new_column(t, "_residual_square", CPL_TYPE_DOUBLE),
03442 "Could not create column");
03443
03444 do {
03445
03446
03447 check_msg(
03448 ( N = cpl_table_get_nrow(t), x1 = cpl_table_get_data_double(t, "_X1_double"), x2 = cpl_table_get_data_double(t, "_X2_double"), y = cpl_table_get_data_double(t, "_Y_double"), res= cpl_table_get_data_double(t, "_residual_square")),
03449 "Could not read table data");
03450
03451 if (sigmaY != NULL) {
03452 check_msg(sy = cpl_table_get_data_double(t, "_sY_double"),
03453 "Could not read table data");
03454 } else {
03455 sy = NULL;
03456 }
03457
03458 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03459
03460
03461 xsh_unwrap_vector(&vx1);
03462 xsh_unwrap_vector(&vx2);
03463 xsh_unwrap_vector(&vy);
03464
03465 vx1 = cpl_vector_wrap(N, x1);
03466 vx2 = cpl_vector_wrap(N, x2);
03467 vy = cpl_vector_wrap(N, y);
03468 if (sy != NULL) {
03469 xsh_unwrap_vector(&vsy);
03470 vsy = cpl_vector_wrap(N, sy);
03471 } else {
03472 vsy = NULL;
03473 }
03474
03475
03476 xsh_unwrap_bivector_vectors(&vx);
03477 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03478
03479
03480 xsh_polynomial_delete(&p);
03481 check_msg(
03482 p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2, NULL, NULL, NULL),
03483 "Could not fit polynomial");
03484
03485
03486 if (kappa > 0) {
03487 double sigma2;
03488 int i;
03489
03490 cpl_table_fill_column_window_double(t, "_residual_square", 0,
03491 cpl_table_get_nrow(t), 0.0);
03492
03493 for (i = 0; i < N; i++) {
03494 double yval, yfit;
03495
03496 yval = y[i];
03497 yfit = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03498 res[i] = (yfit - yval) * (yfit - yval);
03499 }
03500
03501
03502
03503
03504
03505
03506
03507 sigma2 = cpl_table_get_column_median(t, "_residual_square")
03508 / (0.6744 * 0.6744);
03509
03510
03511 check_msg(
03512 rejected = xsh_erase_table_rows(t, "_residual_square", CPL_GREATER_THAN, kappa*kappa*sigma2),
03513 "Could not remove outlier points");
03514
03515
03516 xsh_msg_debug(
03517 "%d of %d points rejected in kappa-sigma clipping. rms=%f", rejected, N, sqrt(sigma2));
03518
03519
03520 total_rejected += rejected;
03521 N = cpl_table_get_nrow(t);
03522 }
03523
03524
03525
03526
03527 } while (rejected > 0 && rejected > min_reject * (N + rejected)
03528 && N >= (degree1 + 1) * (degree2 + 1) + 1);
03529
03530 if (kappa > 0) {
03531 xsh_msg_debug(
03532 "%d of %d points (%f %%) rejected in kappa-sigma clipping", total_rejected, N + total_rejected, (100.0*total_rejected)/(N + total_rejected));
03533 }
03534
03535
03536 {
03537
03538
03539
03540
03541 check_msg(
03542 ( N = cpl_table_get_nrow(t), x1 = cpl_table_get_data_double(t, "_X1_double"), x2 = cpl_table_get_data_double(t, "_X2_double"), y = cpl_table_get_data_double(t, "_Y_double"), res= cpl_table_get_data_double(t, "_residual_square")),
03543 "Could not read table data");
03544
03545 if (sigmaY != NULL) {
03546 check_msg(sy = cpl_table_get_data_double(t, "_sY_double"),
03547 "Could not read table data");
03548 } else {
03549 sy = NULL;
03550 }
03551
03552 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03553
03554
03555 xsh_unwrap_vector(&vx1);
03556 xsh_unwrap_vector(&vx2);
03557 xsh_unwrap_vector(&vy);
03558
03559 vx1 = cpl_vector_wrap(N, x1);
03560 vx2 = cpl_vector_wrap(N, x2);
03561 vy = cpl_vector_wrap(N, y);
03562 if (sy != NULL) {
03563 xsh_unwrap_vector(&vsy);
03564 vsy = cpl_vector_wrap(N, sy);
03565 } else {
03566 vsy = NULL;
03567 }
03568
03569
03570 xsh_unwrap_bivector_vectors(&vx);
03571 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03572 }
03573
03574 xsh_polynomial_delete(&p);
03575 if (variance_fit != NULL || variance != NULL) {
03576
03577 check_msg(
03578 p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2, mse, red_chisq, &variance_local),
03579 "Could not fit polynomial");
03580 } else {
03581 check_msg(
03582 p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2, mse, red_chisq, NULL),
03583 "Could not fit polynomial");
03584 }
03585
03586 cpl_table_erase_column(t, "_residual_square");
03587
03588
03589 if (polynomial_fit != NULL || residual_square != NULL) {
03590 int i;
03591 double *pf;
03592
03593 check_msg( cpl_table_new_column(t, "_polynomial_fit", CPL_TYPE_DOUBLE),
03594 "Could not create column");
03595
03596 cpl_table_fill_column_window_double(t, "_polynomial_fit", 0,
03597 cpl_table_get_nrow(t), 0.0);
03598
03599 x1 = cpl_table_get_data_double(t, "_X1_double");
03600 x2 = cpl_table_get_data_double(t, "_X2_double");
03601 pf = cpl_table_get_data_double(t, "_polynomial_fit");
03602
03603 for (i = 0; i < N; i++) {
03604 #if 0
03605 double x1val, x2val, yfit;
03606
03607 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03608 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03609 yfit = xsh_polynomial_evaluate_2d(p, x1val, x2val),
03610
03611 cpl_table_set_double(t, "_polynomial_fit", i, yfit)),
03612 "Could not evaluate polynomial");
03613
03614 #else
03615 pf[i] = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03616 #endif
03617 }
03618
03619
03620 if (residual_square != NULL) {
03621 check_msg(( cpl_table_duplicate_column(t, residual_square,
03622 t, "_polynomial_fit"), cpl_table_subtract_columns(t, residual_square, Y),
03623 cpl_table_multiply_columns(t, residual_square, residual_square)),
03624
03625 "Could not calculate Residual of fit");
03626 }
03627
03628
03629 if (polynomial_fit != NULL) {
03630 cpl_table_name_column(t, "_polynomial_fit", polynomial_fit);
03631 } else {
03632 cpl_table_erase_column(t, "_polynomial_fit");
03633 }
03634 }
03635
03636
03637 if (variance_fit != NULL) {
03638 int i;
03639 double *vf;
03640
03641 check_msg( cpl_table_new_column(t, variance_fit, CPL_TYPE_DOUBLE),
03642 "Could not create column");
03643
03644 cpl_table_fill_column_window_double(t, variance_fit, 0,
03645 cpl_table_get_nrow(t), 0.0);
03646
03647 x1 = cpl_table_get_data_double(t, "_X1_double");
03648 x2 = cpl_table_get_data_double(t, "_X2_double");
03649 vf = cpl_table_get_data_double(t, variance_fit);
03650
03651 for (i = 0; i < N; i++) {
03652 #if 0
03653 double x1val, x2val, yfit_variance;
03654 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03655 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03656 yfit_variance = xsh_polynomial_evaluate_2d(variance_local,
03657 x1val, x2val),
03658
03659 cpl_table_set_double(t, variance_fit, i, yfit_variance)),
03660 "Could not evaluate polynomial");
03661 #else
03662 vf[i] = xsh_polynomial_evaluate_2d(variance_local, x1[i], x2[i]);
03663 #endif
03664
03665 }
03666 }
03667
03668 check_msg(
03669 ( cpl_table_erase_column(t, "_X1_double"), cpl_table_erase_column(t, "_X2_double"), cpl_table_erase_column(t, "_Y_double")),
03670 "Could not delete temporary columns");
03671
03672 if (sigmaY != NULL) {
03673 check_msg( cpl_table_erase_column(t, "_sY_double"),
03674 "Could not delete temporary column");
03675 }
03676
03677 cleanup: xsh_unwrap_bivector_vectors(&vx);
03678 xsh_unwrap_vector(&vx1);
03679 xsh_unwrap_vector(&vx2);
03680 xsh_unwrap_vector(&vy);
03681 xsh_unwrap_vector(&vsy);
03682
03683 if (variance != NULL) {
03684 *variance = variance_local;
03685 } else {
03686 xsh_polynomial_delete(&variance_local);
03687 }
03688 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03689 xsh_polynomial_delete(&p);
03690 }
03691
03692 return p;
03693 }
03694
03695
03696
03697
03714
03715
03716 int
03717 xsh_select_table_rows(cpl_table *t,
03718 const char *column,
03719 cpl_table_select_operator operator,
03720 double value)
03721 {
03722 int result = 0;
03723 cpl_type type;
03724
03725 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03726 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03727 "No such column: %s", column);
03728
03729 type = cpl_table_get_column_type(t, column);
03730
03731 assure( type == CPL_TYPE_DOUBLE || type == CPL_TYPE_FLOAT ||
03732 type == CPL_TYPE_INT, CPL_ERROR_INVALID_TYPE,
03733 "Column '%s' must be double or int. %s found", column,
03734 xsh_tostring_cpl_type(type));
03735
03736 check_msg( cpl_table_select_all(t), "Error selecting rows");
03737
03738 if (type == CPL_TYPE_DOUBLE)
03739 {
03740 result = cpl_table_and_selected_double(t, column, operator, value);
03741 }
03742 else if (type == CPL_TYPE_FLOAT)
03743 {
03744 result = cpl_table_and_selected_float(t, column, operator, value);
03745 }
03746 else if (type == CPL_TYPE_INT)
03747 {
03748 result = cpl_table_and_selected_int(t, column, operator,
03749 xsh_round_double(value));
03750 }
03751 else { passure(false, ""); }
03752
03753 cleanup:
03754 return result;
03755
03756 }
03757
03758
03759
03760
03761
03780
03781 int
03782 xsh_erase_table_rows(cpl_table *t,
03783 const char *column,
03784 cpl_table_select_operator operator,
03785 double value)
03786 {
03787 int result = 0;
03788
03789 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03790 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03791 "No such column: %s", column);
03792
03793 check_msg( result = xsh_select_table_rows(t, column, operator, value),
03794 "Error selecting rows");
03795
03796 check_msg( cpl_table_erase_selected(t), "Error deleting rows");
03797
03798 cleanup:
03799 return result;
03800 }
03801
03810
03811 cpl_frame* xsh_frame_inv( cpl_frame* in, const char *filename,
03812 xsh_instrument* instr)
03813 {
03814 xsh_pre *pre = NULL;
03815 cpl_frame *result = NULL;
03816 const char* tag = "INV_PRE";
03817
03818 XSH_ASSURE_NOT_NULL( in);
03819 XSH_ASSURE_NOT_NULL( instr);
03820
03821 check( pre = xsh_pre_load( in, instr));
03822 check( xsh_pre_multiply_scalar( pre, -1.0));
03823 check( result = xsh_pre_save( pre, filename, tag, 1));
03824 check( cpl_frame_set_tag( result, tag));
03825
03826 cleanup:
03827 if (cpl_error_get_code() != CPL_ERROR_NONE){
03828 xsh_free_frame( &result);
03829 }
03830 xsh_pre_free( &pre);
03831 return result;
03832 }
03833
03834
03835
03843
03844 cpl_frame* xsh_frame_abs( cpl_frame* in, xsh_instrument* instr,
03845 cpl_frame** sign)
03846 {
03847 xsh_pre *pre = NULL;
03848 cpl_frame *result = NULL;
03849 cpl_frame *sign_frame = NULL;
03850 char name[256];
03851 const char* tag = "ABS_PRE";
03852 const char* sign_tag = "SIGN_PRE";
03853 const char *filename = NULL;
03854 cpl_image *sign_img = NULL;
03855
03856 XSH_ASSURE_NOT_NULL( in);
03857 XSH_ASSURE_NOT_NULL( sign);
03858
03859 check( filename = cpl_frame_get_filename( in));
03860 check( pre = xsh_pre_load( in, instr));
03861 check( sign_img = xsh_pre_abs( pre));
03862 sprintf( name ,"ABS_%s", filename);
03863 check( result = xsh_pre_save( pre, name, tag, 1));
03864 check( cpl_frame_set_tag( result, tag));
03865 sprintf( name ,"SIGN_%s", filename);
03866 check( cpl_image_save( sign_img, name, CPL_BPP_32_SIGNED,
03867 NULL,CPL_IO_DEFAULT));
03868 xsh_add_temporary_file(name);
03869 check( sign_frame = cpl_frame_new());
03870 check( cpl_frame_set_filename( sign_frame, name));
03871 check( cpl_frame_set_tag( sign_frame, sign_tag));
03872 *sign = sign_frame;
03873
03874 cleanup:
03875 if (cpl_error_get_code() != CPL_ERROR_NONE){
03876 xsh_free_frame( &result);
03877 }
03878 xsh_free_image( &sign_img);
03879 xsh_pre_free( &pre);
03880 return result;
03881 }
03882
03889 void
03890 xsh_frame_image_save(cpl_frame* frm,const char* name_o)
03891 {
03892 cpl_image* ima=NULL;
03893 const char* name=NULL;
03894 name=cpl_frame_get_filename(frm);
03895 ima=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
03896
03897 cpl_image_save(ima,name_o,CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
03898 xsh_free_image(&ima);
03899
03900
03901 return;
03902 }
03903
03904
03911 void
03912 xsh_frame_table_save(cpl_frame* frame,const char* name_o)
03913 {
03914 const char* fname=NULL;
03915
03916 int nbext=0;
03917 int extension ;
03918 cpl_table *tbl_ext = NULL;
03919 cpl_propertylist *tbl_ext_header = NULL;
03920 cpl_propertylist *primary_header = NULL;
03921 int i=0;
03922
03923 fname=cpl_frame_get_filename(frame);
03924 nbext = cpl_frame_get_nextensions( frame);
03925
03926 for( i = 0 ; i<nbext ; i++ ) {
03927
03928 check( tbl_ext = cpl_table_load( fname, i+1, 0));
03929 check( tbl_ext_header = cpl_propertylist_load( fname, i+1));
03930
03931 if ( i == 0 ) extension = CPL_IO_DEFAULT ;
03932 else extension = CPL_IO_EXTEND ;
03933 check(cpl_table_save( tbl_ext, primary_header, tbl_ext_header,
03934 name_o, extension));
03935 xsh_free_table( &tbl_ext);
03936 xsh_free_propertylist( &tbl_ext_header);
03937
03938 }
03939
03940 cleanup:
03941 xsh_free_table( &tbl_ext);
03942 xsh_free_propertylist( &tbl_ext_header);
03943
03944 return;
03945 }
03946
03955
03956 cpl_frame* xsh_frame_mult( cpl_frame* in, xsh_instrument* instr,
03957 cpl_frame* sign)
03958 {
03959 xsh_pre *pre = NULL;
03960 cpl_frame *result = NULL;
03961 cpl_image *sign_img = NULL;
03962 const char* name = NULL;
03963 const char* tag = "MULT_IMG_PRE";
03964
03965 XSH_ASSURE_NOT_NULL( in);
03966 XSH_ASSURE_NOT_NULL( sign);
03967
03968 check( name = cpl_frame_get_filename( sign));
03969 check( pre = xsh_pre_load( in, instr));
03970 check( sign_img = cpl_image_load( name, CPL_TYPE_INT, 0, 0));
03971 check( xsh_pre_multiply_image( pre, sign_img));
03972 check( result = xsh_pre_save( pre, "RESTORE_PRE.fits", tag, 1));
03973 check( cpl_frame_set_tag( result, tag));
03974
03975 cleanup:
03976 if (cpl_error_get_code() != CPL_ERROR_NONE){
03977 xsh_free_frame( &result);
03978 }
03979 xsh_free_image( &sign_img);
03980 xsh_pre_free( &pre);
03981 return result;
03982 }
03983
03984
03998
03999
04000
04001 cpl_error_code
04002 xsh_monitor_flux(cpl_frame* frm_ima,const cpl_frame* frm_tab,
04003 xsh_instrument *instrument)
04004 {
04005
04006 int ord_min=0;
04007 int ord_max=0;
04008 int i=0;
04009 const char* name_ima=NULL;
04010 const char* name_tab=NULL;
04011 cpl_table* tab=NULL;
04012 cpl_image* ima=NULL;
04013 cpl_table* ext=NULL;
04014 int next=0;
04015 double* cx=NULL;
04016 double* cy=NULL;
04017 int ix=0;
04018 int iy=0;
04019 double flux_min_init=FLT_MAX;
04020 double flux_max_init=-FLT_MAX;
04021
04022 double flux_min_ord=flux_min_init;
04023 double flux_max_ord=flux_max_init;
04024
04025 double flux_min=flux_min_init;
04026 double flux_max=flux_max_init;
04027 double* pima=NULL;
04028 double flux=0;
04029 cpl_propertylist* plist=NULL;
04030 char qc_flux_min[20];
04031 char qc_flux_max[20];
04032 int sx=0;
04033 int sy=0;
04034 int j=0;
04035 int binx=1;
04036 int biny=1;
04037
04038 cpl_ensure_code(frm_ima != NULL, CPL_ERROR_NULL_INPUT);
04039 cpl_ensure_code(frm_tab != NULL, CPL_ERROR_NULL_INPUT);
04040
04041 check(name_ima=cpl_frame_get_filename(frm_ima));
04042 check(name_tab=cpl_frame_get_filename(frm_tab));
04043
04044 check(plist=cpl_propertylist_load(name_ima,0));
04045
04046 if( xsh_instrument_get_arm( instrument) != XSH_ARM_NIR){
04047 binx=xsh_pfits_get_binx(plist);
04048 biny=xsh_pfits_get_biny(plist);
04049 }
04050 check(tab=cpl_table_load(name_tab,2,0));
04051 check(ima=cpl_image_load(name_ima,CPL_TYPE_DOUBLE,0,0));
04052 check(sx=cpl_image_get_size_x(ima));
04053 check(sy=cpl_image_get_size_y(ima));
04054
04055
04056
04057
04058 check(pima=cpl_image_get_data_double(ima));
04059 check(ord_min=cpl_table_get_column_min(tab,"ABSORDER"));
04060 check(ord_max=cpl_table_get_column_max(tab,"ABSORDER"));
04061
04062
04063 for(i=ord_min;i<=ord_max;i++) {
04064 flux_min_ord=flux_min_init;
04065 flux_max_ord=flux_max_init;
04066
04067 check(next=cpl_table_and_selected_int(tab,"ABSORDER",CPL_EQUAL_TO,i));
04068 ext=cpl_table_extract_selected(tab);
04069 cx=cpl_table_get_data_double(ext,"CENTER_X");
04070 cy=cpl_table_get_data_double(ext,"CENTER_Y");
04071 for(j=0;j<next;j++) {
04072
04073 ix=(int)(cx[j]/binx+0.5);
04074 iy=(int)(cy[j]/biny+0.5);
04075
04076 if( ( (ix>=0) && (ix<sx) ) &&
04077 ( (iy>=0) && (iy<sy) ) ) {
04078 check(flux=pima[ix+sx*iy]);
04079 if(!isnan(flux)) {
04080 if(flux<flux_min_ord) {
04081 flux_min_ord=flux;
04082 continue;
04083 }
04084 if(flux>flux_max_ord) {
04085 flux_max_ord=flux;
04086 }
04087
04088 }
04089 }
04090
04091
04092 }
04093 xsh_free_table(&ext);
04094 cpl_table_select_all(tab);
04095 if(next>1) {
04096 flux_min=(flux_min_ord<flux_min)? flux_min_ord:flux_min;
04097 flux_max=(flux_max_ord>flux_max)? flux_max_ord:flux_max;
04098 }
04099 sprintf(qc_flux_min,"%s%d%s",XSH_QC_FLUX,i," MIN");
04100 sprintf(qc_flux_max,"%s%d%s",XSH_QC_FLUX,i," MAX");
04101
04102
04103 cpl_propertylist_append_double(plist,qc_flux_min,flux_min_ord);
04104 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04105 cpl_propertylist_append_double(plist,qc_flux_max,flux_max_ord);
04106 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04107 }
04108
04109 sprintf(qc_flux_min,"%s%s",XSH_QC_FLUX," MIN");
04110 sprintf(qc_flux_max,"%s%s",XSH_QC_FLUX," MAX");
04111 cpl_propertylist_append_double(plist,qc_flux_min,flux_min);
04112 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04113 cpl_propertylist_append_double(plist,qc_flux_max,flux_max);
04114 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04115 check(xsh_update_pheader_in_image_multi(frm_ima,plist));
04116
04117 cleanup:
04118 xsh_free_table(&ext);
04119 xsh_free_image(&ima);
04120 xsh_free_table(&tab);
04121 xsh_free_propertylist(&plist);
04122
04123
04124 return cpl_error_get_code();
04125
04126 }
04127
04128
04140
04141
04142 cpl_error_code
04143 xsh_update_pheader_in_image_multi(cpl_frame *frame,
04144 const cpl_propertylist* pheader)
04145 {
04146 const char *fname = NULL;
04147 int nbext=0;
04148 int i=0;
04149 cpl_image *image = NULL ;
04150 char cmd[256];
04151 int extension=0 ;
04152 cpl_image* ext_img=NULL;
04153 cpl_propertylist* ext_header=NULL;
04154
04155 XSH_ASSURE_NOT_NULL(frame);
04156 nbext = cpl_frame_get_nextensions( frame);
04157 xsh_msg_dbg_medium("nbext=%d",nbext);
04158 check( fname = cpl_frame_get_filename( frame));
04159 check( image = cpl_image_load( fname, CPL_TYPE_FLOAT, 0, 0));
04160
04161
04162
04163
04164 cpl_image_save(image, "tmp.fits", CPL_BPP_IEEE_FLOAT, pheader,
04165 CPL_IO_DEFAULT ) ;
04166 xsh_free_image(&image);
04167 xsh_msg_dbg_medium("fname=%s",fname);
04168 for( i = 1 ; i<=nbext ; i++ ) {
04169
04170 check( ext_img = cpl_image_load( fname, CPL_TYPE_FLOAT,0, i));
04171 check( ext_header = cpl_propertylist_load( fname ,i));
04172
04173 if ( i == 0 ) {
04174 extension = CPL_IO_DEFAULT ;
04175 }
04176 else {
04177 extension = CPL_IO_EXTEND ;
04178 check(cpl_image_save( ext_img, "tmp.fits", CPL_BPP_IEEE_FLOAT,ext_header,
04179 extension));
04180 }
04181 xsh_free_image( &ext_img) ;
04182 xsh_free_propertylist( &ext_header) ;
04183 }
04184
04185 sprintf(cmd,"mv tmp.fits %s",fname);
04186 system(cmd);
04187 system("rm -f tmp.fits");
04188
04189
04190 cleanup:
04191 xsh_free_image( &ext_img) ;
04192 xsh_free_propertylist( &ext_header) ;
04193 xsh_free_image(&image);
04194
04195 return cpl_error_get_code();
04196 }
04197
04203
04204 double xsh_vector_get_err_median( cpl_vector *vect)
04205 {
04206 double err_median =0.0;
04207 int i, vect_size =0;
04208 double *data = NULL;
04209
04210 XSH_ASSURE_NOT_NULL( vect);
04211
04212 check( vect_size = cpl_vector_get_size( vect));
04213 check( data = cpl_vector_get_data( vect));
04214
04215 if (vect_size > 1){
04216 for( i=0; i< vect_size; i++){
04217 err_median += data[i]*data[i];
04218 }
04219
04220 err_median = sqrt( M_PI / 2.0 *
04221 ((double) vect_size / ((double) vect_size- 1.))) *
04222 (1./(double)vect_size) * sqrt (err_median);
04223 }
04224 else{
04225 err_median = data[0];
04226 }
04227
04228 cleanup:
04229 return err_median;
04230 }
04231
04238
04239 double xsh_vector_get_err_mean( cpl_vector *vect)
04240 {
04241 double err_mean =0.0;
04242 int i, vect_size =0;
04243 double *data = NULL;
04244
04245 XSH_ASSURE_NOT_NULL( vect);
04246
04247 check( vect_size = cpl_vector_get_size( vect));
04248 check( data = cpl_vector_get_data( vect));
04249
04250 for( i=0; i< vect_size; i++){
04251 err_mean += data[i]*data[i];
04252 }
04253 err_mean = sqrt( err_mean)/(double)vect_size;
04254
04255 cleanup:
04256 return err_mean;
04257 }
04258
04259
04260
04261
04267
04268 long xsh_round_double(double x)
04269 {
04270 return (x >=0) ? (long)(x+0.5) : (long)(x-0.5);
04271 }
04272
04273
04282
04283 inline int
04284 xsh_min_int(int x, int y)
04285 {
04286 return (x <=y) ? x : y;
04287 }
04288
04289
04298
04299 inline int
04300 xsh_max_int(int x, int y)
04301 {
04302 return (x >= y) ? x : y;
04303 }
04304
04305
04306
04315
04316 inline double
04317 xsh_min_double(double x, double y)
04318 {
04319 return (x <=y) ? x : y;
04320 }
04321
04322
04323
04332
04333 inline double
04334 xsh_max_double(double x, double y)
04335 {
04336 return (x >=y) ? x : y;
04337 }
04338
04339
04340
04347
04348 double xsh_pow_int(double x, int y)
04349 {
04350 double result = 1.0;
04351
04352
04353 while(y != 0)
04354 {
04355 if (y % 2 == 0)
04356 {
04357 x *= x;
04358 y /= 2;
04359 }
04360 else
04361 {
04362 if (y > 0)
04363 {
04364 result *= x;
04365 y -= 1;
04366 }
04367 else
04368 {
04369 result /= x;
04370 y += 1;
04371 }
04372 }
04373 }
04374 return result;
04375 }
04376
04392 const char*
04393 xsh_string_tolower(char* s)
04394 {
04395
04396 char *t = s;
04397
04398 assert(s != NULL);
04399
04400 while (*t) {
04401 *t = tolower(*t);
04402 t++;
04403 }
04404
04405 return s;
04406
04407 }
04408
04409
04426 const char*
04427 xsh_string_toupper(char* s)
04428 {
04429
04430 char *t = s;
04431
04432 assert(s != NULL);
04433
04434 while (*t) {
04435 *t = toupper(*t);
04436 t++;
04437 }
04438
04439 return s;
04440
04441 }
04442
04443
04444
04460
04461 double
04462 xsh_spline_hermite( double xp, const double *x, const double *y, int n, int *istart )
04463 {
04464 double yp1, yp2, yp = 0;
04465 double xpi, xpi1, l1, l2, lp1, lp2;
04466 int i;
04467
04468 if ( x[0] <= x[n-1] && (xp < x[0] || xp > x[n-1]) ) return 0.0;
04469 if ( x[0] > x[n-1] && (xp > x[0] || xp < x[n-1]) ) return 0.0;
04470
04471 if ( x[0] <= x[n-1] )
04472 {
04473 for ( i = (*istart)+1; i <= n && xp >= x[i-1]; i++ )
04474 ;
04475 }
04476 else
04477 {
04478 for ( i = (*istart)+1; i <= n && xp <= x[i-1]; i++ )
04479 ;
04480 }
04481
04482 *istart = i;
04483 i--;
04484
04485 lp1 = 1.0 / (x[i-1] - x[i]);
04486 lp2 = -lp1;
04487
04488 if ( i == 1 )
04489 {
04490 yp1 = (y[1] - y[0]) / (x[1] - x[0]);
04491 }
04492 else
04493 {
04494 yp1 = (y[i] - y[i-2]) / (x[i] - x[i-2]);
04495 }
04496
04497 if ( i >= n - 1 )
04498 {
04499 yp2 = (y[n-1] - y[n-2]) / (x[n-1] - x[n-2]);
04500 }
04501 else
04502 {
04503 yp2 = (y[i+1] - y[i-1]) / (x[i+1] - x[i-1]);
04504 }
04505
04506 xpi1 = xp - x[i];
04507 xpi = xp - x[i-1];
04508 l1 = xpi1*lp1;
04509 l2 = xpi*lp2;
04510
04511 yp = y[i-1]*(1 - 2.0*lp1*xpi)*l1*l1 +
04512 y[i]*(1 - 2.0*lp2*xpi1)*l2*l2 +
04513 yp1*xpi*l1*l1 + yp2*xpi1*l2*l2;
04514
04515 return yp;
04516 }
04517
04518
04519
04530
04531
04532 double
04533 xsh_spline_hermite_table( double xp, const cpl_table *t, const char *column_x,
04534 const char *column_y, int *istart )
04535 {
04536 double result = 0;
04537 int n;
04538
04539 const double *x, *y;
04540
04541 check_msg( x = cpl_table_get_data_double_const(t, column_x),
04542 "Error reading column '%s'", column_x);
04543 check_msg( y = cpl_table_get_data_double_const(t, column_y),
04544 "Error reading column '%s'", column_y);
04545
04546 n = cpl_table_get_nrow(t);
04547
04548 result = xsh_spline_hermite(xp, x, y, n, istart);
04549
04550 cleanup:
04551 return result;
04552 }
04553
04554
04555
04564 cpl_vector *
04565 xsh_image_to_vector( cpl_image * spectrum )
04566 {
04567 cpl_vector * result =NULL;
04568 cpl_type type=CPL_TYPE_FLOAT;
04569
04570 int i =0;
04571 int ilx=0;
04572 int ily=0;
04573
04574 int* pi=NULL;
04575 float* pf=NULL;
04576 double* pd=NULL;
04577 double* pv=NULL;
04578
04579 int size=0;
04580
04581
04582 XSH_ASSURE_NOT_NULL_MSG(spectrum,"NULL input spectrum (1D) image!Exit.");
04583 ilx=cpl_image_get_size_x(spectrum);
04584 ily=cpl_image_get_size_y(spectrum);
04585 size=ilx*ily;
04586
04587 result=cpl_vector_new(size);
04588 pv=cpl_vector_get_data(result);
04589
04590 switch(type) {
04591
04592 case CPL_TYPE_INT:
04593 pi=cpl_image_get_data_int(spectrum);
04594 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pi[i] ;
04595 break;
04596
04597 case CPL_TYPE_FLOAT:
04598 pf=cpl_image_get_data_float(spectrum);
04599 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pf[i] ;
04600 break;
04601
04602 case CPL_TYPE_DOUBLE:
04603 pd=cpl_image_get_data_double(spectrum);
04604 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pd[i] ;
04605 break;
04606
04607 default:
04608 xsh_msg_error("Wrong input image data type %d",type);
04609 }
04610
04611 cleanup:
04612
04613 return result ;
04614 }
04615
04616
04617
04627
04628
04629 cpl_image*
04630 xsh_vector_to_image(const cpl_vector* vector,cpl_type type)
04631 {
04632 int i=0;
04633 cpl_image* image=NULL;
04634 int size=0;
04635 const double* pv=NULL;
04636 int* pi=NULL;
04637 float* pf=NULL;
04638 double* pd=NULL;
04639
04640
04641 size=cpl_vector_get_size(vector);
04642 image=cpl_image_new(size,1,type);
04643 pv=cpl_vector_get_data_const(vector);
04644 if(type == CPL_TYPE_INT) {
04645 pi=cpl_image_get_data_int(image);
04646 for(i=0;i<size;i++) {
04647 pi[i]=pv[i];
04648 }
04649 } else if (type == CPL_TYPE_FLOAT) {
04650 pf=cpl_image_get_data_float(image);
04651 for(i=0;i<size;i++) {
04652 pf[i]=pv[i];
04653 }
04654 } else if (type == CPL_TYPE_DOUBLE) {
04655 pd=cpl_image_get_data_double(image);
04656 for(i=0;i<size;i++) {
04657 pd[i]=pv[i];
04658 }
04659 } else {
04660 assure( false, CPL_ERROR_INVALID_TYPE,
04661 "No CPL type to represent BITPIX = %d", type);
04662 }
04663
04664 cleanup:
04665 if (cpl_error_get_code() != CPL_ERROR_NONE){
04666 xsh_free_image(&image);
04667 }
04668
04669 return image;
04670
04671 }
04672
04673
04681
04682 cpl_frame*
04683 xsh_util_multiply_by_response(cpl_frame* merged_sci, cpl_frame* response,
04684 const char* tag_o)
04685 {
04686 cpl_frame* result=NULL;
04687 cpl_image* data_sci=NULL;
04688 cpl_image* errs_sci=NULL;
04689 cpl_image* qual_sci=NULL;
04690
04691 cpl_image* data_tmp=NULL;
04692 cpl_image* errs_tmp=NULL;
04693
04694 cpl_vector* data_vec=NULL;
04695 cpl_vector* errs_vec=NULL;
04696 cpl_vector* qual_vec=NULL;
04697
04698 cpl_propertylist* hdat=NULL;
04699 cpl_propertylist* herr=NULL;
04700 cpl_propertylist* hqua=NULL;
04701 cpl_propertylist* plist=NULL;
04702
04703 cpl_table* response_table=NULL;
04704
04705 const char* name_s=NULL;
04706
04707 const char* name_r=NULL;
04708
04709 char* name_o=NULL;
04710 double lambda_start=0;
04711 double lambda_step=0;
04712 int bin=0;
04713 int naxis=0;
04714 int nbins = 0;
04715 int ntraces = 0;
04716
04717 double *fluxcal_science_data = NULL;
04718 double *fluxcal_science_noise = NULL;
04719
04720 XSH_ASSURE_NOT_NULL_MSG(merged_sci,"NULL input merged frame!Exit.");
04721 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04722
04723 check(name_s=cpl_frame_get_filename(merged_sci));
04724
04725 name_o=cpl_sprintf("%s.fits",tag_o);
04726
04727 check(hdat=cpl_propertylist_load(name_s,0));
04728 check(herr=cpl_propertylist_load(name_s,1));
04729 check(hqua=cpl_propertylist_load(name_s,2));
04730
04731 naxis=xsh_pfits_get_naxis(hdat);
04732
04733 if(naxis == 1) {
04734
04735 check(data_vec=cpl_vector_load(name_s,0));
04736 check(errs_vec=cpl_vector_load(name_s,1));
04737
04738 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
04739 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
04740
04741 xsh_free_vector(&data_vec);
04742 xsh_free_vector(&errs_vec);
04743
04744 } else {
04745
04746 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,0));
04747 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,1));
04748 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,2));
04749
04750 }
04751
04752 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
04753 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
04754 xsh_free_image(&data_sci);
04755 xsh_free_image(&errs_sci);
04756
04757 check(name_r=cpl_frame_get_filename(response));
04758 check(response_table=cpl_table_load(name_r,1,0));
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773 xsh_msg("Multiply by response function");
04774
04775 check(nbins = cpl_image_get_size_x(data_tmp));
04776 check(ntraces = cpl_image_get_size_y(data_tmp));
04777
04778 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
04779 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
04780
04781 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
04782 "Error reading start wavelength from reduced science header");
04783 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
04784 "Error reading bin width from header");
04785
04786 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
04787 check(cpl_table_cast_column(response_table,"FLUX","DFLUX",CPL_TYPE_DOUBLE));
04788
04789 for (bin = 1; bin <= nbins; bin++)
04790 {
04791 double lambda;
04792 double response;
04793 int trace;
04794 int istart = 0;
04795
04796 lambda = lambda_start + (bin-1) * lambda_step;
04797 check_msg( response =
04798 xsh_spline_hermite_table(lambda, response_table,
04799 "DLAMBDA", "DFLUX", &istart),
04800 "Error interpolating response curve at lambda = %f wlu", lambda);
04801
04802 xsh_msg_dbg_medium("response=%g",response);
04803
04804 for (trace = 1; trace <= ntraces; trace++)
04805 {
04806
04807
04808
04809
04810 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
04811
04812 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
04813
04814
04815
04816 }
04817 }
04818
04819 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
04820 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
04821 xsh_free_image(&data_tmp);
04822 xsh_free_image(&errs_tmp);
04823
04824 cpl_table_erase_column(response_table,"DLAMBDA");
04825 cpl_table_erase_column(response_table,"DFLUX");
04826 check( xsh_pfits_set_pcatg( hdat, tag_o));
04827 xsh_pfits_set_extname( hdat, "FLUX");
04828
04829 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04830 check(xsh_plist_set_extra_keys(hdat,"IMAGE","DATA","RMSE",
04831 "FLUX","ERRS","QUAL",0));
04832
04833 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04834 xsh_pfits_set_extname( herr, "ERRS");
04835 check(xsh_plist_set_extra_keys(herr,"IMAGE","DATA","RMSE",
04836 "FLUX","ERRS","QUAL",1));
04837
04838
04839 xsh_pfits_set_extname( hqua, "QUAL");
04840 check(xsh_plist_set_extra_keys(hqua,"IMAGE","DATA","RMSE",
04841 "FLUX","ERRS","QUAL",2));
04842
04843
04844
04845 if(naxis==1) {
04846 check(data_vec=xsh_image_to_vector(data_sci));
04847 check(errs_vec=xsh_image_to_vector(errs_sci));
04848
04849 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04850 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
04851 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04852 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
04853 check(qual_vec=cpl_vector_load(name_s,2));
04854 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
04855
04856
04857 } else {
04858 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04859 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
04860 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04861 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
04862 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
04863 }
04864
04865
04866 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
04867
04868 cleanup:
04869
04870 cpl_free(name_o);
04871
04872 xsh_free_image(&data_sci);
04873 xsh_free_image(&errs_sci);
04874 xsh_free_image(&qual_sci);
04875 xsh_free_image(&data_sci);
04876 xsh_free_image(&errs_sci);
04877
04878 xsh_free_vector(&data_vec);
04879 xsh_free_vector(&errs_vec);
04880 xsh_free_vector(&qual_vec);
04881
04882 xsh_free_table(&response_table);
04883 xsh_free_propertylist(&hdat);
04884 xsh_free_propertylist(&herr);
04885 xsh_free_propertylist(&hqua);
04886 xsh_free_propertylist(&plist);
04887
04888 return result;
04889 }
04890
04891
04899
04900 cpl_frame*
04901 xsh_util_multiply_by_response_ord(cpl_frame* extracted_sci, cpl_frame* response,
04902 const char* tag_o)
04903 {
04904 cpl_frame* result=NULL;
04905 cpl_image* data_sci=NULL;
04906 cpl_image* errs_sci=NULL;
04907 cpl_image* qual_sci=NULL;
04908
04909 cpl_image* data_tmp=NULL;
04910 cpl_image* errs_tmp=NULL;
04911
04912 cpl_vector* data_vec=NULL;
04913 cpl_vector* errs_vec=NULL;
04914 cpl_vector* qual_vec=NULL;
04915
04916 cpl_propertylist* hdat=NULL;
04917 cpl_propertylist* herr=NULL;
04918 cpl_propertylist* hqua=NULL;
04919 cpl_propertylist* plist=NULL;
04920
04921 cpl_table* response_table=NULL;
04922
04923 const char* name_s=NULL;
04924
04925 const char* name_r=NULL;
04926 char* name_o=NULL;
04927 double lambda_start=0;
04928 double lambda_step=0;
04929 int bin=0;
04930 int naxis=0;
04931
04932 int nbins = 0;
04933 int ntraces = 0;
04934
04935 int next_sci = 0;
04936 int next_res = 0;
04937 int ext = 0;
04938 int order=0;
04939
04940 double *fluxcal_science_data = NULL;
04941 double *fluxcal_science_noise = NULL;
04942
04943 XSH_ASSURE_NOT_NULL_MSG(extracted_sci,"NULL input extracted frame!Exit.");
04944 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04945
04946 check(name_s=cpl_frame_get_filename(extracted_sci));
04947
04948
04949 name_o=cpl_sprintf("%s.fits",tag_o);
04950 next_sci=cpl_frame_get_nextensions(extracted_sci);
04951 next_res=cpl_frame_get_nextensions(response);
04952 xsh_msg("Multiply by response function");
04953 check(name_r=cpl_frame_get_filename(response));
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963 for(ext=0, order=0;ext<next_sci;ext+=3,order++) {
04964 xsh_free_propertylist(&hdat);
04965 xsh_free_propertylist(&herr);
04966 xsh_free_propertylist(&hqua);
04967
04968 check(hdat=cpl_propertylist_load(name_s,ext+0));
04969 check(herr=cpl_propertylist_load(name_s,ext+1));
04970 check(hqua=cpl_propertylist_load(name_s,ext+2));
04971
04972 naxis=xsh_pfits_get_naxis(hdat);
04973
04974 if(naxis == 1) {
04975
04976 check(data_vec=cpl_vector_load(name_s,ext+0));
04977 check(errs_vec=cpl_vector_load(name_s,ext+1));
04978
04979 xsh_free_image(&data_sci);
04980 xsh_free_image(&errs_sci);
04981 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
04982 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
04983
04984 xsh_free_vector(&data_vec);
04985 xsh_free_vector(&errs_vec);
04986
04987 } else {
04988
04989 xsh_free_image(&data_sci);
04990 xsh_free_image(&errs_sci);
04991 xsh_free_image(&qual_sci);
04992 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
04993 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
04994 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
04995
04996 }
04997
04998 xsh_free_image(&data_tmp);
04999 xsh_free_image(&errs_tmp);
05000 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
05001 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
05002 xsh_free_image(&data_sci);
05003 xsh_free_image(&errs_sci);
05004 xsh_free_table(&response_table);
05005 if(next_res>1) {
05006 check(response_table=cpl_table_load(name_r,order+1,0));
05007
05008 } else {
05009 check(response_table=cpl_table_load(name_r,next_res,0));
05010
05011 }
05012
05013
05014
05015
05016 check(nbins = cpl_image_get_size_x(data_tmp));
05017 check(ntraces = cpl_image_get_size_y(data_tmp));
05018
05019 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
05020 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
05021
05022 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
05023 "Error reading start wavelength from reduced science header");
05024 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
05025 "Error reading bin width from header");
05026
05027 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
05028 check(cpl_table_cast_column(response_table,"RESPONSE","DFLUX",CPL_TYPE_DOUBLE));
05029
05030 for (bin = 1; bin <= nbins; bin++)
05031 {
05032 double lambda;
05033 double response;
05034 int trace;
05035 int istart = 0;
05036
05037 lambda = lambda_start + (bin-1) * lambda_step;
05038 check_msg( response =
05039 xsh_spline_hermite_table(lambda, response_table,
05040 "DLAMBDA", "DFLUX", &istart),
05041 "Error interpolating response curve at lambda = %f wlu", lambda);
05042
05043 xsh_msg_dbg_medium("ext=%d response=%g",ext,response);
05044
05045 for (trace = 1; trace <= ntraces; trace++)
05046 {
05047
05048
05049
05050
05051 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
05052
05053 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
05054
05055
05056
05057 }
05058 }
05059
05060 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
05061 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
05062 xsh_free_image(&data_tmp);
05063 xsh_free_image(&errs_tmp);
05064
05065 cpl_table_erase_column(response_table,"DLAMBDA");
05066 cpl_table_erase_column(response_table,"DFLUX");
05067 check( xsh_pfits_set_pcatg( hdat, tag_o));
05068
05069 xsh_pfits_set_extname( hdat, "FLUX");
05070 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
05071 check(xsh_plist_set_extra_keys(hdat,"IMAGE","DATA","RMSE",
05072 "FLUX","ERRS","QUAL",0));
05073
05074 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
05075 xsh_pfits_set_extname( herr, "ERRS");
05076 check(xsh_plist_set_extra_keys(herr,"IMAGE","DATA","RMSE",
05077 "FLUX","ERRS","QUAL",1));
05078
05079
05080 xsh_pfits_set_extname( hqua, "QUAL");
05081 check(xsh_plist_set_extra_keys(hqua,"IMAGE","DATA","RMSE",
05082 "FLUX","ERRS","QUAL",2));
05083
05084
05085
05086
05087 if(naxis==1) {
05088 check(data_vec=xsh_image_to_vector(data_sci));
05089 check(errs_vec=xsh_image_to_vector(errs_sci));
05090 if(ext==0) {
05091 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05092 } else {
05093 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05094 }
05095 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05096 check(qual_vec=cpl_vector_load(name_s,ext+2));
05097 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05098
05099 } else {
05100 if(ext==0) {
05101 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05102 } else {
05103 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05104 }
05105 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05106 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05107 }
05108
05109 }
05110
05111
05112 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05113
05114 cleanup:
05115
05116 cpl_free(name_o);
05117
05118 xsh_free_image(&data_sci);
05119 xsh_free_image(&errs_sci);
05120 xsh_free_image(&qual_sci);
05121 xsh_free_image(&data_sci);
05122 xsh_free_image(&errs_sci);
05123
05124 xsh_free_vector(&data_vec);
05125 xsh_free_vector(&errs_vec);
05126 xsh_free_vector(&qual_vec);
05127
05128 xsh_free_table(&response_table);
05129 xsh_free_propertylist(&hdat);
05130 xsh_free_propertylist(&herr);
05131 xsh_free_propertylist(&hqua);
05132 xsh_free_propertylist(&plist);
05133
05134 return result;
05135 }
05136
05137 static cpl_error_code
05138 xsh_util_get_infsup(double* piw,
05139 double w,
05140 int i_start,
05141 int i_end,
05142 int* i_inf,
05143 int* i_sup)
05144 {
05145
05146 int i=0;
05147 for(i = i_start;i < i_end;i++) {
05148 if (piw[i] < w) {
05149 *i_inf=i;
05150 *i_sup=i+1;
05151 }
05152 }
05153
05154 return cpl_error_get_code();
05155 }
05156
05157
05158 static double
05159 xsh_spectrum_integrate(double* pif,
05160 double* piw,
05161 int i1_inf,
05162 int i1_sup,
05163 int i2_inf,
05164 int i2_sup,
05165 double wave,
05166 double wstep)
05167 {
05168
05169 double sum1=0;
05170 double sum2=0;
05171 double sum3=0;
05172 int i=0;
05173
05174
05175 for(i=i1_sup;i<i2_inf;i++) {
05176
05177
05178
05179 sum2+=pif[i]*(piw[i+1]-piw[i]);
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191 }
05192
05193
05194
05195
05196 return (sum1+sum2+sum3);
05197 }
05198
05199
05211
05212 cpl_frame*
05213 xsh_spectrum_resample(cpl_frame* frame_inp,
05214 const double wstep,
05215 const double wmin,
05216 const double wmax,
05217 xsh_instrument* instr)
05218 {
05219
05220 cpl_frame* result=NULL;
05221 cpl_table* tab_inp=NULL;
05222 cpl_table* tab_out=NULL;
05223 int nrow_inp=0;
05224 int nrow_out=0;
05225 int i=0;
05226
05227 double wave_min=0;
05228 double wave_max=0;
05229 double wave_start=0;
05230
05231 const char* fname=NULL;
05232 double* pow=NULL;
05233 double* pof=NULL;
05234 double* piw=NULL;
05235 double* pif=NULL;
05236
05237 double wo1=0;
05238 double wo2=0;
05239
05240 int istep=0;
05241
05242 int i1_inf=0;
05243 int i1_sup=0;
05244 int i2_inf=0;
05245 int i2_sup=0;
05246
05247 int i_start=0;
05248 int i_end=0;
05249 double hstep=0;
05250 const char* tag=NULL;
05251 char* name=NULL;
05252 cpl_propertylist* plist=NULL;
05253
05254
05255 check(fname=cpl_frame_get_filename(frame_inp));
05256 tag=cpl_frame_get_tag(frame_inp);
05257 plist=cpl_propertylist_load(fname,0);
05258
05259
05260
05261 tab_inp=cpl_table_load(fname,1,0);
05262 nrow_inp=cpl_table_get_nrow(tab_inp);
05263 wave_min=cpl_table_get_column_min(tab_inp,"LAMBDA");
05264 wave_max=cpl_table_get_column_max(tab_inp,"LAMBDA");
05265
05266 wave_min=(wave_min>wmin) ? wave_min : wmin;
05267 wave_max=(wave_max<wmax) ? wave_max : wmax;
05268
05269
05270 wave_start=floor(wave_min);
05271
05272
05273 if( xsh_instrument_get_arm(instr) == XSH_ARM_UVB){
05274 wave_start=(wave_start>XSH_ATM_EXT_UVB_WAV_MIN)? wave_start : XSH_ATM_EXT_UVB_WAV_MIN;
05275 }
05276 xsh_msg("Resample ref flux std spectrum to %g [nm] step",wstep);
05277
05278
05279
05280
05281
05282 nrow_out=ceil((wave_max-wave_start)/wstep);
05283 tab_out=cpl_table_new(nrow_out);
05284
05285 cpl_table_new_column(tab_out,"LAMBDA",CPL_TYPE_DOUBLE);
05286 cpl_table_new_column(tab_out,"FLUX",CPL_TYPE_DOUBLE);
05287 cpl_table_new_column(tab_out,"BIN_WIDTH",CPL_TYPE_DOUBLE);
05288
05289 cpl_table_fill_column_window_double(tab_out,"LAMBDA",0,nrow_out,0.);
05290 cpl_table_fill_column_window_double(tab_out,"FLUX",0,nrow_out,0.);
05291 cpl_table_fill_column_window_double(tab_out,"BIN_WIDTH",0,nrow_out,wstep);
05292
05293
05294 pow=cpl_table_get_data_double(tab_out,"LAMBDA");
05295 pof=cpl_table_get_data_double(tab_out,"FLUX");
05296
05297 piw=cpl_table_get_data_double(tab_inp,"LAMBDA");
05298 pif=cpl_table_get_data_double(tab_inp,"FLUX");
05299
05300 hstep=0.5*wstep;
05301
05302 i_start=0;
05303 i_end=nrow_inp;
05304
05305
05306 istep=(int) (wstep/(wave_max-wave_min)*nrow_inp+0.5);
05307 istep*=4;
05308
05309
05310
05311
05312 for(i=0;i<nrow_out;i++) {
05313 pow[i]=wave_start+i*wstep;
05314 wo1=pow[i]-hstep;
05315 wo2=pow[i]+hstep;
05316 i_start=0;
05317 i_end=nrow_inp;
05318
05319
05320
05321
05322
05323
05324
05325
05326 xsh_util_get_infsup(piw,wo1,i_start,i_end,&i1_inf,&i1_sup);
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346 xsh_util_get_infsup(piw,wo2,i_start,i_end,&i2_inf,&i2_sup);
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373 pof[i]=xsh_spectrum_integrate(pif,piw,i1_inf,i1_sup,
05374 i2_inf,i2_sup,pow[i],wstep);
05375
05376
05377
05378
05379
05380
05381 }
05382
05383 cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_LESS_THAN,wmin);
05384 cpl_table_erase_selected(tab_out);
05385 cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_GREATER_THAN,wmax);
05386 cpl_table_erase_selected(tab_out);
05387
05388 name=cpl_sprintf("RESAMPLED_%s_%s.fits",tag,
05389 xsh_instrument_arm_tostring( instr));
05390
05391 check(cpl_table_save(tab_out,plist,NULL,name,CPL_IO_DEFAULT));
05392 xsh_add_temporary_file(name);
05393 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_TABLE,
05394 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05395
05396
05397 cleanup:
05398 xsh_free_propertylist(&plist);
05399 xsh_free_table(&tab_inp);
05400 xsh_free_table(&tab_out);
05401 cpl_free(name);
05402
05403 return result;
05404 }
05405
05406
05413
05414 cpl_frame*
05415 xsh_util_frameset_collapse_mean(cpl_frameset* set,
05416 xsh_instrument* instrument)
05417 {
05418 cpl_frame* result=NULL;
05419 cpl_frame* frm=NULL;
05420
05421 cpl_image* ima=NULL;
05422 cpl_image* err=NULL;
05423
05424 cpl_image* ima_sum=NULL;
05425 cpl_image* err_sum=NULL;
05426 cpl_image* qua_sum=NULL;
05427 cpl_propertylist* hdat=NULL;
05428 cpl_propertylist* herr=NULL;
05429 cpl_propertylist* hqua=NULL;
05430 char* name=NULL;
05431 char* tag=NULL;
05432 const char* fname=NULL;
05433 int size=0;
05434 int i=0;
05435
05436
05437 size=cpl_frameset_get_size(set);
05438 for(i=0;i<size;i++) {
05439
05440 frm=cpl_frameset_get_frame(set,i);
05441 fname=cpl_frame_get_filename(frm);
05442
05443 ima=cpl_image_load(fname,XSH_PRE_DATA_TYPE,0,0);
05444 err=cpl_image_load(fname,XSH_PRE_ERRS_TYPE,0,1);
05445
05446 cpl_image_multiply(err,err);
05447 if(i==0) {
05448 ima_sum=cpl_image_duplicate(ima);
05449 err_sum=cpl_image_duplicate(err);
05450 } else {
05451 cpl_image_add(ima_sum,ima);
05452 cpl_image_add(err_sum,err);
05453 }
05454
05455 xsh_free_image(&ima);
05456 xsh_free_image(&err);
05457
05458 }
05459
05460
05461 cpl_image_divide_scalar(ima_sum,size);
05462 cpl_image_divide_scalar(err_sum,size);
05463
05464
05465 check(cpl_image_power(err_sum,0.5));
05466
05467
05468 qua_sum=cpl_image_load(fname,XSH_PRE_QUAL_TYPE,0,2);
05469
05470 frm=cpl_frameset_get_frame(set,0);
05471 fname=cpl_frame_get_filename(frm);
05472 hdat=cpl_propertylist_load(fname,0);
05473 herr=cpl_propertylist_load(fname,1);
05474 hqua=cpl_propertylist_load(fname,2);
05475
05476 name=cpl_sprintf("SKY_AVG_%s.fits",xsh_instrument_arm_tostring( instrument));
05477 tag=cpl_sprintf("SKY_AVG_%s",xsh_instrument_arm_tostring( instrument));
05478
05479 check(cpl_image_save(ima_sum,name,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05480 check(cpl_image_save(err_sum,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05481 check(cpl_image_save(qua_sum,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05482 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_IMAGE,
05483 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05484 xsh_add_temporary_file(name);
05485
05486 cleanup:
05487
05488 xsh_free_image(&ima);
05489 xsh_free_image(&err);
05490
05491 xsh_free_image(&ima_sum);
05492 xsh_free_image(&err_sum);
05493 xsh_free_image(&qua_sum);
05494
05495 xsh_free_propertylist(&hdat);
05496 xsh_free_propertylist(&herr);
05497 xsh_free_propertylist(&hqua);
05498
05499 cpl_free(name);
05500 cpl_free(tag);
05501
05502 return result;
05503 }
05504
05505
05506
05507
05526 cpl_error_code
05527 xsh_normalize_spectrum_image_slice(const char* name_s,
05528 const char* tag_o,
05529 const int ext,
05530 const int binx,
05531 const double gain,
05532 const double exptime,
05533 const double airmass,
05534 const cpl_table* tbl_atm_ext)
05535 {
05536
05537
05538 cpl_image* data_ima=NULL;
05539 cpl_image* errs_ima=NULL;
05540 cpl_image* qual_ima=NULL;
05541 cpl_image* data_nrm=NULL;
05542 cpl_image* errs_nrm=NULL;
05543
05544 cpl_image* data_tmp=NULL;
05545 cpl_image* errs_tmp=NULL;
05546
05547 cpl_image* data_nrm_tmp=NULL;
05548 cpl_image* errs_nrm_tmp=NULL;
05549
05550 cpl_vector* data_vec=NULL;
05551 cpl_vector* errs_vec=NULL;
05552 cpl_vector* qual_vec=NULL;
05553
05554 cpl_propertylist* hdat=NULL;
05555 cpl_propertylist* herr=NULL;
05556 cpl_propertylist* hqua=NULL;
05557 int naxis=0;
05558 char name_o[256];
05559
05560 sprintf(name_o,"%s.fits",tag_o);
05561
05562 xsh_free_propertylist(&hdat);
05563 xsh_free_propertylist(&herr);
05564 xsh_free_propertylist(&hqua);
05565
05566 hdat=cpl_propertylist_load(name_s,ext+0);
05567 herr=cpl_propertylist_load(name_s,ext+1);
05568 hqua=cpl_propertylist_load(name_s,ext+2);
05569
05570
05571 naxis=xsh_pfits_get_naxis(hdat);
05572 xsh_pfits_set_pcatg(hdat,tag_o);
05573 if(naxis == 1) {
05574
05575 check(data_vec=cpl_vector_load(name_s,ext+0));
05576 check(errs_vec=cpl_vector_load(name_s,ext+1));
05577 xsh_free_image(&data_ima);
05578 xsh_free_image(&errs_ima);
05579 check(data_ima=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
05580 check(errs_ima=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
05581 xsh_free_vector(&data_vec);
05582 xsh_free_vector(&errs_vec);
05583
05584 } else {
05585
05586 xsh_free_image(&data_ima);
05587 xsh_free_image(&errs_ima);
05588 xsh_free_image(&qual_ima);
05589 check(data_ima=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
05590 check(errs_ima=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
05591 check(qual_ima=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
05592
05593 }
05594 xsh_free_image(&data_tmp);
05595 xsh_free_image(&errs_tmp);
05596 data_tmp=cpl_image_cast(data_ima,CPL_TYPE_DOUBLE);
05597 errs_tmp=cpl_image_cast(errs_ima,CPL_TYPE_DOUBLE);
05598
05599 xsh_free_image(&data_nrm_tmp);
05600 xsh_free_image(&errs_nrm_tmp);
05601
05602 check(data_nrm_tmp=xsh_normalize_spectrum_image(data_tmp,errs_tmp,hdat,
05603 binx,gain,exptime,airmass,1,
05604 tbl_atm_ext,&errs_nrm_tmp));
05605
05606 xsh_free_image(&data_nrm);
05607 xsh_free_image(&errs_nrm);
05608 check(data_nrm=cpl_image_cast(data_nrm_tmp,CPL_TYPE_FLOAT));
05609 check(errs_nrm=cpl_image_cast(errs_nrm_tmp,CPL_TYPE_FLOAT));
05610
05611 if(naxis==1) {
05612 xsh_free_vector(&data_vec);
05613 xsh_free_vector(&errs_vec);
05614
05615 check(data_vec=xsh_image_to_vector(data_nrm));
05616 check(errs_vec=xsh_image_to_vector(errs_nrm));
05617
05618 if(ext==0) {
05619 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05620 } else {
05621 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05622 }
05623 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05624 xsh_free_vector(&qual_vec);
05625 check(qual_vec=cpl_vector_load(name_s,ext+2));
05626 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05627
05628
05629 } else {
05630 if(ext==0) {
05631 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05632 } else {
05633 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05634 }
05635 check(cpl_image_save(errs_nrm,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05636 check(cpl_image_save(qual_ima,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05637
05638 }
05639
05640
05641
05642 cleanup:
05643 xsh_free_image(&data_ima);
05644 xsh_free_image(&errs_ima);
05645 xsh_free_image(&qual_ima);
05646 xsh_free_image(&data_nrm);
05647 xsh_free_image(&errs_nrm);
05648 xsh_free_image(&data_tmp);
05649 xsh_free_image(&errs_tmp);
05650 xsh_free_image(&data_nrm_tmp);
05651 xsh_free_image(&errs_nrm_tmp);
05652
05653 xsh_free_propertylist(&hdat);
05654 xsh_free_propertylist(&herr);
05655 xsh_free_propertylist(&hqua);
05656
05657 xsh_free_vector(&data_vec);
05658 xsh_free_vector(&errs_vec);
05659 xsh_free_vector(&qual_vec);
05660
05661 return cpl_error_get_code();
05662 }
05663
05664
05665
05682
05683 cpl_frame *
05684 xsh_normalize_spectrum(const cpl_frame *obj_frame,
05685 const cpl_frame *atm_ext_frame,
05686 cpl_boolean correct_binning,
05687 xsh_instrument* instrument,
05688 const char* tag_o)
05689 {
05690
05691 cpl_frame* result=NULL;
05692 const char* name_s=NULL;
05693 const char* aname=NULL;
05694
05695 cpl_table* tbl_atm_ext=NULL;
05696 cpl_propertylist* hdat=NULL;
05697
05698 char* name_o=NULL;
05699 int binx=1;
05700 double gain=0;
05701 double exptime=0;
05702 double airmass=0;
05703
05704 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05705 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05706
05707 name_s=cpl_frame_get_filename(obj_frame);
05708 aname=cpl_frame_get_filename(atm_ext_frame);
05709 tbl_atm_ext=cpl_table_load(aname,1,0);
05710
05711 cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE);
05712 cpl_table_cast_column( tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,"D_EXTINCTION",CPL_TYPE_DOUBLE);
05713
05714
05715 hdat=cpl_propertylist_load(name_s,0);
05716 exptime = xsh_pfits_get_exptime(hdat);
05717 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05718
05719 gain=1./2.12;
05720 } else {
05721 gain = xsh_pfits_get_gain(hdat);
05722 }
05723
05724 if (correct_binning) {
05725
05726 binx = xsh_pfits_get_biny(hdat);
05727 } else {
05728 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05729 binx = 1;
05730 }
05731 airmass=xsh_pfits_get_airm_mean(hdat);
05732 name_o=cpl_sprintf("%s.fits",tag_o);
05733
05734 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,0,binx,gain,
05735 exptime,airmass,tbl_atm_ext));
05736
05737 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05738
05739 cleanup:
05740
05741 xsh_free_table(&tbl_atm_ext);
05742 xsh_free_propertylist(&hdat);
05743 cpl_free(name_o);
05744
05745 return result;
05746
05747 }
05748
05749
05750
05751
05752
05768
05769 cpl_frame *
05770 xsh_normalize_spectrum_ord(const cpl_frame *obj_frame,
05771 const cpl_frame *atm_ext_frame,
05772 cpl_boolean correct_binning,
05773 xsh_instrument* instrument,
05774 const char* tag_o)
05775 {
05776
05777 cpl_frame* result=NULL;
05778 const char* name_s=NULL;
05779 const char* aname=NULL;
05780
05781 cpl_table* tbl_atm_ext=NULL;
05782 cpl_propertylist* hdat=NULL;
05783 char* name_o=NULL;
05784
05785 int next=0;
05786 int ext=0;
05787 int binx=1;
05788 double gain=0;
05789 double exptime=0;
05790 double airmass=0;
05791
05792 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05793 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05794
05795 next=cpl_frame_get_nextensions( obj_frame);
05796 name_s=cpl_frame_get_filename(obj_frame);
05797
05798 aname=cpl_frame_get_filename(atm_ext_frame);
05799 tbl_atm_ext=cpl_table_load(aname,1,0);
05800 check(cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE));
05801 if(!cpl_table_has_column(tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K)){
05802 xsh_msg_warning("You are using an obsolete atm extinction line table");
05803 cpl_table_duplicate_column(tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,
05804 tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
05805 }
05806 check(cpl_table_cast_column( tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,"D_EXTINCTION",CPL_TYPE_DOUBLE));
05807 name_o=cpl_sprintf("%s.fits",tag_o);
05808
05809 hdat=cpl_propertylist_load(name_s,0);
05810
05811 check(exptime = xsh_pfits_get_exptime(hdat));
05812 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05813
05814 gain=1./2.12;
05815 } else {
05816 check(gain = xsh_pfits_get_gain(hdat));
05817 }
05818
05819 if (correct_binning && (xsh_instrument_get_arm(instrument) != XSH_ARM_NIR)) {
05820
05821 check(binx = xsh_pfits_get_biny(hdat));
05822 } else {
05823 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05824 binx = 1;
05825 }
05826 check(airmass=xsh_pfits_get_airm_mean(hdat));
05827
05828 for(ext=0;ext<next;ext+=3) {
05829 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,ext,binx,gain,
05830 exptime,airmass,tbl_atm_ext));
05831 }
05832
05833 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05834
05835 cleanup:
05836
05837 xsh_free_table(&tbl_atm_ext);
05838 xsh_free_propertylist(&hdat);
05839 cpl_free(name_o);
05840
05841 return result;
05842
05843 }
05844
05845
05867
05868
05869 cpl_image *
05870 xsh_normalize_spectrum_image(const cpl_image *spectrum,
05871 const cpl_image *spectrum_error,
05872 const cpl_propertylist *spectrum_header,
05873 const int binx,
05874 const double gain,
05875 const double exptime,
05876 const double airmass,
05877 const int n_traces,
05878 const cpl_table *atm_extinction,
05879 cpl_image **scaled_error)
05880 {
05881 cpl_image *scaled = NULL;
05882 int norders, ny, nx;
05883 double cor_fct=gain*exptime*binx;
05884 XSH_ASSURE_NOT_NULL_MSG(spectrum,"Null input spectrum");
05885 XSH_ASSURE_NOT_NULL_MSG(scaled_error,"Null input scaled error");
05886 XSH_ASSURE_NOT_NULL_MSG(spectrum_error, "Null input spectrum error");
05887 XSH_ASSURE_NOT_NULL_MSG(spectrum_header,"Null input spectrum header");
05888 XSH_ASSURE_NOT_NULL_MSG(atm_extinction,"Null input atmospheric extinction table");
05889
05890 nx = cpl_image_get_size_x(spectrum);
05891 ny = cpl_image_get_size_y(spectrum);
05892
05893
05894 if (spectrum_error != NULL)
05895 {
05896 assure( nx == cpl_image_get_size_x(spectrum_error) &&
05897 ny == cpl_image_get_size_y(spectrum_error), CPL_ERROR_INCOMPATIBLE_INPUT,
05898 "Error spectrum geometry differs from spectrum: %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " vs. %dx%d",
05899 cpl_image_get_size_x(spectrum_error),
05900 cpl_image_get_size_y(spectrum_error),
05901 nx, ny);
05902 }
05903
05904 assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
05905 "Spectrum image height (%d) is not a multiple of "
05906 "the number of traces (%d). Confused, bailing out",
05907 ny, n_traces);
05908
05909 norders = ny / n_traces;
05910
05911
05912
05913
05914 assure( exptime > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive exposure time: %f s", exptime);
05915 assure( gain > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive gain: %f", gain);
05916 assure( binx > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal binning: %d", binx);
05917
05918 xsh_msg_dbg_medium("Correcting for exposure time = %f s, gain = %f, binx = %d", exptime, gain, binx);
05919
05920 check_msg(scaled=cpl_image_divide_scalar_create(spectrum,cor_fct),
05921 "Error correcting spectrum for gain, exposure time, binning");
05922
05923 if (scaled_error != NULL)
05924 {
05925 check_msg( *scaled_error=cpl_image_divide_scalar_create(spectrum_error,
05926 cor_fct),
05927 "Error correcting rebinned spectrum for gain, exposure time, binning");
05928 }
05929
05930
05931
05932
05933 {
05934 double dlambda, lambda_start;
05935 int order;
05936
05937 xsh_msg_dbg_medium("Correcting for extinction through airmass %f", airmass);
05938 check_msg( dlambda = xsh_pfits_get_cdelt1(spectrum_header),
05939 "Error reading bin width from header");
05940
05941 for (order = 1; order <= norders; order++)
05942 {
05943 int trace;
05944
05945
05946
05947
05948
05949 if (norders == 1)
05950 {
05951 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
05952 "Error reading start wavelength from header");
05953 }
05954 else
05955 {
05956
05957 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
05958 "Error reading start wavelength from header");
05959 }
05960
05961 for (trace = 1; trace <= n_traces; trace++)
05962 {
05963 int spectrum_row = (order - 1)*n_traces + trace;
05964 int x;
05965
05966 for (x = 1; x <= nx; x++)
05967 {
05968 int pis_rejected1;
05969 int pis_rejected2;
05970 double flux;
05971 double dflux = 0;
05972 double extinction;
05973 double lambda;
05974
05975 lambda = lambda_start + (x-1) * dlambda;
05976
05977 flux = cpl_image_get(scaled, x, spectrum_row, &pis_rejected1);
05978 if (scaled_error != NULL)
05979 {
05980 dflux = cpl_image_get(*scaled_error, x,
05981 spectrum_row, &pis_rejected2);
05982 }
05983
05984 if (!pis_rejected1 && (scaled_error == NULL || !pis_rejected2))
05985 {
05986 int istart = 0;
05987
05988
05989 check_msg( extinction =
05990 xsh_spline_hermite_table(
05991 lambda, atm_extinction,
05992 "D_LAMBDA", "D_EXTINCTION", &istart),
05993 "Error interpolating extinction coefficient");
05994
05995
05996
05997
05998
05999
06000
06001
06002
06003
06004
06005 cpl_image_set(
06006 scaled, x, spectrum_row,
06007 flux * pow(10, 0.4 * extinction * airmass));
06008 if (scaled_error != NULL)
06009 {
06010 cpl_image_set(
06011 *scaled_error, x, spectrum_row,
06012 dflux * pow(10, 0.4 * extinction * airmass));
06013 }
06014 }
06015 else
06016 {
06017 cpl_image_reject(scaled, x, spectrum_row);
06018 if (scaled_error != NULL)
06019 {
06020 cpl_image_reject(*scaled_error, x, spectrum_row);
06021 }
06022 }
06023 }
06024
06025 }
06026
06027 }
06028 }
06029
06030 cleanup:
06031 if (cpl_error_get_code() != CPL_ERROR_NONE)
06032 {
06033 xsh_free_image(&scaled);
06034 if (scaled_error != NULL)
06035 {
06036 xsh_free_image(scaled_error);
06037 }
06038 }
06039
06040 return scaled;
06041 }
06042
06043 static double
06044 xsh_iterpol_linear(double* data_x,double* data_y,int ndata,double x,
06045 int* i_inf,int* i_sup)
06046 {
06047 int i=0;
06048 double y=0;
06049
06050
06051 double x1=0;
06052 double x2=0;
06053 double y1=0;
06054 double y2=0;
06055
06056
06057
06058
06059
06060 for(i=1;i<ndata-1;i++) {
06061
06062 if(data_x[i]>x) {
06063 y1=data_y[i-1];
06064 y2=data_y[i];
06065 x1=data_x[i-1];
06066 x2=data_x[i];
06067 *i_inf=i-1;
06068 *i_sup=i+1;
06069 break;
06070 }
06071 }
06072
06073
06074 y=(y2-y1)/(x2-x1)*(x-x1)+y1;
06075
06076 return y;
06077 }
06078
06086 cpl_frame*
06087 xsh_spectrum_interpolate_linear(cpl_frame* table_frame,
06088 const double wstep,
06089 const double wmin,
06090 const double wmax)
06091 {
06092
06093 cpl_frame* result=NULL;
06094 cpl_table* table_i=NULL;
06095 cpl_table* table_o=NULL;
06096 const char* name_i=NULL;
06097 const char* tag_i=NULL;
06098
06099 char* name_o=NULL;
06100 char* tag_o=NULL;
06101
06102 cpl_propertylist* plist=NULL;
06103 int nrows_i=0;
06104 int nrows_o=0;
06105 int row=0;
06106
06107 double* pwave_i=NULL;
06108 double* pflux_i=NULL;
06109 double* pwave_o=NULL;
06110 double* pflux_o=NULL;
06111 int i_inf=0;
06112 int i_sup=0;
06113
06114
06115
06116 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06117 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06118 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06119
06120 name_i=cpl_frame_get_filename(table_frame);
06121 tag_i=cpl_frame_get_tag(table_frame);
06122
06123 check(table_i=cpl_table_load(name_i,1,0));
06124 nrows_i=cpl_table_get_nrow(table_i);
06125 plist=cpl_propertylist_load(name_i,0);
06126 nrows_o=(int)((wmax-wmin)/wstep+0.5);
06127 table_o=cpl_table_new(nrows_o);
06128 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06129 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06130 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows_o,0.));
06131 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows_o,0.));
06132 check(pwave_i=cpl_table_get_data_double(table_i,"LAMBDA"));
06133 check(pflux_i=cpl_table_get_data_double(table_i,"FLUX"));
06134 check(pwave_o=cpl_table_get_data_double(table_o,"LAMBDA"));
06135 check(pflux_o=cpl_table_get_data_double(table_o,"FLUX"));
06136 i_inf=0;
06137 i_sup=nrows_o;
06138
06139 for (row = 0; row < nrows_o; row++)
06140 {
06141
06142 pwave_o[row]= wmin + row * wstep;
06143 pflux_o[row]= xsh_iterpol_linear(pwave_i,pflux_i,nrows_i,pwave_o[row],
06144 &i_inf,&i_sup);
06145
06146
06147 }
06148 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06149 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06150 xsh_pfits_set_pcatg(plist,tag_o);
06151 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06152 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06153 CPL_FRAME_GROUP_PRODUCT,
06154 CPL_FRAME_LEVEL_FINAL));
06155 xsh_add_temporary_file(name_o);
06156 cleanup:
06157
06158
06159 xsh_free_table(&table_i);
06160 xsh_free_table(&table_o);
06161 xsh_free_propertylist(&plist);
06162 cpl_free(name_o);
06163 cpl_free(tag_o);
06164
06165 return result;
06166
06167 }
06168
06169
06170
06171
06179 cpl_frame*
06180 xsh_spectrum_interpolate(cpl_frame* table_frame,
06181 const double wstep,
06182 const double wmin,
06183 const double wmax)
06184 {
06185
06186 cpl_frame* result=NULL;
06187 cpl_table* table_i=NULL;
06188 cpl_table* table_o=NULL;
06189 const char* name_i=NULL;
06190 const char* tag_i=NULL;
06191
06192 char* name_o=NULL;
06193 char* tag_o=NULL;
06194
06195 cpl_propertylist* plist=NULL;
06196 int nrows=0;
06197 int row=0;
06198 double wave=0;
06199 double flux_o=0;
06200 double* pwave=NULL;
06201 double* pflux=NULL;
06202
06203 int istart = 0;
06204 double flux_med =0;
06205 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06206 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06207 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06208
06209 name_i=cpl_frame_get_filename(table_frame);
06210
06211 tag_i=cpl_frame_get_tag(table_frame);
06212 check(table_i=cpl_table_load(name_i,1,0));
06213 flux_med=cpl_table_get_column_median(table_i,"FLUX");
06214 cpl_table_divide_scalar(table_i,"FLUX",flux_med);
06215
06216 plist=cpl_propertylist_load(name_i,0);
06217 nrows=(int)((wmax-wmin)/wstep+0.5);
06218 table_o=cpl_table_new(nrows);
06219
06220 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06221
06222 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06223
06224 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06225
06226 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06227
06228
06229 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows,0.));
06230 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows,0.));
06231
06232 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06233 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06234
06235
06236 for (row = 0; row < nrows; row++)
06237 {
06238
06239 wave = wmin + row * wstep;
06240
06241 check_msg( flux_o = xsh_spline_hermite_table(wave, table_i,
06242 "LAMBDA", "FLUX", &istart),
06243 "Error interpolating curve at lambda = %f wlu", wave);
06244 pwave[row]=wave;
06245 pflux[row]=flux_o;
06246
06247 xsh_msg_dbg_medium("interpolated flux[%g]=%g",wave,flux_o);
06248 }
06249
06250 cpl_table_multiply_scalar(table_i,"FLUX",flux_med);
06251 cpl_table_multiply_scalar(table_o,"FLUX",flux_med);
06252
06253 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06254 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06255 xsh_pfits_set_pcatg(plist,tag_o);
06256 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06257 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06258 CPL_FRAME_GROUP_PRODUCT,
06259 CPL_FRAME_LEVEL_FINAL));
06260
06261 xsh_add_temporary_file(name_o);
06262
06263 cleanup:
06264
06265
06266 xsh_free_table(&table_i);
06267 xsh_free_table(&table_o);
06268 xsh_free_propertylist(&plist);
06269 cpl_free(name_o);
06270 cpl_free(tag_o);
06271
06272
06273 return result;
06274
06275 }
06276
06277
06278
06288 void
06289 xsh_array_clip_mean( cpl_array *array,
06290 double kappa,
06291 int niter,
06292 double frac_min,
06293 double *mean,
06294 double *stdev)
06295 {
06296 int i, j, size;
06297 double mean_val;
06298 double sigma, frac;
06299 int *flags = NULL;
06300 int nb_rejected = 0, total_rejected=0;
06301 double* pval=NULL;
06302
06303 XSH_ASSURE_NOT_NULL( array);
06304 XSH_ASSURE_NOT_NULL( mean);
06305 XSH_ASSURE_NOT_NULL( stdev);
06306
06307 check( mean_val = cpl_array_get_mean( array));
06308 check( sigma = cpl_array_get_stdev( array));
06309 check( size = cpl_array_get_size( array));
06310
06311 XSH_CALLOC( flags, int, size);
06312
06313 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06314 xsh_msg_dbg_medium("Accepted fraction %f Mean %f sigma %f", 1.0, mean_val, sigma);
06315
06316
06317 check(pval=cpl_array_get_data_double(array));
06318 for( i=1; i<= niter; i++) {
06319 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06320 nb_rejected = 0;
06321 for( j=0; j< size; j++){
06322
06323 if ( flags[j] == 0 && fabs( pval[j]-mean_val) > kappa*sigma){
06324 nb_rejected++;
06325 flags[j]=1;
06326 check( cpl_array_set_invalid( array, j));
06327 }
06328 }
06329 if ( nb_rejected == 0){
06330 xsh_msg("No more points are rejected. Iterations are stopped.");
06331 break;
06332 }
06333 total_rejected += nb_rejected;
06334 frac = 1-(double)total_rejected/(double)size;
06335 if (frac < frac_min){
06336 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06337 frac_min, frac);
06338 break;
06339 }
06340
06341 check( mean_val = cpl_array_get_mean( array));
06342 check( sigma = cpl_array_get_stdev( array));
06343 xsh_msg("Accepted fraction %f Mean %f sigma %f", frac, mean_val, sigma);
06344 }
06345
06346 xsh_msg("End of clipping : Mean %f sigma %f", mean_val, sigma);
06347 *mean = mean_val;
06348 *stdev = sigma;
06349
06350 cleanup:
06351 XSH_FREE( flags);
06352 return;
06353 }
06354
06366 void
06367 xsh_array_clip_median( cpl_array *array,
06368 double kappa,
06369 int niter,
06370 double frac_min,
06371 double *median,
06372 double *stdev)
06373 {
06374 int i, j, size;
06375 double median_val;
06376 double sigma, frac;
06377 int *flags = NULL;
06378 int nb_rejected = 0, total_rejected=0;
06379 double* pval=NULL;
06380
06381 XSH_ASSURE_NOT_NULL( array);
06382 XSH_ASSURE_NOT_NULL( median);
06383 XSH_ASSURE_NOT_NULL( stdev);
06384
06385 check( median_val = cpl_array_get_median( array));
06386 check( sigma = cpl_array_get_stdev( array));
06387 check( size = cpl_array_get_size( array));
06388
06389 XSH_CALLOC( flags, int, size);
06390
06391 xsh_msg("Iteration %d/%d", 0, niter);
06392 xsh_msg("Accepted fraction %f Median %f sigma %f", 1.0, median_val, sigma);
06393 check(pval=cpl_array_get_data_double(array));
06394 for( i=1; i<= niter; i++) {
06395 xsh_msg("Iteration %d/%d", i, niter);
06396 nb_rejected = 0;
06397 for( j=0; j< size; j++){
06398
06399 if ( flags[j] == 0 && fabs( pval[j]-median_val) > kappa*sigma){
06400 nb_rejected++;
06401 flags[j]=1;
06402 check( cpl_array_set_invalid( array, j));
06403 }
06404 }
06405 if ( nb_rejected == 0){
06406 xsh_msg("No more points are rejected. Iterations are stopped.");
06407 break;
06408 }
06409 total_rejected += nb_rejected;
06410 frac = 1-(double)total_rejected/(double)size;
06411 if (frac < frac_min){
06412 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06413 frac_min, frac);
06414 break;
06415 }
06416 check( median_val = cpl_array_get_median( array));
06417 check( sigma = cpl_array_get_stdev( array));
06418 xsh_msg("Accepted fraction %f Median %f sigma %f", frac, median_val, sigma);
06419 }
06420 xsh_msg("End of clipping : Median %f sigma %f", median_val, sigma);
06421 *median = median_val;
06422 *stdev = sigma;
06423
06424 cleanup:
06425 XSH_FREE( flags);
06426 return;
06427 }
06428
06441 void
06442 xsh_array_clip_poly1d( cpl_vector *pos_vect,
06443 cpl_vector *val_vect,
06444 double kappa,
06445 int niter,
06446 double frac_min,
06447 int deg,
06448 cpl_polynomial **polyp,
06449 double *chisq,
06450 int **flagsp)
06451 {
06452 int i, j, size;
06453 double frac, sigma;
06454 int *flags = NULL;
06455 int nb_rejected = 0, total_rejected=0;
06456 cpl_polynomial *poly = NULL;
06457 cpl_vector *temp_pos = NULL, *temp_val = NULL;
06458 double *positions = NULL;
06459 double *values = NULL;
06460 int ngood=0;
06461
06462 XSH_ASSURE_NOT_NULL( pos_vect);
06463 XSH_ASSURE_NOT_NULL( val_vect);
06464
06465 XSH_ASSURE_NOT_NULL( polyp);
06466 XSH_ASSURE_NOT_NULL( flagsp);
06467
06468 check( poly = xsh_polynomial_fit_1d_create( pos_vect, val_vect, deg,
06469 chisq));
06470 check( size = cpl_vector_get_size( pos_vect));
06471
06472 XSH_CALLOC( flags, int, size);
06473 XSH_CALLOC( positions, double, size);
06474 XSH_CALLOC( values, double, size);
06475
06476 ngood = size;
06477 sigma = sqrt(*chisq);
06478
06479 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06480 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06481 1.0, deg, sigma);
06482
06483 for( i=1; i<= niter; i++) {
06484 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06485 nb_rejected = 0;
06486
06487 for( j=0; j< size; j++){
06488 double pos=0.0, val=0.0, pol_val=0.0;
06489
06490 check( pos = cpl_vector_get( pos_vect, j));
06491 check( val = cpl_vector_get( val_vect, j));
06492 check( pol_val = cpl_polynomial_eval_1d( poly, pos, NULL));
06493
06494 if ( flags[j] == 0 && fabs( pol_val-val) > kappa*sigma){
06495 nb_rejected++;
06496 flags[j]=2;
06497 }
06498 }
06499 if ( nb_rejected == 0){
06500 xsh_msg_dbg_medium("No more points are rejected. Iterations are stopped.");
06501 break;
06502 }
06503 total_rejected += nb_rejected;
06504 frac = 1-(double)total_rejected/(double)size;
06505 if (frac < frac_min){
06506 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06507 frac_min, frac);
06508 break;
06509 }
06510
06511 ngood = 0;
06512 for( j=0; j< size; j++){
06513 if( flags[j] == 0){
06514 positions[ngood] = cpl_vector_get( pos_vect, j);
06515 values[ngood] = cpl_vector_get( val_vect, j);
06516 ngood++;
06517 }
06518 else{
06519 flags[j] = 1;
06520 }
06521 }
06522 check( temp_pos = cpl_vector_wrap( ngood, positions));
06523 check( temp_val = cpl_vector_wrap( ngood, values));
06524
06525 xsh_free_polynomial( &poly);
06526
06527 check( poly = xsh_polynomial_fit_1d_create( temp_pos, temp_val, deg,
06528 chisq));
06529
06530 sigma = sqrt(*chisq);
06531
06532 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06533 frac, deg, sigma);
06534 xsh_unwrap_vector( &temp_pos);
06535 xsh_unwrap_vector( &temp_val);
06536 }
06537
06538 for( j=0; j< size; j++){
06539 if( flags[j] == 2){
06540 flags[j] = 0;
06541 }
06542 }
06543 *polyp = poly;
06544 *flagsp = flags;
06545
06546 cleanup:
06547 XSH_FREE( positions);
06548 XSH_FREE( values);
06549 xsh_unwrap_vector( &temp_pos);
06550 xsh_unwrap_vector( &temp_val);
06551 return;
06552 }
06553
06554 cpl_error_code
06555 xsh_rectify_params_set_defaults(cpl_parameterlist* pars,
06556 const char* rec_id,
06557 xsh_instrument* inst,
06558 xsh_rectify_param * rectify_par)
06559 {
06560 cpl_parameter* p=NULL;
06561
06562 check(p=xsh_parameters_find(pars,rec_id,"rectify-bin-slit"));
06563 if(cpl_parameter_get_double(p) <= 0) {
06564 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB){
06565 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_UVB;
06566 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_UVB);
06567 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS){
06568 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_VIS;
06569 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_VIS);
06570 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
06571 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_NIR;
06572 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_NIR);
06573 }
06574 }
06575 check(p=xsh_parameters_find(pars,rec_id,"rectify-bin-lambda"));
06576 if(cpl_parameter_get_double(p) <= 0) {
06577 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB){
06578 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_UVB;
06579 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_UVB);
06580 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS){
06581 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_VIS;
06582 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_VIS);
06583 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
06584 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_NIR;
06585 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_NIR);
06586 }
06587 }
06588
06589 cleanup:
06590
06591 return cpl_error_get_code();
06592
06593 }
06594
06595
06596 struct data {
06597 size_t n;
06598 double * y;
06599 double * x;
06600 int deg;
06601 };
06602
06603 static int
06604 expb_f (const gsl_vector * x, void *data,
06605 gsl_vector * f)
06606 {
06607 int i;
06608 int n = ((struct data *)data)->n;
06609 double *y = ((struct data *)data)->y;
06610 double *xtab = ((struct data *) data)->x;
06611
06612 double area = gsl_vector_get (x, 0);
06613 double a = gsl_vector_get (x, 1);
06614 double b = gsl_vector_get( x,2);
06615 double c = gsl_vector_get( x,3);
06616 double x0 = gsl_vector_get( x,4);
06617 double sigma = gsl_vector_get( x,5);
06618
06619 for (i = 0; i < n; i++)
06620 {
06621
06622 double t = xtab[i];
06623 double height = area/sqrt(2*M_PI*sigma*sigma);
06624 double W = ((t-x0)*(t-x0))/(2*sigma*sigma);
06625
06626 double Yi = height*exp(-W)+a+b*t+c*t*t;
06627
06628 gsl_vector_set (f, i, Yi - y[i]);
06629 }
06630
06631 return GSL_SUCCESS;
06632 }
06633
06634 static int
06635 expb_df (const gsl_vector * x, void *data,
06636 gsl_matrix * J)
06637 {
06638 int i;
06639 int n = ((struct data *)data)->n;
06640 double *xtab = ((struct data *) data)->x;
06641
06642 double area = gsl_vector_get (x, 0);
06643 double x0 = gsl_vector_get (x, 4);
06644 double sigma = gsl_vector_get( x,5);
06645 int deg = ((struct data *)data)->deg;
06646 for (i = 0; i < n; i++)
06647 {
06648
06649
06650
06651
06652 double t = xtab[i];
06653
06654 double W = ((t-x0)*(t-x0))/(2*sigma*sigma);
06655 double e = 0.0;
06656
06657
06658
06659 e = exp(-W)/sqrt(2*M_PI*sigma*sigma);
06660 gsl_matrix_set (J, i, 0, e);
06661
06662
06663 e = 1;
06664 gsl_matrix_set (J, i, 1, e);
06665
06666
06667 if (deg >= 1){
06668 e = t;
06669 }
06670 else {
06671 e = 0;
06672 }
06673 gsl_matrix_set (J, i, 2, e);
06674
06675
06676 if (deg == 2) {
06677 e = t*t;
06678 }
06679 else {
06680 e = 0;
06681 }
06682 gsl_matrix_set (J, i, 3, e);
06683
06684
06685 e = area/(2*M_PI*sigma)*(t-x0)/sigma*exp(-0.5*pow((t-x0)/sigma,2));
06686 gsl_matrix_set (J, i, 4, e);
06687
06688
06689 e = (sqrt(2)*area*x0*x0-pow(2,1.5)*area*t*x0+sqrt(2)*area*t*t-sqrt(2)*area*sigma*sigma)*exp(-W)/(2*sqrt(M_PI)*sigma*sigma*sigma*sigma);
06690 gsl_matrix_set (J, i, 5, e);
06691
06692 }
06693 return GSL_SUCCESS;
06694 }
06695
06696 static int
06697 expb_fdf (const gsl_vector * x, void *data,
06698 gsl_vector * f, gsl_matrix * J)
06699 {
06700 expb_f (x, data, f);
06701 expb_df (x, data, J);
06702
06703 return GSL_SUCCESS;
06704 }
06705
06706
06707
06708
06709 void xsh_gsl_init_gaussian_fit( cpl_vector *xpos_vect, cpl_vector *ypos_vect,
06710 double *init_par)
06711 {
06712 double flux_max, flux_min, intensity;
06713 int i, size;
06714 double init_area, init_sigma, init_x0=0, init_offset;
06715 double flux_sum =0.0;
06716 double hflux, flux25, flux75;
06717 double init25=0, init75=0;
06718
06719 XSH_ASSURE_NOT_NULL( xpos_vect);
06720 XSH_ASSURE_NOT_NULL( ypos_vect);
06721
06722 size = cpl_vector_get_size( xpos_vect);
06723 flux_min = cpl_vector_get_min( ypos_vect);
06724 flux_max = cpl_vector_get_max( ypos_vect);
06725 intensity = flux_max-flux_min;
06726
06727 init_offset = flux_min;
06728
06729 for (i = 0; i < size; i++){
06730 double yval;
06731
06732 yval = cpl_vector_get( ypos_vect, i);
06733 flux_sum += yval-init_offset;
06734 }
06735
06736 hflux = flux_sum/2.0;
06737 flux25 = flux_sum*0.25;
06738 flux75 = flux_sum*0.75;
06739 flux_sum =0.0;
06740
06741 for (i = 0; i < size; i++){
06742 double yval;
06743
06744 yval = cpl_vector_get( ypos_vect, i);
06745
06746 flux_sum += yval-init_offset;
06747
06748 if ( (init25 == 0) && flux_sum > flux25){
06749 init25 = (i+i-1)/2.0;
06750 }
06751
06752 if ( (init_x0 == 0) && flux_sum > hflux){
06753 init_x0 = (i+i-1)/2.0;
06754 }
06755
06756 if ( (init75 == 0) && flux_sum > flux75){
06757 init75 = (i+i-1)/2.0;
06758 break;
06759 }
06760
06761 }
06762 init_sigma = (init75-init25)/(2*0.6744);
06763 init_area = intensity*sqrt(2*M_PI*init_sigma*init_sigma);
06764
06765 xsh_msg_dbg_high("DV FIT area %f x0 %f sigma %f offset %f",
06766 init_area, init_x0, init_sigma, init_offset);
06767
06768 init_par[0] = init_area;
06769 init_par[1] = init_offset;
06770 init_par[2] = 0;
06771 init_par[3] = 0;
06772 init_par[4] = init_x0;
06773 init_par[5] = init_sigma;
06774
06775 cleanup:
06776 return;
06777 }
06778
06779
06780
06781
06782 void xsh_gsl_fit_gaussian( cpl_vector *xpos_vect, cpl_vector *ypos_vect,
06783 int deg,
06784 double *params, double *errs, int *status)
06785 {
06786 const gsl_multifit_fdfsolver_type *T;
06787 gsl_multifit_fdfsolver *s;
06788 int iter = 0;
06789 const size_t p = 6;
06790 gsl_matrix *covar = gsl_matrix_alloc (p, p);
06791 int n=0;
06792 struct data d = { n, NULL, NULL,deg};
06793 gsl_multifit_function_fdf f;
06794 gsl_vector* x = NULL;
06795 double area, offset, b, c, x0, sigma;
06796 double chi, dof, cte;
06797 int size;
06798 double *xpos = NULL;
06799 double *ypos = NULL;
06800
06801
06802 XSH_ASSURE_NOT_NULL( xpos_vect);
06803 XSH_ASSURE_NOT_NULL( ypos_vect);
06804 XSH_ASSURE_NOT_NULL( params);
06805 XSH_ASSURE_NOT_NULL( errs);
06806 XSH_ASSURE_NOT_NULL( status);
06807
06808
06809 size = cpl_vector_get_size( xpos_vect);
06810 xpos = cpl_vector_get_data( xpos_vect);
06811 ypos = cpl_vector_get_data( ypos_vect);
06812
06813 x = gsl_vector_calloc (p);
06814
06815 area = params[0];
06816 offset = params[1];
06817 b = params[2];
06818 c = params[3];
06819 x0 = params[4];
06820 sigma = params[5];
06821
06822 gsl_vector_set( x, 0, area);
06823 gsl_vector_set( x, 1, offset);
06824 gsl_vector_set( x, 2, b);
06825 gsl_vector_set( x, 3, c);
06826 gsl_vector_set( x, 4, x0);
06827 gsl_vector_set( x, 5, sigma);
06828
06829 n = size;
06830 d.n = size;
06831 d.y = ypos;
06832 d.x = xpos;
06833 d.deg = deg;
06834
06835 f.f = &expb_f;
06836 f.df = &expb_df;
06837 f.fdf = &expb_fdf;
06838 f.n = n;
06839 f.p = p;
06840 f.params = &d;
06841
06842
06843 T = gsl_multifit_fdfsolver_lmsder;
06844 s = gsl_multifit_fdfsolver_alloc (T, n, p);
06845 gsl_multifit_fdfsolver_set (s, &f, x);
06846
06847 xsh_msg_dbg_high ("iter: %3u area % 15.8f a % 15.8f b % 15.8f c % 15.8f x0 % 15.8f sigma % 15.8f |f(x)| = %g\n",
06848 iter,
06849 gsl_vector_get (s->x, 0),
06850 gsl_vector_get (s->x, 1),
06851 gsl_vector_get (s->x, 2),
06852 gsl_vector_get (s->x, 3),
06853 gsl_vector_get (s->x, 4),
06854 gsl_vector_get (s->x, 5),
06855 gsl_blas_dnrm2 (s->f));
06856 do
06857 {
06858 iter++;
06859 *status = gsl_multifit_fdfsolver_iterate (s);
06860
06861 xsh_msg_dbg_high ("iter: %3u area % 15.8f a % 15.8f b % 15.8f c % 15.8f x0 % 15.8f sigma % 15.8f |f(x)| = %g\n",
06862 iter,
06863 gsl_vector_get (s->x, 0),
06864 gsl_vector_get (s->x, 1),
06865 gsl_vector_get (s->x, 2),
06866 gsl_vector_get (s->x, 3),
06867 gsl_vector_get (s->x, 4),
06868 gsl_vector_get (s->x, 5),
06869 gsl_blas_dnrm2 (s->f));
06870
06871 if (*status)
06872 break;
06873
06874 *status = gsl_multifit_test_delta (s->dx, s->x,
06875 1e-2, 1e-2);
06876
06877 }
06878 while ( *status == GSL_CONTINUE && iter < 500);
06879
06880 gsl_multifit_covar (s->J, 0.0, covar);
06881
06882 params[0] = gsl_vector_get( s->x, 0);
06883 params[1] = gsl_vector_get( s->x, 1);
06884 params[2] = gsl_vector_get( s->x, 2);
06885 params[3] = gsl_vector_get( s->x, 3);
06886 params[4] = gsl_vector_get( s->x, 4);
06887 params[5] = gsl_vector_get( s->x, 5);
06888
06889 chi = gsl_blas_dnrm2(s->f);
06890 dof = n-p;
06891 cte = GSL_MAX_DBL(1, chi / sqrt(dof));
06892
06893 errs[0] = cte * sqrt(gsl_matrix_get(covar,0,0));
06894 errs[1] = cte * sqrt(gsl_matrix_get(covar,1,1));
06895 errs[2] = cte * sqrt(gsl_matrix_get(covar,2,2));
06896 errs[3] = cte * sqrt(gsl_matrix_get(covar,3,3));
06897 errs[4] = cte * sqrt(gsl_matrix_get(covar,4,4));
06898 errs[5] = cte * sqrt(gsl_matrix_get(covar,5,5));
06899
06900
06901 cleanup:
06902
06903 gsl_multifit_fdfsolver_free (s);
06904 gsl_matrix_free (covar);
06905 gsl_vector_free( x);
06906 return;
06907 }
06908
06933 double*
06934 xsh_function1d_xcorrelate(
06935 double * line_i,
06936 int width_i,
06937 double * line_t,
06938 int width_t,
06939 int half_search,
06940 int normalise,
06941 double * xcorr_max,
06942 double * delta
06943 )
06944 {
06945 double * xcorr ;
06946 double mean_i, mean_t ;
06947 double rms_i, rms_t ;
06948 double sum, sqsum ;
06949 double norm ;
06950 int maxpos ;
06951 int nsteps ;
06952 int i ;
06953 int step ;
06954 int nval ;
06955 int STEP_MIN=-half_search;
06956 int STEP_MAX=half_search;
06957
06958
06959 sum = sqsum = 0.00 ;
06960 for (i=0 ; i<width_i ; i++) {
06961 sum += line_i[i] ;
06962 sqsum += line_i[i] * line_i[i];
06963 }
06964
06965 mean_i = sum / (double) width_i ;
06966 sqsum /= (double)width_i ;
06967 rms_i = sqsum - mean_i*mean_i ;
06968
06969 sum = sqsum = 0.00 ;
06970 for (i=0 ; i<width_t ; i++) {
06971 sum += line_t[i] ;
06972 sqsum += line_t[i] * line_t[i];
06973 }
06974 mean_t = sum / (double)width_t ;
06975 sqsum /= (double)width_t ;
06976 rms_t = sqsum - mean_t*mean_t ;
06977
06978 norm = 1.00 / sqrt(rms_i * rms_t);
06979
06980 nsteps = (STEP_MAX - STEP_MIN) +1 ;
06981 xcorr = cpl_malloc(nsteps * sizeof(double));
06982 if(normalise==0) {
06983 mean_t=0;
06984 norm=1;
06985 }
06986 for (step=STEP_MIN ; step<=STEP_MAX ; step++) {
06987 xcorr[step-STEP_MIN] = 0.00 ;
06988 nval = 0 ;
06989 for (i=0 ; i<width_t ; i++) {
06990 if ((i+step > 0) &&
06991 (i+step < width_i)) {
06992 xcorr[step-STEP_MIN] += (line_t[i] - mean_t) *
06993 (line_i[i+step] - mean_i) *
06994 norm ;
06995 nval++ ;
06996 }
06997 }
06998 xcorr[step-STEP_MIN] /= (double) nval ;
06999 }
07000
07001 *xcorr_max = xcorr[0] ;
07002 maxpos = 0 ;
07003 for (i=0 ; i<nsteps ; i++) {
07004 if (xcorr[i]>(*xcorr_max)) {
07005 maxpos = i ;
07006 *xcorr_max = xcorr[i];
07007 }
07008 }
07009
07010 cpl_vector* vcor=cpl_vector_wrap(nsteps,xcorr);
07011 double a=xcorr[maxpos-1];
07012 double b=xcorr[maxpos+1];
07013 double c=xcorr[maxpos];
07014 double fraction=(a-b)/(2.*a+2.*b-4.*c);
07015
07016 cpl_vector_unwrap(vcor);
07017
07018
07019
07020 (*delta) = (double)STEP_MIN + (double)maxpos;
07021 *delta-=fraction;
07022
07023 return xcorr;
07024 }
07025