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
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
00060
00061
00062
00063 static int XshDebugLevel = XSH_DEBUG_LEVEL_NONE ;
00064 static int XshTimeStamp = FALSE ;
00065
00066
00067
00068
00069 #define MAXIMUM(x, y) ((x) > (y)) ? (x) : (y)
00070
00071
00072 #define DEV_BLOCKSIZE 4096
00073 #define XSH_ATM_EXT_UVB_WAV_MIN 310.
00074
00082
00083
00085
00086
00087
00088
00089
00090
00091
00092
00093 #define CPL_TYPE float
00094 #define CPL_TYPE_T CPL_TYPE_FLOAT
00095 #define CPL_IMAGE_GET_DATA cpl_image_get_data_float
00096 #define CPL_IMAGE_GET_DATA_CONST cpl_image_get_data_float_const
00097 #define CPL_IMAGE_GET_MEDIAN cpl_tools_get_median_float
00098
00099
00100
00129
00130 cpl_image * xsh_imagelist_collapse_sigclip_iter_create(
00131 const cpl_imagelist * imlist,
00132 double sigma_low,
00133 double sigma_upp,
00134 const int niter)
00135
00136 {
00137 const cpl_image * cur_ima=NULL ;
00138 int ni, nx, ny ;
00139 cpl_table * time_line=NULL ;
00140 cpl_image * out_ima=NULL ;
00141 double out_val ;
00142 int nb_val ;
00143 double mean, stdev ;
00144 double low_thresh, high_thresh ;
00145 int i, j, k ;
00146
00147
00148 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
00149 cpl_ensure(cpl_imagelist_is_uniform(imlist)==0, CPL_ERROR_ILLEGAL_INPUT,
00150 NULL);
00151 cpl_ensure(sigma_low>1., CPL_ERROR_ILLEGAL_INPUT, NULL);
00152 cpl_ensure(sigma_upp>1., CPL_ERROR_ILLEGAL_INPUT, NULL);
00153 cpl_ensure(niter > 0, CPL_ERROR_NULL_INPUT, NULL);
00154
00155 ni = cpl_imagelist_get_size(imlist) ;
00156
00157 cur_ima = cpl_imagelist_get_const(imlist, 0) ;
00158 nx = cpl_image_get_size_x(cur_ima) ;
00159 ny = cpl_image_get_size_y(cur_ima) ;
00160
00161
00162
00163 time_line = cpl_table_new(ni) ;
00164
00165
00166
00167
00168
00169
00170 {
00171
00172 CPL_TYPE * pout_ima ;
00173 const CPL_TYPE * pcur_ima ;
00174 int n=0;
00175 int nbad=0;
00176 CPL_TYPE * ptime_line ;
00177
00178 cpl_table_new_column(time_line,"VAL",CPL_TYPE_T);
00179 cpl_table_fill_column_window(time_line,"VAL",0,ni,0);
00180 if (CPL_TYPE_T == CPL_TYPE_DOUBLE) {
00181 ptime_line = (CPL_TYPE*) cpl_table_get_data_double(time_line,"VAL") ;
00182 } else if (CPL_TYPE_T == CPL_TYPE_FLOAT) {
00183 ptime_line = (CPL_TYPE*) cpl_table_get_data_float(time_line,"VAL") ;
00184 } else {
00185 ptime_line = (CPL_TYPE*) cpl_table_get_data_int(time_line,"VAL") ;
00186 }
00187 out_ima = cpl_image_new(nx, ny, CPL_TYPE_T) ;
00188 pout_ima = CPL_IMAGE_GET_DATA(out_ima) ;
00189
00190 for (j=0 ; j<ny ; j++) {
00191 for (i=0 ; i<nx ; i++) {
00192
00193
00194 for (k=0 ; k<ni ; k++) {
00195 cur_ima = cpl_imagelist_get_const(imlist, k) ;
00196 pcur_ima = CPL_IMAGE_GET_DATA_CONST(cur_ima) ;
00197 ptime_line[k] = (CPL_TYPE)pcur_ima[i+j*nx] ;
00198 }
00199
00200
00201
00202 for(n=0, nbad=0;(n<niter) && (nbad<ni-1);n++) {
00203
00204 check(mean = cpl_table_get_column_mean(time_line,"VAL")) ;
00205 check(stdev = cpl_table_get_column_stdev(time_line,"VAL")) ;
00206 low_thresh = mean - sigma_low * stdev ;
00207 high_thresh = mean + sigma_upp * stdev ;
00208
00209
00210 out_val = 0.0 ;
00211 nb_val = 0 ;
00212 for (k=0 ; k<ni ; k++) {
00213 if (ptime_line[k]<=high_thresh &&
00214 ptime_line[k]>=low_thresh) {
00215
00216 } else {
00217 cpl_table_set_invalid(time_line,"VAL",k);
00218 nbad++;
00219 }
00220 }
00221 }
00222
00223 out_val = cpl_table_get_column_mean(time_line,"VAL") ;
00224
00225 pout_ima[i+j*nx] = (CPL_TYPE)out_val ;
00226 }
00227 }
00228
00229 }
00230
00231 cleanup:
00232 cpl_table_delete(time_line) ;
00233
00234
00235
00236 return out_ima ;
00237 }
00238
00239
00240
00241
00247 static double
00248 xsh_hms2deg(const double hms)
00249 {
00250 int hrs=0;
00251 int min=0;
00252 double sec=0;
00253 double deg=0;
00254 double rest=hms;
00255 int sign=1;
00256
00257 if(hms<0) {
00258 sign=-1;
00259 rest=-hms;
00260 }
00261
00262 hrs=(int)(rest/10000.);
00263 rest=rest-(double)(hrs*10000.);
00264 min=(int)(rest/100.);
00265 sec=rest-(double)(min*100.);
00266 deg=hrs*15+(double)(min/4.)+(double)(sec/240.);
00267 deg=sign*deg;
00268
00269 return deg;
00270
00271 }
00272
00273
00280 static double
00281 xsh_sess2deg(const double sess)
00282 {
00283 int grad=0;
00284 int min=0;
00285 double sec=0;
00286 double deg=0;
00287 double rest=sess;
00288 int sign=1;
00289
00290 if(sess<0) {
00291 sign=-1;
00292 rest=-sess;
00293 }
00294 grad=(int)(rest/10000.);
00295 rest=rest-(double)(grad*10000.);
00296 min=(int)(rest/100.);
00297 sec=rest-(double)(min*100.);
00298 deg=grad+(double)(min/60.)+(double)(sec/3600.);
00299 deg=sign*deg;
00300
00301 return deg;
00302
00303 }
00304
00305
00311 cpl_error_code
00312 xsh_check_input_is_unbinned(cpl_frame* in)
00313 {
00314
00315 cpl_propertylist* plist=NULL;
00316 const char* name=NULL;
00317 int binx=0;
00318 int biny=0;
00319
00320 if(in==NULL) {
00321 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
00322 return cpl_error_get_code();
00323 }
00324 name=cpl_frame_get_filename(in);
00325 plist=cpl_propertylist_load(name,0);
00326
00327 binx=xsh_pfits_get_binx(plist);
00328 biny=xsh_pfits_get_biny(plist);
00329
00330 xsh_free_propertylist(&plist);
00331 if(binx*biny > 1) {
00332 xsh_msg_error("This recipe expects unbinned input raw frames. Exit");
00333 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
00334 }
00335 return cpl_error_get_code();
00336
00337 }
00338
00339
00340
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 int xsh_fileutils_copy (const char * srcpath, const char * dstpath)
00367
00368 {
00369 char *buf;
00370
00371 int src, dst;
00372 int rbytes = 0;
00373 int wbytes = 0;
00374 int blksize = DEV_BLOCKSIZE;
00375
00376 struct stat sb, db;
00377
00378
00379
00380
00381 if ((stat(srcpath,&sb) == 0) && (stat(dstpath,&db) == 0))
00382 {
00383 if (sb.st_ino == db.st_ino)
00384 return 99;
00385 }
00386
00387 if ((src = open (srcpath, O_RDONLY)) == -1) return (-1);
00388
00389 if ((fstat (src, &sb) == -1) || (!S_ISREG (sb.st_mode)))
00390 {
00391 (void) close (src);
00392 return -2;
00393 }
00394
00395 if ((dst = open (dstpath, O_CREAT | O_WRONLY | O_TRUNC, sb.st_mode)) == -1)
00396 {
00397 (void) close (src);
00398 return -3;
00399 }
00400
00401 if ((fstat (dst, &db) == -1) || (!S_ISREG (db.st_mode)))
00402 {
00403 (void) close (src);
00404 (void) close (dst);
00405 (void) unlink (dstpath);
00406 return -4;
00407 }
00408
00409 #ifdef HAVE_ST_BLKSIZE
00410 blksize = db.st_blksize;
00411 #else
00412 # ifdef DEV_BSIZE
00413 blksize = DEV_BSIZE;
00414 # endif
00415 #endif
00416
00417 if ((buf = (char *) cpl_malloc ((size_t)blksize)) == NULL)
00418 {
00419 (void) close (src);
00420 (void) close (dst);
00421 (void) unlink (dstpath);
00422 return -5;
00423 }
00424
00425 while ((rbytes = (int) read (src, buf, (size_t)blksize)) > 0)
00426 {
00427 if ((wbytes = (int) write (dst, buf, (size_t)rbytes)) != rbytes)
00428 {
00429 wbytes = -1;
00430 break;
00431 }
00432 }
00433
00434 (void) close (src);
00435 (void) close (dst);
00436 cpl_free (buf);
00437
00438
00439 if ((rbytes == -1) || (wbytes == -1))
00440 {
00441 (void) unlink (dstpath);
00442 return -6;
00443 }
00444
00445 return 0;
00446
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 int xsh_fileutils_move (const char *srcpath, const char *dstpath)
00472
00473 {
00474 int ii;
00475
00476 struct stat sb;
00477
00478
00479
00480 if ((ii = xsh_fileutils_copy (srcpath, dstpath)) != 0)
00481 {
00482 if (ii == 99)
00483 return 99;
00484 else
00485 return (-2);
00486 }
00487
00488
00489
00490
00491
00492
00493
00494 if (stat (srcpath, &sb) == -1 || !(sb.st_mode & S_IWUSR))
00495 {
00496 (void) unlink (dstpath);
00497 return -1;
00498 }
00499
00500 (void) unlink (srcpath);
00501 return 0;
00502
00503 }
00504
00505
00506
00513
00514 char*
00515 xsh_set_recipe_file_prefix(cpl_frameset* raw,const char* recipe)
00516 {
00517
00518 cpl_frame* frm=NULL;
00519 cpl_propertylist* plist=NULL;
00520 const char* obj=NULL;
00521 char* prefix=NULL;
00522
00523 const char* dpr_catg=NULL;
00524 const char* dpr_tech=NULL;
00525 const char* dpr_type=NULL;
00526 const char* filename=NULL;
00527
00528 check(frm=cpl_frameset_get_frame(raw,0));
00529 filename=cpl_frame_get_filename(frm);
00530 plist=cpl_propertylist_load(filename,0);
00531 dpr_catg=xsh_pfits_get_dpr_catg(plist);
00532 dpr_tech=xsh_pfits_get_dpr_tech(plist);
00533 dpr_type=xsh_pfits_get_dpr_type(plist);
00534
00535 if(strstr(dpr_catg,"SCIENCE")!=NULL) {
00536 if(strstr(dpr_type,"SKY")!=NULL) {
00537 obj="SKY";
00538 } else {
00539 obj="SCI";
00540 }
00541 } else if(strstr(dpr_catg,"CALIB")!=NULL) {
00542 if(strstr(dpr_type,"FLUX")!=NULL) {
00543 obj="FLUX";
00544 } else if(strstr(dpr_type,"TELLURIC")!=NULL) {
00545 obj="TELL";
00546 } else {
00547 obj="CAL";
00548 }
00549 } else {
00550 obj="OBJ";
00551 }
00552
00553 if(strstr(recipe,"respon_slit_stare")!=NULL) {
00554 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00555 } else if(strstr(recipe,"respon_slit_offset")!=NULL) {
00556 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00557 } else if(strstr(recipe,"respon_slit_nod")!=NULL) {
00558 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00559 } else if(strstr(recipe,"scired_slit_stare")!=NULL) {
00560 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00561 } else if(strstr(recipe,"scired_slit_offset")!=NULL) {
00562 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00563 } else if(strstr(recipe,"scired_slit_nod")!=NULL) {
00564 prefix=xsh_stringcat_any(obj,"_SLIT",NULL);
00565 } else if(strstr(recipe,"scired_ifu_stare")!=NULL) {
00566 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00567 } else if(strstr(recipe,"scired_ifu_offset")!=NULL) {
00568 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00569 } else if(strstr(recipe,"geom_ifu")!=NULL) {
00570 prefix=xsh_stringcat_any(obj,"_IFU",NULL);
00571 } else {
00572 xsh_msg_warning("recipe %s not supported",recipe);
00573 prefix=xsh_stringcat_any(obj,"",NULL);
00574 }
00575
00576
00577 cleanup:
00578 xsh_free_propertylist(&plist);
00579
00580 return prefix;
00581 }
00582
00583
00589
00590 cpl_error_code xsh_set_cd_matrix(cpl_propertylist* plist)
00591 {
00592
00593 int naxis=0;
00594 naxis=xsh_pfits_get_naxis(plist);
00595 switch (naxis) {
00596
00597 case 1: xsh_set_cd_matrix1d(plist);break;
00598
00599 case 2: xsh_set_cd_matrix2d(plist);break;
00600
00601 case 3: xsh_set_cd_matrix3d(plist);break;
00602
00603 default: xsh_msg_error("Naxis: %d unsupported",naxis);
00604 }
00605
00606 return cpl_error_get_code();
00607 }
00608
00614
00615 cpl_error_code xsh_set_cd_matrix1d(cpl_propertylist* plist)
00616 {
00617 double cdelt1=xsh_pfits_get_cdelt1(plist);
00618 xsh_pfits_set_cd1(plist,cdelt1);
00619
00620 return cpl_error_get_code();
00621
00622 }
00623
00624
00625
00631
00632 cpl_error_code xsh_set_cd_matrix2d(cpl_propertylist* plist)
00633 {
00634 double cdelt1=0;
00635 double cdelt2=0;
00636
00637
00638 check(cdelt1=xsh_pfits_get_cdelt1(plist));
00639 check(cdelt2=xsh_pfits_get_cdelt2(plist));
00640 check(xsh_pfits_set_cd11(plist,cdelt1));
00641 check(xsh_pfits_set_cd12(plist,0.));
00642 check(xsh_pfits_set_cd21(plist,0.));
00643 check(xsh_pfits_set_cd22(plist,cdelt2));
00644
00645 cleanup:
00646
00647 return cpl_error_get_code();
00648
00649 }
00650
00651
00657
00658 cpl_error_code xsh_set_cd_matrix3d(cpl_propertylist* plist)
00659 {
00660
00661 double cdelt3=0;
00662 check(cdelt3=xsh_pfits_get_cdelt3(plist));
00663
00664 check(xsh_pfits_set_cd31(plist,0.));
00665 check(xsh_pfits_set_cd13(plist,0.));
00666 check(xsh_pfits_set_cd32(plist,0.));
00667 check(xsh_pfits_set_cd23(plist,0.));
00668 check(xsh_pfits_set_cd33(plist,cdelt3));
00669
00670 cleanup:
00671
00672 return cpl_error_get_code();
00673
00674 }
00675
00676
00682
00683
00684 cpl_parameterlist*
00685 xsh_parameterlist_duplicate(const cpl_parameterlist* pin){
00686
00687 cpl_parameter* p=NULL;
00688 cpl_parameterlist* pout=NULL;
00689
00690 pout=cpl_parameterlist_new();
00691 p=cpl_parameterlist_get_first((cpl_parameterlist*)pin);
00692 while (p != NULL)
00693 {
00694 cpl_parameterlist_append(pout,p);
00695 p=cpl_parameterlist_get_next((cpl_parameterlist*)pin);
00696 }
00697 return pout;
00698
00699 }
00700
00701
00702
00709
00710 static void
00711 xsh_property_dump(cpl_property *property)
00712 {
00713
00714 const char *name = cpl_property_get_name(property);
00715 const char *comment = cpl_property_get_comment(property);
00716
00717 char c;
00718
00719 long size = cpl_property_get_size(property);
00720
00721 cpl_type type = cpl_property_get_type(property);
00722
00723
00724 fprintf(stderr, "Property at address %p\n", property);
00725 fprintf(stderr, "\tname : %p '%s'\n", name, name);
00726 fprintf(stderr, "\tcomment: %p '%s'\n", comment, comment);
00727 fprintf(stderr, "\ttype : %#09x\n", type);
00728 fprintf(stderr, "\tsize : %ld\n", size);
00729 fprintf(stderr, "\tvalue : ");
00730
00731
00732 switch (type) {
00733 case CPL_TYPE_CHAR:
00734 c = cpl_property_get_char(property);
00735 if (!c)
00736 fprintf(stderr, "''");
00737 else
00738 fprintf(stderr, "'%c'", c);
00739 break;
00740
00741 case CPL_TYPE_BOOL:
00742 fprintf(stderr, "%d", cpl_property_get_bool(property));
00743 break;
00744
00745 case CPL_TYPE_INT:
00746 fprintf(stderr, "%d", cpl_property_get_int(property));
00747 break;
00748
00749 case CPL_TYPE_LONG:
00750 fprintf(stderr, "%ld", cpl_property_get_long(property));
00751 break;
00752
00753 case CPL_TYPE_FLOAT:
00754 fprintf(stderr, "%.7g", cpl_property_get_float(property));
00755 break;
00756
00757 case CPL_TYPE_DOUBLE:
00758 fprintf(stderr, "%.15g", cpl_property_get_double(property));
00759 break;
00760
00761 case CPL_TYPE_STRING:
00762 fprintf(stderr, "'%s'", cpl_property_get_string(property));
00763 break;
00764
00765 default:
00766 fprintf(stderr, "unknown.");
00767 break;
00768
00769 }
00770
00771 fprintf(stderr, "\n");
00772
00773 return;
00774
00775 }
00776
00777
00786
00787
00788 cpl_frame*
00789 xsh_frameset_average(cpl_frameset *set, const char* tag)
00790 {
00791 cpl_frame* result=NULL;
00792 cpl_frame* frame=NULL;
00793 cpl_image* image=NULL;
00794 cpl_imagelist* iml=NULL;
00795 cpl_propertylist* plist=NULL;
00796 char name_o[80];
00797 const char* name=NULL;
00798 int i=0;
00799 int size=0;
00800
00801 check(size=cpl_frameset_get_size(set));
00802 iml=cpl_imagelist_new();
00803 for(i=0;i<size;i++) {
00804 frame=cpl_frameset_get_frame(set,i);
00805 name=cpl_frame_get_filename(frame);
00806 image=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00807 cpl_imagelist_set(iml,cpl_image_duplicate(image),i);
00808 xsh_free_image(&image);
00809 }
00810 image=cpl_imagelist_collapse_create(iml);
00811 frame=cpl_frameset_get_frame(set,0);
00812 name=cpl_frame_get_filename(frame);
00813 plist=cpl_propertylist_load(name,0);
00814
00815 sprintf(name_o,"%s.fits",tag);
00816 cpl_image_save(image,name_o,CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT);
00817 result=xsh_frame_product(name_o,tag,CPL_FRAME_TYPE_IMAGE,
00818 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
00819
00820 cleanup:
00821 xsh_free_image(&image);
00822 xsh_free_imagelist(&iml);
00823 xsh_free_propertylist(&plist);
00824
00825 return result;
00826 }
00827
00828
00835 cpl_frame* xsh_frameset_add( cpl_frameset *set, xsh_instrument* instr)
00836 {
00837 int iset, i, j, set_size = 0;
00838 cpl_frame *result = NULL;
00839 xsh_pre **pre_list = NULL;
00840 xsh_pre *pre_res = NULL;
00841 float *res_flux = NULL;
00842 float *res_errs = NULL;
00843 int *res_qual = NULL;
00844 int nx, ny;
00845
00846 XSH_ASSURE_NOT_NULL( set);
00847
00848 check( set_size = cpl_frameset_get_size( set));
00849
00850 if (set_size > 0){
00851 XSH_CALLOC( pre_list, xsh_pre*, set_size);
00852
00853 for( iset=0; iset< set_size; iset++){
00854 xsh_pre* pre = NULL;
00855 cpl_frame *frame = NULL;
00856
00857 check( frame = cpl_frameset_get_frame( set, iset));
00858 check( pre = xsh_pre_load( frame, instr));
00859
00860 pre_list[iset] = pre;
00861 }
00862
00863 pre_res = xsh_pre_duplicate( pre_list[0]);
00864 nx = pre_res->nx;
00865 ny = pre_res->ny;
00866 check( res_flux = cpl_image_get_data_float( xsh_pre_get_data( pre_res)));
00867 check( res_errs = cpl_image_get_data_float( xsh_pre_get_errs( pre_res)));
00868 check( res_qual = cpl_image_get_data_int( xsh_pre_get_qual( pre_res)));
00869
00870 for( j=0; j< ny; j++){
00871 for( i=0; i< nx; i++){
00872 int good =0;
00873 float good_flux=0, bad_flux=0;
00874 float good_errs=0, bad_errs=0;
00875 int good_qual=QFLAG_GOOD_PIXEL, bad_qual=QFLAG_GOOD_PIXEL;
00876 int idx;
00877
00878 idx = i+j*nx;
00879
00880 for(iset = 0; iset < set_size; iset++){
00881 float *img_flux = NULL;
00882 float *img_errs = NULL;
00883 int *img_qual = NULL;
00884
00885 check( img_flux = cpl_image_get_data_float( xsh_pre_get_data( pre_list[iset])));
00886 check( img_errs = cpl_image_get_data_float( xsh_pre_get_errs( pre_list[iset])));
00887 check( img_qual = cpl_image_get_data_int( xsh_pre_get_qual( pre_list[iset])));
00888
00889 if ( img_qual[idx] <= XSH_GOOD_PIXEL_LEVEL){
00890 good++;
00891 good_qual|=img_qual[idx];
00892 good_flux += img_flux[idx];
00893 good_errs += img_errs[idx]*img_errs[idx];
00894 }
00895 else{
00896 bad_qual |= img_qual[idx];
00897 bad_flux += img_flux[idx];
00898 bad_errs += img_errs[idx]*img_errs[idx];
00899 }
00900 }
00901
00902 if ( good == 0){
00903 res_flux[idx] = bad_flux;
00904 res_errs[idx] = sqrt( bad_errs);
00905 res_qual[idx] |= bad_qual;
00906 }
00907 else{
00908 res_flux[idx] = good_flux*set_size/good;
00909 res_errs[idx] = sqrt( good_errs)*set_size/good;
00910 res_qual[idx] |= good_qual;
00911 }
00912 }
00913 }
00914 check( result = xsh_pre_save( pre_res, "COADD.fits", "COADD", 1));
00915
00916 }
00917 cleanup:
00918 if (cpl_error_get_code() != CPL_ERROR_NONE){
00919 xsh_free_frame( &result);
00920 }
00921 xsh_pre_free( &pre_res);
00922 for( i=0; i< set_size; i++){
00923 xsh_pre_free( &(pre_list[i]));
00924 }
00925 XSH_FREE( pre_list);
00926 return result;
00927 }
00928
00929
00930
00937
00938 void
00939 xsh_plist_dump(cpl_propertylist *plist)
00940 {
00941
00942 long i=0;
00943 long sz = cpl_propertylist_get_size(plist);
00944
00945
00946 fprintf(stderr, "Property list at address %p:\n", plist);
00947
00948 for (i = 0; i < sz; i++) {
00949 cpl_property *p = cpl_propertylist_get(plist, i);
00950 xsh_property_dump(p);
00951 }
00952
00953 return;
00954
00955 }
00956
00957
00958
00965
00966 cpl_error_code
00967 xsh_frameset_dump(cpl_frameset* set)
00968 {
00969
00970 const cpl_frame* f=NULL;
00971 int n=0;
00972 int i=0;
00973 const char* name=NULL;
00974 const char* tag=NULL;
00975 int group=0;
00976 n=cpl_frameset_get_size(set);
00977 xsh_msg("files present in set");
00978 for(i=0;i<n;i++) {
00979
00980 f=cpl_frameset_get_frame(set,i);
00981 name=cpl_frame_get_filename(f);
00982 tag=cpl_frame_get_tag(f);
00983 group=cpl_frame_get_group(f);
00984 xsh_msg("filename=%s tag=%s group=%d",name,tag,group);
00985
00986 }
00987
00988 return cpl_error_get_code();
00989
00990 }
00991
00992
00999
01000 cpl_error_code
01001 xsh_frameset_dump_nod_info(cpl_frameset* set)
01002 {
01003
01004 const cpl_frame* f=NULL;
01005 int n=0;
01006 int i=0;
01007 const char* name=NULL;
01008 const char* tag=NULL;
01009 cpl_propertylist* plist=NULL;
01010
01011 double cum_off_y=0;
01012 double nod_throw=0;
01013 double jitter_width=0;
01014
01015
01016 n=cpl_frameset_get_size(set);
01017 xsh_msg("files present in set");
01018 for(i=0;i<n;i++) {
01019
01020 f=cpl_frameset_get_frame(set,i);
01021 name=cpl_frame_get_filename(f);
01022 tag=cpl_frame_get_tag(f);
01023
01024
01025 plist=cpl_propertylist_load(name,0);
01026 if(cpl_propertylist_has(plist,XSH_NOD_CUMULATIVE_OFFSETY)) {
01027 cum_off_y=xsh_pfits_get_cumoffsety(plist);
01028 } else {
01029
01030 xsh_msg_warning("missing %s",XSH_NOD_CUMULATIVE_OFFSETY);
01031 }
01032
01033 if(cpl_propertylist_has(plist,XSH_NOD_THROW)) {
01034 nod_throw=xsh_pfits_get_nodthrow(plist);
01035 } else {
01036 xsh_msg_warning("missing %s",XSH_NOD_CUMULATIVE_OFFSETY);
01037 }
01038
01039
01040 if(cpl_propertylist_has(plist,XSH_NOD_JITTER_BOX)) {
01041 jitter_width= xsh_pfits_get_nod_jitterwidth(plist);
01042 } else {
01043 xsh_msg_warning("missing %s",XSH_NOD_JITTER_BOX);
01044 }
01045
01046
01047
01048
01049 xsh_msg("filename=%s tag=%s cum_off_y=%f nod_throw=%f jitter_width=%f",
01050 name,tag,cum_off_y,nod_throw,jitter_width);
01051 xsh_free_propertylist(&plist);
01052 }
01053
01054 return cpl_error_get_code();
01055
01056 }
01057
01058
01059
01060
01071
01072 void
01073 xsh_init (void)
01074 {
01075 xsh_error_reset ();
01076 xsh_msg_init ();
01077 }
01078
01079
01086
01087
01088 char * xsh_get_basename(const char *filename)
01089 {
01090 char *p ;
01091 p = strrchr (filename, '/');
01092 return p ? p + 1 : (char *) filename;
01093 }
01094
01095
01096
01104
01105 const char *
01106 xsh_get_license (void)
01107 {
01108 const char *xsh_license =
01109 "This file is part of the X-shooter Instrument Pipeline\n"
01110 "Copyright (C) 2006 European Southern Observatory\n"
01111 "\n"
01112 "This program is free software; you can redistribute it and/or modify\n"
01113 "it under the terms of the GNU General Public License as published by\n"
01114 "the Free Software Foundation; either version 2 of the License, or\n"
01115 "(at your option) any later version.\n"
01116 "\n"
01117 "This program is distributed in the hope that it will be useful,\n"
01118 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
01119 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
01120 "GNU General Public License for more details.\n"
01121 "\n"
01122 "You should have received a copy of the GNU General Public License\n"
01123 "along with this program; if not, write to the Free Software\n"
01124 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, \n"
01125 "MA 02111-1307 USA";
01126 return xsh_license;
01127 }
01128
01129
01155
01156 cpl_error_code
01157 xsh_begin (cpl_frameset * frames,
01158 const cpl_parameterlist * parameters,
01159 xsh_instrument ** instrument,
01160 cpl_frameset ** raws,
01161 cpl_frameset ** calib,
01162 const char * tag_list[],
01163 int tag_list_size,
01164 const char *recipe_id,
01165 unsigned int binary_version,
01166 const char *short_descr)
01167 {
01168 char *recipe_string = NULL;
01169 char *recipe_version = NULL;
01170 char *stars = NULL;
01171 char *spaces1 = NULL;
01172 char *spaces2 = NULL;
01173 char *spaces3 = NULL;
01174 char *spaces4 = NULL;
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 {
01193 int lvl, ts ;
01194
01195 lvl = xsh_parameters_get_temporary( recipe_id, parameters ) ;
01196 if ( lvl == 0 )
01197 xsh_msg( "Keep Temporary File = no" ) ;
01198 else
01199 xsh_msg( "Keep Temporary File = yes" ) ;
01200
01201 lvl = xsh_parameters_debug_level_get( recipe_id, parameters ) ;
01202 xsh_msg( "Xsh Debug Level = %s", xsh_debug_level_tostring() ) ;
01203
01204 ts = xsh_parameters_time_stamp_get( recipe_id, parameters ) ;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 {
01219 int version_string_length;
01220 int major_version, minor_version, micro_version;
01221
01222 major_version = binary_version / 10000;
01223 minor_version = (binary_version % 10000) / 100;
01224 micro_version = binary_version % 100;
01225
01226
01227 assure (major_version < 100, CPL_ERROR_UNSUPPORTED_MODE,
01228 "Major version: %d", major_version);
01229
01230 version_string_length = strlen ("XX.YY.ZZ");
01231 recipe_version = cpl_calloc (sizeof (char), version_string_length + 1);
01232
01233 snprintf (recipe_version, version_string_length + 1,
01234 "%d.%d.%d", major_version, minor_version, micro_version);
01235
01236 recipe_string =
01237 xsh_stringcat_4 ("Recipe: ", recipe_id, " ", recipe_version);
01238 }
01239
01240 {
01241 int field = MAXIMUM (strlen (PACKAGE_STRING), strlen (recipe_string));
01242 int nstars = 3 + 1 + field + 1 + 3;
01243 int nspaces1, nspaces2, nspaces3, nspaces4;
01244 int i;
01245
01246
01247 nspaces1 = (field - strlen (PACKAGE_STRING)) / 2;
01248 nspaces2 = field - strlen (PACKAGE_STRING) - nspaces1;
01249
01250 nspaces3 = (field - strlen (recipe_string)) / 2;
01251 nspaces4 = field - strlen (recipe_string) - nspaces3;
01252
01253 spaces1 = cpl_calloc (sizeof (char), nspaces1 + 1);
01254 for (i = 0; i < nspaces1; i++)
01255 spaces1[i] = ' ';
01256 spaces2 = cpl_calloc (sizeof (char), nspaces2 + 1);
01257 for (i = 0; i < nspaces2; i++)
01258 spaces2[i] = ' ';
01259 spaces3 = cpl_calloc (sizeof (char), nspaces3 + 1);
01260 for (i = 0; i < nspaces3; i++)
01261 spaces3[i] = ' ';
01262 spaces4 = cpl_calloc (sizeof (char), nspaces4 + 1);
01263 for (i = 0; i < nspaces4; i++)
01264 spaces4[i] = ' ';
01265
01266 stars = cpl_calloc (sizeof (char), nstars + 1);
01267 for (i = 0; i < nstars; i++)
01268 stars[i] = '*';
01269
01270 xsh_msg ("%s", stars);
01271 xsh_msg ("*** %s%s%s ***", spaces1, PACKAGE_STRING, spaces2);
01272 xsh_msg ("*** %s%s%s ***", spaces3, recipe_string, spaces4);
01273 xsh_msg ("%s", stars);
01274 }
01275
01276 xsh_msg (" %s", short_descr);
01277
01278 check( *instrument = xsh_dfs_set_groups( frames));
01279 check( xsh_instrument_set_recipe_id( *instrument, recipe_id));
01280 XSH_NEW_FRAMESET( *raws);
01281 XSH_NEW_FRAMESET( *calib);
01282 check( xsh_dfs_split_in_group( frames, *raws, *calib));
01283 check( xsh_dfs_filter( *raws, tag_list, tag_list_size));
01284 XSH_ASSURE_NOT_NULL( *raws);
01285 XSH_ASSURE_NOT_NULL( *instrument);
01286 xsh_dfs_files_dont_exist(frames);
01287
01288
01289 xsh_msg("RAW files");
01290 check( xsh_print_cpl_frameset( *raws));
01291 xsh_msg("CALIB files");
01292 check( xsh_print_cpl_frameset( *calib));
01293
01294 cleanup:
01295 cpl_free (recipe_string);
01296 cpl_free (recipe_version);
01297 cpl_free (stars);
01298 cpl_free (spaces1);
01299 cpl_free (spaces2);
01300 cpl_free (spaces3);
01301 cpl_free (spaces4);
01302 return cpl_error_get_code ();
01303 }
01304
01305
01306
01307 static char **TempFiles = NULL ;
01308 static int NbTemp = 0 ;
01309 static char **ProdFiles = NULL ;
01310 static int NbProducts = 0 ;
01311
01312
01319
01320 void xsh_add_temporary_file( const char *name)
01321 {
01322 if ( TempFiles == NULL ){
01323 TempFiles = cpl_malloc( sizeof( char*));
01324 }
01325 else {
01326 TempFiles = cpl_realloc( TempFiles, (NbTemp + 1)*sizeof( char *));
01327 }
01328 TempFiles[NbTemp] = cpl_malloc( strlen( name) + 1);
01329 strcpy( TempFiles[NbTemp], name);
01330 NbTemp++;
01331 }
01332
01333
01338
01339 void xsh_free_temporary_files( void)
01340 {
01341 int i;
01342
01343 for( i = 0 ; i<NbTemp ; i++){
01344 cpl_free( TempFiles[i]);
01345 }
01346 cpl_free( TempFiles);
01347 TempFiles = NULL;
01348 NbTemp=0;
01349 }
01350
01351
01358
01359 void xsh_add_product_file( const char *name)
01360 {
01361 if ( ProdFiles == NULL ){
01362 ProdFiles = cpl_malloc( sizeof( char*));
01363 }
01364 else {
01365 ProdFiles = cpl_realloc( ProdFiles, (NbProducts + 1)*sizeof( char *));
01366 }
01367 ProdFiles[NbProducts] = cpl_malloc( strlen( name) + 1);
01368 strcpy( ProdFiles[NbProducts], name);
01369 NbProducts++;
01370 }
01371
01372
01377
01378 void xsh_free_product_files( void)
01379 {
01380 int i;
01381
01382 for( i = 0 ; i<NbProducts ; i++){
01383 cpl_free( ProdFiles[i]);
01384 }
01385 cpl_free( ProdFiles);
01386 ProdFiles=NULL;
01387 NbProducts=0;
01388 }
01389
01390
01391
01404
01405 cpl_error_code
01406 xsh_end (const char *recipe_id,
01407 cpl_frameset * frames,
01408 cpl_parameterlist * parameters )
01409 {
01410 int i;
01411 int warnings = xsh_msg_get_warnings ();
01412
01413
01414 {
01415 cpl_frame * current = NULL;
01416 int nframes = 0, j;
01417
01418 nframes = cpl_frameset_get_size( frames ) ;
01419 for( j = 0 ; j<nframes ; j++ ) {
01420 current = cpl_frameset_get_frame( frames, j);
01421 if ( cpl_frame_get_group( current ) == CPL_FRAME_GROUP_PRODUCT ) {
01422 xsh_print_cpl_frame( current ) ;
01423 }
01424 }
01425 }
01426 frames = frames ;
01427
01428
01429
01430 if ( xsh_parameters_get_temporary( recipe_id, parameters ) == 0 ) {
01431 xsh_msg( "---- Deleting Temporary Files" ) ;
01432 for( i = 0 ; i<NbTemp ; i++ ) {
01433 xsh_msg( " '%s'", TempFiles[i] ) ;
01434 unlink( TempFiles[i] ) ;
01435
01436 }
01437 } else {
01438
01439
01440
01441
01442
01443
01444
01445 }
01446
01447
01448 if (warnings > 0) {
01449 xsh_msg_warning ("Recipe '%s' produced %d warning %s (excluding this one)",
01450 recipe_id, xsh_msg_get_warnings (),
01451 (warnings > 1) ? "s" : "");
01452 }
01453
01454
01455 xsh_free_temporary_files();
01456 xsh_free_product_files();
01457 return cpl_error_get_code ();
01458 }
01459
01460
01485
01486 cpl_error_code
01487 xsh_get_property_value (const cpl_propertylist * plist,
01488 const char *keyword,
01489 cpl_type keywordtype,
01490 void *result)
01491 {
01492 cpl_type t;
01493
01494
01495 assure (plist != NULL, CPL_ERROR_NULL_INPUT, "Null property list");
01496 assure (keyword != NULL, CPL_ERROR_NULL_INPUT, "Null keyword");
01497
01498 assure (cpl_propertylist_has (plist, keyword), CPL_ERROR_DATA_NOT_FOUND,
01499 "Keyword %s does not exist", keyword);
01500
01501 check_msg (t = cpl_propertylist_get_type (plist, keyword),
01502 "Could not read type of keyword '%s'", keyword);
01503 assure (t == keywordtype, CPL_ERROR_TYPE_MISMATCH,
01504 "Keyword '%s' has wrong type (%s). %s expected",
01505 keyword, xsh_tostring_cpl_type (t),
01506 xsh_tostring_cpl_type (keywordtype));
01507
01508 switch (keywordtype) {
01509 case CPL_TYPE_INT:
01510 check_msg (*((int *) result) = cpl_propertylist_get_int (plist, keyword),
01511 "Could not get (integer) value of %s", keyword);
01512 break;
01513 case CPL_TYPE_BOOL:
01514 check_msg (*((bool *) result) = cpl_propertylist_get_bool (plist, keyword),
01515 "Could not get (boolean) value of %s", keyword);
01516 break;
01517 case CPL_TYPE_DOUBLE:
01518 check_msg (*((double *) result) =
01519 cpl_propertylist_get_double (plist, keyword),
01520 "Could not get (double) value of %s", keyword);
01521 break;
01522 case CPL_TYPE_STRING:
01523 check_msg (*((const char **) result) =
01524 cpl_propertylist_get_string (plist, keyword),
01525 "Could not get (string) value of %s", keyword);
01526 break;
01527 default:
01528 assure (false, CPL_ERROR_INVALID_TYPE, "Unknown type");
01529 }
01530
01531 cleanup:
01532 return cpl_error_get_code ();
01533 }
01534
01535
01543
01544 char *
01545 xsh_stringdup (const char *s)
01546 {
01547 char *result = NULL;
01548
01549 assure (s != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01550
01551 result = cpl_calloc (sizeof (char), strlen (s) + 1);
01552 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01553 "Memory allocation failed");
01554
01555 sprintf (result, "%s", s);
01556
01557 cleanup:
01558 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01559 cpl_free (result);
01560 result = NULL;
01561 }
01562
01563 return result;
01564 }
01565
01577 char *
01578 xsh_sdate_utc( time_t *now )
01579 {
01580 char *date = NULL;
01581 struct tm ttm;
01582
01583 ttm = *gmtime( now ) ;
01584 XSH_CALLOC( date, char, 16);
01585
01586 sprintf( date, "%04d%02d%02d-%02d%02d%02d",
01587 ttm.tm_year+1900, ttm.tm_mon+1, ttm.tm_mday,
01588 ttm.tm_hour, ttm.tm_min, ttm.tm_sec ) ;
01589
01590 cleanup:
01591 return date ;
01592
01593 }
01594
01595
01604
01605 char *
01606 xsh_stringcat (const char *s1, const char *s2)
01607 {
01608 char *result = NULL;
01609
01610 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01611 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01612
01613 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + 1);
01614 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01615 "Memory allocation failed");
01616
01617 sprintf (result, "%s%s", s1, s2);
01618
01619 cleanup:
01620 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01621 cpl_free (result);
01622 result = NULL;
01623 }
01624
01625 return result;
01626 }
01627
01628
01638
01639 char *
01640 xsh_stringcat_3 (const char *s1, const char *s2, const char *s3)
01641 {
01642 char *result = NULL;
01643
01644 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01645 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01646 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01647
01648 result =
01649 cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) + strlen (s3) + 1);
01650 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01651 "Memory allocation failed");
01652
01653 sprintf (result, "%s%s%s", s1, s2, s3);
01654
01655 cleanup:
01656 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01657 cpl_free (result);
01658 result = NULL;
01659 }
01660
01661 return result;
01662 }
01663
01664
01676
01677 char *
01678 xsh_stringcat_4 (const char *s1, const char *s2, const char *s3,const char *s4)
01679 {
01680 char *result = NULL;
01681
01682 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01683 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01684 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01685 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01686
01687 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01688 strlen (s3) + strlen (s4) + 1);
01689 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01690 "Memory allocation failed");
01691
01692 sprintf (result, "%s%s%s%s", s1, s2, s3, s4);
01693
01694 cleanup:
01695 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01696 cpl_free (result);
01697 result = NULL;
01698 }
01699
01700 return result;
01701 }
01702
01703
01716
01717 char *
01718 xsh_stringcat_5 (const char *s1, const char *s2, const char *s3,
01719 const char *s4, const char *s5)
01720 {
01721 char *result = NULL;
01722
01723 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01724 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01725 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01726 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01727 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01728
01729 result = cpl_calloc (sizeof (char), strlen (s1) + strlen (s2) +
01730 strlen (s3) +strlen (s4) + strlen (s5) + 1);
01731 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01732 "Memory allocation failed");
01733
01734 sprintf (result, "%s%s%s%s%s", s1, s2, s3, s4, s5);
01735
01736 cleanup:
01737 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01738 cpl_free (result);
01739 result = NULL;
01740 }
01741
01742 return result;
01743 }
01744
01745
01760
01761 char *
01762 xsh_stringcat_6 (const char *s1, const char *s2, const char *s3,
01763 const char *s4, const char *s5, const char *s6)
01764 {
01765 char *result = NULL;
01766
01767 assure (s1 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01768 assure (s2 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01769 assure (s3 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01770 assure (s4 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01771 assure (s5 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01772 assure (s6 != NULL, CPL_ERROR_NULL_INPUT, "Null string");
01773
01774 result = cpl_calloc (sizeof (char),
01775 strlen (s1) + strlen (s2) + strlen (s3) +
01776 strlen (s4) + strlen (s5) + strlen (s6) + 1);
01777 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01778 "Memory allocation failed");
01779
01780 sprintf (result, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6);
01781
01782 cleanup:
01783 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01784 cpl_free (result);
01785 result = NULL;
01786 }
01787
01788 return result;
01789 }
01790
01803 char *
01804 xsh_stringcat_any (const char *s, ...)
01805 {
01806 char *result = NULL;
01807 int size = 2;
01808 va_list av;
01809
01810 va_start (av, s);
01811 result = cpl_malloc (2);
01812 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01813 "Memory allocation failed");
01814 result[0] = '\0';
01815 for (;;) {
01816 size += strlen (s) + 2;
01817 result = cpl_realloc (result, size);
01818 assure (result != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
01819 "Memory allocation failed");
01820 strcat (result, s);
01821 s = va_arg (av, char *);
01822 if (s == NULL || *s == '\0')
01823 break;
01824 }
01825
01826 cleanup:
01827 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01828 cpl_free (result);
01829 result = NULL;
01830 }
01831
01832 va_end (av);
01833 return result;
01834 }
01835
01836
01844
01845 int* xsh_sort(void* base, size_t nmemb, size_t size,
01846 int (*compar)(const void *, const void *)) {
01847
01848 int i = 0;
01849 int * idx = NULL;
01850 xsh_sort_data* sort = NULL;
01851
01852
01853 XSH_ASSURE_NOT_NULL(base);
01854 XSH_ASSURE_NOT_ILLEGAL(nmemb > 0);
01855 XSH_ASSURE_NOT_ILLEGAL(size > 0);
01856 XSH_ASSURE_NOT_NULL(compar);
01857
01858
01859 XSH_MALLOC(idx,int,nmemb);
01860 XSH_MALLOC(sort,xsh_sort_data,nmemb);
01861
01862
01863 for( i=0; i< (int)nmemb; i++) {
01864 sort[i].data = (void*)((size_t)base+i*size);
01865 sort[i].idx = i;
01866 }
01867
01868
01869 qsort(sort,nmemb,sizeof(xsh_sort_data),compar);
01870
01871
01872 for( i=0; i< (int)nmemb; i++) {
01873 idx[i] = sort[i].idx;
01874 }
01875
01876 cleanup:
01877 XSH_FREE(sort);
01878 return idx;
01879 }
01880
01887 void xsh_reindex(double* data, int* idx, int size) {
01888 int i;
01889
01890
01891 XSH_ASSURE_NOT_NULL(data);
01892 XSH_ASSURE_NOT_NULL(idx);
01893 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01894
01895 for(i=0; i< size; i++){
01896 int id;
01897 double temp;
01898
01899 id = idx[i];
01900 while (id < i){
01901 id = idx[id];
01902 }
01903 temp = data[i];
01904 data[i] = data[id];
01905 data[id] = temp;
01906 }
01907 cleanup:
01908 return;
01909 }
01910
01917 void xsh_reindex_float(float * data, int* idx, int size)
01918 {
01919 int i;
01920
01921
01922 XSH_ASSURE_NOT_NULL(data);
01923 XSH_ASSURE_NOT_NULL(idx);
01924 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01925
01926 for(i=0; i< size; i++){
01927 int id;
01928 float temp;
01929
01930 id = idx[i];
01931 while (id < i){
01932 id = idx[id];
01933 }
01934 temp = data[i];
01935 data[i] = data[id];
01936 data[id] = temp;
01937 }
01938 cleanup:
01939 return;
01940 }
01941
01942
01949 void xsh_reindex_int( int * data, int* idx, int size)
01950 {
01951 int i;
01952
01953
01954 XSH_ASSURE_NOT_NULL(data);
01955 XSH_ASSURE_NOT_NULL(idx);
01956 XSH_ASSURE_NOT_ILLEGAL(size >= 0);
01957
01958 for(i=0; i< size; i++){
01959 int id;
01960 int temp;
01961
01962 id = idx[i];
01963 while (id < i){
01964 id = idx[id];
01965 }
01966 temp = data[i];
01967 data[i] = data[id];
01968 data[id] = temp;
01969 }
01970 cleanup:
01971 return;
01972 }
01973
01974
01975
01980
01981 void xsh_free(const void *mem)
01982 {
01983 cpl_free((void *)mem);
01984 return;
01985 }
01986
01987
01988
01993
01994 void
01995 xsh_free_image (cpl_image ** i)
01996 {
01997 if (i && *i) {
01998 cpl_image_delete (*i);
01999 *i = NULL;
02000 }
02001 }
02002
02003
02004
02005
02010
02011 void
02012 xsh_free_table (cpl_table ** t)
02013 {
02014 if (t && *t) {
02015 cpl_table_delete (*t);
02016 *t = NULL;
02017 }
02018 }
02019
02020
02021
02026
02027 void
02028 xsh_free_mask (cpl_mask ** m)
02029 {
02030 if (m && *m) {
02031 cpl_mask_delete (*m);
02032 *m = NULL;
02033 }
02034 }
02035
02036
02041
02042 void
02043 xsh_free_imagelist (cpl_imagelist ** i)
02044 {
02045 if (i && *i) {
02046 cpl_imagelist_delete (*i);
02047 *i = NULL;
02048 }
02049 }
02050
02051
02056
02057 void
02058 xsh_free_propertylist (cpl_propertylist ** p)
02059 {
02060 if (p && *p) {
02061 cpl_propertylist_delete (*p);
02062 *p = NULL;
02063 }
02064 }
02065
02066
02071
02072 void
02073 xsh_free_polynomial (cpl_polynomial ** p)
02074 {
02075 if (p && *p) {
02076 cpl_polynomial_delete (*p);
02077 *p = NULL;
02078 }
02079 }
02080
02081
02086
02087 void
02088 xsh_free_matrix (cpl_matrix ** m)
02089 {
02090 if (m && *m) {
02091 cpl_matrix_delete (*m);
02092 *m = NULL;
02093 }
02094 }
02095
02096
02101
02102 void
02103 xsh_free_parameterlist (cpl_parameterlist ** p)
02104 {
02105 if (p && *p) {
02106 cpl_parameterlist_delete (*p);
02107 *p = NULL;
02108 }
02109 }
02110
02111
02116
02117 void
02118 xsh_free_parameter (cpl_parameter ** p)
02119 {
02120 if (p && *p) {
02121 cpl_parameter_delete (*p);
02122 *p = NULL;
02123 }
02124 }
02125
02126
02131
02132 void
02133 xsh_free_frameset (cpl_frameset ** f)
02134 {
02135 if (f && *f) {
02136 cpl_frameset_delete (*f);
02137 *f = NULL;
02138 }
02139 }
02140
02141
02146
02147 void
02148 xsh_free_frame (cpl_frame ** f)
02149 {
02150 if (f && *f) {
02151 cpl_frame_delete (*f);
02152 *f = NULL;
02153 }
02154 }
02155
02156
02161
02162 void
02163 xsh_free_vector (cpl_vector ** v)
02164 {
02165 if (v && *v) {
02166 cpl_vector_delete (*v);
02167 *v = NULL;
02168 }
02169 }
02170
02171
02176
02177 void
02178 xsh_free_array (cpl_array ** m)
02179 {
02180 if (m && *m) {
02181 cpl_array_delete (*m);
02182 *m = NULL;
02183 }
02184 }
02185
02186
02191
02192 void
02193 xsh_free_stats (cpl_stats ** s)
02194 {
02195 if (s && *s) {
02196 cpl_stats_delete (*s);
02197 *s = NULL;
02198 }
02199 }
02200
02201
02208
02209 void xsh_unwrap_image( cpl_image **i)
02210 {
02211 if ( i && *i) {
02212 cpl_image_unwrap( *i);
02213 *i = NULL;
02214 }
02215 }
02216
02217
02222
02223 void
02224 xsh_unwrap_vector (cpl_vector ** v)
02225 {
02226 if (v && *v) {
02227 cpl_vector_unwrap (*v);
02228 *v = NULL;
02229 }
02230 }
02231
02232
02237
02238 void
02239 xsh_unwrap_bivector_vectors (cpl_bivector ** b)
02240 {
02241 if (b && *b) {
02242 cpl_bivector_unwrap_vectors (*b);
02243 *b = NULL;
02244 }
02245 }
02246
02247
02252 void xsh_show_time( const char *comment )
02253 {
02254 struct rusage tm0 ;
02255
02256 getrusage( 0, &tm0 ) ;
02257 xsh_msg( "%s - User: %u.%06u - Syst: %u.%06u",
02258 comment, (unsigned)tm0.ru_utime.tv_sec,
02259 (unsigned)tm0.ru_utime.tv_usec,
02260 (unsigned)tm0.ru_stime.tv_sec,
02261 (unsigned)tm0.ru_stime.tv_usec ) ;
02262 return ;
02263 }
02264
02265
02266 #define XSH_DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
02267 #define XSH_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; }
02268 #define XSH_INT_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; }
02269
02270 #define XSH_PIX_STACK_SIZE 50
02271
02272
02273
02283 void
02284 xsh_tools_get_statistics(double* tab, int size, double* median,
02285 double* mean, double* stdev)
02286 {
02287 cpl_vector* tab_vec = NULL;
02288 int i = 0;
02289
02290
02291 XSH_ASSURE_NOT_NULL( tab);
02292 XSH_ASSURE_NOT_ILLEGAL( size >= 0);
02293 XSH_ASSURE_NOT_NULL( median);
02294 XSH_ASSURE_NOT_NULL( mean);
02295 XSH_ASSURE_NOT_NULL( stdev);
02296
02297
02298 check (tab_vec = cpl_vector_new( size));
02299 for( i=0; i< size; i++){
02300 check( cpl_vector_set( tab_vec, i, tab[i]));
02301 }
02302
02303 check( *median = cpl_vector_get_median( tab_vec));
02304 check( *stdev = cpl_vector_get_stdev( tab_vec));
02305 check( *mean = cpl_vector_get_mean( tab_vec));
02306
02307 cleanup:
02308 xsh_free_vector( &tab_vec);
02309 return;
02310 }
02322
02323 cpl_error_code
02324 xsh_tools_sort_double( double * pix_arr, int n )
02325 {
02326 int i, ir, j, k, l;
02327 int * i_stack ;
02328 int j_stack ;
02329 double a ;
02330
02331
02332 if ( pix_arr == NULL ) {
02333 return CPL_ERROR_NULL_INPUT ;
02334 }
02335
02336 ir = n ;
02337 l = 1 ;
02338 j_stack = 0 ;
02339 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02340 for (;;) {
02341 if (ir-l < 7) {
02342 for (j=l+1 ; j<=ir ; j++) {
02343 a = pix_arr[j-1];
02344 for (i=j-1 ; i>=1 ; i--) {
02345 if (pix_arr[i-1] <= a) break;
02346 pix_arr[i] = pix_arr[i-1];
02347 }
02348 pix_arr[i] = a;
02349 }
02350 if (j_stack == 0) break;
02351 ir = i_stack[j_stack-- -1];
02352 l = i_stack[j_stack-- -1];
02353 } else {
02354 k = (l+ir) >> 1;
02355 XSH_DOUBLE_SWAP(pix_arr[k-1], pix_arr[l])
02356 if (pix_arr[l] > pix_arr[ir-1]) {
02357 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[ir-1])
02358 }
02359 if (pix_arr[l-1] > pix_arr[ir-1]) {
02360 XSH_DOUBLE_SWAP(pix_arr[l-1], pix_arr[ir-1])
02361 }
02362 if (pix_arr[l] > pix_arr[l-1]) {
02363 XSH_DOUBLE_SWAP(pix_arr[l], pix_arr[l-1])
02364 }
02365 i = l+1;
02366 j = ir;
02367 a = pix_arr[l-1];
02368 for (;;) {
02369 do i++; while (pix_arr[i-1] < a);
02370 do j--; while (pix_arr[j-1] > a);
02371 if (j < i) break;
02372 XSH_DOUBLE_SWAP(pix_arr[i-1], pix_arr[j-1]);
02373 }
02374 pix_arr[l-1] = pix_arr[j-1];
02375 pix_arr[j-1] = a;
02376 j_stack += 2;
02377 if (j_stack > XSH_PIX_STACK_SIZE) {
02378
02379 cpl_free(i_stack);
02380 return CPL_ERROR_ILLEGAL_INPUT ;
02381 }
02382 if (ir-i+1 >= j-l) {
02383 i_stack[j_stack-1] = ir;
02384 i_stack[j_stack-2] = i;
02385 ir = j-1;
02386 } else {
02387 i_stack[j_stack-1] = j-1;
02388 i_stack[j_stack-2] = l;
02389 l = i;
02390 }
02391 }
02392 }
02393 cpl_free(i_stack) ;
02394 return CPL_ERROR_NONE ;
02395 }
02396
02397
02409
02410 cpl_error_code
02411 xsh_tools_sort_float( float * pix_arr, int n )
02412 {
02413 int i, ir, j, k, l;
02414 int * i_stack ;
02415 int j_stack ;
02416 float a ;
02417
02418
02419 if ( pix_arr == NULL ) {
02420 return CPL_ERROR_NULL_INPUT ;
02421 }
02422
02423 ir = n ;
02424 l = 1 ;
02425 j_stack = 0 ;
02426 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(float)) ;
02427 for (;;) {
02428 if (ir-l < 7) {
02429 for (j=l+1 ; j<=ir ; j++) {
02430 a = pix_arr[j-1];
02431 for (i=j-1 ; i>=1 ; i--) {
02432 if (pix_arr[i-1] <= a) break;
02433 pix_arr[i] = pix_arr[i-1];
02434 }
02435 pix_arr[i] = a;
02436 }
02437 if (j_stack == 0) break;
02438 ir = i_stack[j_stack-- -1];
02439 l = i_stack[j_stack-- -1];
02440 } else {
02441 k = (l+ir) >> 1;
02442 XSH_FLOAT_SWAP(pix_arr[k-1], pix_arr[l])
02443 if (pix_arr[l] > pix_arr[ir-1]) {
02444 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[ir-1])
02445 }
02446 if (pix_arr[l-1] > pix_arr[ir-1]) {
02447 XSH_FLOAT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02448 }
02449 if (pix_arr[l] > pix_arr[l-1]) {
02450 XSH_FLOAT_SWAP(pix_arr[l], pix_arr[l-1])
02451 }
02452 i = l+1;
02453 j = ir;
02454 a = pix_arr[l-1];
02455 for (;;) {
02456 do i++; while (pix_arr[i-1] < a);
02457 do j--; while (pix_arr[j-1] > a);
02458 if (j < i) break;
02459 XSH_FLOAT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02460 }
02461 pix_arr[l-1] = pix_arr[j-1];
02462 pix_arr[j-1] = a;
02463 j_stack += 2;
02464 if (j_stack > XSH_PIX_STACK_SIZE) {
02465
02466 cpl_free(i_stack);
02467 return CPL_ERROR_ILLEGAL_INPUT ;
02468 }
02469 if (ir-i+1 >= j-l) {
02470 i_stack[j_stack-1] = ir;
02471 i_stack[j_stack-2] = i;
02472 ir = j-1;
02473 } else {
02474 i_stack[j_stack-1] = j-1;
02475 i_stack[j_stack-2] = l;
02476 l = i;
02477 }
02478 }
02479 }
02480 cpl_free(i_stack) ;
02481 return CPL_ERROR_NONE ;
02482 }
02483
02484
02495 cpl_error_code
02496 xsh_tools_sort_int( int * pix_arr, int n)
02497 {
02498 int i, ir, j, k, l;
02499 int * i_stack ;
02500 int j_stack ;
02501 int a ;
02502
02503
02504 if ( pix_arr == NULL ) {
02505 return CPL_ERROR_NULL_INPUT ;
02506 }
02507
02508 ir = n ;
02509 l = 1 ;
02510 j_stack = 0 ;
02511 i_stack = cpl_malloc(XSH_PIX_STACK_SIZE * sizeof(double)) ;
02512 for (;;) {
02513 if (ir-l < 7) {
02514 for (j=l+1 ; j<=ir ; j++) {
02515 a = pix_arr[j-1];
02516 for (i=j-1 ; i>=1 ; i--) {
02517 if (pix_arr[i-1] <= a) break;
02518 pix_arr[i] = pix_arr[i-1];
02519 }
02520 pix_arr[i] = a;
02521 }
02522 if (j_stack == 0) break;
02523 ir = i_stack[j_stack-- -1];
02524 l = i_stack[j_stack-- -1];
02525 } else {
02526 k = (l+ir) >> 1;
02527 XSH_INT_SWAP(pix_arr[k-1], pix_arr[l])
02528 if (pix_arr[l] > pix_arr[ir-1]) {
02529 XSH_INT_SWAP(pix_arr[l], pix_arr[ir-1])
02530 }
02531 if (pix_arr[l-1] > pix_arr[ir-1]) {
02532 XSH_INT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02533 }
02534 if (pix_arr[l] > pix_arr[l-1]) {
02535 XSH_INT_SWAP(pix_arr[l], pix_arr[l-1])
02536 }
02537 i = l+1;
02538 j = ir;
02539 a = pix_arr[l-1];
02540 for (;;) {
02541 do i++; while (pix_arr[i-1] < a);
02542 do j--; while (pix_arr[j-1] > a);
02543 if (j < i) break;
02544 XSH_INT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02545 }
02546 pix_arr[l-1] = pix_arr[j-1];
02547 pix_arr[j-1] = a;
02548 j_stack += 2;
02549 if (j_stack > XSH_PIX_STACK_SIZE) {
02550
02551 cpl_free(i_stack);
02552 return CPL_ERROR_ILLEGAL_INPUT ;
02553 }
02554 if (ir-i+1 >= j-l) {
02555 i_stack[j_stack-1] = ir;
02556 i_stack[j_stack-2] = i;
02557 ir = j-1;
02558 } else {
02559 i_stack[j_stack-1] = j-1;
02560 i_stack[j_stack-2] = l;
02561 l = i;
02562 }
02563 }
02564 }
02565 cpl_free(i_stack) ;
02566 return CPL_ERROR_NONE ;
02567 }
02568
02584 double xsh_tools_get_median_double( double *array, int size )
02585 {
02586 double result = 0. ;
02587
02588
02589 xsh_tools_sort_double( array, size ) ;
02590
02591
02592 if ( (size % 2) == 1 ) result = *(array+(size/2)) ;
02593 else {
02594 double min, max ;
02595
02596 min = *(array+(size/2)-1) ;
02597 max = *(array+(size/2) ) ;
02598 result = (min+max)/2. ;
02599 }
02600
02601 return result ;
02602 }
02603
02610 int
02611 xsh_tools_running_median_1d_get_max( double * tab, int size, int wsize )
02612 {
02613 int position = 0;
02614 int i ;
02615 double * wtab = NULL ;
02616 double max = -1000000. ;
02617
02618 XSH_ASSURE_NOT_NULL( tab ) ;
02619 XSH_MALLOC( wtab, double, (wsize*2)*2 ) ;
02620
02621
02622
02623
02624
02625
02626
02627
02628 for( i = wsize ; i<(size-wsize) ; i++ ) {
02629 int j, k ;
02630 double f_max;
02631
02632
02633 for( k=0, j = i-wsize ; j<=(i+wsize) ; j++, k++ ) {
02634 wtab[k] = tab[j] ;
02635
02636 }
02637 if ( (f_max=xsh_tools_get_median_double(wtab, (wsize*2) + 1)) > max ) {
02638 max = f_max ;
02639 position = i ;
02640 }
02641 }
02642
02643
02644 cleanup:
02645 XSH_FREE( wtab ) ;
02646 return position ;
02647 }
02648
02649
02650
02659
02660
02661
02662 void xsh_tools_min_max(int size, double *tab, double *min, double *max)
02663 {
02664
02665 int i;
02666
02667 XSH_ASSURE_NOT_NULL(tab);
02668 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02669 XSH_ASSURE_NOT_NULL(min);
02670 XSH_ASSURE_NOT_NULL(max);
02671
02672 *min = tab[0];
02673 *max = tab[0];
02674
02675 for(i=1; i < size; i++) {
02676 if (tab[i] < *min){
02677 *min = tab[i];
02678 }
02679 else if ( tab[i] > *max) {
02680 *max = tab[i];
02681 }
02682 }
02683
02684 cleanup:
02685 return;
02686 }
02687
02699 cpl_vector* xsh_tools_tchebitchev_poly_eval( int n, double X)
02700 {
02701 cpl_vector *result = NULL;
02702
02703 XSH_ASSURE_NOT_ILLEGAL( n >=0);
02704 check( result = cpl_vector_new( n+1));
02705 check( cpl_vector_set(result, 0, 1.0));
02706
02707 if (n > 0){
02708 int indice = 2;
02709 check( cpl_vector_set(result, 1, X));
02710 while( indice <= n){
02711 double T_indice = 0.0;
02712 double T_indice_1 = 0.0;
02713 double T_indice_2 = 0.0;
02714
02715 check( T_indice_1 = cpl_vector_get( result, indice-1));
02716 check( T_indice_2 = cpl_vector_get( result, indice-2));
02717 T_indice = 2*X*T_indice_1-T_indice_2;
02718 check( cpl_vector_set( result, indice, T_indice));
02719 indice++;
02720 }
02721 }
02722 cleanup:
02723 if ( cpl_error_get_code() != CPL_ERROR_NONE){
02724 xsh_free_vector( &result);
02725 }
02726 return result;
02727 }
02728
02729
02730
02740
02741
02742
02743 void
02744 xsh_tools_tchebitchev_transform_tab(int size, double* pos, double min,
02745 double max, double* tcheb_pos)
02746 {
02747 int i;
02748 double a,b;
02749
02750 XSH_ASSURE_NOT_NULL(pos);
02751 XSH_ASSURE_NOT_NULL(tcheb_pos);
02752 XSH_ASSURE_NOT_ILLEGAL(size > 0);
02753 XSH_ASSURE_NOT_ILLEGAL(min < max);
02754
02755 a = 2/ (max-min);
02756 b = 1-2*max/(max-min);
02757
02758 for(i=0; i < size; i++) {
02759 tcheb_pos[i] = pos[i]*a+b;
02760 if ( tcheb_pos[i] < -1. ) tcheb_pos[i] = -1. ;
02761 if ( tcheb_pos[i] > 1. ) tcheb_pos[i] = 1. ;
02762 }
02763
02764 cleanup:
02765 return;
02766 }
02767
02768
02769
02777
02778
02779 double
02780 xsh_tools_tchebitchev_transform(double pos, double min, double max)
02781 {
02782 double a,b;
02783 double res = 0.0;
02784
02785 XSH_ASSURE_NOT_ILLEGAL(min < max);
02786
02787 a = 2/ (max-min);
02788 b = 1-2*max/(max-min);
02789
02790 res = pos*a+b;
02791 if(res <= -1.000001) {
02792 xsh_msg_dbg_medium("OUT_OF_RANGE res <= -1.000001 for %f [%f,%f]",
02793 pos, min , max);
02794 }
02795 if(res >= +1.000001) {
02796 xsh_msg_dbg_medium("OUT_OF_RANGE res >= +1.000001 for %f [%f,%f]",
02797 pos, min , max);
02798 }
02799
02800
02801
02802
02803 cleanup:
02804 return res;
02805 }
02806
02807
02815
02816 double
02817 xsh_tools_tchebitchev_reverse_transform(double pos, double min, double max)
02818 {
02819 double a,b;
02820 double res = 0.0;
02821
02822 XSH_ASSURE_NOT_ILLEGAL(min < max);
02823
02824 a = 2/ (max-min);
02825 b = 1-2*max/(max-min);
02826
02827 res = (pos-b)/a;
02828
02829 cleanup:
02830 return res;
02831 }
02832
02833
02834
02841
02842 void
02843 xsh_image_fit_spline(cpl_image* img, xsh_grid* grid)
02844 {
02845 int nx, ny;
02846 int i = 0, ja, jb, idx = 0, vxsize, size;
02847 double *data = NULL;
02848 int *ylines = NULL;
02849 int *xline = NULL;
02850 double *vline = NULL;
02851 int nbylines;
02852 xsh_grid_point *pointA = NULL;
02853 xsh_grid_point *pointB = NULL;
02854
02855
02856 XSH_ASSURE_NOT_NULL( img);
02857 XSH_ASSURE_NOT_NULL( grid);
02858 XSH_ASSURE_NOT_ILLEGAL( cpl_image_get_type(img) == CPL_TYPE_DOUBLE);
02859
02860 check( data = cpl_image_get_data_double(img));
02861 check( nx = cpl_image_get_size_x(img));
02862 check( ny = cpl_image_get_size_y(img));
02863 check( size = xsh_grid_get_index(grid));
02864
02865 ja = 0;
02866 jb = ja+1;
02867 nbylines = 0;
02868 vxsize = 0;
02869
02870 XSH_MALLOC( ylines, int, ny);
02871 XSH_MALLOC( xline, int, nx);
02872 XSH_MALLOC( vline, double, nx);
02873
02874
02875 while( jb < size) {
02876 double a = 0.0, b = 0.0;
02877 int cur_y;
02878
02879 nbylines++;
02880 vxsize = 1;
02881
02882 check( pointA = xsh_grid_point_get( grid, ja));
02883 check( pointB = xsh_grid_point_get( grid, jb));
02884
02885 cur_y = pointA->y-1;
02886 ylines[nbylines-1]= cur_y;
02887 xline[vxsize-1] = pointA->x-1;
02888 vline[vxsize-1] = pointA->v;
02889
02890 while( ( jb < size) && ( pointA->y == pointB->y) ){
02891 check( pointB = xsh_grid_point_get( grid, jb));
02892
02893 if ( (pointB->x-1) != xline[vxsize-1]){
02894 xline[vxsize] = pointB->x-1;
02895 vline[vxsize] = pointB->v;
02896 vxsize++;
02897 }
02898 jb++;
02899 }
02900 XSH_ASSURE_NOT_ILLEGAL( vxsize >=2);
02901
02902 for(idx=0; idx<vxsize-1; idx++){
02903 int nbpix = 0;
02904 int xa, xb;
02905 double va, vb;
02906
02907 xa = xline[idx];
02908 xb = xline[idx+1];
02909
02910 va = vline[idx];
02911 vb = vline[idx+1];
02912
02913 a = ( vb - va) / ( xb - xa);
02914 b = va-a*xa;
02915
02916 nbpix = xb-xa;
02917
02918 for(i=0; i<= nbpix; i++){
02919 data[xa+i+cur_y*nx] = a*(xa+i)+b;
02920 }
02921 }
02922 ja=jb;
02923 jb=ja+1;
02924 }
02925
02926
02927 xsh_msg("interpolate in Y ");
02928
02929 for( ja=0; ja< nbylines-1; ja++) {
02930 int line1 = ylines[ja];
02931 int line2 = ylines[ja+1];
02932
02933 for(i=0; i< nx; i++){
02934 double val1 = data[i+line1*nx];
02935 double val2 = data[i+line2*nx];
02936 double a = (val2-val1)/(line2-line1);
02937 double b = val1;
02938 int k;
02939
02940 for(k=line1+1; k < line2; k++){
02941 data[i+k*nx] = a*(k-line1)+b;
02942 }
02943 }
02944 }
02945
02946 cleanup:
02947 XSH_FREE( ylines);
02948 XSH_FREE( xline);
02949 XSH_FREE( vline);
02950 return;
02951 }
02952
02953
02962
02963 void
02964 xsh_vector_fit_gaussian( cpl_vector * x,
02965 cpl_vector * y,
02966 XSH_GAUSSIAN_FIT * result )
02967 {
02968 XSH_ASSURE_NOT_NULL( x ) ;
02969 XSH_ASSURE_NOT_NULL( y ) ;
02970 XSH_ASSURE_NOT_NULL( result ) ;
02971
02972 cpl_vector_fit_gaussian( x, NULL, y, NULL, CPL_FIT_ALL, &result->peakpos,
02973 &result->sigma,
02974 &result->area, &result->offset, &result->mse,
02975 NULL, NULL ) ;
02976 cleanup:
02977 return ;
02978 }
02979
02980
02987
02988 int xsh_debug_level_set( int level )
02989 {
02990 int prev = XshDebugLevel ;
02991
02992 XshDebugLevel = level ;
02993
02994 return prev ;
02995 }
02996
02997
03003
03004 int
03005 xsh_debug_level_get( void )
03006 {
03007 return XshDebugLevel ;
03008 }
03009
03010
03016
03017 const char *
03018 xsh_debug_level_tostring( void )
03019 {
03020 switch ( XshDebugLevel ) {
03021 case XSH_DEBUG_LEVEL_NONE:
03022 return "none" ;
03023 case XSH_DEBUG_LEVEL_LOW:
03024 return "low" ;
03025 case XSH_DEBUG_LEVEL_MEDIUM:
03026 return "medium" ;
03027 case XSH_DEBUG_LEVEL_HIGH:
03028 return "high" ;
03029 default:
03030 return "unknown" ;
03031 }
03032 }
03033
03040
03041 int
03042 xsh_time_stamp_set( int ts )
03043 {
03044 int prev = XshTimeStamp ;
03045
03046 XshTimeStamp = ts ;
03047
03048 return prev ;
03049 }
03050
03051
03057
03058 int
03059 xsh_time_stamp_get( void )
03060 {
03061 return XshTimeStamp ;
03062 }
03063
03070 void
03071 xsh_mem_dump( const char * prompt)
03072 {
03073 fprintf( stderr, "\n******** %s *******\n", prompt ) ;
03074 cpl_memory_dump() ;
03075 }
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090 double
03091 convert_bin_to_data( double bin_data, int binning)
03092 {
03093 return (bin_data*binning-0.5*(binning-1));
03094 }
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 double
03109 convert_data_to_bin( double data, int binning)
03110 {
03111 return (data+0.5*(binning-1))/binning;
03112 }
03113
03114
03115
03116
03117 static double
03118 date_to_double( const char * the_date )
03119 {
03120 int yy, mm, dd, hh, min, sec, millis ;
03121 int date, temps ;
03122 double fdate = 0 ;
03123
03124
03125 XSH_ASSURE_NOT_NULL( the_date ) ;
03126
03127 sscanf( the_date, "%d%*c%d%*c%d%*c%d%*c%d%*c%d%*c%d",
03128 &yy, &mm, &dd, &hh, &min, &sec, &millis ) ;
03129
03130 date = yy*10000 + mm*100 + dd ;
03131 temps = hh*10000000 + min*100000 + sec*1000 + millis ;
03132 fdate = (double)date + (double)temps/1000000000. ;
03133
03134 cleanup:
03135 return fdate ;
03136
03137 }
03138
03139 typedef struct {
03140 double frame_date ;
03141 int frame_idx ;
03142 cpl_frame * frame ;
03143 const char * frame_name ;
03144 } FRAME_DATE_IDX ;
03145
03146 static int
03147 compare_frame_date( const void * one, const void * two )
03148 {
03149 FRAME_DATE_IDX * first = (FRAME_DATE_IDX *)one,
03150 * scnd = (FRAME_DATE_IDX *)two ;
03151
03152 if ( first->frame_date > scnd->frame_date ) return 1 ;
03153 else if ( first->frame_date == scnd->frame_date ) return 0 ;
03154 else return -1 ;
03155 }
03156
03157
03158
03159
03160
03167
03168 cpl_frameset*
03169 xsh_order_frameset_by_date( cpl_frameset *frameset)
03170 {
03171 int nb, i ;
03172 FRAME_DATE_IDX *frame_date = NULL;
03173 cpl_frameset *result = NULL ;
03174 cpl_propertylist *header = NULL;
03175
03176 XSH_ASSURE_NOT_NULL( frameset);
03177
03178 check( nb = cpl_frameset_get_size( frameset));
03179 if ( nb <= 1 ) {
03180 check( result = cpl_frameset_duplicate( frameset));
03181 }
03182 else{
03183 XSH_CALLOC( frame_date, FRAME_DATE_IDX, nb);
03184
03185
03186 for( i = 0 ; i < nb ; i++){
03187 const char *fname = NULL ;
03188 cpl_frame *frame = NULL ;
03189 const char *the_date = NULL;
03190
03191
03192 check( frame = cpl_frameset_get_frame( frameset, i));
03193 check( fname = cpl_frame_get_filename( frame));
03194
03195
03196 check( header = cpl_propertylist_load( fname, 0));
03197
03198 check( the_date = xsh_pfits_get_date_obs( header));
03199
03200 frame_date[i].frame_date = date_to_double( the_date);
03201 frame_date[i].frame_idx = i;
03202 frame_date[i].frame = frame;
03203 frame_date[i].frame_name = fname;
03204
03205 xsh_free_propertylist( &header);
03206 }
03207
03208 qsort( frame_date, nb, sizeof( FRAME_DATE_IDX ), compare_frame_date ) ;
03209
03210 if ( xsh_debug_level_get() > XSH_DEBUG_LEVEL_NONE ) {
03211 for( i = 0 ; i<nb ; i++ ) {
03212 xsh_msg( "%d: %.9lf '%s'", frame_date[i].frame_idx,
03213 frame_date[i].frame_date, frame_date[i].frame_name);
03214 }
03215 }
03216
03217 check( result = cpl_frameset_new() ) ;
03218
03219
03220 for( i = 0 ; i <nb ; i++ ){
03221 check( cpl_frameset_insert( result,
03222 cpl_frame_duplicate(frame_date[i].frame)));
03223 }
03224 }
03225 cleanup:
03226 if ( cpl_error_get_code() != CPL_ERROR_NONE){
03227 xsh_free_frameset( &result);
03228 }
03229 xsh_free_propertylist( &header);
03230 XSH_FREE( frame_date);
03231 return result;
03232 }
03233
03234
03235
03283
03284
03285 polynomial *
03286 xsh_polynomial_regression_2d(cpl_table *t,
03287 const char *X1,
03288 const char *X2,
03289 const char *Y,
03290 const char *sigmaY,
03291 int degree1,
03292 int degree2,
03293 const char *polynomial_fit,
03294 const char *residual_square,
03295 const char *variance_fit,
03296 double *mse,
03297 double *red_chisq,
03298 polynomial **variance,
03299 double kappa,
03300 double min_reject)
03301 {
03302 int N;
03303 int rejected;
03304 int total_rejected;
03305 double *x1=NULL;
03306 double *x2=NULL;
03307 double *y=NULL;
03308 double *res=NULL;
03309 double *sy=NULL;
03310 polynomial *p = NULL;
03311 polynomial *variance_local = NULL;
03312 cpl_vector *vx1 = NULL;
03313 cpl_vector *vx2 = NULL;
03314 cpl_bivector *vx = NULL;
03315 cpl_vector *vy = NULL;
03316 cpl_vector *vsy= NULL;
03317 cpl_type type;
03318
03319
03320 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03321 assure( cpl_table_has_column(t, X1), CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", X1);
03322 assure( cpl_table_has_column(t, X2), CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", X2);
03323 assure( cpl_table_has_column(t, Y) , CPL_ERROR_ILLEGAL_INPUT, "No such column: %s", Y);
03324 assure( (variance == NULL && variance_fit == NULL) || sigmaY != NULL,
03325 CPL_ERROR_INCOMPATIBLE_INPUT, "Cannot calculate variances without sigmaY");
03326 if (sigmaY != NULL)
03327 {
03328 assure( cpl_table_has_column(t, sigmaY) , CPL_ERROR_ILLEGAL_INPUT,
03329 "No such column: %s", sigmaY);
03330 }
03331 if (polynomial_fit != NULL)
03332 {
03333 assure( !cpl_table_has_column(t, polynomial_fit) , CPL_ERROR_ILLEGAL_INPUT,
03334 "Table already has '%s' column", polynomial_fit);
03335 }
03336 if (residual_square != NULL)
03337 {
03338 assure( !cpl_table_has_column(t, residual_square), CPL_ERROR_ILLEGAL_INPUT,
03339 "Table already has '%s' column", residual_square);
03340 }
03341 if (variance_fit != NULL)
03342 {
03343 assure( !cpl_table_has_column(t, variance_fit) , CPL_ERROR_ILLEGAL_INPUT,
03344 "Table already has '%s' column", variance_fit);
03345 }
03346
03347
03348 type = cpl_table_get_column_type(t, X1);
03349 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03350 "Input column '%s' has wrong type (%s)", X1, xsh_tostring_cpl_type(type));
03351 type = cpl_table_get_column_type(t, X2);
03352 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03353 "Input column '%s' has wrong type (%s)", X2, xsh_tostring_cpl_type(type));
03354 type = cpl_table_get_column_type(t, Y);
03355 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03356 "Input column '%s' has wrong type (%s)", Y, xsh_tostring_cpl_type(type));
03357 if (sigmaY != NULL)
03358 {
03359 type = cpl_table_get_column_type(t, sigmaY);
03360 assure( type == CPL_TYPE_INT || type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
03361 "Input column '%s' has wrong type (%s)",
03362 sigmaY, xsh_tostring_cpl_type(type));
03363 }
03364
03365
03366 check_msg( cpl_table_cast_column(t, X1 , "_X1_double", CPL_TYPE_DOUBLE),
03367 "Could not cast table column to double");
03368 check_msg( cpl_table_cast_column(t, X2 , "_X2_double", CPL_TYPE_DOUBLE),
03369 "Could not cast table column to double");
03370 check_msg( cpl_table_cast_column(t, Y , "_Y_double", CPL_TYPE_DOUBLE),
03371 "Could not cast table column to double");
03372 if (sigmaY != NULL)
03373 {
03374 check_msg( cpl_table_cast_column(t, sigmaY, "_sY_double", CPL_TYPE_DOUBLE),
03375 "Could not cast table column to double");
03376 }
03377
03378 total_rejected = 0;
03379 rejected = 0;
03380 check_msg( cpl_table_new_column(t, "_residual_square", CPL_TYPE_DOUBLE),
03381 "Could not create column");
03382
03383 do {
03384
03385
03386 check_msg(( N = cpl_table_get_nrow(t),
03387 x1 = cpl_table_get_data_double(t, "_X1_double"),
03388 x2 = cpl_table_get_data_double(t, "_X2_double"),
03389 y = cpl_table_get_data_double(t, "_Y_double"),
03390 res= cpl_table_get_data_double(t, "_residual_square")),
03391 "Could not read table data");
03392
03393 if (sigmaY != NULL)
03394 {
03395 check_msg (sy = cpl_table_get_data_double(t, "_sY_double"),
03396 "Could not read table data");
03397 }
03398 else
03399 {
03400 sy = NULL;
03401 }
03402
03403 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03404
03405
03406 xsh_unwrap_vector(&vx1);
03407 xsh_unwrap_vector(&vx2);
03408 xsh_unwrap_vector(&vy);
03409
03410 vx1 = cpl_vector_wrap(N, x1);
03411 vx2 = cpl_vector_wrap(N, x2);
03412 vy = cpl_vector_wrap(N, y);
03413 if (sy != NULL)
03414 {
03415 xsh_unwrap_vector(&vsy);
03416 vsy = cpl_vector_wrap(N, sy);
03417 }
03418 else
03419 {
03420 vsy = NULL;
03421 }
03422
03423
03424 xsh_unwrap_bivector_vectors(&vx);
03425 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03426
03427
03428 xsh_polynomial_delete(&p);
03429 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03430 NULL, NULL, NULL),
03431 "Could not fit polynomial");
03432
03433
03434 if (kappa > 0)
03435 {
03436 double sigma2;
03437 int i;
03438
03439 cpl_table_fill_column_window_double(t, "_residual_square", 0,
03440 cpl_table_get_nrow(t), 0.0);
03441
03442 for (i = 0; i < N; i++)
03443 {
03444 double yval, yfit;
03445
03446 yval = y[i];
03447 yfit = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03448 res[i] = (yfit-y[i])*(yfit-y[i]);
03449 }
03450
03451
03452
03453
03454
03455
03456
03457 sigma2 = cpl_table_get_column_median(t, "_residual_square") / (0.6744 * 0.6744);
03458
03459
03460
03461 check_msg( rejected = xsh_erase_table_rows(t, "_residual_square",
03462 CPL_GREATER_THAN, kappa*kappa*sigma2),
03463 "Could not remove outlier points");
03464
03465
03466
03467 xsh_msg_debug("%d of %d points rejected in kappa-sigma clipping. rms=%f",
03468 rejected, N, sqrt(sigma2));
03469
03470
03471 total_rejected += rejected;
03472 N = cpl_table_get_nrow(t);
03473 }
03474
03475
03476
03477
03478 } while (rejected > 0 && rejected > min_reject*(N+rejected) &&
03479 N >= (degree1 + 1)*(degree2 + 1) + 1);
03480
03481 if (kappa > 0)
03482 {
03483 xsh_msg_debug("%d of %d points (%f %%) rejected in kappa-sigma clipping",
03484 total_rejected,
03485 N + total_rejected,
03486 (100.0*total_rejected)/(N + total_rejected)
03487 );
03488 }
03489
03490
03491 {
03492
03493
03494
03495
03496 check_msg(( N = cpl_table_get_nrow(t),
03497 x1 = cpl_table_get_data_double(t, "_X1_double"),
03498 x2 = cpl_table_get_data_double(t, "_X2_double"),
03499 y = cpl_table_get_data_double(t, "_Y_double"),
03500 res= cpl_table_get_data_double(t, "_residual_square")),
03501 "Could not read table data");
03502
03503 if (sigmaY != NULL)
03504 {
03505 check_msg (sy = cpl_table_get_data_double(t, "_sY_double"),
03506 "Could not read table data");
03507 }
03508 else
03509 {
03510 sy = NULL;
03511 }
03512
03513 assure( N > 0, CPL_ERROR_ILLEGAL_INPUT, "Empty table");
03514
03515
03516 xsh_unwrap_vector(&vx1);
03517 xsh_unwrap_vector(&vx2);
03518 xsh_unwrap_vector(&vy);
03519
03520 vx1 = cpl_vector_wrap(N, x1);
03521 vx2 = cpl_vector_wrap(N, x2);
03522 vy = cpl_vector_wrap(N, y);
03523 if (sy != NULL)
03524 {
03525 xsh_unwrap_vector(&vsy);
03526 vsy = cpl_vector_wrap(N, sy);
03527 }
03528 else
03529 {
03530 vsy = NULL;
03531 }
03532
03533
03534 xsh_unwrap_bivector_vectors(&vx);
03535 vx = cpl_bivector_wrap_vectors(vx1, vx2);
03536 }
03537
03538 xsh_polynomial_delete(&p);
03539 if (variance_fit != NULL || variance != NULL)
03540 {
03541
03542 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03543 mse, red_chisq, &variance_local),
03544 "Could not fit polynomial");
03545 }
03546 else
03547 {
03548 check_msg( p = xsh_polynomial_fit_2d(vx, vy, vsy, degree1, degree2,
03549 mse, red_chisq, NULL),
03550 "Could not fit polynomial");
03551 }
03552
03553 cpl_table_erase_column(t, "_residual_square");
03554
03555
03556 if (polynomial_fit != NULL || residual_square != NULL)
03557 {
03558 int i;
03559 double *pf;
03560
03561 check_msg( cpl_table_new_column(t, "_polynomial_fit", CPL_TYPE_DOUBLE),
03562 "Could not create column");
03563
03564 cpl_table_fill_column_window_double(t, "_polynomial_fit", 0,
03565 cpl_table_get_nrow(t), 0.0);
03566
03567 x1 = cpl_table_get_data_double(t, "_X1_double");
03568 x2 = cpl_table_get_data_double(t, "_X2_double");
03569 pf = cpl_table_get_data_double(t, "_polynomial_fit");
03570
03571 for (i = 0; i < N; i++){
03572 #if 0
03573 double x1val, x2val, yfit;
03574
03575 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03576 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03577 yfit = xsh_polynomial_evaluate_2d(p, x1val, x2val),
03578
03579 cpl_table_set_double(t, "_polynomial_fit", i, yfit)),
03580 "Could not evaluate polynomial");
03581
03582 #else
03583 pf[i] = xsh_polynomial_evaluate_2d(p, x1[i], x2[i]);
03584 #endif
03585 }
03586
03587
03588 if (residual_square != NULL)
03589 {
03590 check_msg(( cpl_table_duplicate_column(t, residual_square,
03591 t, "_polynomial_fit"),
03592 cpl_table_subtract_columns(t, residual_square, Y),
03593 cpl_table_multiply_columns(t, residual_square, residual_square)),
03594
03595 "Could not calculate Residual of fit");
03596 }
03597
03598
03599 if (polynomial_fit != NULL)
03600 {
03601 cpl_table_name_column(t, "_polynomial_fit", polynomial_fit);
03602 }
03603 else
03604 {
03605 cpl_table_erase_column(t, "_polynomial_fit");
03606 }
03607 }
03608
03609
03610 if (variance_fit != NULL)
03611 {
03612 int i;
03613 double *vf;
03614
03615 check_msg( cpl_table_new_column(t, variance_fit, CPL_TYPE_DOUBLE),
03616 "Could not create column");
03617
03618 cpl_table_fill_column_window_double(t, variance_fit, 0,
03619 cpl_table_get_nrow(t), 0.0);
03620
03621 x1 = cpl_table_get_data_double(t, "_X1_double");
03622 x2 = cpl_table_get_data_double(t, "_X2_double");
03623 vf = cpl_table_get_data_double(t, variance_fit);
03624
03625 for (i = 0; i < N; i++)
03626 {
03627 #if 0
03628 double x1val, x2val, yfit_variance;
03629 check_msg(( x1val = cpl_table_get_double(t, "_X1_double", i, NULL),
03630 x2val = cpl_table_get_double(t, "_X2_double", i, NULL),
03631 yfit_variance = xsh_polynomial_evaluate_2d(variance_local,
03632 x1val, x2val),
03633
03634 cpl_table_set_double(t, variance_fit, i, yfit_variance)),
03635 "Could not evaluate polynomial");
03636 #else
03637 vf[i] = xsh_polynomial_evaluate_2d(variance_local, x1[i], x2[i]);
03638 #endif
03639
03640 }
03641 }
03642
03643
03644 check_msg(( cpl_table_erase_column(t, "_X1_double"),
03645 cpl_table_erase_column(t, "_X2_double"),
03646 cpl_table_erase_column(t, "_Y_double")),
03647 "Could not delete temporary columns");
03648
03649 if (sigmaY != NULL)
03650 {
03651 check_msg( cpl_table_erase_column(t, "_sY_double"),
03652 "Could not delete temporary column");
03653 }
03654
03655 cleanup:
03656 xsh_unwrap_bivector_vectors(&vx);
03657 xsh_unwrap_vector(&vx1);
03658 xsh_unwrap_vector(&vx2);
03659 xsh_unwrap_vector(&vy);
03660 xsh_unwrap_vector(&vsy);
03661
03662 if (variance != NULL)
03663 {
03664 *variance = variance_local;
03665 }
03666 else
03667 {
03668 xsh_polynomial_delete(&variance_local);
03669 }
03670 if (cpl_error_get_code() != CPL_ERROR_NONE)
03671 {
03672 xsh_polynomial_delete(&p);
03673 }
03674
03675 return p;
03676 }
03677
03678
03679
03680
03697
03698
03699 int
03700 xsh_select_table_rows(cpl_table *t,
03701 const char *column,
03702 cpl_table_select_operator operator,
03703 double value)
03704 {
03705 int result = 0;
03706 cpl_type type;
03707
03708 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03709 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03710 "No such column: %s", column);
03711
03712 type = cpl_table_get_column_type(t, column);
03713
03714 assure( type == CPL_TYPE_DOUBLE || type == CPL_TYPE_FLOAT ||
03715 type == CPL_TYPE_INT, CPL_ERROR_INVALID_TYPE,
03716 "Column '%s' must be double or int. %s found", column,
03717 xsh_tostring_cpl_type(type));
03718
03719 check_msg( cpl_table_select_all(t), "Error selecting rows");
03720
03721 if (type == CPL_TYPE_DOUBLE)
03722 {
03723 result = cpl_table_and_selected_double(t, column, operator, value);
03724 }
03725 else if (type == CPL_TYPE_FLOAT)
03726 {
03727 result = cpl_table_and_selected_float(t, column, operator, value);
03728 }
03729 else if (type == CPL_TYPE_INT)
03730 {
03731 result = cpl_table_and_selected_int(t, column, operator,
03732 xsh_round_double(value));
03733 }
03734 else { passure(false, ""); }
03735
03736 cleanup:
03737 return result;
03738
03739 }
03740
03741
03742
03743
03744
03763
03764 int
03765 xsh_erase_table_rows(cpl_table *t,
03766 const char *column,
03767 cpl_table_select_operator operator,
03768 double value)
03769 {
03770 int result = 0;
03771
03772 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
03773 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
03774 "No such column: %s", column);
03775
03776 check_msg( result = xsh_select_table_rows(t, column, operator, value),
03777 "Error selecting rows");
03778
03779 check_msg( cpl_table_erase_selected(t), "Error deleting rows");
03780
03781 cleanup:
03782 return result;
03783 }
03784
03793
03794 cpl_frame* xsh_frame_inv( cpl_frame* in, const char *filename,
03795 xsh_instrument* instr)
03796 {
03797 xsh_pre *pre = NULL;
03798 cpl_frame *result = NULL;
03799 const char* tag = "INV_PRE";
03800
03801 XSH_ASSURE_NOT_NULL( in);
03802 XSH_ASSURE_NOT_NULL( instr);
03803
03804 check( pre = xsh_pre_load( in, instr));
03805 check( xsh_pre_multiply_scalar( pre, -1.0));
03806 check( result = xsh_pre_save( pre, filename, tag, 1));
03807 check( cpl_frame_set_tag( result, tag));
03808
03809 cleanup:
03810 if (cpl_error_get_code() != CPL_ERROR_NONE){
03811 xsh_free_frame( &result);
03812 }
03813 xsh_pre_free( &pre);
03814 return result;
03815 }
03816
03817
03818
03826
03827 cpl_frame* xsh_frame_abs( cpl_frame* in, xsh_instrument* instr,
03828 cpl_frame** sign)
03829 {
03830 xsh_pre *pre = NULL;
03831 cpl_frame *result = NULL;
03832 cpl_frame *sign_frame = NULL;
03833 char name[256];
03834 const char* tag = "ABS_PRE";
03835 const char* sign_tag = "SIGN_PRE";
03836 const char *filename = NULL;
03837 cpl_image *sign_img = NULL;
03838
03839 XSH_ASSURE_NOT_NULL( in);
03840 XSH_ASSURE_NOT_NULL( sign);
03841
03842 check( filename = cpl_frame_get_filename( in));
03843 check( pre = xsh_pre_load( in, instr));
03844 check( sign_img = xsh_pre_abs( pre));
03845 sprintf( name ,"ABS_%s", filename);
03846 check( result = xsh_pre_save( pre, name, tag, 1));
03847 check( cpl_frame_set_tag( result, tag));
03848 sprintf( name ,"SIGN_%s", filename);
03849 check( cpl_image_save( sign_img, name, CPL_BPP_32_SIGNED,
03850 NULL,CPL_IO_DEFAULT));
03851 check( sign_frame = cpl_frame_new());
03852 check( cpl_frame_set_filename( sign_frame, name));
03853 check( cpl_frame_set_tag( sign_frame, sign_tag));
03854 *sign = sign_frame;
03855
03856 cleanup:
03857 if (cpl_error_get_code() != CPL_ERROR_NONE){
03858 xsh_free_frame( &result);
03859 }
03860 xsh_free_image( &sign_img);
03861 xsh_pre_free( &pre);
03862 return result;
03863 }
03864
03871 void
03872 xsh_frame_image_save(cpl_frame* frm,const char* name_o)
03873 {
03874 cpl_image* ima=NULL;
03875 const char* name=NULL;
03876 name=cpl_frame_get_filename(frm);
03877 ima=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
03878
03879 cpl_image_save(ima,name_o,CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
03880 xsh_free_image(&ima);
03881
03882
03883 return;
03884 }
03885
03886
03893 void
03894 xsh_frame_table_save(cpl_frame* frame,const char* name_o)
03895 {
03896 const char* fname=NULL;
03897
03898 int nbext=0;
03899 int extension ;
03900 cpl_table *tbl_ext = NULL;
03901 cpl_propertylist *tbl_ext_header = NULL;
03902 cpl_propertylist *primary_header = NULL;
03903 int i=0;
03904
03905 fname=cpl_frame_get_filename(frame);
03906 nbext = cpl_frame_get_nextensions( frame);
03907
03908 for( i = 0 ; i<nbext ; i++ ) {
03909
03910 check( tbl_ext = cpl_table_load( fname, i+1, 0));
03911 check( tbl_ext_header = cpl_propertylist_load( fname, i+1));
03912
03913 if ( i == 0 ) extension = CPL_IO_DEFAULT ;
03914 else extension = CPL_IO_EXTEND ;
03915 check(cpl_table_save( tbl_ext, primary_header, tbl_ext_header,
03916 name_o, extension));
03917 xsh_free_table( &tbl_ext);
03918 xsh_free_propertylist( &tbl_ext_header);
03919
03920 }
03921
03922 cleanup:
03923 xsh_free_table( &tbl_ext);
03924 xsh_free_propertylist( &tbl_ext_header);
03925
03926 return;
03927 }
03928
03937
03938 cpl_frame* xsh_frame_mult( cpl_frame* in, xsh_instrument* instr,
03939 cpl_frame* sign)
03940 {
03941 xsh_pre *pre = NULL;
03942 cpl_frame *result = NULL;
03943 cpl_image *sign_img = NULL;
03944 const char* name = NULL;
03945 const char* tag = "MULT_IMG_PRE";
03946
03947 XSH_ASSURE_NOT_NULL( in);
03948 XSH_ASSURE_NOT_NULL( sign);
03949
03950 check( name = cpl_frame_get_filename( sign));
03951 check( pre = xsh_pre_load( in, instr));
03952 check( sign_img = cpl_image_load( name, CPL_TYPE_INT, 0, 0));
03953 check( xsh_pre_multiply_image( pre, sign_img));
03954 check( result = xsh_pre_save( pre, "RESTORE_PRE.fits", tag, 1));
03955 check( cpl_frame_set_tag( result, tag));
03956
03957 cleanup:
03958 if (cpl_error_get_code() != CPL_ERROR_NONE){
03959 xsh_free_frame( &result);
03960 }
03961 xsh_free_image( &sign_img);
03962 xsh_pre_free( &pre);
03963 return result;
03964 }
03965
03966
03980
03981
03982
03983 cpl_error_code
03984 xsh_monitor_flux(cpl_frame* frm_ima,const cpl_frame* frm_tab,
03985 xsh_instrument *instrument)
03986 {
03987
03988 int ord_min=0;
03989 int ord_max=0;
03990 int i=0;
03991 const char* name_ima=NULL;
03992 const char* name_tab=NULL;
03993 cpl_table* tab=NULL;
03994 cpl_image* ima=NULL;
03995 cpl_table* ext=NULL;
03996 int next=0;
03997 double* cx=NULL;
03998 double* cy=NULL;
03999 int ix=0;
04000 int iy=0;
04001 double flux_min_init=FLT_MAX;
04002 double flux_max_init=-FLT_MAX;
04003
04004 double flux_min_ord=flux_min_init;
04005 double flux_max_ord=flux_max_init;
04006
04007 double flux_min=flux_min_init;
04008 double flux_max=flux_max_init;
04009 double* pima=NULL;
04010 double flux=0;
04011 cpl_propertylist* plist=NULL;
04012 char qc_flux_min[20];
04013 char qc_flux_max[20];
04014 int sx=0;
04015 int sy=0;
04016 int j=0;
04017 int binx=1;
04018 int biny=1;
04019
04020 cpl_ensure_code(frm_ima != NULL, CPL_ERROR_NULL_INPUT);
04021 cpl_ensure_code(frm_tab != NULL, CPL_ERROR_NULL_INPUT);
04022
04023 check(name_ima=cpl_frame_get_filename(frm_ima));
04024 check(name_tab=cpl_frame_get_filename(frm_tab));
04025
04026 check(plist=cpl_propertylist_load(name_ima,0));
04027
04028 if( xsh_instrument_get_arm( instrument) != XSH_ARM_NIR){
04029 binx=xsh_pfits_get_binx(plist);
04030 biny=xsh_pfits_get_biny(plist);
04031 }
04032 check(tab=cpl_table_load(name_tab,2,0));
04033 check(ima=cpl_image_load(name_ima,CPL_TYPE_DOUBLE,0,0));
04034 check(sx=cpl_image_get_size_x(ima));
04035 check(sy=cpl_image_get_size_y(ima));
04036
04037
04038
04039
04040 check(pima=cpl_image_get_data_double(ima));
04041 check(ord_min=cpl_table_get_column_min(tab,"ABSORDER"));
04042 check(ord_max=cpl_table_get_column_max(tab,"ABSORDER"));
04043
04044
04045 for(i=ord_min;i<=ord_max;i++) {
04046 flux_min_ord=flux_min_init;
04047 flux_max_ord=flux_max_init;
04048
04049 check(next=cpl_table_and_selected_int(tab,"ABSORDER",CPL_EQUAL_TO,i));
04050 ext=cpl_table_extract_selected(tab);
04051 cx=cpl_table_get_data_double(ext,"CENTER_X");
04052 cy=cpl_table_get_data_double(ext,"CENTER_Y");
04053 for(j=0;j<next;j++) {
04054
04055 ix=(int)(cx[j]/binx+0.5);
04056 iy=(int)(cy[j]/biny+0.5);
04057
04058 if( (next >= 1) && ((ix>=0) && (ix<sx)) && ((iy>=0) && (iy<sy)) ) {
04059 check(flux=pima[ix+sx*iy]);
04060 if(!isnan(flux)) {
04061 if(flux<flux_min_ord) flux_min_ord=flux;
04062 if(flux>flux_max_ord) flux_max_ord=flux;
04063
04064
04065
04066 }
04067 }
04068
04069
04070 }
04071 xsh_free_table(&ext);
04072 cpl_table_select_all(tab);
04073 if(next>1) {
04074 flux_min=(flux_min_ord<flux_min)? flux_min_ord:flux_min;
04075 flux_max=(flux_max_ord>flux_max)? flux_max_ord:flux_max;
04076 }
04077 sprintf(qc_flux_min,"%s%d%s",XSH_QC_FLUX,i," MIN");
04078 sprintf(qc_flux_max,"%s%d%s",XSH_QC_FLUX,i," MAX");
04079
04080
04081 cpl_propertylist_append_double(plist,qc_flux_min,flux_min_ord);
04082 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04083 cpl_propertylist_append_double(plist,qc_flux_max,flux_max_ord);
04084 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04085 }
04086
04087 sprintf(qc_flux_min,"%s%s",XSH_QC_FLUX," MIN");
04088 sprintf(qc_flux_max,"%s%s",XSH_QC_FLUX," MAX");
04089 cpl_propertylist_append_double(plist,qc_flux_min,flux_min);
04090 cpl_propertylist_set_comment(plist,qc_flux_min,XSH_QC_FLUX_MIN_C);
04091 cpl_propertylist_append_double(plist,qc_flux_max,flux_max);
04092 cpl_propertylist_set_comment(plist,qc_flux_max,XSH_QC_FLUX_MAX_C);
04093 check(xsh_update_pheader_in_image_multi(frm_ima,plist));
04094
04095 cleanup:
04096 xsh_free_table(&ext);
04097 xsh_free_image(&ima);
04098 xsh_free_table(&tab);
04099 xsh_free_propertylist(&plist);
04100
04101
04102 return cpl_error_get_code();
04103
04104 }
04105
04106
04118
04119
04120 cpl_error_code
04121 xsh_update_pheader_in_image_multi(cpl_frame *frame,
04122 const cpl_propertylist* pheader)
04123 {
04124 const char *fname = NULL;
04125 int nbext=0;
04126 int i=0;
04127 cpl_image *image = NULL ;
04128 char cmd[80];
04129 int extension=0 ;
04130 cpl_image* ext_img=NULL;
04131 cpl_propertylist* ext_header=NULL;
04132
04133 XSH_ASSURE_NOT_NULL(frame);
04134 nbext = cpl_frame_get_nextensions( frame);
04135 xsh_msg_dbg_medium("nbext=%d",nbext);
04136 check( fname = cpl_frame_get_filename( frame));
04137 check( image = cpl_image_load( fname, CPL_TYPE_FLOAT, 0, 0));
04138
04139
04140
04141
04142 cpl_image_save(image, "tmp.fits", CPL_BPP_IEEE_FLOAT, pheader,
04143 CPL_IO_DEFAULT ) ;
04144 xsh_free_image(&image);
04145 xsh_msg_dbg_medium("fname=%s",fname);
04146 for( i = 1 ; i<=nbext ; i++ ) {
04147
04148 check( ext_img = cpl_image_load( fname, CPL_TYPE_FLOAT,0, i));
04149 check( ext_header = cpl_propertylist_load( fname ,i));
04150
04151 if ( i == 0 ) {
04152 extension = CPL_IO_DEFAULT ;
04153 }
04154 else {
04155 extension = CPL_IO_EXTEND ;
04156 check(cpl_image_save( ext_img, "tmp.fits", CPL_BPP_IEEE_FLOAT,ext_header,
04157 extension));
04158 }
04159 xsh_free_image( &ext_img) ;
04160 xsh_free_propertylist( &ext_header) ;
04161 }
04162
04163 sprintf(cmd,"mv tmp.fits %s",fname);
04164 system(cmd);
04165 system("rm -f tmp.fits");
04166
04167
04168 cleanup:
04169 xsh_free_image( &ext_img) ;
04170 xsh_free_propertylist( &ext_header) ;
04171 xsh_free_image(&image);
04172
04173 return cpl_error_get_code();
04174 }
04175
04181
04182 double xsh_vector_get_err_median( cpl_vector *vect)
04183 {
04184 double err_median =0.0;
04185 int i, vect_size =0;
04186 double *data = NULL;
04187
04188 XSH_ASSURE_NOT_NULL( vect);
04189
04190 check( vect_size = cpl_vector_get_size( vect));
04191 check( data = cpl_vector_get_data( vect));
04192
04193 if (vect_size > 1){
04194 for( i=0; i< vect_size; i++){
04195 err_median += data[i]*data[i];
04196 }
04197
04198 err_median = sqrt( M_PI / 2.0 *
04199 ((double) vect_size / ((double) vect_size- 1.))) *
04200 (1./(double)vect_size) * sqrt (err_median);
04201 }
04202 else{
04203 err_median = data[0];
04204 }
04205
04206 cleanup:
04207 return err_median;
04208 }
04209
04216
04217 double xsh_vector_get_err_mean( cpl_vector *vect)
04218 {
04219 double err_mean =0.0;
04220 int i, vect_size =0;
04221 double *data = NULL;
04222
04223 XSH_ASSURE_NOT_NULL( vect);
04224
04225 check( vect_size = cpl_vector_get_size( vect));
04226 check( data = cpl_vector_get_data( vect));
04227
04228 for( i=0; i< vect_size; i++){
04229 err_mean += data[i]*data[i];
04230 }
04231 err_mean = sqrt( err_mean)/(double)vect_size;
04232
04233 cleanup:
04234 return err_mean;
04235 }
04236
04237
04238
04239
04245
04246 long xsh_round_double(double x)
04247 {
04248 return (x >=0) ? (long)(x+0.5) : (long)(x-0.5);
04249 }
04250
04251
04260
04261 inline int
04262 xsh_min_int(int x, int y)
04263 {
04264 return (x <=y) ? x : y;
04265 }
04266
04267
04268
04277
04278 inline int
04279 xsh_max_int(int x, int y)
04280 {
04281 return (x >=y) ? x : y;
04282 }
04283
04284
04285
04286
04287
04296
04297 inline double
04298 xsh_min_double(double x, double y)
04299 {
04300 return (x <=y) ? x : y;
04301 }
04302
04303
04304
04313
04314 inline double
04315 xsh_max_double(double x, double y)
04316 {
04317 return (x >=y) ? x : y;
04318 }
04319
04320
04321
04328
04329 double xsh_pow_int(double x, int y)
04330 {
04331 double result = 1.0;
04332
04333
04334 while(y != 0)
04335 {
04336 if (y % 2 == 0)
04337 {
04338 x *= x;
04339 y /= 2;
04340 }
04341 else
04342 {
04343 if (y > 0)
04344 {
04345 result *= x;
04346 y -= 1;
04347 }
04348 else
04349 {
04350 result /= x;
04351 y += 1;
04352 }
04353 }
04354 }
04355 return result;
04356 }
04357
04373 const char*
04374 xsh_string_tolower(char* s)
04375 {
04376
04377 char *t = s;
04378
04379 assert(s != NULL);
04380
04381 while (*t) {
04382 *t = tolower(*t);
04383 t++;
04384 }
04385
04386 return s;
04387
04388 }
04389
04390
04407 const char*
04408 xsh_string_toupper(char* s)
04409 {
04410
04411 char *t = s;
04412
04413 assert(s != NULL);
04414
04415 while (*t) {
04416 *t = toupper(*t);
04417 t++;
04418 }
04419
04420 return s;
04421
04422 }
04423
04424
04425
04441
04442 double
04443 xsh_spline_hermite( double xp, const double *x, const double *y, int n, int *istart )
04444 {
04445 double yp1, yp2, yp = 0;
04446 double xpi, xpi1, l1, l2, lp1, lp2;
04447 int i;
04448
04449 if ( x[0] <= x[n-1] && (xp < x[0] || xp > x[n-1]) ) return 0.0;
04450 if ( x[0] > x[n-1] && (xp > x[0] || xp < x[n-1]) ) return 0.0;
04451
04452 if ( x[0] <= x[n-1] )
04453 {
04454 for ( i = (*istart)+1; i <= n && xp >= x[i-1]; i++ )
04455 ;
04456 }
04457 else
04458 {
04459 for ( i = (*istart)+1; i <= n && xp <= x[i-1]; i++ )
04460 ;
04461 }
04462
04463 *istart = i;
04464 i--;
04465
04466 lp1 = 1.0 / (x[i-1] - x[i]);
04467 lp2 = -lp1;
04468
04469 if ( i == 1 )
04470 {
04471 yp1 = (y[1] - y[0]) / (x[1] - x[0]);
04472 }
04473 else
04474 {
04475 yp1 = (y[i] - y[i-2]) / (x[i] - x[i-2]);
04476 }
04477
04478 if ( i >= n - 1 )
04479 {
04480 yp2 = (y[n-1] - y[n-2]) / (x[n-1] - x[n-2]);
04481 }
04482 else
04483 {
04484 yp2 = (y[i+1] - y[i-1]) / (x[i+1] - x[i-1]);
04485 }
04486
04487 xpi1 = xp - x[i];
04488 xpi = xp - x[i-1];
04489 l1 = xpi1*lp1;
04490 l2 = xpi*lp2;
04491
04492 yp = y[i-1]*(1 - 2.0*lp1*xpi)*l1*l1 +
04493 y[i]*(1 - 2.0*lp2*xpi1)*l2*l2 +
04494 yp1*xpi*l1*l1 + yp2*xpi1*l2*l2;
04495
04496 return yp;
04497 }
04498
04499
04500
04511
04512
04513 double
04514 xsh_spline_hermite_table( double xp, const cpl_table *t, const char *column_x,
04515 const char *column_y, int *istart )
04516 {
04517 double result = 0;
04518 int n;
04519
04520 const double *x, *y;
04521
04522 check_msg( x = cpl_table_get_data_double_const(t, column_x),
04523 "Error reading column '%s'", column_x);
04524 check_msg( y = cpl_table_get_data_double_const(t, column_y),
04525 "Error reading column '%s'", column_y);
04526
04527 n = cpl_table_get_nrow(t);
04528
04529 result = xsh_spline_hermite(xp, x, y, n, istart);
04530
04531 cleanup:
04532 return result;
04533 }
04534
04535
04536
04545 cpl_vector *
04546 xsh_image_to_vector( cpl_image * spectrum )
04547 {
04548 cpl_vector * result ;
04549 cpl_type type=CPL_TYPE_FLOAT;
04550
04551 int i ;
04552 int ilx=0;
04553 int ily=0;
04554
04555 int* pi=NULL;
04556 float* pf=NULL;
04557 double* pd=NULL;
04558 double* pv=NULL;
04559
04560 int size=0;
04561
04562
04563 XSH_ASSURE_NOT_NULL_MSG(spectrum,"NULL input spectrum (1D) image!Exit.");
04564 ilx=cpl_image_get_size_x(spectrum);
04565 ily=cpl_image_get_size_y(spectrum);
04566 size=ilx*ily;
04567
04568 result=cpl_vector_new(size);
04569 pv=cpl_vector_get_data(result);
04570
04571 switch(type) {
04572
04573 case CPL_TYPE_INT:
04574 pi=cpl_image_get_data_int(spectrum);
04575 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pi[i] ;
04576 break;
04577
04578 case CPL_TYPE_FLOAT:
04579 pf=cpl_image_get_data_float(spectrum);
04580 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pf[i] ;
04581 break;
04582
04583 case CPL_TYPE_DOUBLE:
04584 pd=cpl_image_get_data_double(spectrum);
04585 for ( i = 0 ; i < size ; i++ ) pv[i] = (double) pd[i] ;
04586 break;
04587
04588 default:
04589 xsh_msg_error("Wrong input image data type %d",type);
04590 }
04591
04592 cleanup:
04593
04594 return result ;
04595 }
04596
04597
04598
04608
04609
04610 cpl_image*
04611 xsh_vector_to_image(const cpl_vector* vector,cpl_type type)
04612 {
04613 int i=0;
04614 cpl_image* image=NULL;
04615 int size=0;
04616 const double* pv=NULL;
04617 int* pi=NULL;
04618 float* pf=NULL;
04619 double* pd=NULL;
04620
04621
04622 size=cpl_vector_get_size(vector);
04623 image=cpl_image_new(size,1,type);
04624 pv=cpl_vector_get_data_const(vector);
04625 if(type == CPL_TYPE_INT) {
04626 pi=cpl_image_get_data_int(image);
04627 for(i=0;i<size;i++) {
04628 pi[i]=pv[i];
04629 }
04630 } else if (type == CPL_TYPE_FLOAT) {
04631 pf=cpl_image_get_data_float(image);
04632 for(i=0;i<size;i++) {
04633 pf[i]=pv[i];
04634 }
04635 } else if (type == CPL_TYPE_DOUBLE) {
04636 pd=cpl_image_get_data_double(image);
04637 for(i=0;i<size;i++) {
04638 pd[i]=pv[i];
04639 }
04640 } else {
04641 assure( false, CPL_ERROR_INVALID_TYPE,
04642 "No CPL type to represent BITPIX = %d", type);
04643 }
04644
04645 cleanup:
04646 if (cpl_error_get_code() != CPL_ERROR_NONE){
04647 xsh_free_image(&image);
04648 }
04649
04650 return image;
04651
04652 }
04653
04654
04662
04663 cpl_frame*
04664 xsh_util_multiply_by_response(cpl_frame* merged_sci, cpl_frame* response,
04665 const char* tag_o)
04666 {
04667 cpl_frame* result=NULL;
04668 cpl_image* data_sci=NULL;
04669 cpl_image* errs_sci=NULL;
04670 cpl_image* qual_sci=NULL;
04671
04672 cpl_image* data_tmp=NULL;
04673 cpl_image* errs_tmp=NULL;
04674
04675 cpl_vector* data_vec=NULL;
04676 cpl_vector* errs_vec=NULL;
04677 cpl_vector* qual_vec=NULL;
04678
04679 cpl_propertylist* hdat=NULL;
04680 cpl_propertylist* herr=NULL;
04681 cpl_propertylist* hqua=NULL;
04682
04683 cpl_table* response_table=NULL;
04684
04685 const char* name_s=NULL;
04686 const char* tag_s=NULL;
04687 const char* name_r=NULL;
04688
04689 char* name_o=NULL;
04690 double lambda_start=0;
04691 double lambda_step=0;
04692 int bin=0;
04693 int naxis=0;
04694 int nbins = 0;
04695 int ntraces = 0;
04696
04697 double *fluxcal_science_data = NULL;
04698 double *fluxcal_science_noise = NULL;
04699
04700 XSH_ASSURE_NOT_NULL_MSG(merged_sci,"NULL input merged frame!Exit.");
04701 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04702
04703 check(name_s=cpl_frame_get_filename(merged_sci));
04704 check(tag_s=cpl_frame_get_tag(merged_sci));
04705 name_o=cpl_sprintf("%s.fits",tag_o);
04706
04707 check(hdat=cpl_propertylist_load(name_s,0));
04708 check(herr=cpl_propertylist_load(name_s,1));
04709 check(hqua=cpl_propertylist_load(name_s,2));
04710
04711 naxis=xsh_pfits_get_naxis(hdat);
04712
04713 if(naxis == 1) {
04714
04715 check(data_vec=cpl_vector_load(name_s,0));
04716 check(errs_vec=cpl_vector_load(name_s,1));
04717
04718 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
04719 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
04720
04721 xsh_free_vector(&data_vec);
04722 xsh_free_vector(&errs_vec);
04723
04724 } else {
04725
04726 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,0));
04727 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,1));
04728 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,2));
04729
04730 }
04731
04732 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
04733 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
04734 xsh_free_image(&data_sci);
04735 xsh_free_image(&errs_sci);
04736
04737 check(name_r=cpl_frame_get_filename(response));
04738 check(response_table=cpl_table_load(name_r,1,0));
04739
04740
04741
04742
04743 xsh_msg("Multiply by response function");
04744
04745 check(nbins = cpl_image_get_size_x(data_tmp));
04746 check(ntraces = cpl_image_get_size_y(data_tmp));
04747
04748 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
04749 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
04750
04751 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
04752 "Error reading start wavelength from reduced science header");
04753 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
04754 "Error reading bin width from header");
04755
04756 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
04757 check(cpl_table_cast_column(response_table,"FLUX","DFLUX",CPL_TYPE_DOUBLE));
04758
04759 for (bin = 1; bin <= nbins; bin++)
04760 {
04761 double lambda;
04762 double response;
04763 int trace;
04764 int istart = 0;
04765
04766 lambda = lambda_start + (bin-1) * lambda_step;
04767 check_msg( response =
04768 xsh_spline_hermite_table(lambda, response_table,
04769 "DLAMBDA", "DFLUX", &istart),
04770 "Error interpolating response curve at lambda = %f wlu", lambda);
04771
04772 xsh_msg_dbg_medium("response=%g",response);
04773
04774 for (trace = 1; trace <= ntraces; trace++)
04775 {
04776
04777
04778
04779
04780 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
04781
04782 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
04783
04784
04785
04786 }
04787 }
04788
04789 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
04790 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
04791 xsh_free_image(&data_tmp);
04792 xsh_free_image(&errs_tmp);
04793
04794 cpl_table_erase_column(response_table,"DLAMBDA");
04795 cpl_table_erase_column(response_table,"DFLUX");
04796 check( xsh_pfits_set_pcatg( hdat, tag_o));
04797
04798 if(naxis==1) {
04799 check(data_vec=xsh_image_to_vector(data_sci));
04800 check(errs_vec=xsh_image_to_vector(errs_sci));
04801
04802 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
04803 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
04804 check(qual_vec=cpl_vector_load(name_s,2));
04805 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
04806
04807
04808 } else {
04809 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
04810 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
04811 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
04812 }
04813
04814
04815 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
04816
04817 cleanup:
04818
04819 cpl_free(name_o);
04820
04821 xsh_free_image(&data_sci);
04822 xsh_free_image(&errs_sci);
04823 xsh_free_image(&qual_sci);
04824 xsh_free_image(&data_sci);
04825 xsh_free_image(&errs_sci);
04826
04827 xsh_free_vector(&data_vec);
04828 xsh_free_vector(&errs_vec);
04829 xsh_free_vector(&qual_vec);
04830
04831 xsh_free_table(&response_table);
04832 xsh_free_propertylist(&hdat);
04833 xsh_free_propertylist(&herr);
04834 xsh_free_propertylist(&hqua);
04835
04836 return result;
04837 }
04838
04839
04847
04848 cpl_frame*
04849 xsh_util_multiply_by_response_ord(cpl_frame* extracted_sci, cpl_frame* response,
04850 const char* tag_o)
04851 {
04852 cpl_frame* result=NULL;
04853 cpl_image* data_sci=NULL;
04854 cpl_image* errs_sci=NULL;
04855 cpl_image* qual_sci=NULL;
04856
04857 cpl_image* data_tmp=NULL;
04858 cpl_image* errs_tmp=NULL;
04859
04860 cpl_vector* data_vec=NULL;
04861 cpl_vector* errs_vec=NULL;
04862 cpl_vector* qual_vec=NULL;
04863
04864 cpl_propertylist* hdat=NULL;
04865 cpl_propertylist* herr=NULL;
04866 cpl_propertylist* hqua=NULL;
04867
04868 cpl_table* response_table=NULL;
04869
04870 const char* name_s=NULL;
04871 const char* tag_s=NULL;
04872 const char* name_r=NULL;
04873 char* name_o=NULL;
04874 double lambda_start=0;
04875 double lambda_step=0;
04876 int bin=0;
04877 int naxis=0;
04878
04879 int nbins = 0;
04880 int ntraces = 0;
04881
04882 int next_sci = 0;
04883 int next_res = 0;
04884 int ext = 0;
04885 int order=0;
04886
04887 double *fluxcal_science_data = NULL;
04888 double *fluxcal_science_noise = NULL;
04889
04890 XSH_ASSURE_NOT_NULL_MSG(extracted_sci,"NULL input extracted frame!Exit.");
04891 XSH_ASSURE_NOT_NULL_MSG(response,"NULL input response frame!Exit.");
04892
04893 check(name_s=cpl_frame_get_filename(extracted_sci));
04894 check(tag_s=cpl_frame_get_tag(extracted_sci));
04895
04896 name_o=cpl_sprintf("%s.fits",tag_o);
04897 next_sci=cpl_frame_get_nextensions(extracted_sci);
04898 next_res=cpl_frame_get_nextensions(response);
04899 xsh_msg("Multiply by response function");
04900 check(name_r=cpl_frame_get_filename(response));
04901
04902 for(ext=0, order=0;ext<next_sci;ext+=3,order++) {
04903 xsh_free_propertylist(&hdat);
04904 xsh_free_propertylist(&herr);
04905 xsh_free_propertylist(&hqua);
04906
04907 check(hdat=cpl_propertylist_load(name_s,ext+0));
04908 check(herr=cpl_propertylist_load(name_s,ext+1));
04909 check(hqua=cpl_propertylist_load(name_s,ext+2));
04910
04911 naxis=xsh_pfits_get_naxis(hdat);
04912
04913 if(naxis == 1) {
04914
04915 check(data_vec=cpl_vector_load(name_s,ext+0));
04916 check(errs_vec=cpl_vector_load(name_s,ext+1));
04917
04918 xsh_free_image(&data_sci);
04919 xsh_free_image(&errs_sci);
04920 check(data_sci=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
04921 check(errs_sci=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
04922
04923 xsh_free_vector(&data_vec);
04924 xsh_free_vector(&errs_vec);
04925
04926 } else {
04927
04928 xsh_free_image(&data_sci);
04929 xsh_free_image(&errs_sci);
04930 xsh_free_image(&qual_sci);
04931 check(data_sci=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
04932 check(errs_sci=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
04933 check(qual_sci=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
04934
04935 }
04936
04937 xsh_free_image(&data_tmp);
04938 xsh_free_image(&errs_tmp);
04939 data_tmp=cpl_image_cast(data_sci,CPL_TYPE_DOUBLE);
04940 errs_tmp=cpl_image_cast(errs_sci,CPL_TYPE_DOUBLE);
04941 xsh_free_image(&data_sci);
04942 xsh_free_image(&errs_sci);
04943 xsh_free_table(&response_table);
04944 if(next_res>1) {
04945 check(response_table=cpl_table_load(name_r,order+1,0));
04946 } else {
04947 check(response_table=cpl_table_load(name_r,next_res,0));
04948 }
04949
04950
04951
04952
04953 check(nbins = cpl_image_get_size_x(data_tmp));
04954 check(ntraces = cpl_image_get_size_y(data_tmp));
04955
04956 check(fluxcal_science_data = cpl_image_get_data_double(data_tmp));
04957 check(fluxcal_science_noise = cpl_image_get_data_double(errs_tmp));
04958
04959 check_msg( lambda_start = xsh_pfits_get_crval1(hdat),
04960 "Error reading start wavelength from reduced science header");
04961 check_msg( lambda_step = xsh_pfits_get_cdelt1(hdat),
04962 "Error reading bin width from header");
04963
04964 check(cpl_table_cast_column(response_table,"LAMBDA","DLAMBDA",CPL_TYPE_DOUBLE));
04965 check(cpl_table_cast_column(response_table,"FLUX","DFLUX",CPL_TYPE_DOUBLE));
04966
04967 for (bin = 1; bin <= nbins; bin++)
04968 {
04969 double lambda;
04970 double response;
04971 int trace;
04972 int istart = 0;
04973
04974 lambda = lambda_start + (bin-1) * lambda_step;
04975 check_msg( response =
04976 xsh_spline_hermite_table(lambda, response_table,
04977 "DLAMBDA", "DFLUX", &istart),
04978 "Error interpolating response curve at lambda = %f wlu", lambda);
04979
04980 xsh_msg_dbg_medium("ext=%d response=%g",ext,response);
04981
04982 for (trace = 1; trace <= ntraces; trace++)
04983 {
04984
04985
04986
04987
04988 fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
04989
04990 fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
04991
04992
04993
04994 }
04995 }
04996
04997 data_sci=cpl_image_cast(data_tmp,XSH_PRE_DATA_TYPE);
04998 errs_sci=cpl_image_cast(errs_tmp,XSH_PRE_ERRS_TYPE);
04999 xsh_free_image(&data_tmp);
05000 xsh_free_image(&errs_tmp);
05001
05002 cpl_table_erase_column(response_table,"DLAMBDA");
05003 cpl_table_erase_column(response_table,"DFLUX");
05004 check( xsh_pfits_set_pcatg( hdat, tag_o));
05005
05006 if(naxis==1) {
05007 check(data_vec=xsh_image_to_vector(data_sci));
05008 check(errs_vec=xsh_image_to_vector(errs_sci));
05009 if(ext==0) {
05010 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05011 } else {
05012 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05013 }
05014 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05015 check(qual_vec=cpl_vector_load(name_s,ext+2));
05016 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05017
05018 } else {
05019 if(ext==0) {
05020 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05021 } else {
05022 check(cpl_image_save(data_sci,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05023 }
05024 check(cpl_image_save(errs_sci,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05025 check(cpl_image_save(qual_sci,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05026 }
05027
05028 }
05029
05030
05031 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05032
05033 cleanup:
05034
05035 cpl_free(name_o);
05036
05037 xsh_free_image(&data_sci);
05038 xsh_free_image(&errs_sci);
05039 xsh_free_image(&qual_sci);
05040 xsh_free_image(&data_sci);
05041 xsh_free_image(&errs_sci);
05042
05043 xsh_free_vector(&data_vec);
05044 xsh_free_vector(&errs_vec);
05045 xsh_free_vector(&qual_vec);
05046
05047 xsh_free_table(&response_table);
05048 xsh_free_propertylist(&hdat);
05049 xsh_free_propertylist(&herr);
05050 xsh_free_propertylist(&hqua);
05051
05052 return result;
05053 }
05054
05055 static cpl_error_code
05056 xsh_util_get_infsup(double* piw,
05057 double w,
05058 int i_start,
05059 int i_end,
05060 int* i_inf,
05061 int* i_sup)
05062 {
05063
05064 int i=0;
05065 for(i = i_start;i < i_end;i++) {
05066 if (piw[i] < w) {
05067 *i_inf=i;
05068 *i_sup=i+1;
05069 }
05070 }
05071
05072 return cpl_error_get_code();
05073 }
05074
05075
05076 static double
05077 xsh_spectrum_integrate(double* pif,
05078 double* piw,
05079 int i1_inf,
05080 int i1_sup,
05081 int i2_inf,
05082 int i2_sup,
05083 double wave,
05084 double wstep)
05085 {
05086
05087 double sum1=0;
05088 double sum2=0;
05089 double sum3=0;
05090 int i=0;
05091
05092
05093 for(i=i1_sup;i<i2_inf;i++) {
05094
05095
05096
05097 sum2+=pif[i]*(piw[i+1]-piw[i]);
05098
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109 }
05110
05111
05112
05113
05114 return (sum1+sum2+sum3);
05115 }
05116
05117
05129
05130 cpl_frame*
05131 xsh_spectrum_resample(cpl_frame* frame_inp,
05132 const double wstep,
05133 const double wmin,
05134 const double wmax,
05135 xsh_instrument* instr)
05136 {
05137
05138 cpl_frame* result=NULL;
05139 cpl_table* tab_inp=NULL;
05140 cpl_table* tab_out=NULL;
05141 int nrow_inp=0;
05142 int nrow_out=0;
05143 int i=0;
05144
05145 double wave_min=0;
05146 double wave_max=0;
05147 double wave_start=0;
05148
05149 const char* fname=NULL;
05150 double* pow=NULL;
05151 double* pof=NULL;
05152 double* piw=NULL;
05153 double* pif=NULL;
05154
05155 double wo1=0;
05156 double wo2=0;
05157
05158 int istep=0;
05159
05160 int i1_inf=0;
05161 int i1_sup=0;
05162 int i2_inf=0;
05163 int i2_sup=0;
05164
05165 int i_start=0;
05166 int i_end=0;
05167 double hstep=0;
05168 const char* tag=NULL;
05169 char* name=NULL;
05170 cpl_propertylist* plist=NULL;
05171 int nsel=0;
05172
05173
05174 check(fname=cpl_frame_get_filename(frame_inp));
05175 tag=cpl_frame_get_tag(frame_inp);
05176 plist=cpl_propertylist_load(fname,0);
05177
05178
05179
05180 tab_inp=cpl_table_load(fname,1,0);
05181 nrow_inp=cpl_table_get_nrow(tab_inp);
05182 wave_min=cpl_table_get_column_min(tab_inp,"LAMBDA");
05183 wave_max=cpl_table_get_column_max(tab_inp,"LAMBDA");
05184
05185 wave_min=(wave_min>wmin) ? wave_min : wmin;
05186 wave_max=(wave_max<wmax) ? wave_max : wmax;
05187
05188
05189 wave_start=floor(wave_min);
05190
05191
05192 if( xsh_instrument_get_arm(instr) == XSH_ARM_UVB){
05193 wave_start=(wave_start>XSH_ATM_EXT_UVB_WAV_MIN)? wave_start : XSH_ATM_EXT_UVB_WAV_MIN;
05194 }
05195 xsh_msg("Resample ref flux std spectrum to %g [nm] step",wstep);
05196
05197
05198
05199
05200
05201 nrow_out=ceil((wave_max-wave_start)/wstep);
05202 tab_out=cpl_table_new(nrow_out);
05203
05204 cpl_table_new_column(tab_out,"LAMBDA",CPL_TYPE_DOUBLE);
05205 cpl_table_new_column(tab_out,"FLUX",CPL_TYPE_DOUBLE);
05206 cpl_table_new_column(tab_out,"BIN_WIDTH",CPL_TYPE_DOUBLE);
05207
05208 cpl_table_fill_column_window_double(tab_out,"LAMBDA",0,nrow_out,0.);
05209 cpl_table_fill_column_window_double(tab_out,"FLUX",0,nrow_out,0.);
05210 cpl_table_fill_column_window_double(tab_out,"BIN_WIDTH",0,nrow_out,wstep);
05211
05212
05213 pow=cpl_table_get_data_double(tab_out,"LAMBDA");
05214 pof=cpl_table_get_data_double(tab_out,"FLUX");
05215
05216 piw=cpl_table_get_data_double(tab_inp,"LAMBDA");
05217 pif=cpl_table_get_data_double(tab_inp,"FLUX");
05218
05219 hstep=0.5*wstep;
05220
05221 i_start=0;
05222 i_end=nrow_inp;
05223
05224
05225 istep=(int) (wstep/(wave_max-wave_min)*nrow_inp+0.5);
05226 istep*=4;
05227
05228
05229
05230
05231 for(i=0;i<nrow_out;i++) {
05232 pow[i]=wave_start+i*wstep;
05233 wo1=pow[i]-hstep;
05234 wo2=pow[i]+hstep;
05235 i_start=0;
05236 i_end=nrow_inp;
05237
05238
05239
05240
05241
05242
05243
05244
05245 xsh_util_get_infsup(piw,wo1,i_start,i_end,&i1_inf,&i1_sup);
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262
05263
05264
05265 xsh_util_get_infsup(piw,wo2,i_start,i_end,&i2_inf,&i2_sup);
05266
05267
05268
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292 pof[i]=xsh_spectrum_integrate(pif,piw,i1_inf,i1_sup,
05293 i2_inf,i2_sup,pow[i],wstep);
05294
05295
05296
05297
05298
05299
05300 }
05301
05302 nsel=cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_LESS_THAN,wmin);
05303 cpl_table_erase_selected(tab_out);
05304 nsel=cpl_table_and_selected_double(tab_out,"LAMBDA",CPL_GREATER_THAN,wmax);
05305 cpl_table_erase_selected(tab_out);
05306
05307 name=cpl_sprintf("RESAMPLED_%s_%s.fits",tag,
05308 xsh_instrument_arm_tostring( instr));
05309
05310 check(cpl_table_save(tab_out,plist,NULL,name,CPL_IO_DEFAULT));
05311 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_TABLE,
05312 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05313
05314
05315 cleanup:
05316 xsh_free_propertylist(&plist);
05317 xsh_free_table(&tab_inp);
05318 xsh_free_table(&tab_out);
05319 cpl_free(name);
05320
05321 return result;
05322 }
05323
05324
05331
05332 cpl_frame*
05333 xsh_util_frameset_collapse_mean(cpl_frameset* set,
05334 xsh_instrument* instrument)
05335 {
05336 cpl_frame* result=NULL;
05337 cpl_frame* frm=NULL;
05338
05339 cpl_image* ima=NULL;
05340 cpl_image* err=NULL;
05341
05342 cpl_image* ima_sum=NULL;
05343 cpl_image* err_sum=NULL;
05344 cpl_image* qua_sum=NULL;
05345 cpl_propertylist* hdat=NULL;
05346 cpl_propertylist* herr=NULL;
05347 cpl_propertylist* hqua=NULL;
05348 char* name=NULL;
05349 char* tag=NULL;
05350 const char* fname=NULL;
05351 int size=0;
05352 int i=0;
05353
05354
05355 size=cpl_frameset_get_size(set);
05356 for(i=0;i<size;i++) {
05357
05358 frm=cpl_frameset_get_frame(set,i);
05359 fname=cpl_frame_get_filename(frm);
05360
05361 ima=cpl_image_load(fname,XSH_PRE_DATA_TYPE,0,0);
05362 err=cpl_image_load(fname,XSH_PRE_ERRS_TYPE,0,1);
05363
05364 cpl_image_multiply(err,err);
05365 if(i==0) {
05366 ima_sum=cpl_image_duplicate(ima);
05367 err_sum=cpl_image_duplicate(err);
05368 } else {
05369 cpl_image_add(ima_sum,ima);
05370 cpl_image_add(err_sum,err);
05371 }
05372
05373 xsh_free_image(&ima);
05374 xsh_free_image(&err);
05375
05376 }
05377
05378 cpl_image_divide_scalar(ima_sum,size);
05379 cpl_image_divide_scalar(err_sum,size);
05380
05381
05382 check(cpl_image_power(err_sum,0.5));
05383
05384
05385 qua_sum=cpl_image_load(fname,XSH_PRE_QUAL_TYPE,0,2);
05386
05387 frm=cpl_frameset_get_frame(set,0);
05388 fname=cpl_frame_get_filename(frm);
05389 hdat=cpl_propertylist_load(fname,0);
05390 herr=cpl_propertylist_load(fname,1);
05391 hqua=cpl_propertylist_load(fname,2);
05392
05393 name=cpl_sprintf("SKY_AVG_%s.fits",xsh_instrument_arm_tostring( instrument));
05394 tag=cpl_sprintf("SKY_AVG_%s",xsh_instrument_arm_tostring( instrument));
05395
05396 check(cpl_image_save(ima_sum,name,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05397 check(cpl_image_save(err_sum,name,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05398 check(cpl_image_save(qua_sum,name,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05399 result=xsh_frame_product(name,tag,CPL_FRAME_TYPE_IMAGE,
05400 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05401
05402 cleanup:
05403
05404 xsh_free_image(&ima);
05405 xsh_free_image(&err);
05406
05407 xsh_free_image(&ima_sum);
05408 xsh_free_image(&err_sum);
05409 xsh_free_image(&qua_sum);
05410
05411
05412 cpl_free(name);
05413 cpl_free(tag);
05414
05415 return result;
05416 }
05417
05418
05419
05420
05439 cpl_error_code
05440 xsh_normalize_spectrum_image_slice(const char* name_s,
05441 const char* tag_o,
05442 const int ext,
05443 const int binx,
05444 const double gain,
05445 const double exptime,
05446 const double airmass,
05447 const cpl_table* tbl_atm_ext)
05448 {
05449
05450
05451 cpl_image* data_ima=NULL;
05452 cpl_image* errs_ima=NULL;
05453 cpl_image* qual_ima=NULL;
05454 cpl_image* data_nrm=NULL;
05455 cpl_image* errs_nrm=NULL;
05456
05457 cpl_image* data_tmp=NULL;
05458 cpl_image* errs_tmp=NULL;
05459
05460 cpl_image* data_nrm_tmp=NULL;
05461 cpl_image* errs_nrm_tmp=NULL;
05462
05463 cpl_vector* data_vec=NULL;
05464 cpl_vector* errs_vec=NULL;
05465 cpl_vector* qual_vec=NULL;
05466
05467 cpl_propertylist* hdat=NULL;
05468 cpl_propertylist* herr=NULL;
05469 cpl_propertylist* hqua=NULL;
05470 int naxis=0;
05471 char name_o[80];
05472
05473 sprintf(name_o,"%s.fits",tag_o);
05474
05475 xsh_free_propertylist(&hdat);
05476 xsh_free_propertylist(&herr);
05477 xsh_free_propertylist(&hqua);
05478
05479 hdat=cpl_propertylist_load(name_s,ext+0);
05480 herr=cpl_propertylist_load(name_s,ext+1);
05481 hqua=cpl_propertylist_load(name_s,ext+2);
05482
05483
05484 naxis=xsh_pfits_get_naxis(hdat);
05485 xsh_pfits_set_pcatg(hdat,tag_o);
05486 if(naxis == 1) {
05487
05488 check(data_vec=cpl_vector_load(name_s,ext+0));
05489 check(errs_vec=cpl_vector_load(name_s,ext+1));
05490 xsh_free_image(&data_ima);
05491 xsh_free_image(&errs_ima);
05492 check(data_ima=xsh_vector_to_image(data_vec,XSH_PRE_DATA_TYPE));
05493 check(errs_ima=xsh_vector_to_image(errs_vec,XSH_PRE_ERRS_TYPE));
05494 xsh_free_vector(&data_vec);
05495 xsh_free_vector(&errs_vec);
05496
05497 } else {
05498
05499 xsh_free_image(&data_ima);
05500 xsh_free_image(&errs_ima);
05501 xsh_free_image(&qual_ima);
05502 check(data_ima=cpl_image_load(name_s,XSH_PRE_DATA_TYPE,0,ext+0));
05503 check(errs_ima=cpl_image_load(name_s,XSH_PRE_ERRS_TYPE,0,ext+1));
05504 check(qual_ima=cpl_image_load(name_s,XSH_PRE_QUAL_TYPE,0,ext+2));
05505
05506 }
05507 xsh_free_image(&data_tmp);
05508 xsh_free_image(&errs_tmp);
05509 data_tmp=cpl_image_cast(data_ima,CPL_TYPE_DOUBLE);
05510 errs_tmp=cpl_image_cast(errs_ima,CPL_TYPE_DOUBLE);
05511
05512 xsh_free_image(&data_nrm_tmp);
05513 xsh_free_image(&errs_nrm_tmp);
05514
05515 check(data_nrm_tmp=xsh_normalize_spectrum_image(data_tmp,errs_tmp,hdat,
05516 binx,gain,exptime,airmass,1,
05517 tbl_atm_ext,&errs_nrm_tmp));
05518
05519 xsh_free_image(&data_nrm);
05520 xsh_free_image(&errs_nrm);
05521 check(data_nrm=cpl_image_cast(data_nrm_tmp,CPL_TYPE_FLOAT));
05522 check(errs_nrm=cpl_image_cast(errs_nrm_tmp,CPL_TYPE_FLOAT));
05523
05524 if(naxis==1) {
05525 xsh_free_vector(&data_vec);
05526 xsh_free_vector(&errs_vec);
05527
05528 check(data_vec=xsh_image_to_vector(data_nrm));
05529 check(errs_vec=xsh_image_to_vector(errs_nrm));
05530
05531 if(ext==0) {
05532 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_DEFAULT));
05533 } else {
05534 check(cpl_vector_save(data_vec,name_o,XSH_SPECTRUM_DATA_BPP,hdat,CPL_IO_EXTEND));
05535 }
05536 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,herr,CPL_IO_EXTEND));
05537 xsh_free_vector(&qual_vec);
05538 check(qual_vec=cpl_vector_load(name_s,ext+2));
05539 check(cpl_vector_save(errs_vec,name_o,XSH_SPECTRUM_ERRS_BPP,hqua,CPL_IO_EXTEND));
05540
05541
05542 } else {
05543 if(ext==0) {
05544 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_DEFAULT));
05545 } else {
05546 check(cpl_image_save(data_nrm,name_o,XSH_PRE_DATA_BPP,hdat,CPL_IO_EXTEND));
05547 }
05548 check(cpl_image_save(errs_nrm,name_o,XSH_PRE_ERRS_BPP,herr,CPL_IO_EXTEND));
05549 check(cpl_image_save(qual_ima,name_o,XSH_PRE_QUAL_BPP,hqua,CPL_IO_EXTEND));
05550
05551 }
05552
05553
05554
05555 cleanup:
05556 xsh_free_image(&data_ima);
05557 xsh_free_image(&errs_ima);
05558 xsh_free_image(&qual_ima);
05559 xsh_free_image(&data_nrm);
05560 xsh_free_image(&errs_nrm);
05561 xsh_free_image(&data_tmp);
05562 xsh_free_image(&errs_tmp);
05563 xsh_free_image(&data_nrm_tmp);
05564 xsh_free_image(&errs_nrm_tmp);
05565
05566 xsh_free_propertylist(&hdat);
05567 xsh_free_propertylist(&herr);
05568 xsh_free_propertylist(&hqua);
05569
05570 xsh_free_vector(&data_vec);
05571 xsh_free_vector(&errs_vec);
05572 xsh_free_vector(&qual_vec);
05573
05574 return cpl_error_get_code();
05575 }
05576
05577
05578
05595
05596 cpl_frame *
05597 xsh_normalize_spectrum(const cpl_frame *obj_frame,
05598 const cpl_frame *atm_ext_frame,
05599 cpl_boolean correct_binning,
05600 xsh_instrument* instrument,
05601 const char* tag_o)
05602 {
05603
05604 cpl_frame* result=NULL;
05605 const char* name_s=NULL;
05606 const char* aname=NULL;
05607
05608 cpl_table* tbl_atm_ext=NULL;
05609 cpl_propertylist* hdat=NULL;
05610
05611 char* name_o=NULL;
05612 int binx=1;
05613 double gain=0;
05614 double exptime=0;
05615 double airmass=0;
05616
05617 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05618 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05619
05620 name_s=cpl_frame_get_filename(obj_frame);
05621 aname=cpl_frame_get_filename(atm_ext_frame);
05622 tbl_atm_ext=cpl_table_load(aname,1,0);
05623
05624 cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE);
05625 cpl_table_cast_column( tbl_atm_ext,"LA_SILLA","D_LA_SILLA",CPL_TYPE_DOUBLE);
05626
05627
05628 hdat=cpl_propertylist_load(name_s,0);
05629 exptime = xsh_pfits_get_exptime(hdat);
05630 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05631
05632 gain=1./2.12;
05633 } else {
05634 gain = xsh_pfits_get_gain(hdat);
05635 }
05636
05637 if (correct_binning) {
05638
05639 binx = xsh_pfits_get_biny(hdat);
05640 } else {
05641 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05642 binx = 1;
05643 }
05644 airmass=xsh_pfits_get_airm_mean(hdat);
05645 name_o=cpl_sprintf("%s.fits",tag_o);
05646
05647 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,0,binx,gain,
05648 exptime,airmass,tbl_atm_ext));
05649
05650 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05651
05652 cleanup:
05653
05654 xsh_free_table(&tbl_atm_ext);
05655 xsh_free_propertylist(&hdat);
05656 cpl_free(name_o);
05657
05658 return result;
05659
05660 }
05661
05662
05663
05664
05665
05681
05682 cpl_frame *
05683 xsh_normalize_spectrum_ord(const cpl_frame *obj_frame,
05684 const cpl_frame *atm_ext_frame,
05685 cpl_boolean correct_binning,
05686 xsh_instrument* instrument,
05687 const char* tag_o)
05688 {
05689
05690 cpl_frame* result=NULL;
05691 const char* name_s=NULL;
05692 const char* aname=NULL;
05693
05694 cpl_table* tbl_atm_ext=NULL;
05695 cpl_propertylist* hdat=NULL;
05696 char* name_o=NULL;
05697
05698 int next=0;
05699 int ext=0;
05700 int binx=1;
05701 double gain=0;
05702 double exptime=0;
05703 double airmass=0;
05704
05705 XSH_ASSURE_NOT_NULL_MSG(obj_frame,"Null input object frame");
05706 XSH_ASSURE_NOT_NULL_MSG(atm_ext_frame,"Null input atm ext frame");
05707
05708 next=cpl_frame_get_nextensions( obj_frame);
05709 name_s=cpl_frame_get_filename(obj_frame);
05710
05711 aname=cpl_frame_get_filename(atm_ext_frame);
05712 tbl_atm_ext=cpl_table_load(aname,1,0);
05713 cpl_table_cast_column( tbl_atm_ext,"LAMBDA","D_LAMBDA",CPL_TYPE_DOUBLE);
05714 cpl_table_cast_column( tbl_atm_ext,"LA_SILLA","D_LA_SILLA",CPL_TYPE_DOUBLE);
05715 name_o=cpl_sprintf("%s.fits",tag_o);
05716
05717 hdat=cpl_propertylist_load(name_s,0);
05718
05719 exptime = xsh_pfits_get_exptime(hdat);
05720 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
05721
05722 gain=1./2.12;
05723 } else {
05724 gain = xsh_pfits_get_gain(hdat);
05725 }
05726
05727 if (correct_binning) {
05728
05729 binx = xsh_pfits_get_biny(hdat);
05730 } else {
05731 xsh_msg_dbg_medium("Spectrum will not be normalized to unit binning");
05732 binx = 1;
05733 }
05734 airmass=xsh_pfits_get_airm_mean(hdat);
05735
05736 for(ext=0;ext<next;ext+=3) {
05737 check(xsh_normalize_spectrum_image_slice(name_s,tag_o,ext,binx,gain,
05738 exptime,airmass,tbl_atm_ext));
05739 }
05740
05741 result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
05742
05743 cleanup:
05744
05745 xsh_free_table(&tbl_atm_ext);
05746 xsh_free_propertylist(&hdat);
05747 cpl_free(name_o);
05748
05749 return result;
05750
05751 }
05752
05753
05775
05776
05777 cpl_image *
05778 xsh_normalize_spectrum_image(const cpl_image *spectrum,
05779 const cpl_image *spectrum_error,
05780 const cpl_propertylist *spectrum_header,
05781 const int binx,
05782 const double gain,
05783 const double exptime,
05784 const double airmass,
05785 const int n_traces,
05786 const cpl_table *atm_extinction,
05787 cpl_image **scaled_error)
05788 {
05789 cpl_image *scaled = NULL;
05790 int norders, ny, nx;
05791
05792 XSH_ASSURE_NOT_NULL_MSG(spectrum,"Null input spectrum");
05793 XSH_ASSURE_NOT_NULL_MSG(scaled_error,"Null input scaled error");
05794 XSH_ASSURE_NOT_NULL_MSG(spectrum_error, "Null input spectrum error");
05795 XSH_ASSURE_NOT_NULL_MSG(spectrum_header,"Null input spectrum header");
05796 XSH_ASSURE_NOT_NULL_MSG(atm_extinction,"Null input atmospheric extinction table");
05797
05798 nx = cpl_image_get_size_x(spectrum);
05799 ny = cpl_image_get_size_y(spectrum);
05800
05801
05802 if (spectrum_error != NULL)
05803 {
05804 assure( nx == cpl_image_get_size_x(spectrum_error) &&
05805 ny == cpl_image_get_size_y(spectrum_error), CPL_ERROR_INCOMPATIBLE_INPUT,
05806 "Error spectrum geometry differs from spectrum: %dx%d vs. %dx%d",
05807 cpl_image_get_size_x(spectrum_error),
05808 cpl_image_get_size_y(spectrum_error),
05809 nx, ny);
05810 }
05811
05812 assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
05813 "Spectrum image height (%d) is not a multiple of "
05814 "the number of traces (%d). Confused, bailing out",
05815 ny, n_traces);
05816
05817 norders = ny / n_traces;
05818
05819
05820
05821
05822 assure( exptime > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive exposure time: %f s", exptime);
05823 assure( gain > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive gain: %f", gain);
05824 assure( binx > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal binning: %d", binx);
05825
05826 xsh_msg_dbg_medium("Correcting for exposure time = %f s, gain = %f, binx = %d", exptime, gain, binx);
05827
05828 check_msg(scaled=cpl_image_divide_scalar_create(spectrum,exptime*gain*binx),
05829 "Error correcting spectrum for gain, exposure time, binning");
05830
05831 if (scaled_error != NULL)
05832 {
05833 check_msg( *scaled_error=cpl_image_divide_scalar_create(spectrum_error,
05834 exptime*gain*binx),
05835 "Error correcting rebinned spectrum for gain, exposure time, binning");
05836 }
05837
05838
05839
05840
05841 {
05842 double dlambda, lambda_start;
05843 int order;
05844
05845 xsh_msg_dbg_medium("Correcting for extinction through airmass %f", airmass);
05846 check_msg( dlambda = xsh_pfits_get_cdelt1(spectrum_header),
05847 "Error reading bin width from header");
05848
05849 for (order = 1; order <= norders; order++)
05850 {
05851 int trace;
05852
05853
05854
05855
05856
05857 if (norders == 1)
05858 {
05859 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
05860 "Error reading start wavelength from header");
05861 }
05862 else
05863 {
05864
05865 check_msg( lambda_start = xsh_pfits_get_crval1(spectrum_header),
05866 "Error reading start wavelength from header");
05867 }
05868
05869 for (trace = 1; trace <= n_traces; trace++)
05870 {
05871 int spectrum_row = (order - 1)*n_traces + trace;
05872 int x;
05873
05874 for (x = 1; x <= nx; x++)
05875 {
05876 int pis_rejected1;
05877 int pis_rejected2;
05878 double flux;
05879 double dflux = 0;
05880 double extinction;
05881 double lambda;
05882
05883 lambda = lambda_start + (x-1) * dlambda;
05884
05885 flux = cpl_image_get(scaled, x, spectrum_row, &pis_rejected1);
05886 if (scaled_error != NULL)
05887 {
05888 dflux = cpl_image_get(*scaled_error, x,
05889 spectrum_row, &pis_rejected2);
05890 }
05891
05892 if (!pis_rejected1 && (scaled_error == NULL || !pis_rejected2))
05893 {
05894 int istart = 0;
05895
05896
05897 check_msg( extinction =
05898 xsh_spline_hermite_table(
05899 lambda, atm_extinction,
05900 "D_LAMBDA", "D_LA_SILLA", &istart),
05901 "Error interpolating extinction coefficient");
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913 cpl_image_set(
05914 scaled, x, spectrum_row,
05915 flux * pow(10, 0.4 * extinction * airmass));
05916 if (scaled_error != NULL)
05917 {
05918 cpl_image_set(
05919 *scaled_error, x, spectrum_row,
05920 dflux * pow(10, 0.4 * extinction * airmass));
05921 }
05922 }
05923 else
05924 {
05925 cpl_image_reject(scaled, x, spectrum_row);
05926 if (scaled_error != NULL)
05927 {
05928 cpl_image_reject(*scaled_error, x, spectrum_row);
05929 }
05930 }
05931 }
05932
05933 }
05934
05935 }
05936 }
05937
05938 cleanup:
05939 if (cpl_error_get_code() != CPL_ERROR_NONE)
05940 {
05941 xsh_free_image(&scaled);
05942 if (scaled_error != NULL)
05943 {
05944 xsh_free_image(scaled_error);
05945 }
05946 }
05947
05948 return scaled;
05949 }
05950
05951 static double
05952 xsh_iterpol_linear(double* data_x,double* data_y,int ndata,double x,
05953 int* i_inf,int* i_sup)
05954 {
05955 int i=0;
05956 double y=0;
05957 int i_min=0;
05958 int i_max=0;
05959 double x1=0;
05960 double x2=0;
05961 double y1=0;
05962 double y2=0;
05963
05964 i_min=((*i_inf)>0) ? (*i_inf):0;
05965 i_max=((*i_sup)<ndata) ? (*i_sup):ndata;
05966
05967
05968 for(i=0;i<ndata;i++) {
05969
05970 if(data_x[i]>x) {
05971 y1=data_y[i-1];
05972 y2=data_y[i];
05973 x1=data_x[i-1];
05974 x2=data_x[i];
05975 *i_inf=i-1;
05976 *i_sup=i+1;
05977 break;
05978 }
05979 }
05980
05981
05982 y=(y2-y1)/(x2-x1)*(x-x1)+y1;
05983
05984 return y;
05985 }
05986
05994 cpl_frame*
05995 xsh_spectrum_interpolate_linear(cpl_frame* table_frame,
05996 const double wstep,
05997 const double wmin,
05998 const double wmax)
05999 {
06000
06001 cpl_frame* result=NULL;
06002 cpl_table* table_i=NULL;
06003 cpl_table* table_o=NULL;
06004 const char* name_i=NULL;
06005 const char* tag_i=NULL;
06006
06007 char* name_o=NULL;
06008 char* tag_o=NULL;
06009
06010 cpl_propertylist* plist=NULL;
06011 int nrows_i=0;
06012 int nrows_o=0;
06013 int row=0;
06014
06015 double* pwave_i=NULL;
06016 double* pflux_i=NULL;
06017 double* pwave_o=NULL;
06018 double* pflux_o=NULL;
06019 int i_inf=0;
06020 int i_sup=0;
06021
06022 int istart = 0;
06023
06024 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06025 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06026 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06027
06028 name_i=cpl_frame_get_filename(table_frame);
06029 tag_i=cpl_frame_get_tag(table_frame);
06030 table_i=cpl_table_load(name_i,1,0);
06031 nrows_i=cpl_table_get_nrow(table_i);
06032 plist=cpl_propertylist_load(name_i,0);
06033 nrows_o=(int)((wmax-wmin)/wstep+0.5);
06034 table_o=cpl_table_new(nrows_o);
06035 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06036 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06037 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows_o,0.));
06038 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows_o,0.));
06039 check(pwave_i=cpl_table_get_data_double(table_i,"LAMBDA"));
06040 check(pflux_i=cpl_table_get_data_double(table_i,"FLUX"));
06041 check(pwave_o=cpl_table_get_data_double(table_o,"LAMBDA"));
06042 check(pflux_o=cpl_table_get_data_double(table_o,"FLUX"));
06043 i_inf=0;
06044 i_sup=nrows_o;
06045
06046 for (row = 0; row < nrows_o; row++)
06047 {
06048
06049 pwave_o[row]= wmin + row * wstep;
06050 pflux_o[row]= xsh_iterpol_linear(pwave_i,pflux_i,nrows_i,pwave_o[row],
06051 &i_inf,&i_sup);
06052
06053
06054 }
06055 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06056 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06057 xsh_pfits_set_pcatg(plist,tag_o);
06058 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06059 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06060 CPL_FRAME_GROUP_PRODUCT,
06061 CPL_FRAME_LEVEL_FINAL));
06062
06063 cleanup:
06064
06065
06066 xsh_free_table(&table_i);
06067 xsh_free_table(&table_o);
06068 xsh_free_propertylist(&plist);
06069 cpl_free(name_o);
06070 cpl_free(tag_o);
06071
06072 return result;
06073
06074 }
06075
06076
06077
06078
06086 cpl_frame*
06087 xsh_spectrum_interpolate(cpl_frame* table_frame,
06088 const double wstep,
06089 const double wmin,
06090 const double wmax)
06091 {
06092
06093 cpl_frame* result=NULL;
06094 cpl_table* table_i=NULL;
06095 cpl_table* table_o=NULL;
06096 const char* name_i=NULL;
06097 const char* tag_i=NULL;
06098
06099 char* name_o=NULL;
06100 char* tag_o=NULL;
06101
06102 cpl_propertylist* plist=NULL;
06103 int nrows=0;
06104 int row=0;
06105 double wave=0;
06106 double flux_o=0;
06107 double* pwave=NULL;
06108 double* pflux=NULL;
06109
06110 int istart = 0;
06111
06112 XSH_ASSURE_NOT_NULL_MSG(table_frame,"Null input table frame");
06113 XSH_ASSURE_NOT_ILLEGAL_MSG(wmax>wmin,"wmax < wmin");
06114 XSH_ASSURE_NOT_ILLEGAL_MSG(wstep>0,"wstep <= 0");
06115
06116 name_i=cpl_frame_get_filename(table_frame);
06117 tag_i=cpl_frame_get_tag(table_frame);
06118 table_i=cpl_table_load(name_i,1,0);
06119 plist=cpl_propertylist_load(name_i,0);
06120 nrows=(int)((wmax-wmin)/wstep+0.5);
06121 table_o=cpl_table_new(nrows);
06122 cpl_table_new_column(table_o,"LAMBDA",CPL_TYPE_DOUBLE);
06123 cpl_table_new_column(table_o,"FLUX",CPL_TYPE_DOUBLE);
06124 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06125 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06126 check(cpl_table_fill_column_window_double(table_o,"LAMBDA",0,nrows,0.));
06127 check(cpl_table_fill_column_window_double(table_o,"FLUX",0,nrows,0.));
06128 check(pwave=cpl_table_get_data_double(table_o,"LAMBDA"));
06129 check(pflux=cpl_table_get_data_double(table_o,"FLUX"));
06130
06131 for (row = 0; row < nrows; row++)
06132 {
06133
06134 wave = wmin + row * wstep;
06135
06136 check_msg( flux_o = xsh_spline_hermite_table(wave, table_i,
06137 "LAMBDA", "FLUX", &istart),
06138 "Error interpolating curve at lambda = %f wlu", wave);
06139 pwave[row]=wave;
06140 pflux[row]=flux_o;
06141
06142 xsh_msg_dbg_medium("interpolated flux[%g]=%g",wave,flux_o);
06143 }
06144 tag_o=cpl_sprintf("INTERPOL_%s",tag_i);
06145 name_o=cpl_sprintf("INTERPOL_%s.fits",tag_i);
06146 xsh_pfits_set_pcatg(plist,tag_o);
06147 check(cpl_table_save(table_o,plist,NULL,name_o,CPL_IO_DEFAULT));
06148 check(result=xsh_frame_product(name_o,tag_o,CPL_FRAME_TYPE_TABLE,
06149 CPL_FRAME_GROUP_PRODUCT,
06150 CPL_FRAME_LEVEL_FINAL));
06151
06152 cleanup:
06153
06154
06155 xsh_free_table(&table_i);
06156 xsh_free_table(&table_o);
06157 xsh_free_propertylist(&plist);
06158 cpl_free(name_o);
06159 cpl_free(tag_o);
06160
06161 return result;
06162
06163 }
06164
06165
06166
06176 void
06177 xsh_array_clip_mean( cpl_array *array,
06178 double kappa,
06179 int niter,
06180 double frac_min,
06181 double *mean,
06182 double *stdev)
06183 {
06184 int i, j, size;
06185 double mean_val;
06186 double sigma, frac;
06187 int *flags = NULL;
06188 int nb_rejected = 0, total_rejected=0;
06189
06190 XSH_ASSURE_NOT_NULL( array);
06191 XSH_ASSURE_NOT_NULL( mean);
06192 XSH_ASSURE_NOT_NULL( stdev);
06193
06194 check( mean_val = cpl_array_get_mean( array));
06195 check( sigma = cpl_array_get_stdev( array));
06196 check( size = cpl_array_get_size( array));
06197
06198 XSH_CALLOC( flags, int, size);
06199
06200 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06201 xsh_msg_dbg_medium("Accepted fraction %f Mean %f sigma %f", 1.0, mean_val, sigma);
06202
06203
06204 for( i=1; i<= niter; i++) {
06205 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06206 nb_rejected = 0;
06207 for( j=0; j< size; j++){
06208 double val=0.0;
06209 int status;
06210
06211 val = cpl_array_get_double( array, j, &status);
06212 if ( flags[j] == 0 && fabs( val-mean_val) > kappa*sigma){
06213 nb_rejected++;
06214 flags[j]=1;
06215 }
06216 }
06217 if ( nb_rejected == 0){
06218 xsh_msg("No more points are rejected. Iterations are stopped.");
06219 break;
06220 }
06221 total_rejected += nb_rejected;
06222 frac = 1-(double)total_rejected/(double)size;
06223 if (frac < frac_min){
06224 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06225 frac_min, frac);
06226 break;
06227 }
06228 for( j=0; j< size; j++){
06229 if( flags[j] == 1){
06230 check( cpl_array_set_invalid( array, j));
06231 }
06232 }
06233 check( mean_val = cpl_array_get_mean( array));
06234 check( sigma = cpl_array_get_stdev( array));
06235 xsh_msg("Accepted fraction %f Mean %f sigma %f", frac, mean_val, sigma);
06236 }
06237
06238 xsh_msg("End of clipping : Mean %f sigma %f", mean_val, sigma);
06239 *mean = mean_val;
06240 *stdev = sigma;
06241
06242 cleanup:
06243 XSH_FREE( flags);
06244 return;
06245 }
06246
06258 void
06259 xsh_array_clip_median( cpl_array *array,
06260 double kappa,
06261 int niter,
06262 double frac_min,
06263 double *median,
06264 double *stdev)
06265 {
06266 int i, j, size;
06267 double median_val;
06268 double sigma, frac;
06269 int *flags = NULL;
06270 int nb_rejected = 0, total_rejected=0;
06271
06272 XSH_ASSURE_NOT_NULL( array);
06273 XSH_ASSURE_NOT_NULL( median);
06274 XSH_ASSURE_NOT_NULL( stdev);
06275
06276 check( median_val = cpl_array_get_median( array));
06277 check( sigma = cpl_array_get_stdev( array));
06278 check( size = cpl_array_get_size( array));
06279
06280 XSH_CALLOC( flags, int, size);
06281
06282 xsh_msg("Iteration %d/%d", 0, niter);
06283 xsh_msg("Accepted fraction %f Median %f sigma %f", 1.0, median_val, sigma);
06284
06285 for( i=1; i<= niter; i++) {
06286 xsh_msg("Iteration %d/%d", i, niter);
06287 nb_rejected = 0;
06288 for( j=0; j< size; j++){
06289 double val=0.0;
06290 int status;
06291
06292 val = cpl_array_get_double( array, j, &status);
06293 if ( flags[j] == 0 && fabs( val-median_val) > kappa*sigma){
06294 nb_rejected++;
06295 flags[j]=1;
06296 }
06297 }
06298 if ( nb_rejected == 0){
06299 xsh_msg("No more points are rejected. Iterations are stopped.");
06300 break;
06301 }
06302 total_rejected += nb_rejected;
06303 frac = 1-(double)total_rejected/(double)size;
06304 if (frac < frac_min){
06305 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06306 frac_min, frac);
06307 break;
06308 }
06309 for( j=0; j< size; j++){
06310 if( flags[j] == 1){
06311 check( cpl_array_set_invalid( array, j));
06312 }
06313 }
06314 check( median_val = cpl_array_get_median( array));
06315 check( sigma = cpl_array_get_stdev( array));
06316 xsh_msg("Accepted fraction %f Median %f sigma %f", frac, median_val, sigma);
06317 }
06318 xsh_msg("End of clipping : Median %f sigma %f", median_val, sigma);
06319 *median = median_val;
06320 *stdev = sigma;
06321
06322 cleanup:
06323 XSH_FREE( flags);
06324 return;
06325 }
06326
06339 void
06340 xsh_array_clip_poly1d( cpl_vector *pos_vect,
06341 cpl_vector *val_vect,
06342 double kappa,
06343 int niter,
06344 double frac_min,
06345 int deg,
06346 cpl_polynomial **polyp,
06347 double *chisq,
06348 int **flagsp)
06349 {
06350 int i, j, size;
06351 double frac, sigma;
06352 int *flags = NULL;
06353 int nb_rejected = 0, total_rejected=0;
06354 cpl_polynomial *poly = NULL;
06355 cpl_vector *temp_pos = NULL, *temp_val = NULL;
06356 double *positions = NULL;
06357 double *values = NULL;
06358 int ngood=0;
06359
06360 XSH_ASSURE_NOT_NULL( pos_vect);
06361 XSH_ASSURE_NOT_NULL( val_vect);
06362
06363 XSH_ASSURE_NOT_NULL( polyp);
06364 XSH_ASSURE_NOT_NULL( flagsp);
06365
06366 check( poly = xsh_polynomial_fit_1d_create( pos_vect, val_vect, deg,
06367 chisq));
06368 check( size = cpl_vector_get_size( pos_vect));
06369
06370 XSH_CALLOC( flags, int, size);
06371 XSH_CALLOC( positions, double, size);
06372 XSH_CALLOC( values, double, size);
06373
06374 ngood = size;
06375 sigma = sqrt(*chisq);
06376
06377 xsh_msg_dbg_medium("Iteration %d/%d", 0, niter);
06378 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06379 1.0, deg, sigma);
06380
06381 for( i=1; i<= niter; i++) {
06382 xsh_msg_dbg_medium("Iteration %d/%d", i, niter);
06383 nb_rejected = 0;
06384
06385 for( j=0; j< size; j++){
06386 double pos=0.0, val=0.0, pol_val=0.0;
06387
06388 check( pos = cpl_vector_get( pos_vect, j));
06389 check( val = cpl_vector_get( val_vect, j));
06390 check( pol_val = cpl_polynomial_eval_1d( poly, pos, NULL));
06391
06392 if ( flags[j] == 0 && fabs( pol_val-val) > kappa*sigma){
06393 nb_rejected++;
06394 flags[j]=2;
06395 }
06396 }
06397 if ( nb_rejected == 0){
06398 xsh_msg_dbg_medium("No more points are rejected. Iterations are stopped.");
06399 break;
06400 }
06401 total_rejected += nb_rejected;
06402 frac = 1-(double)total_rejected/(double)size;
06403 if (frac < frac_min){
06404 xsh_msg("Minimal fraction of accepted points %f is reached (%f). Iterations are stopped",
06405 frac_min, frac);
06406 break;
06407 }
06408
06409 ngood = 0;
06410 for( j=0; j< size; j++){
06411 if( flags[j] == 0){
06412 positions[ngood] = cpl_vector_get( pos_vect, j);
06413 values[ngood] = cpl_vector_get( val_vect, j);
06414 ngood++;
06415 }
06416 else{
06417 flags[j] = 1;
06418 }
06419 }
06420 check( temp_pos = cpl_vector_wrap( ngood, positions));
06421 check( temp_val = cpl_vector_wrap( ngood, values));
06422
06423 xsh_free_polynomial( &poly);
06424
06425 check( poly = xsh_polynomial_fit_1d_create( temp_pos, temp_val, deg,
06426 chisq));
06427
06428 sigma = sqrt(*chisq);
06429
06430 xsh_msg_dbg_medium("Accepted fraction %f Polynomial deg %d sigma %f",
06431 frac, deg, sigma);
06432 xsh_unwrap_vector( &temp_pos);
06433 xsh_unwrap_vector( &temp_val);
06434 }
06435
06436 for( j=0; j< size; j++){
06437 if( flags[j] == 2){
06438 flags[j] = 0;
06439 }
06440 }
06441 *polyp = poly;
06442 *flagsp = flags;
06443
06444 cleanup:
06445 XSH_FREE( positions);
06446 XSH_FREE( values);
06447 xsh_unwrap_vector( &temp_pos);
06448 xsh_unwrap_vector( &temp_val);
06449 return;
06450 }
06451
06452
06453