39 #include "irplib_utils.h"
41 #include "sofi_utils.h"
42 #include "sofi_pfits.h"
49 static int sofi_img_detlin_create(cpl_plugin *) ;
50 static int sofi_img_detlin_exec(cpl_plugin *) ;
51 static int sofi_img_detlin_destroy(cpl_plugin *) ;
52 static int sofi_img_detlin(cpl_parameterlist *, cpl_frameset *) ;
54 static cpl_imagelist * sofi_img_detlin_load(cpl_frameset *, cpl_frameset *,
56 static int sofi_img_detlin_save(cpl_imagelist *, cpl_parameterlist *,
68 double lamp_stability ;
69 } sofi_img_detlin_config ;
71 static char sofi_img_detlin_description[] =
72 "sofi_img_detlin -- SOFI imaging detector linearity recipe.\n"
73 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
74 "raw-file.fits "SOFI_IMG_DETLIN_LAMP_RAW
" or\n"
75 "raw-file.fits "SOFI_IMG_DETLIN_DARK_RAW
"\n";
90 int cpl_plugin_get_info(cpl_pluginlist * list)
92 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
93 cpl_plugin * plugin = &recipe->interface ;
95 cpl_plugin_init(plugin,
98 CPL_PLUGIN_TYPE_RECIPE,
100 "Detector linearity recipe",
101 sofi_img_detlin_description,
105 sofi_img_detlin_create,
106 sofi_img_detlin_exec,
107 sofi_img_detlin_destroy) ;
109 cpl_pluginlist_append(list, plugin) ;
124 static int sofi_img_detlin_create(cpl_plugin * plugin)
126 cpl_recipe * recipe ;
130 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
131 recipe = (cpl_recipe *)plugin ;
132 else return CPL_ERROR_UNSPECIFIED;
135 recipe->parameters = cpl_parameterlist_new() ;
139 p = cpl_parameter_new_value(
"sofi.sofi_img_detlin.force", CPL_TYPE_BOOL,
140 "flag to force th computation",
"sofi.sofi_img_detlin",
142 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"force") ;
143 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
144 cpl_parameterlist_append(recipe->parameters, p) ;
157 static int sofi_img_detlin_exec(cpl_plugin * plugin)
159 cpl_recipe * recipe ;
162 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
163 recipe = (cpl_recipe *)plugin ;
164 else return CPL_ERROR_UNSPECIFIED;
166 return sofi_img_detlin(recipe->parameters, recipe->frames) ;
176 static int sofi_img_detlin_destroy(cpl_plugin * plugin)
178 cpl_recipe * recipe ;
181 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
182 recipe = (cpl_recipe *)plugin ;
183 else return CPL_ERROR_UNSPECIFIED;
185 cpl_parameterlist_delete(recipe->parameters) ;
197 static int sofi_img_detlin(
198 cpl_parameterlist * parlist,
199 cpl_frameset * framelist)
201 cpl_parameter * par ;
202 cpl_frameset * darkframes ;
203 cpl_frameset * lampframes ;
204 cpl_imagelist * iset ;
205 cpl_vector * ditval ;
206 cpl_imagelist * fitres ;
207 cpl_image * error_im ;
216 par = cpl_parameterlist_find(parlist,
"sofi.sofi_img_detlin.force") ;
217 sofi_img_detlin_config.force_flag = cpl_parameter_get_bool(par) ;
221 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames") ;
222 return CPL_ERROR_UNSPECIFIED;
227 SOFI_IMG_DETLIN_LAMP_RAW)) == NULL) {
228 cpl_msg_error(cpl_func,
"Cannot find any lamp frame in input");
229 return CPL_ERROR_UNSPECIFIED;
232 SOFI_IMG_DETLIN_DARK_RAW)) == NULL) {
233 cpl_msg_error(cpl_func,
"Cannot find any dark frame in input");
234 cpl_frameset_delete(lampframes) ;
235 return CPL_ERROR_UNSPECIFIED;
239 cpl_msg_info(cpl_func,
"Load the data") ;
240 cpl_msg_indent_more() ;
241 if ((iset = sofi_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
242 cpl_msg_error(cpl_func,
"Cannot load the data") ;
243 cpl_frameset_delete(lampframes) ;
244 cpl_frameset_delete(darkframes) ;
245 cpl_msg_indent_less() ;
246 return CPL_ERROR_UNSPECIFIED;
248 cpl_frameset_delete(lampframes) ;
249 cpl_frameset_delete(darkframes) ;
250 cpl_msg_indent_less() ;
253 error_im = cpl_image_duplicate(cpl_imagelist_get(iset, 0)) ;
256 cpl_msg_info(cpl_func,
"Compute the linearity coefficients") ;
257 cpl_msg_indent_more() ;
258 if ((fitres = cpl_fit_imagelist_polynomial(ditval, iset, 0, degree,
259 CPL_FALSE, CPL_TYPE_FLOAT, error_im)) == NULL) {
260 cpl_msg_error(cpl_func,
"Cannot compute the linearity coefficients") ;
261 cpl_imagelist_delete(iset) ;
262 cpl_vector_delete(ditval) ;
263 cpl_image_delete(error_im) ;
264 cpl_msg_indent_less() ;
265 return CPL_ERROR_UNSPECIFIED;
267 cpl_msg_indent_less() ;
268 cpl_vector_delete(ditval) ;
269 cpl_imagelist_delete(iset) ;
272 cpl_imagelist_set(fitres, error_im, degree+1) ;
275 cpl_msg_info(cpl_func,
"Save the products") ;
276 cpl_msg_indent_more() ;
277 if (sofi_img_detlin_save(fitres, parlist, framelist)==-1) {
278 cpl_msg_error(cpl_func,
"Cannot save the products") ;
279 cpl_imagelist_delete(fitres) ;
280 cpl_msg_indent_less() ;
281 return CPL_ERROR_UNSPECIFIED;
283 cpl_msg_indent_less() ;
286 cpl_imagelist_delete(fitres) ;
299 static cpl_imagelist * sofi_img_detlin_load(
300 cpl_frameset * lamps,
301 cpl_frameset * darks,
302 cpl_vector ** ditvals)
305 cpl_vector * selection ;
307 cpl_propertylist * propertylist ;
308 double dit_lamp, dit_dark ;
310 cpl_imagelist * lamps_data ;
311 cpl_imagelist * darks_data ;
312 double * stab_levels ;
313 cpl_vector * dit_purged ;
315 double * pdit_purged ;
319 if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3)
return NULL ;
320 if (cpl_frameset_get_size(darks) != nb_lamps)
return NULL ;
323 cpl_msg_info(cpl_func,
"Checking DIT consistency") ;
324 selection = cpl_vector_new(nb_lamps) ;
325 *ditvals = cpl_vector_new(nb_lamps) ;
326 pditvals = cpl_vector_get_data(*ditvals) ;
328 for (i=0 ; i<nb_lamps ; i++) {
330 if (cpl_error_get_code()) {
331 cpl_vector_delete(selection) ;
332 cpl_vector_delete(*ditvals) ;
336 frame = cpl_frameset_get_position(lamps, i) ;
337 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
339 cpl_propertylist_delete(propertylist) ;
340 if (cpl_error_get_code()) {
341 cpl_msg_error(cpl_func,
"Cannot get DIT") ;
342 cpl_vector_delete(selection) ;
343 cpl_vector_delete(*ditvals) ;
347 frame = cpl_frameset_get_position(darks, i) ;
348 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
350 cpl_propertylist_delete(propertylist) ;
351 if (cpl_error_get_code()) {
352 cpl_msg_error(cpl_func,
"Cannot get DIT") ;
353 cpl_vector_delete(selection) ;
354 cpl_vector_delete(*ditvals) ;
358 if (fabs(dit_dark-dit_lamp) > 1e-3) {
359 cpl_msg_error(cpl_func,
"DIT not consistent between LAMP and DARK");
360 cpl_vector_delete(selection) ;
361 cpl_vector_delete(*ditvals) ;
364 pditvals[i] = dit_lamp ;
367 cpl_vector_set(selection, i, -1.0) ;
370 if (fabs(dit_lamp - pditvals[0]) < 1e-5) {
371 cpl_vector_set(selection, i, -1.0) ;
374 cpl_vector_set(selection, i, 1.0) ;
381 cpl_msg_error(cpl_func,
"Not enough frames for stability check") ;
382 cpl_vector_delete(selection) ;
383 cpl_vector_delete(*ditvals) ;
388 cpl_msg_info(cpl_func,
"Compute the differences lamp - dark") ;
389 lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0) ;
390 darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0) ;
391 if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
392 cpl_msg_error(cpl_func,
"Cannot subtract the 2 image lists") ;
393 cpl_vector_delete(selection) ;
394 cpl_vector_delete(*ditvals) ;
395 if (lamps_data) cpl_imagelist_delete(lamps_data) ;
396 if (darks_data) cpl_imagelist_delete(darks_data) ;
399 cpl_imagelist_delete(darks_data) ;
402 cpl_msg_info(cpl_func,
"Check the lamp stability") ;
403 stab_levels = cpl_malloc(dit_stab *
sizeof(
double)) ;
405 for (i=0 ; i<nb_lamps ; i++) {
406 if (cpl_vector_get(selection, i) < 0) {
408 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i)) ;
414 sofi_img_detlin_config.lamp_stability = 0.0 ;
415 for (i=1 ; i<dit_stab ; i++) {
416 if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
417 sofi_img_detlin_config.lamp_stability)
418 sofi_img_detlin_config.lamp_stability =
419 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0] ;
421 cpl_free(stab_levels) ;
424 if (sofi_img_detlin_config.lamp_stability > 0.01) {
425 if (sofi_img_detlin_config.force_flag == 1) {
426 cpl_msg_warning(cpl_func,
427 "level difference #%d too high - proceed anyway",i+1);
429 cpl_msg_error(cpl_func,
"level difference #%d too high", i+1);
430 cpl_vector_delete(selection) ;
431 cpl_vector_delete(*ditvals) ;
432 cpl_imagelist_delete(lamps_data) ;
438 if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
439 cpl_msg_error(cpl_func,
"cannot discard stability frames") ;
440 cpl_vector_delete(selection) ;
441 cpl_vector_delete(*ditvals) ;
442 cpl_imagelist_delete(lamps_data) ;
445 dit_purged = cpl_vector_new(cpl_imagelist_get_size(lamps_data)) ;
446 pdit_purged = cpl_vector_get_data(dit_purged) ;
448 for (i=0 ; i<nb_lamps ; i++) {
449 if (cpl_vector_get(selection, i) > 0) {
450 pdit_purged[j] = pditvals[i] ;
454 cpl_vector_delete(*ditvals) ;
455 *ditvals = dit_purged ;
458 cpl_vector_delete(selection) ;
471 static int sofi_img_detlin_save(
472 cpl_imagelist * fitres,
473 cpl_parameterlist * parlist,
476 const cpl_frame * ref_frame;
477 cpl_propertylist * plist ;
478 cpl_propertylist * qclist ;
479 cpl_propertylist * paflist ;
480 double qc_meda, qc_medb, qc_medc, qc_medq ;
483 qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0)) ;
484 qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1)) ;
485 qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2)) ;
486 qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3)) ;
489 qclist = cpl_propertylist_new() ;
490 cpl_propertylist_append_double(qclist,
"ESO QC DETLIN MEDA", qc_meda) ;
491 cpl_propertylist_append_double(qclist,
"ESO QC DETLIN MEDB", qc_medb) ;
492 cpl_propertylist_append_double(qclist,
"ESO QC DETLIN MEDC", qc_medc) ;
493 cpl_propertylist_append_double(qclist,
"ESO QC DETLIN MEDQ", qc_medq) ;
494 cpl_propertylist_append_double(qclist,
"ESO QC DETLIN LAMP",
495 sofi_img_detlin_config.lamp_stability ) ;
498 irplib_dfs_save_image(set,
501 cpl_imagelist_get(fitres, 0),
507 PACKAGE
"/" PACKAGE_VERSION,
508 "sofi_img_detlin_A.fits") ;
511 irplib_dfs_save_image(set,
514 cpl_imagelist_get(fitres, 1),
520 PACKAGE
"/" PACKAGE_VERSION,
521 "sofi_img_detlin_B.fits") ;
524 irplib_dfs_save_image(set,
527 cpl_imagelist_get(fitres, 2),
533 PACKAGE
"/" PACKAGE_VERSION,
534 "sofi_img_detlin_C.fits") ;
537 irplib_dfs_save_image(set,
540 cpl_imagelist_get(fitres, 3),
546 PACKAGE
"/" PACKAGE_VERSION,
547 "sofi_img_detlin_Q.fits") ;
550 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
553 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
555 cpl_msg_error(cpl_func,
"getting header from reference frame");
556 cpl_propertylist_delete(qclist) ;
557 return CPL_ERROR_UNSPECIFIED;
561 paflist = cpl_propertylist_new() ;
562 cpl_propertylist_copy_property_regexp(paflist, plist,
563 "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
564 "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0) ;
565 cpl_propertylist_delete(plist) ;
568 cpl_propertylist_copy_property_regexp(paflist, qclist,
".", 0) ;
569 cpl_propertylist_delete(qclist) ;
572 cpl_dfs_save_paf(
"SOFI",
575 "sofi_img_detlin_QC.paf") ;
576 cpl_propertylist_delete(paflist) ;