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 int nb_val ;
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 nb_val = 0 ;
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 const char* dpr_tech=NULL;
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 dpr_tech=xsh_pfits_get_dpr_tech(plist);
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[80];
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, ts ;
01224
01225 lvl = xsh_parameters_get_temporary( recipe_id, parameters ) ;
01226 if ( lvl == 0 )
01227 xsh_msg( "Keep Temporary File = no" ) ;
01228 else
01229 xsh_msg( "Keep Temporary File = yes" ) ;
01230
01231 lvl = xsh_parameters_debug_level_get( recipe_id, parameters ) ;
01232 xsh_msg( "Xsh Debug Level = %s", xsh_debug_level_tostring() ) ;
01233
01234 ts = xsh_parameters_time_stamp_get( recipe_id, parameters ) ;
01235 }
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 {
01249 int version_string_length;
01250 int major_version, minor_version, micro_version;
01251
01252 major_version = binary_version / 10000;
01253 minor_version = (binary_version % 10000) / 100;
01254 micro_version = binary_version % 100;
01255
01256
01257 assure (major_version < 100, CPL_ERROR_UNSUPPORTED_MODE,
01258 "Major version: %d", major_version);
01259
01260 version_string_length = strlen ("XX.YY.ZZ");
01261 recipe_version = cpl_calloc (sizeof (char), version_string_length + 1);
01262
01263 snprintf (recipe_version, version_string_length + 1,
01264 "%d.%d.%d", major_version, minor_version, micro_version);
01265
01266 recipe_string =
01267 xsh_stringcat_4 ("Recipe: ", recipe_id, " ", recipe_version);
01268 }
01269
01270 {
01271 int field = MAXIMUM (strlen (PACKAGE_STRING), strlen (recipe_string));
01272 int nstars = 3 + 1 + field + 1 + 3;
01273 int nspaces1, nspaces2, nspaces3, nspaces4;
01274 int i;
01275
01276
01277 nspaces1 = (field - strlen (PACKAGE_STRING)) / 2;
01278 nspaces2 = field - strlen (PACKAGE_STRING) - nspaces1;
01279
01280 nspaces3 = (field - strlen (recipe_string)) / 2;
01281 nspaces4 = field - strlen (recipe_string) - nspaces3;
01282
01283 spaces1 = cpl_calloc (sizeof (char), nspaces1 + 1);
01284 for (i = 0; i < nspaces1; i++)
01285 spaces1[i] = ' ';
01286 spaces2 = cpl_calloc (sizeof (char), nspaces2 + 1);
01287 for (i = 0; i < nspaces2; i++)
01288 spaces2[i] = ' ';
01289 spaces3 = cpl_calloc (sizeof (char), nspaces3 + 1);
01290 for (i = 0; i < nspaces3; i++)
01291 spaces3[i] = ' ';
01292 spaces4 = cpl_calloc (sizeof (char), nspaces4 + 1);
01293 for (i = 0; i < nspaces4; i++)
01294 spaces4[i] = ' ';
01295
01296 stars = cpl_calloc (sizeof (char), nstars + 1);
01297 for (i = 0; i < nstars; i++)
01298 stars[i] = '*';
01299
01300 xsh_msg ("%s", stars);
01301 xsh_msg ("*** %s%s%s ***", spaces1, PACKAGE_STRING, spaces2);
01302 xsh_msg ("*** %s%s%s ***", spaces3, recipe_string, spaces4);
01303 xsh_msg ("%s", stars);
01304 }
01305
01306 xsh_msg (" %s", short_descr);
01307
01308 check( *instrument = xsh_dfs_set_groups( frames));
01309 check( xsh_instrument_set_recipe_id( *instrument, recipe_id));
01310 p=xsh_parameters_find(parameters,recipe_id,"decode-bp");
01311 decode_bp=cpl_parameter_get_int(p);
01312 check( xsh_instrument_set_decode_bp( *instrument, decode_bp));
01313 XSH_NEW_FRAMESET( *raws);
01314 XSH_NEW_FRAMESET( *calib);
01315 check( xsh_dfs_split_in_group( frames, *raws, *calib));
01316 check( xsh_dfs_filter( *raws, tag_list, tag_list_size));
01317 XSH_ASSURE_NOT_NULL( *raws);
01318 XSH_ASSURE_NOT_NULL( *instrument);
01319 xsh_dfs_files_dont_exist(frames);
01320 nraws=cpl_frameset_get_size(*raws);
01321 XSH_ASSURE_NOT_ILLEGAL_MSG(nraws>0,"Provide at least a valid input raw frame");
01322
01323 xsh_msg("RAW files");
01324 check( xsh_print_cpl_frameset( *raws));
01325 xsh_msg("CALIB files");
01326 check( xsh_print_cpl_frameset( *calib));
01327
01328 if((*calib != NULL) && (xsh_instrument_get_arm(*instrument) != XSH_ARM_NIR)) {
01329
01330 cpl_frameset_dump(*raws,stdout);
01331 check(*calib=xsh_correct_calib(*raws,*calib));
01332
01333 }
01334 if(xsh_instrument_get_arm(*instrument) == XSH_ARM_NIR) {
01335 xsh_instrument_nir_corr_if_JH(*raws,*instrument);
01336 if( (strcmp(recipe_id,"xsh_lingain") !=0) &&
01337 (strcmp(recipe_id,"xsh_mdark") !=0) ) {
01338 check(xsh_instrument_nir_corr_if_spectral_format_is_JH(*calib,*instrument));
01339 }
01340 xsh_calib_nir_corr_if_JH(*calib,*instrument,recipe_id);
01341 }
01342
01343 cleanup:
01344 cpl_free (recipe_string);
01345 cpl_free (recipe_version);
01346 cpl_free (stars);
01347 cpl_free (spaces1);
01348 cpl_free (spaces2);
01349 cpl_free (spaces3);
01350 cpl_free (spaces4);
01351 return cpl_error_get_code ();
01352 }
01353
01354
01355
01356 static char **TempFiles = NULL ;
01357 static int NbTemp = 0 ;
01358 static char **ProdFiles = NULL ;
01359 static int NbProducts = 0 ;
01360
01361
01368
01369 void xsh_add_temporary_file( const char *name)
01370 {
01371 if ( TempFiles == NULL ){
01372 TempFiles = cpl_malloc( sizeof( char*));
01373 }
01374 else {
01375 TempFiles = cpl_realloc( TempFiles, (NbTemp + 1)*sizeof( char *));
01376 }
01377 TempFiles[NbTemp] = cpl_malloc( strlen( name) + 1);
01378 strcpy( TempFiles[NbTemp], name);
01379 NbTemp++;
01380 }
01381
01382
01387
01388 void xsh_free_temporary_files( void)
01389 {
01390 int i;
01391
01392 for( i = 0 ; i<NbTemp ; i++){
01393 cpl_free( TempFiles[i]);
01394 }
01395 cpl_free( TempFiles);
01396 TempFiles = NULL;
01397 NbTemp=0;
01398 }
01399
01400
01407
01408 void xsh_add_product_file( const char *name)
01409 {
01410 if ( ProdFiles == NULL ){
01411 ProdFiles = cpl_malloc( sizeof( char*));
01412 }
01413 else {
01414 ProdFiles = cpl_realloc( ProdFiles, (NbProducts + 1)*sizeof( char *));
01415 }
01416 ProdFiles[NbProducts] = cpl_malloc( strlen( name) + 1);
01417 strcpy( ProdFiles[NbProducts], name);
01418 NbProducts++;
01419 }
01420
01421
01426
01427 void xsh_free_product_files( void)
01428 {
01429 int i;
01430
01431 for( i = 0 ; i<NbProducts ; i++){
01432 cpl_free( ProdFiles[i]);
01433 }
01434 cpl_free( ProdFiles);
01435 ProdFiles=NULL;
01436 NbProducts=0;
01437 }
01438
01439
01440
01453
01454 cpl_error_code
01455 xsh_end (const char *recipe_id,
01456 cpl_frameset * frames,
01457 cpl_parameterlist * parameters )
01458 {
01459 int i;
01460 int warnings = xsh_msg_get_warnings ();
01461
01462
01463 {
01464 cpl_frame * current = NULL;
01465 int nframes = 0, j;
01466
01467 nframes = cpl_frameset_get_size( frames ) ;
01468 for( j = 0 ; j<nframes ; j++ ) {
01469 current = cpl_frameset_get_frame( frames, j);
01470 if ( cpl_frame_get_group( current ) == CPL_FRAME_GROUP_PRODUCT ) {
01471 xsh_print_cpl_frame( current ) ;
01472 }
01473 }
01474 }
01475 frames = frames ;
01476
01477
01478
01479 if ( xsh_parameters_get_temporary( recipe_id, parameters ) == 0 ) {
01480 xsh_msg( "---- Deleting Temporary Files" ) ;
01481 for( i = 0 ; i<NbTemp ; i++ ) {
01482 xsh_msg( " '%s'", TempFiles[i] ) ;
01483 unlink( TempFiles[i] ) ;
01484
01485 }
01486 } else {
01487
01488
01489
01490
01491
01492
01493
01494 }
01495
01496
01497 if (warnings > 0) {
01498 xsh_msg_warning ("Recipe '%s' produced %d warning %s (excluding this one)",
01499 recipe_id, xsh_msg_get_warnings (),
01500 (warnings > 1) ? "s" : "");
01501 }
01502
01503
01504 xsh_free_temporary_files();
01505 xsh_free_product_files();
01506 return cpl_error_get_code ();
01507 }
01508
01509
01534
01535 cpl_error_code
01536 xsh_get_property_value (const cpl_propertylist * plist,
01537 const char *keyword,
01538 cpl_type keywordtype,
01539 void *result)
01540 {
01541 cpl_type t;
01542
01543
01544 assure (plist != NULL, CPL_ERROR_NULL_INPUT, "Null property list");
01545 assure (keyword != NULL, CPL_ERROR_NULL_INPUT, "Null keyword");
01546
01547 assure (cpl_propertylist_has (plist, keyword), CPL_ERROR_DATA_NOT_FOUND,
01548 "Keyword %s does not exist", keyword);
01549
01550 check_msg (t = cpl_propertylist_get_type (plist, keyword),
01551 "Could not read type of keyword '%s'", keyword);
01552 assure (t == keywordtype, CPL_ERROR_TYPE_MISMATCH,
01553 "Keyword '%s' has wrong type (%s). %s expected",
01554 keyword, xsh_tostring_cpl_type (t),
01555 xsh_tostring_cpl_type (keywordtype));
01556
01557 switch (keywordtype) {
01558 case CPL_TYPE_INT:
01559 check_msg (*((int *) result) = cpl_propertylist_get_int (plist, keyword),
01560 "Could not get (integer) value of %s", keyword);
01561 break;
01562 case CPL_TYPE_BOOL:
01563 check_msg (*((bool *) result) = cpl_propertylist_get_bool (plist, keyword),
01564 "Could not get (boolean) value of %s", keyword);
01565 break;
01566 case CPL_TYPE_DOUBLE:
01567 check_msg (*((double *) result) =
01568 cpl_propertylist_get_double (plist, keyword),
01569 "Could not get (double) value of %s", keyword);
01570 break;
01571 case CPL_TYPE_STRING:
01572 check_msg (*((const char **) result) =
01573 cpl_propertylist_get_string (plist, keyword),
01574 "Could not get (string) value of %s", keyword);
01575 break;
01576 default:
01577 assure (false, CPL_ERROR_INVALID_TYPE, "Unknown type");
01578 }
01579
01580 cleanup:
01581 return cpl_error_get_code ();
01582 }
01583
01584
01592
01593 char *
01594 xsh_stringdup (const char *s)
01595 {
01596 char *result = NULL;
01597
01598 assure (s != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01599
01600 result = cpl_calloc (sizeof (char), strlen (s) + 1);
01601 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01602 "Memory allocation failed");
01603
01604 sprintf (result, "%s", s);
01605
01606 cleanup:
01607 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01608 cpl_free (result);
01609 result = NULL;
01610 }
01611
01612 return result;
01613 }
01614
01626 char *
01627 xsh_sdate_utc( time_t *now )
01628 {
01629 char *date = NULL;
01630 struct tm ttm;
01631
01632 ttm = *gmtime( now ) ;
01633 XSH_CALLOC( date, char, 16);
01634
01635 sprintf( date, "%04d%02d%02d-%02d%02d%02d",
01636 ttm.tm_year+1900, ttm.tm_mon+1, ttm.tm_mday,
01637 ttm.tm_hour, ttm.tm_min, ttm.tm_sec ) ;
01638
01639 cleanup:
01640 return date ;
01641
01642 }
01643
01644
01653
01654 char *
01655 xsh_stringcat (const char *s1, const char *s2)
01656 {
01657 char *result = NULL;
01658
01659 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01660 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01661
01662 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + 1);
01663 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01664 "Memory allocation failed");
01665
01666 sprintf (result, "%s%s", s1, s2);
01667
01668 cleanup:
01669 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01670 cpl_free (result);
01671 result = NULL;
01672 }
01673
01674 return result;
01675 }
01676
01677
01687
01688 char *
01689 xsh_stringcat_3 (const char *s1, const char *s2, const char *s3)
01690 {
01691 char *result = NULL;
01692
01693 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01694 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01695 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01696
01697 result =
01698 cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + strlen (s3) + 1);
01699 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01700 "Memory allocation failed");
01701
01702 sprintf (result, "%s%s%s", s1, s2, s3);
01703
01704 cleanup:
01705 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01706 cpl_free (result);
01707 result = NULL;
01708 }
01709
01710 return result;
01711 }
01712
01713
01725
01726 char *
01727 xsh_stringcat_4 (const char *s1, const char *s2, const char *s3,const char *s4)
01728 {
01729 char *result = NULL;
01730
01731 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01732 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01733 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01734 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01735
01736 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01737 strlen (s3) + strlen (s4) + 1);
01738 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01739 "Memory allocation failed");
01740
01741 sprintf (result, "%s%s%s%s", s1, s2, s3, s4);
01742
01743 cleanup:
01744 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01745 cpl_free (result);
01746 result = NULL;
01747 }
01748
01749 return result;
01750 }
01751
01752
01765
01766 char *
01767 xsh_stringcat_5 (const char *s1, const char *s2, const char *s3,
01768 const char *s4, const char *s5)
01769 {
01770 char *result = NULL;
01771
01772 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01773 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01774 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01775 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01776 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01777
01778 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01779 strlen (s3) +strlen (s4) + strlen (s5) + 1);
01780 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01781 "Memory allocation failed");
01782
01783 sprintf (result, "%s%s%s%s%s", s1, s2, s3, s4, s5);
01784
01785 cleanup:
01786 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01787 cpl_free (result);
01788 result = NULL;
01789 }
01790
01791 return result;
01792 }
01793
01794
01809
01810 char *
01811 xsh_stringcat_6 (const char *s1, const char *s2, const char *s3,
01812 const char *s4, const char *s5, const char *s6)
01813 {
01814 char *result = NULL;
01815
01816 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01817 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01818 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01819 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01820 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01821 assure (s6 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01822
01823 result = cpl_calloc (sizeof (char),
01824 strlen (s1) + strlen (s2) + strlen (s3) +
01825 strlen (s4) + strlen (s5) + strlen (s6) + 1);
01826 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01827 "Memory allocation failed");
01828
01829 sprintf (result, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6);
01830
01831 cleanup:
01832 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01833 cpl_free (result);
01834 result = NULL;
01835 }
01836
01837 return result;
01838 }
01839
01852 char *
01853 xsh_stringcat_any (const char *s, ...)
01854 {
01855 char *result = NULL;
01856 int size = 2;
01857 va_list av;
01858
01859 va_start (av, s);
01860 result = cpl_malloc (2);
01861 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01862 "Memory allocation failed");
01863 result[0] = '\0';
01864 for (;;) {
01865 size += strlen (s) + 2;
01866 result = cpl_realloc (result, size);
01867 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01868 "Memory allocation failed");
01869 strcat (result, s);
01870 s = va_arg (av, char *);
01871 if (s == NULL || *s == '\0')
01872 break;
01873 }
01874
01875 cleanup:
01876 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01877 cpl_free (result);
01878 result = NULL;
01879 }
01880
01881 va_end (av);
01882 return result;
01883 }
01884
01885
01893
01894 int* xsh_sort(void* base, size_t nmemb, size_t size,
01895 int (*compar)(const void *, const void *)) {
01896
01897 int i = 0;
01898 int * idx = NULL;
01899 xsh_sort_data* sort = NULL;
01900
01901
01902 XSH_ASSURE_NOT_NULL(base);
01903 XSH_ASSURE_NOT_ILLEGAL(nmemb > 0);
01904 XSH_ASSURE_NOT_ILLEGAL(size > 0);
01905 XSH_ASSURE_NOT_NULL(compar);
01906
01907
01908 XSH_MALLOC(idx,int,nmemb);
01909 XSH_MALLOC(sort,xsh_sort_data,nmemb);
01910
01911
01912 for( i=0; i< (int)nmemb; i++) {
01913 sort[i].data = (void*)((size_t)base+i*size);
01914 sort[i].idx = i;
01915 }
01916
01917
01918 qsort(sort,nmemb,sizeof(xsh_sort_data),compar);
01919
01920
01921 for( i=0; i< (int)nmemb; i++) {
01922 idx[i] = sort[i].idx;
01923 }
01924
01925 cleanup:
01926 XSH_FREE(sort);
01927 return idx;
01928 }
01929
01936 void xsh_reindex(double* data, int* idx, int size) {
01937 int i;
01938
01939
01940 XSH_ASSURE_NOT_NULL(data);
01941 XSH_ASSURE_NOT_NULL(idx);
01942 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01943
01944 for(i=0; i< size; i++){
01945 int id;
01946 double temp;
01947
01948 id = idx[i];
01949 while (id < i){
01950 id = idx[id];
01951 }
01952 temp = data[i];
01953 data[i] = data[id];
01954 data[id] = temp;
01955 }
01956 cleanup:
01957 return;
01958 }
01959
01966 void xsh_reindex_float(float * data, int* idx, int size)
01967 {
01968 int i;
01969
01970
01971 XSH_ASSURE_NOT_NULL(data);
01972 XSH_ASSURE_NOT_NULL(idx);
01973 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01974
01975 for(i=0; i< size; i++){
01976 int id;
01977 float temp;
01978
01979 id = idx[i];
01980 while (id < i){
01981 id = idx[id];
01982 }
01983 temp = data[i];
01984 data[i] = data[id];
01985 data[id] = temp;
01986 }
01987 cleanup:
01988 return;
01989 }
01990
01991
01998 void xsh_reindex_int( int * data, int* idx, int size)
01999 {
02000 int i;
02001
02002
02003 XSH_ASSURE_NOT_NULL(data);
02004 XSH_ASSURE_NOT_NULL(idx);
02005 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
02006
02007 for(i=0; i< size; i++){
02008 int id;
02009 int temp;
02010
02011 id = idx[i];
02012 while (id < i){
02013 id = idx[id];
02014 }
02015 temp = data[i];
02016 data[i] = data[id];
02017 data[id] = temp;
02018 }
02019 cleanup:
02020 return;
02021 }
02022
02023
02024
02029
02030 void xsh_free(const void *mem)
02031 {
02032 cpl_free((void *)mem);
02033 return;
02034 }
02035
02036
02037
02042
02043 void
02044 xsh_free_image (cpl_image ** i)
02045 {
02046 if (i && *i) {
02047 cpl_image_delete (*i);
02048 *i = NULL;
02049 }
02050 }
02051
02052
02053
02054
02059
02060 void
02061 xsh_free_table (cpl_table ** t)
02062 {
02063 if (t && *t) {
02064 cpl_table_delete (*t);
02065 *t = NULL;
02066 }
02067 }
02068
02069
02070
02075
02076 void
02077 xsh_free_mask (cpl_mask ** m)
02078 {
02079 if (m && *m) {
02080 cpl_mask_delete (*m);
02081 *m = NULL;
02082 }
02083 }
02084
02085
02090
02091 void
02092 xsh_free_imagelist (cpl_imagelist ** i)
02093 {
02094 if (i && *i) {
02095 cpl_imagelist_delete (*i);
02096 *i = NULL;
02097 }
02098 }
02099
02100
02105
02106 void
02107 xsh_free_propertylist (cpl_propertylist ** p)
02108 {
02109 if (p && *p) {
02110 cpl_propertylist_delete (*p);
02111 *p = NULL;
02112 }
02113 }
02114
02115
02120
02121 void
02122 xsh_free_polynomial (cpl_polynomial ** p)
02123 {
02124 if (p && *p) {
02125 cpl_polynomial_delete (*p);
02126 *p = NULL;
02127 }
02128 }
02129
02130
02135
02136 void
02137 xsh_free_matrix (cpl_matrix ** m)
02138 {
02139 if (m && *m) {
02140 cpl_matrix_delete (*m);
02141 *m = NULL;
02142 }
02143 }
02144
02145
02150
02151 void
02152 xsh_free_parameterlist (cpl_parameterlist ** p)
02153 {
02154 if (p && *p) {
02155 cpl_parameterlist_delete (*p);
02156 *p = NULL;
02157 }
02158 }
02159
02160
02165
02166 void
02167 xsh_free_parameter (cpl_parameter ** p)
02168 {
02169 if (p && *p) {
02170 cpl_parameter_delete (*p);
02171 *p = NULL;
02172 }
02173 }
02174
02175
02180
02181 void
02182 xsh_free_frameset (cpl_frameset ** f)
02183 {
02184 if (f && *f) {
02185 cpl_frameset_delete (*f);
02186 *f = NULL;
02187 }
02188 }
02189
02190
02195
02196 void
02197 xsh_free_frame (cpl_frame ** f)
02198 {
02199 if (f && *f) {
02200 cpl_frame_delete (*f);
02201 *f = NULL;
02202 }
02203 }
02204
02205
02210
02211 void
02212 xsh_free_vector (cpl_vector ** v)
02213 {
02214 if (v && *v) {
02215 cpl_vector_delete (*v);
02216 *v = NULL;
02217 }
02218 }
02219
02220
02225
02226 void
02227 xsh_free_array (cpl_array ** m)
02228 {
02229 if (m && *m) {
02230 cpl_array_delete (*m);
02231 *m = NULL;
02232 }
02233 }
02234
02235
02240
02241 void
02242 xsh_free_stats (cpl_stats ** s)
02243 {
02244 if (s && *s) {
02245 cpl_stats_delete (*s);
02246 *s = NULL;
02247 }
02248 }
02249
02250
02257
02258 void xsh_unwrap_image( cpl_image **i)
02259 {
02260 if ( i && *i) {
02261 cpl_image_unwrap( *i);
02262 *i = NULL;
02263 }
02264 }
02265
02266
02271
02272 void
02273 xsh_unwrap_vector (cpl_vector ** v)
02274 {
02275 if (v && *v) {
02276 cpl_vector_unwrap (*v);
02277 *v = NULL;
02278 }
02279 }
02280
02281
02282
02287
02288 void
02289 xsh_unwrap_array (cpl_array ** a)
02290 {
02291 if (a && *a) {
02292 cpl_array_unwrap (*a);
02293 *a = NULL;
02294 }
02295 }
02296
02297
02302
02303 void
02304 xsh_unwrap_bivector_vectors (cpl_bivector ** b)
02305 {
02306 if (b && *b) {
02307 cpl_bivector_unwrap_vectors (*b);
02308 *b = NULL;
02309 }
02310 }
02311
02312
02317 void xsh_show_time( const char *comment )
02318 {
02319 struct rusage tm0 ;
02320
02321 getrusage( 0, &tm0 ) ;
02322 xsh_msg( "%s - User: %u.%06u - Syst: %u.%06u",
02323 comment, (unsigned)tm0.ru_utime.tv_sec,
02324 (unsigned)tm0.ru_utime.tv_usec,
02325 (unsigned)tm0.ru_stime.tv_sec,
02326 (unsigned)tm0.ru_stime.tv_usec ) ;
02327 return ;
02328 }
02329
02330
02331 #define XSH_DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
02332 #define XSH_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; }
02333 #define XSH_INT_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; }
02334
02335 #define XSH_PIX_STACK_SIZE 50
02336
02337
02338
02348 void
02349 xsh_tools_get_statistics(double* tab, int size, double* median,
02350 double* mean, double* stdev)
02351 {
02352 cpl_vector* tab_vec = NULL;
02353 int i = 0;
02354
02355
02356 XSH_ASSURE_NOT_NULL( tab);
02357 XSH_ASSURE_NOT_ILLEGAL( size >= 0);
02358 XSH_ASSURE_NOT_NULL( median);
02359 XSH_ASSURE_NOT_NULL( mean);
02360 XSH_ASSURE_NOT_NULL( stdev);
02361
02362
02363 check (tab_vec = cpl_vector_new( size));
02364 for( i=0; i< size; i++){
02365 check( cpl_vector_set( tab_vec, i, tab[i]));
02366 }
02367
02368 check( *median = cpl_vector_get_median( tab_vec));
02369 check( *stdev = cpl_vector_get_stdev( tab_vec));
02370 check( *mean = cpl_vector_get_mean( tab_vec));
02371
02372 cleanup:
02373 xsh_free_vector( &tab_vec);
02374 return;
02375 }
02387
02388 cpl_error_code
02389 xsh_tools_sort_double( double * pix_arr, int n )
02390 {
02391 int i, ir, j, k, l;
02392 int * i_stack ;
02393 int j_stack ;
02394 double a ;
02395
02396
02397 if ( pix_arr == NULL ) {
02398 return CPL_ERROR_NULL_INPUT ;
02399 }
02400
02401 ir = n ;
02402 l = 1 ;
02403 j_stack = 0 ;
02404 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02405 for (;;) {
02406 if (ir-l < 7) {
02407 for (j=l+1 ; j<=ir ; j++) {
02408 a = pix_arr[j-1];
02409 for (i=j-1 ; i>=1 ; i--) {
02410 if (pix_arr[i-1] <= a) break;
02411 pix_arr[i] = pix_arr[i-1];
02412 }
02413 pix_arr[i] = a;
02414 }
02415 if (j_stack == 0) break;
02416 ir = i_stack[j_stack-- -1];
02417 l = i_stack[j_stack-- -1];
02418 } else {
02419 k = (l+ir) >> 1;
02420 XSH_DOUBLE_SWAP(pix_arr[k-1], pix_arr[l])
02421 if (pix_arr[l] > pix_arr[ir-1]) {
02422 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[ir-1])
02423 }
02424 if (pix_arr[l-1] > pix_arr[ir-1]) {
02425 XSH_DOUBLE_SWAP(pix_arr[l-1], pix_arr[ir-1])
02426 }
02427 if (pix_arr[l] > pix_arr[l-1]) {
02428 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[l-1])
02429 }
02430 i = l+1;
02431 j = ir;
02432 a = pix_arr[l-1];
02433 for (;;) {
02434 do i++; while (pix_arr[i-1] < a);
02435 do j--; while (pix_arr[j-1] > a);
02436 if (j < i) break;
02437 XSH_DOUBLE_SWAP(pix_arr[i-1], pix_arr[j-1]);
02438 }
02439 pix_arr[l-1] = pix_arr[j-1];
02440 pix_arr[j-1] = a;
02441 j_stack += 2;
02442 if (j_stack > XSH_PIX_STACK_SIZE) {
02443
02444 cpl_free(i_stack);
02445 return CPL_ERROR_ILLEGAL_INPUT ;
02446 }
02447 if (ir-i+1 >= j-l) {
02448 i_stack[j_stack-1] = ir;
02449 i_stack[j_stack-2] = i;
02450 ir = j-1;
02451 } else {
02452 i_stack[j_stack-1] = j-1;
02453 i_stack[j_stack-2] = l;
02454 l = i;
02455 }
02456 }
02457 }
02458 cpl_free(i_stack) ;
02459 return CPL_ERROR_NONE ;
02460 }
02461
02462
02474
02475 cpl_error_code
02476 xsh_tools_sort_float( float * pix_arr, int n )
02477 {
02478 int i, ir, j, k, l;
02479 int * i_stack ;
02480 int j_stack ;
02481 float a ;
02482
02483
02484 if ( pix_arr == NULL ) {
02485 return CPL_ERROR_NULL_INPUT ;
02486 }
02487
02488 ir = n ;
02489 l = 1 ;
02490 j_stack = 0 ;
02491 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(float)) ;
02492 for (;;) {
02493 if (ir-l < 7) {
02494 for (j=l+1 ; j<=ir ; j++) {
02495 a = pix_arr[j-1];
02496 for (i=j-1 ; i>=1 ; i--) {
02497 if (pix_arr[i-1] <= a) break;
02498 pix_arr[i] = pix_arr[i-1];
02499 }
02500 pix_arr[i] = a;
02501 }
02502 if (j_stack == 0) break;
02503 ir = i_stack[j_stack-- -1];
02504 l = i_stack[j_stack-- -1];
02505 } else {
02506 k = (l+ir) >> 1;
02507 XSH_FLOAT_SWAP(pix_arr[k-1], pix_arr[l])
02508 if (pix_arr[l] > pix_arr[ir-1]) {
02509 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[ir-1])
02510 }
02511 if (pix_arr[l-1] > pix_arr[ir-1]) {
02512 XSH_FLOAT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02513 }
02514 if (pix_arr[l] > pix_arr[l-1]) {
02515 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[l-1])
02516 }
02517 i = l+1;
02518 j = ir;
02519 a = pix_arr[l-1];
02520 for (;;) {
02521 do i++; while (pix_arr[i-1] < a);
02522 do j--; while (pix_arr[j-1] > a);
02523 if (j < i) break;
02524 XSH_FLOAT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02525 }
02526 pix_arr[l-1] = pix_arr[j-1];
02527 pix_arr[j-1] = a;
02528 j_stack += 2;
02529 if (j_stack > XSH_PIX_STACK_SIZE) {
02530
02531 cpl_free(i_stack);
02532 return CPL_ERROR_ILLEGAL_INPUT ;
02533 }
02534 if (ir-i+1 >= j-l) {
02535 i_stack[j_stack-1] = ir;
02536 i_stack[j_stack-2] = i;
02537 ir = j-1;
02538 } else {
02539 i_stack[j_stack-1] = j-1;
02540 i_stack[j_stack-2] = l;
02541 l = i;
02542 }
02543 }
02544 }
02545 cpl_free(i_stack) ;
02546 return CPL_ERROR_NONE ;
02547 }
02548
02549
02560 cpl_error_code
02561 xsh_tools_sort_int( int * pix_arr, int n)
02562 {
02563 int i, ir, j, k, l;
02564 int * i_stack ;
02565 int j_stack ;
02566 int a ;
02567
02568
02569 if ( pix_arr == NULL ) {
02570 return CPL_ERROR_NULL_INPUT ;
02571 }
02572
02573 ir = n ;
02574 l = 1 ;
02575 j_stack = 0 ;
02576 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02577 for (;;) {
02578 if (ir-l < 7) {
02579 for (j=l+1 ; j<=ir ; j++) {
02580 a = pix_arr[j-1];
02581 for (i=j-1 ; i>=1 ; i--) {
02582 if (pix_arr[i-1] <= a) break;
02583 pix_arr[i] = pix_arr[i-1];
02584 }
02585 pix_arr[i] = a;
02586 }
02587 if (j_stack == 0) break;
02588 ir = i_stack[j_stack-- -1];
02589 l = i_stack[j_stack-- -1];
02590 } else {
02591 k = (l+ir) >> 1;
02592 XSH_INT_SWAP(pix_arr[k-1], pix_arr[l])
02593 if (pix_arr[l] > pix_arr[ir-1]) {
02594 XSH_INT_SWAP(pix_arr[l], pix_arr[ir-1])
02595 }
02596 if (pix_arr[l-1] > pix_arr[ir-1]) {
02597 XSH_INT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02598 }
02599 if (pix_arr[l] > pix_arr[l-1]) {
02600 XSH_INT_SWAP(pix_arr[l], pix_arr[l-1])
02601 }
02602 i = l+1;
02603 j = ir;
02604 a = pix_arr[l-1];
02605 for (;;) {
02606 do i++; while (pix_arr[i-1] < a);
02607 do j--; while (pix_arr[j-1] > a);
02608 if (j < i) break;
02609 XSH_INT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02610 }
02611 pix_arr[l-1] = pix_arr[j-1];
02612 pix_arr[j-1] = a;
02613 j_stack += 2;
02614 if (j_stack > XSH_PIX_STACK_SIZE) {
02615
02616 cpl_free(i_stack);
02617 return CPL_ERROR_ILLEGAL_INPUT ;
02618 }
02619 if (ir-i+1 >= j-l) {
02620 i_stack[j_stack-1] = ir;
02621 i_stack[j_stack-2] = i;
02622 ir = j-1;
02623 } else {
02624 i_stack[j_stack-1] = j-1;
02625 i_stack[j_stack-2] = l;
02626 l = i;
02627 }
02628 }
02629 }
02630 cpl_free(i_stack) ;
02631 return CPL_ERROR_NONE ;
02632 }
02633
02649 double xsh_tools_get_median_double( double *array, int size )
02650 {
02651 double result = 0. ;
02652
02653
02654 xsh_tools_sort_double( array, size ) ;
02655
02656
02657 if ( (size % 2) == 1 ) result = *(array+(size/2)) ;
02658 else {
02659 double min, max ;
02660
02661 min = *(array+(size/2)-1) ;
02662 max = *(array+(size/2) ) ;
02663 result = (min+max)/2. ;
02664 }
02665
02666 return result ;
02667 }
02668
02675 int
02676 xsh_tools_running_median_1d_get_max( double * tab, int size, int wsize )
02677 {
02678 int position = 0;
02679 int i ;
02680 double * wtab = NULL ;
02681 double max = -1000000. ;
02682
02683 XSH_ASSURE_NOT_NULL( tab ) ;
02684 XSH_MALLOC( wtab, double, (wsize*2)*2 ) ;
02685
02686
02687
02688
02689
02690
02691
02692
02693 for( i = wsize ; i<(size-wsize) ; i++ ) {
02694 int j, k ;
02695 double f_max;
02696
02697
02698 for( k=0, j = i-wsize ; j<=(i+wsize) ; j++, k++ ) {
02699 wtab[k] = tab[j] ;
02700
02701 }
02702 if ( (f_max=xsh_tools_get_median_double(wtab, (wsize*2) + 1)) > max ) {
02703 max = f_max ;
02704 position = i ;
02705 }
02706 }
02707
02708
02709 cleanup:
02710 XSH_FREE( wtab ) ;
02711 return position ;
02712 }
02713
02714
02715
02724
02725
02726
02727 void xsh_tools_min_max(int size, double *tab, double *min, double *max)
02728 {
02729
02730 int i;
02731
02732 XSH_ASSURE_NOT_NULL(tab);
02733 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02734 XSH_ASSURE_NOT_NULL(min);
02735 XSH_ASSURE_NOT_NULL(max);
02736
02737 *min = tab[0];
02738 *max = tab[0];
02739
02740 for(i=1; i < size; i++) {
02741 if (tab[i] < *min){
02742 *min = tab[i];
02743 }
02744 else if ( tab[i] > *max) {
02745 *max = tab[i];
02746 }
02747 }
02748
02749 cleanup:
02750 return;
02751 }
02752
02764 cpl_vector* xsh_tools_tchebitchev_poly_eval( int n, double X)
02765 {
02766 cpl_vector *result = NULL;
02767
02768 XSH_ASSURE_NOT_ILLEGAL( n >=0);
02769 check( result = cpl_vector_new( n+1));
02770 check( cpl_vector_set(result, 0, 1.0));
02771
02772 if (n > 0){
02773 int indice = 2;
02774 check( cpl_vector_set(result, 1, X));
02775 while( indice <= n){
02776 double T_indice = 0.0;
02777 double T_indice_1 = 0.0;
02778 double T_indice_2 = 0.0;
02779
02780 check( T_indice_1 = cpl_vector_get( result, indice-1));
02781 check( T_indice_2 = cpl_vector_get( result, indice-2));
02782 T_indice = 2*X*T_indice_1-T_indice_2;
02783 check( cpl_vector_set( result, indice, T_indice));
02784 indice++;
02785 }
02786 }
02787 cleanup:
02788 if ( cpl_error_get_code() != CPL_ERROR_NONE){
02789 xsh_free_vector( &result);
02790 }
02791 return result;
02792 }
02793
02794
02795
02805
02806
02807
02808 void
02809 xsh_tools_tchebitchev_transform_tab(int size, double* pos, double min,
02810 double max, double* tcheb_pos)
02811 {
02812 int i;
02813 double a,b;
02814
02815 XSH_ASSURE_NOT_NULL(pos);
02816 XSH_ASSURE_NOT_NULL(tcheb_pos);
02817 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02818 XSH_ASSURE_NOT_ILLEGAL(min < max);
02819
02820 a = 2/ (max-min);
02821 b = 1-2*max/(max-min);
02822
02823 for(i=0; i < size; i++) {
02824 tcheb_pos[i] = pos[i]*a+b;
02825 if ( tcheb_pos[i] < -1. ) tcheb_pos[i] = -1. ;
02826 if ( tcheb_pos[i] > 1. ) tcheb_pos[i] = 1. ;
02827 }
02828
02829 cleanup:
02830 return;
02831 }
02832
02833
02834
02842
02843
02844 double
02845 xsh_tools_tchebitchev_transform(double pos, double min, double max)
02846 {
02847 double a,b;
02848 double res = 0.0;
02849
02850 XSH_ASSURE_NOT_ILLEGAL(min < max);
02851
02852 a = 2/ (max-min);
02853 b = 1-2*max/(max-min);
02854
02855 res = pos*a+b;
02856 if(res <= -1.000001) {
02857 xsh_msg_dbg_medium("OUT_OF_RANGE res <= -1.000001 for %f [%f,%f]",
02858 pos, min , max);
02859 }
02860 if(res >= +1.000001) {
02861 xsh_msg_dbg_medium("OUT_OF_RANGE res >= +1.000001 for %f [%f,%f]",
02862 pos, min , max);
02863 }
02864
02865
02866
02867
02868 cleanup:
02869 return res;
02870 }
02871
02872
02880
02881 double
02882 xsh_tools_tchebitchev_reverse_transform(double pos, double min, double max)
02883 {
02884 double a,b;
02885 double res = 0.0;
02886
02887 XSH_ASSURE_NOT_ILLEGAL(min < max);
02888
02889 a = 2/ (max-min);
02890 b = 1-2*max/(max-min);
02891
02892 res = (pos-b)/a;
02893
02894 cleanup:
02895 return res;
02896 }
02897
02898
02899
02906
02907 void
02908 xsh_image_fit_spline(cpl_image* img, xsh_grid* grid)
02909 {
02910 int nx, ny;
02911 int i = 0, ja, jb, idx = 0, vxsize, size;
02912 double *data = NULL;
02913 int *ylines = NULL;
02914 int *xline = NULL;
02915 double *vline = NULL;
02916 int nbylines;
02917 xsh_grid_point *pointA = NULL;
02918 xsh_grid_point *pointB = NULL;
02919
02920
02921 XSH_ASSURE_NOT_NULL( img);
02922 XSH_ASSURE_NOT_NULL( grid);
02923 XSH_ASSURE_NOT_ILLEGAL( cpl_image_get_type(img) == CPL_TYPE_DOUBLE);
02924
02925 check( data = cpl_image_get_data_double(img));
02926 check( nx = cpl_image_get_size_x(img));
02927 check( ny = cpl_image_get_size_y(img));
02928 check( size = xsh_grid_get_index(grid));
02929
02930 ja = 0;
02931 jb = ja+1;
02932 nbylines = 0;
02933 vxsize = 0;
02934
02935 XSH_MALLOC( ylines, int, ny);
02936 XSH_MALLOC( xline, int, nx);
02937 XSH_MALLOC( vline, double, nx);
02938
02939
02940 while( jb < size) {
02941 double a = 0.0, b = 0.0;
02942 int cur_y;
02943
02944 nbylines++;
02945 vxsize = 1;
02946
02947 check( pointA = xsh_grid_point_get( grid, ja));
02948 check( pointB = xsh_grid_point_get( grid, jb));
02949
02950 cur_y = pointA->y-1;
02951 ylines[nbylines-1]= cur_y;
02952 xline[vxsize-1] = pointA->x-1;
02953 vline[vxsize-1] = pointA->v;
02954
02955 while( ( jb < size) && ( pointA->y == pointB->y) ){
02956 check( pointB = xsh_grid_point_get( grid, jb));
02957
02958 if ( (pointB->x-1) != xline[vxsize-1]){
02959 xline[vxsize] = pointB->x-1;
02960 vline[vxsize] = pointB->v;
02961 vxsize++;
02962 }
02963 jb++;
02964 }
02965 XSH_ASSURE_NOT_ILLEGAL( vxsize >=2);
02966
02967 for(idx=0; idx<vxsize-1; idx++){
02968 int nbpix = 0;
02969 int xa, xb;
02970 double va, vb;
02971
02972 xa = xline[idx];
02973 xb = xline[idx+1];
02974
02975 va = vline[idx];
02976 vb = vline[idx+1];
02977
02978 a = ( vb - va) / ( xb - xa);
02979 b = va-a*xa;
02980
02981 nbpix = xb-xa;
02982
02983 for(i=0; i<= nbpix; i++){
02984 data[xa+i+cur_y*nx] = a*(xa+i)+b;
02985 }
02986 }
02987 ja=jb;
02988 jb=ja+1;
02989 }
02990
02991
02992 xsh_msg("interpolate in Y ");
02993
02994 for( ja=0; ja< nbylines-1; ja++) {
02995 int line1 = ylines[ja];
02996 int line2 = ylines[ja+1];
02997
02998 for(i=0; i< nx; i++){
02999 double val1 = data[i+line1*nx];
03000 double val2 = data[i+line2*nx];
03001 double a = (val2-val1)/(line2-line1);
03002 double b = val1;
03003 int k;
03004
03005 for(k=line1+1; k < line2; k++){
03006 data[i+k*nx] = a*(k-line1)+b;
03007 }
03008 }
03009 }
03010
03011 cleanup:
03012 XSH_FREE( ylines);
03013 XSH_FREE( xline);
03014 XSH_FREE( vline);
03015 return;
03016 }
03017
03018
03027
03028 void
03029 xsh_vector_fit_gaussian( cpl_vector * x,
03030 cpl_vector * y,
03031 XSH_GAUSSIAN_FIT * result )
03032 {
03033 XSH_ASSURE_NOT_NULL( x ) ;
03034 XSH_ASSURE_NOT_NULL( y ) ;
03035 XSH_ASSURE_NOT_NULL( result ) ;
03036
03037 cpl_vector_fit_gaussian( x, NULL, y, NULL, CPL_FIT_ALL, &result->peakpos,
03038 &result->sigma,
03039 &result->area, &result->offset, &result->mse,
03040 NULL, NULL ) ;
03041 cleanup:
03042 return ;
03043 }
03044
03045
03052
03053 int xsh_debug_level_set( int level )
03054 {
03055 int prev = XshDebugLevel ;
03056
03057 XshDebugLevel = level ;
03058
03059 return prev ;
03060 }
03061
03062
03068
03069 int
03070 xsh_debug_level_get( void )
03071 {
03072 return XshDebugLevel ;
03073 }
03074
03075
03081
03082 const char *
03083 xsh_debug_level_tostring( void )
03084 {
03085 switch ( XshDebugLevel ) {
03086 case XSH_DEBUG_LEVEL_NONE:
03087 return "none" ;
03088 case XSH_DEBUG_LEVEL_LOW:
03089 return "low" ;
03090 case XSH_DEBUG_LEVEL_MEDIUM:
03091 return "medium" ;
03092 case XSH_DEBUG_LEVEL_HIGH:
03093 return "high" ;
03094 default:
03095 return "unknown" ;
03096 }
03097 }
03098
03105
03106 int
03107 xsh_time_stamp_set( int ts )
03108 {
03109 int prev = XshTimeStamp ;
03110
03111 XshTimeStamp = ts ;
03112
03113 return prev ;
03114 }
03115
03116
03122
03123 int
03124 xsh_time_stamp_get( void )
03125 {
03126 return XshTimeStamp ;
03127 }
03128
03135 void
03136 xsh_mem_dump( const char * prompt)
03137 {
03138 fprintf( stderr, "\n******** %s *******\n", prompt ) ;
03139 cpl_memory_dump() ;
03140 }
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155 double
03156 convert_bin_to_data( double bin_data, int binning)
03157 {
03158 return (bin_data*binning-0.5*(binning-1));
03159 }
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173 double
03174 convert_data_to_bin( double data, int binning)
03175 {
03176 return (data+0.5*(binning-1))/binning;
03177 }
03178
03179
03180
03181
03182 static double
03183 date_to_double( const char * the_date )
03184 {
03185 int yy, mm, dd, hh, min, sec, millis ;
03186 int date, temps ;
03187 double fdate = 0 ;
03188
03189
03190 XSH_ASSURE_NOT_NULL( the_date ) ;
03191
03192 sscanf( the_date, "%d%*c%d%*c%d%*c%d%*c%d%*c%d%*c%d",
03193 &yy, &mm, &dd, &hh, &min, &sec, &millis ) ;
03194
03195 date = yy*10000 + mm*100 + dd ;
03196 temps = hh*10000000 + min*100000 + sec*1000 + millis ;
03197 fdate = (double)date + (double)temps/1000000000. ;
03198
03199 cleanup:
03200 return fdate ;
03201
03202 }
03203
03204 typedef struct {
03205 double frame_date ;
03206 int frame_idx ;
03207 cpl_frame * frame ;
03208 const char * frame_name ;
03209 } FRAME_DATE_IDX ;
03210
03211 static int
03212 compare_frame_date( const void * one, const void * two )
03213 {
03214 FRAME_DATE_IDX * first = (FRAME_DATE_IDX *)one,
03215 * scnd = (FRAME_DATE_IDX *)two ;
03216
03217 if ( first->frame_date > scnd->frame_date ) return 1 ;
03218 else if ( first->frame_date == scnd->frame_date ) return 0 ;
03219 else return -1 ;
03220 }
03221
03222
03223
03224
03225
03232
03233 cpl_frameset*
03234 xsh_order_frameset_by_date( cpl_frameset *frameset)
03235 {
03236 int nb, i ;
03237 FRAME_DATE_IDX *frame_date = NULL;
03238 cpl_frameset *result = NULL ;
03239 cpl_propertylist *header = NULL;
03240
03241 XSH_ASSURE_NOT_NULL( frameset);
03242
03243 check( nb = cpl_frameset_get_size( frameset));
03244 if ( nb <= 1 ) {
03245 check( result = cpl_frameset_duplicate( frameset));
03246 }
03247 else{
03248 XSH_CALLOC( frame_date, FRAME_DATE_IDX, nb);
03249
03250
03251 for( i = 0 ; i < nb ; i++){
03252 const char *fname = NULL ;
03253 cpl_frame *frame = NULL ;
03254 const char *the_date = NULL;
03255
03256
03257 check( frame = cpl_frameset_get_frame( frameset, i));
03258 check( fname = cpl_frame_get_filename( frame));
03259
03260
03261 check( header = cpl_propertylist_load( fname, 0));
03262
03263 check( the_date = xsh_pfits_get_date_obs( header));
03264
03265 frame_date[i].frame_date = date_to_double( the_date);
03266 frame_date[i].frame_idx = i;
03267 frame_date[i].frame = frame;
03268 frame_date[i].frame_name = fname;
03269
03270 xsh_free_propertylist( &header);
03271 }
03272
03273 qsort( frame_date, nb, sizeof( FRAME_DATE_IDX ), compare_frame_date ) ;
03274
03275 if ( xsh_debug_level_get() > XSH_DEBUG_LEVEL_NONE ) {
03276 for( i = 0 ; i<nb ; i++ ) {
03277 xsh_msg( "%d: %.9lf '%s'", frame_date[i].frame_idx,
03278 frame_date[i].frame_date, frame_date[i].frame_name);
03279 }
03280 }
03281
03282 check( result = cpl_frameset_new() ) ;
03283
03284
03285 for( i = 0 ; i <nb ; i++ ){
03286 check( cpl_frameset_insert( result,
03287 cpl_frame_duplicate(frame_date[i].frame)));
03288 }
03289 }
03290 cleanup:
03291 if ( cpl_error_get_code() != CPL_ERROR_NONE){
03292 xsh_free_frameset( &result);
03293 }
03294 xsh_free_propertylist( &header);
03295 XSH_FREE( frame_date);
03296 return result;
03297 }
03298
03299
03300
03348
03349
03350 polynomial *
03351 xsh_polynomial_regression_2d(cpl_table *t,
03352 const char *X1,
03353 const char *X2,
03354 const char *Y,
03355 const char *sigmaY,
03356 int degree1,
03357 int degree2,
03358 const char *polynomial_fit,
03359 const char *residual_square,
03360 const char *variance_fit,
03361 double *mse,
03362 double *red_chisq,
03363 polynomial **variance,
03364 double kappa,
03365 double min_reject)
03366 {
03367 int N;
03368 int rejected;
03369 int total_rejected;
03370 double *x1=NULL;
03371 double *x2=NULL;
03372 double *y=NULL;
03373 double *res=NULL;
03374 double *sy=NULL;
03375 polynomial *p = NULL;
03376 polynomial *variance_local = NULL;
03377 cpl_vector *vx1 = NULL;
03378 cpl_vector *vx2 = NULL;
03379 cpl_bivector *vx = NULL;
03380 cpl_vector *vy = NULL;
03381 cpl_vector *vsy= NULL;
03382 cpl_type type;
03383
03384
03385 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03386 assure( cpl_table_has_column(t, X1), CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", X1);
03387 assure( cpl_table_has_column(t, X2), CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", X2);
03388 assure( cpl_table_has_column(t, Y) , CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", Y);
03389 assure( (variance == NULL && variance_fit == NULL) || sigmaY != NULL,
03390 CPL_ERROR_INCOMPATIBLE_INPUT, "Cannot calculate variances without sigmaY");
03391 if (sigmaY != NULL)
03392 {
03393 assure( cpl_table_has_column(t, sigmaY) , CPL_ERROR_ILLEGAL_INPUT,
03394 "No such column: %s", sigmaY);
03395 }
03396 if (polynomial_fit != NULL)
03397 {
03398 assure( !cpl_table_has_column(t, polynomial_fit) , CPL_ERROR_ILLEGAL_INPUT,
03399 "Table already has '%s' column", polynomial_fit);
03400 }
03401 if (residual_square != NULL)
03402 {
03403 assure( !cpl_table_has_column(t, residual_square), CPL_ERROR_ILLEGAL_INPUT,
03404 "Table already has '%s' column", residual_square);
03405 }
03406 if (variance_fit != NULL)
03407 {
03408 assure( !cpl_table_has_column(t, variance_fit) , CPL_ERROR_ILLEGAL_INPUT,
03409 "Table already has '%s' column", variance_fit);
03410 }
03411
03412
03413 type = cpl_table_get_column_type(t, X1);
03414 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03415 "Input column '%s' has wrong type (%s)", X1, xsh_tostring_cpl_type(type));
03416 type = cpl_table_get_column_type(t, X2);
03417 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03418 "Input column '%s' has wrong type (%s)", X2, xsh_tostring_cpl_type(type));
03419 type = cpl_table_get_column_type(t, Y);
03420 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03421 "Input column '%s' has wrong type (%s)", Y, xsh_tostring_cpl_type(type));
03422 if (sigmaY != NULL)
03423 {
03424 type = cpl_table_get_column_type(t, sigmaY);
03425 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03426 "Input column '%s' has wrong type (%s)",
03427 sigmaY, xsh_tostring_cpl_type(type));
03428 }
03429
03430
03431 check_msg( cpl_table_cast_column(t, X1 , "_X1_double", CPL_TYPE_DOUBLE),
03432 "Could not cast table column to double");
03433 check_msg( cpl_table_cast_column(t, X2 , "_X2_double", CPL_TYPE_DOUBLE),
03434 "Could not cast table column to double");
03435 check_msg( cpl_table_cast_column(t, Y , "_Y_double", CPL_TYPE_DOUBLE),
03436 "Could not cast table column to double");
03437 if (sigmaY != NULL)
03438 {
03439 check_msg( cpl_table_cast_column(t, sigmaY, "_sY_double", CPL_TYPE_DOUBLE),
03440 "Could not cast table column to double");
03441 }
03442
03443 total_rejected = 0;
03444 rejected = 0;
03445 check_msg( cpl_table_new_column(t, "_residual_square", CPL_TYPE_DOUBLE),
03446 "Could not create column");
03447
03448 do {
03449
03450
03451 check_msg(( N = cpl_table_get_nrow(t),
03452 x1 = cpl_table_get_data_double(t, "_X1_double"),
03453 x2 = cpl_table_get_data_double(t, "_X2_double"),
03454 y = cpl_table_get_data_double(t, "_Y_double"),
03455 res= cpl_table_get_data_double(t, "_residual_square")),
03456 "Could not read table data");
03457
03458 if (sigmaY != NULL)
03459 {
03460 check_msg (sy = cpl_table_get_data_double(t, "_sY_double"),
03461 "Could not read table data");
03462 }
03463 else
03464 {
03465 sy = NULL;
03466 }
03467
03468 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03469
03470
03471 xsh_unwrap_vector(&vx1);
03472 xsh_unwrap_vector(&vx2);
03473 xsh_unwrap_vector(&vy);
03474
03475 vx1 = cpl_vector_wrap(N, x1);
03476 vx2 = cpl_vector_wrap(N, x2);
03477 vy = cpl_vector_wrap(N, y);
03478 if (sy != NULL)
03479 {
03480 xsh_unwrap_vector(&vsy);
03481 vsy = cpl_vector_wrap(N, sy);
03482 }
03483 else
03484 {
03485 vsy = NULL;
03486 }
03487
03488
03489 xsh_unwrap_bivector_vectors(&vx);
03490 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03491
03492
03493 xsh_polynomial_delete(&p);
03494 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03495 NULL, NULL, NULL),
03496 "Could not fit polynomial");
03497
03498
03499 if (kappa > 0)
03500 {
03501 double sigma2;
03502 int i;
03503
03504 cpl_table_fill_column_window_double(t, "_residual_square", 0,
03505 cpl_table_get_nrow(t), 0.0);
03506
03507 for (i = 0; i < N; i++)
03508 {
03509 double yval, yfit;
03510
03511 yval = y[i];
03512 yfit = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03513 res[i] = (yfit-y[i])*(yfit-y[i]);
03514 }
03515
03516
03517
03518
03519
03520
03521
03522 sigma2 = cpl_table_get_column_median(t, "_residual_square") / (0.6744 * 0.6744);
03523
03524
03525
03526 check_msg( rejected = xsh_erase_table_rows(t, "_residual_square",
03527 CPL_GREATER_THAN, kappa*kappa*sigma2),
03528 "Could not remove outlier points");
03529
03530
03531
03532 xsh_msg_debug("%d of %d points rejected in kappa-sigma clipping. rms=%f",
03533 rejected, N, sqrt(sigma2));
03534
03535
03536 total_rejected += rejected;
03537 N = cpl_table_get_nrow(t);
03538 }
03539
03540
03541
03542
03543 } while (rejected > 0 && rejected > min_reject*(N+rejected) &&
03544 N >= (degree1 + 1)*(degree2 + 1) + 1);
03545
03546 if (kappa > 0)
03547 {
03548 xsh_msg_debug("%d of %d points (%f %%) rejected in kappa-sigma clipping",
03549 total_rejected,
03550 N + total_rejected,
03551 (100.0*total_rejected)/(N + total_rejected)
03552 );
03553 }
03554
03555
03556 {
03557
03558
03559
03560
03561 check_msg(( N = cpl_table_get_nrow(t),
03562 x1 = cpl_table_get_data_double(t, "_X1_double"),
03563 x2 = cpl_table_get_data_double(t, "_X2_double"),
03564 y = cpl_table_get_data_double(t, "_Y_double"),
03565 res= cpl_table_get_data_double(t, "_residual_square")),
03566 "Could not read table data");
03567
03568 if (sigmaY != NULL)
03569 {
03570 check_msg (sy = cpl_table_get_data_double(t, "_sY_double"),
03571 "Could not read table data");
03572 }
03573 else
03574 {
03575 sy = NULL;
03576 }
03577
03578 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03579
03580
03581 xsh_unwrap_vector(&vx1);
03582 xsh_unwrap_vector(&vx2);
03583 xsh_unwrap_vector(&vy);
03584
03585 vx1 = cpl_vector_wrap(N, x1);
03586 vx2 = cpl_vector_wrap(N, x2);
03587 vy = cpl_vector_wrap(N, y);
03588 if (sy != NULL)
03589 {
03590 xsh_unwrap_vector(&vsy);
03591 vsy = cpl_vector_wrap(N, sy);
03592 }
03593 else
03594 {
03595 vsy = NULL;
03596 }
03597
03598
03599 xsh_unwrap_bivector_vectors(&vx);
03600 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03601 }
03602
03603 xsh_polynomial_delete(&p);
03604 if (variance_fit != NULL || variance != NULL)
03605 {
03606
03607 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03608 mse, red_chisq, &variance_local),
03609 "Could not fit polynomial");
03610 }
03611 else
03612 {
03613 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03614 mse, red_chisq, NULL),
03615 "Could not fit polynomial");
03616 }
03617
03618 cpl_table_erase_column(t, "_residual_square");
03619
03620
03621 if (polynomial_fit != NULL || residual_square != NULL)
03622 {
03623 int i;
03624 double *pf;
03625
03626 check_msg( cpl_table_new_column(t, "_polynomial_fit", CPL_TYPE_DOUBLE),
03627 "Could not create column");
03628
03629 cpl_table_fill_column_window_double(t, "_polynomial_fit", 0,
03630 cpl_table_get_nrow(t), 0.0);
03631
03632 x1 = cpl_table_get_data_double(t, "_X1_double");
03633 x2 = cpl_table_get_data_double(t, "_X2_double");
03634 pf = cpl_table_get_data_double(t, "_polynomial_fit");
03635
03636 for (i = 0; i < N; i++){
03637 #if 0
03638 double x1val, x2val, yfit;
03639
03640 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03641 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03642 yfit = xsh_polynomial_evaluate_2d(p, x1val, x2val),
03643
03644 cpl_table_set_double(t, "_polynomial_fit", i, yfit)),
03645 "Could not evaluate polynomial");
03646
03647 #else
03648 pf[i] = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03649 #endif
03650 }
03651
03652
03653 if (residual_square != NULL)
03654 {
03655 check_msg(( cpl_table_duplicate_column(t, residual_square,
03656 t, "_polynomial_fit"),
03657 cpl_table_subtract_columns(t, residual_square, Y),
03658 cpl_table_multiply_columns(t, residual_square, residual_square)),
03659
03660 "Could not calculate Residual of fit");
03661 }
03662
03663
03664 if (polynomial_fit != NULL)
03665 {
03666 cpl_table_name_column(t, "_polynomial_fit", polynomial_fit);
03667 }
03668 else
03669 {
03670 cpl_table_erase_column(t, "_polynomial_fit");
03671 }
03672 }
03673
03674
03675 if (variance_fit != NULL)
03676 {
03677 int i;
03678 double *vf;
03679
03680 check_msg( cpl_table_new_column(t, variance_fit, CPL_TYPE_DOUBLE),
03681 "Could not create column");
03682
03683 cpl_table_fill_column_window_double(t, variance_fit, 0,
03684 cpl_table_get_nrow(t), 0.0);
03685
03686 x1 = cpl_table_get_data_double(t, "_X1_double");
03687 x2 = cpl_table_get_data_double(t, "_X2_double");
03688 vf = cpl_table_get_data_double(t, variance_fit);
03689
03690 for (i = 0; i < N; i++)
03691 {
03692 #if 0
03693 double x1val, x2val, yfit_variance;
03694 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03695 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03696 yfit_variance = xsh_polynomial_evaluate_2d(variance_local,
03697 x1val, x2val),
03698
03699 cpl_table_set_double(t, variance_fit, i, yfit_variance)),
03700 "Could not evaluate polynomial");
03701 #else
03702 vf[i] = xsh_polynomial_evaluate_2d(variance_local, x1[i], x2[i]);
03703 #endif
03704
03705 }
03706 }
03707
03708
03709 check_msg(( cpl_table_erase_column(t, "_X1_double"),
03710 cpl_table_erase_column(t, "_X2_double"),
03711 cpl_table_erase_column(t, "_Y_double")),
03712 "Could not delete temporary columns");
03713
03714 if (sigmaY != NULL)
03715 {
03716 check_msg( cpl_table_erase_column(t, "_sY_double"),
03717 "Could not delete temporary column");
03718 }
03719
03720 cleanup:
03721 xsh_unwrap_bivector_vectors(&vx);
03722 xsh_unwrap_vector(&vx1);
03723 xsh_unwrap_vector(&vx2);
03724 xsh_unwrap_vector(&vy);
03725 xsh_unwrap_vector(&vsy);
03726
03727 if (variance != NULL)
03728 {
03729 *variance = variance_local;
03730 }
03731 else
03732 {
03733 xsh_polynomial_delete(&variance_local);
03734 }
03735 if (cpl_error_get_code() != CPL_ERROR_NONE)
03736 {
03737 xsh_polynomial_delete(&p);
03738 }
03739
03740 return p;
03741 }
03742
03743
03744
03745
03762
03763
03764 int
03765 xsh_select_table_rows(cpl_table *t,
03766 const char *column,
03767 cpl_table_select_operator operator,
03768 double value)
03769 {
03770 int result = 0;
03771 cpl_type type;
03772
03773 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03774 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03775 "No such column: %s", column);
03776
03777 type = cpl_table_get_column_type(t, column);
03778
03779 assure( type == CPL_TYPE_DOUBLE || type == CPL_TYPE_FLOAT ||
03780 type == CPL_TYPE_INT, CPL_ERROR_INVALID_TYPE,
03781 "Column '%s' must be double or int. %s found", column,
03782 xsh_tostring_cpl_type(type));
03783
03784 check_msg( cpl_table_select_all(t), "Error selecting rows");
03785
03786 if (type == CPL_TYPE_DOUBLE)
03787 {
03788 result = cpl_table_and_selected_double(t, column, operator, value);
03789 }
03790 else if (type == CPL_TYPE_FLOAT)
03791 {
03792 result = cpl_table_and_selected_float(t, column, operator, value);
03793 }
03794 else if (type == CPL_TYPE_INT)
03795 {
03796 result = cpl_table_and_selected_int(t, column, operator,
03797 xsh_round_double(value));
03798 }
03799 else { passure(false, ""); }
03800
03801 cleanup:
03802 return result;
03803
03804 }
03805
03806
03807
03808
03809
03828
03829 int
03830 xsh_erase_table_rows(cpl_table *t,
03831 const char *column,
03832 cpl_table_select_operator operator,
03833 double value)
03834 {
03835 int result = 0;
03836
03837 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03838 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03839 "No such column: %s", column);
03840
03841 check_msg( result = xsh_select_table_rows(t, column, operator, value),
03842 "Error selecting rows");
03843
03844 check_msg( cpl_table_erase_selected(t), "Error deleting rows");
03845
03846 cleanup:
03847 return result;
03848 }
03849
03858
03859 cpl_frame* xsh_frame_inv( cpl_frame* in, const char *filename,
03860 xsh_instrument* instr)
03861 {
03862 xsh_pre *pre = NULL;
03863 cpl_frame *result = NULL;
03864 const char* tag = "INV_PRE";
03865
03866 XSH_ASSURE_NOT_NULL( in);
03867 XSH_ASSURE_NOT_NULL( instr);
03868
03869 check( pre = xsh_pre_load( in, instr));
03870 check( xsh_pre_multiply_scalar( pre, -1.0));
03871 check( result = xsh_pre_save( pre, filename, tag, 1));
03872 check( cpl_frame_set_tag( result, tag));
03873
03874 cleanup:
03875 if (cpl_error_get_code() != CPL_ERROR_NONE){
03876 xsh_free_frame( &result);
03877 }
03878 xsh_pre_free( &pre);
03879 return result;
03880 }
03881
03882
03883
03891
03892 cpl_frame* xsh_frame_abs( cpl_frame* in, xsh_instrument* instr,
03893 cpl_frame** sign)
03894 {
03895 xsh_pre *pre = NULL;
03896 cpl_frame *result = NULL;
03897 cpl_frame *sign_frame = NULL;
03898 char name[256];
03899 const char* tag = "ABS_PRE";
03900 const char* sign_tag = "SIGN_PRE";
03901 const char *filename = NULL;
03902 cpl_image *sign_img = NULL;
03903
03904 XSH_ASSURE_NOT_NULL( in);
03905 XSH_ASSURE_NOT_NULL( sign);
03906
03907 check( filename = cpl_frame_get_filename( in));
03908 check( pre = xsh_pre_load( in, instr));
03909 check( sign_img = xsh_pre_abs( pre));
03910 sprintf( name ,"ABS_%s", filename);
03911 check( result = xsh_pre_save( pre, name, tag, 1));
03912 check( cpl_frame_set_tag( result, tag));
03913 sprintf( name ,"SIGN_%s", filename);
03914 check( cpl_image_save( sign_img, name, CPL_BPP_32_SIGNED,
03915 NULL,CPL_IO_DEFAULT));
03916 xsh_add_temporary_file(name);
03917 check( sign_frame = cpl_frame_new());
03918 check( cpl_frame_set_filename( sign_frame, name));
03919 check( cpl_frame_set_tag( sign_frame, sign_tag));
03920 *sign = sign_frame;
03921
03922 cleanup:
03923 if (cpl_error_get_code() != CPL_ERROR_NONE){
03924 xsh_free_frame( &result);
03925 }
03926 xsh_free_image( &sign_img);
03927 xsh_pre_free( &pre);
03928 return result;
03929 }
03930
03937 void
03938 xsh_frame_image_save(cpl_frame* frm,const char* name_o)
03939 {
03940 cpl_image* ima=NULL;
03941 const char* name=NULL;
03942 name=cpl_frame_get_filename(frm);
03943 ima=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
03944
03945 cpl_image_save(ima,name_o,CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
03946 xsh_free_image(&ima);
03947
03948
03949 return;
03950 }
03951
03952
03959 void
03960 xsh_frame_table_save(cpl_frame* frame,const char* name_o)
03961 {
03962 const char* fname=NULL;
03963
03964 int nbext=0;
03965 int extension ;
03966 cpl_table *tbl_ext = NULL;
03967 cpl_propertylist *tbl_ext_header = NULL;
03968 cpl_propertylist *primary_header = NULL;
03969 int i=0;
03970
03971 fname=cpl_frame_get_filename(frame);
03972 nbext = cpl_frame_get_nextensions( frame);
03973
03974 for( i = 0 ; i<nbext ; i++ ) {
03975
03976 check( tbl_ext = cpl_table_load( fname, i+1, 0));
03977 check( tbl_ext_header = cpl_propertylist_load( fname, i+1));
03978
03979 if ( i == 0 ) extension = CPL_IO_DEFAULT ;
03980 else extension = CPL_IO_EXTEND ;
03981 check(cpl_table_save( tbl_ext, primary_header, tbl_ext_header,
03982 name_o, extension));
03983 xsh_free_table( &tbl_ext);
03984 xsh_free_propertylist( &tbl_ext_header);
03985
03986 }
03987
03988 cleanup:
03989 xsh_free_table( &tbl_ext);
03990 xsh_free_propertylist( &tbl_ext_header);
03991
03992 return;
03993 }
03994
04003
04004 cpl_frame* xsh_frame_mult( cpl_frame* in, xsh_instrument* instr,
04005 cpl_frame* sign)
04006 {
04007 xsh_pre *pre = NULL;
04008 cpl_frame *result = NULL;
04009 cpl_image *sign_img = NULL;
04010 const char* name = NULL;
04011 const char* tag = "MULT_IMG_PRE";
04012
04013 XSH_ASSURE_NOT_NULL( in);
04014 XSH_ASSURE_NOT_NULL( sign);
04015
04016 check( name = cpl_frame_get_filename( sign));
04017 check( pre = xsh_pre_load( in, instr));
04018 check( sign_img = cpl_image_load( name, CPL_TYPE_INT, 0, 0));
04019 check( xsh_pre_multiply_image( pre, sign_img));
04020 check( result = xsh_pre_save( pre, "RESTORE_PRE.fits", tag, 1));
04021 check( cpl_frame_set_tag( result, tag));
04022
04023 cleanup:
04024 if (cpl_error_get_code() != CPL_ERROR_NONE){
04025 xsh_free_frame( &result);
04026 }
04027 xsh_free_image( &sign_img);
04028 xsh_pre_free( &pre);
04029 return result;
04030 }
04031
04032
04046
04047
04048
04049 cpl_error_code
04050 xsh_monitor_flux(cpl_frame* frm_ima,const cpl_frame* frm_tab,
04051 xsh_instrument *instrument)
04052 {
04053
04054 int ord_min=0;
04055 int ord_max=0;
04056 int i=0;
04057 const char* name_ima=NULL;
04058 const char* name_tab=NULL;
04059 cpl_table* tab=NULL;
04060 cpl_image* ima=NULL;
04061 cpl_table* ext=NULL;
04062 int next=0;
04063 double* cx=NULL;
04064 double* cy=NULL;
04065 int ix=0;
04066 int iy=0;
04067 double flux_min_init=FLT_MAX;
04068 double flux_max_init=-FLT_MAX;
04069
04070 double flux_min_ord=flux_min_init;
04071 double flux_max_ord=flux_max_init;
04072
04073 double flux_min=flux_min_init;
04074 double flux_max=flux_max_init;
04075 double* pima=NULL;
04076 double flux=0;
04077 cpl_propertylist* plist=NULL;
04078 char qc_flux_min[20];
04079 char qc_flux_max[20];
04080 int sx=0;
04081 int sy=0;
04082 int j=0;
04083 int binx=1;
04084 int biny=1;
04085
04086 cpl_ensure_code(frm_ima != NULL, CPL_ERROR_NULL_INPUT);
04087 cpl_ensure_code(frm_tab != NULL, CPL_ERROR_NULL_INPUT);
04088
04089 check(name_ima=cpl_frame_get_filename(frm_ima));
04090 check(name_tab=cpl_frame_get_filename(frm_tab));
04091
04092 check(plist=cpl_propertylist_load(name_ima,0));
04093
04094 if( xsh_instrument_get_arm( instrument) != XSH_ARM_NIR){
04095 binx=xsh_pfits_get_binx(plist);
04096 biny=xsh_pfits_get_biny(plist);
04097 }
04098 check(tab=cpl_table_load(name_tab,2,0));
04099 check(ima=cpl_image_load(name_ima,CPL_TYPE_DOUBLE,0,0));
04100 check(sx=cpl_image_get_size_x(ima));
04101 check(sy=cpl_image_get_size_y(ima));
04102
04103
04104
04105
04106 check(pima=cpl_image_get_data_double(ima));
04107 check(ord_min=cpl_table_get_column_min(tab,"ABSORDER"));
04108 check(ord_max=cpl_table_get_column_max(tab,"ABSORDER"));
04109
04110
04111 for(i=ord_min;i<=ord_max;i++) {
04112 flux_min_ord=flux_min_init;
04113 flux_max_ord=flux_max_init;
04114
04115 check(next=cpl_table_and_selected_int(tab,"ABSORDER",CPL_EQUAL_TO,i));
04116 ext=cpl_table_extract_selected(tab);
04117 cx=cpl_table_get_data_double(ext,"CENTER_X");
04118 cy=cpl_table_get_data_double(ext,"CENTER_Y");
04119 for(j=0;j<next;j++) {
04120
04121 ix=(int)(cx[j]/binx+0.5);
04122 iy=(int)(cy[j]/biny+0.5);
04123
04124 if( (next >= 1) && ((ix>=0) && (ix<sx)) && ((iy>=0) && (iy<sy)) ) {
04125 check(flux=pima[ix+sx*iy]);
04126 if(!isnan(flux)) {
04127 if(flux<flux_min_ord) flux_min_ord=flux;
04128 if(flux>flux_max_ord) flux_max_ord=flux;
04129
04130
04131
04132 }
04133 }
04134
04135
04136 }
04137 xsh_free_table(&ext);
04138 cpl_table_select_all(tab);
04139 if(next>1) {
04140 flux_min=(flux_min_ord<flux_min)? flux_min_ord:flux_min;
04141 flux_max=(flux_max_ord>flux_max)? flux_max_ord:flux_max;
04142 }
04143 sprintf(qc_flux_min,"%s%d%s",XSH_QC_FLUX,i," MIN");
04144 sprintf(qc_flux_max,"%s%d%s",XSH_QC_FLUX,i," MAX");
04145
04146
04147 cpl_propertylist_append_double(plist,qc_flux_min,flux_min_ord);
04148 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04149 cpl_propertylist_append_double(plist,qc_flux_max,flux_max_ord);
04150 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04151 }
04152
04153 sprintf(qc_flux_min,"%s%s",XSH_QC_FLUX," MIN");
04154 sprintf(qc_flux_max,"%s%s",XSH_QC_FLUX," MAX");
04155 cpl_propertylist_append_double(plist,qc_flux_min,flux_min);
04156 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04157 cpl_propertylist_append_double(plist,qc_flux_max,flux_max);
04158 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04159 check(xsh_update_pheader_in_image_multi(frm_ima,plist));
04160
04161 cleanup:
04162 xsh_free_table(&ext);
04163 xsh_free_image(&ima);
04164 xsh_free_table(&tab);
04165 xsh_free_propertylist(&plist);
04166
04167
04168 return cpl_error_get_code();
04169
04170 }
04171
04172
04184
04185
04186 cpl_error_code
04187 xsh_update_pheader_in_image_multi(cpl_frame *frame,
04188 const cpl_propertylist* pheader)
04189 {
04190 const char *fname = NULL;
04191 int nbext=0;
04192 int i=0;
04193 cpl_image *image = NULL ;
04194 char cmd[80];
04195 int extension=0 ;
04196 cpl_image* ext_img=NULL;
04197 cpl_propertylist* ext_header=NULL;
04198
04199 XSH_ASSURE_NOT_NULL(frame);
04200 nbext = cpl_frame_get_nextensions( frame);
04201 xsh_msg_dbg_medium("nbext=%d",nbext);
04202 check( fname = cpl_frame_get_filename( frame));
04203 check( image = cpl_image_load( fname, CPL_TYPE_FLOAT, 0, 0));
04204
04205
04206
04207
04208 cpl_image_save(image, "tmp.fits", CPL_BPP_IEEE_FLOAT, pheader,
04209 CPL_IO_DEFAULT ) ;
04210 xsh_free_image(&image);
04211 xsh_msg_dbg_medium("fname=%s",fname);
04212 for( i = 1 ; i<=nbext ; i++ ) {
04213
04214 check( ext_img = cpl_image_load( fname, CPL_TYPE_FLOAT,0, i));
04215 check( ext_header = cpl_propertylist_load( fname ,i));
04216
04217 if ( i == 0 ) {
04218 extension = CPL_IO_DEFAULT ;
04219 }
04220 else {
04221 extension = CPL_IO_EXTEND ;
04222 check(cpl_image_save( ext_img, "tmp.fits", CPL_BPP_IEEE_FLOAT,ext_header,
04223 extension));
04224 }
04225 xsh_free_image( &ext_img) ;
04226 xsh_free_propertylist( &ext_header) ;
04227 }
04228
04229 sprintf(cmd,"mv tmp.fits %s",fname);
04230 system(cmd);
04231 system("rm -f tmp.fits");
04232
04233
04234 cleanup:
04235 xsh_free_image( &ext_img) ;
04236 xsh_free_propertylist( &ext_header) ;
04237 xsh_free_image(&image);
04238
04239 return cpl_error_get_code();
04240 }
04241
04247
04248 double xsh_vector_get_err_median( cpl_vector *vect)
04249 {
04250 double err_median =0.0;
04251 int i, vect_size =0;
04252 double *data = NULL;
04253
04254 XSH_ASSURE_NOT_NULL( vect);
04255
04256 check( vect_size = cpl_vector_get_size( vect));
04257 check( data = cpl_vector_get_data( vect));
04258
04259 if (vect_size > 1){
04260 for( i=0; i< vect_size; i++){
04261 err_median += data[i]*data[i];
04262 }
04263
04264 err_median = sqrt( M_PI / 2.0 *
04265 ((double) vect_size / ((double) vect_size- 1.))) *
04266 (1./(double)vect_size) * sqrt (err_median);
04267 }
04268 else{
04269 err_median = data[0];
04270 }
04271
04272 cleanup:
04273 return err_median;
04274 }
04275
04282
04283 double xsh_vector_get_err_mean( cpl_vector *vect)
04284 {
04285 double err_mean =0.0;
04286 int i, vect_size =0;
04287 double *data = NULL;
04288
04289 XSH_ASSURE_NOT_NULL( vect);
04290
04291 check( vect_size = cpl_vector_get_size( vect));
04292 check( data = cpl_vector_get_data( vect));
04293
04294 for( i=0; i< vect_size; i++){
04295 err_mean += data[i]*data[i];
04296 }
04297 err_mean = sqrt( err_mean)/(double)vect_size;
04298
04299 cleanup:
04300 return err_mean;
04301 }
04302
04303
04304
04305
04311
04312 long xsh_round_double(double x)
04313 {
04314 return (x >=0) ? (long)(x+0.5) : (long)(x-0.5);
04315 }
04316
04317
04326
04327 inline int
04328 xsh_min_int(int x, int y)
04329 {
04330 return (x <=y) ? x : y;
04331 }
04332
04333
04334
04343
04344 inline int
04345 xsh_max_int(int x, int y)
04346 {
04347 return (x >=y) ? x : y;
04348 }
04349
04350
04351
04352
04353
04362
04363 inline double
04364 xsh_min_double(double x, double y)
04365 {
04366 return (x <=y) ? x : y;
04367 }
04368
04369
04370
04379
04380 inline double
04381 xsh_max_double(double x, double y)
04382 {
04383 return (x >=y) ? x : y;
04384 }
04385
04386
04387
04394
04395 double xsh_pow_int(double x, int y)
04396 {
04397 double result = 1.0;
04398
04399
04400 while(y != 0)
04401 {
04402 if (y % 2 == 0)
04403 {
04404 x *= x;
04405 y /= 2;
04406 }
04407 else
04408 {
04409 if (y > 0)
04410 {
04411 result *= x;
04412 y -= 1;
04413 }
04414 else
04415 {
04416 result /= x;
04417 y += 1;
04418 }
04419 }
04420 }
04421 return result;
04422 }
04423
04439 const char*
04440 xsh_string_tolower(char* s)
04441 {
04442
04443 char *t = s;
04444
04445 assert(s != NULL);
04446
04447 while (*t) {
04448 *t = tolower(*t);
04449 t++;
04450 }
04451
04452 return s;
04453
04454 }
04455
04456
04473 const char*
04474 xsh_string_toupper(char* s)
04475 {
04476
04477 char *t = s;
04478
04479 assert(s != NULL);
04480
04481 while (*t) {
04482 *t = toupper(*t);
04483 t++;
04484 }
04485
04486 return s;
04487
04488 }
04489
04490
04491
04507
04508 double
04509 xsh_spline_hermite( double xp, const double *x, const double *y, int n, int *istart )
04510 {
04511 double yp1, yp2, yp = 0;
04512 double xpi, xpi1, l1, l2, lp1, lp2;
04513 int i;
04514
04515 if ( x[0] <= x[n-1] && (xp < x[0] || xp > x[n-1]) ) return 0.0;
04516 if ( x[0] > x[n-1] && (xp > x[0] || xp < x[n-1]) ) return 0.0;
04517
04518 if ( x[0] <= x[n-1] )
04519 {
04520 for ( i = (*istart)+1; i <= n && xp >= x[i-1]; i++ )
04521 ;
04522 }
04523 else
04524 {
04525 for ( i = (*istart)+1; i <= n && xp <= x[i-1]; i++ )
04526 ;
04527 }
04528
04529 *istart = i;
04530 i--;
04531
04532 lp1 = 1.0 / (x[i-1] - x[i]);
04533 lp2 = -lp1;
04534
04535 if ( i == 1 )
04536 {
04537 yp1 = (y[1] - y[0]) / (x[1] - x[0]);
04538 }
04539 else
04540 {
04541 yp1 = (y[i] - y[i-2]) / (x[i] - x[i-2]);
04542 }
04543
04544 if ( i >= n - 1 )
04545 {
04546 yp2 = (y[n-1] - y[n-2]) / (x[n-1] - x[n-2]);
04547 }
04548 else
04549 {
04550 yp2 = (y[i+1] - y[i-1]) / (x[i+1] - x[i-1]);
04551 }
04552
04553 xpi1 = xp - x[i];
04554 xpi = xp - x[i-1];
04555 l1 = xpi1*lp1;
04556 l2 = xpi*lp2;
04557
04558 yp = y[i-1]*(1 - 2.0*lp1*xpi)*l1*l1 +
04559 y[i]*(1 - 2.0*lp2*xpi1)*l2*l2 +
04560 yp1*xpi*l1*l1 + yp2*xpi1*l2*l2;
04561
04562 return yp;
04563 }
04564
04565
04566
04577
04578
04579 double
04580 xsh_spline_hermite_table( double xp, const cpl_table *t, const char *column_x,
04581 const char *column_y, int *istart )
04582 {
04583 double result = 0;
04584 int n;
04585
04586 const double *x, *y;
04587
04588 check_msg( x = cpl_table_get_data_double_const(t, column_x),
04589 "Error reading column '%s'", column_x);
04590 check_msg( y = cpl_table_get_data_double_const(t, column_y),
04591 "Error reading column '%s'", column_y);
04592
04593 n = cpl_table_get_nrow(t);
04594
04595 result = xsh_spline_hermite(xp, x, y, n, istart);
04596
04597 cleanup:
04598 return result;
04599 }
04600
04601
04602
04611 cpl_vector *
04612 xsh_image_to_vector( cpl_image * spectrum )
04613 {
04614 cpl_vector * result ;
04615 cpl_type type=CPL_TYPE_FLOAT;
04616
04617 int i ;
04618 int ilx=0;
04619 int ily=0;
04620
04621 int* pi=NULL;
04622 float* pf=NULL;
04623 double* pd=NULL;
04624 double* pv=NULL;
04625
04626 int size=0;
04627
04628
04629 XSH_ASSURE_NOT_NULL_MSG(spectrum,"NULL input spectrum (1D) image!Exit.");
04630 ilx=cpl_image_get_size_x(spectrum);
04631 ily=cpl_image_get_size_y(spectrum);
04632 size=ilx*ily;
04633
04634 result=cpl_vector_new(size);
04635 pv=cpl_vector_get_data(result);
04636
04637 switch(type) {
04638
04639 case CPL_TYPE_INT:
04640 pi=cpl_image_get_data_int(spectrum);
04641 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pi[i] ;
04642 break;
04643
04644 case CPL_TYPE_FLOAT:
04645 pf=cpl_image_get_data_float(spectrum);
04646 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pf[i] ;
04647 break;
04648
04649 case CPL_TYPE_DOUBLE:
04650 pd=cpl_image_get_data_double(spectrum);
04651 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pd[i] ;
04652 break;
04653
04654 default:
04655 xsh_msg_error("Wrong input image data type %d",type);
04656 }
04657
04658 cleanup:
04659
04660 return result ;
04661 }
04662
04663
04664
04674
04675
04676 cpl_image*
04677 xsh_vector_to_image(const cpl_vector* vector,cpl_type type)
04678 {
04679 int i=0;
04680 cpl_image* image=NULL;
04681 int size=0;
04682 const double* pv=NULL;
04683 int* pi=NULL;
04684 float* pf=NULL;
04685 double* pd=NULL;
04686
04687
04688 size=cpl_vector_get_size(vector);
04689 image=cpl_image_new(size,1,type);
04690 pv=cpl_vector_get_data_const(vector);
04691 if(type == CPL_TYPE_INT) {
04692 pi=cpl_image_get_data_int(image);
04693 for(i=0;i<size;i++) {
04694 pi[i]=pv[i];
04695 }
04696 } else if (type == CPL_TYPE_FLOAT) {
04697 pf=cpl_image_get_data_float(image);
04698 for(i=0;i<size;i++) {
04699 pf[i]=pv[i];
04700 }
04701 } else if (type == CPL_TYPE_DOUBLE) {
04702 pd=cpl_image_get_data_double(image);
04703 for(i=0;i<size;i++) {
04704 pd[i]=pv[i];
04705 }
04706 } else {
04707 assure( false, CPL_ERROR_INVALID_TYPE,
04708 "No CPL type to represent BITPIX = %d", type);
04709 }
04710
04711 cleanup:
04712 if (cpl_error_get_code() != CPL_ERROR_NONE){
04713 xsh_free_image(&image);
04714 }
04715
04716 return image;
04717
04718 }
04719
04720
04728
04729 cpl_frame*
04730 xsh_util_multiply_by_response(cpl_frame* merged_sci, cpl_frame* response,
04731 const char* tag_o)
04732 {
04733 cpl_frame* result=NULL;
04734 cpl_image* data_sci=NULL;
04735 cpl_image* errs_sci=NULL;
04736 cpl_image* qual_sci=NULL;
04737
04738 cpl_image* data_tmp=NULL;
04739 cpl_image* errs_tmp=NULL;
04740
04741 cpl_vector* data_vec=NULL;
04742 cpl_vector* errs_vec=NULL;
04743 cpl_vector* qual_vec=NULL;
04744
04745 cpl_propertylist* hdat=NULL;
04746 cpl_propertylist* herr=NULL;
04747 cpl_propertylist* hqua=NULL;
04748 cpl_propertylist* plist=NULL;
04749
04750 cpl_table* response_table=NULL;
04751
04752 const char* name_s=NULL;
04753 const char* tag_s=NULL;
04754 const char* name_r=NULL;
04755
04756 char* name_o=NULL;
04757 double lambda_start=0;
04758 double lambda_step=0;
04759 int bin=0;
04760 int naxis=0;
04761 int nbins = 0;
04762 int ntraces = 0;
04763
04764 double *fluxcal_science_data = NULL;
04765 double *fluxcal_science_noise = NULL;
04766
04767 XSH_ASSURE_NOT_NULL_MSG(merged_sci,"NULL input merged frame!Exit.");
04768 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04769
04770 check(name_s=cpl_frame_get_filename(merged_sci));
04771 check(tag_s=cpl_frame_get_tag(merged_sci));
04772 name_o=cpl_sprintf("%s.fits",tag_o);
04773
04774 check(hdat=cpl_propertylist_load(name_s,0));
04775 check(herr=cpl_propertylist_load(name_s,1));
04776 check(hqua=cpl_propertylist_load(name_s,2));
04777
04778 naxis=xsh_pfits_get_naxis(hdat);
04779
04780 if(naxis == 1) {
04781
04782 check(data_vec=cpl_vector_load(name_s,0));
04783 check(errs_vec=cpl_vector_load(name_s,1));
04784
04785 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
04786 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
04787
04788 xsh_free_vector(&data_vec);
04789 xsh_free_vector(&errs_vec);
04790
04791 } else {
04792
04793 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,0));
04794 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,1));
04795 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,2));
04796
04797 }
04798
04799 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
04800 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
04801 xsh_free_image(&data_sci);
04802 xsh_free_image(&errs_sci);
04803
04804 check(name_r=cpl_frame_get_filename(response));
04805 check(response_table=cpl_table_load(name_r,1,0));
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820 xsh_msg("Multiply by response function");
04821
04822 check(nbins = cpl_image_get_size_x(data_tmp));
04823 check(ntraces = cpl_image_get_size_y(data_tmp));
04824
04825 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
04826 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
04827
04828 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
04829 "Error reading start wavelength from reduced science header");
04830 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
04831 "Error reading bin width from header");
04832
04833 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
04834 check(cpl_table_cast_column(response_table,"FLUX","DFLUX",CPL_TYPE_DOUBLE));
04835
04836 for (bin = 1; bin <= nbins; bin++)
04837 {
04838 double lambda;
04839 double response;
04840 int trace;
04841 int istart = 0;
04842
04843 lambda = lambda_start + (bin-1) * lambda_step;
04844 check_msg( response =
04845 xsh_spline_hermite_table(lambda, response_table,
04846 "DLAMBDA", "DFLUX", &istart),
04847 "Error interpolating response curve at lambda = %f wlu", lambda);
04848
04849 xsh_msg_dbg_medium("response=%g",response);
04850
04851 for (trace = 1; trace <= ntraces; trace++)
04852 {
04853
04854
04855
04856
04857 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
04858
04859 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
04860
04861
04862
04863 }
04864 }
04865
04866 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
04867 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
04868 xsh_free_image(&data_tmp);
04869 xsh_free_image(&errs_tmp);
04870
04871 cpl_table_erase_column(response_table,"DLAMBDA");
04872 cpl_table_erase_column(response_table,"DFLUX");
04873 check( xsh_pfits_set_pcatg( hdat, tag_o));
04874 xsh_pfits_set_extname( hdat, "FLUX");
04875
04876 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04877 check(xsh_plist_set_extra_keys(hdat,"IMAGE","DATA","RMSE",
04878 "FLUX","ERRS","QUAL",0));
04879
04880 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04881 xsh_pfits_set_extname( herr, "ERRS");
04882 check(xsh_plist_set_extra_keys(herr,"IMAGE","DATA","RMSE",
04883 "FLUX","ERRS","QUAL",1));
04884
04885
04886 xsh_pfits_set_extname( hqua, "QUAL");
04887 check(xsh_plist_set_extra_keys(hqua,"IMAGE","DATA","RMSE",
04888 "FLUX","ERRS","QUAL",2));
04889
04890
04891
04892 if(naxis==1) {
04893 check(data_vec=xsh_image_to_vector(data_sci));
04894 check(errs_vec=xsh_image_to_vector(errs_sci));
04895
04896 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04897 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
04898 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04899 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
04900 check(qual_vec=cpl_vector_load(name_s,2));
04901 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
04902
04903
04904 } else {
04905 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
04906 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
04907 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
04908 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
04909 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
04910 }
04911
04912
04913 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
04914
04915 cleanup:
04916
04917 cpl_free(name_o);
04918
04919 xsh_free_image(&data_sci);
04920 xsh_free_image(&errs_sci);
04921 xsh_free_image(&qual_sci);
04922 xsh_free_image(&data_sci);
04923 xsh_free_image(&errs_sci);
04924
04925 xsh_free_vector(&data_vec);
04926 xsh_free_vector(&errs_vec);
04927 xsh_free_vector(&qual_vec);
04928
04929 xsh_free_table(&response_table);
04930 xsh_free_propertylist(&hdat);
04931 xsh_free_propertylist(&herr);
04932 xsh_free_propertylist(&hqua);
04933 xsh_free_propertylist(&plist);
04934
04935 return result;
04936 }
04937
04938
04946
04947 cpl_frame*
04948 xsh_util_multiply_by_response_ord(cpl_frame* extracted_sci, cpl_frame* response,
04949 const char* tag_o)
04950 {
04951 cpl_frame* result=NULL;
04952 cpl_image* data_sci=NULL;
04953 cpl_image* errs_sci=NULL;
04954 cpl_image* qual_sci=NULL;
04955
04956 cpl_image* data_tmp=NULL;
04957 cpl_image* errs_tmp=NULL;
04958
04959 cpl_vector* data_vec=NULL;
04960 cpl_vector* errs_vec=NULL;
04961 cpl_vector* qual_vec=NULL;
04962
04963 cpl_propertylist* hdat=NULL;
04964 cpl_propertylist* herr=NULL;
04965 cpl_propertylist* hqua=NULL;
04966 cpl_propertylist* plist=NULL;
04967
04968 cpl_table* response_table=NULL;
04969
04970 const char* name_s=NULL;
04971 const char* tag_s=NULL;
04972 const char* name_r=NULL;
04973 char* name_o=NULL;
04974 double lambda_start=0;
04975 double lambda_step=0;
04976 int bin=0;
04977 int naxis=0;
04978
04979 int nbins = 0;
04980 int ntraces = 0;
04981
04982 int next_sci = 0;
04983 int next_res = 0;
04984 int ext = 0;
04985 int order=0;
04986
04987 double *fluxcal_science_data = NULL;
04988 double *fluxcal_science_noise = NULL;
04989
04990 XSH_ASSURE_NOT_NULL_MSG(extracted_sci,"NULL input extracted frame!Exit.");
04991 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04992
04993 check(name_s=cpl_frame_get_filename(extracted_sci));
04994 check(tag_s=cpl_frame_get_tag(extracted_sci));
04995
04996 name_o=cpl_sprintf("%s.fits",tag_o);
04997 next_sci=cpl_frame_get_nextensions(extracted_sci);
04998 next_res=cpl_frame_get_nextensions(response);
04999 xsh_msg("Multiply by response function");
05000 check(name_r=cpl_frame_get_filename(response));
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010 for(ext=0, order=0;ext<next_sci;ext+=3,order++) {
05011 xsh_free_propertylist(&hdat);
05012 xsh_free_propertylist(&herr);
05013 xsh_free_propertylist(&hqua);
05014
05015 check(hdat=cpl_propertylist_load(name_s,ext+0));
05016 check(herr=cpl_propertylist_load(name_s,ext+1));
05017 check(hqua=cpl_propertylist_load(name_s,ext+2));
05018
05019 naxis=xsh_pfits_get_naxis(hdat);
05020
05021 if(naxis == 1) {
05022
05023 check(data_vec=cpl_vector_load(name_s,ext+0));
05024 check(errs_vec=cpl_vector_load(name_s,ext+1));
05025
05026 xsh_free_image(&data_sci);
05027 xsh_free_image(&errs_sci);
05028 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
05029 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
05030
05031 xsh_free_vector(&data_vec);
05032 xsh_free_vector(&errs_vec);
05033
05034 } else {
05035
05036 xsh_free_image(&data_sci);
05037 xsh_free_image(&errs_sci);
05038 xsh_free_image(&qual_sci);
05039 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
05040 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
05041 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
05042
05043 }
05044
05045 xsh_free_image(&data_tmp);
05046 xsh_free_image(&errs_tmp);
05047 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
05048 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
05049 xsh_free_image(&data_sci);
05050 xsh_free_image(&errs_sci);
05051 xsh_free_table(&response_table);
05052 if(next_res>1) {
05053 check(response_table=cpl_table_load(name_r,order+1,0));
05054
05055 } else {
05056 check(response_table=cpl_table_load(name_r,next_res,0));
05057
05058 }
05059
05060
05061
05062
05063 check(nbins = cpl_image_get_size_x(data_tmp));
05064 check(ntraces = cpl_image_get_size_y(data_tmp));
05065
05066 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
05067 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
05068
05069 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
05070 "Error reading start wavelength from reduced science header");
05071 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
05072 "Error reading bin width from header");
05073
05074 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
05075 check(cpl_table_cast_column(response_table,"RESPONSE","DFLUX",CPL_TYPE_DOUBLE));
05076
05077 for (bin = 1; bin <= nbins; bin++)
05078 {
05079 double lambda;
05080 double response;
05081 int trace;
05082 int istart = 0;
05083
05084 lambda = lambda_start + (bin-1) * lambda_step;
05085 check_msg( response =
05086 xsh_spline_hermite_table(lambda, response_table,
05087 "DLAMBDA", "DFLUX", &istart),
05088 "Error interpolating response curve at lambda = %f wlu", lambda);
05089
05090 xsh_msg_dbg_medium("ext=%d response=%g",ext,response);
05091
05092 for (trace = 1; trace <= ntraces; trace++)
05093 {
05094
05095
05096
05097
05098 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
05099
05100 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
05101
05102
05103
05104 }
05105 }
05106
05107 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
05108 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
05109 xsh_free_image(&data_tmp);
05110 xsh_free_image(&errs_tmp);
05111
05112 cpl_table_erase_column(response_table,"DLAMBDA");
05113 cpl_table_erase_column(response_table,"DFLUX");
05114 check( xsh_pfits_set_pcatg( hdat, tag_o));
05115
05116 xsh_pfits_set_extname( hdat, "FLUX");
05117 xsh_pfits_set_bunit(hdat,XSH_BUNIT_FLUX_ABS_C);
05118 check(xsh_plist_set_extra_keys(hdat,"IMAGE","DATA","RMSE",
05119 "FLUX","ERRS","QUAL",0));
05120
05121 xsh_pfits_set_bunit(herr,XSH_BUNIT_FLUX_ABS_C);
05122 xsh_pfits_set_extname( herr, "ERRS");
05123 check(xsh_plist_set_extra_keys(herr,"IMAGE","DATA","RMSE",
05124 "FLUX","ERRS","QUAL",1));
05125
05126
05127 xsh_pfits_set_extname( hqua, "QUAL");
05128 check(xsh_plist_set_extra_keys(hqua,"IMAGE","DATA","RMSE",
05129 "FLUX","ERRS","QUAL",2));
05130
05131
05132
05133
05134 if(naxis==1) {
05135 check(data_vec=xsh_image_to_vector(data_sci));
05136 check(errs_vec=xsh_image_to_vector(errs_sci));
05137 if(ext==0) {
05138 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05139 } else {
05140 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05141 }
05142 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05143 check(qual_vec=cpl_vector_load(name_s,ext+2));
05144 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05145
05146 } else {
05147 if(ext==0) {
05148 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05149 } else {
05150 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05151 }
05152 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05153 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05154 }
05155
05156 }
05157
05158
05159 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05160
05161 cleanup:
05162
05163 cpl_free(name_o);
05164
05165 xsh_free_image(&data_sci);
05166 xsh_free_image(&errs_sci);
05167 xsh_free_image(&qual_sci);
05168 xsh_free_image(&data_sci);
05169 xsh_free_image(&errs_sci);
05170
05171 xsh_free_vector(&data_vec);
05172 xsh_free_vector(&errs_vec);
05173 xsh_free_vector(&qual_vec);
05174
05175 xsh_free_table(&response_table);
05176 xsh_free_propertylist(&hdat);
05177 xsh_free_propertylist(&herr);
05178 xsh_free_propertylist(&hqua);
05179 xsh_free_propertylist(&plist);
05180
05181 return result;
05182 }
05183
05184 static cpl_error_code
05185 xsh_util_get_infsup(double* piw,
05186 double w,
05187 int i_start,
05188 int i_end,
05189 int* i_inf,
05190 int* i_sup)
05191 {
05192
05193 int i=0;
05194 for(i = i_start;i < i_end;i++) {
05195 if (piw[i] < w) {
05196 *i_inf=i;
05197 *i_sup=i+1;
05198 }
05199 }
05200
05201 return cpl_error_get_code();
05202 }
05203
05204
05205 static double
05206 xsh_spectrum_integrate(double* pif,
05207 double* piw,
05208 int i1_inf,
05209 int i1_sup,
05210 int i2_inf,
05211 int i2_sup,
05212 double wave,
05213 double wstep)
05214 {
05215
05216 double sum1=0;
05217 double sum2=0;
05218 double sum3=0;
05219 int i=0;
05220
05221
05222 for(i=i1_sup;i<i2_inf;i++) {
05223
05224
05225
05226 sum2+=pif[i]*(piw[i+1]-piw[i]);
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238 }
05239
05240
05241
05242
05243 return (sum1+sum2+sum3);
05244 }
05245
05246
05258
05259 cpl_frame*
05260 xsh_spectrum_resample(cpl_frame* frame_inp,
05261 const double wstep,
05262 const double wmin,
05263 const double wmax,
05264 xsh_instrument* instr)
05265 {
05266
05267 cpl_frame* result=NULL;
05268 cpl_table* tab_inp=NULL;
05269 cpl_table* tab_out=NULL;
05270 int nrow_inp=0;
05271 int nrow_out=0;
05272 int i=0;
05273
05274 double wave_min=0;
05275 double wave_max=0;
05276 double wave_start=0;
05277
05278 const char* fname=NULL;
05279 double* pow=NULL;
05280 double* pof=NULL;
05281 double* piw=NULL;
05282 double* pif=NULL;
05283
05284 double wo1=0;
05285 double wo2=0;
05286
05287 int istep=0;
05288
05289 int i1_inf=0;
05290 int i1_sup=0;
05291 int i2_inf=0;
05292 int i2_sup=0;
05293
05294 int i_start=0;
05295 int i_end=0;
05296 double hstep=0;
05297 const char* tag=NULL;
05298 char* name=NULL;
05299 cpl_propertylist* plist=NULL;
05300 int nsel=0;
05301
05302
05303 check(fname=cpl_frame_get_filename(frame_inp));
05304 tag=cpl_frame_get_tag(frame_inp);
05305 plist=cpl_propertylist_load(fname,0);
05306
05307
05308
05309 tab_inp=cpl_table_load(fname,1,0);
05310 nrow_inp=cpl_table_get_nrow(tab_inp);
05311 wave_min=cpl_table_get_column_min(tab_inp,"LAMBDA");
05312 wave_max=cpl_table_get_column_max(tab_inp,"LAMBDA");
05313
05314 wave_min=(wave_min>wmin) ? wave_min : wmin;
05315 wave_max=(wave_max<wmax) ? wave_max : wmax;
05316
05317
05318 wave_start=floor(wave_min);
05319
05320
05321 if( xsh_instrument_get_arm(instr) == XSH_ARM_UVB){
05322 wave_start=(wave_start>XSH_ATM_EXT_UVB_WAV_MIN)? wave_start : XSH_ATM_EXT_UVB_WAV_MIN;
05323 }
05324 xsh_msg("Resample ref flux std spectrum to %g [nm] step",wstep);
05325
05326
05327
05328
05329
05330 nrow_out=ceil((wave_max-wave_start)/wstep);
05331 tab_out=cpl_table_new(nrow_out);
05332
05333 cpl_table_new_column(tab_out,"LAMBDA",CPL_TYPE_DOUBLE);
05334 cpl_table_new_column(tab_out,"FLUX",CPL_TYPE_DOUBLE);
05335 cpl_table_new_column(tab_out,"BIN_WIDTH",CPL_TYPE_DOUBLE);
05336
05337 cpl_table_fill_column_window_double(tab_out,"LAMBDA",0,nrow_out,0.);
05338 cpl_table_fill_column_window_double(tab_out,"FLUX",0,nrow_out,0.);
05339 cpl_table_fill_column_window_double(tab_out,"BIN_WIDTH",0,nrow_out,wstep);
05340
05341
05342 pow=cpl_table_get_data_double(tab_out,"LAMBDA");
05343 pof=cpl_table_get_data_double(tab_out,"FLUX");
05344
05345 piw=cpl_table_get_data_double(tab_inp,"LAMBDA");
05346 pif=cpl_table_get_data_double(tab_inp,"FLUX");
05347
05348 hstep=0.5*wstep;
05349
05350 i_start=0;
05351 i_end=nrow_inp;
05352
05353
05354 istep=(int) (wstep/(wave_max-wave_min)*nrow_inp+0.5);
05355 istep*=4;
05356
05357
05358
05359
05360 for(i=0;i<nrow_out;i++) {
05361 pow[i]=wave_start+i*wstep;
05362 wo1=pow[i]-hstep;
05363 wo2=pow[i]+hstep;
05364 i_start=0;
05365 i_end=nrow_inp;
05366
05367
05368
05369
05370
05371
05372
05373
05374 xsh_util_get_infsup(piw,wo1,i_start,i_end,&i1_inf,&i1_sup);
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394 xsh_util_get_infsup(piw,wo2,i_start,i_end,&i2_inf,&i2_sup);
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421 pof[i]=xsh_spectrum_integrate(pif,piw,i1_inf,i1_sup,
05422 i2_inf,i2_sup,pow[i],wstep);
05423
05424
05425
05426
05427
05428
05429 }
05430
05431 nsel=cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_LESS_THAN,wmin);
05432 cpl_table_erase_selected(tab_out);
05433 nsel=cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_GREATER_THAN,wmax);
05434 cpl_table_erase_selected(tab_out);
05435
05436 name=cpl_sprintf("RESAMPLED_%s_%s.fits",tag,
05437 xsh_instrument_arm_tostring( instr));
05438
05439 check(cpl_table_save(tab_out,plist,NULL,name,CPL_IO_DEFAULT));
05440 xsh_add_temporary_file(name);
05441 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_TABLE,
05442 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05443
05444
05445 cleanup:
05446 xsh_free_propertylist(&plist);
05447 xsh_free_table(&tab_inp);
05448 xsh_free_table(&tab_out);
05449 cpl_free(name);
05450
05451 return result;
05452 }
05453
05454
05461
05462 cpl_frame*
05463 xsh_util_frameset_collapse_mean(cpl_frameset* set,
05464 xsh_instrument* instrument)
05465 {
05466 cpl_frame* result=NULL;
05467 cpl_frame* frm=NULL;
05468
05469 cpl_image* ima=NULL;
05470 cpl_image* err=NULL;
05471
05472 cpl_image* ima_sum=NULL;
05473 cpl_image* err_sum=NULL;
05474 cpl_image* qua_sum=NULL;
05475 cpl_propertylist* hdat=NULL;
05476 cpl_propertylist* herr=NULL;
05477 cpl_propertylist* hqua=NULL;
05478 char* name=NULL;
05479 char* tag=NULL;
05480 const char* fname=NULL;
05481 int size=0;
05482 int i=0;
05483
05484
05485 size=cpl_frameset_get_size(set);
05486 for(i=0;i<size;i++) {
05487
05488 frm=cpl_frameset_get_frame(set,i);
05489 fname=cpl_frame_get_filename(frm);
05490
05491 ima=cpl_image_load(fname,XSH_PRE_DATA_TYPE,0,0);
05492 err=cpl_image_load(fname,XSH_PRE_ERRS_TYPE,0,1);
05493
05494 cpl_image_multiply(err,err);
05495 if(i==0) {
05496 ima_sum=cpl_image_duplicate(ima);
05497 err_sum=cpl_image_duplicate(err);
05498 } else {
05499 cpl_image_add(ima_sum,ima);
05500 cpl_image_add(err_sum,err);
05501 }
05502
05503 xsh_free_image(&ima);
05504 xsh_free_image(&err);
05505
05506 }
05507
05508 cpl_image_divide_scalar(ima_sum,size);
05509 cpl_image_divide_scalar(err_sum,size);
05510
05511
05512 check(cpl_image_power(err_sum,0.5));
05513
05514
05515 qua_sum=cpl_image_load(fname,XSH_PRE_QUAL_TYPE,0,2);
05516
05517 frm=cpl_frameset_get_frame(set,0);
05518 fname=cpl_frame_get_filename(frm);
05519 hdat=cpl_propertylist_load(fname,0);
05520 herr=cpl_propertylist_load(fname,1);
05521 hqua=cpl_propertylist_load(fname,2);
05522
05523 name=cpl_sprintf("SKY_AVG_%s.fits",xsh_instrument_arm_tostring( instrument));
05524 tag=cpl_sprintf("SKY_AVG_%s",xsh_instrument_arm_tostring( instrument));
05525
05526 check(cpl_image_save(ima_sum,name,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05527 check(cpl_image_save(err_sum,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05528 check(cpl_image_save(qua_sum,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05529 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_IMAGE,
05530 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05531
05532 cleanup:
05533
05534 xsh_free_image(&ima);
05535 xsh_free_image(&err);
05536
05537 xsh_free_image(&ima_sum);
05538 xsh_free_image(&err_sum);
05539 xsh_free_image(&qua_sum);
05540
05541
05542 cpl_free(name);
05543 cpl_free(tag);
05544
05545 return result;
05546 }
05547
05548
05549
05550
05569 cpl_error_code
05570 xsh_normalize_spectrum_image_slice(const char* name_s,
05571 const char* tag_o,
05572 const int ext,
05573 const int binx,
05574 const double gain,
05575 const double exptime,
05576 const double airmass,
05577 const cpl_table* tbl_atm_ext)
05578 {
05579
05580
05581 cpl_image* data_ima=NULL;
05582 cpl_image* errs_ima=NULL;
05583 cpl_image* qual_ima=NULL;
05584 cpl_image* data_nrm=NULL;
05585 cpl_image* errs_nrm=NULL;
05586
05587 cpl_image* data_tmp=NULL;
05588 cpl_image* errs_tmp=NULL;
05589
05590 cpl_image* data_nrm_tmp=NULL;
05591 cpl_image* errs_nrm_tmp=NULL;
05592
05593 cpl_vector* data_vec=NULL;
05594 cpl_vector* errs_vec=NULL;
05595 cpl_vector* qual_vec=NULL;
05596
05597 cpl_propertylist* hdat=NULL;
05598 cpl_propertylist* herr=NULL;
05599 cpl_propertylist* hqua=NULL;
05600 int naxis=0;
05601 char name_o[80];
05602
05603 sprintf(name_o,"%s.fits",tag_o);
05604
05605 xsh_free_propertylist(&hdat);
05606 xsh_free_propertylist(&herr);
05607 xsh_free_propertylist(&hqua);
05608
05609 hdat=cpl_propertylist_load(name_s,ext+0);
05610 herr=cpl_propertylist_load(name_s,ext+1);
05611 hqua=cpl_propertylist_load(name_s,ext+2);
05612
05613
05614 naxis=xsh_pfits_get_naxis(hdat);
05615 xsh_pfits_set_pcatg(hdat,tag_o);
05616 if(naxis == 1) {
05617
05618 check(data_vec=cpl_vector_load(name_s,ext+0));
05619 check(errs_vec=cpl_vector_load(name_s,ext+1));
05620 xsh_free_image(&data_ima);
05621 xsh_free_image(&errs_ima);
05622 check(data_ima=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
05623 check(errs_ima=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
05624 xsh_free_vector(&data_vec);
05625 xsh_free_vector(&errs_vec);
05626
05627 } else {
05628
05629 xsh_free_image(&data_ima);
05630 xsh_free_image(&errs_ima);
05631 xsh_free_image(&qual_ima);
05632 check(data_ima=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
05633 check(errs_ima=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
05634 check(qual_ima=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
05635
05636 }
05637 xsh_free_image(&data_tmp);
05638 xsh_free_image(&errs_tmp);
05639 data_tmp=cpl_image_cast(data_ima,CPL_TYPE_DOUBLE);
05640 errs_tmp=cpl_image_cast(errs_ima,CPL_TYPE_DOUBLE);
05641
05642 xsh_free_image(&data_nrm_tmp);
05643 xsh_free_image(&errs_nrm_tmp);
05644
05645 check(data_nrm_tmp=xsh_normalize_spectrum_image(data_tmp,errs_tmp,hdat,
05646 binx,gain,exptime,airmass,1,
05647 tbl_atm_ext,&errs_nrm_tmp));
05648
05649 xsh_free_image(&data_nrm);
05650 xsh_free_image(&errs_nrm);
05651 check(data_nrm=cpl_image_cast(data_nrm_tmp,CPL_TYPE_FLOAT));
05652 check(errs_nrm=cpl_image_cast(errs_nrm_tmp,CPL_TYPE_FLOAT));
05653
05654 if(naxis==1) {
05655 xsh_free_vector(&data_vec);
05656 xsh_free_vector(&errs_vec);
05657
05658 check(data_vec=xsh_image_to_vector(data_nrm));
05659 check(errs_vec=xsh_image_to_vector(errs_nrm));
05660
05661 if(ext==0) {
05662 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05663 } else {
05664 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05665 }
05666 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05667 xsh_free_vector(&qual_vec);
05668 check(qual_vec=cpl_vector_load(name_s,ext+2));
05669 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05670
05671
05672 } else {
05673 if(ext==0) {
05674 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05675 } else {
05676 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05677 }
05678 check(cpl_image_save(errs_nrm,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05679 check(cpl_image_save(qual_ima,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05680
05681 }
05682
05683
05684
05685 cleanup:
05686 xsh_free_image(&data_ima);
05687 xsh_free_image(&errs_ima);
05688 xsh_free_image(&qual_ima);
05689 xsh_free_image(&data_nrm);
05690 xsh_free_image(&errs_nrm);
05691 xsh_free_image(&data_tmp);
05692 xsh_free_image(&errs_tmp);
05693 xsh_free_image(&data_nrm_tmp);
05694 xsh_free_image(&errs_nrm_tmp);
05695
05696 xsh_free_propertylist(&hdat);
05697 xsh_free_propertylist(&herr);
05698 xsh_free_propertylist(&hqua);
05699
05700 xsh_free_vector(&data_vec);
05701 xsh_free_vector(&errs_vec);
05702 xsh_free_vector(&qual_vec);
05703
05704 return cpl_error_get_code();
05705 }
05706
05707
05708
05725
05726 cpl_frame *
05727 xsh_normalize_spectrum(const cpl_frame *obj_frame,
05728 const cpl_frame *atm_ext_frame,
05729 cpl_boolean correct_binning,
05730 xsh_instrument* instrument,
05731 const char* tag_o)
05732 {
05733
05734 cpl_frame* result=NULL;
05735 const char* name_s=NULL;
05736 const char* aname=NULL;
05737
05738 cpl_table* tbl_atm_ext=NULL;
05739 cpl_propertylist* hdat=NULL;
05740
05741 char* name_o=NULL;
05742 int binx=1;
05743 double gain=0;
05744 double exptime=0;
05745 double airmass=0;
05746
05747 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05748 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05749
05750 name_s=cpl_frame_get_filename(obj_frame);
05751 aname=cpl_frame_get_filename(atm_ext_frame);
05752 tbl_atm_ext=cpl_table_load(aname,1,0);
05753
05754 cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE);
05755 cpl_table_cast_column( tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,"D_EXTINCTION",CPL_TYPE_DOUBLE);
05756
05757
05758 hdat=cpl_propertylist_load(name_s,0);
05759 exptime = xsh_pfits_get_exptime(hdat);
05760 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05761
05762 gain=1./2.12;
05763 } else {
05764 gain = xsh_pfits_get_gain(hdat);
05765 }
05766
05767 if (correct_binning) {
05768
05769 binx = xsh_pfits_get_biny(hdat);
05770 } else {
05771 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05772 binx = 1;
05773 }
05774 airmass=xsh_pfits_get_airm_mean(hdat);
05775 name_o=cpl_sprintf("%s.fits",tag_o);
05776
05777 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,0,binx,gain,
05778 exptime,airmass,tbl_atm_ext));
05779
05780 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05781
05782 cleanup:
05783
05784 xsh_free_table(&tbl_atm_ext);
05785 xsh_free_propertylist(&hdat);
05786 cpl_free(name_o);
05787
05788 return result;
05789
05790 }
05791
05792
05793
05794
05795
05811
05812 cpl_frame *
05813 xsh_normalize_spectrum_ord(const cpl_frame *obj_frame,
05814 const cpl_frame *atm_ext_frame,
05815 cpl_boolean correct_binning,
05816 xsh_instrument* instrument,
05817 const char* tag_o)
05818 {
05819
05820 cpl_frame* result=NULL;
05821 const char* name_s=NULL;
05822 const char* aname=NULL;
05823
05824 cpl_table* tbl_atm_ext=NULL;
05825 cpl_propertylist* hdat=NULL;
05826 char* name_o=NULL;
05827
05828 int next=0;
05829 int ext=0;
05830 int binx=1;
05831 double gain=0;
05832 double exptime=0;
05833 double airmass=0;
05834
05835 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05836 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05837
05838 next=cpl_frame_get_nextensions( obj_frame);
05839 name_s=cpl_frame_get_filename(obj_frame);
05840
05841 aname=cpl_frame_get_filename(atm_ext_frame);
05842 tbl_atm_ext=cpl_table_load(aname,1,0);
05843 check(cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE));
05844 if(!cpl_table_has_column(tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K)){
05845 xsh_msg_warning("You are using an obsolete atm extinction line table");
05846 cpl_table_duplicate_column(tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,
05847 tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
05848 }
05849 check(cpl_table_cast_column( tbl_atm_ext,XSH_ATMOS_EXT_LIST_COLNAME_K,"D_EXTINCTION",CPL_TYPE_DOUBLE));
05850 name_o=cpl_sprintf("%s.fits",tag_o);
05851
05852 hdat=cpl_propertylist_load(name_s,0);
05853
05854 check(exptime = xsh_pfits_get_exptime(hdat));
05855 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05856
05857 gain=1./2.12;
05858 } else {
05859 check(gain = xsh_pfits_get_gain(hdat));
05860 }
05861
05862 if (correct_binning && (xsh_instrument_get_arm(instrument) != XSH_ARM_NIR)) {
05863
05864 check(binx = xsh_pfits_get_biny(hdat));
05865 } else {
05866 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05867 binx = 1;
05868 }
05869 check(airmass=xsh_pfits_get_airm_mean(hdat));
05870
05871 for(ext=0;ext<next;ext+=3) {
05872 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,ext,binx,gain,
05873 exptime,airmass,tbl_atm_ext));
05874 }
05875
05876 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05877
05878 cleanup:
05879
05880 xsh_free_table(&tbl_atm_ext);
05881 xsh_free_propertylist(&hdat);
05882 cpl_free(name_o);
05883
05884 return result;
05885
05886 }
05887
05888
05910
05911
05912 cpl_image *
05913 xsh_normalize_spectrum_image(const cpl_image *spectrum,
05914 const cpl_image *spectrum_error,
05915 const cpl_propertylist *spectrum_header,
05916 const int binx,
05917 const double gain,
05918 const double exptime,
05919 const double airmass,
05920 const int n_traces,
05921 const cpl_table *atm_extinction,
05922 cpl_image **scaled_error)
05923 {
05924 cpl_image *scaled = NULL;
05925 int norders, ny, nx;
05926 double cor_fct=gain*exptime*binx;
05927 XSH_ASSURE_NOT_NULL_MSG(spectrum,"Null input spectrum");
05928 XSH_ASSURE_NOT_NULL_MSG(scaled_error,"Null input scaled error");
05929 XSH_ASSURE_NOT_NULL_MSG(spectrum_error, "Null input spectrum error");
05930 XSH_ASSURE_NOT_NULL_MSG(spectrum_header,"Null input spectrum header");
05931 XSH_ASSURE_NOT_NULL_MSG(atm_extinction,"Null input atmospheric extinction table");
05932
05933 nx = cpl_image_get_size_x(spectrum);
05934 ny = cpl_image_get_size_y(spectrum);
05935
05936
05937 if (spectrum_error != NULL)
05938 {
05939 assure( nx == cpl_image_get_size_x(spectrum_error) &&
05940 ny == cpl_image_get_size_y(spectrum_error), CPL_ERROR_INCOMPATIBLE_INPUT,
05941 "Error spectrum geometry differs from spectrum: %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " vs. %dx%d",
05942 cpl_image_get_size_x(spectrum_error),
05943 cpl_image_get_size_y(spectrum_error),
05944 nx, ny);
05945 }
05946
05947 assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
05948 "Spectrum image height (%d) is not a multiple of "
05949 "the number of traces (%d). Confused, bailing out",
05950 ny, n_traces);
05951
05952 norders = ny / n_traces;
05953
05954
05955
05956
05957 assure( exptime > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive exposure time: %f s", exptime);
05958 assure( gain > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive gain: %f", gain);
05959 assure( binx > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal binning: %d", binx);
05960
05961 xsh_msg_dbg_medium("Correcting for exposure time = %f s, gain = %f, binx = %d", exptime, gain, binx);
05962
05963 check_msg(scaled=cpl_image_divide_scalar_create(spectrum,cor_fct),
05964 "Error correcting spectrum for gain, exposure time, binning");
05965
05966 if (scaled_error != NULL)
05967 {
05968 check_msg( *scaled_error=cpl_image_divide_scalar_create(spectrum_error,
05969 cor_fct),
05970 "Error correcting rebinned spectrum for gain, exposure time, binning");
05971 }
05972
05973
05974
05975
05976 {
05977 double dlambda, lambda_start;
05978 int order;
05979
05980 xsh_msg_dbg_medium("Correcting for extinction through airmass %f", airmass);
05981 check_msg( dlambda = xsh_pfits_get_cdelt1(spectrum_header),
05982 "Error reading bin width from header");
05983
05984 for (order = 1; order <= norders; order++)
05985 {
05986 int trace;
05987
05988
05989
05990
05991
05992 if (norders == 1)
05993 {
05994 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
05995 "Error reading start wavelength from header");
05996 }
05997 else
05998 {
05999
06000 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
06001 "Error reading start wavelength from header");
06002 }
06003
06004 for (trace = 1; trace <= n_traces; trace++)
06005 {
06006 int spectrum_row = (order - 1)*n_traces + trace;
06007 int x;
06008
06009 for (x = 1; x <= nx; x++)
06010 {
06011 int pis_rejected1;
06012 int pis_rejected2;
06013 double flux;
06014 double dflux = 0;
06015 double extinction;
06016 double lambda;
06017
06018 lambda = lambda_start + (x-1) * dlambda;
06019
06020 flux = cpl_image_get(scaled, x, spectrum_row, &pis_rejected1);
06021 if (scaled_error != NULL)
06022 {
06023 dflux = cpl_image_get(*scaled_error, x,
06024 spectrum_row, &pis_rejected2);
06025 }
06026
06027 if (!pis_rejected1 && (scaled_error == NULL || !pis_rejected2))
06028 {
06029 int istart = 0;
06030
06031
06032 check_msg( extinction =
06033 xsh_spline_hermite_table(
06034 lambda, atm_extinction,
06035 "D_LAMBDA", "D_EXTINCTION", &istart),
06036 "Error interpolating extinction coefficient");
06037
06038
06039
06040
06041
06042
06043
06044
06045
06046
06047
06048 cpl_image_set(
06049 scaled, x, spectrum_row,
06050 flux * pow(10, 0.4 * extinction * airmass));
06051 if (scaled_error != NULL)
06052 {
06053 cpl_image_set(
06054 *scaled_error, x, spectrum_row,
06055 dflux * pow(10, 0.4 * extinction * airmass));
06056 }
06057 }
06058 else
06059 {
06060 cpl_image_reject(scaled, x, spectrum_row);
06061 if (scaled_error != NULL)
06062 {
06063 cpl_image_reject(*scaled_error, x, spectrum_row);
06064 }
06065 }
06066 }
06067
06068 }
06069
06070 }
06071 }
06072
06073 cleanup:
06074 if (cpl_error_get_code() != CPL_ERROR_NONE)
06075 {
06076 xsh_free_image(&scaled);
06077 if (scaled_error != NULL)
06078 {
06079 xsh_free_image(scaled_error);
06080 }
06081 }
06082
06083 return scaled;
06084 }
06085
06086 static double
06087 xsh_iterpol_linear(double* data_x,double* data_y,int ndata,double x,
06088 int* i_inf,int* i_sup)
06089 {
06090 int i=0;
06091 double y=0;
06092 int i_min=0;
06093 int i_max=0;
06094 double x1=0;
06095 double x2=0;
06096 double y1=0;
06097 double y2=0;
06098
06099 i_min=((*i_inf)>0) ? (*i_inf):0;
06100 i_max=((*i_sup)<ndata) ? (*i_sup):ndata;
06101
06102
06103 for(i=0;i<ndata;i++) {
06104
06105 if(data_x[i]>x) {
06106 y1=data_y[i-1];
06107 y2=data_y[i];
06108 x1=data_x[i-1];
06109 x2=data_x[i];
06110 *i_inf=i-1;
06111 *i_sup=i+1;
06112 break;
06113 }
06114 }
06115
06116
06117 y=(y2-y1)/(x2-x1)*(x-x1)+y1;
06118
06119 return y;
06120 }
06121
06129 cpl_frame*
06130 xsh_spectrum_interpolate_linear(cpl_frame* table_frame,
06131 const double wstep,
06132 const double wmin,
06133 const double wmax)
06134 {
06135
06136 cpl_frame* result=NULL;
06137 cpl_table* table_i=NULL;
06138 cpl_table* table_o=NULL;
06139 const char* name_i=NULL;
06140 const char* tag_i=NULL;
06141
06142 char* name_o=NULL;
06143 char* tag_o=NULL;
06144
06145 cpl_propertylist* plist=NULL;
06146 int nrows_i=0;
06147 int nrows_o=0;
06148 int row=0;
06149
06150 double* pwave_i=NULL;
06151 double* pflux_i=NULL;
06152 double* pwave_o=NULL;
06153 double* pflux_o=NULL;
06154 int i_inf=0;
06155 int i_sup=0;
06156
06157
06158
06159 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06160 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06161 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06162
06163 name_i=cpl_frame_get_filename(table_frame);
06164 tag_i=cpl_frame_get_tag(table_frame);
06165 table_i=cpl_table_load(name_i,1,0);
06166 nrows_i=cpl_table_get_nrow(table_i);
06167 plist=cpl_propertylist_load(name_i,0);
06168 nrows_o=(int)((wmax-wmin)/wstep+0.5);
06169 table_o=cpl_table_new(nrows_o);
06170 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06171 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06172 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows_o,0.));
06173 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows_o,0.));
06174 check(pwave_i=cpl_table_get_data_double(table_i,"LAMBDA"));
06175 check(pflux_i=cpl_table_get_data_double(table_i,"FLUX"));
06176 check(pwave_o=cpl_table_get_data_double(table_o,"LAMBDA"));
06177 check(pflux_o=cpl_table_get_data_double(table_o,"FLUX"));
06178 i_inf=0;
06179 i_sup=nrows_o;
06180
06181 for (row = 0; row < nrows_o; row++)
06182 {
06183
06184 pwave_o[row]= wmin + row * wstep;
06185 pflux_o[row]= xsh_iterpol_linear(pwave_i,pflux_i,nrows_i,pwave_o[row],
06186 &i_inf,&i_sup);
06187
06188
06189 }
06190 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06191 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06192 xsh_pfits_set_pcatg(plist,tag_o);
06193 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06194 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06195 CPL_FRAME_GROUP_PRODUCT,
06196 CPL_FRAME_LEVEL_FINAL));
06197 xsh_add_temporary_file(name_o);
06198 cleanup:
06199
06200
06201 xsh_free_table(&table_i);
06202 xsh_free_table(&table_o);
06203 xsh_free_propertylist(&plist);
06204 cpl_free(name_o);
06205 cpl_free(tag_o);
06206
06207 return result;
06208
06209 }
06210
06211
06212
06213
06221 cpl_frame*
06222 xsh_spectrum_interpolate(cpl_frame* table_frame,
06223 const double wstep,
06224 const double wmin,
06225 const double wmax)
06226 {
06227
06228 cpl_frame* result=NULL;
06229 cpl_table* table_i=NULL;
06230 cpl_table* table_o=NULL;
06231 const char* name_i=NULL;
06232 const char* tag_i=NULL;
06233
06234 char* name_o=NULL;
06235 char* tag_o=NULL;
06236
06237 cpl_propertylist* plist=NULL;
06238 int nrows=0;
06239 int row=0;
06240 double wave=0;
06241 double flux_o=0;
06242 double* pwave=NULL;
06243 double* pflux=NULL;
06244
06245 int istart = 0;
06246
06247 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06248 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06249 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06250
06251 name_i=cpl_frame_get_filename(table_frame);
06252
06253 tag_i=cpl_frame_get_tag(table_frame);
06254 check(table_i=cpl_table_load(name_i,1,0));
06255 plist=cpl_propertylist_load(name_i,0);
06256 nrows=(int)((wmax-wmin)/wstep+0.5);
06257 table_o=cpl_table_new(nrows);
06258
06259 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06260
06261 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06262
06263 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06264
06265 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06266
06267
06268 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows,0.));
06269 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows,0.));
06270
06271 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06272 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06273
06274
06275 for (row = 0; row < nrows; row++)
06276 {
06277
06278 wave = wmin + row * wstep;
06279
06280 check_msg( flux_o = xsh_spline_hermite_table(wave, table_i,
06281 "LAMBDA", "FLUX", &istart),
06282 "Error interpolating curve at lambda = %f wlu", wave);
06283 pwave[row]=wave;
06284 pflux[row]=flux_o;
06285
06286 xsh_msg_dbg_medium("interpolated flux[%g]=%g",wave,flux_o);
06287 }
06288
06289
06290 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06291 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06292 xsh_pfits_set_pcatg(plist,tag_o);
06293 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06294 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06295 CPL_FRAME_GROUP_PRODUCT,
06296 CPL_FRAME_LEVEL_FINAL));
06297
06298 xsh_add_temporary_file(name_o);
06299
06300 cleanup:
06301
06302
06303 xsh_free_table(&table_i);
06304 xsh_free_table(&table_o);
06305 xsh_free_propertylist(&plist);
06306 cpl_free(name_o);
06307 cpl_free(tag_o);
06308
06309
06310 return result;
06311
06312 }
06313
06314
06315
06325 void
06326 xsh_array_clip_mean( cpl_array *array,
06327 double kappa,
06328 int niter,
06329 double frac_min,
06330 double *mean,
06331 double *stdev)
06332 {
06333 int i, j, size;
06334 double mean_val;
06335 double sigma, frac;
06336 int *flags = NULL;
06337 int nb_rejected = 0, total_rejected=0;
06338 double* pval=NULL;
06339
06340 XSH_ASSURE_NOT_NULL( array);
06341 XSH_ASSURE_NOT_NULL( mean);
06342 XSH_ASSURE_NOT_NULL( stdev);
06343
06344 check( mean_val = cpl_array_get_mean( array));
06345 check( sigma = cpl_array_get_stdev( array));
06346 check( size = cpl_array_get_size( array));
06347
06348 XSH_CALLOC( flags, int, size);
06349
06350 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06351 xsh_msg_dbg_medium("Accepted fraction %f Mean %f sigma %f", 1.0, mean_val, sigma);
06352
06353
06354 check(pval=cpl_array_get_data_double(array));
06355 for( i=1; i<= niter; i++) {
06356 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06357 nb_rejected = 0;
06358 for( j=0; j< size; j++){
06359
06360 if ( flags[j] == 0 && fabs( pval[j]-mean_val) > kappa*sigma){
06361 nb_rejected++;
06362 flags[j]=1;
06363 check( cpl_array_set_invalid( array, j));
06364 }
06365 }
06366 if ( nb_rejected == 0){
06367 xsh_msg("No more points are rejected. Iterations are stopped.");
06368 break;
06369 }
06370 total_rejected += nb_rejected;
06371 frac = 1-(double)total_rejected/(double)size;
06372 if (frac < frac_min){
06373 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06374 frac_min, frac);
06375 break;
06376 }
06377
06378 check( mean_val = cpl_array_get_mean( array));
06379 check( sigma = cpl_array_get_stdev( array));
06380 xsh_msg("Accepted fraction %f Mean %f sigma %f", frac, mean_val, sigma);
06381 }
06382
06383 xsh_msg("End of clipping : Mean %f sigma %f", mean_val, sigma);
06384 *mean = mean_val;
06385 *stdev = sigma;
06386
06387 cleanup:
06388 XSH_FREE( flags);
06389 return;
06390 }
06391
06403 void
06404 xsh_array_clip_median( cpl_array *array,
06405 double kappa,
06406 int niter,
06407 double frac_min,
06408 double *median,
06409 double *stdev)
06410 {
06411 int i, j, size;
06412 double median_val;
06413 double sigma, frac;
06414 int *flags = NULL;
06415 int nb_rejected = 0, total_rejected=0;
06416 double* pval=NULL;
06417
06418 XSH_ASSURE_NOT_NULL( array);
06419 XSH_ASSURE_NOT_NULL( median);
06420 XSH_ASSURE_NOT_NULL( stdev);
06421
06422 check( median_val = cpl_array_get_median( array));
06423 check( sigma = cpl_array_get_stdev( array));
06424 check( size = cpl_array_get_size( array));
06425
06426 XSH_CALLOC( flags, int, size);
06427
06428 xsh_msg("Iteration %d/%d", 0, niter);
06429 xsh_msg("Accepted fraction %f Median %f sigma %f", 1.0, median_val, sigma);
06430 check(pval=cpl_array_get_data_double(array));
06431 for( i=1; i<= niter; i++) {
06432 xsh_msg("Iteration %d/%d", i, niter);
06433 nb_rejected = 0;
06434 for( j=0; j< size; j++){
06435
06436 if ( flags[j] == 0 && fabs( pval[j]-median_val) > kappa*sigma){
06437 nb_rejected++;
06438 flags[j]=1;
06439 check( cpl_array_set_invalid( array, j));
06440 }
06441 }
06442 if ( nb_rejected == 0){
06443 xsh_msg("No more points are rejected. Iterations are stopped.");
06444 break;
06445 }
06446 total_rejected += nb_rejected;
06447 frac = 1-(double)total_rejected/(double)size;
06448 if (frac < frac_min){
06449 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06450 frac_min, frac);
06451 break;
06452 }
06453 check( median_val = cpl_array_get_median( array));
06454 check( sigma = cpl_array_get_stdev( array));
06455 xsh_msg("Accepted fraction %f Median %f sigma %f", frac, median_val, sigma);
06456 }
06457 xsh_msg("End of clipping : Median %f sigma %f", median_val, sigma);
06458 *median = median_val;
06459 *stdev = sigma;
06460
06461 cleanup:
06462 XSH_FREE( flags);
06463 return;
06464 }
06465
06478 void
06479 xsh_array_clip_poly1d( cpl_vector *pos_vect,
06480 cpl_vector *val_vect,
06481 double kappa,
06482 int niter,
06483 double frac_min,
06484 int deg,
06485 cpl_polynomial **polyp,
06486 double *chisq,
06487 int **flagsp)
06488 {
06489 int i, j, size;
06490 double frac, sigma;
06491 int *flags = NULL;
06492 int nb_rejected = 0, total_rejected=0;
06493 cpl_polynomial *poly = NULL;
06494 cpl_vector *temp_pos = NULL, *temp_val = NULL;
06495 double *positions = NULL;
06496 double *values = NULL;
06497 int ngood=0;
06498
06499 XSH_ASSURE_NOT_NULL( pos_vect);
06500 XSH_ASSURE_NOT_NULL( val_vect);
06501
06502 XSH_ASSURE_NOT_NULL( polyp);
06503 XSH_ASSURE_NOT_NULL( flagsp);
06504
06505 check( poly = xsh_polynomial_fit_1d_create( pos_vect, val_vect, deg,
06506 chisq));
06507 check( size = cpl_vector_get_size( pos_vect));
06508
06509 XSH_CALLOC( flags, int, size);
06510 XSH_CALLOC( positions, double, size);
06511 XSH_CALLOC( values, double, size);
06512
06513 ngood = size;
06514 sigma = sqrt(*chisq);
06515
06516 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06517 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06518 1.0, deg, sigma);
06519
06520 for( i=1; i<= niter; i++) {
06521 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06522 nb_rejected = 0;
06523
06524 for( j=0; j< size; j++){
06525 double pos=0.0, val=0.0, pol_val=0.0;
06526
06527 check( pos = cpl_vector_get( pos_vect, j));
06528 check( val = cpl_vector_get( val_vect, j));
06529 check( pol_val = cpl_polynomial_eval_1d( poly, pos, NULL));
06530
06531 if ( flags[j] == 0 && fabs( pol_val-val) > kappa*sigma){
06532 nb_rejected++;
06533 flags[j]=2;
06534 }
06535 }
06536 if ( nb_rejected == 0){
06537 xsh_msg_dbg_medium("No more points are rejected. Iterations are stopped.");
06538 break;
06539 }
06540 total_rejected += nb_rejected;
06541 frac = 1-(double)total_rejected/(double)size;
06542 if (frac < frac_min){
06543 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06544 frac_min, frac);
06545 break;
06546 }
06547
06548 ngood = 0;
06549 for( j=0; j< size; j++){
06550 if( flags[j] == 0){
06551 positions[ngood] = cpl_vector_get( pos_vect, j);
06552 values[ngood] = cpl_vector_get( val_vect, j);
06553 ngood++;
06554 }
06555 else{
06556 flags[j] = 1;
06557 }
06558 }
06559 check( temp_pos = cpl_vector_wrap( ngood, positions));
06560 check( temp_val = cpl_vector_wrap( ngood, values));
06561
06562 xsh_free_polynomial( &poly);
06563
06564 check( poly = xsh_polynomial_fit_1d_create( temp_pos, temp_val, deg,
06565 chisq));
06566
06567 sigma = sqrt(*chisq);
06568
06569 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06570 frac, deg, sigma);
06571 xsh_unwrap_vector( &temp_pos);
06572 xsh_unwrap_vector( &temp_val);
06573 }
06574
06575 for( j=0; j< size; j++){
06576 if( flags[j] == 2){
06577 flags[j] = 0;
06578 }
06579 }
06580 *polyp = poly;
06581 *flagsp = flags;
06582
06583 cleanup:
06584 XSH_FREE( positions);
06585 XSH_FREE( values);
06586 xsh_unwrap_vector( &temp_pos);
06587 xsh_unwrap_vector( &temp_val);
06588 return;
06589 }
06590
06591 cpl_error_code
06592 xsh_rectify_params_set_defaults(cpl_parameterlist* pars,
06593 const char* rec_id,
06594 xsh_instrument* inst,
06595 xsh_rectify_param * rectify_par)
06596 {
06597 cpl_parameter* p=NULL;
06598
06599 check(p=xsh_parameters_find(pars,rec_id,"rectify-bin-slit"));
06600 if(cpl_parameter_get_double(p) <= 0) {
06601 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB){
06602 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_UVB;
06603 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_UVB);
06604 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS){
06605 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_VIS;
06606 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_VIS);
06607 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
06608 rectify_par->rectif_bin_space=XSH_SLIT_BIN_SIZE_PIPE_NIR;
06609 cpl_parameter_set_double(p,XSH_SLIT_BIN_SIZE_PIPE_NIR);
06610 }
06611 }
06612 check(p=xsh_parameters_find(pars,rec_id,"rectify-bin-lambda"));
06613 if(cpl_parameter_get_double(p) <= 0) {
06614 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB){
06615 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_UVB;
06616 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_UVB);
06617 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS){
06618 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_VIS;
06619 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_VIS);
06620 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR){
06621 rectify_par->rectif_bin_lambda=XSH_WAVE_BIN_SIZE_PIPE_NIR;
06622 cpl_parameter_set_double(p,XSH_WAVE_BIN_SIZE_PIPE_NIR);
06623 }
06624 }
06625
06626 cleanup:
06627
06628 return cpl_error_get_code();
06629
06630 }
06631
06632
06633 struct data {
06634 size_t n;
06635 double * y;
06636 double * x;
06637 int deg;
06638 };
06639
06640 static int
06641 expb_f (const gsl_vector * x, void *data,
06642 gsl_vector * f)
06643 {
06644 int i;
06645 int n = ((struct data *)data)->n;
06646 double *y = ((struct data *)data)->y;
06647 double *xtab = ((struct data *) data)->x;
06648
06649 double area = gsl_vector_get (x, 0);
06650 double a = gsl_vector_get (x, 1);
06651 double b = gsl_vector_get( x,2);
06652 double c = gsl_vector_get( x,3);
06653 double x0 = gsl_vector_get( x,4);
06654 double sigma = gsl_vector_get( x,5);
06655
06656 for (i = 0; i < n; i++)
06657 {
06658
06659 double t = xtab[i];
06660 double height = area/sqrt(2*M_PI*sigma*sigma);
06661 double W = ((t-x0)*(t-x0))/(2*sigma*sigma);
06662
06663 double Yi = height*exp(-W)+a+b*t+c*t*t;
06664
06665 gsl_vector_set (f, i, Yi - y[i]);
06666 }
06667
06668 return GSL_SUCCESS;
06669 }
06670
06671 static int
06672 expb_df (const gsl_vector * x, void *data,
06673 gsl_matrix * J)
06674 {
06675 int i;
06676 int n = ((struct data *)data)->n;
06677 double *xtab = ((struct data *) data)->x;
06678
06679 double area = gsl_vector_get (x, 0);
06680 double x0 = gsl_vector_get (x, 4);
06681 double sigma = gsl_vector_get( x,5);
06682 int deg = ((struct data *)data)->deg;
06683 for (i = 0; i < n; i++)
06684 {
06685
06686
06687
06688
06689 double t = xtab[i];
06690
06691 double W = ((t-x0)*(t-x0))/(2*sigma*sigma);
06692 double e = 0.0;
06693
06694
06695
06696 e = exp(-W)/sqrt(2*M_PI*sigma*sigma);
06697 gsl_matrix_set (J, i, 0, e);
06698
06699
06700 e = 1;
06701 gsl_matrix_set (J, i, 1, e);
06702
06703
06704 if (deg >= 1){
06705 e = t;
06706 }
06707 else {
06708 e = 0;
06709 }
06710 gsl_matrix_set (J, i, 2, e);
06711
06712
06713 if (deg == 2) {
06714 e = t*t;
06715 }
06716 else {
06717 e = 0;
06718 }
06719 gsl_matrix_set (J, i, 3, e);
06720
06721
06722 e = area/(2*M_PI*sigma)*(t-x0)/sigma*exp(-0.5*pow((t-x0)/sigma,2));
06723 gsl_matrix_set (J, i, 4, e);
06724
06725
06726 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);
06727 gsl_matrix_set (J, i, 5, e);
06728
06729 }
06730 return GSL_SUCCESS;
06731 }
06732
06733 static int
06734 expb_fdf (const gsl_vector * x, void *data,
06735 gsl_vector * f, gsl_matrix * J)
06736 {
06737 expb_f (x, data, f);
06738 expb_df (x, data, J);
06739
06740 return GSL_SUCCESS;
06741 }
06742
06743
06744
06745
06746 void xsh_gsl_init_gaussian_fit( cpl_vector *xpos_vect, cpl_vector *ypos_vect,
06747 double *init_par)
06748 {
06749 double flux_max, flux_min, intensity;
06750 int i, size;
06751 double init_area, init_sigma, init_x0=0, init_offset;
06752 double flux_sum =0.0;
06753 double hflux, flux25, flux75;
06754 double init25=0, init75=0;
06755
06756 XSH_ASSURE_NOT_NULL( xpos_vect);
06757 XSH_ASSURE_NOT_NULL( ypos_vect);
06758
06759 size = cpl_vector_get_size( xpos_vect);
06760 flux_min = cpl_vector_get_min( ypos_vect);
06761 flux_max = cpl_vector_get_max( ypos_vect);
06762 intensity = flux_max-flux_min;
06763
06764 init_offset = flux_min;
06765
06766 for (i = 0; i < size; i++){
06767 double yval;
06768
06769 yval = cpl_vector_get( ypos_vect, i);
06770 flux_sum += yval-init_offset;
06771 }
06772
06773 hflux = flux_sum/2.0;
06774 flux25 = flux_sum*0.25;
06775 flux75 = flux_sum*0.75;
06776 flux_sum =0.0;
06777
06778 for (i = 0; i < size; i++){
06779 double yval;
06780
06781 yval = cpl_vector_get( ypos_vect, i);
06782
06783 flux_sum += yval-init_offset;
06784
06785 if ( (init25 == 0) && flux_sum > flux25){
06786 init25 = (i+i-1)/2.0;
06787 }
06788
06789 if ( (init_x0 == 0) && flux_sum > hflux){
06790 init_x0 = (i+i-1)/2.0;
06791 }
06792
06793 if ( (init75 == 0) && flux_sum > flux75){
06794 init75 = (i+i-1)/2.0;
06795 break;
06796 }
06797
06798 }
06799 init_sigma = (init75-init25)/(2*0.6744);
06800 init_area = intensity*sqrt(2*M_PI*init_sigma*init_sigma);
06801
06802 xsh_msg_dbg_high("DV FIT area %f x0 %f sigma %f offset %f",
06803 init_area, init_x0, init_sigma, init_offset);
06804
06805 init_par[0] = init_area;
06806 init_par[1] = init_offset;
06807 init_par[2] = 0;
06808 init_par[3] = 0;
06809 init_par[4] = init_x0;
06810 init_par[5] = init_sigma;
06811
06812 cleanup:
06813 return;
06814 }
06815
06816
06817
06818
06819 void xsh_gsl_fit_gaussian( cpl_vector *xpos_vect, cpl_vector *ypos_vect,
06820 int deg,
06821 double *params, double *errs, int *status)
06822 {
06823 const gsl_multifit_fdfsolver_type *T;
06824 gsl_multifit_fdfsolver *s;
06825 int iter = 0;
06826 const size_t p = 6;
06827 gsl_matrix *covar = gsl_matrix_alloc (p, p);
06828 int n=0;
06829 struct data d = { n, NULL, NULL,deg};
06830 gsl_multifit_function_fdf f;
06831 gsl_vector* x = NULL;
06832 double area, offset, b, c, x0, sigma;
06833 double chi, dof, cte;
06834 int size;
06835 double *xpos = NULL;
06836 double *ypos = NULL;
06837
06838
06839 XSH_ASSURE_NOT_NULL( xpos_vect);
06840 XSH_ASSURE_NOT_NULL( ypos_vect);
06841 XSH_ASSURE_NOT_NULL( params);
06842 XSH_ASSURE_NOT_NULL( errs);
06843 XSH_ASSURE_NOT_NULL( status);
06844
06845
06846 size = cpl_vector_get_size( xpos_vect);
06847 xpos = cpl_vector_get_data( xpos_vect);
06848 ypos = cpl_vector_get_data( ypos_vect);
06849
06850 x = gsl_vector_calloc (p);
06851
06852 area = params[0];
06853 offset = params[1];
06854 b = params[2];
06855 c = params[3];
06856 x0 = params[4];
06857 sigma = params[5];
06858
06859 gsl_vector_set( x, 0, area);
06860 gsl_vector_set( x, 1, offset);
06861 gsl_vector_set( x, 2, b);
06862 gsl_vector_set( x, 3, c);
06863 gsl_vector_set( x, 4, x0);
06864 gsl_vector_set( x, 5, sigma);
06865
06866 n = size;
06867 d.n = size;
06868 d.y = ypos;
06869 d.x = xpos;
06870 d.deg = deg;
06871
06872 f.f = &expb_f;
06873 f.df = &expb_df;
06874 f.fdf = &expb_fdf;
06875 f.n = n;
06876 f.p = p;
06877 f.params = &d;
06878
06879
06880 T = gsl_multifit_fdfsolver_lmsder;
06881 s = gsl_multifit_fdfsolver_alloc (T, n, p);
06882 gsl_multifit_fdfsolver_set (s, &f, x);
06883
06884 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",
06885 iter,
06886 gsl_vector_get (s->x, 0),
06887 gsl_vector_get (s->x, 1),
06888 gsl_vector_get (s->x, 2),
06889 gsl_vector_get (s->x, 3),
06890 gsl_vector_get (s->x, 4),
06891 gsl_vector_get (s->x, 5),
06892 gsl_blas_dnrm2 (s->f));
06893 do
06894 {
06895 iter++;
06896 *status = gsl_multifit_fdfsolver_iterate (s);
06897
06898 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",
06899 iter,
06900 gsl_vector_get (s->x, 0),
06901 gsl_vector_get (s->x, 1),
06902 gsl_vector_get (s->x, 2),
06903 gsl_vector_get (s->x, 3),
06904 gsl_vector_get (s->x, 4),
06905 gsl_vector_get (s->x, 5),
06906 gsl_blas_dnrm2 (s->f));
06907
06908 if (*status)
06909 break;
06910
06911 *status = gsl_multifit_test_delta (s->dx, s->x,
06912 1e-2, 1e-2);
06913
06914 }
06915 while ( *status == GSL_CONTINUE && iter < 500);
06916
06917 gsl_multifit_covar (s->J, 0.0, covar);
06918
06919 params[0] = gsl_vector_get( s->x, 0);
06920 params[1] = gsl_vector_get( s->x, 1);
06921 params[2] = gsl_vector_get( s->x, 2);
06922 params[3] = gsl_vector_get( s->x, 3);
06923 params[4] = gsl_vector_get( s->x, 4);
06924 params[5] = gsl_vector_get( s->x, 5);
06925
06926 chi = gsl_blas_dnrm2(s->f);
06927 dof = n-p;
06928 cte = GSL_MAX_DBL(1, chi / sqrt(dof));
06929
06930 errs[0] = cte * sqrt(gsl_matrix_get(covar,0,0));
06931 errs[1] = cte * sqrt(gsl_matrix_get(covar,1,1));
06932 errs[2] = cte * sqrt(gsl_matrix_get(covar,2,2));
06933 errs[3] = cte * sqrt(gsl_matrix_get(covar,3,3));
06934 errs[4] = cte * sqrt(gsl_matrix_get(covar,4,4));
06935 errs[5] = cte * sqrt(gsl_matrix_get(covar,5,5));
06936
06937
06938 cleanup:
06939
06940 gsl_multifit_fdfsolver_free (s);
06941 gsl_matrix_free (covar);
06942 gsl_vector_free( x);
06943 return;
06944 }
06945
06946