MUSE Pipeline Reference Manual  2.1.1
muse_badpix_from_dq.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set sw=2 sts=2 et cin: */
3 /*
4  * This file is part of the MUSE Instrument Pipeline
5  * Copyright (C) 2007-2014 European Southern Observatory
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include <muse.h>
23 #include <string.h>
24 
25 /*----------------------------------------------------------------------------*/
54 /*----------------------------------------------------------------------------*/
55 
58 #define PRINT_USAGE(rc) \
59  fprintf(stderr, "Usage: %s [ -i INTABLE ] INFILE OUTTABLE\n", argv[0]); \
60  cpl_end(); return (rc);
61 
62 int main(int argc, char **argv)
63 {
64  cpl_init(CPL_INIT_DEFAULT);
66  if (argc <= 2) {
67  /* two filenames are needed at least */
68  PRINT_USAGE(1);
69  }
70 
71  if (getenv("ESOREX_MSG_LEVEL") && !strncmp(getenv("ESOREX_MSG_LEVEL"),
72  "debug", 6)) {
73  cpl_msg_set_level(CPL_MSG_DEBUG);
74  }
75 
76  char *iname = NULL, /* input image */
77  *tiname = NULL, /* optional input table */
78  *toname = NULL; /* output table */
79 
80  /* argument processing */
81  int i;
82  for (i = 1; i < argc; i++) {
83  if (strncmp(argv[i], "-i", 3) == 0) {
84  /* skip to next arg to input table filename */
85  i++;
86  if (i < argc) {
87  tiname = argv[i];
88  } else {
89  PRINT_USAGE(2);
90  }
91  } else if (strncmp(argv[i], "-", 1) == 0) { /* unallowed options */
92  PRINT_USAGE(9);
93  } else {
94  if (iname && toname) {
95  break; /* we have the possible names, skip the rest */
96  }
97  if (!iname) {
98  iname = argv[i]; /* set the name for the input image */
99  } else {
100  toname = argv[i]; /* set the name for the output table */
101  }
102  }
103  } /* for i (all arguments) */
104 
105  int extension = cpl_fits_find_extension(iname, EXTNAME_DQ);
106  cpl_image *image = cpl_image_load(iname, CPL_TYPE_INT, 0, extension);
107  if (!image) {
108  PRINT_USAGE(10);
109  }
110  /* load main headers */
111  cpl_propertylist *header = cpl_propertylist_load(iname, 0);
112  int nx = cpl_image_get_size_x(image),
113  ny = cpl_image_get_size_y(image);
114  unsigned char nifu = muse_utils_get_ifu(header);
115  printf("Read %dx%d image of IFU %hhu from \"%s\"\n", nx, ny, nifu, iname);
116 
117  /* part1: ======================================= *
118  * convert the DQ from the image into a new table */
119  cpl_table *table = muse_quality_convert_dq(image);
120 #if 0
121  cpl_table_dump(table, 0, 1000, stdout);
122  fflush(stdout);
123 #endif
124  cpl_size nrow = cpl_table_get_nrow(table);
125  printf("%"CPL_SIZE_FORMAT" bad pixel%s found\n", nrow, nrow != 1 ? "s" : "");
126 
127  /* part2: ============================================ *
128  * load and handle the input badpix table if it exists */
129  if (tiname) { /* try to open the input table, verify that it really exists */
130  cpl_propertylist *htest = cpl_propertylist_load(tiname, 0);
131  if (htest) {
132  cpl_propertylist_delete(htest);
133  } else {
134  printf("WARNING: could not open input table \"%s\"!\n", tiname);
135  tiname = NULL; /* it doesn't exist, don't keep the name */
136  } /* else */
137  } /* if tiname */
138 
139  /* merge created table with existing one, if there is one */
140  cpl_table *intable = NULL;
141  int inext = -1;
142  if (tiname) {
143  char *extifu = cpl_sprintf("CHAN%02hhu", nifu);
144  intable = muse_quality_merge_badpix_from_file(table, tiname, extifu, &inext);
145  cpl_free(extifu);
146  if (!intable) {
147  intable = table;
148  } /* if !intable */
149  } /* if tiname */
150  /* copy the input BADPIX_TABLE, replacing the one extension we modified */
151  muse_quality_copy_badpix_table(tiname, toname, inext, intable);
152 
153  /* save or append the extension if not already done above */
154  if (inext < 0) {
155  cpl_propertylist *pheader = NULL;
156  /* create a primary header, if we create a new file */
157  if (!tiname) {
158  pheader = cpl_propertylist_load_regexp(iname, 0, "TELESCOP|INSTRUME|"
159  "ESO DET ", 0);
160  /* remove exposure-specifc info and the stuff about *
161  * CHIP and OUTi again, that belongs into the extension */
162  cpl_propertylist_erase_regexp(pheader, "ESO DET DEV[0-9] (SHUT |EXP )|"
163  "ESO DET (EXP |[DU]IT|NDIT|DKTM)", 0);
164  cpl_propertylist_erase_regexp(pheader, "ESO DET (CHIP |OUT[1-4])", 0);
165  cpl_propertylist_update_string(pheader, "OBJECT",
166  "Bad pixel table for MUSE (BADPIX_TABLE)");
167  cpl_propertylist_update_string(pheader, "PIPEFILE", toname);
168  cpl_propertylist_set_comment(pheader, "PIPEFILE",
169  "pretend to be a pipeline output file");
170  } /* if !tiname */
171  /* for saving, cut the extension header to the necessary *
172  * information of extension name and about CHIP and OUTi */
173  cpl_propertylist_erase_regexp(header, "^EXT|ESO DET (CHIP |OUT[1-4])", 1);
174  /* create new file if necessary or append to the file saved above */
175  cpl_error_code rc = cpl_table_save(table, pheader, header, toname,
176  pheader ? CPL_IO_CREATE : CPL_IO_EXTEND);
177  if (rc != CPL_ERROR_NONE) {
178  fprintf(stderr, "Saving to \"%s\" failed (rc=%d): %s\n", toname, rc,
179  cpl_error_get_message());
180  } else {
181  printf("Saved to \"%s\"\n", toname);
182  }
183  cpl_propertylist_delete(pheader); /* in case it was created */
184  } /* if inext < 0 (not saved yet) */
185  cpl_table_delete(table);
186  cpl_image_delete(image);
187  cpl_propertylist_delete(header);
188 
189  if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
190  printf("Output file \"%s\" has primary header and %"CPL_SIZE_FORMAT
191  " extensions\n", toname, cpl_fits_count_extensions(toname));
192  cpl_errorstate_dump(0, CPL_FALSE, NULL);
193  cpl_memory_dump();
194  }
195  cpl_end();
196  return 0;
197 }
198 
cpl_table * muse_quality_convert_dq(cpl_image *aDQ)
Convert a data quality (DQ) image extension to a bad pixel table.
Definition: muse_quality.c:511
unsigned char muse_utils_get_ifu(const cpl_propertylist *aHeaders)
Find out the IFU/channel from which this header originated.
Definition: muse_utils.c:98
cpl_error_code muse_quality_copy_badpix_table(const char *aInFile, const char *aOutFile, int aExtension, const cpl_table *aTable)
Copy bad pixel table on disk, replacing the table in one extension.
Definition: muse_quality.c:764
cpl_table * muse_quality_merge_badpix_from_file(const cpl_table *aTable, const char *aInFile, const char *aExtname, int *aExt)
Merge bad pixel table in memory with table from file on disk.
Definition: muse_quality.c:698
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.