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
00148 XSH_ASSURE_NOT_NULL( rec_frame);
00149 XSH_ASSURE_NOT_NULL( instrument);
00150 XSH_ASSURE_NOT_NULL( merge_par);
00151 XSH_ASSURE_NOT_NULL( tag);
00152
00153 xsh_msg_dbg_medium( "Method : %s", MERGE_METHOD_PRINT (merge_par->method));
00154
00155
00156
00157 name=cpl_frame_get_filename(rec_frame);
00158 header=cpl_propertylist_load(name,0);
00159 naxis=xsh_pfits_get_naxis(header);
00160 xsh_free_propertylist(&header);
00161 if(naxis==2) {
00162 check( rec_list = xsh_rec_list_load_eso( rec_frame, instrument));
00163 eso_mode=1;
00164 } else {
00165 check( rec_list = xsh_rec_list_load( rec_frame, instrument));
00166 }
00167
00168 check (lambda_min = xsh_pfits_get_rectify_lambda_min( rec_list->header));
00169 check( lambda_max = xsh_pfits_get_rectify_lambda_max( rec_list->header));
00170 check( lambda_step = xsh_pfits_get_rectify_bin_lambda( rec_list->header));
00171
00172
00173 check( rec_pcatg = xsh_pfits_get_pcatg( rec_list->header));
00174
00175
00176 if (
00177 strstr( rec_pcatg, XSH_ORDER2D ) != NULL ||
00178 strstr( rec_pcatg, XSH_MERGE2D ) != NULL ||
00179 strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT ) != NULL ||
00180 strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_IFU ) != NULL
00181 ) {
00182
00183 double slit_min=0.0, slit_max=0.0, slit_step=0.0;
00184
00185 check( slit_min = xsh_pfits_get_rectify_space_min( rec_list->header));
00186 check( slit_max = xsh_pfits_get_rectify_space_max( rec_list->header));
00187 check( slit_step = xsh_pfits_get_rectify_bin_space( rec_list->header));
00188
00189 xsh_msg_dbg_high("Construct 2D spectrum %f %f %f",slit_min, slit_max,
00190 slit_step);
00191 xsh_msg_dbg_medium("lambda min %f max %f step %f",lambda_min, lambda_max,
00192 lambda_step);
00193 check( spectrum = xsh_spectrum_2D_create( lambda_min, lambda_max,
00194 lambda_step, slit_min, slit_max, slit_step));
00195 }
00196 else{
00197 xsh_msg_dbg_high("Construct 1D spectrum");
00198 xsh_msg_dbg_medium("lambda min %f max %f step %f",lambda_min, lambda_max,
00199 lambda_step);
00200 check( spectrum = xsh_spectrum_1D_create( lambda_min, lambda_max,
00201 lambda_step));
00202 }
00203
00204 spectrum_name = xsh_stringcat_any( tag, ".fits", NULL);
00205
00206 check( spectrum_size_lambda = xsh_spectrum_get_size_lambda( spectrum));
00207 check( spectrum_size_slit = xsh_spectrum_get_size_slit( spectrum));
00208 check( spectrum_flux = xsh_spectrum_get_flux( spectrum));
00209 check( spectrum_errs = xsh_spectrum_get_errs( spectrum));
00210 check( spectrum_qual = xsh_spectrum_get_qual( spectrum));
00211 XSH_CALLOC( spectrum_by_lambda, int, spectrum->size);
00212
00213 xsh_msg_dbg_medium( "Spectrum size (Lambda X slit) = (%d X %d) \n"\
00214 "Lambda %f to %f", spectrum_size_lambda, spectrum_size_slit,
00215 lambda_min, lambda_min+lambda_step*(spectrum_size_lambda-1));
00216
00217
00218
00219
00220 for(islit = 0; islit < spectrum_size_slit; islit++){
00221 for ( iorder=rec_list->size-1; iorder>=0; iorder--) {
00222 int nlambda = xsh_rec_list_get_nlambda( rec_list, iorder);
00223 double* lambda = xsh_rec_list_get_lambda( rec_list, iorder);
00224 float *flux = xsh_rec_list_get_data1( rec_list, iorder);
00225 float *errs = xsh_rec_list_get_errs1( rec_list, iorder);
00226 int *qual = xsh_rec_list_get_qual1( rec_list, iorder);
00227 int nslit = xsh_rec_list_get_nslit( rec_list, iorder);
00228 int ilambda=0;
00229 double n;
00230
00231
00232
00233
00234 if (spectrum_size_slit !=nslit){
00235 xsh_msg_warning("spectrum size slit %d is different from order size %d",
00236 spectrum_size_slit, nslit);
00237 }
00238 xsh_msg_dbg_high( "slit %d lambda %f %f", islit,
00239 lambda[0], lambda[nlambda-1]);
00240
00241
00242
00243
00244 n = (lambda[0]-lambda_min)/lambda_step;
00245 spectrum_flux_index = (int)xsh_round_double( n);
00246
00247 xsh_msg_dbg_high( "iorder %d begin at index %f --> %d", iorder, n,
00248 spectrum_flux_index);
00249
00250
00251 if (islit < nslit){
00252
00253 for(ilambda=0; ilambda < nlambda; ilambda++){
00254 int i_spectrum = spectrum_flux_index+ilambda+
00255 islit * spectrum_size_lambda;
00256 int i_rec_order = ilambda+islit * nlambda;
00257
00258
00259
00260
00261 if (errs[i_rec_order] == 0){
00262 continue;
00263 }
00264 if ( spectrum_by_lambda[i_spectrum] == 0){
00265 spectrum_by_lambda[i_spectrum]++;
00266 spectrum_flux[i_spectrum] = flux[i_rec_order];
00267 spectrum_errs[i_spectrum] = errs[i_rec_order];
00268 spectrum_qual[i_spectrum] = qual[i_rec_order];
00269 }
00270 else{
00271 double flux_a, err_a, weight_a;
00272 double flux_b, err_b, weight_b;
00273 double flux_res = 0.0, err_res= 1.0;
00274 int nb, qual_a, qual_b, qual_res;
00275
00276 flux_a = spectrum_flux[i_spectrum];
00277 err_a = spectrum_errs[i_spectrum];
00278 flux_b = flux[i_rec_order];
00279 err_b = errs[i_rec_order];
00280 nb = spectrum_by_lambda[i_spectrum];
00281 qual_a = spectrum_qual[i_spectrum];
00282 qual_b = qual[i_rec_order];
00283 flux_res = spectrum_flux[i_spectrum];
00284 err_res = spectrum_errs[i_spectrum];
00285 qual_res = spectrum_qual[i_spectrum];
00286
00287
00288
00289
00290
00291 if ( qual_a <= XSH_GOOD_PIXEL_LEVEL){
00292 if ( qual_b <= XSH_GOOD_PIXEL_LEVEL){
00293 if ( merge_par->method == MEAN_MERGE_METHOD){
00294 weight_a = nb;
00295 weight_b = 1.0;
00296 }
00297 else{
00298 weight_a = nb / (err_a*err_a);
00299 weight_b = 1.0 / (err_b*err_b);
00300 }
00301 check( xsh_merge_point( flux_a, err_a, weight_a, flux_b,
00302 err_b, weight_b, &flux_res, &err_res));
00303
00304 qual_res = qual_a | qual_b;
00305 nb++;
00306 }
00307 }
00308 else{
00309 if ( qual_b <= XSH_GOOD_PIXEL_LEVEL){
00310 flux_res = flux_b;
00311 err_res = err_b;
00312 qual_res = qual_b;
00313 nb = 1;
00314 }
00315 else{
00316 if ( merge_par->method == MEAN_MERGE_METHOD){
00317 weight_a = nb;
00318 weight_b = 1.0;
00319 }
00320 else{
00321 weight_a = nb / (err_a*err_a);
00322 weight_b = 1.0 / (err_b*err_b);
00323 }
00324 check( xsh_merge_point( flux_a, err_a, weight_a, flux_b,
00325 err_b, weight_b, &flux_res, &err_res));
00326 qual_res = qual_a | qual_b;
00327 nb++;
00328 }
00329 }
00330
00331
00332
00333
00334 spectrum_flux[i_spectrum] = flux_res;
00335 spectrum_errs[i_spectrum] = err_res;
00336 spectrum_qual[i_spectrum] = qual_res;
00337 spectrum_by_lambda[i_spectrum] = nb;
00338 }
00339
00340 }
00341
00342 }
00343 }
00344
00345 }
00346
00347
00348 if(eso_mode) {
00349 cpl_propertylist_erase_regexp(rec_list->header,"^CRVAL1",0);
00350 cpl_propertylist_erase_regexp(rec_list->header,"^CRVAL2",0);
00351 cpl_propertylist_erase_regexp(rec_list->header,"^CRPIX1",0);
00352 cpl_propertylist_erase_regexp(rec_list->header,"^CRPIX2",0);
00353 cpl_propertylist_erase_regexp(rec_list->header,"^CDELT1",0);
00354 cpl_propertylist_erase_regexp(rec_list->header,"^CDELT2",0);
00355 }
00356 check( cpl_propertylist_append( spectrum->flux_header, rec_list->header));
00357
00358 check( res_frame = xsh_spectrum_save(spectrum, spectrum_name,tag));
00359 check( cpl_frame_set_tag( res_frame, tag));
00360
00361
00362 cleanup:
00363 xsh_spectrum_free( &spectrum);
00364 xsh_rec_list_free( &rec_list ) ;
00365 XSH_FREE( spectrum_by_lambda);
00366 XSH_FREE( spectrum_name);
00367 return res_frame ;
00368 }
00369
00370
00385
00386 cpl_frame * xsh_merge_ord( cpl_frame * rec_frame, xsh_instrument* instrument,
00387 xsh_merge_param* merge_par,const char* rec_prefix)
00388 {
00389 cpl_frame *res_frame = NULL;
00390 xsh_msg("Merge slit orders");
00391 check( res_frame = xsh_merge_ord_slitlet( rec_frame, instrument, merge_par,
00392 CENTER_SLIT,rec_prefix));
00393
00394 cleanup:
00395 return res_frame;
00396 }
00397
00414
00415 cpl_frame * xsh_merge_ord_slitlet( cpl_frame * rec_frame,
00416 xsh_instrument* instrument,
00417 xsh_merge_param* merge_par, int slitlet,
00418 const char* rec_prefix)
00419 {
00420 cpl_frame *res_frame = NULL;
00421 cpl_propertylist *header = NULL;
00422 const char *rec_pcatg = NULL;
00423 const char *tag_suf = NULL;
00424 const char *filename = NULL;
00425 char tag[80];
00426
00427
00428 XSH_ASSURE_NOT_NULL( rec_frame);
00429 XSH_ASSURE_NOT_NULL( instrument);
00430 XSH_ASSURE_NOT_NULL( merge_par);
00431
00432
00433 check( filename = cpl_frame_get_filename( rec_frame));
00434 check( header = cpl_propertylist_load( filename, 0));
00435 check( rec_pcatg = xsh_pfits_get_pcatg( header));
00436 check(tag_suf = cpl_frame_get_tag(rec_frame));
00437
00438 if ( strstr( rec_pcatg, XSH_FLUX_ORDER2D ) != NULL ) {
00439 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE2D, instrument);
00440 }
00441 else if ( strstr( rec_pcatg, XSH_NORM_ORDER2D ) != NULL ) {
00442 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE2D, instrument);
00443 }
00444 else if ( strstr( rec_pcatg, XSH_ORDER2D ) != NULL ) {
00445 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE2D, slitlet,
00446 instrument);
00447 }
00448 else if ( strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT ) != NULL){
00449
00450 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE2D,
00451 instrument);
00452 }
00453 else if ( strstr( rec_pcatg, XSH_ORDER_EXT1D ) != NULL){
00454
00455 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_EXT1D,
00456 instrument);
00457 }
00458 else if ( strstr( rec_pcatg, XSH_ORDER_OXT1D ) != NULL){
00459
00460 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_OXT1D,
00461 instrument);
00462 }
00463 else if ( strstr( rec_pcatg, XSH_FLUX_ORDER1D ) != NULL){
00464 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE1D, instrument);
00465 }
00466 else if ( strstr( rec_pcatg, XSH_NORM_ORDER1D ) != NULL){
00467 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE1D, instrument);
00468 }
00469 else if ( strstr( rec_pcatg, XSH_ORDER1D ) != NULL){
00470 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE1D, slitlet,
00471 instrument);
00472 }
00473 else{
00474 tag_suf="";
00475 xsh_msg_error("Invalid PRO.CATG %s for file %s", rec_pcatg, filename);
00476 }
00477 sprintf(tag,"%s_%s",rec_prefix,tag_suf);
00478 check( res_frame = xsh_merge_ord_with_tag( rec_frame, instrument,
00479 merge_par, tag));
00480
00481 cleanup:
00482 xsh_free_propertylist( &header);
00483 return res_frame ;
00484 }
00485
00500
00501 cpl_frameset* xsh_merge_ord_ifu(cpl_frameset* rec_frameset,
00502 xsh_instrument* instrument,
00503 xsh_merge_param* merge_par,
00504 const char* rec_prefix)
00505 {
00506 cpl_frameset *result_set = NULL;
00507 cpl_frameset *drl_frameset = NULL;
00508 int slitlet;
00509 int i=0;
00510
00511 XSH_ASSURE_NOT_NULL( rec_frameset);
00512 XSH_ASSURE_NOT_NULL( instrument);
00513 XSH_ASSURE_NOT_NULL( merge_par);
00514
00515 xsh_msg("Merge IFU orders");
00516 check( result_set = cpl_frameset_new());
00517 check( drl_frameset = xsh_frameset_drl_frames( rec_frameset));
00518
00519 {
00520 int idbg;
00521 cpl_frame *test_frame;
00522
00523 for(idbg = 0; idbg < 3; idbg++){
00524 check( test_frame = cpl_frameset_get_frame( drl_frameset, idbg ));
00525 XSH_REGDEBUG("DBG %d ==> %s", idbg, cpl_frame_get_filename( test_frame));
00526 }
00527 }
00528
00529
00530 for( slitlet = LOWER_IFU_SLITLET; slitlet <= UPPER_IFU_SLITLET; slitlet++){
00531 cpl_frame * rec_frame = NULL ;
00532 cpl_frame * ord_frame = NULL ;
00533
00534 xsh_msg( " Slitlet %s", SlitletName[slitlet] ) ;
00535 check( rec_frame = cpl_frameset_get_frame( drl_frameset, i));
00536
00537
00538 check( ord_frame = xsh_merge_ord_slitlet( rec_frame, instrument,
00539 merge_par,slitlet,rec_prefix));
00540 check( cpl_frameset_insert( result_set, ord_frame));
00541 i++;
00542 }
00543
00544 cleanup:
00545 xsh_free_frameset( &drl_frameset);
00546 return result_set ;
00547 }
00548