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