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