OMEGA Pipeline Reference Manual  1.0.5
omega_shutter.c
1 /*
2  * omega_shutter.c
3  *
4  *
5  * This file is part of the OMEGA Pipeline
6  * Copyright (C) 2002,2003 European Southern Observatory
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  *
23  * Created on: Jan 4, 2011
24  * Author: agabasch
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 
32 #include "omega_recipe.h"
33 
34 /*----------------------------------------------------------------------------*/
56 /*-----------------------------------------------------------------------------
57  Functions prototypes
58  -----------------------------------------------------------------------------*/
59 
60 static int omega_shutter_create(cpl_plugin *);
61 static int omega_shutter_exec(cpl_plugin *);
62 static int omega_shutter_destroy(cpl_plugin *);
63 static int omega_shutter(cpl_frameset *, cpl_parameterlist *);
64 
65 /*-----------------------------------------------------------------------------
66  Private Functions
67  -----------------------------------------------------------------------------*/
68 
69 int omega_shutter_combine(cpl_parameterlist *pars, int xn);
70 int omega_shutter_biassubtract(cpl_parameterlist *pars, int xn);
71 static void omega_shutter_init(void);
72 static void omega_shutter_tidy(void);
73 static cpl_error_code omega_shutter_basicsteps(cpl_frameset * frameset,
74  cpl_image * mbias, cpl_imagelist * ilist_shortexp_up,
75  float exptime_lower, float exptime_upper,
76  const char * direction, int extension);
77 static cpl_matrix * omega_fill_ccdlayout(void);
78 static cpl_error_code omega_average_ccd_table(cpl_imagelist * ilist_in,
79  cpl_table * table_out );
80 static cpl_error_code omega_table_insert_xcoordinates(cpl_table * table);
81 static float omega_get_exptime_limit(cpl_frameset * frameset);
82 
83 /*-----------------------------------------------------------------------------
84  Static structures
85  -----------------------------------------------------------------------------*/
86 
87 static struct {
88  /* Inputs. Parameters */
89  int oc;
90 }omega_shutter_config;
91 
92 /* Input and Output */
93 static struct {
94 
95  cpl_size *labels;
96  const cpl_frame *mbframe;
97  cpl_frameset *domelist;
98 }ps;
99 
100 /*-----------------------------------------------------------------------------
101  Static global variables
102  -----------------------------------------------------------------------------*/
103 
104 /* Static variables */
105 #define RECIPE "omega_shutter"
106 
107 static char omega_shutter_man[] =
108 
109  "This recipe tests illumination variations due to inhomogeneities "
110  "in the \nshutter blade speed.\n"
111  "\n"
112  "Input files:\n\n"
113  " DO category: Type: Explanation: Required: \n"
114  " DOME_SHUTTERTEST Raw Domeflat Y \n"
115  " and \n"
116  " MASTER_BIAS Raw Master bias Y \n\n"
117  "Output files:\n\n"
118  " DO category: Data type: Explanation: \n"
119  " SHUTTER_DOWN Products: Collapsed CCD array \n"
120  " and \n"
121  " SHUTTER_UP Products: Collapsed CCD array \n\n";
122 
123 #define omega_shutter_exit(message) \
124  { \
125  if (message) cpl_msg_error(cpl_func, message); \
126  cpl_imagelist_delete(ilist_shortexp_up); \
127  cpl_imagelist_delete(ilist_longexp_up); \
128  cpl_imagelist_delete(ilist_shortexp_down); \
129  cpl_imagelist_delete(ilist_longexp_down); \
130  cpl_imagelist_delete(ilist_up); \
131  cpl_imagelist_delete(ilist_down); \
132  cpl_image_delete(mbias); \
133  cpl_table_delete(table_up); \
134  cpl_table_delete(table_down); \
135  cpl_propertylist_delete(plistHeader); \
136  cpl_msg_indent_less(); \
137  return -1; \
138  }
139 
140 #define omega_average_ccd_table_exit(message) \
141  { \
142  if (message) cpl_msg_error(cpl_func, message); \
143  cpl_matrix_delete(ccd_mapping); \
144  cpl_imagelist_delete(ilist_tmp); \
145  cpl_image_delete(image_tmp); \
146  cpl_image_delete(image_collapsed); \
147  cpl_table_delete(table_local); \
148  cpl_msg_indent_less(); \
149  return cpl_error_set(cpl_func, cpl_error_get_code()); \
150  }
151 
152 #define omega_shutter_basicsteps_exit(message) \
153  { \
154  if (message) cpl_msg_error(cpl_func, message); \
155  cpl_propertylist_delete(plist); \
156  cpl_image_delete(image_local); \
157  cpl_image_delete(image_local_collapsed); \
158  cpl_free(direction_local); \
159  cpl_msg_indent_less(); \
160  return cpl_error_set(cpl_func, cpl_error_get_code()); \
161  }
162 
163 /*----------------------------------------------------------------------------*/
171 /*----------------------------------------------------------------------------*/
172 int cpl_plugin_get_info(cpl_pluginlist * list)
173 {
174  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
175  cpl_plugin * plugin = &recipe->interface ;
176 
177  if (cpl_plugin_init(plugin,
178  CPL_PLUGIN_API,
179  OMEGA_BINARY_VERSION,
180  CPL_PLUGIN_TYPE_RECIPE,
181  "omega_shutter",
182  "OMEGA - Test the shutter homogeneity",
183  omega_shutter_man,
184  "Armin Gabasch",
185  PACKAGE_BUGREPORT,
187  omega_shutter_create,
188  omega_shutter_exec,
189  omega_shutter_destroy)) {
190  cpl_msg_error(cpl_func, "Plugin initialization failed");
191  (void)cpl_error_set_where(cpl_func);
192  return 1;
193  }
194 
195  if (cpl_pluginlist_append(list, plugin)) {
196  cpl_msg_error(cpl_func, "Error adding plugin to list");
197  (void)cpl_error_set_where(cpl_func);
198  return 1;
199  }
200 
201  return 0;
202 }
203 
204 /*----------------------------------------------------------------------------*/
213 /*----------------------------------------------------------------------------*/
214 static int omega_shutter_create(cpl_plugin * plugin)
215 {
216  cpl_recipe * recipe;
217  cpl_parameter * p ;
218 
219  /* Do not create the recipe if an error code is already set */
220  if (cpl_error_get_code() != CPL_ERROR_NONE) {
221  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
222  cpl_func, __LINE__, cpl_error_get_where());
223  return (int)cpl_error_get_code();
224  }
225 
226  if (plugin == NULL) {
227  cpl_msg_error(cpl_func, "Null plugin");
228  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
229  }
230 
231  /* Verify plugin type */
232  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
233  cpl_msg_error(cpl_func, "Plugin is not a recipe");
234  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
235  }
236 
237  /* Get the recipe */
238  recipe = (cpl_recipe *)plugin;
239 
240  /* Create the parameters list in the cpl_recipe object */
241  recipe->parameters = cpl_parameterlist_new() ;
242 
243  if (recipe->parameters == NULL) {
244  cpl_msg_error(cpl_func, "Parameter list allocation failed");
245  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
246  }
247 
248  /* Fill the parameters list */
249 
250  /* General Parameters */
251 
252 
253  p = cpl_parameter_new_range("omega.omega_shutter.OverscanMethod",
254  CPL_TYPE_INT,
255  "Overscan Correction Method",
256  "omega_shutter",
257  0, 0, 6);
258  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"oc-meth") ;
259  cpl_parameterlist_append(recipe->parameters, p) ;
260 
261  p = cpl_parameter_new_value("omega.omega_shutter.ExtensionNumber",
262  CPL_TYPE_INT,
263  "DUMMY parameter to ensure Paranal DFS compatibility!!",
264  "omega_shutter",
265  -1) ;
266 
267  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
268  cpl_parameterlist_append(recipe->parameters, p) ;
269 
270 
271 
272  return 0;
273 }
274 
275 /*----------------------------------------------------------------------------*/
281 /*----------------------------------------------------------------------------*/
282 static int omega_shutter_exec(cpl_plugin * plugin)
283 {
284  cpl_recipe * recipe;
285  int recipe_status;
286  cpl_errorstate initial_errorstate = cpl_errorstate_get();
287 
288  /* Return immediately if an error code is already set */
289  if (cpl_error_get_code() != CPL_ERROR_NONE) {
290  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
291  cpl_func, __LINE__, cpl_error_get_where());
292  return (int)cpl_error_get_code();
293  }
294 
295  if (plugin == NULL) {
296  cpl_msg_error(cpl_func, "Null plugin");
297  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
298  }
299 
300  /* Verify plugin type */
301  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
302  cpl_msg_error(cpl_func, "Plugin is not a recipe");
303  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
304  }
305 
306  /* Get the recipe */
307  recipe = (cpl_recipe *)plugin;
308 
309  /* Verify parameter and frame lists */
310  if (recipe->parameters == NULL) {
311  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
312  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
313  }
314  if (recipe->frames == NULL) {
315  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
316  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
317  }
318 
319  /* Invoke the recipe */
320  recipe_status = omega_shutter(recipe->frames, recipe->parameters);
321 
322  /* Ensure DFS-compliance of the products */
323  if (cpl_dfs_update_product_header(recipe->frames)) {
324  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
325  }
326 
327  if (!cpl_errorstate_is_equal(initial_errorstate)) {
328  /* Dump the error history since recipe execution start.
329  At this point the recipe cannot recover from the error */
330  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
331  }
332 
333  return recipe_status;
334 
335 }
336 
337 /*----------------------------------------------------------------------------*/
343 /*----------------------------------------------------------------------------*/
344 static int omega_shutter_destroy(cpl_plugin * plugin)
345 {
346  cpl_recipe *recipe;
347 
348  if (plugin == NULL) {
349  cpl_msg_error(cpl_func, "Null plugin");
350  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
351  }
352 
353  /* Verify plugin type */
354  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
355  cpl_msg_error(cpl_func, "Plugin is not a recipe");
356  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
357  }
358 
359  /* Get the recipe */
360  recipe = (cpl_recipe *)plugin;
361 
362  cpl_parameterlist_delete(recipe->parameters);
363 
364  return 0 ;
365 }
366 
367 static int omega_shutter(cpl_frameset *set, cpl_parameterlist *pars)
368 {
369 
370  int j=0,jst=0,jfn=0;
371  cpl_size nlab=0;
372  int nflats = 0;
373  int oscan1 = 0;
374  cpl_parameter *par =NULL;
375  cpl_imagelist * ilist_shortexp_up =NULL;
376  cpl_imagelist * ilist_longexp_up =NULL;
377  cpl_imagelist * ilist_shortexp_down =NULL;
378  cpl_imagelist * ilist_longexp_down =NULL;
379  cpl_imagelist * ilist_up =NULL;
380  cpl_imagelist * ilist_down =NULL;
381  cpl_image * mbias=NULL;
382  cpl_table * table_up=NULL;
383  cpl_table * table_down=NULL;
384  cpl_propertylist * plistHeader=NULL;
385  float shutter_explimit=0.;
386  //cpl_errorstate prestate=cpl_errorstate_get();
387 
388  /*Start the recipe */
389 
390  if (!pars) {
391  cpl_msg_error (cpl_func, "Parameters list not found");
392  return -1;
393  }
394 
395  if (cpl_frameset_is_empty(set) == 1) {
396  cpl_msg_error (cpl_func, "Frameset not found");
397  return -1;
398  }
399 
400  /* Retrieve input parameters */
401  par = cpl_parameterlist_find(pars, "omega.omega_shutter.OverscanMethod") ;
402  omega_shutter_config.oc = cpl_parameter_get_int(par) ;
403 
404  /* Identify the RAW and CALIB frames in the input frameset */
405  if (oc_dfs_set_groups(set)) {
406  cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
407  return -1 ;
408  }
409 
410  /*Initialized things*/
411  omega_shutter_init();
412 
413  /* Verify the frameset contents. */
414  if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
415  &nlab)) == NULL) {
416  cpl_msg_error(cpl_func,"Cannot labelise the input frameset");
417  omega_shutter_tidy();
418  return -1;
419  }
420  if ((ps.domelist = omega_frameset_subgroup(set,ps.labels,nlab,
421  SHUTTER_RAW)) == NULL) {
422  cpl_msg_error(cpl_func,"Cannot find dome frames in input frameset");
423  omega_shutter_tidy();
424  return -1;
425  }
426 
427  nflats = cpl_frameset_count_tags(ps.domelist, SHUTTER_RAW);
428  if (nflats < 4) {
429  cpl_msg_error (cpl_func, "Need at least 4 (%s) frames to run "
430  "this recipe", SHUTTER_RAW);
431  omega_shutter_tidy();
432  return -1;
433  }
434 
435  cpl_msg_info (cpl_func,"There are %d %s in frame set",nflats, SHUTTER_RAW);
436 
437  /* Check for calibration frames */
438  /* Master Bias */
439  ps.mbframe = cpl_frameset_find_const(set, OMEGA_CALIB_BIAS);
440  if (ps.mbframe == NULL) {
441  cpl_msg_error (cpl_func, "Need at least 1 (%s) frames to run "
442  "this recipe", OMEGA_CALIB_BIAS);
443  omega_shutter_tidy();
444  return -1;
445  }
446  else{
447  cpl_msg_info(cpl_func,"Using %s %s",OMEGA_CALIB_BIAS,
448  cpl_frame_get_filename(ps.mbframe));
449  }
450 
451 
452  /* Loop for each of the image extensions */
453  jst=1; /*First extension*/
454  jfn=32; /*Last extension*/
455 
456 
457  ilist_shortexp_up =cpl_imagelist_new();
458  ilist_longexp_up =cpl_imagelist_new();
459  ilist_shortexp_down =cpl_imagelist_new();
460  ilist_longexp_down =cpl_imagelist_new();
461 
462  shutter_explimit=omega_get_exptime_limit(ps.domelist);
463  cpl_msg_info(cpl_func, "Limit to discriminate long and short exposures:"
464  " %f second",shutter_explimit);
465 
466  for (j = jst; j <= jfn; j++) {
467  cpl_msg_info(cpl_func,"Beginning work on extension %02d",j);
468  cpl_msg_indent_more();
469 
470  /* Check overscan correction method consistency */
471  if(ps.mbframe != NULL){
472  oscan1 = omega_pfits_get_overscan(ps.mbframe, j);
473  if(oscan1 != omega_shutter_config.oc) {
474  cpl_msg_warning (cpl_func, "Overscan correction mode for Master"
475  " Bias (oc = %d) differs from the one used here "
476  "(oc = %d)", oscan1, omega_shutter_config.oc);
477  }
478  }
479 
480  /*Load master bias*/
481  mbias = cpl_image_load(cpl_frame_get_filename(ps.mbframe),
482  CPL_TYPE_FLOAT,0,j);
483  if(mbias==NULL){
484  cpl_msg_error (cpl_func, "Unable to load extension %d of the master"
485  " bias file %s", j, cpl_frame_get_filename(ps.mbframe));
486  omega_shutter_tidy();
487  omega_shutter_exit(NULL);
488  }
489 
490  /*Overscan correction, bias subtraction, exposure time normalisation*/
491 
492  if(omega_shutter_basicsteps(ps.domelist, mbias, ilist_shortexp_up ,
493  FLT_MIN , shutter_explimit, "up" ,j) != CPL_ERROR_NONE) {
494  cpl_msg_error (cpl_func, "Unable to perform basic image calibration"
495  " on extension %d ", j);
496  omega_shutter_tidy();
497  omega_shutter_exit(NULL);
498  }
499 
500  if(omega_shutter_basicsteps(ps.domelist, mbias, ilist_longexp_up ,
501  shutter_explimit, FLT_MAX , "up" ,j) != CPL_ERROR_NONE){
502  cpl_msg_error (cpl_func, "Unable to perform basic image calibration"
503  " on extension %d ", j);
504  omega_shutter_tidy();
505  omega_shutter_exit(NULL);
506  }
507 
508  if(omega_shutter_basicsteps(ps.domelist, mbias, ilist_shortexp_down,
509  FLT_MIN , shutter_explimit, "down",j)!= CPL_ERROR_NONE){
510  cpl_msg_error (cpl_func, "Unable to perform basic image calibration"
511  " on extension %d ", j);
512  omega_shutter_tidy();
513  omega_shutter_exit(NULL);
514  }
515 
516  if(omega_shutter_basicsteps(ps.domelist, mbias, ilist_longexp_down ,
517  shutter_explimit, FLT_MAX , "down",j)!= CPL_ERROR_NONE){
518  cpl_msg_error (cpl_func, "Unable to perform basic image calibration"
519  " on extension %d ", j);
520  omega_shutter_tidy();
521  omega_shutter_exit(NULL);
522  }
523 
524  cpl_image_delete(mbias); mbias=NULL;
525  cpl_msg_indent_less();
526  }
527 
528  /*Divide the short exposure by the long exposure*/
529 
530  cpl_msg_info(cpl_func,"Dividing long exposures through short exposures");
531 
532  if(cpl_imagelist_divide(ilist_shortexp_up,ilist_longexp_up)!=
533  CPL_ERROR_NONE){
534  omega_shutter_tidy();
535  omega_shutter_exit("Can not divide long exposure through short exposure");
536  }
537 
538  if(cpl_imagelist_divide(ilist_shortexp_down,ilist_longexp_down)!=
539  CPL_ERROR_NONE){
540  omega_shutter_tidy();
541  omega_shutter_exit("Can not divide long exposure through short exposure");
542  }
543 
544 
545  ilist_up=cpl_imagelist_new();
546  ilist_down=cpl_imagelist_new();
547  table_up=cpl_table_new(0);
548  table_down=cpl_table_new(0);
549 
550  cpl_table_new_column(table_up,"RowAveraged",CPL_TYPE_FLOAT);
551  cpl_table_new_column(table_down,"RowAveraged",CPL_TYPE_FLOAT);
552 
553 
554  cpl_msg_info(cpl_func,"Final average-collapsing the full CCD array in "
555  "y-direction");
556 
557  if(omega_average_ccd_table(ilist_shortexp_up, table_up)!= CPL_ERROR_NONE){
558  omega_shutter_tidy();
559  omega_shutter_exit("Can not collapse CCD array in y-direction");
560  }
561 
562  if(omega_average_ccd_table(ilist_shortexp_down, table_down)!=CPL_ERROR_NONE){
563  omega_shutter_tidy();
564  omega_shutter_exit("Can not collapse CCD array in y-direction");
565  }
566 
567  if(omega_table_insert_xcoordinates(table_up)!= CPL_ERROR_NONE ||
568  omega_table_insert_xcoordinates(table_down)!= CPL_ERROR_NONE){
569  omega_shutter_tidy();
570  omega_shutter_exit("Can not insert x-coordinates in the product table");
571  }
572 
573 
574  plistHeader=cpl_propertylist_new();
575  cpl_propertylist_append_string(plistHeader, CPL_DFS_PRO_CATG, "SHUTTER_UP");
576 
577  if(cpl_dfs_save_table(set, NULL, pars, set, NULL, table_up, NULL,
578  "omega_shutter", plistHeader, NULL, PACKAGE "/" PACKAGE_VERSION ,
579  "omega_shutter_up.fits") != CPL_ERROR_NONE){
580  omega_shutter_tidy();
581  omega_shutter_exit("Can not save the product SHUTTER_UP");
582  }
583 
584  cpl_propertylist_update_string(plistHeader, CPL_DFS_PRO_CATG, "SHUTTER_DOWN");
585  if (cpl_dfs_save_table(set, NULL, pars, set, NULL, table_down, NULL,
586  "omega_shutter", plistHeader, NULL, PACKAGE "/" PACKAGE_VERSION ,
587  "omega_shutter_down.fits")!=CPL_ERROR_NONE){
588  omega_shutter_tidy();
589  omega_shutter_exit("Can not save the product SHUTTER_DOWN");
590  }
591  cpl_propertylist_delete(plistHeader); plistHeader=NULL;
592 
593  /*Clean up */
594  cpl_imagelist_delete(ilist_shortexp_up); ilist_shortexp_up=NULL;
595  cpl_imagelist_delete(ilist_longexp_up); ilist_longexp_up=NULL;
596  cpl_imagelist_delete(ilist_shortexp_down); ilist_shortexp_down=NULL;
597  cpl_imagelist_delete(ilist_longexp_down); ilist_longexp_down=NULL;
598  cpl_imagelist_delete(ilist_up); ilist_up=NULL;
599  cpl_imagelist_delete(ilist_down); ilist_down=NULL;
600  cpl_table_delete(table_up); table_up=NULL;
601  cpl_table_delete(table_down); table_down=NULL;
602  omega_shutter_tidy();
603 
604  return 0;
605 }
606 
616 static cpl_error_code omega_average_ccd_table(cpl_imagelist * ilist_in,
617  cpl_table * table_out ){
618 
619  cpl_matrix * ccd_mapping=NULL;
620  cpl_imagelist * ilist_tmp=NULL;
621  cpl_image * image_tmp=NULL;
622  cpl_image * image_collapsed=NULL;
623  cpl_table * table_local=NULL;;
624  int nrow=0, ncol=0, row=0, col=0;
625  int ccd_index=0;
626  cpl_errorstate prestate=cpl_errorstate_get();
627 
628  ccd_mapping=omega_fill_ccdlayout();
629  //Test: cpl_error_set(cpl_func,CPL_ERROR_ACCESS_OUT_OF_RANGE);
630  if (!cpl_errorstate_is_equal(prestate)){
631  omega_average_ccd_table_exit(NULL);
632  }
633 
634  nrow=cpl_matrix_get_nrow(ccd_mapping); /*4*/
635  ncol=cpl_matrix_get_ncol(ccd_mapping); /*8*/
636  if (!cpl_errorstate_is_equal(prestate)){
637  omega_average_ccd_table_exit(NULL);
638  }
639 
640  for (col=0; col<ncol;col++){
641  cpl_msg_debug(cpl_func,"working on column: %d", col);
642  cpl_msg_indent_more();
643  ilist_tmp=cpl_imagelist_new();
644  for (row=0; row<nrow;row++){
645  cpl_msg_debug(cpl_func,"working on row: %d", row);
646  ccd_index=cpl_matrix_get(ccd_mapping,row,col)-1;
647  cpl_msg_debug(cpl_func,"fits file extension: %d", ccd_index+1);
648  image_tmp=cpl_image_duplicate(cpl_imagelist_get(ilist_in,ccd_index));
649  cpl_imagelist_set(ilist_tmp,image_tmp,row);
650  }
651  if (!cpl_errorstate_is_equal(prestate)){
652  omega_average_ccd_table_exit(NULL);
653  }
654 
655  image_collapsed=cpl_imagelist_collapse_create(ilist_tmp);
656  if (!cpl_errorstate_is_equal(prestate)){
657  omega_average_ccd_table_exit(NULL);
658  }
659  table_local=cpl_table_new(cpl_image_get_size_x(image_collapsed));
660  cpl_table_new_column(table_local,"RowAveraged",CPL_TYPE_FLOAT);
661  cpl_table_copy_data_float(table_local,"RowAveraged",
662  cpl_image_get_data_float(image_collapsed));
663  if (!cpl_errorstate_is_equal(prestate)){
664  omega_average_ccd_table_exit(NULL);
665  }
666 
667  cpl_table_insert(table_out, table_local, cpl_table_get_nrow(table_out));
668  cpl_table_delete(table_local); table_local=NULL;
669  cpl_image_delete(image_collapsed); image_collapsed=NULL;
670  cpl_imagelist_delete(ilist_tmp); ilist_tmp=NULL;
671  cpl_msg_indent_less();
672  }
673 
674  cpl_matrix_delete(ccd_mapping); ccd_mapping=NULL;
675 
676  /* Propagate error, if any */
677  return cpl_error_set(cpl_func, cpl_error_get_code());
678 
679 }
680 
681 
689 static cpl_matrix * omega_fill_ccdlayout(void){
690  cpl_matrix * ccd=NULL;
691 
692 
693  ccd=cpl_matrix_new(4,8);
694 
695  cpl_matrix_set(ccd,0,0 ,1 );
696  cpl_matrix_set(ccd,0,1 ,2 );
697  cpl_matrix_set(ccd,0,2 ,3 );
698  cpl_matrix_set(ccd,0,3 ,4 );
699  cpl_matrix_set(ccd,0,4 ,17);
700  cpl_matrix_set(ccd,0,5 ,18);
701  cpl_matrix_set(ccd,0,6 ,19);
702  cpl_matrix_set(ccd,0,7 ,20);
703 
704  cpl_matrix_set(ccd,1,0 ,5 );
705  cpl_matrix_set(ccd,1,1 ,6 );
706  cpl_matrix_set(ccd,1,2 ,7 );
707  cpl_matrix_set(ccd,1,3 ,8 );
708  cpl_matrix_set(ccd,1,4 ,21);
709  cpl_matrix_set(ccd,1,5 ,22);
710  cpl_matrix_set(ccd,1,6 ,23);
711  cpl_matrix_set(ccd,1,7 ,24);
712 
713  cpl_matrix_set(ccd,2,0 ,9);
714  cpl_matrix_set(ccd,2,1 ,10);
715  cpl_matrix_set(ccd,2,2 ,11);
716  cpl_matrix_set(ccd,2,3 ,12);
717  cpl_matrix_set(ccd,2,4 ,25);
718  cpl_matrix_set(ccd,2,5 ,26);
719  cpl_matrix_set(ccd,2,6 ,27);
720  cpl_matrix_set(ccd,2,7 ,28);
721 
722 
723  cpl_matrix_set(ccd,3,0 ,13);
724  cpl_matrix_set(ccd,3,1 ,14);
725  cpl_matrix_set(ccd,3,2 ,15);
726  cpl_matrix_set(ccd,3,3 ,16);
727  cpl_matrix_set(ccd,3,4 ,29);
728  cpl_matrix_set(ccd,3,5 ,30);
729  cpl_matrix_set(ccd,3,6 ,31);
730  cpl_matrix_set(ccd,3,7 ,32);
731 
732  return ccd;
733 }
734 
751 static cpl_error_code omega_shutter_basicsteps(cpl_frameset * frameset,
752  cpl_image * mbias, cpl_imagelist * ilist, float exptime_lower,
753  float exptime_upper, const char * direction, int extension)
754 {
755  char * direction_local=NULL;
756  double local_TMOPEN=0.;
757  float exptime_local=0;
758  cpl_propertylist * plist=NULL;
759  cpl_image * image_local=NULL;
760  cpl_image * image_local_collapsed=NULL;
761  cpl_frame * cur_frame=NULL;
762  cpl_errorstate prestate = cpl_errorstate_get();
763 
764  cur_frame=cpl_frameset_get_first(frameset);
765 
766  /*Looping over frames*/
767  while(cur_frame)
768  {
769  cpl_free(direction_local); direction_local=NULL;
770  plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame),0);
771  local_TMOPEN=cpl_propertylist_get_double(plist,
772  "ESO DET SHUT TMOPEN");
773  if(cpl_error_get_code() != CPL_ERROR_NONE)
774  {
775  omega_shutter_basicsteps_exit("Missing keyword "
776  "ESO DET SHUT TMOPEN in scientific header");
777  }
778  cpl_msg_debug(cpl_func, "ESO DET SHUT TMOPEN: %g", local_TMOPEN);
779  if(local_TMOPEN>0.){
780  direction_local= cpl_sprintf("up");
781  }
782  else {
783  direction_local= cpl_sprintf("down");
784  }
785 
786  exptime_local=cpl_propertylist_get_float(plist, "EXPTIME");
787 
788  if ((cpl_error_get_code() != CPL_ERROR_NONE) || (exptime_local <=0)){
789  cpl_error_set(cpl_func,CPL_ERROR_ILLEGAL_INPUT);
790  omega_shutter_basicsteps_exit("Missing keyword "
791  "EXPTIME in scientific header or EXPTIME <= ZERO");
792  }
793 
794  if(strcmp(direction_local,direction)==0 && exptime_local >exptime_lower
795  && exptime_local <=exptime_upper)
796  {
797  cpl_msg_debug(cpl_func, "Loop: ESO DET SHUT TMOPEN: %g", local_TMOPEN);
798  cpl_msg_debug(cpl_func, "Loop: direction_local: %s", direction_local);
799  cpl_msg_debug(cpl_func, "Loop: direction: %s", direction);
800 
801  cpl_msg_info(cpl_func,"Trimming and overscan correcting");
802 
803  image_local=TrimOscanCorrect(cur_frame, omega_shutter_config.oc,
804  extension);
805 
806  if(image_local==NULL){
807  omega_shutter_basicsteps_exit("Can not trim and correct the "
808  "overscan ");
809  }
810 
811  //Subtract Bias !!!
812  cpl_msg_info(cpl_func,"Subtracting the bias");
813  cpl_image_subtract(image_local,mbias);
814  if (!cpl_errorstate_is_equal(prestate)){
815  omega_shutter_basicsteps_exit("Can not subtract the bias");
816  }
817 
818  /*Collapse image in y direction by using the median*/
819  cpl_msg_info(cpl_func,"Median collapsing in y-direction");
820  image_local_collapsed=cpl_image_collapse_median_create(
821  image_local, 0, 0, 0);
822  if (!cpl_errorstate_is_equal(prestate)){
823  omega_shutter_basicsteps_exit("Can not collapse the image in "
824  "y-direction");
825  }
826 
827  /*Devide image through the exposure time*/
828  cpl_msg_info(cpl_func,"Normalizing the exposure time to 1 sec");
829  cpl_image_divide_scalar(image_local_collapsed,exptime_local);
830  if (!cpl_errorstate_is_equal(prestate)){
831  omega_shutter_basicsteps_exit("can not normalize the exposure "
832  "time to unity");
833  }
834 
835  /*Insert image in the imagelist*/
836  cpl_imagelist_set(ilist,image_local_collapsed,extension-1);
837 
838  /*Free memory*/
839  cpl_image_delete(image_local); image_local=NULL;
840 
841  }
842  cpl_propertylist_delete(plist); plist=NULL;
843  cpl_free(direction_local); direction_local=NULL;
844  cur_frame=cpl_frameset_get_next(frameset);
845  }
846 
847 
848  if (cpl_imagelist_get_size(ilist)<1){
849  cpl_error_set_message(cpl_func,CPL_ERROR_ILLEGAL_INPUT,"Imagelist is "
850  "empty! Please check the input raw frames");
851  }
852 
853  /* Propagate error, if any */
854  return cpl_error_set(cpl_func, cpl_error_get_code());
855 
856 }
864 static cpl_error_code omega_table_insert_xcoordinates(cpl_table * intable)
865 {
866  /*Fill the column x_coordinate to better plot the results*/
867  int * ptablecol=NULL;
868  int i = 0;
869  cpl_errorstate prestate = cpl_errorstate_get();
870 
871  cpl_table_new_column(intable, "x_coordinate", CPL_TYPE_INT);
872  cpl_table_fill_column_window_int(intable, "x_coordinate", 0,
873  cpl_table_get_nrow(intable), 0);
874  ptablecol = cpl_table_get_data_int(intable, "x_coordinate");
875 
876  if (!cpl_errorstate_is_equal(prestate)){
877  return cpl_error_set(cpl_func, cpl_error_get_code());
878  }
879  else {
880 
881  for(i = 0; i < cpl_table_get_nrow(intable); i++){
882  ptablecol[i] = i + 1;
883  }
884  }
885  /* Propagate error, if any */
886  return cpl_error_set(cpl_func, cpl_error_get_code());
887 }
888 
889 /* Initialize the pointers */
890 static void omega_shutter_init(void) {
891  ps.labels = NULL;
892  ps.mbframe = NULL;
893  ps.domelist = NULL;
894 
895 }
896 
897 /* Free any allocated memory */
898 static void omega_shutter_tidy(void) {
899  freespace(ps.labels);
900  freeframeset(ps.domelist);
901 
902 }
903 
912 static float omega_get_exptime_limit(cpl_frameset * frameset){
913 
914  cpl_vector * exptime_vector=NULL;
915  cpl_propertylist * plist=NULL;
916  cpl_frame * cur_frame=NULL;
917  int i=0;
918  float exptime_limit=0;
919 
920  exptime_vector=cpl_vector_new(cpl_frameset_get_size(frameset));
921 
922  cur_frame=cpl_frameset_get_first(frameset);
923 
924  i=0;
925  /*Looping over frames*/
926  while(cur_frame)
927  {
928  plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame),0);
929  if(!cpl_propertylist_has(plist, "EXPTIME"))
930  {
931  cpl_msg_warning(cpl_func,"Can not find EXPTIME in file %s",
932  cpl_frame_get_filename(cur_frame));
933  cpl_propertylist_delete(plist);
934  cpl_vector_delete(exptime_vector);
935  return 0.;
936  }
937 
938  cpl_vector_set(exptime_vector, i,
939  cpl_propertylist_get_float(plist, "EXPTIME"));
940  cpl_propertylist_delete(plist);
941  i++;
942  cur_frame=cpl_frameset_get_next(frameset);
943  }
944 
945  exptime_limit=(cpl_vector_get_min(exptime_vector)+
946  cpl_vector_get_max(exptime_vector))/2.;
947  cpl_vector_delete(exptime_vector);
948 
949  return exptime_limit;
950 
951 }
952