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 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029
00030
00037
00040
00041
00042
00043
00044 #include <math.h>
00045 #include <xsh_drl.h>
00046
00047 #include <xsh_utils_table.h>
00048 #include <xsh_badpixelmap.h>
00049 #include <xsh_data_pre.h>
00050 #include <xsh_dfs.h>
00051 #include <xsh_pfits.h>
00052 #include <xsh_error.h>
00053 #include <xsh_msg.h>
00054 #include <xsh_fit.h>
00055 #include <xsh_data_instrument.h>
00056 #include <xsh_data_rec.h>
00057 #include <xsh_data_spectrum.h>
00058 #include <xsh_ifu_defs.h>
00059 #include <xsh_irplib_utils.h>
00060 #include <cpl.h>
00061
00062
00063
00064
00065
00066
00067
00068
00069
00093
00094 static void xsh_merge_point( double flux_a, double err_a, double weight_a,
00095 double flux_b, double err_b, double weight_b, double *flux_res,
00096 double *err_res)
00097 {
00098 XSH_ASSURE_NOT_NULL( flux_res);
00099 XSH_ASSURE_NOT_NULL( err_res);
00100
00101 *flux_res = (weight_a*flux_a+weight_b*flux_b)/ (weight_a+weight_b);
00102 *err_res = 1./sqrt(weight_a+weight_b);
00103
00104 cleanup:
00105 return;
00106 }
00107
00108
00123
00124 static cpl_frame * xsh_merge_ord_with_tag( cpl_frame *rec_frame,
00125 xsh_instrument *instrument, xsh_merge_param *merge_par,
00126 const char *tag)
00127 {
00128 cpl_frame *res_frame = NULL;
00129 xsh_rec_list *rec_list = NULL;
00130 xsh_spectrum *spectrum = NULL;
00131
00132 int iorder=0, islit=0;
00133 int spectrum_size_lambda=0;
00134 int spectrum_size_slit=0;
00135 double lambda_min=0.0, lambda_max=0.0, lambda_step=0.0;
00136 double *spectrum_flux = NULL;
00137 double *spectrum_errs = NULL;
00138 int *spectrum_qual = NULL;
00139 int spectrum_flux_index = 0;
00140 int *spectrum_by_lambda = NULL;
00141 const char* rec_pcatg = NULL;
00142 char* spectrum_name = NULL;
00143 const char* name=NULL;
00144 cpl_propertylist* header=NULL;
00145 int naxis=0;
00146 int eso_mode=0;
00147 int decode_bp=instrument->decode_bp;
00148
00149 XSH_ASSURE_NOT_NULL( rec_frame);
00150 XSH_ASSURE_NOT_NULL( instrument);
00151 XSH_ASSURE_NOT_NULL( merge_par);
00152 XSH_ASSURE_NOT_NULL( tag);
00153
00154 xsh_msg_dbg_medium( "Method : %s", MERGE_METHOD_PRINT (merge_par->method));
00155
00156
00157
00158 name=cpl_frame_get_filename(rec_frame);
00159 header=cpl_propertylist_load(name,0);
00160 naxis=xsh_pfits_get_naxis(header);
00161 xsh_free_propertylist(&header);
00162 if(naxis==2) {
00163 check( rec_list = xsh_rec_list_load_eso( rec_frame, instrument));
00164 eso_mode=1;
00165 } else {
00166 check( rec_list = xsh_rec_list_load( rec_frame, instrument));
00167 }
00168
00169 check (lambda_min = xsh_pfits_get_rectify_lambda_min( rec_list->header));
00170 check( lambda_max = xsh_pfits_get_rectify_lambda_max( rec_list->header));
00171 check( lambda_step = xsh_pfits_get_rectify_bin_lambda( rec_list->header));
00172
00173
00174 check( rec_pcatg = xsh_pfits_get_pcatg( rec_list->header));
00175
00176
00177 if (
00178 strstr( rec_pcatg, XSH_ORDER2D ) != NULL ||
00179 strstr( rec_pcatg, XSH_MERGE2D ) != NULL ||
00180 strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT ) != NULL ||
00181 strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_IFU ) != NULL
00182 ) {
00183
00184 double slit_min=0.0, slit_max=0.0, slit_step=0.0;
00185
00186 check( slit_min = xsh_pfits_get_rectify_space_min( rec_list->header));
00187 check( slit_max = xsh_pfits_get_rectify_space_max( rec_list->header));
00188 check( slit_step = xsh_pfits_get_rectify_bin_space( rec_list->header));
00189
00190 xsh_msg_dbg_high("Construct 2D spectrum %f %f %f",slit_min, slit_max,
00191 slit_step);
00192 xsh_msg_dbg_medium("lambda min %f max %f step %f",lambda_min, lambda_max,
00193 lambda_step);
00194 check( spectrum = xsh_spectrum_2D_create( lambda_min, lambda_max,
00195 lambda_step, slit_min, slit_max, slit_step));
00196 }
00197 else{
00198 xsh_msg_dbg_high("Construct 1D spectrum");
00199 xsh_msg_dbg_medium("lambda min %f max %f step %f",lambda_min, lambda_max,
00200 lambda_step);
00201 check( spectrum = xsh_spectrum_1D_create( lambda_min, lambda_max,
00202 lambda_step));
00203 }
00204
00205 spectrum_name = xsh_stringcat_any( tag, ".fits", NULL);
00206
00207 check( spectrum_size_lambda = xsh_spectrum_get_size_lambda( spectrum));
00208 check( spectrum_size_slit = xsh_spectrum_get_size_slit( spectrum));
00209 check( spectrum_flux = xsh_spectrum_get_flux( spectrum));
00210 check( spectrum_errs = xsh_spectrum_get_errs( spectrum));
00211 check( spectrum_qual = xsh_spectrum_get_qual( spectrum));
00212 XSH_CALLOC( spectrum_by_lambda, int, spectrum->size);
00213
00214 xsh_msg_dbg_medium( "Spectrum size (Lambda X slit) = (%d X %d) \n"\
00215 "Lambda %f to %f", spectrum_size_lambda, spectrum_size_slit,
00216 lambda_min, lambda_min+lambda_step*(spectrum_size_lambda-1));
00217
00218
00219
00220
00221 int problem_slit_size=0;
00222 for(islit = 0; islit < spectrum_size_slit; islit++){
00223 for ( iorder=rec_list->size-1; iorder>=0; iorder--) {
00224 int nlambda = xsh_rec_list_get_nlambda( rec_list, iorder);
00225 double* lambda = xsh_rec_list_get_lambda( rec_list, iorder);
00226 float *flux = xsh_rec_list_get_data1( rec_list, iorder);
00227 float *errs = xsh_rec_list_get_errs1( rec_list, iorder);
00228 int *qual = xsh_rec_list_get_qual1( rec_list, iorder);
00229 int nslit = xsh_rec_list_get_nslit( rec_list, iorder);
00230 int ilambda=0;
00231 double n;
00232
00233
00234
00235
00236 if (spectrum_size_slit !=nslit){
00237
00238
00239
00240
00241 problem_slit_size=1;
00242 }
00243
00244 xsh_msg_dbg_high( "slit %d lambda %f %f", islit,
00245 lambda[0], lambda[nlambda-1]);
00246
00247
00248
00249
00250 n = (lambda[0]-lambda_min)/lambda_step;
00251 spectrum_flux_index = (int)xsh_round_double( n);
00252
00253 xsh_msg_dbg_high( "iorder %d begin at index %f --> %d", iorder, n,
00254 spectrum_flux_index);
00255
00256
00257 if (islit < nslit){
00258
00259 for(ilambda=0; ilambda < nlambda; ilambda++){
00260 int i_spectrum = spectrum_flux_index+ilambda+
00261 islit * spectrum_size_lambda;
00262 int i_rec_order = ilambda+islit * nlambda;
00263
00264
00265
00266
00267 if (errs[i_rec_order] == 0){
00268 continue;
00269 }
00270 if ( spectrum_by_lambda[i_spectrum] == 0){
00271 spectrum_by_lambda[i_spectrum]++;
00272 spectrum_flux[i_spectrum] = flux[i_rec_order];
00273 spectrum_errs[i_spectrum] = errs[i_rec_order];
00274 spectrum_qual[i_spectrum] = qual[i_rec_order];
00275 }
00276 else{
00277 double flux_a, err_a, weight_a;
00278 double flux_b, err_b, weight_b;
00279 double flux_res = 0.0, err_res= 1.0;
00280 int nb, qual_a, qual_b, qual_res;
00281
00282 flux_a = spectrum_flux[i_spectrum];
00283 err_a = spectrum_errs[i_spectrum];
00284 flux_b = flux[i_rec_order];
00285 err_b = errs[i_rec_order];
00286 nb = spectrum_by_lambda[i_spectrum];
00287 qual_a = spectrum_qual[i_spectrum];
00288 qual_b = qual[i_rec_order];
00289 flux_res = spectrum_flux[i_spectrum];
00290 err_res = spectrum_errs[i_spectrum];
00291 qual_res = spectrum_qual[i_spectrum];
00292
00293
00294
00295
00296
00297 if ( (qual_a & decode_bp) == 0 ){
00298
00299 if ( (qual_b & decode_bp) == 0 ){
00300
00301 if ( merge_par->method == MEAN_MERGE_METHOD){
00302 weight_a = nb;
00303 weight_b = 1.0;
00304 }
00305 else{
00306 weight_a = nb / (err_a*err_a);
00307 weight_b = 1.0 / (err_b*err_b);
00308 }
00309 check( xsh_merge_point( flux_a, err_a, weight_a, flux_b,
00310 err_b, weight_b, &flux_res, &err_res));
00311
00312 qual_res = qual_a | qual_b;
00313 nb++;
00314 }
00315 }
00316 else{
00317 if ( (qual_b & decode_bp) == 0 ){
00318
00319 flux_res = flux_b;
00320 err_res = err_b;
00321 qual_res = qual_b;
00322 nb = 1;
00323 }
00324 else{
00325 if ( merge_par->method == MEAN_MERGE_METHOD){
00326 weight_a = nb;
00327 weight_b = 1.0;
00328 }
00329 else{
00330 weight_a = nb / (err_a*err_a);
00331 weight_b = 1.0 / (err_b*err_b);
00332 }
00333 check( xsh_merge_point( flux_a, err_a, weight_a, flux_b,
00334 err_b, weight_b, &flux_res, &err_res));
00335 qual_res = qual_a | qual_b;
00336 nb++;
00337 }
00338 }
00339
00340
00341
00342
00343 spectrum_flux[i_spectrum] = flux_res;
00344 spectrum_errs[i_spectrum] = err_res;
00345 spectrum_qual[i_spectrum] = qual_res;
00346 spectrum_by_lambda[i_spectrum] = nb;
00347 }
00348
00349 }
00350
00351 }
00352 }
00353
00354 }
00355 if(problem_slit_size==1) {
00356 xsh_msg_warning("spectrum size slit is different from order size");
00357 }
00358
00359 if(eso_mode) {
00360 cpl_propertylist_erase_regexp(rec_list->header,"^CRVAL1",0);
00361 cpl_propertylist_erase_regexp(rec_list->header,"^CRVAL2",0);
00362 cpl_propertylist_erase_regexp(rec_list->header,"^CRPIX1",0);
00363 cpl_propertylist_erase_regexp(rec_list->header,"^CRPIX2",0);
00364 cpl_propertylist_erase_regexp(rec_list->header,"^CDELT1",0);
00365 cpl_propertylist_erase_regexp(rec_list->header,"^CDELT2",0);
00366 }
00367 check( cpl_propertylist_append( spectrum->flux_header, rec_list->header));
00368
00369 const char* bunit=xsh_pfits_get_bunit(spectrum->flux_header);
00370 xsh_pfits_set_bunit(spectrum->errs_header,bunit);
00371
00372 check( res_frame = xsh_spectrum_save(spectrum, spectrum_name,tag));
00373 check( cpl_frame_set_tag( res_frame, tag));
00374
00375
00376 cleanup:
00377 xsh_spectrum_free( &spectrum);
00378 xsh_rec_list_free( &rec_list ) ;
00379 XSH_FREE( spectrum_by_lambda);
00380 XSH_FREE( spectrum_name);
00381 return res_frame ;
00382 }
00383
00384
00399
00400 cpl_frame * xsh_merge_ord( cpl_frame * rec_frame, xsh_instrument* instrument,
00401 xsh_merge_param* merge_par,const char* rec_prefix)
00402 {
00403 cpl_frame *res_frame = NULL;
00404 xsh_msg("Merge slit orders");
00405 check( res_frame = xsh_merge_ord_slitlet( rec_frame, instrument, merge_par,
00406 CENTER_SLIT,rec_prefix));
00407
00408 cleanup:
00409 return res_frame;
00410 }
00411
00428
00429 cpl_frame * xsh_merge_ord_slitlet( cpl_frame * rec_frame,
00430 xsh_instrument* instrument,
00431 xsh_merge_param* merge_par, int slitlet,
00432 const char* rec_prefix)
00433 {
00434 cpl_frame *res_frame = NULL;
00435 cpl_propertylist *header = NULL;
00436 const char *rec_pcatg = NULL;
00437 const char *tag_suf = NULL;
00438 const char *filename = NULL;
00439 char tag[80];
00440
00441
00442 XSH_ASSURE_NOT_NULL( rec_frame);
00443 XSH_ASSURE_NOT_NULL( instrument);
00444 XSH_ASSURE_NOT_NULL( merge_par);
00445
00446
00447 check( filename = cpl_frame_get_filename( rec_frame));
00448 check( header = cpl_propertylist_load( filename, 0));
00449 check( rec_pcatg = xsh_pfits_get_pcatg( header));
00450 check(tag_suf = cpl_frame_get_tag(rec_frame));
00451
00452 if ( strstr( rec_pcatg, XSH_FLUX_ORDER2D ) != NULL ) {
00453 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE2D, instrument);
00454 }
00455 else if ( strstr( rec_pcatg, XSH_NORM_ORDER2D ) != NULL ) {
00456 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE2D, instrument);
00457 }
00458
00459
00460
00461
00462 else if ( strstr( rec_pcatg, XSH_ORDER2D ) != NULL ) {
00463 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE2D, slitlet,
00464 instrument);
00465 }
00466 else if ( strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT ) != NULL){
00467
00468 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE2D,
00469 instrument);
00470 }
00471 else if ( strstr( rec_pcatg, XSH_ORDER_EXT1D ) != NULL){
00472
00473 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_EXT1D,
00474 instrument);
00475 }
00476 else if ( strstr( rec_pcatg, XSH_ORDER_OXT1D ) != NULL){
00477
00478 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_OXT1D,
00479 instrument);
00480 }
00481 else if ( strstr( rec_pcatg, XSH_FLUX_OXT1D ) != NULL){
00482 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MOXT1D, instrument);
00483 }
00484 else if ( strstr( rec_pcatg, XSH_FLUX_ORDER1D ) != NULL){
00485 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE1D, instrument);
00486 }
00487 else if ( strstr( rec_pcatg, XSH_NORM_ORDER1D ) != NULL){
00488 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE1D, instrument);
00489 }
00490 else if ( strstr( rec_pcatg, XSH_ORDER1D ) != NULL){
00491 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE1D, slitlet,
00492 instrument);
00493 }
00494 else{
00495 tag_suf="";
00496 xsh_msg_error("Invalid PRO.CATG %s for file %s", rec_pcatg, filename);
00497 }
00498 sprintf(tag,"%s_%s",rec_prefix,tag_suf);
00499 check( res_frame = xsh_merge_ord_with_tag( rec_frame, instrument,
00500 merge_par, tag));
00501
00502 cleanup:
00503 xsh_free_propertylist( &header);
00504 return res_frame ;
00505 }
00506
00507
00508 static void xsh_frame_set_shift_ref( cpl_frame *rec_frame, cpl_frame *shift_frame)
00509 {
00510 cpl_propertylist *rec_header = NULL;
00511 cpl_propertylist *shift_header = NULL;
00512 const char *rec_name = NULL;
00513 const char *shift_name = NULL;
00514 double waveref, slitref;
00515
00516 XSH_ASSURE_NOT_NULL( rec_frame);
00517 XSH_ASSURE_NOT_NULL( shift_frame);
00518
00519 check( rec_name = cpl_frame_get_filename( rec_frame));
00520 check( shift_name = cpl_frame_get_filename( shift_frame));
00521
00522 check( rec_header = cpl_propertylist_load( rec_name, 0));
00523 check( shift_header = cpl_propertylist_load( shift_name, 0));
00524
00525 waveref = xsh_pfits_get_shiftifu_lambdaref( shift_header);
00526 slitref = xsh_pfits_get_shiftifu_slitref( shift_header);
00527
00528 if (cpl_error_get_code() == CPL_ERROR_NONE){
00529 check( xsh_pfits_set_shiftifu_lambdaref( rec_header, waveref));
00530 check( xsh_pfits_set_shiftifu_slitref( rec_header, slitref));
00531 check( cpl_propertylist_save( rec_header, rec_name, CPL_IO_EXTEND));
00532 }
00533 xsh_error_reset();
00534
00535 cleanup:
00536 xsh_free_propertylist( &rec_header);
00537 xsh_free_propertylist( &shift_header);
00538 return;
00539 }
00540
00541
00542
00557
00558 cpl_frameset* xsh_merge_ord_ifu(cpl_frameset* rec_frameset,
00559 xsh_instrument* instrument,
00560 xsh_merge_param* merge_par,
00561 const char* rec_prefix)
00562 {
00563 cpl_frameset *result_set = NULL;
00564 cpl_frameset *drl_frameset = NULL;
00565 int slitlet;
00566 int i=0;
00567
00568 XSH_ASSURE_NOT_NULL( rec_frameset);
00569 XSH_ASSURE_NOT_NULL( instrument);
00570 XSH_ASSURE_NOT_NULL( merge_par);
00571
00572 xsh_msg("Merge IFU orders");
00573 check( result_set = cpl_frameset_new());
00574 check( drl_frameset = xsh_frameset_drl_frames( rec_frameset));
00575
00576
00577 for( slitlet = LOWER_IFU_SLITLET; slitlet <= UPPER_IFU_SLITLET; slitlet++){
00578 cpl_frame * rec_frame = NULL ;
00579 cpl_frame * ord_frame = NULL ;
00580
00581 check( rec_frame = cpl_frameset_get_frame( drl_frameset, i));
00582
00583
00584 check( ord_frame = xsh_merge_ord_slitlet( rec_frame, instrument,
00585 merge_par,slitlet,rec_prefix));
00586
00587 check( xsh_frame_set_shift_ref( rec_frame, ord_frame));
00588 xsh_msg( "Merge for Slitlet %s, %s", SlitletName[slitlet],
00589 cpl_frame_get_filename( ord_frame)) ;
00590 check( cpl_frameset_insert( result_set, ord_frame));
00591 i++;
00592 }
00593
00594 cleanup:
00595 if (cpl_error_get_code() != CPL_ERROR_NONE){
00596 xsh_free_frameset( &result_set);
00597 }
00598 xsh_free_frameset( &drl_frameset);
00599 return result_set ;
00600 }
00601