MUSE Pipeline Reference Manual  2.1.1
muse_offset_list_create.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) 2015 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 /*----------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------*/
62 
65 #define PRINT_USAGE(rc) \
66  fprintf(stderr, "Usage: %s [ -f ] [ -s SOFFILE ] OFFSET_LIST " \
67  "[ FILE [ FILE [ ... ] ] ] \n", argv[0]); \
68  cpl_end(); return (rc);
69 
70 int main(int argc, char **argv)
71 {
72  const char *idstring = "muse_offset_list_create";
73  cpl_init(CPL_INIT_DEFAULT);
74  cpl_msg_set_time_on();
76  cpl_msg_set_level(CPL_MSG_DEBUG);
77  cpl_msg_set_component_on();
78  cpl_errorstate state = cpl_errorstate_get();
79 
80  if (argc < 2) {
81  /* one filename is needed at least */
82  PRINT_USAGE(1);
83  }
84 
85  char *oname = NULL; /* output filename */
86  cpl_array *files = NULL, /* file names */
87  *soffiles = NULL; /* file names from .sof */
88  cpl_boolean overwrite = CPL_FALSE;
89  int i;
90 
91  /* argument processing */
92  for (i = 1; i < argc; i++) {
93  if (strncmp(argv[i], "-s", 3) == 0) {
94  /* skip to next arg to name of the .sof file */
95  i++;
96  if (i < argc) {
97  FILE *fp = fopen(argv[i], "r");
98  if (!fp) {
99  PRINT_USAGE(3);
100  }
101  if (!soffiles) {
102  soffiles = cpl_array_new(0, CPL_TYPE_STRING);
103  }
104  char fn[4096],
105  tag[50];
106  while (fscanf(fp, "%4095s %49s", fn, tag) != EOF) {
107  if (!strncmp(tag, "PIXTABLE_", 9)) {
108 #if 0 /* DEBUG */
109  cpl_msg_debug(idstring, "IS a pixel table: \"%s\" is %s", fn, tag);
110 #endif
111  /* seems to be a pixel table, use this filename */
112  cpl_array_set_size(soffiles, cpl_array_get_size(soffiles) + 1);
113  /* set the name for this one input file */
114  cpl_array_set_string(soffiles, cpl_array_get_size(soffiles) - 1, fn);
115  } else {
116 #if 0 /* DEBUG */
117  cpl_msg_debug(idstring, "not a pixel table: \"%s\" is %s", fn, tag);
118 #endif
119  }
120  } /* while */
121  fclose(fp);
122  } else {
123  PRINT_USAGE(2);
124  }
125  } else if (strncmp(argv[i], "-f", 3) == 0) {
126  overwrite = CPL_TRUE;
127  } else if (strncmp(argv[i], "-", 1) == 0) { /* unallowed options */
128  PRINT_USAGE(9);
129  } else {
130  if (!oname) {
131  oname = argv[i];
132  } else if (!files) {
133  files = cpl_array_new(1, CPL_TYPE_STRING);
134  /* set the name for this one input file */
135  cpl_array_set_string(files, 0, argv[i]);
136  } else {
137  cpl_array_set_size(files, cpl_array_get_size(files) + 1);
138  /* set the name for this one input file */
139  cpl_array_set_string(files, cpl_array_get_size(files) - 1, argv[i]);
140  }
141  }
142  } /* for i (all arguments) */
143 
144 #if 0 /* DEBUG */
145  printf("files:\n");
146  cpl_array_dump(files, 0, cpl_array_get_size(files), stdout);
147  printf("from .sof:\n");
148  cpl_array_dump(soffiles, 0, cpl_array_get_size(soffiles), stdout);
149  fflush(stdout);
150 #endif
151 
152  /* merge both lists of filenames, if necessary */
153  if (!files) {
154  files = soffiles;
155  } else {
156  if (cpl_array_get_size(soffiles) > 0) {
157  cpl_array_insert(files, soffiles, cpl_array_get_size(files));
158  }
159  cpl_array_delete(soffiles);
160  soffiles = NULL;
161  }
162 
163  /* check that there _is_ and output filename and ensure its *
164  * non-existance (unless we force overwriting it) */
165  if (!oname) {
166  cpl_array_delete(files);
167  PRINT_USAGE(10);
168  }
169  if (!access(oname, F_OK) && !overwrite) {
170  cpl_array_delete(files);
171  PRINT_USAGE(11);
172  }
173 
174  /* create primary header and the table */
175  cpl_propertylist *pheader = cpl_propertylist_new();
176  cpl_propertylist_append_string(pheader, "INSTRUME", "MUSE");
177  cpl_propertylist_append_string(pheader, "ESO PRO CATG", MUSE_TAG_OFFSET_LIST);
178  cpl_table *olist = NULL;
179  int nfiles = 0;
180  if (!files) {
181  cpl_msg_debug(idstring, "No MUSE exposures given on input, creating empty "
182  "table with 10 rows");
184  cpl_propertylist_append_string(pheader, "FILES", "no files given");
185  } else {
186  nfiles = cpl_array_get_size(files);
187  cpl_msg_debug(idstring, "%d MUSE exposures given on input, creating table "
188  "for these", nfiles);
189  olist = muse_cpltable_new(muse_offset_list_def, nfiles);
190  }
191 
192 #if 0
193  /* this doesn't work, because we cannot easily construct a cpl_recipe *
194  * that is valid enough for muse_processing_new() to work */
195  cpl_recipe *recipe = NULL;
196  muse_processing *proc = muse_processing_new("muse_offset_list_create", recipe);
199 #endif
200 
201  /* fill the DATE-OBS and MJD-OBS columns in the table */
202  for (i = 0; i < nfiles; i++) {
203  const char *fn = cpl_array_get_string(files, i);
204  cpl_propertylist *header = cpl_propertylist_load(fn, 0);
205  if (!header) {
206  cpl_msg_warning(idstring, "Could not load primary header from \"%s\"!",
207  fn);
208  continue;
209  }
210  cpl_table_set_string(olist, MUSE_OFFSETS_DATEOBS, i,
211  muse_pfits_get_dateobs(header));
212  cpl_table_set_double(olist, MUSE_OFFSETS_MJDOBS, i,
213  muse_pfits_get_mjdobs(header));
214  cpl_propertylist_delete(header);
215  char *kw = cpl_sprintf("FILE%d", i+1),
216  *p = strrchr(fn, '/');
217  if (p) {
218  p++;
219  } else {
220  p = (char *)fn;
221  }
222  cpl_propertylist_append_string(pheader, kw, p);
223  cpl_free(kw);
224  } /* for i (all files) */
225 
226  /* save the table and clean up */
227  cpl_error_code rc = cpl_table_save(olist, pheader, NULL, oname, CPL_IO_CREATE);
228  cpl_array_delete(files);
229  cpl_table_delete(olist);
230  cpl_propertylist_delete(pheader);
231  switch (rc) {
232  case CPL_ERROR_NONE:
233  rc = 0;
234  cpl_msg_info(idstring, "Saved %s as \"%s\"", MUSE_TAG_OFFSET_LIST, oname);
235  break;
236  case CPL_ERROR_FILE_NOT_CREATED:
237  cpl_msg_error(idstring, "Could not create output file \"%s\"", oname);
238  rc = 12;
239  break;
240  default:
241  rc = 50;
242  cpl_msg_error(idstring, "An unknown error occurred: %s",
243  cpl_error_get_message());
244  } /* switch */
245 
246  if (!cpl_errorstate_is_equal(state)) {
247  cpl_errorstate_dump(state, CPL_FALSE, muse_cplerrorstate_dump_some);
248  }
249  cpl_memory_dump();
250  cpl_end();
251  return rc;
252 }
253 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
const char * muse_pfits_get_dateobs(const cpl_propertylist *aHeaders)
find out the date of observations
Definition: muse_pfits.c:364
const muse_cpltable_def muse_offset_list_def[]
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
double muse_pfits_get_mjdobs(const cpl_propertylist *aHeaders)
find out the Julian Date of the observation
Definition: muse_pfits.c:346
cpl_table * muse_processing_sort_exposures(muse_processing *aProcessing)
Sort input frames (containing lists of pixel table filenames) into different exposures.
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.