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
00036
00037
00041
00042
00043
00044
00045 #include <math.h>
00046 #include <xsh_data_spectrum1D.h>
00047 #include <xsh_data_spectrum.h>
00048 #include <xsh_utils.h>
00049 #include <xsh_error.h>
00050 #include <xsh_msg.h>
00051 #include <xsh_pfits.h>
00052 #include <xsh_dfs.h>
00053 #include <cpl.h>
00054
00055
00056
00057
00058
00059
00069
00070 xsh_spectrum1D* xsh_spectrum1D_create( double lambda_min, double lambda_max,
00071 double lambda_step)
00072 {
00073 xsh_spectrum1D* result = NULL;
00074
00075
00076
00077 XSH_ASSURE_NOT_ILLEGAL( lambda_min >= 0.0 && lambda_min <= lambda_max);
00078 XSH_ASSURE_NOT_ILLEGAL( lambda_step >=0);
00079
00080 XSH_CALLOC(result, xsh_spectrum1D,1);
00081
00082 result->lambda_min = lambda_min;
00083 result->lambda_max = lambda_max;
00084 result->lambda_step = lambda_step;
00085
00086 XSH_NEW_PROPERTYLIST( result->flux_header);
00087 check( xsh_pfits_set_crpix1( result->flux_header, 0.5));
00088 check( xsh_pfits_set_crval1( result->flux_header, lambda_min));
00089 check( xsh_pfits_set_cdelt1( result->flux_header, lambda_step));
00090
00091 XSH_NEW_PROPERTYLIST( result->errs_header);
00092 check( xsh_pfits_set_extname ( result->errs_header, "ERRS"));
00093 XSH_NEW_PROPERTYLIST( result->qual_header);
00094 check( xsh_pfits_set_extname ( result->qual_header, "QUAL"));
00095
00096
00097 result->size = (int)((lambda_max-lambda_min)/lambda_step+0.5);
00098
00099 check( result->flux = cpl_image_new( result->size, 1, CPL_TYPE_DOUBLE));
00100 check( result->errs = cpl_image_new( result->size, 1, CPL_TYPE_DOUBLE));
00101 check( result->qual = cpl_image_new( result->size, 1, CPL_TYPE_INT));
00102
00103 cleanup:
00104 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00105 xsh_spectrum1D_free(&result);
00106 }
00107 return result;
00108 }
00109
00110
00111
00120
00121 xsh_spectrum1D* xsh_spectrum1D_load( cpl_frame* s1d_frame,
00122 xsh_instrument* instr)
00123 {
00124 xsh_spectrum1D* result = NULL;
00125 const char *s1dname = NULL;
00126
00127 XSH_ASSURE_NOT_NULL( s1d_frame);
00128 XSH_ASSURE_NOT_NULL( instr);
00129
00130 XSH_ASSURE_NOT_ILLEGAL(cpl_frame_get_nextensions(s1d_frame) == 2);
00131
00132 check( s1dname = cpl_frame_get_filename( s1d_frame));
00133
00134 XSH_CALLOC(result, xsh_spectrum1D,1);
00135
00136 check( result->flux_header = cpl_propertylist_load( s1dname,0));
00137 check( result->errs_header = cpl_propertylist_load( s1dname,1));
00138 check( result->qual_header = cpl_propertylist_load( s1dname,2));
00139
00140 check( result->lambda_min = xsh_pfits_get_crval1( result->flux_header));
00141 check( result->lambda_step = xsh_pfits_get_cdelt1( result->flux_header));
00142 check( result->size = xsh_pfits_get_naxis1( result->flux_header));
00143 result->lambda_max = result->lambda_min+
00144 (result->lambda_step*result->size-1);
00145
00146 check( result->flux = cpl_image_load( s1dname, CPL_TYPE_DOUBLE, 0, 0));
00147 check( result->errs = cpl_image_load( s1dname, CPL_TYPE_DOUBLE, 0, 1));
00148 check( result->qual = cpl_image_load( s1dname, CPL_TYPE_INT, 0, 2));
00149
00150 cleanup:
00151 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00152 xsh_spectrum1D_free(&result);
00153 }
00154 return result;
00155 }
00156
00164
00165 int xsh_spectrum1D_get_size( xsh_spectrum1D* s)
00166 {
00167 int res=0;
00168
00169 XSH_ASSURE_NOT_NULL( s);
00170
00171 res = s->size;
00172
00173 cleanup:
00174 return res;
00175 }
00176
00177
00185
00186 double xsh_spectrum1D_get_lambda_min( xsh_spectrum1D* s)
00187 {
00188 double res=0.0;
00189
00190 XSH_ASSURE_NOT_NULL( s);
00191
00192 res = s->lambda_min;
00193
00194 cleanup:
00195 return res;
00196 }
00197
00198
00206
00207 double xsh_spectrum1D_get_lambda_max( xsh_spectrum1D* s)
00208 {
00209 double res=0.0;
00210
00211 XSH_ASSURE_NOT_NULL( s);
00212
00213 res = s->lambda_max;
00214
00215 cleanup:
00216 return res;
00217 }
00218
00219
00227
00228 double xsh_spectrum1D_get_lambda_step( xsh_spectrum1D* s)
00229 {
00230 double res=0.0;
00231
00232 XSH_ASSURE_NOT_NULL( s);
00233
00234 res = s->lambda_step;
00235
00236 cleanup:
00237 return res;
00238 }
00239
00240
00241
00249
00250 double* xsh_spectrum1D_get_flux( xsh_spectrum1D* s)
00251 {
00252 double *res=NULL;
00253
00254 XSH_ASSURE_NOT_NULL( s);
00255
00256 check( res = cpl_image_get_data_double( s->flux));
00257
00258 cleanup:
00259 return res;
00260 }
00261
00262
00263
00271
00272 double* xsh_spectrum1D_get_errs( xsh_spectrum1D* s)
00273 {
00274 double *res=NULL;
00275
00276 XSH_ASSURE_NOT_NULL( s);
00277
00278 check( res = cpl_image_get_data_double( s->errs));
00279
00280 cleanup:
00281 return res;
00282 }
00283
00284
00285
00293
00294 int* xsh_spectrum1D_get_qual( xsh_spectrum1D* s)
00295 {
00296 int* res = NULL;
00297
00298 XSH_ASSURE_NOT_NULL( s);
00299
00300 check( res = cpl_image_get_data_int( s->qual));
00301
00302 cleanup:
00303 return res;
00304 }
00305
00306
00312
00313 void xsh_spectrum1D_free( xsh_spectrum1D** s)
00314 {
00315 if (s && *s){
00316 xsh_free_propertylist( &((*s)->flux_header));
00317 xsh_free_propertylist( &((*s)->errs_header));
00318 xsh_free_propertylist( &((*s)->qual_header));
00319 xsh_free_image( &((*s)->flux));
00320 xsh_free_image( &((*s)->errs));
00321 xsh_free_image( &((*s)->qual));
00322 XSH_FREE( (*s));
00323 }
00324 }
00325
00326
00335
00336 cpl_frame* xsh_spectrum1D_save( xsh_spectrum1D* s, const char* filename)
00337 {
00338 cpl_frame *product_frame = NULL;
00339
00340 XSH_ASSURE_NOT_NULL(s);
00341 XSH_ASSURE_NOT_NULL(filename);
00342
00343
00344
00345 check_msg (cpl_image_save ( s->flux, filename, XSH_SPECTRUM1D_DATA_BPP,
00346 s->flux_header, CPL_IO_DEFAULT),
00347 "Could not save data to %s extension 0", filename);
00348 check_msg (cpl_image_save ( s->errs, filename, XSH_SPECTRUM1D_ERRS_BPP,
00349 s->errs_header, CPL_IO_EXTEND),
00350 "Could not save errs to %s extension 1", filename);
00351 check_msg (cpl_image_save ( s->qual, filename, XSH_SPECTRUM1D_QUAL_BPP,
00352 s->qual_header, CPL_IO_EXTEND),
00353 "Could not save qual to %s extension 2", filename);
00354
00355
00356 check(product_frame=xsh_frame_product(filename,
00357 "TAG",
00358 CPL_FRAME_TYPE_IMAGE,
00359 CPL_FRAME_GROUP_PRODUCT,
00360 CPL_FRAME_LEVEL_FINAL));
00361
00362 cleanup:
00363 if (cpl_error_get_code () != CPL_ERROR_NONE) {
00364 xsh_free_frame(&product_frame);
00365 product_frame = NULL;
00366 }
00367 return product_frame;
00368 }
00369
00370 static cpl_error_code
00371 xsh_monitor_spectrum1D_flux_qc(xsh_spectrum* s,
00372 const double ws,
00373 const double we,
00374 const int index)
00375 {
00376
00377 int xstart=0;
00378 int xend=0;
00379 double flux=0;
00380 double err=0;
00381 double sn=0;
00382
00383 char comment[40];
00384 char qc_key[20];
00385 xstart=((ws - s->lambda_min)/s->lambda_step+0.5);
00386 xend= ((we - s->lambda_min)/s->lambda_step-0.5);
00387
00388 xstart=(xstart < s->size) ? xstart: s->size;
00389 xend=(xend < s->size) ? xend: s->size;
00390 xstart=(xstart < xend) ? xstart: xend-1;
00391
00392 check(flux=cpl_image_get_mean_window(s->flux,xstart,1,xend,1));
00393 sprintf(qc_key,"%s%d VAL",XSH_QC_FLUX,index);
00394 sprintf(comment,"Flux in %4.0f-%4.0f nm",ws,we);
00395
00396 check(cpl_propertylist_append_double(s->flux_header,qc_key,flux));
00397 check(cpl_propertylist_set_comment(s->flux_header,qc_key,comment));
00398
00399 err=cpl_image_get_mean_window(s->errs,xstart,1,xend,1);
00400 sprintf(qc_key,"%s%d ERR",XSH_QC_FLUX,index);
00401 sprintf(comment,"Error Flux in %4.0f-%4.0f nm",ws,we);
00402
00403 cpl_propertylist_append_double(s->flux_header,qc_key,err);
00404 cpl_propertylist_set_comment(s->flux_header,qc_key,comment);
00405
00406 sprintf(qc_key,"%s%d SN",XSH_QC_FLUX,index);
00407 sprintf(comment,"Signal to noise ratio in %4.0f-%4.0f nm",ws,we);
00408
00409 sn = (fabs(err) > 1.e-37) ? flux/err : -999;
00410
00411 cpl_propertylist_append_double(s->flux_header,qc_key,sn);
00412 cpl_propertylist_set_comment(s->flux_header,qc_key,comment);
00413
00414 cleanup:
00415 return cpl_error_get_code();
00416
00417 }
00418
00419
00420 cpl_error_code
00421 xsh_monitor_spectrum1D_flux(cpl_frame* in_frm,xsh_instrument* instrument)
00422 {
00423
00424 xsh_spectrum* s1d=NULL;
00425 const char* s1dname=NULL;
00426 const char *tag = NULL;
00427 cpl_frame *product = NULL;
00428
00429 check( s1dname=cpl_frame_get_filename(in_frm));
00430 check( s1d=xsh_spectrum_load(in_frm));
00431 check( tag = cpl_frame_get_tag(in_frm));
00432
00433 if ( xsh_instrument_get_arm(instrument) == XSH_ARM_UVB){
00434
00435 check( xsh_monitor_spectrum1D_flux_qc(s1d,450,470,1));
00436 check( xsh_monitor_spectrum1D_flux_qc(s1d,510,530,2));
00437
00438 }
00439 else if ( xsh_instrument_get_arm(instrument) == XSH_ARM_VIS){
00440
00441 xsh_monitor_spectrum1D_flux_qc(s1d,672,680,1);
00442 xsh_monitor_spectrum1D_flux_qc(s1d,745,756,2);
00443 xsh_monitor_spectrum1D_flux_qc(s1d,992,999,3);
00444
00445 }
00446 else if ( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
00447
00448 check(xsh_monitor_spectrum1D_flux_qc(s1d,1514,1548,1));
00449 if(!xsh_instrument_nir_is_JH(in_frm,instrument)) {
00450 check(xsh_monitor_spectrum1D_flux_qc(s1d,2214,2243,2));
00451 }
00452 }
00453
00454 check( product = xsh_spectrum_save(s1d,s1dname, tag));
00455
00456 cleanup:
00457 xsh_spectrum_free(&s1d);
00458 xsh_free_frame( &product);
00459 return cpl_error_get_code();
00460 }
00461