33 #include "omega_recipe.h"
35 #include "omega_coadd.h"
36 #include "omega_catalog.h"
37 #include "omega_background.h"
38 #include "omega_cosmic.h"
39 #include "omega_photometry.h"
40 #include "omega_science.h"
41 #include "omega_satellites.h"
42 #include "omega_wcscor.h"
95 static int omega_science_create(cpl_plugin *) ;
96 static int omega_science_exec(cpl_plugin *) ;
97 static int omega_science_destroy(cpl_plugin *) ;
98 static int omega_science(cpl_frameset *,cpl_parameterlist *);
104 static int omega_science_retrieve_input_param(
const cpl_parameterlist *parlist);
105 static int omega_science_load_calib();
106 static void omega_science_init(
void);
107 static void omega_science_tidy(
int level);
108 static cpl_error_code omega_correct_crpix_union(cpl_propertylist *xlist,
109 cpl_bivector *offsets);
123 }omega_science_config;
148 const cpl_frame *bpmfr;
149 const cpl_frame *fringesfr;
150 const cpl_frame *illumfr;
151 const cpl_frame *mbiasfr;
152 const cpl_frame *mflatfr;
153 const cpl_frame *nskyfr;
154 const cpl_frame *usnoa2;
155 const cpl_frame *photomfr;
158 cpl_frameset *scilist;
159 cpl_propertylist *ph;
160 cpl_propertylist *eh;
175 cpl_image **combined;
176 cpl_table *catalogue;
177 cpl_propertylist *qclist;
178 cpl_propertylist *plist;
183 #define RECIPE "omega_science"
197 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
198 cpl_plugin * plugin = &recipe->interface ;
200 cpl_plugin_init(plugin,
202 OMEGA_BINARY_VERSION,
203 CPL_PLUGIN_TYPE_RECIPE,
205 "OMEGA - This recipe is used to reduce science observations.",
206 "The recipe assumes that the data is for a single CCD. \n"
207 "The following operations are performed: \n\n"
208 " 1. Trim and overscan correct; \n"
209 " 2. Subtract the bias and divide by the flat field; \n"
210 " 3. Correct for fringing, illumination and the background, if requested; \n"
211 " 4. Extract the zero point from the data and calculate the extinction \n"
212 " value and save both in the header and in one table. \n\n"
213 " ------------------------------------------------------------------------ \n\n"
214 " Mandatory inputs : \n\n"
215 " : a raw standard star frame \n"
216 " : a master bias frame (Calfile 541) \n"
217 " : a master flat field (Calfile 546) \n\n"
218 " : a master USNOA2 table \n"
219 " : a standard stars catalog table \n\n"
220 " Optional inputs : \n\n"
221 " : fringe map (Calfile 545) \n"
222 " : bad pixels map (Calfile 522+535) \n"
223 " : illumination correction frame (Calfile 548) \n\n"
224 " The recipe will save the extinction and zero point values in one table.",
225 "Sandra Castro / Armin Gabasch",
228 omega_science_create,
230 omega_science_destroy) ;
232 cpl_pluginlist_append(list, plugin) ;
247 static int omega_science_create(cpl_plugin * plugin)
254 if (cpl_error_get_code() != CPL_ERROR_NONE) {
255 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
256 cpl_func, __LINE__, cpl_error_get_where());
257 return (
int)cpl_error_get_code();
260 if (plugin == NULL) {
261 cpl_msg_error(cpl_func,
"Null plugin");
262 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
266 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
267 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
268 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
272 recipe = (cpl_recipe *)plugin;
275 recipe->parameters = cpl_parameterlist_new() ;
276 if (recipe->parameters == NULL) {
277 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
278 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
284 p = cpl_parameter_new_value(
"omega.omega_science.ExtensionNumber",
286 "FITS extension number to load (1 to 32). (-1 == all)",
290 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext") ;
291 cpl_parameterlist_append(recipe->parameters, p) ;
293 p = cpl_parameter_new_range(
"omega.omega_science.OverscanMethod",
295 "Overscan Correction Method",
298 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"oc-meth") ;
299 cpl_parameterlist_append(recipe->parameters, p) ;
303 p = cpl_parameter_new_value(
"omega.omega_science.LowThreSatuPixel",
305 "Low threshold for calculating the saturated pixels map.",
309 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"lt-satu") ;
310 cpl_parameterlist_append(recipe->parameters, p) ;
312 p = cpl_parameter_new_value(
"omega.omega_science.HighThreSatuPixel",
314 "High threshold for calculating the saturated pixels map.",
318 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ht-satu") ;
319 cpl_parameterlist_append(recipe->parameters, p) ;
322 p = cpl_parameter_new_value(
"omega.omega_science.DetectionThreSatellite",
324 "Minimum SNR for pixels to contribute to Hough map.",
328 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"det-sate") ;
329 cpl_parameterlist_append(recipe->parameters, p) ;
331 p = cpl_parameter_new_value(
"omega.omega_science.HoughThreshold",
333 "Threshold for satellite tracks in Hough image.",
337 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"hough-thre") ;
338 cpl_parameterlist_append(recipe->parameters, p) ;
342 p = cpl_parameter_new_value(
"omega.omega_science.SigmaFringeScaling",
344 "Sigma threshold in image data for scaling estimate (fringes only)",
348 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sigma-fringes") ;
349 cpl_parameterlist_append(recipe->parameters, p) ;
351 p = cpl_parameter_new_value(
"omega.omega_science.LowThreFringe",
353 "Lower bound of fringes to include in scaling (fringes only)",
357 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"lfringes") ;
358 cpl_parameterlist_append(recipe->parameters, p) ;
360 p = cpl_parameter_new_value(
"omega.omega_science.HighThreFringe",
362 "Higher bound of fringes to include in scaling (fringes only)",
366 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"hfringes") ;
367 cpl_parameterlist_append(recipe->parameters, p) ;
371 p = cpl_parameter_new_value(
"omega.omega_science.SubtractBackground",
373 "Boolean value to subtract background or not. 1(TRUE), 0(FALSE)",
377 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sub-back") ;
378 cpl_parameterlist_append(recipe->parameters, p) ;
380 p = cpl_parameter_new_value(
"omega.omega_science.BackThreshold",
382 "Detection threshold for background in image (Sextractor DETECT_THRESH)",
386 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"backthre") ;
387 cpl_parameterlist_append(recipe->parameters, p) ;
391 path = cpl_sprintf(
"%s", OMEGA_BIN_PATH);
392 p = cpl_parameter_new_value(
"omega.omega_science.BinPath",
394 "Path to any external executable program.",
398 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"bin-path");
399 cpl_parameterlist_append(recipe->parameters, p);
403 path = cpl_sprintf(
"%s/omega.sex", OMEGA_CONFIG_PATH);
404 p = cpl_parameter_new_value(
"omega.omega_science.SexConfig",
406 "Path to Sextractor config file.",
410 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-config");
411 cpl_parameterlist_append(recipe->parameters, p);
415 path = cpl_sprintf(
"%s/omega.conv", OMEGA_CONFIG_PATH);
416 p = cpl_parameter_new_value(
"omega.omega_science.SexConv",
418 "Path to Sextractor convolution mask file.",
422 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-conv");
423 cpl_parameterlist_append(recipe->parameters, p);
427 path = cpl_sprintf(
"%s/omega.param", OMEGA_CONFIG_PATH);
428 p = cpl_parameter_new_value(
"omega.omega_science.SexParam",
430 "Path to Sextractor parameters file.",
434 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-param");
435 cpl_parameterlist_append(recipe->parameters, p);
438 path = cpl_sprintf(
"%s/omega.nnw", OMEGA_CONFIG_PATH);
439 p = cpl_parameter_new_value(
"omega.omega_science.SexNnw",
441 "Path to Sextractor neural network config file.",
445 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-nnw");
446 cpl_parameterlist_append(recipe->parameters, p);
449 p = cpl_parameter_new_value(
"omega.omega_science.SexDetThreshold",
451 "Detection threshold for Sextractor sources.",
455 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-dthre");
456 cpl_parameterlist_append(recipe->parameters, p);
460 path = cpl_sprintf(
"%s/omega.cosmic.sex", OMEGA_CONFIG_PATH);
461 p = cpl_parameter_new_value(
"omega.omega_science.SexCosmic",
463 "Path to Sextractor cosmic detection mode config file.",
467 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-cosmic");
468 cpl_parameterlist_append(recipe->parameters, p);
471 path = cpl_sprintf(
"%s/omega.cosmic.param", OMEGA_CONFIG_PATH);
472 p = cpl_parameter_new_value(
"omega.omega_science.SexCosmicParam",
474 "Path to Sextractor cosmic parameters file.",
478 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sex-cosmic-param");
479 cpl_parameterlist_append(recipe->parameters, p);
482 path = cpl_sprintf(
"%s/cosmic.ret", OMEGA_CONFIG_PATH);
483 p = cpl_parameter_new_value(
"omega.omega_science.SexCosmicFilt",
485 "Path to Sextractor filter mask for cosmic detection mode.",
489 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-cosfilt");
490 cpl_parameterlist_append(recipe->parameters, p);
493 p = cpl_parameter_new_value(
"omega.omega_science.SexCosmicDet",
495 "Detection threshold for detecting cosmic rays in Sextractor",
499 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sex-cosmic-det") ;
500 cpl_parameterlist_append(recipe->parameters, p) ;
504 p = cpl_parameter_new_value(
"omega.omega_science.AstromDetThre",
506 "Sextractor threshold to detect stars for astrometric correction.",
510 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"astrom-thre") ;
511 cpl_parameterlist_append(recipe->parameters, p) ;
513 p = cpl_parameter_new_enum(
"omega.omega_science.PlateSolution",
515 "Number of constant plate fits to do for the astrometry solution.",
519 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"platesol");
520 cpl_parameterlist_append(recipe->parameters, p);
522 p = cpl_parameter_new_value(
"omega.omega_science.NumIterations",
524 "Number of iterations for the plate solution fitting.",
528 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"niter");
529 cpl_parameterlist_append(recipe->parameters, p);
532 p = cpl_parameter_new_range(
"omega.omega_science.SextractorFlagLimit",
534 "Sextractor FLAG upper limit to preselect good sources for the "
535 "astrometric correction computation.",
"omega.Astrom",
537 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"SextractorFlagLimit") ;
538 cpl_parameterlist_append(recipe->parameters, p) ;
540 p = cpl_parameter_new_range(
"omega.omega_science.SextractorClassStar",
542 "Sextractor CLASS_STAR lower limit to preselect starlike objects "
543 "for the astrometric correction computation.",
"omega.Astrom",
545 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"SextractorClassStar") ;
546 cpl_parameterlist_append(recipe->parameters, p) ;
551 p = cpl_parameter_new_value(
"omega.omega_science.PhotomDetThre",
553 "Sextractor threshold to detect stars for photometric correction.",
557 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"photom-thre") ;
558 cpl_parameterlist_append(recipe->parameters, p) ;
560 p = cpl_parameter_new_value(
"omega.omega_science.MatchPhotomRadius",
562 "Radius within which to match photometric stds and stars",
566 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"radius") ;
567 cpl_parameterlist_append(recipe->parameters, p) ;
569 p = cpl_parameter_new_value(
"omega.omega_science.PhotomAperture",
571 "Aperture in pixels for photometric measurements in Sextractor",
575 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"aperture") ;
576 cpl_parameterlist_append(recipe->parameters, p) ;
579 p = cpl_parameter_new_value(
"omega.omega_science.Nstars",
581 "Number of stars in image to use in "
586 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nstars");
587 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
588 cpl_parameterlist_append(recipe->parameters, p);
591 p = cpl_parameter_new_value(
"omega.omega_science.Npattern",
593 "Number of catalogue sources to use in "
598 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"npattern");
599 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
600 cpl_parameterlist_append(recipe->parameters, p);
603 p = cpl_parameter_new_value(
"omega.omega_science.Tolerance",
605 "Max relative difference of angles and scales from their "
606 "median value for match acceptance (tolerance)",
610 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"tol");
611 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
612 cpl_parameterlist_append(recipe->parameters, p);
614 p = cpl_parameter_new_value(
"omega.omega_science.SearchPatternRadius",
616 "Search radius for full PPM (pixels)",
619 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"pradius");
620 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
621 cpl_parameterlist_append(recipe->parameters, p);
623 p = cpl_parameter_new_value(
"omega.omega_science.MaxPatternRadius",
625 "Maximum search radius for full PPM (pixels)",
628 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"maxpradius");
629 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
630 cpl_parameterlist_append(recipe->parameters, p);
633 p = cpl_parameter_new_value(
"omega.omega_science.xcorr",
635 "String of four values meaning: x,y search area and "
636 "x,y measurement area, needed for cross-correlation "
637 "when stacking images",
641 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xcorr");
642 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
643 cpl_parameterlist_append(recipe->parameters, p);
645 p = cpl_parameter_new_value(
"omega.omega_science.CombMode",
647 "Combination mode to use when stacking images. "
648 "union,intersect or first",
652 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"comb-mode");
653 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
654 cpl_parameterlist_append(recipe->parameters, p);
656 p = cpl_parameter_new_value(
"omega.omega_science.StackRej",
658 "Number of low and high values to reject when stacking",
662 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stack-rej");
663 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
664 cpl_parameterlist_append(recipe->parameters, p);
667 p = cpl_parameter_new_value(
"omega.omega_science.CatThre",
669 "Sextractor threshold to detect sources in stack image",
673 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"cat-thre") ;
674 cpl_parameterlist_append(recipe->parameters, p) ;
678 p = cpl_parameter_new_value(
"omega.omega_science.mag_zpt_no_std_table",
680 "Zeropoint used if the standard star zeropoint table is empty ",
683 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"mag_zpt_no_std_table") ;
684 cpl_parameterlist_append(recipe->parameters, p) ;
688 p = cpl_parameter_new_value(
"omega.omega_science.mag_zpt_err_no_std_table",
690 "Zeropoint error used if the standard star zeropoint table is empty ",
693 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"mag_zpt_err_no_std_table") ;
694 cpl_parameterlist_append(recipe->parameters, p) ;
698 p = cpl_parameter_new_value(
"omega.omega_science.ext_no_std_table",
700 "extinction used if the standard star zeropoint table is empty",
703 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ext_no_std_table") ;
704 cpl_parameterlist_append(recipe->parameters, p) ;
718 static int omega_science_exec(cpl_plugin * plugin)
724 if (cpl_error_get_code() != CPL_ERROR_NONE) {
725 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
726 cpl_func, __LINE__, cpl_error_get_where());
727 return (
int)cpl_error_get_code();
730 if (plugin == NULL) {
731 cpl_msg_error(cpl_func,
"Null plugin");
732 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
736 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
737 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
738 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
742 recipe = (cpl_recipe *)plugin;
745 if (recipe->parameters == NULL) {
746 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
747 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
749 if (recipe->frames == NULL) {
750 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
751 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
755 recipe_status = omega_science(recipe->frames, recipe->parameters);
758 if (cpl_dfs_update_product_header(recipe->frames)) {
759 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
762 return recipe_status;
773 static int omega_science_destroy(cpl_plugin * plugin)
777 if (plugin == NULL) {
778 cpl_msg_error(cpl_func,
"Null plugin");
779 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
783 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
784 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
785 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
789 recipe = (cpl_recipe *)plugin;
791 cpl_parameterlist_delete(recipe->parameters) ;
807 static int omega_science(cpl_frameset *
set, cpl_parameterlist *pars)
809 int j,jst,jfn,i,n_ext;
813 static int isfirst = 0;
814 cpl_size *plabels = NULL;
816 double pixscalex = 0.0;
817 double pixscaley = 0.0;
819 double ellipticity = 0.0;
820 double zeropoint_final=0.0;
821 const char *smoothed =
"omega_stacksmooth.fits";
822 const char *smoothed_weight =
"omega_stacksmooth_weight.fits";
823 const char *tag = NULL;
824 const char *tag_mask = NULL;
825 const char * maskname= NULL;
828 cpl_image *image_simple_mask=NULL;
830 cpl_frame *firstframe=NULL;
831 cpl_frame *product_frame=NULL ;
832 cpl_frame *product_frame_mask=NULL ;
833 cpl_frame *conf_frame;
835 cpl_frameset *proset=NULL;
836 cpl_frameset *proset_mask=NULL;
837 cpl_bivector *offsets=NULL;
838 cpl_propertylist *plist, *xlist, *alist;
839 cpl_propertylist *plist_dummy=NULL;
840 cpl_propertylist *flist;
841 cpl_propertylist *qclist=NULL;
842 cpl_parameter *par = NULL;
843 const char *sval = NULL;
849 cpl_msg_error (cpl_func,
"Parameters list not found");
853 if (cpl_frameset_is_empty(
set) == 1) {
854 cpl_msg_error (cpl_func,
"Frameset not found");
859 if(omega_science_retrieve_input_param(pars) != 0){
860 cpl_msg_error(cpl_func,
"Cannot retrieve input parameters. %s", cpl_error_get_message());
865 if (oc_dfs_set_groups(
set)) {
866 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames") ;
871 omega_science_init();
872 omega_sci_qc.Seeing = 0.0;
873 omega_sci_qc.mratio = 0.0;
874 omega_sci_qc.nmatches = 0;
875 omega_sci_qc.nstars = 0;
880 cpl_msg_error(cpl_func,
"Cannot labelise the input frameset");
881 omega_science_tidy(0);
885 omega_science_config.mode = 0;
888 STARE_RAW)) != NULL) {
889 omega_science_config.mode = 1;
894 JITTER_RAW)) != NULL) {
895 omega_science_config.mode = 2;
900 DITHER_RAW)) != NULL) {
901 omega_science_config.mode = 3;
906 OFFSET_RAW)) != NULL) {
907 omega_science_config.mode = 4;
912 cpl_msg_error(cpl_func,
"Cannot find science frames in input frameset");
913 omega_science_tidy(0);
917 nraw = cpl_frameset_get_size(ps.scilist);
918 cpl_msg_info(cpl_func,
"There are %d %s frames in frame set",nraw,tag);
922 ps.mbiasfr = cpl_frameset_find_const(
set, OMEGA_CALIB_BIAS);
923 if (ps.mbiasfr == NULL) {
924 cpl_msg_error(cpl_func,
"Cannot find %s frame in frame set", OMEGA_CALIB_BIAS);
925 omega_science_tidy(0);
927 cpl_msg_info(cpl_func,
"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(ps.mbiasfr));
930 ps.mflatfr = cpl_frameset_find_const(
set, OMEGA_CALIB_FLAT);
931 if(ps.mflatfr == NULL) {
932 cpl_msg_error(cpl_func,
"Cannot find %s frame in frame set", OMEGA_CALIB_FLAT);
933 omega_science_tidy(0);
936 cpl_msg_info(cpl_func,
"Using %s %s", OMEGA_CALIB_FLAT, cpl_frame_get_filename(ps.mflatfr));
939 ps.photomfr = cpl_frameset_find (
set,OMEGA_CALIB_ZP);
940 if(ps.photomfr == NULL) {
941 cpl_msg_warning(cpl_func,
"Cannot find %s in frame set", OMEGA_CALIB_ZP);
946 cpl_msg_info(cpl_func,
"Using %s %s",OMEGA_CALIB_ZP,cpl_frame_get_filename(ps.photomfr));
949 ps.usnoa2 = cpl_frameset_find (
set, OMEGA_USNOA2);
950 if (ps.usnoa2 == NULL) {
951 cpl_msg_error(cpl_func,
"Cannot find %s frame in frame set",OMEGA_USNOA2);
952 omega_science_tidy(0);
955 cpl_msg_info(cpl_func,
"Using %s %s", OMEGA_USNOA2, cpl_frame_get_filename(ps.usnoa2));
958 ps.bpmfr = cpl_frameset_find (
set,OMEGA_CALIB_BPM);
959 if(ps.bpmfr == NULL) {
960 cpl_msg_error(cpl_func,
"Cannot find %s in frame set", OMEGA_CALIB_BPM);
961 omega_science_tidy(0);
964 cpl_msg_info(cpl_func,
"Using %s %s",OMEGA_CALIB_BPM,cpl_frame_get_filename(ps.bpmfr));
968 ps.illumfr = cpl_frameset_find(
set, OMEGA_CALIB_ILLUM);
969 if(ps.illumfr != NULL)
970 cpl_msg_info(cpl_func,
"Using %s %s",OMEGA_CALIB_ILLUM,cpl_frame_get_filename(ps.illumfr));
983 sciframe = cpl_frameset_find(
set,tag);
986 if(omega_science_config.extnum == 0){
987 cpl_msg_error(cpl_func,
"Unsupported extension request, %d",omega_science_config.extnum);
988 omega_science_tidy(0);
994 for(i=0; i < nraw; i++){
995 cpl_msg_info(cpl_func,
"Working on %s",cpl_frame_get_filename(sciframe));
1000 for (j = jst; j <= jfn; j++) {
1001 isfirst = (j == jst);
1003 cpl_msg_indent_more();
1004 cpl_msg_info(cpl_func,
".....Working on extension %d.....",j);
1005 cpl_msg_indent_less();
1008 if(omega_science_load_calib(j) != 0){
1009 cpl_msg_error(cpl_func,
"Cannot load calibration frame(s)");
1010 omega_science_tidy(0);
1019 ps.usnoa2,ps.illum,ps.fringes,ps.nsky, &zeropoint_final ,pars, j);
1021 if(ps.sfits == NULL){
1022 cpl_msg_error(cpl_func,
"Unable to reduce image");
1023 omega_science_tidy(0);
1028 omega_science_tidy(1);
1034 if(omega_science_config.mode == 1) {
1035 ps.proname = cpl_sprintf(
"%s_%s_%d.fits", INSTRUME,SIMPLE_STARE,i);
1039 if(omega_science_config.mode == 2){
1040 ps.proname = cpl_sprintf(
"%s_%s_%d.fits", INSTRUME,SIMPLE_JITTER,i);
1042 tag = SIMPLE_JITTER;
1044 if(omega_science_config.mode == 3){
1045 ps.proname = cpl_sprintf(
"%s_%s_%d.fits", INSTRUME,SIMPLE_DITHER,i);
1047 tag = SIMPLE_DITHER;
1049 if(omega_science_config.mode == 4){
1050 ps.proname = cpl_sprintf(
"%s_%s_%d.fits", INSTRUME,SIMPLE_OFFSET,i);
1052 tag = SIMPLE_OFFSET;
1054 maskname=cpl_sprintf(
"%s_%s_%d.fits", INSTRUME,SIMPLE_MASK,i);
1056 tag_mask=SIMPLE_MASK;
1059 cpl_msg_info(cpl_func,
"Saving SIMPLE image");
1060 if(
omega_save_fits(ps.sfits,
set,pars,NULL,CPL_BPP_IEEE_FLOAT,ps.proname,RECIPE,
1061 product_frame,sciframe,isfirst) == -1){
1062 cpl_msg_error(cpl_func,
"Cannot save SIMPLE image. %s",cpl_error_get_message());
1064 omega_science_tidy(0);
1069 image_simple_mask=cpl_image_new_from_mask(cpl_image_get_bpm(ps.sfits->image));
1070 cpl_image_delete(ps.sfits->image); ps.sfits->image=NULL;
1071 ps.sfits->image=image_simple_mask;
1073 cpl_msg_info(cpl_func,
"Saving SIMPLE MASK file");
1074 if(
omega_save_fits(ps.sfits,
set,pars,NULL,CPL_BPP_8_UNSIGNED,maskname,RECIPE,
1075 product_frame_mask,sciframe,isfirst) == -1){
1076 cpl_msg_error(cpl_func,
"Cannot save SIMPLE image. %s",cpl_error_get_message());
1078 omega_science_tidy(0);
1086 sciframe = cpl_frameset_find(
set, NULL);
1088 freespace(ps.proname);
1090 product_frame = NULL;
1091 product_frame_mask= NULL;
1097 cpl_msg_error(cpl_func,
"Cannot labelise the output frameset");
1098 omega_science_tidy(0);
1105 cpl_msg_error(cpl_func,
"Cannot create simple frameset");
1107 omega_science_tidy(0);
1113 tag_mask)) == NULL) {
1114 cpl_msg_error(cpl_func,
"Cannot create simple mask frameset");
1116 omega_science_tidy(0);
1144 firstframe = cpl_frameset_get_first(proset);
1145 n_ext = cpl_fits_count_extensions(cpl_frame_get_filename(firstframe));
1148 plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(firstframe),0,
"ESO INS FILT",0);
1150 has_fringes = cpl_propertylist_get_int(flist,
"HAS_FRINGES");
1155 cpl_msg_info(cpl_func,
"Creating stack image and catalogue");
1156 for(j = 1; j <= n_ext; j++){
1162 cpl_msg_indent_more();
1163 cpl_msg_info(cpl_func,
"....... Image in position %d .......",j);
1164 cpl_msg_indent_less();
1166 plist = cpl_propertylist_load(cpl_frame_get_filename(firstframe),j);
1167 omega_get_pixelscale(plist, &pixscalex, &pixscaley);
1174 if(cpl_frameset_get_size(proset)==1){
1175 ps.combined = cpl_malloc(2*
sizeof(cpl_image *));
1176 ps.combined[0]=cpl_image_load(cpl_frame_get_filename(cpl_frameset_get_first(proset)),CPL_TYPE_FLOAT,0,j);
1177 ps.combined[1]=cpl_image_load(cpl_frame_get_filename(cpl_frameset_get_first(proset_mask)),CPL_TYPE_INT,0,j);
1178 cpl_image_threshold(ps.combined[1],0.5,0.6,1,0);
1185 if(ps.combined == NULL){
1186 cpl_msg_error(cpl_func,
"Unable to create stack image. %s", cpl_error_get_message());
1187 freebivector(offsets);
1188 freeframeset(proset);
1189 freeframeset(proset_mask);
1190 omega_science_tidy(0);
1195 if(cpl_frameset_get_size(proset) >= 3){
1196 cpl_imagelist *ilist = cpl_imagelist_load_frameset(proset, CPL_TYPE_FLOAT,1,j);
1198 cpl_frameset_get_size(proset))) != NULL){
1199 cpl_image_divide(ps.combined[0],ps.nsky);
1203 if(has_fringes == 1){
1204 cpl_msg_info(cpl_func,
"Applying fringing correction");
1205 ps.bpm = cpl_image_load(cpl_frame_get_filename(ps.bpmfr),CPL_TYPE_FLOAT,0,j);
1206 ps.fringes = cpl_image_subtract_scalar_create(ps.nsky, 1.0);
1207 if(ps.fringes != NULL)
1210 freeimage(ps.fringes);
1220 if(cpl_detector_interpolate_rejected(smooth) != CPL_ERROR_NONE)
1221 cpl_msg_debug(cpl_func,
"Cannot clean rejected pixels. %s",
1222 cpl_error_get_message());
1224 xlist = cpl_propertylist_load(cpl_frame_get_filename(firstframe),j);
1227 plist_dummy = cpl_propertylist_load_regexp(
1228 cpl_frame_get_filename(firstframe),0,
"ESO INS FILT",0);
1229 cpl_propertylist_copy_property_regexp(xlist,plist_dummy,
"ESO INS FILT",0);
1230 freeplist(plist_dummy);
1236 par = cpl_parameterlist_find(pars,
"omega.omega_science.CombMode");
1237 sval = cpl_parameter_get_string(par);
1238 if (!strcmp(sval,
"union")){
1239 omega_correct_crpix_union(xlist, offsets);
1242 alist = cpl_propertylist_new();
1243 cpl_propertylist_append_string(alist,
"EXTNAME",
1244 cpl_propertylist_get_string(xlist,
"EXTNAME"));
1245 cpl_propertylist_set_comment(alist,
"EXTNAME",
"Extension name");
1248 cpl_propertylist_save(xlist,smoothed,CPL_IO_CREATE);
1249 cpl_image_save(smooth,smoothed,BITPIX,xlist,CPL_IO_EXTEND);
1251 cpl_propertylist_save(xlist,smoothed_weight,CPL_IO_CREATE);
1252 cpl_image_save(ps.combined[1],smoothed_weight,BITPIX,xlist,CPL_IO_EXTEND);
1255 cpl_msg_info(cpl_func,
"Refining WCS for stack image");
1257 &omega_sci_qc.nmatches, &omega_sci_qc.mratio);
1258 if(ps.plist == NULL){
1259 cpl_msg_warning(cpl_func,
"Unable to refine WCS for stack image");
1260 ps.plist = cpl_propertylist_duplicate(xlist);
1266 ps.qclist = cpl_propertylist_new();
1267 cpl_propertylist_update_int(ps.qclist,
"ESO QC SCI MATCHES", omega_sci_qc.nmatches);
1268 cpl_propertylist_set_comment(ps.qclist,
"ESO QC SCI MATCHES",
1269 "number matches between USNOA2 cat and stars");
1270 cpl_propertylist_update_double(ps.qclist,
"ESO QC SCI RATIO MATCHES", omega_sci_qc.mratio);
1271 cpl_propertylist_set_comment(ps.qclist,
"ESO QC SCI RATIO MATCHES",
1272 "ratio USNOA2 matches/detected stars");
1276 ps.proname = cpl_sprintf(
"%s_%s.fits", INSTRUME,STACK_PROCATG);
1277 ps.confname = cpl_sprintf(
"%s_%s.fits", INSTRUME,CONF_PROCATG);
1282 cpl_msg_info(cpl_func,
"Saving stack and confidence map");
1284 if(!cpl_propertylist_has(ps.plist,
"EXTNAME")){
1285 cpl_propertylist_copy_property(ps.plist,alist,
"EXTNAME");
1287 if(
omega_save_image(ps.combined[0],
set,pars,ps.plist,ps.qclist,CPL_BPP_IEEE_FLOAT,
1288 ps.proname,RECIPE,product_frame,NULL,isfirst) == -1){
1289 cpl_msg_error(cpl_func,
"Cannot save product. %s", cpl_error_get_message());
1290 freebivector(offsets);
1291 freeframeset(proset);
1292 freeframeset(proset_mask);
1294 omega_science_tidy(0);
1299 ps.confname,RECIPE,conf_frame,NULL,isfirst) == -1){
1300 cpl_msg_error(cpl_func,
"Cannot save product. %s", cpl_error_get_message());
1301 freebivector(offsets);
1302 freeframeset(proset);
1303 freeframeset(proset_mask);
1305 omega_science_tidy(0);
1309 freeplist(ps.qclist);
1310 freeplist(ps.plist);
1311 if(ps.combined!=NULL) {
1312 freeimage(ps.combined[0]);
1313 freeimage(ps.combined[1]);
1314 freespace(ps.combined);
1319 if(ps.catalogue == NULL){
1320 cpl_msg_error(cpl_func,
"Unable to create catalogue of stack. %s", cpl_error_get_message());
1322 freebivector(offsets);
1323 freeframeset(proset);
1324 freeframeset(proset_mask);
1325 omega_science_tidy(0);
1330 cpl_msg_warning(cpl_func,
"Cannot find stars with CLASS_STAR near 1 to calculate seeing");
1334 qclist = cpl_propertylist_new();
1335 cpl_propertylist_update_double(qclist,
"ESO QC SCI SEEING", Seeing);
1336 cpl_propertylist_set_comment(qclist,
"ESO QC SCI SEEING",
"calculated seeing of science field");
1337 cpl_propertylist_update_double(qclist,
"ESO QC SCI ELLIPTICITY", ellipticity);
1338 cpl_propertylist_set_comment(qclist,
"ESO QC SCI ELLIPTICITY",
"calculated ellipticity of science field");
1343 ps.catname = cpl_sprintf(
"%s_%s.fits", INSTRUME,CAT_PROCATG);
1346 cpl_msg_info(cpl_func,
"Saving catalogue");
1348 catframe,NULL,isfirst) == -1){
1349 freebivector(offsets);
1350 freeframeset(proset);
1351 freeframeset(proset_mask);
1354 omega_science_tidy(0);
1358 freetable(ps.catalogue);
1359 freebivector(offsets);
1364 cpl_msg_info(cpl_func,
"Cleaning up");
1366 freeframeset(proset);
1367 freeframeset(proset_mask);
1370 omega_science_tidy(0);
1378 static int omega_science_retrieve_input_param(
const cpl_parameterlist * parlist)
1381 const cpl_parameter *par = NULL;
1382 cpl_errorstate prestate = cpl_errorstate_get();
1385 par = cpl_parameterlist_find_const(parlist,
"omega.omega_science.ExtensionNumber") ;
1386 omega_science_config.extnum = cpl_parameter_get_int(par) ;
1387 par = cpl_parameterlist_find_const(parlist,
"omega.omega_science.OverscanMethod") ;
1388 omega_science_config.oc = cpl_parameter_get_int(par) ;
1390 if(!cpl_errorstate_is_equal(prestate)){
1391 cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
1398 static int omega_science_load_calib(
int ext)
1403 ps.mbias = cpl_image_load(cpl_frame_get_filename(ps.mbiasfr), CPL_TYPE_FLOAT, 0, ext);
1404 if(ps.mbias == NULL){
1405 cpl_msg_error(cpl_func,
"Cannot load Master Bias. %s", cpl_error_get_message());
1409 ps.mflat = cpl_image_load(cpl_frame_get_filename(ps.mflatfr),CPL_TYPE_FLOAT,0,ext);
1410 if (ps.mflat == NULL){
1411 cpl_msg_error(cpl_func,
"Cannot load Master Flat. %s",cpl_error_get_message());
1416 ps.bpm = cpl_image_load(cpl_frame_get_filename(ps.bpmfr), CPL_TYPE_INT, 0, ext);
1418 cpl_msg_error(cpl_func,
"Cannot load BPM. %s", cpl_error_get_message());
1423 ps.photom = cpl_table_load(cpl_frame_get_filename(ps.photomfr),ext,0);
1424 if(ps.photom == NULL){
1425 cpl_msg_warning(cpl_func,
"Cannot load the zeropoint table. %s",cpl_error_get_message());
1426 cpl_msg_warning(cpl_func,
"Using values defined in the recipe parameter");
1435 if(ps.illumfr != NULL)
1436 ps.illum = cpl_image_load(cpl_frame_get_filename(ps.illumfr),CPL_TYPE_FLOAT,0,ext);
1445 static cpl_error_code omega_correct_crpix_union(cpl_propertylist *xlist,
1446 cpl_bivector *offsets){
1448 cpl_vector * offset_x=NULL;
1449 cpl_vector * offset_y=NULL;
1453 offset_x=cpl_bivector_get_x(offsets);
1454 offset_y=cpl_bivector_get_y(offsets);
1457 if (cpl_vector_get_max(offset_x)-cpl_vector_get_min(offset_x) > 3000 ||
1458 cpl_vector_get_max(offset_y)-cpl_vector_get_min(offset_y) > 6000){
1461 return cpl_error_get_code();
1465 if(cpl_propertylist_has(xlist,
"CRPIX1") &&
1466 cpl_propertylist_has(xlist,
"CRPIX2")){
1467 crpix1=cpl_propertylist_get_double(xlist,
"CRPIX1");
1468 crpix2=cpl_propertylist_get_double(xlist,
"CRPIX2");
1470 cpl_propertylist_update_double(xlist,
"CRPIX1",
1471 crpix1-cpl_vector_get_min(offset_x));
1473 cpl_propertylist_update_double(xlist,
"CRPIX2",
1474 crpix2-cpl_vector_get_min(offset_y));
1478 return cpl_error_get_code();
1484 static void omega_science_init(
void) {
1486 ps.fringesfr = NULL;
1498 ps.catalogue = NULL;
1518 static void omega_science_tidy(
int level) {
1519 freeimage(ps.mbias);
1520 freeimage(ps.mflat);
1522 freeimage(ps.illum);
1523 freetable(ps.photom);
1524 freefits(ps.scifits);
1525 freeframeset(ps.scilist);
1529 freeimage(ps.fringes);
1532 if(ps.combined!=NULL) {
1533 freeimage(ps.combined[0]);
1534 freeimage(ps.combined[1]);
1535 freespace(ps.combined);
1537 freetable(ps.catalogue);
1538 freeimage(ps.mflat);
1539 freespace(ps.labels);
1540 freespace(ps.proname);
1541 freespace(ps.confname);
1542 freespace(ps.catname);
1543 freeplist(ps.qclist);
1544 freeplist(ps.plist);