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 weight_a,
00095 double flux_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 double tmp_val = 1.0/(weight_a+weight_b);
00102 *flux_res = (weight_a*flux_a+weight_b*flux_b) * tmp_val;
00103 *err_res = sqrt(tmp_val);
00104
00105 cleanup:
00106 return;
00107 }
00108
00109
00124
00125 static cpl_frame * xsh_merge_ord_with_tag(cpl_frame *rec_frame,
00126 xsh_instrument *instrument, int merge_par, const char *tag) {
00127 cpl_frame *res_frame = NULL;
00128 xsh_rec_list *rec_list = NULL;
00129 xsh_spectrum *spectrum = NULL;
00130
00131 int iorder = 0, islit = 0;
00132 int spectrum_size_lambda = 0;
00133 int spectrum_size_slit = 0;
00134 double lambda_min = 0.0, lambda_max = 0.0, lambda_step = 0.0;
00135 double *spectrum_flux = NULL;
00136 double *spectrum_errs = NULL;
00137 int *spectrum_qual = NULL;
00138 int spectrum_flux_index = 0;
00139 int *spectrum_by_lambda = NULL;
00140 const char* rec_pcatg = NULL;
00141 char* spectrum_name = NULL;
00142 const char* name = NULL;
00143 cpl_propertylist* header = NULL;
00144 int naxis = 0;
00145 int eso_mode = 0;
00146 int decode_bp = instrument->decode_bp;
00147
00148 XSH_ASSURE_NOT_NULL( rec_frame);
00149 XSH_ASSURE_NOT_NULL( instrument);
00150 XSH_ASSURE_NOT_NULL( tag);
00151
00152
00153
00154 name = cpl_frame_get_filename(rec_frame);
00155 header = cpl_propertylist_load(name, 0);
00156 naxis = xsh_pfits_get_naxis(header);
00157 xsh_free_propertylist(&header);
00158 if (naxis == 2) {
00159 check( rec_list = xsh_rec_list_load_eso( rec_frame, instrument));
00160 eso_mode = 1;
00161 } else {
00162 check( rec_list = xsh_rec_list_load( rec_frame, instrument));
00163 }
00164
00165 check(lambda_min = xsh_pfits_get_rectify_lambda_min( rec_list->header));
00166 check( lambda_max = xsh_pfits_get_rectify_lambda_max( rec_list->header));
00167 check( lambda_step = xsh_pfits_get_rectify_bin_lambda( rec_list->header));
00168
00169
00170 check( rec_pcatg = xsh_pfits_get_pcatg( rec_list->header));
00171
00172
00173 if (strstr(rec_pcatg, XSH_ORDER2D) != NULL
00174 || strstr(rec_pcatg, XSH_MERGE2D) != NULL
00175 || strstr(rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT) != NULL
00176 || strstr(rec_pcatg, XSH_COMBINED_OFFSET_2D_IFU) != NULL) {
00177
00178 double slit_min = 0.0, slit_max = 0.0, slit_step = 0.0;
00179
00180 check( slit_min = xsh_pfits_get_rectify_space_min( rec_list->header));
00181 check( slit_max = xsh_pfits_get_rectify_space_max( rec_list->header));
00182 check( slit_step = xsh_pfits_get_rectify_bin_space( rec_list->header));
00183
00184 xsh_msg_dbg_high(
00185 "Construct 2D spectrum %f %f %f", slit_min, slit_max, slit_step);
00186 xsh_msg_dbg_medium(
00187 "lambda min %f max %f step %f", lambda_min, lambda_max, lambda_step);
00188 check(
00189 spectrum = xsh_spectrum_2D_create( lambda_min, lambda_max, lambda_step, slit_min, slit_max, slit_step));
00190 } else {
00191 xsh_msg_dbg_high("Construct 1D spectrum");
00192 xsh_msg_dbg_medium(
00193 "lambda min %f max %f step %f", lambda_min, lambda_max, lambda_step);
00194 check(
00195 spectrum = xsh_spectrum_1D_create( lambda_min, lambda_max, lambda_step));
00196 }
00197
00198 spectrum_name = xsh_stringcat_any(tag, ".fits", NULL);
00199
00200 check( spectrum_size_lambda = xsh_spectrum_get_size_lambda( spectrum));
00201 check( spectrum_size_slit = xsh_spectrum_get_size_slit( spectrum));
00202 check( spectrum_flux = xsh_spectrum_get_flux( spectrum));
00203 check( spectrum_errs = xsh_spectrum_get_errs( spectrum));
00204 check( spectrum_qual = xsh_spectrum_get_qual( spectrum));
00205 XSH_CALLOC( spectrum_by_lambda, int, spectrum->size);
00206
00207 xsh_msg_dbg_medium ( "Spectrum size (Lambda X slit) = (%d X %d) \n"
00208 "Lambda %f to %f", spectrum_size_lambda, spectrum_size_slit,
00209 lambda_min, lambda_min+lambda_step*(spectrum_size_lambda-1));
00210
00211
00212
00213
00214 int problem_slit_size = 0;
00215 for (islit = 0; islit < spectrum_size_slit; islit++) {
00216 for (iorder = rec_list->size - 1; iorder >= 0; iorder--) {
00217 int nlambda = xsh_rec_list_get_nlambda(rec_list, iorder);
00218 double* lambda = xsh_rec_list_get_lambda(rec_list, iorder);
00219 float *flux = xsh_rec_list_get_data1(rec_list, iorder);
00220 float *errs = xsh_rec_list_get_errs1(rec_list, iorder);
00221 int *qual = xsh_rec_list_get_qual1(rec_list, iorder);
00222 int nslit = xsh_rec_list_get_nslit(rec_list, iorder);
00223 int ilambda = 0;
00224 double n;
00225
00226
00227
00228
00229 if (spectrum_size_slit != nslit) {
00230
00231
00232
00233
00234 problem_slit_size = 1;
00235 }
00236
00237 xsh_msg_dbg_high(
00238 "slit %d lambda %f %f", islit, lambda[0], lambda[nlambda-1]);
00239
00240
00241
00242
00243 n = (lambda[0] - lambda_min) / lambda_step;
00244 spectrum_flux_index = (int) xsh_round_double(n);
00245
00246 xsh_msg_dbg_high(
00247 "iorder %d begin at index %f --> %d", iorder, n, spectrum_flux_index);
00248
00249 if (islit < nslit) {
00250 int ilambda_off=spectrum_flux_index+ islit*spectrum_size_lambda;
00251 int islit_nlambda = islit * nlambda;
00252 for (ilambda = 0; ilambda < nlambda; ilambda++) {
00253
00254 int i_rec_order = ilambda + islit_nlambda;
00255 if (errs[i_rec_order] == 0) {
00256 continue;
00257 }
00258
00259 int i_spectrum = ilambda_off + ilambda;
00260 if (spectrum_by_lambda[i_spectrum] == 0) {
00261 spectrum_by_lambda[i_spectrum] = 1;
00262 spectrum_flux[i_spectrum] = flux[i_rec_order];
00263 spectrum_errs[i_spectrum] = errs[i_rec_order];
00264 spectrum_qual[i_spectrum] = qual[i_rec_order];
00265 } else {
00266 double flux_a, err_a, weight_a;
00267 double flux_b, err_b, weight_b;
00268 double flux_res = 0.0, err_res = 1.0;
00269 int qual_a, qual_b, qual_res;
00270
00271 flux_a = spectrum_flux[i_spectrum];
00272 err_a = spectrum_errs[i_spectrum];
00273 qual_a = spectrum_qual[i_spectrum];
00274
00275 flux_b = flux[i_rec_order];
00276 err_b = errs[i_rec_order];
00277 qual_b = qual[i_rec_order];
00278
00279
00280 flux_res = flux_a;
00281 err_res = err_a;
00282 qual_res = qual_a;
00283
00284
00285 if (((qual_a & decode_bp) == 0) && ((qual_b & decode_bp) > 0)) {
00286 flux_res = flux_a;
00287 err_res = err_a;
00288 qual_res = qual_a;
00289
00290
00291 } else if (((qual_a & decode_bp) > 0) && ((qual_b & decode_bp) == 0)) {
00292 flux_res = flux_b;
00293 err_res = err_b;
00294 qual_res = qual_b;
00295
00296
00297 } else {
00298
00299
00300 weight_a = 1.0 / (err_a * err_a);
00301 weight_b = 1.0 / (err_b * err_b);
00302
00303 check(xsh_merge_point( flux_a, weight_a, flux_b, weight_b, &flux_res, &err_res));
00304 qual_res = qual_a | qual_b;
00305 }
00306
00307
00308 spectrum_flux[i_spectrum] = flux_res;
00309 spectrum_errs[i_spectrum] = err_res;
00310 spectrum_qual[i_spectrum] = qual_res;
00311 spectrum_by_lambda[i_spectrum] = 1;
00312 }
00313
00314 }
00315
00316 }
00317 }
00318
00319 }
00320 if (problem_slit_size == 1) {
00321 xsh_msg_warning("spectrum size slit is different from order size");
00322 }
00323
00324 if (eso_mode) {
00325 cpl_propertylist_erase_regexp(rec_list->header, "^CRVAL1", 0);
00326 cpl_propertylist_erase_regexp(rec_list->header, "^CRVAL2", 0);
00327 cpl_propertylist_erase_regexp(rec_list->header, "^CRPIX1", 0);
00328 cpl_propertylist_erase_regexp(rec_list->header, "^CRPIX2", 0);
00329 cpl_propertylist_erase_regexp(rec_list->header, "^CDELT1", 0);
00330 cpl_propertylist_erase_regexp(rec_list->header, "^CDELT2", 0);
00331 }check( cpl_propertylist_append( spectrum->flux_header, rec_list->header));
00332
00333 const char* bunit = xsh_pfits_get_bunit(spectrum->flux_header);
00334 xsh_pfits_set_bunit(spectrum->errs_header, bunit);
00335
00336 check( res_frame = xsh_spectrum_save(spectrum, spectrum_name,tag));
00337 check( cpl_frame_set_tag( res_frame, tag));
00338
00339 cleanup: xsh_spectrum_free(&spectrum);
00340 xsh_rec_list_free(&rec_list);
00341 XSH_FREE( spectrum_by_lambda);
00342 XSH_FREE( spectrum_name);
00343 return res_frame;
00344 }
00345
00346
00361
00362 cpl_frame * xsh_merge_ord( cpl_frame * rec_frame, xsh_instrument* instrument,
00363 int merge_par,const char* rec_prefix)
00364 {
00365 cpl_frame *res_frame = NULL;
00366 xsh_msg("Merge slit orders");
00367 check( res_frame = xsh_merge_ord_slitlet( rec_frame, instrument, merge_par,
00368 CENTER_SLIT,rec_prefix));
00369
00370 cleanup:
00371 return res_frame;
00372 }
00373
00390
00391 cpl_frame * xsh_merge_ord_slitlet( cpl_frame * rec_frame,
00392 xsh_instrument* instrument,
00393 int merge_par, int slitlet,
00394 const char* rec_prefix)
00395 {
00396 cpl_frame *res_frame = NULL;
00397 cpl_propertylist *header = NULL;
00398 const char *rec_pcatg = NULL;
00399 const char *tag_suf = NULL;
00400 const char *filename = NULL;
00401 char tag[256];
00402
00403
00404 XSH_ASSURE_NOT_NULL( rec_frame);
00405 XSH_ASSURE_NOT_NULL( instrument);
00406
00407
00408 check( filename = cpl_frame_get_filename( rec_frame));
00409 check( header = cpl_propertylist_load( filename, 0));
00410 check( rec_pcatg = xsh_pfits_get_pcatg( header));
00411 check(tag_suf = cpl_frame_get_tag(rec_frame));
00412
00413 if ( strstr( rec_pcatg, XSH_FLUX_ORDER2D ) != NULL ) {
00414 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE2D, instrument);
00415 }
00416 else if ( strstr( rec_pcatg, XSH_NORM_ORDER2D ) != NULL ) {
00417 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE2D, instrument);
00418 }
00419
00420
00421
00422
00423 else if ( strstr( rec_pcatg, XSH_ORDER2D ) != NULL ) {
00424 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE2D, slitlet,
00425 instrument);
00426 }
00427 else if ( strstr( rec_pcatg, XSH_COMBINED_OFFSET_2D_SLIT ) != NULL){
00428
00429 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE2D,
00430 instrument);
00431 }
00432 else if ( strstr( rec_pcatg, XSH_ORDER_EXT1D ) != NULL){
00433
00434 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_EXT1D,
00435 instrument);
00436 }
00437 else if ( strstr( rec_pcatg, XSH_ORDER_OXT1D ) != NULL){
00438
00439 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_MERGE_OXT1D,
00440 instrument);
00441 }
00442 else if ( strstr( rec_pcatg, XSH_FLUX_OXT1D ) != NULL){
00443 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MOXT1D, instrument);
00444 }
00445 else if ( strstr( rec_pcatg, XSH_FLUX_ORDER1D ) != NULL){
00446 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_FLUX_MERGE1D, instrument);
00447 }
00448 else if ( strstr( rec_pcatg, XSH_NORM_ORDER1D ) != NULL){
00449 tag_suf = XSH_GET_TAG_FROM_ARM( XSH_NORM_MERGE1D, instrument);
00450 }
00451 else if ( strstr( rec_pcatg, XSH_ORDER1D ) != NULL){
00452 tag_suf = XSH_GET_TAG_FROM_SLITLET( XSH_MERGE1D, slitlet,
00453 instrument);
00454 }
00455 else{
00456 tag_suf="";
00457 xsh_msg_error("Invalid PRO.CATG %s for file %s", rec_pcatg, filename);
00458 }
00459 sprintf(tag,"%s_%s",rec_prefix,tag_suf);
00460 check( res_frame = xsh_merge_ord_with_tag( rec_frame, instrument,
00461 merge_par, tag));
00462
00463 cleanup:
00464 xsh_free_propertylist( &header);
00465 return res_frame ;
00466 }
00467
00468
00469 static void xsh_frame_set_shift_ref( cpl_frame *rec_frame, cpl_frame *shift_frame)
00470 {
00471 cpl_propertylist *rec_header = NULL;
00472 cpl_propertylist *shift_header = NULL;
00473 const char *rec_name = NULL;
00474 const char *shift_name = NULL;
00475 double waveref, slitref;
00476
00477 XSH_ASSURE_NOT_NULL( rec_frame);
00478 XSH_ASSURE_NOT_NULL( shift_frame);
00479
00480 check( rec_name = cpl_frame_get_filename( rec_frame));
00481 check( shift_name = cpl_frame_get_filename( shift_frame));
00482
00483 check( rec_header = cpl_propertylist_load( rec_name, 0));
00484 check( shift_header = cpl_propertylist_load( shift_name, 0));
00485
00486 waveref = xsh_pfits_get_shiftifu_lambdaref( shift_header);
00487 slitref = xsh_pfits_get_shiftifu_slitref( shift_header);
00488
00489 if (cpl_error_get_code() == CPL_ERROR_NONE){
00490 check( xsh_pfits_set_shiftifu_lambdaref( rec_header, waveref));
00491 check( xsh_pfits_set_shiftifu_slitref( rec_header, slitref));
00492 check( cpl_propertylist_save( rec_header, rec_name, CPL_IO_EXTEND));
00493 }
00494 xsh_error_reset();
00495
00496 cleanup:
00497 xsh_free_propertylist( &rec_header);
00498 xsh_free_propertylist( &shift_header);
00499 return;
00500 }
00501
00502
00503
00518
00519 cpl_frameset* xsh_merge_ord_ifu(cpl_frameset* rec_frameset,
00520 xsh_instrument* instrument,
00521 int merge_par,
00522 const char* rec_prefix)
00523 {
00524 cpl_frameset *result_set = NULL;
00525 cpl_frameset *drl_frameset = NULL;
00526 int slitlet;
00527 int i=0;
00528
00529 XSH_ASSURE_NOT_NULL( rec_frameset);
00530 XSH_ASSURE_NOT_NULL( instrument);
00531
00532 xsh_msg("Merge IFU orders");
00533 check( result_set = cpl_frameset_new());
00534 check( drl_frameset = xsh_frameset_drl_frames( rec_frameset));
00535
00536
00537 for( slitlet = LOWER_IFU_SLITLET; slitlet <= UPPER_IFU_SLITLET; slitlet++){
00538 cpl_frame * rec_frame = NULL ;
00539 cpl_frame * ord_frame = NULL ;
00540
00541 check( rec_frame = cpl_frameset_get_frame( drl_frameset, i));
00542
00543
00544 check( ord_frame = xsh_merge_ord_slitlet( rec_frame, instrument,
00545 merge_par,slitlet,rec_prefix));
00546
00547 check( xsh_frame_set_shift_ref( rec_frame, ord_frame));
00548 xsh_msg( "Merge for Slitlet %s, %s", SlitletName[slitlet],
00549 cpl_frame_get_filename( ord_frame)) ;
00550 check( cpl_frameset_insert( result_set, ord_frame));
00551 i++;
00552 }
00553
00554 cleanup:
00555 if (cpl_error_get_code() != CPL_ERROR_NONE){
00556 xsh_free_frameset( &result_set);
00557 }
00558 xsh_free_frameset( &drl_frameset);
00559 return result_set ;
00560 }
00561