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 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 
00033 
00034 
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 
00039 #include "irplib_utils.h"
00040 
00041 #include "isaac_utils.h"
00042 #include "isaac_pfits.h"
00043 #include "isaac_dfs.h"
00044 #include "isaac_fit.h"
00045 
00046 
00047 
00048 
00049 
00050 static int isaac_img_detlin_create(cpl_plugin *);
00051 static int isaac_img_detlin_exec(cpl_plugin *);
00052 static int isaac_img_detlin_destroy(cpl_plugin *);
00053 static int isaac_img_detlin(cpl_parameterlist *, cpl_frameset *);
00054 
00055 static cpl_imagelist * isaac_img_detlin_load(cpl_frameset *, cpl_frameset *, 
00056         double **);
00057 static int isaac_img_detlin_save(cpl_imagelist *, cpl_parameterlist *, 
00058         cpl_frameset *);
00059 
00060 
00061 
00062 
00063 
00064 static struct {
00065     
00066     int     force_flag;
00067 
00068     
00069     double  lamp_stability;
00070 } isaac_img_detlin_config;
00071 
00072 static char isaac_img_detlin_description[] =
00073 "isaac_img_detlin -- ISAAC imaging detector linearity recipe.\n"
00074 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00075 "raw-file.fits "ISAAC_IMG_DETLIN_LAMP_RAW" or\n"
00076 "raw-file.fits "ISAAC_IMG_DETLIN_DARK_RAW"\n";
00077 
00078 
00079 
00080 
00081 
00082 
00090 
00091 int cpl_plugin_get_info(cpl_pluginlist * list)
00092 {
00093     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe));
00094     cpl_plugin  *   plugin = &recipe->interface;
00095 
00096     cpl_plugin_init(plugin,
00097                     CPL_PLUGIN_API,
00098                     ISAAC_BINARY_VERSION,
00099                     CPL_PLUGIN_TYPE_RECIPE,
00100                     "isaac_img_detlin",
00101                     "Detector linearity recipe",
00102                     isaac_img_detlin_description,
00103                     "Lars Lundin",
00104                     PACKAGE_BUGREPORT,
00105                     isaac_get_license(),
00106                     isaac_img_detlin_create,
00107                     isaac_img_detlin_exec,
00108                     isaac_img_detlin_destroy);
00109 
00110     cpl_pluginlist_append(list, plugin);
00111     
00112     return 0;
00113 }
00114 
00115 
00124 
00125 static int isaac_img_detlin_create(cpl_plugin * plugin)
00126 {
00127     cpl_recipe      * recipe;
00128     cpl_parameter   * p;
00129 
00130     
00131     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00132         recipe = (cpl_recipe *)plugin;
00133     else return -1;
00134 
00135     
00136     recipe->parameters = cpl_parameterlist_new(); 
00137 
00138     
00139     
00140     p = cpl_parameter_new_value("isaac.isaac_img_detlin.force", CPL_TYPE_BOOL,
00141             "flag to force th computation", "isaac.isaac_img_detlin",
00142             FALSE);
00143     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force");
00144     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00145     cpl_parameterlist_append(recipe->parameters, p);
00146 
00147     
00148     return 0;
00149 }
00150 
00151 
00157 
00158 static int isaac_img_detlin_exec(cpl_plugin * plugin)
00159 {
00160     cpl_recipe  *   recipe;
00161 
00162     
00163     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00164         recipe = (cpl_recipe *)plugin;
00165     else return -1;
00166 
00167     return isaac_img_detlin(recipe->parameters, recipe->frames);
00168 }
00169 
00170 
00176 
00177 static int isaac_img_detlin_destroy(cpl_plugin * plugin)
00178 {
00179     cpl_recipe  *   recipe;
00180 
00181     
00182     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00183         recipe = (cpl_recipe *)plugin;
00184     else return -1;
00185 
00186     cpl_parameterlist_delete(recipe->parameters);
00187     return 0;
00188 }
00189 
00190 
00197 
00198 static int isaac_img_detlin(
00199         cpl_parameterlist   *   parlist, 
00200         cpl_frameset        *   framelist)
00201 {
00202     cpl_parameter   *   par;
00203     cpl_frameset    *   darkframes;
00204     cpl_frameset    *   lampframes;
00205     cpl_imagelist   *   iset;
00206     double          *   ditval;
00207     cpl_imagelist   *   fitres;
00208 
00209     
00210     par = NULL;
00211 
00212     
00213     
00214     par = cpl_parameterlist_find(parlist, "isaac.isaac_img_detlin.force");
00215     isaac_img_detlin_config.force_flag = cpl_parameter_get_bool(par);
00216 
00217     
00218     if (isaac_dfs_set_groups(framelist)) {
00219         cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00220         return -1;
00221     }
00222 
00223     
00224     if ((lampframes = isaac_extract_frameset(framelist,
00225                     ISAAC_IMG_DETLIN_LAMP_RAW)) == NULL) {
00226         cpl_msg_error(cpl_func, "Cannot find any lamp frame in input");
00227         return -1;
00228     }
00229     if ((darkframes = isaac_extract_frameset(framelist,
00230                     ISAAC_IMG_DETLIN_DARK_RAW)) == NULL) {
00231         cpl_msg_error(cpl_func, "Cannot find any dark frame in input");
00232         cpl_frameset_delete(lampframes);
00233         return -1;
00234     }
00235 
00236     
00237     cpl_msg_info(cpl_func, "Load the data");
00238     cpl_msg_indent_more();
00239     if ((iset = isaac_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
00240         cpl_msg_error(cpl_func, "Cannot load the data");
00241         cpl_frameset_delete(lampframes);
00242         cpl_frameset_delete(darkframes);
00243         cpl_msg_indent_less();
00244         return -1;
00245     }
00246     cpl_frameset_delete(lampframes);
00247     cpl_frameset_delete(darkframes);
00248     cpl_msg_indent_less();
00249    
00250     
00251     cpl_msg_info(cpl_func, "Compute the linearity coefficients");
00252     cpl_msg_indent_more();
00253     if ((fitres = isaac_imagelist_fit_polynomial(iset, ditval, 3)) == NULL) {
00254         cpl_msg_error(cpl_func, "Cannot compute the linearity coefficients");
00255         cpl_imagelist_delete(iset);
00256         cpl_free(ditval);
00257         cpl_msg_indent_less();
00258         return -1;
00259     }
00260     cpl_msg_indent_less();
00261     cpl_free(ditval);
00262     cpl_imagelist_delete(iset);
00263 
00264     
00265     cpl_msg_info(cpl_func, "Save the products");
00266     cpl_msg_indent_more();
00267     if (isaac_img_detlin_save(fitres, parlist, framelist)==-1) {
00268         cpl_msg_error(cpl_func, "Cannot save the products");
00269         cpl_imagelist_delete(fitres);
00270         cpl_msg_indent_less();
00271         return -1;
00272     }
00273     cpl_msg_indent_less();
00274 
00275     
00276     cpl_imagelist_delete(fitres);
00277     return 0;
00278 }
00279 
00280 
00288 
00289 static cpl_imagelist * isaac_img_detlin_load(
00290         cpl_frameset    *   lamps,
00291         cpl_frameset    *   darks,
00292         double          **  ditvals)
00293 {
00294     int                     nb_lamps;
00295     cpl_vector          *   selection;
00296     cpl_frame           *   frame;
00297     cpl_propertylist    *   propertylist;
00298     double                  dit_lamp, dit_dark;
00299     int                     dit_stab;
00300     cpl_imagelist       *   lamps_data;
00301     cpl_imagelist       *   darks_data;
00302     double              *   stab_levels;
00303     double              *   dit_purged;
00304     int                     i, j;
00305 
00306     
00307     if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3) return NULL;
00308     if (cpl_frameset_get_size(darks) != nb_lamps) return NULL;
00309 
00310     
00311     cpl_msg_info(cpl_func, "Checking DIT consistency");
00312     selection = cpl_vector_new(nb_lamps);
00313     *ditvals = cpl_malloc(nb_lamps * sizeof(double));
00314     dit_stab = 0;
00315     for (i=0; i<nb_lamps; i++) {
00316         
00317         if (cpl_error_get_code()) {
00318             cpl_vector_delete(selection);
00319             cpl_free(*ditvals);
00320             return NULL;
00321         }
00322         
00323         frame = cpl_frameset_get_frame(lamps, i);
00324         propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00325         dit_lamp = (double)isaac_pfits_get_dit(propertylist);
00326         cpl_propertylist_delete(propertylist);
00327         if (cpl_error_get_code()) {
00328             cpl_msg_error(cpl_func, "Cannot get DIT");
00329             cpl_vector_delete(selection);
00330             cpl_free(*ditvals);
00331             return NULL;
00332         }
00333         
00334         frame = cpl_frameset_get_frame(darks, i);
00335         propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00336         dit_dark = (double)isaac_pfits_get_dit(propertylist);
00337         cpl_propertylist_delete(propertylist);
00338         if (cpl_error_get_code()) {
00339             cpl_msg_error(cpl_func, "Cannot get DIT");
00340             cpl_vector_delete(selection);
00341             cpl_free(*ditvals);
00342             return NULL;
00343         }
00344         
00345         if (fabs(dit_dark-dit_lamp) > 1e-3) {
00346             cpl_msg_error(cpl_func, "DIT not consistent between LAMP and DARK");
00347             cpl_vector_delete(selection);
00348             cpl_free(*ditvals);
00349             return NULL;
00350         }
00351         (*ditvals)[i] = dit_lamp;
00352         
00353         if (i==0) {
00354             cpl_vector_set(selection, i, -1.0);
00355             dit_stab ++;
00356         } else {
00357             if (fabs(dit_lamp - (*ditvals)[0]) < 1e-5) {
00358                 cpl_vector_set(selection, i, -1.0);
00359                 dit_stab ++;
00360             } else {
00361                 cpl_vector_set(selection, i, 1.0);
00362             }
00363         }
00364     }
00365     
00366     
00367     if (dit_stab < 2) {
00368         cpl_msg_error(cpl_func, "Not enough frames for stability check");
00369         cpl_vector_delete(selection);
00370         cpl_free(*ditvals);
00371         return NULL;
00372     }
00373 
00374     
00375     cpl_msg_info(cpl_func, "Compute the differences lamp - dark");
00376     lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0);
00377     darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0);
00378     if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
00379         cpl_msg_error(cpl_func, "Cannot subtract the 2 image lists");
00380         cpl_vector_delete(selection);
00381         cpl_free(*ditvals);
00382         if (lamps_data) cpl_imagelist_delete(lamps_data);
00383         if (darks_data) cpl_imagelist_delete(darks_data);
00384         return NULL;
00385     }
00386     cpl_imagelist_delete(darks_data);
00387     
00388     
00389     cpl_msg_info(cpl_func, "Check the lamp stability");
00390     stab_levels = cpl_malloc(dit_stab * sizeof(double));
00391     j = 0;
00392     for (i=0; i<nb_lamps; i++) {
00393         if (cpl_vector_get(selection, i) < 0) {
00394             stab_levels[j] = 
00395                 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i));
00396             j++;
00397         }
00398     }
00399 
00400     
00401     isaac_img_detlin_config.lamp_stability = 0.0;
00402     for (i=1; i<dit_stab; i++) {
00403         if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
00404                 isaac_img_detlin_config.lamp_stability) 
00405             isaac_img_detlin_config.lamp_stability = 
00406                 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0];
00407     }
00408     cpl_free(stab_levels);
00409     
00410     
00411     if (isaac_img_detlin_config.lamp_stability > 0.01) {
00412         if (isaac_img_detlin_config.force_flag == 1) {
00413             cpl_msg_warning(cpl_func, 
00414                     "level difference #%d too high - proceed anyway",i+1);
00415         } else {
00416             cpl_msg_error(cpl_func, "level difference #%d too high", i+1);
00417             cpl_vector_delete(selection);
00418             cpl_free(*ditvals);
00419             cpl_imagelist_delete(lamps_data);
00420             return NULL;
00421         }
00422     }
00423 
00424     
00425     if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
00426         cpl_msg_error(cpl_func, "cannot discard stability frames");
00427         cpl_vector_delete(selection);
00428         cpl_free(*ditvals);
00429         cpl_imagelist_delete(lamps_data);
00430         return NULL;
00431     }
00432     dit_purged = cpl_malloc(cpl_imagelist_get_size(lamps_data)*sizeof(double));
00433     j = 0;
00434     for (i=0; i<nb_lamps; i++) {
00435         if (cpl_vector_get(selection, i) > 0) {
00436             dit_purged[j] = (*ditvals)[i];
00437             j++;
00438         }
00439     }
00440     cpl_free(*ditvals);
00441     *ditvals = dit_purged;
00442     
00443     
00444     cpl_vector_delete(selection);
00445     return lamps_data;
00446 }
00447 
00448 
00456 
00457 static int isaac_img_detlin_save(
00458         cpl_imagelist       *   fitres,
00459         cpl_parameterlist   *   parlist,
00460         cpl_frameset        *   set)
00461 {
00462     const cpl_frame           *   ref_frame;
00463     cpl_propertylist    *   plist;
00464     cpl_propertylist    *   qclist;
00465     cpl_propertylist    *   paflist;
00466     double                  qc_meda, qc_medb, qc_medc, qc_medq;
00467 
00468     
00469     qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0));
00470     qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1));
00471     qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2));
00472     qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3));
00473    
00474     
00475     qclist = cpl_propertylist_new();
00476     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDA", qc_meda);
00477     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDB", qc_medb);
00478     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDC", qc_medc);
00479     cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDQ", qc_medq);
00480     cpl_propertylist_append_double(qclist, "ESO QC DETLIN LAMP", 
00481             isaac_img_detlin_config.lamp_stability );
00482 
00483     
00484     irplib_dfs_save_image(set,
00485             parlist,
00486             set,
00487             cpl_imagelist_get(fitres, 0),
00488             CPL_BPP_IEEE_FLOAT,
00489             "isaac_img_detlin",
00490             ISAAC_IMG_DETLIN_A,
00491             qclist,
00492             NULL,
00493             PACKAGE "/" PACKAGE_VERSION,
00494             "isaac_img_detlin_A.fits");
00495 
00496     
00497     irplib_dfs_save_image(set,
00498             parlist,
00499             set,
00500             cpl_imagelist_get(fitres, 1),
00501             CPL_BPP_IEEE_FLOAT,
00502             "isaac_img_detlin",
00503             ISAAC_IMG_DETLIN_B,
00504             qclist,
00505             NULL,
00506             PACKAGE "/" PACKAGE_VERSION,
00507             "isaac_img_detlin_B.fits");
00508 
00509     
00510     irplib_dfs_save_image(set,
00511             parlist,
00512             set,
00513             cpl_imagelist_get(fitres, 2),
00514             CPL_BPP_IEEE_FLOAT,
00515             "isaac_img_detlin",
00516             ISAAC_IMG_DETLIN_C,
00517             qclist,
00518             NULL,
00519             PACKAGE "/" PACKAGE_VERSION,
00520             "isaac_img_detlin_C.fits");
00521 
00522     
00523     irplib_dfs_save_image(set,
00524             parlist,
00525             set,
00526             cpl_imagelist_get(fitres, 3),
00527             CPL_BPP_IEEE_FLOAT,
00528             "isaac_img_detlin",
00529             ISAAC_IMG_DETLIN_Q,
00530             qclist,
00531             NULL,
00532             PACKAGE "/" PACKAGE_VERSION,
00533             "isaac_img_detlin_Q.fits");
00534 
00535     
00536     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00537 
00538     
00539     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00540                     0)) == NULL) {
00541         cpl_msg_error(cpl_func, "getting header from reference frame");
00542         cpl_propertylist_delete(qclist);
00543         return -1;
00544     }
00545 
00546     
00547     paflist = cpl_propertylist_new();
00548     cpl_propertylist_copy_property_regexp(paflist, plist,
00549         "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
00550         "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0);
00551     cpl_propertylist_delete(plist);
00552 
00553     
00554     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00555     cpl_propertylist_delete(qclist);
00556 
00557     
00558     cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
00559                                    ISAAC_IMG_DETLIN_A);
00560 
00561     
00562     cpl_dfs_save_paf("ISAAC",
00563             "isaac_img_detlin",
00564             paflist,
00565             "isaac_img_detlin_QC.paf");
00566     cpl_propertylist_delete(paflist);
00567     return  0;
00568 }
00569