34#include "kmo_priv_stats.h"
35#include "kmo_priv_functions.h"
38#include "kmo_constants.h"
44static int kmo_stats_create(cpl_plugin *);
45static int kmo_stats_exec(cpl_plugin *);
46static int kmo_stats_destroy(cpl_plugin *);
47static int kmo_stats(cpl_parameterlist *, cpl_frameset *);
53static char kmo_stats_description[] =
54"This recipe performs basic statistics on KMOS-conform data-frames of type F2D,\n"
55"F1I, F2I and F3I either with or without noise and RAW. Optionally a 2D mask\n"
56"can be provided to define a region on which the statistics should be calculated\n"
57"on (mask 0: exclude pixel, mask 1: include pixel). A mask can’t be provided for\n"
58"statistics on F1I frames.\n"
59"The output is stored in a vector of length 11. The vector represents following\n"
61" 1. Number of pixels\n"
62" 2. Number of finite pixels\n"
64" 4. Standard Deviation\n"
65" 5. Mean with iterative rejection (i.e. mean & sigma are calculated iterati-\n"
66" vely, each time rejecting pixels more than +/-N sigma from the mean)\n"
67" 6. Standard Deviation with iterative rejection\n"
69" 8. Mode (i.e. the peak in a histogram of pixel values)\n"
70" 9. Noise (a robust estimate given by the standard deviation from the nega-\n"
71" tive side of the histogram of pixel values)\n"
75"The same numerical operations are applied to the noise as with the data itself.\n"
80"These parameters specify with extensions to process. The value 0, which is\n"
81"default, calulates all extensions.\n"
83"ADVANCED PARAMETERS\n"
84"-------------------\n"
88"An iterative sigma clipping is applied in order to calculate the mode (using\n"
89"kmo_stats). For each position all pixels in the spectrum are examined. If they\n"
90"deviate significantly, they will be rejected according to the conditions:\n"
91" val > mean + stdev * cpos_rej\n"
93" val < mean - stdev * cneg_rej\n"
94"In the first iteration median and percentile level are used.\n"
96"-------------------------------------------------------------------------------\n"
101" category group Type Explanation Required #Frames\n"
102" -------- ----- ----- ----------- -------- -------\n"
103" <none or any> - F3I or The datacubes Y 1 \n"
109" <none or any> - F2I or The mask N 0,1 \n"
117" category Type Explanation\n"
118" -------- ----- -----------\n"
119" STATS F1I Calculated statistics parameters \n"
120"-------------------------------------------------------------------------------\n"
145 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
146 cpl_plugin *plugin = &recipe->interface;
148 cpl_plugin_init(plugin,
151 CPL_PLUGIN_TYPE_RECIPE,
153 "Perform basic statistics on a KMOS-conform fits-file",
154 kmo_stats_description,
156 "https://support.eso.org/",
162 cpl_pluginlist_append(list, plugin);
174static int kmo_stats_create(cpl_plugin *plugin)
180 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
181 recipe = (cpl_recipe *)plugin;
186 recipe->parameters = cpl_parameterlist_new();
189 p = cpl_parameter_new_value(
"kmos.kmo_stats.ext",
191 "The extension the stats should be calculated "
192 "of. Zero is default and calculates the stats "
196 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext");
197 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
198 cpl_parameterlist_append(recipe->parameters, p);
201 return kmos_combine_pars_create(recipe->parameters,
212static int kmo_stats_exec(cpl_plugin *plugin)
217 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
218 recipe = (cpl_recipe *)plugin;
221 return kmo_stats(recipe->parameters, recipe->frames);
229static int kmo_stats_destroy(cpl_plugin *plugin)
234 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
235 recipe = (cpl_recipe *)plugin;
238 cpl_parameterlist_delete(recipe->parameters);
256static int kmo_stats(cpl_parameterlist *parlist, cpl_frameset *frameset)
258 double cpos_rej = 0.0,
261 cpl_imagelist *data_in = NULL;
263 cpl_image *mask = NULL,
266 kmclipm_vector *vec_in = NULL,
277 mask_available = FALSE,
285 cpl_propertylist *sub_header = NULL;
287 main_fits_desc desc1,
290 cpl_frame *data_frame = NULL,
296 const char *cmethod =
"ksigma";
298 char *tmp_str = NULL,
303 kmo_init_fits_desc(&desc1);
306 KMO_TRY_ASSURE((parlist != NULL) &&
308 CPL_ERROR_NULL_INPUT,
309 "Not all input data is provided!");
311 KMO_TRY_ASSURE((cpl_frameset_get_size(frameset) == 1) ||
312 ((cpl_frameset_get_size(frameset) == 2)),
313 CPL_ERROR_NULL_INPUT,
314 "Either a cube (F3I) or a cube and a mask (F2I) "
315 "must be provided!");
317 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
318 CPL_ERROR_ILLEGAL_INPUT,
319 "Cannot identify RAW and CALIB frames!");
321 if (cpl_frameset_get_size(frameset) == 1) {
322 strcpy(do_mode1,
"0");
323 strcpy(do_mode2,
"");
325 strcpy(do_mode1,
"0");
326 strcpy(do_mode2,
"1");
327 KMO_TRY_EXIT_IF_NULL(
328 mask_frame = kmo_dfs_get_frame(frameset, do_mode2));
330 KMO_TRY_EXIT_IF_NULL(
331 data_frame = kmo_dfs_get_frame(frameset, do_mode1));
333 cpl_msg_info(
"",
"--- Parameter setup for kmo_stats ---------");
336 desc1 = kmo_identify_fits_header(
337 cpl_frame_get_filename(data_frame));
338 KMO_TRY_CHECK_ERROR_STATE_MSG(
"Provided fits file doesn't seem to be "
341 KMO_TRY_ASSURE((desc1.fits_type == f3i_fits) ||
342 (desc1.fits_type == f1i_fits) ||
343 (desc1.fits_type == f2i_fits) ||
344 (desc1.fits_type == f2d_fits) ||
345 (desc1.fits_type == b2d_fits) ||
346 (desc1.fits_type == raw_fits),
347 CPL_ERROR_ILLEGAL_INPUT,
348 "First input file hasn't correct data type "
349 "(KMOSTYPE must be F1I, F2I, F3I, F2D, B2D or RAW)!");
351 ifu = kmo_dfs_get_parameter_int(parlist,
352 "kmos.kmo_stats.ext");
353 KMO_TRY_EXIT_IF_ERROR(
354 kmo_dfs_print_parameter_help(parlist,
"kmos.kmo_stats.ext"));
356 KMO_TRY_ASSURE((desc1.nr_ext >= ifu) ||
358 CPL_ERROR_ILLEGAL_INPUT,
359 "ext must be smaller or equal to the number of "
362 KMO_TRY_EXIT_IF_ERROR(
363 kmos_combine_pars_load(parlist,
374 cpl_msg_info(
"",
"-------------------------------------------");
377 if (cpl_frameset_get_size(frameset) == 2) {
378 kmo_init_fits_desc(&desc2);
381 desc2 = kmo_identify_fits_header(
382 cpl_frame_get_filename(mask_frame));
383 KMO_TRY_CHECK_ERROR_STATE_MSG(
"Provided fits file doesn't seem "
384 "to be in KMOS-format!");
386 mask_available = TRUE;
387 if ((desc1.fits_type == f3i_fits) ||
388 (desc1.fits_type == f2i_fits))
390 KMO_TRY_ASSURE(desc2.fits_type == f2i_fits,
391 CPL_ERROR_ILLEGAL_INPUT,
392 "Mask hasn't correct data type "
393 "(KMOSTYPE must be F2I)!");
394 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
395 (desc1.naxis2 == desc2.naxis2),
396 CPL_ERROR_ILLEGAL_INPUT,
397 "STAT_DATA and STAT_MASK don't have the same "
399 }
else if ((desc1.fits_type == f2d_fits) ||
400 (desc1.fits_type == b2d_fits) ||
401 (desc1.fits_type == raw_fits))
403 KMO_TRY_ASSURE((desc2.fits_type == f2d_fits) ||
404 (desc2.fits_type == b2d_fits),
405 CPL_ERROR_ILLEGAL_INPUT,
406 "Mask file hasn't correct data type "
407 "(KMOSTYPE must be F2D or B2D)!");
408 KMO_TRY_ASSURE((desc1.naxis1 == desc2.naxis1) &&
409 (desc1.naxis2 == desc2.naxis2),
410 CPL_ERROR_ILLEGAL_INPUT,
411 "STAT_DATA and STAT_MASK don't have the same "
413 }
else if (desc1.fits_type == f1i_fits)
416 CPL_ERROR_ILLEGAL_INPUT,
417 "Mask can't be provided for F1I frames!");
419 mask_available = FALSE;
422 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) ||
423 (desc1.nr_ext/2 == desc2.nr_ext) ||
424 ((desc2.nr_ext == 1) && (ifu > 0) &&
425 (ifu <= desc1.nr_ext)),
426 CPL_ERROR_ILLEGAL_INPUT,
427 "Mask hasn't same number of extensions as data!");
430 if (desc1.ex_noise == TRUE) {
431 nr_devices = desc1.nr_ext / 2;
433 nr_devices = desc1.nr_ext;
437 if (((desc1.ex_noise == FALSE) &&
438 (desc1.sub_desc[ifu-1].valid_data == FALSE)) ||
439 ((desc1.ex_noise == TRUE) &&
440 (desc1.sub_desc[2 * (ifu-1) - 1].valid_data == FALSE)))
442 cpl_msg_info(cpl_func,
"No valid IFU or detector has been "
444 kmo_free_fits_desc(&desc1);
445 kmo_free_fits_desc(&desc2);
451 KMO_TRY_EXIT_IF_ERROR(
452 kmo_dfs_save_main_header(frameset, STATS,
"", data_frame,
453 NULL, parlist, cpl_func));
457 for (i = 1; i <= nr_devices; i++) {
458 if (desc1.ex_noise == FALSE) {
459 devnr = desc1.sub_desc[i - 1].device_nr;
461 devnr = desc1.sub_desc[2 * i - 1].device_nr;
464 if (desc1.ex_badpix == FALSE) {
465 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
467 index_data = kmo_identify_index_desc(desc1, devnr, 2);
469 KMO_TRY_CHECK_ERROR_STATE();
471 if (desc1.ex_noise) {
472 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
474 KMO_TRY_CHECK_ERROR_STATE();
477 kmclipm_omit_warning_one_slice = TRUE;
479 if ((ifu == 0) || (ifu == i)) {
482 if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
493 if (mask_available == TRUE) {
495 if (desc2.nr_ext == 1) {
498 if (desc2.naxis == 1) {
499 KMO_TRY_EXIT_IF_NULL(
500 mask_vec = kmo_dfs_load_vector(frameset,
504 }
else if (desc2.naxis == 2) {
505 if (desc2.fits_type == b2d_fits) {
506 KMO_TRY_EXIT_IF_NULL(
507 mask = kmo_dfs_load_image(frameset,
512 KMO_TRY_EXIT_IF_NULL(
513 mask = kmo_dfs_load_image(frameset,
516 FALSE, FALSE, NULL));
519 KMO_TRY_ASSURE(1 == 0,
520 CPL_ERROR_ILLEGAL_INPUT,
521 "STAT_MASK must either be a "
522 "vector or an image!");
527 if (desc1.fits_type == f3i_fits) {
528 KMO_TRY_EXIT_IF_NULL(
529 data_in = kmo_dfs_load_cube(frameset, do_mode1,
531 KMO_TRY_EXIT_IF_NULL(
532 data_out = kmo_calc_stats_cube(data_in,
537 cpl_imagelist_delete(data_in); data_in = NULL;
538 }
else if (desc1.fits_type == f1i_fits) {
539 KMO_TRY_EXIT_IF_NULL(
540 vec_in = kmo_dfs_load_vector(frameset, do_mode1,
542 KMO_TRY_EXIT_IF_NULL(
543 data_out = kmo_calc_stats_vec(vec_in,
548 kmclipm_vector_delete(vec_in); vec_in = NULL;
549 }
else if ((desc1.fits_type == f2i_fits) ||
550 (desc1.fits_type == f2d_fits) ||
551 (desc1.fits_type == b2d_fits) ||
552 (desc1.fits_type == raw_fits))
554 int sat_mode = FALSE;
555 if (desc1.fits_type == raw_fits) {
559 if (desc1.fits_type == b2d_fits) {
560 KMO_TRY_EXIT_IF_NULL(
561 img_in = kmo_dfs_load_image(frameset, do_mode1,
562 devnr, 2, sat_mode, NULL));
564 KMO_TRY_EXIT_IF_NULL(
565 img_in = kmo_dfs_load_image(frameset, do_mode1,
567 FALSE, sat_mode, NULL));
569 KMO_TRY_EXIT_IF_NULL(
570 data_out = kmo_calc_stats_img(img_in,
575 cpl_image_delete(img_in); img_in = NULL;
578 CPL_ERROR_ILLEGAL_INPUT,
579 "Unsupported fits_type!");
582 stats_size = kmclipm_vector_get_size(data_out);
584 if ((desc1.fits_type == f3i_fits) ||
585 (desc1.fits_type == f2i_fits) ||
586 (desc1.fits_type == f2d_fits) ||
587 (desc1.fits_type == b2d_fits) ||
588 (desc1.fits_type == raw_fits))
590 if (mask_available == TRUE) {
591 cpl_image_delete(mask); mask = NULL;
596 if (desc1.fits_type == b2d_fits) {
597 KMO_TRY_EXIT_IF_NULL(
598 sub_header = kmo_dfs_load_sub_header(frameset, do_mode1, devnr,
601 KMO_TRY_EXIT_IF_NULL(
602 sub_header = kmo_dfs_load_sub_header(frameset, do_mode1, devnr,
606 if ((desc1.fits_type == raw_fits) ||
607 (desc1.fits_type == b2d_fits))
609 KMO_TRY_EXIT_IF_NULL(
610 tmp_str = cpl_sprintf(
"%s%d%s",
"DET.",
613 KMO_TRY_EXIT_IF_ERROR(
614 kmclipm_update_property_string(sub_header,
617 "FITS extension name"));
618 cpl_free(tmp_str); tmp_str = NULL;
621 KMO_TRY_EXIT_IF_ERROR(
622 kmo_dfs_save_vector(data_out, STATS,
"", sub_header, 0./0.));
624 cpl_propertylist_delete(sub_header); sub_header = NULL;
625 kmclipm_vector_delete(data_out); data_out = NULL;
630 if (desc1.ex_noise) {
631 if (desc1.sub_desc[index_noise-1].valid_data) {
632 if (desc1.fits_type == f3i_fits) {
633 KMO_TRY_EXIT_IF_NULL(
634 data_in = kmo_dfs_load_cube(frameset, do_mode1,
637 KMO_TRY_EXIT_IF_NULL(
638 data_out = kmo_calc_stats_cube(data_in,
643 cpl_imagelist_delete(data_in); data_in = NULL;
644 }
else if (desc1.fits_type == f1i_fits) {
645 KMO_TRY_EXIT_IF_NULL(
646 vec_in = kmo_dfs_load_vector(frameset, do_mode1,
648 KMO_TRY_EXIT_IF_NULL(
649 data_out = kmo_calc_stats_vec(vec_in,
654 kmclipm_vector_delete(vec_in); vec_in = NULL;
655 }
else if ((desc1.fits_type == f2i_fits) ||
656 (desc1.fits_type == f2d_fits) ||
657 (desc1.fits_type == raw_fits))
659 KMO_TRY_EXIT_IF_NULL(
660 img_in = kmo_dfs_load_image(frameset, do_mode1,
661 devnr, TRUE, FALSE, NULL));
663 KMO_TRY_EXIT_IF_NULL(
664 data_out = kmo_calc_stats_img(img_in,
669 cpl_image_delete(img_in); img_in = NULL;
672 if ((desc1.fits_type == f3i_fits) ||
673 (desc1.fits_type == f2i_fits) ||
674 (desc1.fits_type == f2d_fits) ||
675 (desc1.fits_type == raw_fits))
677 if (mask_available == TRUE) {
678 cpl_image_delete(mask); mask = NULL;
679 kmclipm_vector_delete(mask_vec); mask_vec = NULL;
684 KMO_TRY_EXIT_IF_NULL(
685 sub_header = kmo_dfs_load_sub_header(frameset,
689 if ((desc1.fits_type == raw_fits) ||
690 (desc1.fits_type == b2d_fits))
692 KMO_TRY_EXIT_IF_NULL(
693 tmp_str = cpl_sprintf(
"%s%d%s",
"DET.",
696 KMO_TRY_EXIT_IF_ERROR(
697 kmclipm_update_property_string(sub_header,
700 "FITS extension name"));
701 cpl_free(tmp_str); tmp_str = NULL;
704 KMO_TRY_EXIT_IF_ERROR(
705 kmo_dfs_save_vector(data_out, STATS,
"",
708 cpl_propertylist_delete(sub_header);sub_header = NULL;
709 kmclipm_vector_delete(data_out); data_out = NULL;
714 KMO_TRY_EXIT_IF_NULL(
715 sub_header = kmo_dfs_load_sub_header(frameset,
719 if ((desc1.fits_type == raw_fits) ||
720 (desc1.fits_type == b2d_fits))
722 KMO_TRY_EXIT_IF_NULL(
723 tmp_str = cpl_sprintf(
"%s%d%s",
"DET.",
726 KMO_TRY_EXIT_IF_ERROR(
727 kmclipm_update_property_string(sub_header,
730 "FITS extension name"));
731 cpl_free(tmp_str); tmp_str = NULL;
734 KMO_TRY_EXIT_IF_ERROR(
735 kmo_dfs_save_sub_header(STATS,
"", sub_header));
736 cpl_propertylist_delete(sub_header); sub_header = NULL;
738 if (desc1.ex_noise) {
739 cpl_propertylist_delete(sub_header); sub_header = NULL;
741 KMO_TRY_EXIT_IF_NULL(
742 sub_header = kmo_dfs_load_sub_header(frameset,
746 if ((desc1.fits_type == raw_fits) ||
747 (desc1.fits_type == b2d_fits))
749 KMO_TRY_EXIT_IF_NULL(
750 tmp_str = cpl_sprintf(
"%s%d%s",
"DET.",
753 KMO_TRY_EXIT_IF_ERROR(
754 kmclipm_update_property_string(sub_header,
757 "FITS extension name"));
758 cpl_free(tmp_str); tmp_str = NULL;
761 KMO_TRY_EXIT_IF_ERROR(
762 kmo_dfs_save_sub_header(STATS,
"", sub_header));
763 cpl_propertylist_delete(sub_header); sub_header = NULL;
770 kmo_free_fits_desc(&desc1);
771 kmo_init_fits_desc(&desc1);
773 KMO_TRY_EXIT_IF_NULL(
774 data_frame = kmo_dfs_get_frame(frameset, STATS));
776 desc1 = kmo_identify_fits_header(
777 cpl_frame_get_filename(data_frame));
779 KMO_TRY_CHECK_ERROR_STATE_MSG(
"Provided fits file doesn't seem to be "
782 cpl_msg_info(
"",
"-------------------------------------------");
783 cpl_msg_info(
"",
"--- kmo_stats info ---");
784 cpl_msg_info(
"",
"-------------------------------------------");
786 KMO_TRY_EXIT_IF_NULL(
787 strarr = (
char**)cpl_malloc((stats_size+1) *
sizeof(
char*)));
789 for (i = 0; i < stats_size+1; i++) {
790 KMO_TRY_EXIT_IF_NULL(
791 strarr[i] = (
char*)cpl_malloc(1024 *
sizeof(
char)));
793 case 0: strcpy(strarr[i],
" |");
break;
794 case 1: strcpy(strarr[i],
"1. #pixels: | ");
break;
795 case 2: strcpy(strarr[i],
"2. #finite pix.: | ");
break;
796 case 3: strcpy(strarr[i],
"3. mean: | ");
break;
797 case 4: strcpy(strarr[i],
"4. stdev: | ");
break;
798 case 5: strcpy(strarr[i],
"5. mean w. rej.: | ");
break;
799 case 6: strcpy(strarr[i],
"6. stdev w. rej.:| ");
break;
800 case 7: strcpy(strarr[i],
"7. median: | ");
break;
801 case 8: strcpy(strarr[i],
"8. mode: | ");
break;
802 case 9: strcpy(strarr[i],
"9. noise est.: | ");
break;
803 case 10: strcpy(strarr[i],
"10. min. value: | ");
break;
804 case 11: strcpy(strarr[i],
"11. max. value: | ");
break;
805 default: cpl_msg_error(cpl_func,
"To much values in output "
806 "statistic vector!");
break;
810 if (desc1.ex_noise == TRUE) {
811 nr_devices = desc1.nr_ext / 2;
813 nr_devices = desc1.nr_ext;
816 for (j = 1; j <= nr_devices; j++) {
817 if (desc1.ex_noise == FALSE) {
818 devnr = desc1.sub_desc[j - 1].device_nr;
820 devnr = desc1.sub_desc[2 * j - 1].device_nr;
823 if (desc1.ex_badpix == FALSE) {
824 index_data = kmo_identify_index_desc(desc1, devnr, FALSE);
826 index_data = kmo_identify_index_desc(desc1, devnr, 2);
828 KMO_TRY_CHECK_ERROR_STATE();
830 if (desc1.ex_noise) {
831 index_noise = kmo_identify_index_desc(desc1, devnr, TRUE);
833 KMO_TRY_CHECK_ERROR_STATE();
837 if (desc1.sub_desc[index_data-1].valid_data == TRUE) {
848 KMO_TRY_EXIT_IF_NULL(
849 sub_header = kmo_dfs_load_sub_header(frameset, STATS, extnr,
853 cpl_propertylist_get_string(sub_header, EXTNAME));
854 strcat(strarr[0],
"|");
855 cpl_propertylist_delete(sub_header); sub_header = NULL;
857 KMO_TRY_EXIT_IF_NULL(
858 data_out = kmo_dfs_load_vector(frameset, STATS, extnr, FALSE));
860 for (i = 1; i < stats_size+1; i++) {
863 val = kmclipm_vector_get(data_out, i-1, &rejected);
865 KMO_TRY_EXIT_IF_NULL(
866 tmp_str = cpl_sprintf(
"%8.7g |", val));
868 KMO_TRY_EXIT_IF_NULL(
869 tmp_str = cpl_sprintf(
" - |"));
872 strcat(strarr[i], tmp_str);
873 cpl_free(tmp_str); tmp_str = NULL;
875 kmclipm_vector_delete(data_out); data_out = NULL;
877 if (desc1.ex_noise == TRUE) {
878 KMO_TRY_EXIT_IF_NULL(
879 sub_header = kmo_dfs_load_sub_header(frameset, STATS,
882 cpl_propertylist_get_string(sub_header, EXTNAME));
883 strcat(strarr[0],
"|");
884 cpl_propertylist_delete(sub_header); sub_header = NULL;
886 KMO_TRY_EXIT_IF_NULL(
887 data_out = kmo_dfs_load_vector(frameset, STATS, extnr,
890 for (i = 1; i < stats_size+1; i++) {
893 val = kmclipm_vector_get(data_out, i-1, &rejected);
895 KMO_TRY_EXIT_IF_NULL(
896 tmp_str = cpl_sprintf(
"%9.7g | ", val));
898 KMO_TRY_EXIT_IF_NULL(
899 tmp_str = cpl_sprintf(
" - |"));
902 strcat(strarr[i], tmp_str);
903 cpl_free(tmp_str); tmp_str = NULL;
905 kmclipm_vector_delete(data_out); data_out = NULL;
910 for (i = 0; i < stats_size+1; i++) {
911 cpl_msg_info(
"",
"%s", strarr[i]);
912 cpl_free(strarr[i]); strarr[i] = NULL;
914 cpl_free(strarr); strarr = NULL;
915 cpl_msg_info(
"",
"-------------------------------------------");
924 kmo_free_fits_desc(&desc1);
925 if (mask_available == TRUE) {
926 kmo_free_fits_desc(&desc2);
928 cpl_propertylist_delete(sub_header); sub_header = NULL;
929 cpl_imagelist_delete(data_in); data_in = NULL;
930 kmclipm_vector_delete(data_out); data_out = NULL;
931 cpl_image_delete(mask); mask = NULL;
932 kmclipm_vector_delete(mask_vec); mask_vec = NULL;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.