MUSE Pipeline Reference Manual  0.18.5
muse_badpix_from_ascii.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 #include <muse_instrument.h>
26 #include "muse_data_format_z.h"
27 
28 /*----------------------------------------------------------------------------*/
78 /*----------------------------------------------------------------------------*/
79 
82 #define PRINT_USAGE(rc) \
83  fprintf(stderr, "Usage: %s [ -i INTABLE ] [ -r REFIMAGE [ -n extname ] ] " \
84  "[ -t ] ASCIIFILE IFUNUM OUTTABLE\n", argv[0]); \
85  cpl_end(); return (rc);
86 
87 int main(int argc, char **argv)
88 {
89  if (argc <= 3) {
90  /* two filenames plus IFU number are needed at least */
91  PRINT_USAGE(1);
92  }
93 
94  cpl_init(CPL_INIT_DEFAULT);
95  if (getenv("ESOREX_MSG_LEVEL") && !strncmp(getenv("ESOREX_MSG_LEVEL"),
96  "debug", 6)) {
97  cpl_msg_set_level(CPL_MSG_DEBUG);
98  }
99 
100  char *fname = NULL, /* input ASCII file */
101  *toname = NULL, /* output table */
102  *riname = NULL, /* optional reference image */
103  *tiname = NULL, /* optional input table */
104  *extname = NULL; /* optional extension name */
105  unsigned char nifu = 0; /* IFU number */
106  cpl_boolean trimmedcoords = CPL_FALSE;
107 
108  /* argument processing */
109  int i;
110  for (i = 1; i < argc; i++) {
111  if (strncmp(argv[i], "-i", 3) == 0) {
112  /* skip to next arg to input table filename */
113  i++;
114  if (i < argc) {
115  tiname = argv[i];
116  } else {
117  PRINT_USAGE(2);
118  }
119  } else if (strncmp(argv[i], "-r", 3) == 0) {
120  /* skip to next arg to input image filename */
121  i++;
122  if (i < argc) {
123  riname = argv[i];
124  } else {
125  PRINT_USAGE(3);
126  }
127  } else if (strncmp(argv[i], "-n", 3) == 0) {
128  /* skip to next arg to get sigma value */
129  i++;
130  if (i < argc) {
131  extname = argv[i];
132  } else {
133  PRINT_USAGE(5);
134  }
135  } else if (strncmp(argv[i], "-t", 3) == 0) {
136  /* skip to next arg to get sigma value */
137  trimmedcoords = CPL_TRUE;
138  } else if (strncmp(argv[i], "-", 1) == 0) { /* unallowed options */
139  PRINT_USAGE(9);
140  } else {
141  if (fname && toname) {
142  break; /* we have the possible names, skip the rest */
143  }
144  if (!fname) {
145  fname = argv[i]; /* set the name for the input ASCII file */
146  } else if (nifu == 0) {
147  int ifunum = atoi(argv[i]);
148  if (ifunum < 1 || ifunum > kMuseNumIFUs) {
149  PRINT_USAGE(9);
150  }
151  nifu = ifunum;
152  } else {
153  toname = argv[i]; /* set the name for the output table */
154  }
155  }
156  } /* for i (all arguments) */
157 
158  /* open the ASCII input file to verify its existence */
159  FILE *fp = fopen(fname, "r");
160  if (!fp) {
161  PRINT_USAGE(10);
162  }
163 
164  /* part1: ======================================= *
165  * convert the ASCII file into a new table */
166  if (trimmedcoords) {
167  printf("Converting coordinates from trimmed to raw data dimensions\n");
168  }
169 #define START_SIZE 10000
170  cpl_table *table = muse_cpltable_new(muse_badpix_table_def, START_SIZE);
171  cpl_size irow = 0, nrow = cpl_table_get_nrow(table);
172  int ix, iy, idq;
173  while (fscanf(fp, "%d %d %d", &ix, &iy, &idq) == 3) {
174  if (irow >= nrow) {
175  cpl_table_set_size(table, nrow + START_SIZE);
176  nrow = cpl_table_get_nrow(table);
177  } /* if index too large */
178  if (trimmedcoords) {
179  muse_quadrants_coords_to_raw(NULL, &ix, &iy);
180  }
181  cpl_table_set_int(table, MUSE_BADPIX_X, irow, ix);
182  cpl_table_set_int(table, MUSE_BADPIX_Y, irow, iy);
183  cpl_table_set_int(table, MUSE_BADPIX_DQ, irow++, idq);
184  } /* while lines to scan */
185  cpl_table_set_size(table, irow);
186  printf("%"CPL_SIZE_FORMAT" bad pixel%s read from \"%s\"\n", irow,
187  irow != 1 ? "s" : "", fname);
188  fclose(fp);
189  if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
190  printf("first 10 entries of the new table, as converted from ASCII:\n");
191  cpl_table_dump(table, 0, 10, stdout);
192  fflush(stdout);
193  }
194 
195  /* part2: ============================================ *
196  * load and handle the input badpix table if it exists */
197  if (tiname) { /* try to open the input table, verify that it really exists */
198  cpl_propertylist *htest = cpl_propertylist_load(tiname, 0);
199  if (htest) {
200  cpl_propertylist_delete(htest);
201  } else {
202  printf("WARNING: could not open input table \"%s\"!\n", tiname);
203  tiname = NULL; /* it doesn't exist, don't keep the name */
204  } /* else */
205  } /* if tiname */
206 
207  /* merge created table with existing one, if there is one */
208  char *chan = cpl_sprintf("CHAN%02hhu", nifu);
209  cpl_table *intable = NULL;
210  int inext = -1;
211  if (tiname) {
212  cpl_errorstate state = cpl_errorstate_get();
213  intable = muse_quality_merge_badpix_from_file(table, tiname, chan, &inext);
214  if (!intable) {
215  cpl_errorstate_set(state);
216  intable = table;
217  } /* if !intable */
218  } /* if tiname */
219  /* copy the input BADPIX_TABLE, maybe replacing the one extension we modified */
220  cpl_error_code rc = muse_quality_copy_badpix_table(tiname, toname, inext,
221  intable);
222  cpl_boolean savedsomething = rc == CPL_ERROR_NONE;
223 
224  /* save or append the extension if not already done above */
225  inext = cpl_fits_find_extension(toname, chan);
226  if (inext <= 0) {
227  cpl_propertylist *pheader = NULL,
228  *header = NULL;
229  if (!riname) {
230  printf("WARNING: no pre-existing data, creating minimal header from "
231  "scratch!\n");
232  pheader = cpl_propertylist_new();
233  cpl_propertylist_append_string(pheader, "TELESCOP", "ESO-VLT-U4");
234  cpl_propertylist_append_string(pheader, "INSTRUME", "MUSE");
235  cpl_propertylist_append_string(pheader, "OBJECT",
236  "Bad pixel table for MUSE (BADPIX_TABLE)");
237  header = cpl_propertylist_new();
238  cpl_propertylist_append_string(header, "EXTNAME", chan);
239  cpl_propertylist_append_string(header, "ESO DET CHIP NAME", chan);
240  } else {
241  printf("Using primary header from \"%s\" as starting point\n", riname);
242  pheader = cpl_propertylist_load_regexp(riname, 0, "TELESCOP|INSTRUME|"
243  "ESO DET ", 0);
244  /* remove exposure-specifc info and the stuff about *
245  * CHIP and OUTi again, that belongs into the extension */
246  cpl_propertylist_erase_regexp(pheader, "ESO DET DEV[0-9] (SHUT |EXP )|"
247  "ESO DET (EXP |[DU]IT|NDIT|DKTM)", 0);
248  cpl_propertylist_erase_regexp(pheader, "ESO DET (CHIP |OUT[1-4])", 0);
249  cpl_propertylist_update_string(pheader, "OBJECT",
250  "Bad pixel table for MUSE (BADPIX_TABLE)");
251  int refext = cpl_fits_find_extension(riname, extname);
252  if (refext >= 0) {
253  printf("Using extension header from \"%s[%s]\" (%d)\n", riname, extname,
254  refext);
255  header = cpl_propertylist_load_regexp(riname, refext,
256  "^EXT|ESO DET (CHIP |OUT[1-4])", 0);
257  } else {
258  printf("WARNING: no pre-existing extension found, creating minimal "
259  "extension header from scratch!\n");
260  header = cpl_propertylist_new();
261  cpl_propertylist_append_string(header, "EXTNAME", chan);
262  cpl_propertylist_append_string(header, "ESO DET CHIP NAME", chan);
263  }
264  }
265  if (savedsomething) {
266  /* just extend the already saved data with the new extension */
267  rc = cpl_table_save(table, NULL, header, toname, CPL_IO_EXTEND);
268  } else {
269  /* save the whole file, overwriting what may be there under that name */
270  cpl_propertylist_update_string(pheader, "PIPEFILE", toname);
271  cpl_propertylist_set_comment(pheader, "PIPEFILE",
272  "pretend to be a pipeline output file");
273  cpl_propertylist_update_string(pheader, "ESO PRO CATG", MUSE_TAG_BADPIX_TABLE);
274  cpl_propertylist_set_comment(pheader, "ESO PRO CATG",
275  "MUSE bad pixel table");
276  rc = cpl_table_save(table, pheader, header, toname, CPL_IO_CREATE);
277  }
278  if (rc != CPL_ERROR_NONE) {
279  fprintf(stderr, "Saving to \"%s\" failed (rc=%d): %s\n", toname, rc,
280  cpl_error_get_message());
281  } else {
282  printf("Saved to \"%s\" (%s)\n", toname,
283  savedsomething ? "new extension" : "new file");
284  }
285  cpl_propertylist_delete(pheader);
286  cpl_propertylist_delete(header);
287  } /* if new table now saved yet */
288  cpl_free(chan);
289  cpl_table_delete(table);
290 
291  if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
292  printf("Output file \"%s\" has primary header and %"CPL_SIZE_FORMAT
293  " extensions\n", toname, cpl_fits_count_extensions(toname));
294  cpl_errorstate_dump(0, CPL_FALSE, NULL);
295  cpl_memory_dump();
296  fflush(NULL);
297  }
298  cpl_end();
299  return 0;
300 }
301 
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:759
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:693
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
const muse_cpltable_def muse_badpix_table_def[]
cpl_error_code muse_quadrants_coords_to_raw(cpl_propertylist *aHeader, int *aX, int *aY)
Convert coordinates of a trimmed image to raw-image coordinates.