NACO Pipeline Reference Manual  4.4.0
irplib_utils.c
1 /* $Id: irplib_utils.c,v 1.85 2013-07-04 12:10:55 jtaylor Exp $
2  *
3  * This file is part of the irplib package
4  * Copyright (C) 2002,2003 European Southern Observatory
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 /*
22  * $Author: jtaylor $
23  * $Date: 2013-07-04 12:10:55 $
24  * $Revision: 1.85 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 #include "irplib_utils.h"
36 
37 #include <cpl.h>
38 #include <math.h>
39 
40 #include <string.h>
41 #include <assert.h>
42 #include <stdlib.h>
43 #include <errno.h>
44 
45 
46 
47 /*-----------------------------------------------------------------------------
48  Defines
49  -----------------------------------------------------------------------------*/
50 
51 /* TEMPORARY SUPPORT OF CPL 5.x */
52 #ifndef CPL_SIZE_FORMAT
53 #define CPL_SIZE_FORMAT "d"
54 #define cpl_size int
55 #endif
56 /* END TEMPORARY SUPPORT OF CPL 5.x */
57 
58 #ifndef inline
59 #define inline /* inline */
60 #endif
61 
62 /*-----------------------------------------------------------------------------
63  Missing Function Prototypes
64  -----------------------------------------------------------------------------*/
65 
66 /*-----------------------------------------------------------------------------
67  Private Function Prototypes
68  -----------------------------------------------------------------------------*/
69 
70 inline static double irplib_data_get_double(const void *, cpl_type, int)
71 #ifdef CPL_HAVE_GNUC_NONNULL
72  __attribute__((nonnull))
73 #endif
74  ;
75 
76 inline static void irplib_data_set_double(void *, cpl_type, int, double)
77 #ifdef CPL_HAVE_GNUC_NONNULL
78  __attribute__((nonnull))
79 #endif
80  ;
81 
82 
83 static
84 void irplib_errorstate_dump_one_level(void (*)(const char *,
85  const char *, ...)
86  #ifdef __GNUC__
87  __attribute__((format (printf, 2, 3)))
88  #endif
89  , unsigned, unsigned, unsigned);
90 static double frame_get_exptime(const cpl_frame * pframe);
91 static void quicksort(int* index, double* exptime, int left, int right);
92 
93 static cpl_error_code irplib_dfs_product_save(cpl_frameset *,
94  cpl_propertylist *,
95  const cpl_parameterlist *,
96  const cpl_frameset *,
97  const cpl_frame *,
98  const cpl_imagelist *,
99  const cpl_image *,
100  cpl_type,
101  const cpl_table *,
102  const cpl_propertylist *,
103  const char *,
104  const cpl_propertylist *,
105  const char *,
106  const char *,
107  const char *);
108 
109 /*----------------------------------------------------------------------------*/
113 /*----------------------------------------------------------------------------*/
117 /*----------------------------------------------------------------------------*/
129 /*----------------------------------------------------------------------------*/
130 void irplib_errorstate_dump_warning(unsigned self, unsigned first,
131  unsigned last)
132 {
133 
134  irplib_errorstate_dump_one_level(&cpl_msg_warning, self, first, last);
135 
136 }
137 
138 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
139  const cpl_vector * x_pos,
140  const cpl_vector * values,
141  int degree,
142  double * mse,
143  double * rechisq
144  );
145 
146 /*----------------------------------------------------------------------------*/
156 /*----------------------------------------------------------------------------*/
157 void irplib_errorstate_dump_info(unsigned self, unsigned first,
158  unsigned last)
159 {
160 
161  irplib_errorstate_dump_one_level(&cpl_msg_info, self, first, last);
162 
163 }
164 
165 
166 /*----------------------------------------------------------------------------*/
176 /*----------------------------------------------------------------------------*/
177 void irplib_errorstate_dump_debug(unsigned self, unsigned first,
178  unsigned last)
179 {
180 
181  irplib_errorstate_dump_one_level(&cpl_msg_debug, self, first, last);
182 
183 }
184 
185 
186 /*----------------------------------------------------------------------------*/
207 /*----------------------------------------------------------------------------*/
208 cpl_error_code irplib_dfs_save_image(cpl_frameset * allframes,
209  const cpl_parameterlist * parlist,
210  const cpl_frameset * usedframes,
211  const cpl_image * image,
212  cpl_type_bpp bpp,
213  const char * recipe,
214  const char * procat,
215  const cpl_propertylist * applist,
216  const char * remregexp,
217  const char * pipe_id,
218  const char * filename)
219 {
220  cpl_errorstate prestate = cpl_errorstate_get();
221  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
222  : cpl_propertylist_new();
223 
224  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
225 
226  irplib_dfs_save_image_(allframes, NULL, parlist, usedframes, NULL, image,
227  bpp, recipe, prolist, remregexp, pipe_id, filename);
228 
229  cpl_propertylist_delete(prolist);
230 
231  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
232 
233  return CPL_ERROR_NONE;
234 
235 }
236 
237 /*----------------------------------------------------------------------------*/
254 /*----------------------------------------------------------------------------*/
255 cpl_error_code
256 irplib_dfs_save_propertylist(cpl_frameset * allframes,
257  const cpl_parameterlist * parlist,
258  const cpl_frameset * usedframes,
259  const char * recipe,
260  const char * procat,
261  const cpl_propertylist * applist,
262  const char * remregexp,
263  const char * pipe_id,
264  const char * filename)
265 {
266  cpl_errorstate prestate = cpl_errorstate_get();
267  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
268  : cpl_propertylist_new();
269 
270  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
271 
272  cpl_dfs_save_propertylist(allframes, NULL, parlist, usedframes, NULL,
273  recipe, prolist, remregexp, pipe_id, filename);
274 
275  cpl_propertylist_delete(prolist);
276 
277  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
278 
279  return CPL_ERROR_NONE;
280 
281 }
282 
283 /*----------------------------------------------------------------------------*/
302 /*----------------------------------------------------------------------------*/
303 cpl_error_code irplib_dfs_save_imagelist(cpl_frameset * allframes,
304  const cpl_parameterlist * parlist,
305  const cpl_frameset * usedframes,
306  const cpl_imagelist * imagelist,
307  cpl_type_bpp bpp,
308  const char * recipe,
309  const char * procat,
310  const cpl_propertylist * applist,
311  const char * remregexp,
312  const char * pipe_id,
313  const char * filename)
314 {
315  cpl_errorstate prestate = cpl_errorstate_get();
316  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
317  : cpl_propertylist_new();
318 
319  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
320 
321  cpl_dfs_save_imagelist(allframes, NULL, parlist, usedframes, NULL,
322  imagelist, bpp, recipe, prolist, remregexp, pipe_id,
323  filename);
324 
325  cpl_propertylist_delete(prolist);
326 
327  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
328 
329  return CPL_ERROR_NONE;
330 }
331 
332 /*----------------------------------------------------------------------------*/
350 /*----------------------------------------------------------------------------*/
351 cpl_error_code irplib_dfs_save_table(cpl_frameset * allframes,
352  const cpl_parameterlist * parlist,
353  const cpl_frameset * usedframes,
354  const cpl_table * table,
355  const cpl_propertylist * tablelist,
356  const char * recipe,
357  const char * procat,
358  const cpl_propertylist * applist,
359  const char * remregexp,
360  const char * pipe_id,
361  const char * filename)
362 {
363 
364  cpl_errorstate prestate = cpl_errorstate_get();
365  cpl_propertylist * prolist = applist ? cpl_propertylist_duplicate(applist)
366  : cpl_propertylist_new();
367 
368  cpl_propertylist_update_string(prolist, CPL_DFS_PRO_CATG, procat);
369 
370  cpl_dfs_save_table(allframes, NULL, parlist, usedframes, NULL,
371  table, tablelist, recipe, prolist, remregexp,
372  pipe_id, filename);
373 
374  cpl_propertylist_delete(prolist);
375 
376  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
377 
378  return CPL_ERROR_NONE;
379 }
380 
381 
382 
383 /*----------------------------------------------------------------------------*/
410 /*----------------------------------------------------------------------------*/
411 cpl_error_code irplib_dfs_save_image_(cpl_frameset * allframes,
412  cpl_propertylist * header,
413  const cpl_parameterlist * parlist,
414  const cpl_frameset * usedframes,
415  const cpl_frame * inherit,
416  const cpl_image * image,
417  cpl_type type,
418  const char * recipe,
419  const cpl_propertylist * applist,
420  const char * remregexp,
421  const char * pipe_id,
422  const char * filename)
423 {
424  return
425  irplib_dfs_product_save(allframes, header, parlist, usedframes, inherit,
426  NULL, image, type, NULL, NULL, recipe,
427  applist, remregexp, pipe_id, filename)
428  ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
429 
430 }
431 
432 
433 /*----------------------------------------------------------------------------*/
457 /*----------------------------------------------------------------------------*/
458 
459 static
460 cpl_error_code irplib_dfs_product_save(cpl_frameset * allframes,
461  cpl_propertylist * header,
462  const cpl_parameterlist * parlist,
463  const cpl_frameset * usedframes,
464  const cpl_frame * inherit,
465  const cpl_imagelist * imagelist,
466  const cpl_image * image,
467  cpl_type type,
468  const cpl_table * table,
469  const cpl_propertylist * tablelist,
470  const char * recipe,
471  const cpl_propertylist * applist,
472  const char * remregexp,
473  const char * pipe_id,
474  const char * filename) {
475 
476  const char * procat;
477  cpl_propertylist * plist;
478  cpl_frame * product_frame;
479  /* Inside this function the product-types are numbered:
480  0: imagelist
481  1: table
482  2: image
483  3: propertylist only
484  */
485  const unsigned pronum
486  = imagelist != NULL ? 0 : table != NULL ? 1 : (image != NULL ? 2 : 3);
487  const char * proname[] = {"imagelist", "table", "image",
488  "propertylist"};
489  /* FIXME: Define a frame type for an imagelist and when data-less */
490  const int protype[] = {CPL_FRAME_TYPE_ANY, CPL_FRAME_TYPE_TABLE,
491  CPL_FRAME_TYPE_IMAGE, CPL_FRAME_TYPE_ANY};
492  cpl_error_code error = CPL_ERROR_NONE;
493 
494 
495  /* No more than one of imagelist, table and image may be non-NULL */
496  /* tablelist may only be non-NULL when table is non-NULL */
497  if (imagelist != NULL) {
498  assert(pronum == 0);
499  assert(image == NULL);
500  assert(table == NULL);
501  assert(tablelist == NULL);
502  } else if (table != NULL) {
503  assert(pronum == 1);
504  assert(imagelist == NULL);
505  assert(image == NULL);
506  } else if (image != NULL) {
507  assert(pronum == 2);
508  assert(imagelist == NULL);
509  assert(table == NULL);
510  assert(tablelist == NULL);
511  } else {
512  assert(pronum == 3);
513  assert(imagelist == NULL);
514  assert(table == NULL);
515  assert(tablelist == NULL);
516  assert(image == NULL);
517  }
518 
519  cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
520  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
521  cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
522  cpl_ensure_code(recipe != NULL, CPL_ERROR_NULL_INPUT);
523  cpl_ensure_code(applist != NULL, CPL_ERROR_NULL_INPUT);
524  cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
525  cpl_ensure_code(filename != NULL, CPL_ERROR_NULL_INPUT);
526 
527  procat = cpl_propertylist_get_string(applist, CPL_DFS_PRO_CATG);
528 
529  cpl_ensure_code(procat != NULL, cpl_error_get_code());
530 
531  cpl_msg_info(cpl_func, "Writing FITS %s product(%s): %s", proname[pronum],
532  procat, filename);
533 
534  product_frame = cpl_frame_new();
535 
536  /* Create product frame */
537  error |= cpl_frame_set_filename(product_frame, filename);
538  error |= cpl_frame_set_tag(product_frame, procat);
539  error |= cpl_frame_set_type(product_frame, protype[pronum]);
540  error |= cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
541  error |= cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
542 
543  if (error) {
544  cpl_frame_delete(product_frame);
545  return cpl_error_set_where(cpl_func);
546  }
547 
548  if (header != NULL) {
549  cpl_propertylist_empty(header);
550  plist = header;
551  } else {
552  plist = cpl_propertylist_new();
553  }
554 
555  /* Add any QC parameters here */
556  if (applist != NULL) error = cpl_propertylist_copy_property_regexp(plist,
557  applist,
558  ".", 0);
559 
560  /* Add DataFlow keywords */
561  if (!error)
562  error = cpl_dfs_setup_product_header(plist, product_frame, usedframes,
563  parlist, recipe, pipe_id,
564  "PRO-1.15", inherit);
565 
566  if (remregexp != NULL && !error) {
567  cpl_errorstate prestate = cpl_errorstate_get();
568  (void)cpl_propertylist_erase_regexp(plist, remregexp, 0);
569  if (!cpl_errorstate_is_equal(prestate)) error = cpl_error_get_code();
570  }
571 
572  if (!error) {
573  switch (pronum) {
574  case 0:
575  error = cpl_imagelist_save(imagelist, filename, type, plist,
576  CPL_IO_CREATE);
577  break;
578  case 1:
579  error = cpl_table_save(table, plist, tablelist, filename,
580  CPL_IO_CREATE);
581  break;
582  case 2:
583  error = cpl_image_save(image, filename, type, plist,
584  CPL_IO_CREATE);
585  break;
586  default:
587  /* case 3: */
588  error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
589  }
590  }
591 
592  if (!error) {
593  /* Insert the frame of the saved file in the input frameset */
594  error = cpl_frameset_insert(allframes, product_frame);
595 
596  } else {
597  cpl_frame_delete(product_frame);
598  }
599 
600  if (plist != header) cpl_propertylist_delete(plist);
601 
602  cpl_ensure_code(!error, error);
603 
604  return CPL_ERROR_NONE;
605 
606 }
607 
608 
609 /*----------------------------------------------------------------------------*/
664 /*----------------------------------------------------------------------------*/
665 cpl_error_code irplib_image_split(const cpl_image * self,
666  cpl_image * im_low,
667  cpl_image * im_mid,
668  cpl_image * im_high,
669  double th_low,
670  cpl_boolean isleq_low,
671  double th_high,
672  cpl_boolean isgeq_high,
673  double alt_low,
674  double alt_high,
675  cpl_boolean isbad_low,
676  cpl_boolean isbad_mid,
677  cpl_boolean isbad_high)
678 {
679 
680  const void * selfdata = cpl_image_get_data_const(self);
681  /* hasbpm reduces check-overhead if self does not have a bpm, and if
682  self is also passed as an output image, that ends up with bad pixels */
683  /* FIXME: Need a proper way to know if a bpm has been allocated :-((((((( */
684  const cpl_boolean hasbpm
685  = cpl_image_count_rejected(self) ? CPL_TRUE : CPL_FALSE;
686  const cpl_binary * selfbpm = hasbpm
687  ? cpl_mask_get_data_const(cpl_image_get_bpm_const(self)) : NULL;
688  const cpl_type selftype = cpl_image_get_type(self);
689  const int nx = cpl_image_get_size_x(self);
690  const int ny = cpl_image_get_size_y(self);
691  const int npix = nx * ny;
692  const cpl_boolean do_low = im_low != NULL;
693  const cpl_boolean do_mid = im_mid != NULL;
694  const cpl_boolean do_high = im_high != NULL;
695  void * lowdata = NULL;
696  void * middata = NULL;
697  void * highdata = NULL;
698  cpl_binary * lowbpm = NULL;
699  cpl_binary * midbpm = NULL;
700  cpl_binary * highbpm = NULL;
701  const cpl_type lowtype
702  = do_low ? cpl_image_get_type(im_low) : CPL_TYPE_INVALID;
703  const cpl_type midtype
704  = do_mid ? cpl_image_get_type(im_mid) : CPL_TYPE_INVALID;
705  const cpl_type hightype
706  = do_high ? cpl_image_get_type(im_high) : CPL_TYPE_INVALID;
707  int i;
708 
709 
710  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
711  cpl_ensure_code(do_low || do_mid || do_high, CPL_ERROR_NULL_INPUT);
712  cpl_ensure_code(th_low <= th_high, CPL_ERROR_ILLEGAL_INPUT);
713 
714  if (do_low) {
715  cpl_ensure_code(cpl_image_get_size_x(im_low) == nx,
716  CPL_ERROR_INCOMPATIBLE_INPUT);
717  cpl_ensure_code(cpl_image_get_size_y(im_low) == ny,
718  CPL_ERROR_INCOMPATIBLE_INPUT);
719  lowdata = cpl_image_get_data(im_low);
720  }
721 
722  if (do_mid) {
723  cpl_ensure_code(cpl_image_get_size_x(im_mid) == nx,
724  CPL_ERROR_INCOMPATIBLE_INPUT);
725  cpl_ensure_code(cpl_image_get_size_y(im_mid) == ny,
726  CPL_ERROR_INCOMPATIBLE_INPUT);
727  middata = cpl_image_get_data(im_mid);
728  }
729 
730  if (do_high) {
731  cpl_ensure_code(cpl_image_get_size_x(im_high) == nx,
732  CPL_ERROR_INCOMPATIBLE_INPUT);
733  cpl_ensure_code(cpl_image_get_size_y(im_high) == ny,
734  CPL_ERROR_INCOMPATIBLE_INPUT);
735  highdata = cpl_image_get_data(im_high);
736  }
737 
738  /* From this point a failure would indicate a serious bug in CPL */
739 
740  for (i = 0; i < npix; i++) {
741  const double value = irplib_data_get_double(selfdata, selftype, i);
742  cpl_boolean isalt_low = do_low;
743  cpl_boolean isalt_mid = do_mid;
744  cpl_boolean isalt_high = do_high;
745  cpl_boolean setbad_low = do_low;
746  cpl_boolean setbad_mid = do_mid;
747  cpl_boolean setbad_high = do_high;
748  const void * setdata = NULL;
749  double alt_mid = 0.0; /* Avoid (false) uninit warning */
750 
751  if (isleq_low ? value <= th_low : value < th_low) {
752  if (do_low) {
753  isalt_low = CPL_FALSE;
754  irplib_data_set_double(lowdata, lowtype, i, value);
755  setbad_low = hasbpm && selfbpm[i];
756  setdata = lowdata;
757  }
758  alt_mid = alt_low;
759  } else if (isgeq_high ? value >= th_high : value > th_high) {
760  if (do_high) {
761  isalt_high = CPL_FALSE;
762  irplib_data_set_double(highdata, hightype, i, value);
763  setbad_high = hasbpm && selfbpm[i];
764  setdata = highdata;
765  }
766  alt_mid = alt_high;
767  } else if (do_mid) {
768  isalt_mid = CPL_FALSE;
769  irplib_data_set_double(middata, midtype, i, value);
770  setbad_mid = hasbpm && selfbpm[i];
771  setdata = middata;
772  }
773 
774  if (isalt_low && lowdata != setdata) {
775  irplib_data_set_double(lowdata, lowtype, i, alt_low);
776  setbad_low = isbad_low;
777  }
778  if (isalt_mid && middata != setdata) {
779  irplib_data_set_double(middata, midtype, i, alt_mid);
780  setbad_mid = isbad_mid;
781  }
782  if (isalt_high && highdata != setdata) {
783  irplib_data_set_double(highdata, hightype, i, alt_high);
784  setbad_high = isbad_high;
785  }
786 
787  if (setbad_low) {
788  if (lowbpm == NULL) lowbpm
789  = cpl_mask_get_data(cpl_image_get_bpm(im_low));
790  lowbpm[i] = CPL_BINARY_1;
791  }
792  if (setbad_mid) {
793  if (midbpm == NULL) midbpm
794  = cpl_mask_get_data(cpl_image_get_bpm(im_mid));
795  midbpm[i] = CPL_BINARY_1;
796  }
797  if (setbad_high) {
798  if (highbpm == NULL) highbpm
799  = cpl_mask_get_data(cpl_image_get_bpm(im_high));
800  highbpm[i] = CPL_BINARY_1;
801  }
802  }
803 
804  return CPL_ERROR_NONE;
805 
806 }
807 
808 
809 /*----------------------------------------------------------------------------*/
857 /*----------------------------------------------------------------------------*/
858 
859 cpl_error_code
860 irplib_dfs_table_convert(cpl_table * self,
861  cpl_frameset * allframes,
862  const cpl_frameset * useframes,
863  int maxlinelen,
864  char commentchar,
865  const char * product_name,
866  const char * procatg,
867  const cpl_parameterlist * parlist,
868  const char * recipe_name,
869  const cpl_propertylist * mainlist,
870  const cpl_propertylist * extlist,
871  const char * remregexp,
872  const char * instrume,
873  const char * pipe_id,
874  cpl_boolean (*table_set_row)
875  (cpl_table *, const char *, int,
876  const cpl_frame *,
877  const cpl_parameterlist *),
878  cpl_error_code (*table_check)
879  (cpl_table *,
880  const cpl_frameset *,
881  const cpl_parameterlist *))
882 {
883 
884  const char * filename;
885  cpl_propertylist * applist = NULL;
886  cpl_errorstate prestate = cpl_errorstate_get();
887  cpl_error_code error;
888  char * fallback_filename = NULL;
889 
890  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
891  cpl_ensure_code(allframes != NULL, CPL_ERROR_NULL_INPUT);
892  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
893  cpl_ensure_code(procatg != NULL, CPL_ERROR_NULL_INPUT);
894  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
895  cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
896  cpl_ensure_code(instrume != NULL, CPL_ERROR_NULL_INPUT);
897  cpl_ensure_code(pipe_id != NULL, CPL_ERROR_NULL_INPUT);
898 
899  cpl_ensure_code(!irplib_table_read_from_frameset(self, useframes,
900  maxlinelen,
901  commentchar,
902  parlist,
903  table_set_row),
904  cpl_error_get_code());
905 
906  if (table_check != NULL && (table_check(self, useframes, parlist) ||
907  !cpl_errorstate_is_equal(prestate))) {
908  return cpl_error_set_message(cpl_func, cpl_error_get_code(),
909  "Consistency check of table failed");
910  }
911 
912  fallback_filename = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
913  filename = product_name != NULL ? product_name : fallback_filename;
914 
915  applist = mainlist == NULL
916  ? cpl_propertylist_new() : cpl_propertylist_duplicate(mainlist);
917 
918  error = cpl_propertylist_update_string(applist, "INSTRUME", instrume);
919 
920  if (!error)
921  error = irplib_dfs_save_table(allframes, parlist, useframes, self,
922  extlist, recipe_name, procatg, applist,
923  remregexp, pipe_id, filename);
924 
925  cpl_propertylist_delete(applist);
926  cpl_free(fallback_filename);
927 
928  /* Propagate the error, if any */
929  cpl_ensure_code(!error, error);
930 
931  return CPL_ERROR_NONE;
932 
933 }
934 
935 
936 
937 /*----------------------------------------------------------------------------*/
986 /*----------------------------------------------------------------------------*/
987 
988 cpl_error_code
990  const cpl_frameset * useframes,
991  int maxlinelen,
992  char commentchar,
993  const cpl_parameterlist * parlist,
994  cpl_boolean (*table_set_row)
995  (cpl_table *, const char *, int,
996  const cpl_frame *,
997  const cpl_parameterlist *))
998 {
999 
1000  const cpl_frame * rawframe;
1001  char * linebuffer = NULL;
1002  FILE * stream = NULL;
1003  int nfiles = 0;
1004  int nrow = cpl_table_get_nrow(self);
1005  int irow = 0;
1006  cpl_errorstate prestate = cpl_errorstate_get();
1007  cpl_frameset_iterator * iterator = NULL;
1008 
1009  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
1010  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
1011  cpl_ensure_code(maxlinelen > 0, CPL_ERROR_ILLEGAL_INPUT);
1012  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
1013  cpl_ensure_code(table_set_row != NULL, CPL_ERROR_NULL_INPUT);
1014 
1015  linebuffer = cpl_malloc(maxlinelen);
1016 
1017  for (rawframe = irplib_frameset_get_first_const(&iterator, useframes);
1018  rawframe != NULL;
1019  rawframe = irplib_frameset_get_next_const(iterator), nfiles++) {
1020 
1021  const char * rawfile = cpl_frame_get_filename(rawframe);
1022  const char * done; /* Indicate when the reading is done */
1023  const int irowpre = irow;
1024  int iirow = 0;
1025  int ierror;
1026 
1027  if (rawfile == NULL) break; /* Should not happen... */
1028 
1029  stream = fopen(rawfile, "r");
1030 
1031  if (stream == NULL) {
1032 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1033  cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
1034  "open %s for reading", rawfile);
1035 #else
1036  cpl_error_set_message(cpl_func, CPL_ERROR_FILE_IO, "Could not "
1037  "open file for reading");
1038 #endif
1039  break;
1040  }
1041 
1042  for (;(done = fgets(linebuffer, maxlinelen, stream)) != NULL; iirow++) {
1043 
1044  if (linebuffer[0] != commentchar) {
1045  cpl_boolean didset;
1046 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1047  const int prerow = irow;
1048 #endif
1049 
1050  if (irow == nrow) {
1051  nrow += nrow ? nrow : 1;
1052  if (cpl_table_set_size(self, nrow)) break;
1053  }
1054 
1055  didset = table_set_row(self, linebuffer, irow, rawframe,
1056  parlist);
1057  if (didset) irow++;
1058 
1059  if (!cpl_errorstate_is_equal(prestate)) {
1060  if (didset)
1061 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1062  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1063  "Failed to set table row %d "
1064  "using line %d from %d. file %s",
1065  1+prerow, iirow+1,
1066  nfiles+1, rawfile);
1067  else
1068  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1069  "Failure with line %d from %d. "
1070  "file %s", iirow+1,
1071  nfiles+1, rawfile);
1072 #else
1073  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1074  "Failed to set table row"
1075  "using catalogue line");
1076  else
1077  cpl_error_set_message(cpl_func, cpl_error_get_code(),
1078  "Failure with catalogue line");
1079 #endif
1080 
1081  break;
1082  }
1083  }
1084  }
1085  if (done != NULL) break;
1086 
1087  ierror = fclose(stream);
1088  stream = NULL;
1089  if (ierror) break;
1090 
1091 
1092  if (irow == irowpre)
1093  cpl_msg_warning(cpl_func, "No usable lines in the %d. file: %s",
1094  1+nfiles, rawfile);
1095  }
1096 
1097  cpl_frameset_iterator_delete(iterator);
1098  cpl_free(linebuffer);
1099  if (stream != NULL) fclose(stream);
1100 
1101  /* Check for premature end */
1102  cpl_ensure_code(rawframe == NULL, cpl_error_get_code());
1103 
1104  if (irow == 0) {
1105 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1106  return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1107  "No usable lines in the %d input "
1108  "frame(s)", nfiles);
1109 #else
1110  return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1111  "No usable lines in the input frame(s)");
1112 #endif
1113  }
1114 
1115  /* Resize the table to the actual number of rows set */
1116  cpl_ensure_code(!cpl_table_set_size(self, irow), cpl_error_get_code());
1117 
1118  return CPL_ERROR_NONE;
1119 }
1120 
1121 
1122 
1123 /*----------------------------------------------------------------------------*/
1135 /*----------------------------------------------------------------------------*/
1136 void irplib_reset(void)
1137 {
1138  return;
1139 }
1140 
1141 /*----------------------------------------------------------------------------*/
1148 /*----------------------------------------------------------------------------*/
1150  cpl_frame * frame1,
1151  cpl_frame * frame2)
1152 {
1153  const char * v1 ;
1154  const char * v2 ;
1155 
1156  /* Test entries */
1157  if (frame1==NULL || frame2==NULL) return -1 ;
1158 
1159  /* Get the tags */
1160  if ((v1 = cpl_frame_get_tag(frame1)) == NULL) return -1 ;
1161  if ((v2 = cpl_frame_get_tag(frame2)) == NULL) return -1 ;
1162 
1163  /* Compare the tags */
1164  if (strcmp(v1, v2)) return 0 ;
1165  else return 1 ;
1166 }
1167 
1168 /*----------------------------------------------------------------------------*/
1184 /*----------------------------------------------------------------------------*/
1185 const char * irplib_frameset_find_file(const cpl_frameset * self,
1186  const char * tag)
1187 {
1188  const cpl_frame * frame = cpl_frameset_find_const(self, tag);
1189 
1190 
1191  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1192 
1193  if (frame == NULL) return NULL;
1194 
1195  if (cpl_frameset_find_const(self, NULL))
1196  cpl_msg_warning(cpl_func,
1197  "Frameset has more than one file with tag: %s",
1198  tag);
1199 
1200  return cpl_frame_get_filename(frame);
1201 
1202 }
1203 
1204 /*----------------------------------------------------------------------------*/
1214 /*----------------------------------------------------------------------------*/
1215 const
1216 cpl_frame * irplib_frameset_get_first_from_group(const cpl_frameset * self,
1217  cpl_frame_group group)
1218 {
1219  const cpl_frame * frame;
1220  cpl_frameset_iterator * iterator = NULL;
1221 
1222  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1223 
1224  for (frame = irplib_frameset_get_first_const(&iterator, self);
1225  frame != NULL ;
1226  frame = irplib_frameset_get_next_const(iterator)) {
1227  if (cpl_frame_get_group(frame) == group) break;
1228  }
1229  cpl_frameset_iterator_delete(iterator);
1230  return frame;
1231 }
1232 
1233 /*----------------------------------------------------------------------------*/
1252 /*----------------------------------------------------------------------------*/
1253 cpl_error_code irplib_apertures_find_max_flux(const cpl_apertures * self,
1254  int * ind, int nfind)
1255 {
1256  const int nsize = cpl_apertures_get_size(self);
1257  int ifind;
1258 
1259 
1260  cpl_ensure_code(nsize > 0, cpl_error_get_code());
1261  cpl_ensure_code(ind, CPL_ERROR_NULL_INPUT);
1262  cpl_ensure_code(nfind > 0, CPL_ERROR_ILLEGAL_INPUT);
1263  cpl_ensure_code(nfind <= nsize, CPL_ERROR_ILLEGAL_INPUT);
1264 
1265  for (ifind=0; ifind < nfind; ifind++) {
1266  double maxflux = -1;
1267  int maxind = -1;
1268  int i;
1269  for (i=1; i <= nsize; i++) {
1270  int k;
1271 
1272  /* The flux has to be the highest among those not already found */
1273  for (k=0; k < ifind; k++) if (ind[k] == i) break;
1274 
1275  if (k == ifind) {
1276  /* i has not been inserted into ind */
1277  const double flux = cpl_apertures_get_flux(self, i);
1278 
1279  if (maxind < 0 || flux > maxflux) {
1280  maxind = i;
1281  maxflux = flux;
1282  }
1283  }
1284  }
1285  ind[ifind] = maxind;
1286  }
1287 
1288  return CPL_ERROR_NONE;
1289 
1290 }
1291 
1296 /*----------------------------------------------------------------------------*/
1307 /*----------------------------------------------------------------------------*/
1308 inline static
1309 double irplib_data_get_double(const void * self, cpl_type type, int i)
1310 {
1311 
1312  double value;
1313 
1314 
1315  switch (type) {
1316  case CPL_TYPE_FLOAT:
1317  {
1318  const float * pself = (const float*)self;
1319  value = (double)pself[i];
1320  break;
1321  }
1322  case CPL_TYPE_INT:
1323  {
1324  const int * pself = (const int*)self;
1325  value = (double)pself[i];
1326  break;
1327  }
1328  default: /* case CPL_TYPE_DOUBLE */
1329  {
1330  const double * pself = (const double*)self;
1331  value = pself[i];
1332  break;
1333  }
1334  }
1335 
1336  return value;
1337 
1338 }
1339 
1340 
1341 /*----------------------------------------------------------------------------*/
1352 /*----------------------------------------------------------------------------*/
1353 inline static
1354 void irplib_data_set_double(void * self, cpl_type type, int i, double value)
1355 {
1356 
1357  switch (type) {
1358  case CPL_TYPE_FLOAT:
1359  {
1360  float * pself = (float*)self;
1361  pself[i] = (float)value;
1362  break;
1363  }
1364  case CPL_TYPE_INT:
1365  {
1366  int * pself = (int*)self;
1367  pself[i] = (int)value;
1368  break;
1369  }
1370  default: /* case CPL_TYPE_DOUBLE */
1371  {
1372  double * pself = (double*)self;
1373  pself[i] = value;
1374  break;
1375  }
1376  }
1377 }
1378 
1379 
1380 
1381 
1382 
1383 /*----------------------------------------------------------------------------*/
1394 /*----------------------------------------------------------------------------*/
1395 static
1396 void irplib_errorstate_dump_one_level(void (*messenger)(const char *,
1397  const char *, ...),
1398  unsigned self, unsigned first,
1399  unsigned last)
1400 {
1401 
1402  const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
1403  const unsigned newest = is_reverse ? first : last;
1404  const unsigned oldest = is_reverse ? last : first;
1405  const char * revmsg = is_reverse ? " in reverse order" : "";
1406 
1407 
1408  /*
1409  cx_assert( messenger != NULL );
1410  cx_assert( oldest <= self );
1411  cx_assert( newest >= self );
1412  */
1413 
1414  if (newest == 0) {
1415  messenger(cpl_func, "No error(s) to dump");
1416  /* cx_assert( oldest == 0); */
1417  } else {
1418  /*
1419  cx_assert( oldest > 0);
1420  cx_assert( newest >= oldest);
1421  */
1422  if (self == first) {
1423  if (oldest == 1) {
1424  messenger(cpl_func, "Dumping all %u error(s)%s:", newest,
1425  revmsg);
1426  } else {
1427  messenger(cpl_func, "Dumping the %u most recent error(s) "
1428  "out of a total of %u errors%s:",
1429  newest - oldest + 1, newest, revmsg);
1430  }
1431  cpl_msg_indent_more();
1432  }
1433 
1434  messenger(cpl_func, "[%u/%u] '%s' (%u) at %s", self, newest,
1435  cpl_error_get_message(), cpl_error_get_code(),
1436  cpl_error_get_where());
1437 
1438  if (self == last) cpl_msg_indent_less();
1439  }
1440 }
1441 
1442 cpl_polynomial * irplib_polynomial_fit_1d_create_chiq(
1443  const cpl_vector * x_pos,
1444  const cpl_vector * values,
1445  int degree,
1446  double * rechisq
1447  )
1448  {
1449  return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, NULL, rechisq);
1450  }
1451 cpl_polynomial * irplib_polynomial_fit_1d_create(
1452  const cpl_vector * x_pos,
1453  const cpl_vector * values,
1454  int degree,
1455  double * mse
1456  )
1457 {
1458 
1459  return irplib_polynomial_fit_1d_create_common(x_pos, values, degree, mse, NULL);
1460 }
1461 static cpl_polynomial * irplib_polynomial_fit_1d_create_common(
1462  const cpl_vector * x_pos,
1463  const cpl_vector * values,
1464  int degree,
1465  double * mse,
1466  double * rechisq
1467  )
1468 {
1469  cpl_polynomial * fit1d = NULL;
1470  cpl_size loc_degree = (cpl_size)degree ;
1471  int x_size = 0;
1472  fit1d = cpl_polynomial_new(1);
1473  x_size = cpl_vector_get_size(x_pos);
1474  if(fit1d != NULL && x_size > 1)
1475  {
1476  cpl_matrix * samppos = NULL;
1477  cpl_vector * fitresidual = NULL;
1478  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1479  samppos = cpl_matrix_wrap(1, x_size,
1480  (double*)cpl_vector_get_data_const(x_pos));
1481  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1482  fitresidual = cpl_vector_new(x_size);
1483  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1484  cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
1485  CPL_FALSE, NULL, &loc_degree);
1486  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1487  cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL,
1488  fit1d, samppos, rechisq);
1489  cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
1490  if (mse)
1491  {
1492  *mse = cpl_vector_product(fitresidual, fitresidual)
1493  / cpl_vector_get_size(fitresidual);
1494  }
1495  cpl_matrix_unwrap(samppos);
1496  cpl_vector_delete(fitresidual);
1497  }
1498  return fit1d;
1499 }
1500 
1501 static void quicksort(int* iindex, double* exptime, int left, int right)
1502 {
1503  int i = left;
1504  int j = right;
1505  int pivot = (i + j) / 2;
1506  double index_value = exptime[pivot];
1507  do
1508  {
1509  while(exptime[i] < index_value) i++;
1510  while(exptime[j] > index_value) j--;
1511  if (i <= j)
1512  {
1513  if(i < j)
1514  {
1515  int tmp = iindex[i];
1516  double dtmp = exptime[i];
1517  iindex[i]=iindex[j];
1518  iindex[j]=tmp;
1519  exptime[i] = exptime[j];
1520  exptime[j] = dtmp;
1521  }
1522  i++;
1523  j--;
1524  }
1525  } while (i <= j);
1526 
1527  if (i < right)
1528  {
1529  quicksort(iindex, exptime, i, right);
1530  }
1531  if (left < j)
1532  {
1533  quicksort(iindex, exptime,left, j);
1534  }
1535 }
1536 cpl_error_code irplib_frameset_sort(const cpl_frameset * self, int* iindex, double* exptime)
1537 {
1538  int i = 0;
1539  const cpl_frame* tmp_frame = 0;
1540  cpl_error_code error = CPL_ERROR_NONE;
1541  int sz = cpl_frameset_get_size(self);
1542  cpl_frameset_iterator* iterator = NULL;
1543 
1544  /* 1. get an array of frames */
1545  tmp_frame = irplib_frameset_get_first_const(&iterator, self);
1546  while(tmp_frame)
1547  {
1548  exptime[i] = frame_get_exptime(tmp_frame);
1549  iindex[i] = i;
1550  tmp_frame = irplib_frameset_get_next_const(iterator);
1551  i++;
1552  }
1553  cpl_frameset_iterator_delete(iterator);
1554  /* 2.sort */
1555  quicksort(iindex, exptime, 0, sz - 1);
1556 
1557  return error;
1558 }
1559 
1560 static double frame_get_exptime(const cpl_frame * pframe)
1561 {
1562  double dval = 0;
1563  cpl_propertylist * plist =
1564  cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe), 0,
1565  "EXPTIME", CPL_FALSE);
1566  if(plist) {
1567  dval = cpl_propertylist_get_double(plist, "EXPTIME");
1568  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1569  cpl_msg_error(cpl_func, "error during reading EXPTIME key from "
1570  "the frame [%s]", cpl_frame_get_filename(pframe));
1571  }
1572  }
1573  /* Free and return */
1574  cpl_propertylist_delete(plist);
1575  return dval;
1576 }
1577 
1578 
1579 /*----------------------------------------------------------------------------*/
1593 /*----------------------------------------------------------------------------*/
1594 void * irplib_aligned_malloc(size_t alignment, size_t size)
1595 {
1596 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
1597  return aligned_alloc(alignment, size);
1598 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1599  void *ptr;
1600  if (alignment == 1)
1601  return malloc (size);
1602  if (alignment == 2 || (sizeof (void *) == 8 && alignment == 4))
1603  alignment = sizeof (void *);
1604  if (posix_memalign (&ptr, alignment, size) == 0)
1605  return ptr;
1606  else
1607  return NULL;
1608 #else
1609  /* copied from gmm_malloc.h in gcc-4.8 */
1610  void * malloc_ptr;
1611  void * aligned_ptr;
1612 
1613  /* Error if align is not a power of two. */
1614  if (alignment & (alignment - 1)) {
1615  errno = EINVAL;
1616  return NULL;
1617  }
1618 
1619  if (size == 0)
1620  return NULL;
1621 
1622  /* Assume malloc'd pointer is aligned at least to sizeof (void*).
1623  If necessary, add another sizeof (void*) to store the value
1624  returned by malloc. Effectively this enforces a minimum alignment
1625  of sizeof double. */
1626  if (alignment < 2 * sizeof (void *))
1627  alignment = 2 * sizeof (void *);
1628 
1629  malloc_ptr = malloc (size + alignment);
1630  if (!malloc_ptr)
1631  return NULL;
1632 
1633  /* Align We have at least sizeof (void *) space below malloc'd ptr. */
1634  aligned_ptr = (void *) (((size_t) malloc_ptr + alignment)
1635  & ~((size_t) (alignment) - 1));
1636 
1637  /* Store the original pointer just before p. */
1638  *(((void **) aligned_ptr) - 1) = malloc_ptr;
1639 
1640  return aligned_ptr;
1641 #endif
1642 }
1643 
1644 
1645 /*----------------------------------------------------------------------------*/
1655 /*----------------------------------------------------------------------------*/
1656 void * irplib_aligned_calloc(size_t alignment, size_t nelem, size_t nbytes)
1657 {
1658  void * buffer = irplib_aligned_malloc(alignment, nelem * nbytes);
1659  if (buffer == NULL)
1660  return NULL;
1661  /* cast to aligned pointer helps compilers to emit better (builtin) code */
1662  memset((size_t *)buffer, 0, nelem * nbytes);
1663  return buffer;
1664 }
1665 
1666 
1667 /*----------------------------------------------------------------------------*/
1675 /*----------------------------------------------------------------------------*/
1676 void irplib_aligned_free (void * aligned_ptr)
1677 {
1678 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
1679  free(aligned_ptr);
1680 #elif defined HAVE_POSIX_MEMALIGN && defined HAVE_DECL_POSIX_MEMALIGN
1681  free(aligned_ptr);
1682 #else
1683  if (aligned_ptr)
1684  free (*(((void **) aligned_ptr) - 1));
1685 #endif
1686 }
1687 
1688 
1689 /*----------------------------------------------------------------------------*/
1702 /*----------------------------------------------------------------------------*/
1703 const cpl_frame *
1704 irplib_frameset_get_first_const(cpl_frameset_iterator **iterator,
1705  const cpl_frameset *frameset)
1706 {
1707  cpl_ensure(iterator != NULL, CPL_ERROR_NULL_INPUT, NULL);
1708  *iterator = cpl_frameset_iterator_new(frameset);
1709  return cpl_frameset_iterator_get_const(*iterator);
1710 }
1711 
1712 /*----------------------------------------------------------------------------*/
1721 /*----------------------------------------------------------------------------*/
1722 const cpl_frame *
1723 irplib_frameset_get_next_const(cpl_frameset_iterator *iterator)
1724 {
1725  cpl_errorstate prestate = cpl_errorstate_get();
1726  cpl_error_code error = cpl_frameset_iterator_advance(iterator, 1);
1727  if (error == CPL_ERROR_ACCESS_OUT_OF_RANGE) {
1728  cpl_errorstate_set(prestate);
1729  return NULL;
1730  } else if (error != CPL_ERROR_NONE) {
1731  return NULL;
1732  }
1733  return cpl_frameset_iterator_get_const(iterator);
1734 }
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:351
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:460
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:157
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:989
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:256
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:411
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:860
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:130
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:177
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:208
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:665
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:303