VISIR Pipeline Reference Manual  4.1.7
visir_img_chain.c
1 /*
2  * This file is part of the VISIR Pipeline
3  * Copyright (C) 2012,2013,2014,2015 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 
25 /*-----------------------------------------------------------------------------
26  Includes
27  -----------------------------------------------------------------------------*/
28 
29 #ifndef _XOPEN_SOURCE
30 #define _XOPEN_SOURCE 600 /* setenv */
31 #endif
32 
33 #include "visir_recipe.h"
34 
35 #include "visir_utils.h"
36 #include "irplib_utils.h"
37 #include <cxlist.h>
38 #include <string.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 /* for strcasecmp */
42 #include <strings.h>
43 
44 int visir_util_repack_get_info(cpl_pluginlist *);
45 int visir_util_detect_shift_get_info(cpl_pluginlist *);
46 int visir_util_clip_get_info(cpl_pluginlist *);
47 int visir_util_run_swarp_get_info(cpl_pluginlist *);
48 int visir_util_qc_get_info(cpl_pluginlist *);
49 int visir_old_img_phot_get_info(cpl_pluginlist *);
50 int visir_util_join_get_info(cpl_pluginlist *);
51 static cpl_error_code visir_img_reduce_fill_parameterlist(cpl_parameterlist *);
52 static int visir_img_reduce(cpl_frameset *,
53  const cpl_parameterlist *);
54 
55 
56 /*-----------------------------------------------------------------------------
57  Defines
58  -----------------------------------------------------------------------------*/
59 
60 #define RECIPE_STRING "visir_img_reduce"
61 #define DEFAULT_CONFIG VISIR_CONFIG_PATH "/visir_default.swarp"
62 
63 /*-----------------------------------------------------------------------------
64  Private Functions prototypes
65  -----------------------------------------------------------------------------*/
66 
67 /* FIXME: this code is littered with many unimportant memory leaks */
68 
69 static int visir_img_reduce_create(cpl_plugin * plugin)
70 {
71  cpl_recipe * recipe = (cpl_recipe *)plugin; /* Needed for the fill */
72  cpl_errorstate prestate = cpl_errorstate_get(); /* To check the fill */
73 
74  /* Propagate error, if any */
75  /* - Need two function calls to ensure plugin validity before the fill */
76  return cpl_recipedefine_create(plugin)
77  || cpl_recipedefine_create_is_ok(prestate,
78  visir_img_reduce_fill_parameterlist(recipe->parameters))
79  ? (int)cpl_error_set_where(cpl_func) : 0;
80 }
81 
82 
83 /*----------------------------------------------------------------------------*/
96 /*----------------------------------------------------------------------------*/
97 static int visir_img_reduce_exec(cpl_plugin * plugin)
98 {
99  char * progname = getenv("_");
100  char * classpath = getenv("CLASSPATH");
101  cpl_msg_debug(cpl_func, "Program name: %s", progname);
102  cpl_msg_debug(cpl_func, "CLASSPATH: %s", classpath);
103  if ((progname && strstr(progname, "gasgano")) ||
104  (classpath && strstr(classpath, "gasgano.jar"))) {
105  cpl_msg_info(cpl_func, "Running under gasgano, disabling OpenMP");
106  setenv("OMP_NUM_THREADS", "0", 1);
107  return visir_tmpdir_exec(RECIPE_STRING, plugin, visir_img_reduce);
108  }
109  else if (getenv("VISIR_NO_FORK") != NULL) {
110  /* debugging and coverage is better without fork */
111  return cpl_recipedefine_exec(plugin, visir_img_reduce)
112  ? (int)cpl_error_set_where(cpl_func) : 0;
113  }
114  else
115  return visir_forking_exec(RECIPE_STRING, plugin, visir_img_reduce);
116 }
117 
118 
119 /* The definition of the recipe destroy function */
120 static int visir_img_reduce_destroy(cpl_plugin * plugin)
121 {
122  /* Propagate error, if any */
123  return cpl_recipedefine_destroy(plugin)
124  ? (int)cpl_error_set_where(cpl_func) : 0;
125 }
126 
127 int cpl_plugin_get_info(cpl_pluginlist * list)
128 {
129  /* Propagate error, if any. Return 1 on failure */
130  return cpl_recipedefine_init(list, CPL_VERSION_CODE,
131  VISIR_BINARY_VERSION,
132  "visir_img_reduce",
133  "Combines a stack of chopped, jittered and/or "
134  "nodded exposures and can compute the "
135  "sensitivity for standard star observations",
136  "This recipe recombines the data observed in "
137  "chopping/nodding or\n"
138  "chopping or nodding modes into one combined image using "
139  "optionally\n"
140  "cross-correlation methods.\n"
141  "The files listed in the Set Of Frames (sof-file) "
142  "must be tagged:\n"
143  "VISIR-observation-file.fits " VISIR_IMG_COMBINE_CNJ " or\n"
144  "VISIR-observation-file.fits " VISIR_IMG_COMBINE_CJ " or\n"
145  "VISIR-observation-file.fits " VISIR_IMG_COMBINE_NJ " or\n"
146  "VISIR-observation-file.fits " VISIR_IMG_COMBINE_DJ " or\n"
147  "VISIR-observation-file.fits BURST\n"
148  "VISIR-Standard-star-catalog " VISIR_CALIB_STDSTAR_IMG " (optional)\n"
149  "VISIR-linearty-table.fits "VISIR_CALIB_LIN" (optional)"
150  MAN_VISIR_CALIB_BPM_IMG,
151  "Julian Taylor",
152  "jtaylor@partner.eso.org",
153  cpl_get_license(PACKAGE_NAME, "2015"),
154  visir_img_reduce_create,
155  visir_img_reduce_exec,
156  visir_img_reduce_destroy)
157  ? ((void)cpl_error_set_where(cpl_func), 1) : 0;
158 }
159 
160 /* FIXME:
161 cpl_recipe_define(visir_img_reduce, VISIR_BINARY_VERSION,
162  "Julian Taylor", PACKAGE_BUGREPORT, "2012",
163  "Attempt to remove stripes in spectral data",
164  "The files listed in the Set Of Frames (sof-file) "
165  "must be tagged:\n"
166  "VISIR-chopnod-corrected-file.fits "
167  "\nThe product(s) will have a FITS card\n"
168  "'HIERARCH ESO PRO CATG' with a value of:\n");
169 */
170 
171 /*----------------------------------------------------------------------------*/
175 /*----------------------------------------------------------------------------*/
176 
177 /*-----------------------------------------------------------------------------
178  Functions code
179  -----------------------------------------------------------------------------*/
180 
181 /*----------------------------------------------------------------------------*/
189 /*----------------------------------------------------------------------------*/
190 static cpl_error_code
191 visir_img_reduce_fill_parameterlist(cpl_parameterlist * self)
192 {
193  cpl_pluginlist * plugins = cpl_pluginlist_new();
194  const char * context = PACKAGE ".visir_img_reduce";
195 
196  cpl_recipe * repack = visir_init_recipe("visir_util_repack",
197  &visir_util_repack_get_info,
198  plugins);
199  cpl_recipe * shift = visir_init_recipe("visir_util_detect_shift",
200  &visir_util_detect_shift_get_info,
201  plugins);
202  cpl_recipe * clip = visir_init_recipe("visir_util_clip",
203  &visir_util_clip_get_info,
204  plugins);
205  cpl_recipe * swarp = visir_init_recipe("visir_util_run_swarp",
206  &visir_util_run_swarp_get_info,
207  plugins);
208  cpl_recipe * phot = visir_init_recipe("visir_old_img_phot",
209  &visir_old_img_phot_get_info,
210  plugins);
211 
212  cpl_plugin_get_init(&repack->interface)(&repack->interface);
213  cpl_plugin_get_init(&shift->interface)(&shift->interface);
214  cpl_plugin_get_init(&clip->interface)(&clip->interface);
215  cpl_plugin_get_init(&swarp->interface)(&swarp->interface);
216  cpl_plugin_get_init(&phot->interface)(&phot->interface);
217  cpl_parameterlist * repack_par = repack->parameters;
218  cpl_parameterlist * clip_par = clip->parameters;
219  cpl_parameterlist * shift_par = shift->parameters;
220  cpl_parameterlist * swarp_par = swarp->parameters;
221  cpl_parameterlist * phot_par = phot->parameters;
222  skip_if(0);
223 
224  for (cpl_parameter * p = cpl_parameterlist_get_first(repack_par);
225  p != NULL; p = cpl_parameterlist_get_next(repack_par)) {
226  const char * name = cpl_parameter_get_name(p);
227  if (strstr(name, "bkgcorrect"))
228  continue;
229  if (strstr(name, "normalize"))
230  continue;
231  if (strstr(name, "compress"))
232  continue;
233  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
234  }
235 
236  skip_if(0);
237 
238  for (cpl_parameter * p = cpl_parameterlist_get_first(shift_par);
239  p != NULL; p = cpl_parameterlist_get_next(shift_par)) {
240  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
241  }
242 
243  skip_if(0);
244 
245  for (cpl_parameter * p = cpl_parameterlist_get_first(clip_par);
246  p != NULL; p = cpl_parameterlist_get_next(clip_par)) {
247  const char * name = cpl_parameter_get_name(p);
248  if (strstr(name, "error-out-type"))
249  continue;
250  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
251  }
252 
253  skip_if(0);
254 
255  for (cpl_parameter * p = cpl_parameterlist_get_first(swarp_par);
256  p != NULL; p = cpl_parameterlist_get_next(swarp_par)) {
257  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
258  }
259 
260  skip_if(0);
261 
262  for (cpl_parameter * p = cpl_parameterlist_get_first(phot_par);
263  p != NULL; p = cpl_parameterlist_get_next(phot_par)) {
264  const char * name = cpl_parameter_get_name(p);
265  if (strstr(name, "jy_val") || strstr(name, "radii"))
266  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
267  }
268 
269  skip_if(irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
270  "delete-temp", CPL_TRUE, NULL,
271  context, "Delete temporary files "
272  "created during processing"));
273  end_skip;
274 
275  cpl_parameterlist_delete(repack->parameters);
276  cpl_parameterlist_delete(shift->parameters);
277  cpl_parameterlist_delete(clip->parameters);
278  cpl_parameterlist_delete(swarp->parameters);
279  cpl_parameterlist_delete(phot->parameters);
280  cpl_plugin_delete(&repack->interface);
281  cpl_plugin_delete(&shift->interface);
282  cpl_plugin_delete(&clip->interface);
283  cpl_plugin_delete(&swarp->interface);
284  cpl_plugin_delete(&phot->interface);
285  cpl_pluginlist_delete(plugins);
286 
287  return cpl_error_get_code();
288 }
289 
290 static cpl_error_code
291 util_repack_set_parameters(cpl_parameterlist * rec_pars,
292  const cpl_parameterlist * chain_pars)
293 {
294  cpl_parameter * par;
295 
296  skip_if(visir_copy_parameters(rec_pars, chain_pars));
297 
298  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.bkgcorrect");
299 
300  if (par)
301  cpl_parameter_set_string(par, "chopnod");
302 
303  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.normalize");
304 
305  if (par)
306  cpl_parameter_set_bool(par, CPL_TRUE);
307 
308  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.compress");
309 
310  if (par)
311  cpl_parameter_set_bool(par, CPL_TRUE);
312 
313  end_skip;
314 
315  return cpl_error_get_code();
316 }
317 
318 
319 static cpl_error_code
320 check_swarp(void)
321 {
322  int ret = system(VISIR_SWARP_BIN " -v > /dev/null 2>/dev/null");
323  if (ret != 0) {
324  cpl_error_set_message(cpl_func, CPL_ERROR_UNSUPPORTED_MODE,
325  "swarp not found in PATH");
326  return CPL_ERROR_UNSUPPORTED_MODE;
327  }
328  return CPL_ERROR_NONE;
329 }
330 
331 
332 static cpl_frame *
333 run_phot(cpl_recipe * phot, cpl_frameset *photset,
334  const cpl_parameterlist * parlist,
335  cpl_frame * imgf_, cpl_frame * wgtf_,
336  cpl_frame * qcf_,
337  const int idx)
338 {
339  cpl_frame * imgf = cpl_frame_duplicate(imgf_);
340  cpl_frame * wgtf = cpl_frame_duplicate(wgtf_);
341  cpl_frame * qcf = cpl_frame_duplicate(qcf_);
342  cpl_frame * res = NULL;
343  char buffer[128];
344 
345  skip_if(0);
346 
347  cpl_frame_set_tag(imgf, "IM_CAL_PHOT_PREPROCESSED");
348  cpl_frameset_insert(photset, imgf);
349  cpl_frame_set_tag(wgtf, VISIR_UTIL_WEIGHT_MAP_PROCATG);
350  cpl_frameset_insert(photset, wgtf);
351  cpl_frame_set_group(qcf, CPL_FRAME_GROUP_RAW);
352  cpl_frame_set_tag(qcf, VISIR_UTIL_QC_PROCATG);
353  cpl_frameset_insert(photset, qcf);
354 
355  skip_if(visir_run_recipe(phot, photset, parlist, &visir_copy_parameters));
356  res = cpl_frameset_find(photset, VISIR_IMG_PHOT_COMBINED_PROCATG);
357  if (res == NULL)
358  res = cpl_frameset_find(photset, VISIR_IMG_PHOT_ONEBEAM_PROCATG);
359 
360  sprintf(buffer, "visir_img_phot_%03d.fits", idx);
361  skip_if(rename(cpl_frame_get_filename(res), buffer) == -1);
362  cpl_frame_set_filename(res, buffer);
363 
364  end_skip;
365 
366  return res;
367 }
368 
369 /*----------------------------------------------------------------------------*/
376 /*----------------------------------------------------------------------------*/
377 static int visir_img_reduce(cpl_frameset * framelist,
378  const cpl_parameterlist * parlist)
379 {
380  cpl_errorstate cleanstate = cpl_errorstate_get();
381  cpl_frameset * repackset = cpl_frameset_new();
382  cpl_frameset * photset = cpl_frameset_new();
383  cpl_recipe * repack = NULL;
384  cpl_recipe * shift = NULL;
385  cpl_recipe * clip = NULL;
386  cpl_recipe * qc = NULL;
387  cpl_recipe * swarp = NULL;
388  cpl_recipe * join = NULL;
389  cpl_recipe * phot = NULL;
390  cpl_pluginlist * plugins = cpl_pluginlist_new();
391  cpl_frameset * usedframes = cpl_frameset_new();
392  cpl_frame * meanfrm = NULL;
393 
394  skip_if(check_swarp());
395 
396 
397  repack = visir_init_recipe("visir_util_repack",
398  &visir_util_repack_get_info, plugins);
399  shift = visir_init_recipe("visir_util_detect_shift",
400  &visir_util_detect_shift_get_info, plugins);
401  clip = visir_init_recipe("visir_util_clip",
402  &visir_util_clip_get_info, plugins);
403  qc = visir_init_recipe("visir_util_qc",
404  &visir_util_qc_get_info, plugins);
405  swarp = visir_init_recipe("visir_util_run_swarp",
406  &visir_util_run_swarp_get_info, plugins);
407  join = visir_init_recipe("visir_util_join",
408  &visir_util_join_get_info, plugins);
409 
410  visir_dfs_set_groups(framelist);
411 
412  FOR_EACH_FRAMESET(frame_, framelist) {
413  cpl_frame * frame = cpl_frame_duplicate(frame_);
414  cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame));
415  if (strcmp(cpl_frame_get_tag(frame), VISIR_IMA_STD_CAT_PROCATG) == 0)
416  cpl_frameset_insert(photset, frame);
417  else
418  cpl_frameset_insert(repackset, frame);
419  }
420  skip_if(visir_run_recipe(repack, repackset, parlist,
421  &util_repack_set_parameters));
422  meanfrm = cpl_frame_duplicate(cpl_frameset_find(repackset, "MEAN"));
423 
424 
425  cpl_frameset * shiftset = visir_prepare_frameset(repackset, NULL, 0,
426  CPL_TRUE);
427  /* jitter correction modifies input calib file and adds a new one
428  * to the recipe output, so drop the original one from the frameset */
429  shiftset = visir_remove_modified_calib(shiftset);
430  cpl_frameset_delete(repackset);
431  repackset = NULL;
432  skip_if(visir_run_recipe(shift, shiftset, parlist, &visir_copy_parameters));
433  shiftset = visir_remove_modified_calib(shiftset);
434 
435 
436  const char * tagmap[] = {"BEAM_DETECTED", VISIR_UTIL_INPUTS_RAW};
437  cpl_frameset * clipset =
438  visir_prepare_frameset(shiftset, tagmap, ARRAY_LEN(tagmap), CPL_FALSE);
439  skip_if(visir_run_recipe(clip, clipset, parlist, &visir_copy_parameters));
440 
441 
442  const char * qctagmap[] = {"BEAM_DETECTED", VISIR_UTIL_CORRECTED};
443  cpl_frameset * qcset = visir_prepare_frameset(shiftset, qctagmap,
444  ARRAY_LEN(qctagmap),
445  CPL_FALSE);
446  skip_if(visir_run_recipe(qc, qcset, parlist, &visir_copy_parameters));
447 
448 
449  const char * swarptagmap[] = {"BEAM_DETECTED", VISIR_UTIL_CORRECTED};
450  cpl_frameset * swarpset = visir_prepare_frameset(shiftset, swarptagmap,
451  ARRAY_LEN(swarptagmap),
452  CPL_FALSE);
453  cpl_frameset_delete(shiftset);
454  shiftset = NULL;
455  FOR_EACH_FRAMESET(frm, clipset) {
456  if (strcmp(cpl_frame_get_tag(frm), VISIR_UTIL_ERROR_MAP) != 0)
457  continue;
458  cpl_frame * frame = cpl_frame_duplicate(frm);
459  cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
460  cpl_frameset_insert(swarpset, frame);
461  }
462  cpl_frameset_delete(clipset);
463  clipset = NULL;
464  skip_if(visir_run_recipe(swarp, swarpset, parlist, &visir_copy_parameters));
465  irplib_framelist * swarpfl = irplib_framelist_cast(swarpset);
466  irplib_framelist * qcfl = irplib_framelist_cast(qcset);
467 
468  irplib_framelist * imgs = irplib_framelist_extract(swarpfl, "COADDED_IMAGE");
469  irplib_framelist * wgts = irplib_framelist_extract(swarpfl, "COADDED_WEIGHT");
470  irplib_framelist * qcs = irplib_framelist_extract(qcfl, VISIR_UTIL_QC_PROCATG);
471  if (cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) {
472  imgs = irplib_framelist_new();
473  wgts = irplib_framelist_new();
474  qcs = irplib_framelist_new();
475  cpl_errorstate_set(cleanstate);
476  }
477  cpl_frame * coadd_imgf = cpl_frameset_find(swarpset, "COADDED_IMAGE_COMBINED");
478  cpl_frame * coadd_wgtf = cpl_frameset_find(swarpset, "COADDED_WEIGHT_COMBINED");
479  skip_if(coadd_imgf == NULL || coadd_wgtf == NULL);
480 
481 
482  if (cpl_frameset_get_size(photset) != 0) {
483  phot = visir_init_recipe("visir_old_img_phot",
484  &visir_old_img_phot_get_info, plugins);
485  cpl_frameset *orig_phot = cpl_frameset_duplicate(photset);
486  run_phot(phot, photset, parlist, coadd_imgf, coadd_wgtf,
487  cpl_frameset_find(qcset, VISIR_UTIL_QC_PROCATG"_COMBINED"), 0);
488  skip_if(0);
489 
490  for (int i = 0; i < irplib_framelist_get_size(imgs); i++) {
491  cpl_frame * imgf = irplib_framelist_get(imgs, i);
492  cpl_frame * wgtf = irplib_framelist_get(wgts, i);
493  cpl_frame * qcf = irplib_framelist_get(qcs, i);
494  cpl_frameset *copy = cpl_frameset_duplicate(orig_phot);
495  cpl_frame * res = run_phot(phot, copy, parlist, imgf, wgtf, qcf, i + 1);
496  cpl_frameset_insert(photset, res);
497  skip_if(0);
498  }
499  }
500 
501  {
502  cpl_frame * wgtf = cpl_frame_duplicate(coadd_wgtf);
503  cpl_frameset * joinset = cpl_frameset_new();
504  if (cpl_frameset_get_size(photset) != 0) {
505  FOR_EACH_FRAMESET(frm, photset) {
506  if (strcmp(cpl_frame_get_tag(frm),
507  VISIR_IMG_PHOT_COMBINED_PROCATG) == 0 ||
508  strcmp(cpl_frame_get_tag(frm),
509  VISIR_IMG_PHOT_ONEBEAM_PROCATG) == 0) {
510  cpl_frame * dfrm = cpl_frame_duplicate(frm);
511  cpl_frameset_insert(joinset, dfrm);
512  }
513  }
514 
515  }
516  else {
517  cpl_frame * imgf = cpl_frame_duplicate(coadd_imgf);
518  cpl_frame * qcf =
519  cpl_frameset_find(qcset, VISIR_UTIL_QC_PROCATG"_COMBINED");
520  qcf = cpl_frame_duplicate(qcf);
521  cpl_frameset_insert(joinset, imgf);
522  for (int i = 0; i < irplib_framelist_get_size(imgs); i++) {
523  imgf = cpl_frame_duplicate(irplib_framelist_get(imgs, i));
524  cpl_frameset_insert(joinset, imgf);
525  }
526  cpl_frame_set_tag(qcf, VISIR_UTIL_QC_PROCATG);
527  cpl_frame_set_group(qcf, CPL_FRAME_GROUP_RAW);
528  cpl_frameset_insert(joinset, qcf);
529  for (int i = 0; i < irplib_framelist_get_size(qcs); i++) {
530  qcf = cpl_frame_duplicate(irplib_framelist_get(qcs, i));
531  cpl_frame_set_group(qcf, CPL_FRAME_GROUP_RAW);
532  cpl_frameset_insert(joinset, qcf);
533  }
534  }
535 
536  cpl_frame_set_tag(wgtf, VISIR_UTIL_WEIGHT_MAP_PROCATG);
537  cpl_frameset_insert(joinset, wgtf);
538  for (int i = 0; i < irplib_framelist_get_size(wgts); i++) {
539  wgtf = cpl_frame_duplicate(irplib_framelist_get(wgts, i));
540  cpl_frame_set_tag(wgtf, VISIR_UTIL_WEIGHT_MAP_PROCATG);
541  cpl_frameset_insert(joinset, wgtf);
542  }
543 
544  skip_if(visir_run_recipe(join, joinset, parlist,
545  &visir_copy_parameters));
546 
547  FOR_EACH_FRAMESET(frm, joinset)
548  if (cpl_frame_get_group(frm) == CPL_FRAME_GROUP_PRODUCT)
549  cpl_frameset_insert(framelist, cpl_frame_duplicate(frm));
550  cpl_frameset_delete(joinset);
551  cpl_frameset_insert(framelist, meanfrm);
552  meanfrm = NULL;
553  skip_if(0);
554  }
555 
556  end_skip;
557 
558  {
559  cpl_recipe * recipes[] = {repack, shift, clip, qc, swarp, phot, join};
560  for (size_t i = 0; i < ARRAY_LEN(recipes); i++)
561  if (recipes[i])
562  cpl_plugin_delete(&(recipes[i]->interface));
563  }
564  cpl_pluginlist_delete(plugins);
565 
566  cpl_frame_delete(meanfrm);
567  cpl_frameset_delete(photset);
568  cpl_frameset_delete(usedframes);
569 
570  return cpl_error_get_code();
571 }
cpl_frame * irplib_framelist_get(irplib_framelist *self, int pos)
Get the specified frame from the framelist.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
irplib_framelist * irplib_framelist_new(void)
Create an empty framelist.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.