UVES Pipeline Reference Manual  5.4.6
uves_reduce_mflat_combine.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2013-08-08 13:36:46 $
23  * $Revision: 1.12 $
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 /*----------------------------------------------------------------------------*/
35 /*----------------------------------------------------------------------------*/
40 /*-----------------------------------------------------------------------------
41  Includes
42  -----------------------------------------------------------------------------*/
43 #include <uves_reduce_mflat_combine.h>
44 
45 #include <uves.h>
46 #include <uves_backsub.h>
47 #include <uves_chip.h>
48 #include <uves_dfs.h>
49 #include <uves_pfits.h>
50 #include <uves_parameters.h>
51 #include <uves_utils.h>
52 #include <uves_utils_wrappers.h>
53 #include <uves_qclog.h>
54 #include <uves_error.h>
55 #include <uves_msg.h>
56 
57 #include <cpl.h>
58 #include <float.h>
59 #include <string.h>
60 /*-----------------------------------------------------------------------------
61  Functions prototypes
62  -----------------------------------------------------------------------------*/
63 
64 static void
65 uves_reduce_mflat_combine(cpl_frameset *frames,
66  const cpl_parameterlist *parameters,
67  bool flames,
68  const char *recipe_id,
69  const char *starttime);
70 
71 /*-----------------------------------------------------------------------------
72  Implementation
73  -----------------------------------------------------------------------------*/
74 const char * const uves_mflat_combine_desc =
75 "This recipe combined a MASTER_FLAT_xxxx with a MASTER_DFLAT_xxxx\n"
76 "Input are:\n"
77 "a master flat (MASTER_FLAT_xxxx)\n"
78 "a master dflat (MASTER_DFLAT_xxxx)\n"
79 "an order table (ORDER_TABLE_xxxx)\n"
80 "provided for each chip (xxxx = BLUE, REDL, REDU). \n"
81 "Output is a MASTER_FLAT_xxxx\n";
82 
83 /*----------------------------------------------------------------------------*/
90 /*----------------------------------------------------------------------------*/
91 int
92 uves_mflat_combine_define_parameters_body(cpl_parameterlist *parameters,
93  const char *recipe_id)
94 {
95 
96  /*****************
97  * General *
98  *****************/
99  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
100  {
101  return -1;
102  }
103 
104  return (cpl_error_get_code() != CPL_ERROR_NONE);
105 }
106 
107 
108 
109 
110 /*----------------------------------------------------------------------------*/
122 /*----------------------------------------------------------------------------*/
123 void
124 uves_mflat_combine_exe_body(cpl_frameset *frames,
125  const cpl_parameterlist *parameters,
126  const char *starttime,
127  const char *recipe_id)
128 {
129  bool flames = false;
130  check_nomsg(uves_reduce_mflat_combine(frames, parameters,flames,recipe_id,
131  starttime));
132 
133  cleanup:
134  return;
135 }
136 
137 /*----------------------------------------------------------------------------*/
153 cpl_image*
154 uves_combine_flats(const cpl_frame* frm_flat,
155  const cpl_frame* frm_dflat,
156  cpl_frameset* frames,
157  bool flames,
158  const int ORDER_THRESHOLD)
159 {
160 
161 
162  const char * name_flat=NULL ;
163  const char * name_dflat=NULL ;
164  const char *ordertable_filename = "";
165 
166  cpl_image* ima_flat=NULL;
167  cpl_image* ima_dflat=NULL;
168  cpl_image* ima_cflat=NULL;
169  cpl_image* ima_mask=NULL;
170 
171  int sx=0;
172  int sy=0;
173  int j=0;
174  int i=0;
175 
176  double* point_mask=NULL;
177 
178  double xpos=0;
179  double ypos=0;
180 
181  double order_ref=(double)ORDER_THRESHOLD;
182  int ypos_min=0;
183  int ypos_max=0;
184  int ypos_cen=0;
185  int xpos_cen=0;
186  int xrad=5;
187  int yrad=5;
188  int llx=0;
189  int lly=0;
190  int urx=0;
191  int ury=0;
192  double dflux=0;
193  double fflux=0;
194  double scale=0;
195 
196  /* Input */
197  /* Order table */
198  cpl_table *ordertable = NULL;
199  uves_propertylist *ordertable_header = NULL;
200  polynomial *order_locations = NULL;
201  cpl_table *traces = NULL;
202  const char *chip_name = "";
203  enum uves_chip chip=UVES_CHIP_BLUE;
204 
205 
206 
207  name_flat=cpl_frame_get_filename(frm_flat);
208  name_dflat=cpl_frame_get_filename(frm_dflat);
209  check_nomsg(ima_flat=cpl_image_load(name_flat,CPL_TYPE_DOUBLE,0,0));
210  check_nomsg(ima_dflat=cpl_image_load(name_dflat,CPL_TYPE_DOUBLE,0,0));
211 
212  /* check size flat is same as size dflat */
213  sx=cpl_image_get_size_x(ima_flat);
214  sy=cpl_image_get_size_y(ima_flat);
215  assure(sx==cpl_image_get_size_x(ima_dflat),CPL_ERROR_ILLEGAL_INPUT,
216  "illagal x size");
217  assure(sy==cpl_image_get_size_y(ima_dflat),CPL_ERROR_ILLEGAL_INPUT,
218  "illagal y size");
219 
220 
221 
222  check_nomsg( chip_name = UVES_CHIP_ID(chip));
223  uves_msg("Combining %s chip", uves_chip_tostring_upper(chip));
224 
225  check( uves_load_ordertable(frames,
226  flames,
227  chip_name,
228  &ordertable_filename,
229  &ordertable,
230  &ordertable_header,
231  NULL,
232  &order_locations,
233  &traces, NULL, NULL,
234  NULL, NULL, /* fibre_pos,fibre_mask */
235  chip,
236  false),
237  "Could not load order table");
238  uves_msg("Using order table in '%s'", ordertable_filename);
239 
240  /* Do real job */
241  ypos=uves_polynomial_evaluate_2d(order_locations,0,order_ref);
242  ypos+=uves_polynomial_evaluate_2d(order_locations,0,order_ref+1);
243  ypos/=2.;
244  ypos_min=(int)ypos;
245 
246 
247  ypos=uves_polynomial_evaluate_2d(order_locations,(double)sx,order_ref);
248  ypos+=uves_polynomial_evaluate_2d(order_locations,(double)sx,order_ref+1);
249  ypos/=2.;
250  ypos_max=(int)ypos;
251 
252  uves_msg_debug("ypos min=%d max=%d",ypos_min,ypos_max);
253  ima_mask = cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
254  point_mask=cpl_image_get_data_double(ima_mask);
255  /* set upper part of mask to 1 */
256  for(j=(int)ypos_max;j<sy;j++) {
257  for(i=0;i<sx;i++) {
258  point_mask[j*sx+i]=1.;
259  }
260  }
261 
262  /* in transition region (only) make the check */
263  for(j=ypos_min;j<ypos_max;j++) {
264  for(i=0;i<sx;i++) {
265  xpos=(double)i;
266  /* Here the order trace pass through the order center
267  but we want to have the trace in the inter order region
268  y=(yc1+yc2)/2; where yc1 and yc2 are the two position at
269  order center and order+1 center
270  */
271  ypos= uves_polynomial_evaluate_2d(order_locations,xpos,order_ref);
272  ypos+=uves_polynomial_evaluate_2d(order_locations,xpos,order_ref+1);
273  ypos/=2.;
274  if(j > ypos) {
275  point_mask[j*sx+i] = 1.;
276  }
277  }
278  }
279 
280 /*
281  cpl_image_save(ima_mask,"ima_mask_ord.fits", CPL_BPP_IEEE_FLOAT,NULL,
282  CPL_IO_DEFAULT);
283 
284 */
285  /*determine ref flux on flat (order_ref+1) */
286  xpos_cen=sx/2;
287  llx=xpos_cen-xrad;
288  urx=xpos_cen+xrad;
289  ypos= uves_polynomial_evaluate_2d(order_locations,(double)xpos_cen,
290  order_ref+1);
291  ypos_cen=(int)ypos;
292  lly=ypos_cen-yrad;
293  ury=ypos_cen+yrad;
294  fflux=cpl_image_get_median_window(ima_flat,llx,lly,urx,ury);
295 
296 
297 
298  /*determine ref flux on dflat (order_ref) */
299  ypos=uves_polynomial_evaluate_2d(order_locations,(double)xpos_cen,order_ref);
300  ypos_cen=(int)ypos;
301  lly=ypos_cen-yrad;
302  ury=ypos_cen+yrad;
303  dflux=cpl_image_get_median_window(ima_dflat,llx,lly,urx,ury);
304 
305 
306  scale=fflux/dflux;
307 
308  uves_msg_debug("flux: n=%g d=%g s=%g",fflux,dflux,scale);
309 
310  /* combine images */
311  ima_cflat=cpl_image_duplicate(ima_flat);
312  cpl_image_multiply(ima_cflat,ima_mask);
313  cpl_image_multiply_scalar(ima_mask,-1.);
314  cpl_image_add_scalar(ima_mask,1.);
315  cpl_image_multiply(ima_dflat,ima_mask);
316  cpl_image_multiply_scalar(ima_dflat,scale);
317  cpl_image_add(ima_cflat,ima_dflat);
318 /*
319  cpl_image_save(ima_cflat,"ima_cflat.fits", CPL_BPP_IEEE_FLOAT,NULL,
320  CPL_IO_DEFAULT);
321 */
322 
323 
324  cleanup:
325 
326  uves_free_table(&ordertable);
327  uves_free_propertylist(&ordertable_header);
328  uves_polynomial_delete(&order_locations);
329  uves_free_table(&traces);
330  uves_free_image(&ima_flat);
331  uves_free_image(&ima_dflat);
332  uves_free_image(&ima_mask);
333 
334  return ima_cflat;
335 }
336 /*----------------------------------------------------------------------------*/
346 /*----------------------------------------------------------------------------*/
347 static void
348 uves_reduce_mflat_combine(cpl_frameset *frames,
349  const cpl_parameterlist *parameters,
350  bool flames,
351  const char *recipe_id,
352  const char *starttime)
353 {
354  bool debug_mode;
355  cpl_frame * frm_dflat=NULL ;
356  cpl_frame * frm_flat=NULL ;
357  const char * name_flat=NULL ;
358  const char * name_dflat=NULL ;
359  uves_propertylist* hflat=NULL;
360 
361  /* Output */
362  cpl_table *qclog[] = {NULL, NULL};
363  uves_propertylist *product_header=NULL;
364  cpl_image* ima_cflat=NULL;
365 
366  /* Local variables */
367  //char *product_filename = "master_cflat_blue.fits";
368  char *product_filename = NULL;
369  const char *product_tag[2] = {NULL, NULL};
370  char pro_filename[255];
371  //const char *product_tag = "MASTER_FLAT_BLUE";
372  const char* PROCESS_CHIP=NULL;
373  int ORDER_THRESHOLD=7;
374 
375  enum uves_chip chip;
376  int raw_index=0;
377  bool blue=true;
378 
379  /* Read recipe parameters */
380  {
381  /* General */
382  check( uves_get_parameter(parameters, NULL, "uves", "debug",
383  CPL_TYPE_BOOL , &debug_mode ),
384  "Could not read parameter");
385  }
386  check( uves_get_parameter(parameters, NULL, "uves", "process_chip",
387  CPL_TYPE_STRING, &PROCESS_CHIP),
388  "Could not read parameter");
389 
390  uves_string_toupper((char*)PROCESS_CHIP);
391 
392  check( uves_get_parameter(parameters, NULL, "uves", "order_threshold",
393  CPL_TYPE_INT, &ORDER_THRESHOLD),
394  "Could not read parameter");
395 
396  for (chip = uves_chip_get_first(blue);
397  chip != UVES_CHIP_INVALID;
398  chip = uves_chip_get_next(chip))
399  {
400  if (
401  cpl_frameset_find(frames,UVES_MASTER_FLAT(chip)) != NULL ||
402  cpl_frameset_find(frames,UVES_MASTER_DFLAT(chip)) != NULL
403  )
404  {
405 
406  if(chip == UVES_CHIP_BLUE) {
407  blue = true;
408  }
409  else {
410  blue = false;
411  }
412  } else {
413  blue = false;
414  }
415  }
416 
417  /* Load and check input frames */
418  /* Loop over one or two chips */
419  for (chip = uves_chip_get_first(blue);
420  chip != UVES_CHIP_INVALID;
421  chip = uves_chip_get_next(chip))
422  {
423 
424  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
425  chip = uves_chip_get_next(chip);
426  }
427 
428  raw_index = uves_chip_get_index(chip);
429 
430  uves_msg("Processing %s chip", uves_chip_tostring_upper(chip));
431 
432 
433  frm_flat=cpl_frameset_find(frames,UVES_MASTER_FLAT(chip));
434  frm_dflat=cpl_frameset_find(frames,UVES_MASTER_DFLAT(chip));
435 
436  if(frm_flat == NULL && frm_dflat == NULL) {
437  uves_msg_error("A %s or %s frame or both must be provided in input",
438  UVES_MASTER_FLAT(chip),UVES_MASTER_DFLAT(chip));
439  goto cleanup;
440  }
441  else if(frm_flat == NULL && frm_dflat != NULL) {
442  name_dflat=cpl_frame_get_filename(frm_dflat);
443  hflat=uves_propertylist_load(name_dflat,0);
444  ima_cflat=cpl_image_load(name_dflat,CPL_TYPE_DOUBLE,0,0);
445  } else if (frm_flat != NULL && frm_dflat == NULL) {
446  name_flat=cpl_frame_get_filename(frm_flat);
447  hflat=uves_propertylist_load(name_flat,0);
448  ima_cflat=cpl_image_load(name_flat,CPL_TYPE_DOUBLE,0,0);
449  } else {
450  check_nomsg(name_dflat=cpl_frame_get_filename(frm_dflat));
451  check_nomsg(hflat=uves_propertylist_load(name_dflat,0));
452 
453  check_nomsg(ima_cflat=uves_combine_flats(frm_flat,frm_dflat,frames,
454  flames,ORDER_THRESHOLD));
455 
456  }
457 
458  cpl_free(product_filename);
459  check( product_filename = uves_masterflat_filename(chip),
460  "Error getting filename");
461 
462 
463  sprintf(pro_filename, "%s", product_filename);
464  product_header=uves_propertylist_duplicate(hflat);
465  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_FLAT(chip);
466 
467  check( uves_frameset_insert(
468  frames,
469  ima_cflat,
470  CPL_FRAME_GROUP_PRODUCT,
471  CPL_FRAME_TYPE_IMAGE,
472  CPL_FRAME_LEVEL_INTERMEDIATE,
473  pro_filename,
474  product_tag[raw_index],
475  hflat,
476  product_header,
477  NULL,
478  parameters,
479  recipe_id,
480  PACKAGE "/" PACKAGE_VERSION, qclog,
481  starttime, true, UVES_ALL_STATS),
482  "Could not add master flat %s %s to frameset",
483  pro_filename, product_tag[raw_index]);
484 
485  uves_msg("Master flat %s %s added to frameset",
486  pro_filename, product_tag[raw_index]);
487 
488 
489  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
490  chip = uves_chip_get_next(chip);
491  }
492 
493 
494  uves_free_image(&ima_cflat);
495  uves_qclog_delete(&qclog[0]);
496  uves_free_propertylist(&product_header);
497  uves_free_propertylist(&hflat);
498 
499  } /* For each chip */
500 
501 
502  cleanup:
503 
504  uves_free_image(&ima_cflat);
505  uves_qclog_delete(&qclog[0]);
506  uves_free_propertylist(&product_header);
507  uves_free_propertylist(&hflat);
508  cpl_free(product_filename);
509 
510  return;
511 }
512 
513 
#define uves_msg_error(...)
Print an error message.
Definition: uves_msg.h:64
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define check_nomsg(CMD)
Definition: uves_error.h:204
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
Definition: uves_qclog.c:716
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
uves_propertylist * uves_propertylist_load(const char *name, int position)
Create a property list from a file.
static void uves_reduce_mflat_combine(cpl_frameset *frames, const cpl_parameterlist *parameters, bool flames, const char *recipe_id, const char *starttime)
Get the command line options and execute the data reduction.
double uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
int uves_chip_get_index(enum uves_chip chip)
Convert to integer.
Definition: uves_chip.c:124
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
Definition: uves_chip.c:92
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
Definition: uves_chip.c:108
#define uves_msg_debug(...)
Print a debug message.
Definition: uves_msg.h:97
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
Definition: uves_chip.c:156
uves_propertylist * uves_propertylist_duplicate(const uves_propertylist *self)
Create a copy of the given property list.
const char * uves_string_toupper(char *s)
Convert all lowercase characters in a string into uppercase characters.
Definition: uves_utils.c:1493
void uves_mflat_combine_exe_body(cpl_frameset *frames, const cpl_parameterlist *parameters, const char *starttime, const char *recipe_id)
Get the command line options and execute the data reduction.
#define check(CMD,...)
Definition: uves_error.h:198
int uves_mflat_combine_define_parameters_body(cpl_parameterlist *parameters, const char *recipe_id)
Setup the recipe options.
cpl_image * uves_combine_flats(const cpl_frame *frm_flat, const cpl_frame *frm_dflat, cpl_frameset *frames, bool flames, const int ORDER_THRESHOLD)
Get the command line options and execute the data reduction.