VISIR Pipeline Reference Manual  4.1.7
irplib_utils.c
1 /*
2  * This file is part of the irplib package
3  * Copyright (C) 2002,2003,2014 European Southern Observatory
4  * 2004 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 
25 /*-----------------------------------------------------------------------------
26  Includes
27  -----------------------------------------------------------------------------*/
28 #include "irplib_utils.h"
29 
30 #include <string.h>
31 #include <assert.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 
35 #include <cpl.h>
36 #include <math.h>
37 
38 /*-----------------------------------------------------------------------------
39  Defines
40  -----------------------------------------------------------------------------*/
41 
42 #ifndef inline
43 #define inline /* inline */
44 #endif
45 
46 /*-----------------------------------------------------------------------------
47  Missing Function Prototypes
48  -----------------------------------------------------------------------------*/
49 
50 /*-----------------------------------------------------------------------------
51  Private Function Prototypes
52  -----------------------------------------------------------------------------*/
53 
54 inline static double irplib_data_get_double(const void *, cpl_type, int)
55 #ifdef CPL_HAVE_GNUC_NONNULL
56  __attribute__((nonnull))
57 #endif
58  ;
59 
60 inline static void irplib_data_set_double(void *, cpl_type, int, double)
61 #ifdef CPL_HAVE_GNUC_NONNULL
62  __attribute__((nonnull))
63 #endif
64  ;
65 
66 
67 static
68 void irplib_errorstate_dump_one_level(void (*)(const char *,
69  const char *, ...)
70  #ifdef __GNUC__
71  __attribute__((format (printf, 2, 3)))
72  #endif
73  , unsigned, unsigned, unsigned);
74 static double frame_get_exptime(const cpl_frame * pframe);
75 static void quicksort(int* index, double* exptime, int left, int right);
76 
77 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
78  cpl_propertylist *,
79  const cpl_parameterlist *,
80  const cpl_frameset *,
81  const cpl_frame *,
82  const cpl_imagelist *,
83  const cpl_image *,
84  cpl_type,
85  const cpl_table *,
86  const cpl_propertylist *,
87  const char *,
88  const cpl_propertylist *,
89  const char *,
90  const char *,
91  const char *);
92 
93 /*----------------------------------------------------------------------------*/
97 /*----------------------------------------------------------------------------*/
101 /*----------------------------------------------------------------------------*/
113 /*----------------------------------------------------------------------------*/
114 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
115  unsigned last)
116 {
117 
118  irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
119 
120 }
121 
122 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
123  const cpl_vector * x_pos,
124  const cpl_vector * values,
125  int degree,
126  double * mse,
127  double * rechisq
128  );
129 
130 /*----------------------------------------------------------------------------*/
140 /*----------------------------------------------------------------------------*/
141 void irplib_errorstate_dump_info(unsigned self, unsigned first,
142  unsigned last)
143 {
144 
145  irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
146 
147 }
148 
149 
150 /*----------------------------------------------------------------------------*/
160 /*----------------------------------------------------------------------------*/
161 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
162  unsigned last)
163 {
164 
165  irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
166 
167 }
168 
169 
170 /*----------------------------------------------------------------------------*/
191 /*----------------------------------------------------------------------------*/
192 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
193  const cpl_parameterlist * parlist,
194  const cpl_frameset * usedframes,
195  const cpl_image * image,
196  cpl_type_bpp bpp,
197  const char * recipe,
198  const char * procat,
199  const cpl_propertylist * applist,
200  const char * remregexp,
201  const char * pipe_id,
202  const char * filename)
203 {
204  cpl_errorstate prestate = cpl_errorstate_get();
205  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
206  : cpl_propertylist_new();
207 
208  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
209 
210  irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
211  bpp, recipe, prolist, remregexp, pipe_id, filename);
212 
213  cpl_propertylist_delete(prolist);
214 
215  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
216 
217  return CPL_ERROR_NONE;
218 
219 }
220 
221 /*----------------------------------------------------------------------------*/
238 /*----------------------------------------------------------------------------*/
239 cpl_error_code
240 irplib_dfs_save_propertylist(cpl_frameset * allframes,
241  const cpl_parameterlist * parlist,
242  const cpl_frameset * usedframes,
243  const char * recipe,
244  const char * procat,
245  const cpl_propertylist * applist,
246  const char * remregexp,
247  const char * pipe_id,
248  const char * filename)
249 {
250  cpl_errorstate prestate = cpl_errorstate_get();
251  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
252  : cpl_propertylist_new();
253 
254  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
255 
256  cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
257  recipe, prolist, remregexp, pipe_id, filename);
258 
259  cpl_propertylist_delete(prolist);
260 
261  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
262 
263  return CPL_ERROR_NONE;
264 
265 }
266 
267 /*----------------------------------------------------------------------------*/
286 /*----------------------------------------------------------------------------*/
287 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
288  const cpl_parameterlist * parlist,
289  const cpl_frameset * usedframes,
290  const cpl_imagelist * imagelist,
291  cpl_type_bpp bpp,
292  const char * recipe,
293  const char * procat,
294  const cpl_propertylist * applist,
295  const char * remregexp,
296  const char * pipe_id,
297  const char * filename)
298 {
299  cpl_errorstate prestate = cpl_errorstate_get();
300  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
301  : cpl_propertylist_new();
302 
303  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
304 
305  cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
306  imagelist, bpp, recipe, prolist, remregexp, pipe_id,
307  filename);
308 
309  cpl_propertylist_delete(prolist);
310 
311  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
312 
313  return CPL_ERROR_NONE;
314 }
315 
316 /*----------------------------------------------------------------------------*/
334 /*----------------------------------------------------------------------------*/
335 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
336  const cpl_parameterlist * parlist,
337  const cpl_frameset * usedframes,
338  const cpl_table * table,
339  const cpl_propertylist * tablelist,
340  const char * recipe,
341  const char * procat,
342  const cpl_propertylist * applist,
343  const char * remregexp,
344  const char * pipe_id,
345  const char * filename)
346 {
347 
348  cpl_errorstate prestate = cpl_errorstate_get();
349  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
350  : cpl_propertylist_new();
351 
352  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
353 
354  cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
355  table, tablelist, recipe, prolist, remregexp,
356  pipe_id, filename);
357 
358  cpl_propertylist_delete(prolist);
359 
360  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
361 
362  return CPL_ERROR_NONE;
363 }
364 
365 
366 
367 /*----------------------------------------------------------------------------*/
394 /*----------------------------------------------------------------------------*/
395 cpl_error_code irplib_dfs_save_image_(cpl_frameset * allframes,
396  cpl_propertylist * header,
397  const cpl_parameterlist * parlist,
398  const cpl_frameset * usedframes,
399  const cpl_frame * inherit,
400  const cpl_image * image,
401  cpl_type type,
402  const char * recipe,
403  const cpl_propertylist * applist,
404  const char * remregexp,
405  const char * pipe_id,
406  const char * filename)
407 {
408  return
409  irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
410  NULL, image, type, NULL, NULL, recipe,
411  applist, remregexp, pipe_id, filename)
412  ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
413 
414 }
415 
416 
417 /*----------------------------------------------------------------------------*/
441 /*----------------------------------------------------------------------------*/
442 
443 static
444 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
445  cpl_propertylist * header,
446  const cpl_parameterlist * parlist,
447  const cpl_frameset * usedframes,
448  const cpl_frame * inherit,
449  const cpl_imagelist * imagelist,
450  const cpl_image * image,
451  cpl_type type,
452  const cpl_table * table,
453  const cpl_propertylist * tablelist,
454  const char * recipe,
455  const cpl_propertylist * applist,
456  const char * remregexp,
457  const char * pipe_id,
458  const char * filename) {
459 
460  const char * procat;
461  cpl_propertylist * plist;
462  cpl_frame * product_frame;
463  /* Inside this function the product-types are numbered:
464  0: imagelist
465  1: table
466  2: image
467  3: propertylist only
468  */
469  const unsigned pronum
470  = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
471  const char * proname[] = {"imagelist", "table", "image",
472  "propertylist"};
473  /* FIXME: Define a frame type for an imagelist and when data-less */
474  const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
475  CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
476  cpl_error_code error = CPL_ERROR_NONE;
477 
478 
479  /* No more than one of imagelist, table and image may be non-NULL */
480  /* tablelist may only be non-NULL when table is non-NULL */
481  if (imagelist != NULL) {
482  assert(pronum == 0);
483  assert(image == NULL);
484  assert(table == NULL);
485  assert(tablelist == NULL);
486  } else if (table != NULL) {
487  assert(pronum == 1);
488  assert(imagelist == NULL);
489  assert(image == NULL);
490  } else if (image != NULL) {
491  assert(pronum == 2);
492  assert(imagelist == NULL);
493  assert(table == NULL);
494  assert(tablelist == NULL);
495  } else {
496  assert(pronum == 3);
497  assert(imagelist == NULL);
498  assert(table == NULL);
499  assert(tablelist == NULL);
500  assert(image == NULL);
501  }
502 
503  cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
504  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
505  cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
506  cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
507  cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
508  cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
509  cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
510 
511  procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
512 
513  cpl_ensure_code(procat != NULL, cpl_error_get_code());
514 
515  cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", proname[pronum],
516  procat, filename);
517 
518  product_frame = cpl_frame_new();
519 
520  /* Create product frame */
521  error |= cpl_frame_set_filename(product_frame, filename);
522  error |= cpl_frame_set_tag(product_frame, procat);
523  error |= cpl_frame_set_type(product_frame, protype[pronum]);
524  error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
525  error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
526 
527  if (error) {
528  cpl_frame_delete(product_frame);
529  return cpl_error_set_where(cpl_func);
530  }
531 
532  if (header != NULL) {
533  cpl_propertylist_empty(header);
534  plist = header;
535  } else {
536  plist = cpl_propertylist_new();
537  }
538 
539  /* Add any QC parameters here */
540  if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
541  applist,
542  ".", 0);
543 
544  /* Add DataFlow keywords */
545  if (!error)
546  error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
547  parlist, recipe, pipe_id,
548  "PRO-1.15", inherit);
549 
550  if (remregexp != NULL && !error) {
551  cpl_errorstate prestate = cpl_errorstate_get();
552  (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
553  if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
554  }
555 
556  if (!error) {
557  switch (pronum) {
558  case 0:
559  error = cpl_imagelist_save(imagelist, filename, type, plist,
560  CPL_IO_CREATE);
561  break;
562  case 1:
563  error = cpl_table_save(table, plist, tablelist, filename,
564  CPL_IO_CREATE);
565  break;
566  case 2:
567  error = cpl_image_save(image, filename, type, plist,
568  CPL_IO_CREATE);
569  break;
570  default:
571  /* case 3: */
572  error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
573  }
574  }
575 
576  if (!error) {
577  /* Insert the frame of the saved file in the input frameset */
578  error = cpl_frameset_insert(allframes, product_frame);
579 
580  } else {
581  cpl_frame_delete(product_frame);
582  }
583 
584  if (plist != header) cpl_propertylist_delete(plist);
585 
586  cpl_ensure_code(!error, error);
587 
588  return CPL_ERROR_NONE;
589 
590 }
591 
592 
593 /*----------------------------------------------------------------------------*/
648 /*----------------------------------------------------------------------------*/
649 cpl_error_code irplib_image_split(const cpl_image * self,
650  cpl_image * im_low,
651  cpl_image * im_mid,
652  cpl_image * im_high,
653  double th_low,
654  cpl_boolean isleq_low,
655  double th_high,
656  cpl_boolean isgeq_high,
657  double alt_low,
658  double alt_high,
659  cpl_boolean isbad_low,
660  cpl_boolean isbad_mid,
661  cpl_boolean isbad_high)
662 {
663 
664  const void * selfdata = cpl_image_get_data_const(self);
665  /* hasbpm reduces check-overhead if self does not have a bpm, and if
666  self is also passed as an output image, that ends up with bad pixels */
667  /* FIXME: Need a proper way to know if a bpm has been allocated :-((((((( */
668  const cpl_boolean hasbpm
669  = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
670  const cpl_binary * selfbpm = hasbpm
671  ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
672  const cpl_type selftype = cpl_image_get_type(self);
673  const int nx = cpl_image_get_size_x(self);
674  const int ny = cpl_image_get_size_y(self);
675  const int npix = nx * ny;
676  const cpl_boolean do_low = im_low != NULL;
677  const cpl_boolean do_mid = im_mid != NULL;
678  const cpl_boolean do_high = im_high != NULL;
679  void * lowdata = NULL;
680  void * middata = NULL;
681  void * highdata = NULL;
682  cpl_binary * lowbpm = NULL;
683  cpl_binary * midbpm = NULL;
684  cpl_binary * highbpm = NULL;
685  const cpl_type lowtype
686  = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
687  const cpl_type midtype
688  = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
689  const cpl_type hightype
690  = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
691  int i;
692 
693 
694  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
695  cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
696  cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
697 
698  if (do_low) {
699  cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
700  CPL_ERROR_INCOMPATIBLE_INPUT);
701  cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
702  CPL_ERROR_INCOMPATIBLE_INPUT);
703  lowdata = cpl_image_get_data(im_low);
704  }
705 
706  if (do_mid) {
707  cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
708  CPL_ERROR_INCOMPATIBLE_INPUT);
709  cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
710  CPL_ERROR_INCOMPATIBLE_INPUT);
711  middata = cpl_image_get_data(im_mid);
712  }
713 
714  if (do_high) {
715  cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
716  CPL_ERROR_INCOMPATIBLE_INPUT);
717  cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
718  CPL_ERROR_INCOMPATIBLE_INPUT);
719  highdata = cpl_image_get_data(im_high);
720  }
721 
722  /* From this point a failure would indicate a serious bug in CPL */
723 
724  for (i = 0; i < npix; i++) {
725  const double value = irplib_data_get_double(selfdata, selftype, i);
726  cpl_boolean isalt_low = do_low;
727  cpl_boolean isalt_mid = do_mid;
728  cpl_boolean isalt_high = do_high;
729  cpl_boolean setbad_low = do_low;
730  cpl_boolean setbad_mid = do_mid;
731  cpl_boolean setbad_high = do_high;
732  const void * setdata = NULL;
733  double alt_mid = 0.0; /* Avoid (false) uninit warning */
734 
735  if (isleq_low ? value <= th_low : value < th_low) {
736  if (do_low) {
737  isalt_low = CPL_FALSE;
738  irplib_data_set_double(lowdata, lowtype, i, value);
739  setbad_low = hasbpm && selfbpm[i];
740  setdata = lowdata;
741  }
742  alt_mid = alt_low;
743  } else if (isgeq_high ? value >= th_high : value > th_high) {
744  if (do_high) {
745  isalt_high = CPL_FALSE;
746  irplib_data_set_double(highdata, hightype, i, value);
747  setbad_high = hasbpm && selfbpm[i];
748  setdata = highdata;
749  }
750  alt_mid = alt_high;
751  } else if (do_mid) {
752  isalt_mid = CPL_FALSE;
753  irplib_data_set_double(middata, midtype, i, value);
754  setbad_mid = hasbpm && selfbpm[i];
755  setdata = middata;
756  }
757 
758  if (isalt_low && lowdata != setdata) {
759  irplib_data_set_double(lowdata, lowtype, i, alt_low);
760  setbad_low = isbad_low;
761  }
762  if (isalt_mid && middata != setdata) {
763  irplib_data_set_double(middata, midtype, i, alt_mid);
764  setbad_mid = isbad_mid;
765  }
766  if (isalt_high && highdata != setdata) {
767  irplib_data_set_double(highdata, hightype, i, alt_high);
768  setbad_high = isbad_high;
769  }
770 
771  if (setbad_low) {
772  if (lowbpm == NULL) lowbpm
773  = cpl_mask_get_data(cpl_image_get_bpm(im_low));
774  lowbpm[i] = CPL_BINARY_1;
775  }
776  if (setbad_mid) {
777  if (midbpm == NULL) midbpm
778  = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
779  midbpm[i] = CPL_BINARY_1;
780  }
781  if (setbad_high) {
782  if (highbpm == NULL) highbpm
783  = cpl_mask_get_data(cpl_image_get_bpm(im_high));
784  highbpm[i] = CPL_BINARY_1;
785  }
786  }
787 
788  return CPL_ERROR_NONE;
789 
790 }
791 
792 
793 /*----------------------------------------------------------------------------*/
841 /*----------------------------------------------------------------------------*/
842 
843 cpl_error_code
844 irplib_dfs_table_convert(cpl_table * self,
845  cpl_frameset * allframes,
846  const cpl_frameset * useframes,
847  int maxlinelen,
848  char commentchar,
849  const char * product_name,
850  const char * procatg,
851  const cpl_parameterlist * parlist,
852  const char * recipe_name,
853  const cpl_propertylist * mainlist,
854  const cpl_propertylist * extlist,
855  const char * remregexp,
856  const char * instrume,
857  const char * pipe_id,
858  cpl_boolean (*table_set_row)
859  (cpl_table *, const char *, int,
860  const cpl_frame *,
861  const cpl_parameterlist *),
862  cpl_error_code (*table_check)
863  (cpl_table *,
864  const cpl_frameset *,
865  const cpl_parameterlist *))
866 {
867 
868  const char * filename;
869  cpl_propertylist * applist = NULL;
870  cpl_errorstate prestate = cpl_errorstate_get();
871  cpl_error_code error;
872  char * fallback_filename = NULL;
873 
874  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
875  cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
876  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
877  cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
878  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
879  cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
880  cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
881  cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
882 
883  cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
884  maxlinelen,
885  commentchar,
886  parlist,
887  table_set_row),
888  cpl_error_get_code());
889 
890  if (table_check != NULL && (table_check(self, useframes, parlist) ||
891  !cpl_errorstate_is_equal(prestate))) {
892  return cpl_error_set_message(cpl_func, cpl_error_get_code(),
893  "Consistency check of table failed");
894  }
895 
896  fallback_filename = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
897  filename = product_name != NULL ? product_name : fallback_filename;
898 
899  applist = mainlist == NULL
900  ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
901 
902  error = cpl_propertylist_update_string(applist, "INSTRUME", instrume);
903 
904  if (!error)
905  error = irplib_dfs_save_table(allframes, parlist, useframes, self,
906  extlist, recipe_name, procatg, applist,
907  remregexp, pipe_id, filename);
908 
909  cpl_propertylist_delete(applist);
910  cpl_free(fallback_filename);
911 
912  /* Propagate the error, if any */
913  cpl_ensure_code(!error, error);
914 
915  return CPL_ERROR_NONE;
916 
917 }
918 
919 
920 
921 /*----------------------------------------------------------------------------*/
970 /*----------------------------------------------------------------------------*/
971 
972 cpl_error_code
974  const cpl_frameset * useframes,
975  int maxlinelen,
976  char commentchar,
977  const cpl_parameterlist * parlist,
978  cpl_boolean (*table_set_row)
979  (cpl_table *, const char *, int,
980  const cpl_frame *,
981  const cpl_parameterlist *))
982 {
983 
984  const cpl_frame * rawframe;
985  char * linebuffer = NULL;
986  FILE * stream = NULL;
987  int nfiles = 0;
988  int nrow = cpl_table_get_nrow(self);
989  int irow = 0;
990  cpl_errorstate prestate = cpl_errorstate_get();
991  cpl_frameset_iterator * iterator = NULL;
992 
993  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
994  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
995  cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
996  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
997  cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
998 
999  linebuffer = cpl_malloc(maxlinelen);
1000 
1001  for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
1002  rawframe != NULL;
1003  rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
1004 
1005  const char * rawfile = cpl_frame_get_filename(rawframe);
1006  const char * done; /* Indicate when the reading is done */
1007  const int irowpre = irow;
1008  int iirow = 0;
1009  int ierror;
1010 
1011  if (rawfile == NULL) break; /* Should not happen... */
1012 
1013  stream = fopen(rawfile, "r");
1014 
1015  if (stream == NULL) {
1016 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1017  cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
1018  "open %s for reading", rawfile);
1019 #else
1020  cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
1021  "open file for reading");
1022 #endif
1023  break;
1024  }
1025 
1026  for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
1027 
1028  if (linebuffer[0] != commentchar) {
1029  cpl_boolean didset;
1030 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1031  const int prerow = irow;
1032 #endif
1033 
1034  if (irow == nrow) {
1035  nrow += nrow ? nrow : 1;
1036  if (cpl_table_set_size(self, nrow)) break;
1037  }
1038 
1039  didset = table_set_row(self, linebuffer, irow, rawframe,
1040  parlist);
1041  if (didset) irow++;
1042 
1043  if (!cpl_errorstate_is_equal(prestate)) {
1044  if (didset)
1045 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1046  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1047  "Failed to set table row %d "
1048  "using line %d from %d. file %s",
1049  1+prerow, iirow+1,
1050  nfiles+1, rawfile);
1051  else
1052  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1053  "Failure with line %d from %d. "
1054  "file %s", iirow+1,
1055  nfiles+1, rawfile);
1056 #else
1057  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1058  "Failed to set table row"
1059  "using catalogue line");
1060  else
1061  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1062  "Failure with catalogue line");
1063 #endif
1064 
1065  break;
1066  }
1067  }
1068  }
1069  if (done != NULL) break;
1070 
1071  ierror = fclose(stream);
1072  stream = NULL;
1073  if (ierror) break;
1074 
1075 
1076  if (irow == irowpre)
1077  cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
1078  1+nfiles, rawfile);
1079  }
1080 
1081  cpl_frameset_iterator_delete(iterator);
1082  cpl_free(linebuffer);
1083  if (stream != NULL) fclose(stream);
1084 
1085  /* Check for premature end */
1086  cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1087 
1088  if (irow == 0) {
1089 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1090  return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1091  "No usable lines in the %d input "
1092  "frame(s)", nfiles);
1093 #else
1094  return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1095  "No usable lines in the input frame(s)");
1096 #endif
1097  }
1098 
1099  /* Resize the table to the actual number of rows set */
1100  cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
1101 
1102  return CPL_ERROR_NONE;
1103 }
1104 
1105 
1106 
1107 /*----------------------------------------------------------------------------*/
1119 /*----------------------------------------------------------------------------*/
1120 void irplib_reset(void)
1121 {
1122  return;
1123 }
1124 
1125 /*----------------------------------------------------------------------------*/
1132 /*----------------------------------------------------------------------------*/
1134  cpl_frame * frame1,
1135  cpl_frame * frame2)
1136 {
1137  const char * v1 ;
1138  const char * v2 ;
1139 
1140  /* Test entries */
1141  if (frame1==NULL || frame2==NULL) return -1 ;
1142 
1143  /* Get the tags */
1144  if ((v1 = cpl_frame_get_tag(frame1)) == NULL) return -1 ;
1145  if ((v2 = cpl_frame_get_tag(frame2)) == NULL) return -1 ;
1146 
1147  /* Compare the tags */
1148  if (strcmp(v1, v2)) return 0 ;
1149  else return 1 ;
1150 }
1151 
1152 /*----------------------------------------------------------------------------*/
1168 /*----------------------------------------------------------------------------*/
1169 const char * irplib_frameset_find_file(const cpl_frameset * self,
1170  const char * tag)
1171 {
1172  const cpl_frame * frame = cpl_frameset_find_const(self, tag);
1173 
1174 
1175  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1176 
1177  if (frame == NULL) return NULL;
1178 
1179  if (cpl_frameset_find_const(self, NULL))
1180  cpl_msg_warning(cpl_func,
1181  "Frameset has more than one file with tag: %s",
1182  tag);
1183 
1184  return cpl_frame_get_filename(frame);
1185 
1186 }
1187 
1188 /*----------------------------------------------------------------------------*/
1198 /*----------------------------------------------------------------------------*/
1199 const
1200 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
1201  cpl_frame_group group)
1202 {
1203  const cpl_frame * frame;
1204  cpl_frameset_iterator * iterator = NULL;
1205 
1206  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1207 
1208  for (frame = irplib_frameset_get_first_const(&iterator, self);
1209  frame != NULL ;
1210  frame = irplib_frameset_get_next_const(iterator)) {
1211  if (cpl_frame_get_group(frame) == group) break;
1212  }
1213  cpl_frameset_iterator_delete(iterator);
1214  return frame;
1215 }
1216 
1217 /*----------------------------------------------------------------------------*/
1236 /*----------------------------------------------------------------------------*/
1237 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
1238  int * ind, int nfind)
1239 {
1240  const int nsize = cpl_apertures_get_size(self);
1241  int ifind;
1242 
1243 
1244  cpl_ensure_code(nsize > 0, cpl_error_get_code());
1245  cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1246  cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1247  cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1248 
1249  for (ifind=0; ifind < nfind; ifind++) {
1250  double maxflux = -1;
1251  int maxind = -1;
1252  int i;
1253  for (i=1; i <= nsize; i++) {
1254  int k;
1255 
1256  /* The flux has to be the highest among those not already found */
1257  for (k=0; k < ifind; k++) if (ind[k] == i) break;
1258 
1259  if (k == ifind) {
1260  /* i has not been inserted into ind */
1261  const double flux = cpl_apertures_get_flux(self, i);
1262 
1263  if (maxind < 0 || flux > maxflux) {
1264  maxind = i;
1265  maxflux = flux;
1266  }
1267  }
1268  }
1269  ind[ifind] = maxind;
1270  }
1271 
1272  return CPL_ERROR_NONE;
1273 
1274 }
1275 
1280 /*----------------------------------------------------------------------------*/
1291 /*----------------------------------------------------------------------------*/
1292 inline static
1293 double irplib_data_get_double(const void * self, cpl_type type, int i)
1294 {
1295 
1296  double value;
1297 
1298 
1299  switch (type) {
1300  case CPL_TYPE_FLOAT:
1301  {
1302  const float * pself = (const float*)self;
1303  value = (double)pself[i];
1304  break;
1305  }
1306  case CPL_TYPE_INT:
1307  {
1308  const int * pself = (const int*)self;
1309  value = (double)pself[i];
1310  break;
1311  }
1312  default: /* case CPL_TYPE_DOUBLE */
1313  {
1314  const double * pself = (const double*)self;
1315  value = pself[i];
1316  break;
1317  }
1318  }
1319 
1320  return value;
1321 
1322 }
1323 
1324 
1325 /*----------------------------------------------------------------------------*/
1336 /*----------------------------------------------------------------------------*/
1337 inline static
1338 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
1339 {
1340 
1341  switch (type) {
1342  case CPL_TYPE_FLOAT:
1343  {
1344  float * pself = (float*)self;
1345  pself[i] = (float)value;
1346  break;
1347  }
1348  case CPL_TYPE_INT:
1349  {
1350  int * pself = (int*)self;
1351  pself[i] = (int)value;
1352  break;
1353  }
1354  default: /* case CPL_TYPE_DOUBLE */
1355  {
1356  double * pself = (double*)self;
1357  pself[i] = value;
1358  break;
1359  }
1360  }
1361 }
1362 
1363 
1364 
1365 
1366 
1367 /*----------------------------------------------------------------------------*/
1378 /*----------------------------------------------------------------------------*/
1379 static
1380 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
1381  const char *, ...),
1382  unsigned self, unsigned first,
1383  unsigned last)
1384 {
1385 
1386  const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
1387  const unsigned newest = is_reverse ? first : last;
1388  const unsigned oldest = is_reverse ? last : first;
1389  const char * revmsg = is_reverse ? " in reverse order" : "";
1390 
1391 
1392  /*
1393  cx_assert( messenger != NULL );
1394  cx_assert( oldest <= self );
1395  cx_assert( newest >= self );
1396  */
1397 
1398  if (newest == 0) {
1399  messenger(cpl_func, "No error(s) to dump");
1400  /* cx_assert( oldest == 0); */
1401  } else {
1402  /*
1403  cx_assert( oldest > 0);
1404  cx_assert( newest >= oldest);
1405  */
1406  if (self == first) {
1407  if (oldest == 1) {
1408  messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
1409  revmsg);
1410  } else {
1411  messenger(cpl_func, "Dumping the %u most recent error(s) "
1412  "out of a total of %u errors%s:",
1413  newest - oldest + 1, newest, revmsg);
1414  }
1415  cpl_msg_indent_more();
1416  }
1417 
1418  messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
1419  cpl_error_get_message(), cpl_error_get_code(),
1420  cpl_error_get_where());
1421 
1422  if (self == last) cpl_msg_indent_less();
1423  }
1424 }
1425 
1426 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
1427  const cpl_vector * x_pos,
1428  const cpl_vector * values,
1429  int degree,
1430  double * rechisq
1431  )
1432  {
1433  return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
1434  }
1435 cpl_polynomial * irplib_polynomial_fit_1d_create(
1436  const cpl_vector * x_pos,
1437  const cpl_vector * values,
1438  int degree,
1439  double * mse
1440  )
1441 {
1442 
1443  return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
1444 }
1445 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
1446  const cpl_vector * x_pos,
1447  const cpl_vector * values,
1448  int degree,
1449  double * mse,
1450  double * rechisq
1451  )
1452 {
1453  cpl_polynomial * fit1d = NULL;
1454  cpl_size loc_degree = (cpl_size)degree ;
1455  int x_size = 0;
1456  fit1d = cpl_polynomial_new(1);
1457  x_size = cpl_vector_get_size(x_pos);
1458  if(fit1d != NULL && x_size > 1)
1459  {
1460  cpl_matrix * samppos = NULL;
1461  cpl_vector * fitresidual = NULL;
1462  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1463  samppos = cpl_matrix_wrap(1, x_size,
1464  (double*)cpl_vector_get_data_const(x_pos));
1465  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1466  fitresidual = cpl_vector_new(x_size);
1467  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1468  cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
1469  CPL_FALSE, NULL, &loc_degree);
1470  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1471  cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1472  fit1d, samppos, rechisq);
1473  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1474  if (mse)
1475  {
1476  *mse = cpl_vector_product(fitresidual, fitresidual)
1477  / cpl_vector_get_size(fitresidual);
1478  }
1479  cpl_matrix_unwrap(samppos);
1480  cpl_vector_delete(fitresidual);
1481  }
1482  return fit1d;
1483 }
1484 
1485 static void quicksort(int* iindex, double* exptime, int left, int right)
1486 {
1487  int i = left;
1488  int j = right;
1489  int pivot = (i + j) / 2;
1490  double index_value = exptime[pivot];
1491  do
1492  {
1493  while(exptime[i] < index_value) i++;
1494  while(exptime[j] > index_value) j--;
1495  if (i <= j)
1496  {
1497  if(i < j)
1498  {
1499  int tmp = iindex[i];
1500  double dtmp = exptime[i];
1501  iindex[i]=iindex[j];
1502  iindex[j]=tmp;
1503  exptime[i] = exptime[j];
1504  exptime[j] = dtmp;
1505  }
1506  i++;
1507  j--;
1508  }
1509  } while (i <= j);
1510 
1511  if (i < right)
1512  {
1513  quicksort(iindex, exptime, i, right);
1514  }
1515  if (left < j)
1516  {
1517  quicksort(iindex, exptime,left, j);
1518  }
1519 }
1520 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
1521 {
1522  int i = 0;
1523  const cpl_frame* tmp_frame = 0;
1524  cpl_error_code error = CPL_ERROR_NONE;
1525  int sz = cpl_frameset_get_size(self);
1526  cpl_frameset_iterator* iterator = NULL;
1527 
1528  /* 1. get an array of frames */
1529  tmp_frame = irplib_frameset_get_first_const(&iterator, self);
1530  while(tmp_frame)
1531  {
1532  exptime[i] = frame_get_exptime(tmp_frame);
1533  iindex[i] = i;
1534  tmp_frame = irplib_frameset_get_next_const(iterator);
1535  i++;
1536  }
1537  cpl_frameset_iterator_delete(iterator);
1538  /* 2.sort */
1539  quicksort(iindex, exptime, 0, sz - 1);
1540 
1541  return error;
1542 }
1543 
1544 static double frame_get_exptime(const cpl_frame * pframe)
1545 {
1546  double dval = 0;
1547  cpl_propertylist * plist =
1548  cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1549  "EXPTIME", CPL_FALSE);
1550  if(plist) {
1551  dval = cpl_propertylist_get_double(plist, "EXPTIME");
1552  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1553  cpl_msg_error(cpl_func, "error during reading EXPTIME key from "
1554  "the frame [%s]", cpl_frame_get_filename(pframe));
1555  }
1556  }
1557  /* Free and return */
1558  cpl_propertylist_delete(plist);
1559  return dval;
1560 }
1561 
1562 
1563 /*----------------------------------------------------------------------------*/
1577 /*----------------------------------------------------------------------------*/
1578 void * irplib_aligned_malloc(size_t alignment, size_t size)
1579 {
1580  if (alignment == 0)
1581  alignment = 1;
1582  /* Error if align is not a power of two. */
1583  if (alignment & (alignment - 1)) {
1584  errno = EINVAL;
1585  return NULL;
1586  }
1587  /* make size a multiple of alignment (required by C11) */
1588  if ((size % alignment) != 0) {
1589  size += alignment - (size % alignment);
1590  }
1591 
1592 #if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1593  return aligned_alloc(alignment, size);
1594 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1595  {
1596  void *ptr;
1597  if (alignment == 1)
1598  return malloc (size);
1599  if (alignment == 2 || (sizeof (void *) == 8 && alignment == 4))
1600  alignment = sizeof (void *);
1601  if (posix_memalign (&ptr, alignment, size) == 0)
1602  return ptr;
1603  else
1604  return NULL;
1605  }
1606 #else
1607  /* copied from gmm_malloc.h in gcc-4.8 */
1608  {
1609  void * malloc_ptr;
1610  void * aligned_ptr;
1611 
1612  if (size == 0)
1613  return NULL;
1614 
1615  /* Assume malloc'd pointer is aligned at least to sizeof (void*).
1616  If necessary, add another sizeof (void*) to store the value
1617  returned by malloc. Effectively this enforces a minimum alignment
1618  of sizeof double. */
1619  if (alignment < 2 * sizeof (void *))
1620  alignment = 2 * sizeof (void *);
1621 
1622  malloc_ptr = malloc (size + alignment);
1623  if (!malloc_ptr)
1624  return NULL;
1625 
1626  /* Align We have at least sizeof (void *) space below malloc'd ptr. */
1627  aligned_ptr = (void *) (((size_t) malloc_ptr + alignment)
1628  & ~((size_t) (alignment) - 1));
1629 
1630  /* Store the original pointer just before p. */
1631  *(((void **) aligned_ptr) - 1) = malloc_ptr;
1632 
1633  return aligned_ptr;
1634  }
1635 #endif
1636 }
1637 
1638 
1639 /*----------------------------------------------------------------------------*/
1649 /*----------------------------------------------------------------------------*/
1650 void * irplib_aligned_calloc(size_t alignment, size_t nelem, size_t nbytes)
1651 {
1652  void * buffer = irplib_aligned_malloc(alignment, nelem * nbytes);
1653  if (buffer == NULL)
1654  return NULL;
1655  /* cast to aligned pointer helps compilers to emit better (builtin) code */
1656  memset((size_t *)buffer, 0, nelem * nbytes);
1657  return buffer;
1658 }
1659 
1660 
1661 /*----------------------------------------------------------------------------*/
1669 /*----------------------------------------------------------------------------*/
1670 void irplib_aligned_free (void * aligned_ptr)
1671 {
1672 #if defined HAVE_DECL_ALIGNED_ALLOC && defined HAVE_ALIGNED_ALLOC
1673  free(aligned_ptr);
1674 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1675  free(aligned_ptr);
1676 #else
1677  if (aligned_ptr)
1678  free (*(((void **) aligned_ptr) - 1));
1679 #endif
1680 }
1681 
1682 
1683 /*----------------------------------------------------------------------------*/
1696 /*----------------------------------------------------------------------------*/
1697 const cpl_frame *
1698 irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
1699  const cpl_frameset *frameset)
1700 {
1701  cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
1702  *iterator = cpl_frameset_iterator_new(frameset);
1703  return cpl_frameset_iterator_get_const(*iterator);
1704 }
1705 
1706 /*----------------------------------------------------------------------------*/
1715 /*----------------------------------------------------------------------------*/
1716 const cpl_frame *
1717 irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
1718 {
1719  cpl_errorstate prestate = cpl_errorstate_get();
1720  cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
1721  if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1722  cpl_errorstate_set(prestate);
1723  return NULL;
1724  } else if (error != CPL_ERROR_NONE) {
1725  return NULL;
1726  }
1727  return cpl_frameset_iterator_get_const(iterator);
1728 }
cpl_error_code irplib_dfs_save_table(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_table *table, const cpl_propertylist *tablelist, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a table as a DFS-compliant pipeline product.
Definition: irplib_utils.c:335
static cpl_error_code irplib_dfs_product_save(cpl_frameset *, cpl_propertylist *, const cpl_parameterlist *, const cpl_frameset *, const cpl_frame *, const cpl_imagelist *, const cpl_image *, cpl_type, const cpl_table *, const cpl_propertylist *, const char *, const cpl_propertylist *, const char *, const char *, const char *)
Save either an image or table as a pipeline product.
Definition: irplib_utils.c:444
void irplib_errorstate_dump_info(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL info level.
Definition: irplib_utils.c:141
cpl_error_code irplib_table_read_from_frameset(cpl_table *self, const cpl_frameset *useframes, int maxlinelen, char commentchar, const cpl_parameterlist *parlist, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *))
Set the rows of a table with data from one or more (ASCII) files.
Definition: irplib_utils.c:973
void irplib_reset(void)
Reset IRPLIB state.
cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures *self, int *ind, int nfind)
Find the aperture(s) with the greatest flux.
cpl_error_code irplib_dfs_save_propertylist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a propertylist as a DFS-compliant pipeline product.
Definition: irplib_utils.c:240
cpl_error_code irplib_dfs_save_image_(cpl_frameset *allframes, cpl_propertylist *header, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_frame *inherit, const cpl_image *image, cpl_type type, const char *recipe, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
Definition: irplib_utils.c:395
const cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset *self, cpl_frame_group group)
Find the first frame belonging to the given group.
cpl_error_code irplib_dfs_table_convert(cpl_table *self, cpl_frameset *allframes, const cpl_frameset *useframes, int maxlinelen, char commentchar, const char *product_name, const char *procatg, const cpl_parameterlist *parlist, const char *recipe_name, const cpl_propertylist *mainlist, const cpl_propertylist *extlist, const char *remregexp, const char *instrume, const char *pipe_id, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *), cpl_error_code(*table_check)(cpl_table *, const cpl_frameset *, const cpl_parameterlist *))
Create a DFS product with one table from one or more (ASCII) file(s)
Definition: irplib_utils.c:844
void irplib_errorstate_dump_warning(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL warning level.
Definition: irplib_utils.c:114
void irplib_errorstate_dump_debug(unsigned self, unsigned first, unsigned last)
Dump a single CPL error at the CPL debug level.
Definition: irplib_utils.c:161
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
Definition: irplib_utils.c:192
int irplib_compare_tags(cpl_frame *frame1, cpl_frame *frame2)
Comparison function to identify different input frames.
const char * irplib_frameset_find_file(const cpl_frameset *self, const char *tag)
Find the filename with the given tag in a frame set.
cpl_error_code irplib_image_split(const cpl_image *self, cpl_image *im_low, cpl_image *im_mid, cpl_image *im_high, double th_low, cpl_boolean isleq_low, double th_high, cpl_boolean isgeq_high, double alt_low, double alt_high, cpl_boolean isbad_low, cpl_boolean isbad_mid, cpl_boolean isbad_high)
Split the values in an image in three according to two thresholds.
Definition: irplib_utils.c:649
cpl_error_code irplib_dfs_save_imagelist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_imagelist *imagelist, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an imagelist as a DFS-compliant pipeline product.
Definition: irplib_utils.c:287