VIRCAM Pipeline  1.3.4
vircam_science_postprocess.c
1 /* $Id: vircam_science_postprocess.c,v 1.2 2013-10-21 14:43:04 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2013 Cambridge Astronomy Survey Unit
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jim $
23  * $Date: 2013-10-21 14:43:04 $
24  * $Revision: 1.2 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /* Includes */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <libgen.h>
38 #include <cpl.h>
39 #include <math.h>
40 
41 #include "vircam_utils.h"
42 #include "vircam_mask.h"
43 #include "vircam_pfits.h"
44 #include "vircam_dfs.h"
45 #include "vircam_mods.h"
46 #include "vircam_fits.h"
47 #include "vircam_tfits.h"
48 #include "vircam_paf.h"
49 #include "vircam_sky.h"
50 #include "vircam_filt.h"
51 #include "vircam_stats.h"
52 #include "vircam_wcsutils.h"
53 
54 #define VIRCAM_PATHSZ 128
55 #define VIRCAM_NEXTN 16
56 
57 struct {
58 
59  /* Input command line parameters */
60 
61  int nebulise;
62  int grout;
63  int minphotom;
64  int prettynames;
65  int neb_medfilt;
66  int neb_linfilt;
67  int cat_ipix;
68  float cat_thresh;
69  int cat_icrowd;
70  float cat_rcore;
71  int cat_nbsize;
72 } vircam_sci_postproc_config;
73 
74 static char vircam_recipename[VIRCAM_PATHSZ];
75 static char vircam_recipepaf[VIRCAM_PATHSZ];
76 
77 struct {
78  cpl_size *labels;
79  cpl_frameset *paws;
80  cpl_frameset *confs;
81  cpl_frameset *cats;
82 
83  cpl_frame *phottab;
84  cpl_table *tphottab;
85  cpl_frame *catindex;
86  char *catpath;
87  char *catname;
88  cpl_frame *schlf_n;
89  cpl_frame *schlf_s;
90 
91  vir_fits *outmos;
92  vir_fits *outmosconf;
93  vir_tfits *outmoscat;
94 } ps;
95 
96 static char vircam_science_postprocess_description[] =
97 "vircam_science_postprocess -- VIRCAM science postprocess recipe.\n\n"
98 "Mosaic a list of vircam stacks and generate a catalogue. Optionally nebulise\n"
99 "before generating the catalogue.\n"
100 "The program accepts the following files in the SOF:\n\n"
101 " Tag Description\n"
102 " -----------------------------------------------------------------------\n"
103 " %-22s A list of science jittered stacks images\n"
104 " %-22s A list of science jittered stack confidence maps\n"
105 " %-22s A list of science jittered stack catalogues\n"
106 " %-22s Northern Schlegel Map\n"
107 " %-22s Southern Schlegel Map\n"
108 " %-22s A master 2MASS index\n"
109 " %-22s A photometric calibration table\n"
110 "All of the above are required\n"
111 "\n";
112 
113 /* Main stuff for CPL/esorex */
114 
115 static int vircam_science_postprocess_create(cpl_plugin *plugin);
116 static int vircam_science_postprocess_exec(cpl_plugin *plugin);
117 static int vircam_science_postprocess_destroy(cpl_plugin *plugin);
118 static int vircam_science_postprocess(cpl_parameterlist *parlist,
119  cpl_frameset *framelist);
120 
121 
122 static int vircam_sci_postproc_save_image(vir_fits *outim,
123  cpl_frameset *framelist,
124  cpl_parameterlist *parlist,
125  cpl_frame *template, int isim);
126 static int vircam_sci_postproc_save_cat(vir_tfits *outcat,
127  cpl_frameset *framelist,
128  cpl_parameterlist *parlist,
129  cpl_frame *template);
130 static void vircam_sci_postproc_init(void);
131 static int vircam_sci_testfrm_1(cpl_frame *fr, int nextn_expected, int isimg);
132 static void vircam_sci_product_name(const char *template, int producttype,
133  int nametype, int fnumber, char *outfname);
134 static void vircam_sci_postproc_tidy(void);
135 
136 /*---------------------------------------------------------------------------*/
144 /*---------------------------------------------------------------------------*/
145 
146 int cpl_plugin_get_info(cpl_pluginlist *list) {
147  cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
148  cpl_plugin *plugin = &recipe->interface;
149  char alldesc[SZ_ALLDESC];
150  (void)snprintf(alldesc,SZ_ALLDESC,
151  vircam_science_postprocess_description,
152  VIRCAM_PRO_JITTERED_SCI,VIRCAM_PRO_CONF_SCI,
153  VIRCAM_PRO_OBJCAT_SCI,VIRCAM_CAL_SCHL_N,
154  VIRCAM_CAL_SCHL_S,VIRCAM_CAL_2MASS,VIRCAM_CAL_PHOTTAB);
155 
156  cpl_plugin_init(plugin,
157  CPL_PLUGIN_API,
158  VIRCAM_BINARY_VERSION,
159  CPL_PLUGIN_TYPE_RECIPE,
160  "vircam_science_postprocess",
161  "VIRCAM science postprocessing recipe",
162  alldesc,
163  "Jim Lewis",
164  "jrl@ast.cam.ac.uk",
166  vircam_science_postprocess_create,
167  vircam_science_postprocess_exec,
168  vircam_science_postprocess_destroy);
169 
170  cpl_pluginlist_append(list,plugin);
171 
172  return(0);
173 }
174 
175 /*---------------------------------------------------------------------------*/
184 /*---------------------------------------------------------------------------*/
185 
186 static int vircam_science_postprocess_create(cpl_plugin *plugin) {
187  cpl_recipe *recipe;
188  cpl_parameter *p;
189 
190  /* Get the recipe out of the plugin */
191 
192  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
193  recipe = (cpl_recipe *)plugin;
194  else
195  return(-1);
196 
197  /* Create the parameters list in the cpl_recipe object */
198 
199  recipe->parameters = cpl_parameterlist_new();
200 
201  /* Fill in flag to use the nebuliser */
202 
203  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.nebulise",
204  CPL_TYPE_BOOL,
205  "Nebulise the stacks before object detection?",
206  "vircam.vircam_science_postprocess",TRUE);
207  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"nebulise");
208  cpl_parameterlist_append(recipe->parameters,p);
209 
210  /* Fill in flag to grout the output catalogue */
211 
212  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.grout",
213  CPL_TYPE_BOOL,
214  "Grout the output tile catalogue?",
215  "vircam.vircam_science_postprocess",TRUE);
216  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"grout");
217  cpl_parameterlist_append(recipe->parameters,p);
218 
219  /* Fill in the minimum number of stars for photometry */
220 
221  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.minphotom",
222  CPL_TYPE_INT,
223  "Minimum number of stars for photometry solution",
224  "vircam.vircam_science_postprocess",20);
225  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"minphotom");
226  cpl_parameterlist_append(recipe->parameters,p);
227 
228  /* Fill in flag to use pretty names */
229 
230  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.prettynames",
231  CPL_TYPE_BOOL,
232  "Use pretty names?",
233  "vircam.vircam_science_postprocess",0);
234  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"prettynames");
235  cpl_parameterlist_append(recipe->parameters,p);
236 
237  /* Fill in the median filter size for nebuliser */
238 
239  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.neb_medfilt",
240  CPL_TYPE_INT,
241  "Median filter size for nebuliser",
242  "vircam.vircam_science_postprocess",101);
243  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"neb_medfilt");
244  cpl_parameterlist_append(recipe->parameters,p);
245 
246  /* Fill in the linear filter size for nebuliser */
247 
248  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.neb_linfilt",
249  CPL_TYPE_INT,
250  "Median filter size for nebuliser",
251  "vircam.vircam_science_postprocess",33);
252  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"neb_linfilt");
253  cpl_parameterlist_append(recipe->parameters,p);
254 
255  /* Fill in the minimum object size */
256 
257  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_ipix",
258  CPL_TYPE_INT,
259  "Minimum pixel area for each detected object",
260  "vircam.vircam_science_postprocess",4);
261  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_ipix");
262  cpl_parameterlist_append(recipe->parameters,p);
263 
264  /* Fill in the detection threshold parameter */
265 
266  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_thresh",
267  CPL_TYPE_DOUBLE,
268  "Detection threshold in sigma above sky",
269  "vircam.vircam_science_postprocess",1.25);
270  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_thresh");
271  cpl_parameterlist_append(recipe->parameters,p);
272 
273  /* Fill in flag to use deblending software or not */
274 
275  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_icrowd",
276  CPL_TYPE_BOOL,"Use deblending?",
277  "vircam.vircam_science_postprocess",1);
278  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_icrowd");
279  cpl_parameterlist_append(recipe->parameters,p);
280 
281  /* Fill in core radius */
282 
283  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_rcore",
284  CPL_TYPE_DOUBLE,"Value of Rcore in pixels",
285  "vircam.vircam_science_postprocess",3.0);
286  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"stk_rcore");
287  cpl_parameterlist_append(recipe->parameters,p);
288 
289  /* Fill in background smoothing box size */
290 
291  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_nbsize",
292  CPL_TYPE_INT,"Background smoothing box size",
293  "vircam.vircam_science_postprocess",64);
294  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_nbsize");
295  cpl_parameterlist_append(recipe->parameters,p);
296 
297  /* Get out of here */
298 
299  return(0);
300 }
301 
302 /*---------------------------------------------------------------------------*/
308 /*---------------------------------------------------------------------------*/
309 
310 static int vircam_science_postprocess_exec(cpl_plugin *plugin) {
311  cpl_recipe *recipe;
312 
313  /* Get the recipe out of the plugin */
314 
315  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
316  recipe = (cpl_recipe *)plugin;
317  else
318  return(-1);
319 
320  return(vircam_science_postprocess(recipe->parameters,recipe->frames));
321 }
322 
323 /*---------------------------------------------------------------------------*/
329 /*---------------------------------------------------------------------------*/
330 
331 static int vircam_science_postprocess_destroy(cpl_plugin *plugin) {
332  cpl_recipe *recipe ;
333 
334  /* Get the recipe out of the plugin */
335 
336  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
337  recipe = (cpl_recipe *)plugin;
338  else
339  return(-1);
340 
341  cpl_parameterlist_delete(recipe->parameters);
342  return(0);
343 }
344 
345 static int vircam_science_postprocess(cpl_parameterlist *parlist,
346  cpl_frameset *framelist) {
347  const char *fctid="vircam_scienc_postprocess";
348  cpl_parameter *p;
349  int nfail,status,n,i,j;
350  cpl_size nlab;
351  cpl_frameset *tmpframeset;
352  cpl_frame *frm,*frmc,*newfrm;
353  char tmpfilename[VIRCAM_PATHSZ],filt[16];
354  vir_fits *inf,*infc,*tmpoutmos,*tmpoutmosconf,*backmap;
355  vir_tfits *outmoscatg;
356  cpl_table *stdscat,*matchstds;
357 
358  /* Check validity of the input frameset */
359 
360  if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
361  cpl_msg_error(fctid,"Input framelist NULL or has no input data");
362  return(-1);
363  }
364 
365  /* Initialise some things */
366 
367  vircam_sci_postproc_init();
368  (void)strncpy(vircam_recipename,fctid,VIRCAM_PATHSZ);
369  (void)snprintf(vircam_recipepaf,VIRCAM_PATHSZ,"VIRCAM/%s",fctid);
370 
371  /* Stacking special parameters */
372 
373  p = cpl_parameterlist_find(parlist,
374  "vircam.vircam_science_postprocess.nebulise");
375  vircam_sci_postproc_config.nebulise = cpl_parameter_get_bool(p);
376  p = cpl_parameterlist_find(parlist,
377  "vircam.vircam_science_postprocess.grout");
378  vircam_sci_postproc_config.grout = cpl_parameter_get_bool(p);
379  p = cpl_parameterlist_find(parlist,
380  "vircam.vircam_science_postprocess.minphotom");
381  vircam_sci_postproc_config.minphotom = cpl_parameter_get_int(p);
382  p = cpl_parameterlist_find(parlist,
383  "vircam.vircam_science_postprocess.prettynames");
384  vircam_sci_postproc_config.prettynames = cpl_parameter_get_bool(p);
385  p = cpl_parameterlist_find(parlist,
386  "vircam.vircam_science_postprocess.neb_medfilt");
387  vircam_sci_postproc_config.neb_medfilt = cpl_parameter_get_int(p);
388  p = cpl_parameterlist_find(parlist,
389  "vircam.vircam_science_postprocess.neb_linfilt");
390  vircam_sci_postproc_config.neb_linfilt = cpl_parameter_get_int(p);
391 
392  p = cpl_parameterlist_find(parlist,
393  "vircam.vircam_science_postprocess.cat_ipix");
394  vircam_sci_postproc_config.cat_ipix = cpl_parameter_get_int(p);
395  p = cpl_parameterlist_find(parlist,
396  "vircam.vircam_science_postprocess.cat_thresh");
397  vircam_sci_postproc_config.cat_thresh = (float)cpl_parameter_get_double(p);
398  p = cpl_parameterlist_find(parlist,
399  "vircam.vircam_science_postprocess.cat_icrowd");
400  vircam_sci_postproc_config.cat_icrowd = cpl_parameter_get_bool(p);
401  p = cpl_parameterlist_find(parlist,
402  "vircam.vircam_science_postprocess.cat_rcore");
403  vircam_sci_postproc_config.cat_rcore = (float)cpl_parameter_get_double(p);
404  p = cpl_parameterlist_find(parlist,
405  "vircam.vircam_science_postprocess.cat_nbsize");
406  vircam_sci_postproc_config.cat_nbsize = cpl_parameter_get_int(p);
407 
408  /* Sort out raw from calib frames */
409 
410  if (vircam_dfs_set_groups(framelist) != VIR_OK) {
411  cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
412  vircam_sci_postproc_tidy();
413  return(-1);
414  }
415 
416  /* Label the input frames */
417 
418  if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
419  &nlab)) == NULL) {
420  cpl_msg_error(fctid,"Cannot labelise the input frames");
421  vircam_sci_postproc_tidy();
422  return(-1);
423  }
424 
425  /* Get the input science frames and their confidence maps */
426 
427  if ((ps.paws =
428  vircam_frameset_subgroup(framelist,ps.labels,(int)nlab,
429  VIRCAM_PRO_JITTERED_SCI)) == NULL) {
430  cpl_msg_error(fctid,"No science images to process!");
431  vircam_sci_postproc_tidy();
432  return(-1);
433  }
434  if ((ps.confs =
435  vircam_frameset_subgroup(framelist,ps.labels,(int)nlab,
436  VIRCAM_PRO_CONF_SCI)) == NULL) {
437  cpl_msg_error(fctid,"No science confidence maps to process!");
438  vircam_sci_postproc_tidy();
439  return(-1);
440  }
441  if ((ps.cats =
442  vircam_frameset_subgroup(framelist,ps.labels,(int)nlab,
443  VIRCAM_PRO_OBJCAT_SCI)) == NULL) {
444  cpl_msg_error(fctid,"No science object catalogues to process!");
445  vircam_sci_postproc_tidy();
446  return(-1);
447  }
448 
449  /* Check to see if there is a photometric table */
450 
451  nfail = 0;
452  if ((ps.phottab = vircam_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
453  VIRCAM_CAL_PHOTTAB)) == NULL) {
454  cpl_msg_error(fctid,"No photometric table found");
455  vircam_sci_postproc_tidy();
456  return(-1);
457  }
458  nfail += vircam_sci_testfrm_1(ps.phottab,1,0);
459 
460 
461  /* Is the 2mass index file specified? */
462 
463  if ((ps.catindex = vircam_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
464  VIRCAM_CAL_2MASS)) == NULL) {
465  cpl_msg_error(fctid,"No 2MASS index found -- cannot continue");
466  vircam_sci_postproc_tidy();
467  return(-1);
468  }
469  nfail += vircam_sci_testfrm_1(ps.catindex,1,0);
470 
471  /* Is the Northern Schlegel file specified? */
472 
473  if ((ps.schlf_n = vircam_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
474  VIRCAM_CAL_SCHL_N)) == NULL) {
475  cpl_msg_error(fctid,"Schlegel North map not found -- cannot continue");
476  vircam_sci_postproc_tidy();
477  return(-1);
478  }
479  nfail += vircam_sci_testfrm_1(ps.schlf_n,0,1);
480 
481  /* Is the Southern Schlegel file specified? */
482 
483  if ((ps.schlf_s = vircam_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
484  VIRCAM_CAL_SCHL_S)) == NULL) {
485  cpl_msg_error(fctid,"Schlegel South map not found -- cannot continue");
486  vircam_sci_postproc_tidy();
487  return(-1);
488  }
489  nfail += vircam_sci_testfrm_1(ps.schlf_s,0,1);
490 
491  /* Ok if any of this failed, then get out of here. This makes it a bit
492  simpler later on since we now know that all of the specified files
493  have the correct number of extensions and will load properly */
494 
495  if (nfail > 0) {
496  cpl_msg_error(fctid,
497  "There are %" CPL_SIZE_FORMAT " input file errors -- cannot continue",
498  (cpl_size)nfail);
499  vircam_sci_postproc_tidy();
500  return(-1);
501  }
502 
503  /* Get catalogue parameters */
504 
505  if (vircam_catpars(ps.catindex,&(ps.catpath),&(ps.catname)) == VIR_FATAL) {
506  vircam_sci_postproc_tidy();
507  return(-1);
508  }
509  freeframe(ps.catindex);
510 
511  /* Using the nebuliser before doing the catalogue, then create a frameset
512  of nebulised pawprints */
513 
514  status = VIR_OK;
515  if (vircam_sci_postproc_config.nebulise) {
516  tmpframeset = cpl_frameset_new();
517  n = (int)cpl_frameset_get_size(ps.paws);
518  cpl_msg_info(fctid,"Nebulising pawprints");
519  cpl_msg_indent_more();
520  for (i = 0; i < n; i++) {
521  cpl_msg_info(fctid,"Doing pawprint %" CPL_SIZE_FORMAT "",
522  (cpl_size)(i+1));
523  frm = cpl_frameset_get_frame(ps.paws,(cpl_size)i);
524  frmc = cpl_frameset_get_frame(ps.confs,(cpl_size)i);
525  (void)sprintf(tmpfilename,"tmp_%s",cpl_frame_get_filename(frm));
526  newfrm = cpl_frame_new();
527  cpl_frame_set_tag(newfrm,VIRCAM_SCI_OBJECT_RAW);
528  cpl_frame_set_filename(newfrm,tmpfilename);
529  cpl_frameset_insert(tmpframeset,newfrm);
530  for (j = 1; j <= VIRCAM_NEXTN; j++) {
531  inf = vircam_fits_load(frm,CPL_TYPE_FLOAT,j);
532  infc = vircam_fits_load(frmc,CPL_TYPE_INT,j);
533 
534  (void)vircam_nebuliser(inf,infc,101,33,3,1,0,0,0,0,10.0,3.0,
535  &backmap,&status);
536  if (status != VIR_OK) {
537  vircam_sci_postproc_tidy();
538  freefits(inf);
539  freefits(infc);
540  freeframeset(tmpframeset);
541  return(-1);
542  }
543  if (j == 1) {
544  if (access(tmpfilename,F_OK))
545  remove(tmpfilename);
546  cpl_image_save(NULL,tmpfilename,CPL_TYPE_UCHAR,
547  vircam_fits_get_phu(inf),CPL_IO_DEFAULT);
548  }
549  cpl_image_save(vircam_fits_get_image(inf),tmpfilename,
550  CPL_TYPE_FLOAT,vircam_fits_get_ehu(inf),
551  CPL_IO_EXTEND);
552  freefits(inf);
553  freefits(infc);
554  }
555  }
556  cpl_msg_indent_less();
557 
558  /* Mosaic the nebulised files */
559 
560  cpl_msg_info(fctid,"Tiling nebulised pawprints");
561  (void)vircam_mosaic(tmpframeset,ps.confs,1,2,0.0,"EXPTIME",
562  25,&tmpoutmos,&tmpoutmosconf,&status);
563  if (status != VIR_OK) {
564  vircam_sci_postproc_tidy();
565  freeframeset(tmpframeset);
566  freefits(tmpoutmos);
567  freefits(tmpoutmosconf);
568  return(-1);
569  }
570 
571  /* Chuck nebulised pawprints */
572 
573  for (i = 0; i < n; i++) {
574  frm = cpl_frameset_get_frame(tmpframeset,i);
575  remove(cpl_frame_get_filename(frm));
576  }
577  freeframeset(tmpframeset);
578 
579  /* Now do an imcore to create a catalogue from the nebulised mosaic. */
580 
581  cpl_msg_info(fctid,"Creating catalogue from nebulised mosaic");
582  (void)vircam_imcore(tmpoutmos,tmpoutmosconf,
583  vircam_sci_postproc_config.cat_ipix,
584  vircam_sci_postproc_config.cat_thresh,
585  vircam_sci_postproc_config.cat_icrowd,
586  vircam_sci_postproc_config.cat_rcore,
587  vircam_sci_postproc_config.cat_nbsize,6,
588  2.0,&(ps.outmoscat),&status);
589  if (status != VIR_OK) {
590  vircam_sci_postproc_tidy();
591  freeframeset(tmpframeset);
592  freefits(tmpoutmos);
593  freefits(tmpoutmosconf);
594  return(-1);
595  }
596 
597  /* Chuck the nebulised tile and confidence map */
598 
599  freefits(tmpoutmos);
600  freefits(tmpoutmosconf);
601 
602  /* Do the real mosaic */
603 
604  cpl_msg_info(fctid,"Creating the real mosaic");
605  (void)vircam_mosaic(ps.paws,ps.confs,1,2,0.0,"EXPTIME",25,&(ps.outmos),
606  &(ps.outmosconf),&status);
607  if (status != VIR_OK) {
608  vircam_sci_postproc_tidy();
609  return(-1);
610  }
611 
612  /* Not using the nebuliser, so just do an imcore to create a catalogue
613  from the real mosaic */
614 
615  } else {
616 
617  /* First do the real mosaic */
618 
619  cpl_msg_info(fctid,"Creating the real mosaic");
620  (void)vircam_mosaic(ps.paws,ps.confs,1,2,0.0,"EXPTIME",25,&(ps.outmos),
621  &(ps.outmosconf),&status);
622  if (status != VIR_OK) {
623  vircam_sci_postproc_tidy();
624  return(-1);
625  }
626 
627  /* Now the imcore */
628 
629  cpl_msg_info(fctid,"Creating catalogue from mosaic");
630  (void)vircam_imcore(ps.outmos,ps.outmosconf,
631  vircam_sci_postproc_config.cat_ipix,
632  vircam_sci_postproc_config.cat_thresh,
633  vircam_sci_postproc_config.cat_icrowd,
634  vircam_sci_postproc_config.cat_rcore,
635  vircam_sci_postproc_config.cat_nbsize,6,
636  2.0,&(ps.outmoscat),&status);
637  }
638 
639  /* Get some standard stars and match it against the catalogue. Do
640  the WCS fit */
641 
642  cpl_msg_info(fctid,"Doing WCS on mosaic");
643  (void)vircam_getstds(vircam_fits_get_ehu(ps.outmos),1,
644  ps.catpath,ps.catname,&stdscat,&status);
645  (void)vircam_matchstds(vircam_tfits_get_table(ps.outmoscat),stdscat,300.0,
646  &matchstds,&status);
647  (void)vircam_platesol(vircam_fits_get_ehu(ps.outmos),
648  vircam_tfits_get_ehu(ps.outmoscat),matchstds,6,1,
649  &status);
650  if (status != VIR_OK) {
651  freetable(stdscat);
652  freetable(matchstds);
653  vircam_sci_postproc_tidy();
654  return(-1);
655  }
656  freetable(stdscat);
657 
658  /* Now do the photometry */
659 
660  cpl_msg_info(fctid,"Doing photometry on mosaic");
661  ps.tphottab = cpl_table_load(cpl_frame_get_filename(ps.phottab),1,0);
663  vircam_photcal_extinct(&(ps.outmos),&matchstds,&(ps.outmoscat),1,
664  filt,ps.tphottab,
665  vircam_sci_postproc_config.minphotom,
666  ps.schlf_n,ps.schlf_s,&status);
667  if (status != VIR_OK) {
668  freetable(matchstds);
669  vircam_sci_postproc_tidy();
670  return(-1);
671  }
672  freetable(matchstds);
673 
674  /* Grout the output catalogue (if requested) */
675 
676  if (vircam_sci_postproc_config.grout) {
677  cpl_msg_info(fctid,"Grouting catalogue");
678  (void)vircam_grout(ps.outmoscat,ps.cats,ps.confs,&outmoscatg,&status);
679  freetfits(ps.outmoscat);
680  ps.outmoscat = outmoscatg;
681  }
682 
683  /* Save the mosaic and its confidence map */
684 
685  cpl_msg_info(fctid,"Saving mosaic, confidence map and catalogue");
686  (void)vircam_sci_postproc_save_image(ps.outmos,framelist,parlist,
687  cpl_frameset_get_frame(ps.paws,0),
688  1);
689  (void)vircam_sci_postproc_save_image(ps.outmosconf,framelist,parlist,
690  cpl_frameset_get_frame(ps.paws,0),
691  0);
692  (void)vircam_sci_postproc_save_cat(ps.outmoscat,framelist,parlist,
693  cpl_frameset_get_frame(ps.paws,0));
694 
695  /* Tidy up */
696 
697  vircam_sci_postproc_tidy();
698  return(0);
699 }
700 
701 static int vircam_sci_postproc_save_image(vir_fits *outim,
702  cpl_frameset *framelist,
703  cpl_parameterlist *parlist,
704  cpl_frame *template, int isim) {
705  char fname[VIRCAM_PATHSZ];
706  cpl_frame *product_frame;
707  cpl_propertylist *plist;
708  cpl_type type;
709  int ptype;
710  const char *fctid="vircam_sci_postproc_save_image";
711 
712  /* Get some information so we can set a file name */
713 
714  ptype = (isim ? 0 : 1);
715  vircam_sci_product_name(cpl_frame_get_filename(template),ptype,
716  vircam_sci_postproc_config.prettynames,1,fname);
717 
718  /* Set up the file */
719 
720  if (access(fname,F_OK))
721  remove(fname);
722  product_frame = cpl_frame_new();
723  cpl_frame_set_filename(product_frame,fname);
724  if (isim)
725  cpl_frame_set_tag(product_frame,VIRCAM_PRO_MOSAIC);
726  else
727  cpl_frame_set_tag(product_frame,VIRCAM_PRO_MOSAIC_CONF);
728  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
729  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
730  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
731 
732  /* Set up the PHU header */
733 
734  plist = vircam_fits_get_phu(outim);
735  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,parlist,
736  vircam_recipename,"PRO-1.15",
737  template,1);
738 
739  /* 'Save' the PHU image */
740 
741  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
742  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
743  cpl_msg_error(fctid,"Cannot save product PHU");
744  cpl_frame_delete(product_frame);
745  return(-1);
746  }
747  cpl_frameset_insert(framelist,product_frame);
748 
749  /* Now save the extension */
750 
751  plist = vircam_fits_get_ehu(outim);
752  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
753  parlist,vircam_recipename,
754  "PRO-1.15",template);
755  if (isim)
756  type = CPL_TYPE_FLOAT;
757  else
758  type = CPL_TYPE_INT;
759  if (cpl_image_save(vircam_fits_get_image(outim),fname,type,
760  plist,CPL_IO_EXTEND) != CPL_ERROR_NONE) {
761  cpl_msg_error(fctid,"Cannot save product image extension -- %s",
762  cpl_error_get_message());
763  return(-1);
764  }
765  return(0);
766 }
767 
768 static int vircam_sci_postproc_save_cat(vir_tfits *outcat,
769  cpl_frameset *framelist,
770  cpl_parameterlist *parlist,
771  cpl_frame *template) {
772  char fname[VIRCAM_PATHSZ];
773  cpl_frame *product_frame;
774  cpl_propertylist *plist;
775  const char *fctid = "vircam_sci_postproc_save_cat";
776 
777  /* Get some information so we can set a file name */
778 
779  vircam_sci_product_name(cpl_frame_get_filename(template),2,
780  vircam_sci_postproc_config.prettynames,1,fname);
781 
782  /* Set up the file */
783 
784  if (access(fname,F_OK))
785  remove(fname);
786  product_frame = cpl_frame_new();
787  cpl_frame_set_filename(product_frame,fname);
788  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OBJCAT_SCI);
789  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_TABLE);
790  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
791  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
792 
793  /* Set up the PHU header */
794 
795  plist = vircam_tfits_get_phu(outcat);
796  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,parlist,
797  vircam_recipename,"PRO-1.15",NULL,0);
798 
799  /* 'Save' the PHU image */
800 
801  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
802  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
803  cpl_msg_error(fctid,"Cannot save product PHU");
804  cpl_frame_delete(product_frame);
805  return(-1);
806  }
807  cpl_frameset_insert(framelist,product_frame);
808 
809  /* Now save the extension */
810 
811  plist = vircam_tfits_get_ehu(outcat);
812  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
813  parlist,vircam_recipename,
814  "PRO-1.15",template);
815  if (cpl_table_save(vircam_tfits_get_table(outcat),NULL,plist,fname,
816  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
817  cpl_msg_error(fctid,"Cannot save product table extension -- %s",
818  cpl_error_get_message());
819  return(-1);
820  }
821  return(0);
822 }
823 
824 static void vircam_sci_postproc_init(void) {
825  ps.labels = NULL;
826  ps.paws = NULL;
827  ps.confs = NULL;
828  ps.cats = NULL;
829  ps.phottab = NULL;
830  ps.tphottab = NULL;
831  ps.catindex = NULL;
832  ps.catpath = NULL;
833  ps.catname = NULL;
834  ps.schlf_n = NULL;
835  ps.schlf_s = NULL;
836  ps.outmos = NULL;
837  ps.outmosconf = NULL;
838  ps.outmoscat = NULL;
839 }
840 
841 static int vircam_sci_testfrm_1(cpl_frame *fr, int nextn_expected, int isimg) {
842  int nextn,nerr,j;
843  vir_fits *test;
844  vir_tfits *testt;
845  const char *fctid="vircam_sci_testfrm";
846 
847  /* Return immediately if given nonsense */
848 
849  if (fr == NULL)
850  return(0);
851 
852  /* Test to see how many extensions there are and compare to see
853  if it matches the number expected */
854 
855  nextn = cpl_frame_get_nextensions(fr);
856  if (nextn != nextn_expected) {
857  cpl_msg_error(fctid,"Frame %s has %" CPL_SIZE_FORMAT " extensions, expected %" CPL_SIZE_FORMAT "\n",
858  cpl_frame_get_filename(fr),(cpl_size)nextn,
859  (cpl_size)nextn_expected);
860  return(1);
861  }
862 
863  /* Test to see if you can load each of the extensions */
864 
865  nerr = 0;
866  for (j = 1; j <= nextn; j++) {
867  if (isimg) {
868  test = vircam_fits_load(fr,CPL_TYPE_FLOAT,j);
869  if (test == NULL) {
870  cpl_msg_error(fctid,
871  "Frame image %s[%" CPL_SIZE_FORMAT "] won't load\n",
872  cpl_frame_get_filename(fr),(cpl_size)j);
873  nerr++;
874  continue;
875  }
876  freefits(test);
877  } else {
878  testt = vircam_tfits_load(fr,j);
879  if (testt == NULL) {
880  cpl_msg_error(fctid,
881  "Frame table %s[%" CPL_SIZE_FORMAT "] won't load\n",
882  cpl_frame_get_filename(fr),(cpl_size)j);
883  nerr++;
884  continue;
885  }
886  freetfits(testt);
887  }
888  }
889  return(nerr);
890 }
891 
892 /*---------------------------------------------------------------------------*/
921 /*---------------------------------------------------------------------------*/
922 
923 static void vircam_sci_product_name(const char *template, int producttype,
924  int nametype, int fnumber, char *outfname) {
925  const char *esonames[] = {"tile_","tile_conf_","tile_cat"};
926  const char *suffix[] = {"_tl","_tl_conf","_tl_cat"};
927  char *fname,*bname,*dot;
928 
929  /* If the name type is the ESO predictable sort, then it's easy. Just
930  use the esonames defined above and append the correct number */
931 
932  switch (nametype) {
933  case 0:
934  (void)sprintf(outfname,"%s%d.fits",esonames[producttype],fnumber);
935  break;
936 
937  /* If this is a temporary file, then just append tmp_ to the template
938  name and return that */
939 
940  case 2:
941  fname = cpl_strdup(template);
942  bname = basename(fname);
943  (void)sprintf(outfname,"tmp_%s",bname);
944  freespace(fname);
945  break;
946 
947  /* Ok, we want a pretty name... */
948 
949  case 1:
950  fname = cpl_strdup(template);
951  bname = basename(fname);
952  (void)sprintf(outfname,"%s",bname);
953  dot = strrchr(outfname,'.');
954  (void)sprintf(dot,"%s.fits",suffix[producttype]);
955  freespace(fname);
956  break;
957 
958  /* something else ?? */
959 
960  default:
961  (void)strcpy(outfname,"");
962  break;
963  }
964  return;
965 }
966 
967 static void vircam_sci_postproc_tidy(void) {
968  freespace(ps.labels);
969  freeframeset(ps.paws);
970  freeframeset(ps.confs);
971  freeframeset(ps.cats);
972  freeframe(ps.phottab);
973  freetable(ps.tphottab);
974  freeframe(ps.catindex);
975  freespace(ps.catpath);
976  freespace(ps.catname);
977  freeframe(ps.schlf_n);
978  freeframe(ps.schlf_s);
979  freefits(ps.outmos);
980  freefits(ps.outmosconf);
981  freetfits(ps.outmoscat);
982 }
983 
984 /*
985 
986 $Log: not supported by cvs2svn $
987 Revision 1.1 2013/10/15 17:01:44 jim
988 new entry
989 
990 
991 */
const char * vircam_get_license(void)
Definition: vircam_utils.c:92
cpl_table * vircam_tfits_get_table(vir_tfits *p)
Definition: vircam_tfits.c:364
int vircam_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Definition: vircam_utils.c:141
int vircam_pfits_get_filter(const cpl_propertylist *plist, char *filt)
Get the name of the current filter.
Definition: vircam_pfits.c:649
cpl_frame * vircam_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: vircam_utils.c:247
int vircam_grout(vir_tfits *intab, cpl_frameset *input_cats, cpl_frameset *input_confs, vir_tfits **outtab, int *status)
Correct input tile catalogues.
Definition: vircam_grout.c:108
int vircam_nebuliser(vir_fits *infile, vir_fits *inconf, int medfilt, int linfilt, int niter, int axis, int twod, int takeout_sky, int norm, int wantback, float signeg, float sigpos, vir_fits **backmap, int *status)
Remove small scale background variations.
cpl_propertylist * vircam_tfits_get_ehu(vir_tfits *p)
Definition: vircam_tfits.c:473
cpl_image * vircam_fits_get_image(vir_fits *p)
Definition: vircam_fits.c:349
cpl_frameset * vircam_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: vircam_utils.c:193
void vircam_dfs_set_product_exten_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit)
Definition: vircam_dfs.c:273
void vircam_dfs_set_product_primary_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit, int synch)
Definition: vircam_dfs.c:203
int vircam_catpars(cpl_frame *indx, char **catpath, char **catname)
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
Definition: vircam_fits.c:416
int vircam_platesol(cpl_propertylist *plist, cpl_propertylist *tlist, cpl_table *matchedstds, int nconst, int shiftan, int *status)
Work out a WCS for an image.
vir_fits * vircam_fits_load(cpl_frame *frame, cpl_type type, int nexten)
Definition: vircam_fits.c:80
vir_tfits * vircam_tfits_load(cpl_frame *table, int nexten)
Definition: vircam_tfits.c:78
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
Definition: vircam_fits.c:457
cpl_propertylist * vircam_tfits_get_phu(vir_tfits *p)
Definition: vircam_tfits.c:432
int vircam_getstds(cpl_propertylist *plist, int cache, char *path, char *catname, cpl_table **stds, int *status)
Get a table of standard stars that appear on an image from a catalogue.
int vircam_imcore(vir_fits *infile, vir_fits *conf, int ipix, float threshold, int icrowd, float rcore, int nbsize, int cattyp, float filtfwhm, vir_tfits **outtab, int *status)
Generate object catalogues from input images.
int vircam_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad, cpl_table **outtab, int *status)
Match object and standard star tables by their xy coordinates.
Definition: vircam_match.c:299
int vircam_dfs_set_groups(cpl_frameset *set)
Definition: vircam_dfs.c:87