VIRCAM Pipeline  2.3.12
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) 2015 European Southern Observatory
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 <casu_utils.h>
42 #include <casu_mods.h>
43 #include <casu_mask.h>
44 #include <casu_sky.h>
45 #include <casu_filt.h>
46 #include <casu_wcsutils.h>
47 #include <casu_stats.h>
48 
49 #include "vircam_utils.h"
50 #include "vircam_pfits.h"
51 #include "vircam_dfs.h"
52 #include "vircam_mods.h"
53 #include "vircam_paf.h"
54 #include "vircam_sky.h"
55 
56 
57 struct {
58 
59  /* Input command line parameters */
60 
61  int nebulise;
62  int grout;
63  int minphotom;
64  int prettynames;
65  int cdssearch;
66  int neb_medfilt;
67  int neb_linfilt;
68  int cat_ipix;
69  float cat_thresh;
70  int cat_icrowd;
71  float cat_rcore;
72  int cat_nbsize;
73  char *cacheloc;
74  float magerrcut;
75 } vircam_sci_postproc_config;
76 
77 static char vircam_recipename[VIRCAM_PATHSZ];
78 static char vircam_recipepaf[VIRCAM_PATHSZ];
79 
80 struct {
81  cpl_size *labels;
82  cpl_frameset *paws;
83  cpl_frameset *confs;
84  cpl_frameset *cats;
85 
86  cpl_frame *phottab;
87  cpl_table *tphottab;
88  cpl_frame *catindex;
89  char *catpath;
90  char *catname;
91  cpl_frame *schlf_n;
92  cpl_frame *schlf_s;
93 
94  casu_fits *outmos;
95  casu_fits *outmosconf;
96  casu_tfits *outmoscat;
97 } ps;
98 
99 /* Main stuff for CPL/esorex */
100 
101 static int vircam_science_postprocess_create(cpl_plugin *plugin);
102 static int vircam_science_postprocess_exec(cpl_plugin *plugin);
103 static int vircam_science_postprocess_destroy(cpl_plugin *plugin);
104 static int vircam_science_postprocess(cpl_parameterlist *parlist,
105  cpl_frameset *framelist);
106 
107 
108 static int vircam_sci_postproc_save_image(casu_fits *outim,
109  cpl_frameset *framelist,
110  cpl_parameterlist *parlist,
111  cpl_frame *template, int isim);
112 static int vircam_sci_postproc_save_cat(casu_tfits *outcat,
113  cpl_frameset *framelist,
114  cpl_parameterlist *parlist,
115  cpl_frame *template);
116 static void vircam_sci_postproc_init(void);
117 static int vircam_sci_testfrm_1(cpl_frame *fr, int nextn_expected, int isimg);
118 static void vircam_sci_product_name(const char *template, int producttype,
119  int nametype, int fnumber, char *outfname);
120 static void vircam_sci_postproc_tidy(void);
121 
122 static char vircam_science_postprocess_description[] =
123 "vircam_science_postprocess -- VIRCAM science postprocess recipe.\n\n"
124 "Mosaic a list of vircam stacks and generate a catalogue. Optionally nebulise\n"
125 "before generating the catalogue.\n"
126 "The program accepts the following files in the SOF:\n\n"
127 " Tag Description\n"
128 " -----------------------------------------------------------------------\n"
129 " %-22s A list of science jittered stacks images\n"
130 " %-22s A list of science jittered stack confidence maps\n"
131 " %-22s A list of science jittered stack catalogues\n"
132 " %-22s Northern Schlegel Map\n"
133 " %-22s Southern Schlegel Map\n"
134 " %-22s A master 2MASS index\n"
135 " %-22s A photometric calibration table\n"
136 "All of the above are required\n"
137 "\n";
138 
269 /* Function code */
270 
271 /*---------------------------------------------------------------------------*/
279 /*---------------------------------------------------------------------------*/
280 
281 int cpl_plugin_get_info(cpl_pluginlist *list) {
282  cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
283  cpl_plugin *plugin = &recipe->interface;
284  char alldesc[SZ_ALLDESC];
285  (void)snprintf(alldesc,SZ_ALLDESC,
286  vircam_science_postprocess_description,
287  VIRCAM_PRO_JITTERED_SCI,VIRCAM_PRO_CONF_SCI,
288  VIRCAM_PRO_OBJCAT_SCI,VIRCAM_CAL_SCHL_N,
289  VIRCAM_CAL_SCHL_S,VIRCAM_CAL_2MASS,VIRCAM_CAL_PHOTTAB);
290 
291  cpl_plugin_init(plugin,
292  CPL_PLUGIN_API,
293  VIRCAM_BINARY_VERSION,
294  CPL_PLUGIN_TYPE_RECIPE,
295  "vircam_science_postprocess",
296  "VIRCAM science postprocessing recipe",
297  alldesc,
298  "Jim Lewis",
299  "jrl@ast.cam.ac.uk",
301  vircam_science_postprocess_create,
302  vircam_science_postprocess_exec,
303  vircam_science_postprocess_destroy);
304 
305  cpl_pluginlist_append(list,plugin);
306 
307  return(0);
308 }
309 
310 /*---------------------------------------------------------------------------*/
319 /*---------------------------------------------------------------------------*/
320 
321 static int vircam_science_postprocess_create(cpl_plugin *plugin) {
322  cpl_recipe *recipe;
323  cpl_parameter *p;
324 
325  /* Get the recipe out of the plugin */
326 
327  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
328  recipe = (cpl_recipe *)plugin;
329  else
330  return(-1);
331 
332  /* Create the parameters list in the cpl_recipe object */
333 
334  recipe->parameters = cpl_parameterlist_new();
335 
336  /* Fill in flag to use the nebuliser */
337 
338  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.nebulise",
339  CPL_TYPE_BOOL,
340  "Nebulise the stacks before object detection?",
341  "vircam.vircam_science_postprocess",FALSE);
342  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"nebulise");
343  cpl_parameterlist_append(recipe->parameters,p);
344 
345  /* Fill in flag to grout the output catalogue */
346 
347  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.grout",
348  CPL_TYPE_BOOL,
349  "Grout the output tile catalogue?",
350  "vircam.vircam_science_postprocess",TRUE);
351  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"grout");
352  cpl_parameterlist_append(recipe->parameters,p);
353 
354  /* Fill in the minimum number of stars for photometry */
355 
356  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.minphotom",
357  CPL_TYPE_INT,
358  "Minimum number of stars for photometry solution",
359  "vircam.vircam_science_postprocess",20,1,
360  100000);
361  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"minphotom");
362  cpl_parameterlist_append(recipe->parameters,p);
363 
364  /* Fill in flag to use pretty names */
365 
366  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.prettynames",
367  CPL_TYPE_BOOL,
368  "Use pretty names?",
369  "vircam.vircam_science_postprocess",FALSE);
370  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"prettynames");
371  cpl_parameterlist_append(recipe->parameters,p);
372 
373  /* Fill in flag to decide whether to use CDS to get 2MASS standards */
374 
375  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cdssearch",
376  CPL_TYPE_BOOL,"Use CDS for 2MASS standards?",
377  "vircam.vircam_science_postprocess",FALSE);
378  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cdssearch");
379  cpl_parameterlist_append(recipe->parameters,p);
380 
381  /* Fill in the median filter size for nebuliser */
382 
383  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.neb_medfilt",
384  CPL_TYPE_INT,
385  "Median filter size for nebuliser",
386  "vircam.vircam_science_postprocess",101,11,
387  2047);
388  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"neb_medfilt");
389  cpl_parameterlist_append(recipe->parameters,p);
390 
391  /* Fill in the linear filter size for nebuliser */
392 
393  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.neb_linfilt",
394  CPL_TYPE_INT,
395  "Linear filter size for nebuliser",
396  "vircam.vircam_science_postprocess",33,3,2047);
397  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"neb_linfilt");
398  cpl_parameterlist_append(recipe->parameters,p);
399 
400  /* Fill in the minimum object size */
401 
402  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.cat_ipix",
403  CPL_TYPE_INT,
404  "Minimum pixel area for each detected object",
405  "vircam.vircam_science_postprocess",4,1,100000);
406  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_ipix");
407  cpl_parameterlist_append(recipe->parameters,p);
408 
409  /* Fill in the detection threshold parameter */
410 
411  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.cat_thresh",
412  CPL_TYPE_DOUBLE,
413  "Detection threshold in sigma above sky",
414  "vircam.vircam_science_postprocess",1.25,
415  1.0e-6,1.0e10);
416  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_thresh");
417  cpl_parameterlist_append(recipe->parameters,p);
418 
419  /* Fill in flag to use deblending software or not */
420 
421  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cat_icrowd",
422  CPL_TYPE_BOOL,"Use deblending?",
423  "vircam.vircam_science_postprocess",TRUE);
424  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_icrowd");
425  cpl_parameterlist_append(recipe->parameters,p);
426 
427  /* Fill in core radius */
428 
429  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.cat_rcore",
430  CPL_TYPE_DOUBLE,"Value of Rcore in pixels",
431  "vircam.vircam_science_postprocess",3.0,1.0e-6,
432  1024.0);
433  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_rcore");
434  cpl_parameterlist_append(recipe->parameters,p);
435 
436  /* Fill in background smoothing box size */
437 
438  p = cpl_parameter_new_range("vircam.vircam_science_postprocess.cat_nbsize",
439  CPL_TYPE_INT,"Background smoothing box size",
440  "vircam.vircam_science_postprocess",64,1,2048);
441  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cat_nbsize");
442  cpl_parameterlist_append(recipe->parameters,p);
443 
444  /* Location for standard star cache */
445 
446  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.cacheloc",
447  CPL_TYPE_STRING,
448  "Location for standard star cache",
449  "vircam.vircam_science_postprocess",".");
450  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cacheloc");
451  cpl_parameterlist_append(recipe->parameters,p);
452 
453  /* Magnitude error cut */
454 
455  p = cpl_parameter_new_value("vircam.vircam_science_postprocess.magerrcut",
456  CPL_TYPE_DOUBLE,
457  "Magnitude error cut",
458  "vircam.vircam_science_postprocess",100.0);
459  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"magerrcut");
460  cpl_parameterlist_append(recipe->parameters,p);
461 
462  /* Get out of here */
463 
464  return(0);
465 }
466 
467 /*---------------------------------------------------------------------------*/
473 /*---------------------------------------------------------------------------*/
474 
475 static int vircam_science_postprocess_exec(cpl_plugin *plugin) {
476  cpl_recipe *recipe;
477 
478  /* Get the recipe out of the plugin */
479 
480  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
481  recipe = (cpl_recipe *)plugin;
482  else
483  return(-1);
484 
485  return(vircam_science_postprocess(recipe->parameters,recipe->frames));
486 }
487 
488 /*---------------------------------------------------------------------------*/
494 /*---------------------------------------------------------------------------*/
495 
496 static int vircam_science_postprocess_destroy(cpl_plugin *plugin) {
497  cpl_recipe *recipe ;
498 
499  /* Get the recipe out of the plugin */
500 
501  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
502  recipe = (cpl_recipe *)plugin;
503  else
504  return(-1);
505 
506  cpl_parameterlist_delete(recipe->parameters);
507  return(0);
508 }
509 
510 /*---------------------------------------------------------------------------*/
517 /*---------------------------------------------------------------------------*/
518 
519 static int vircam_science_postprocess(cpl_parameterlist *parlist,
520  cpl_frameset *framelist) {
521  const char *fctid="vircam_scienc_postprocess";
522  cpl_parameter *p;
523  int nfail,status,n,i,j;
524  cpl_size nlab;
525  cpl_frameset *tmpframeset;
526  cpl_frame *frm,*frmc,*newfrm;
527  char tmpfilename[VIRCAM_PATHSZ],filt[16];
528  casu_fits *inf,*infc,*tmpoutmos,*tmpoutmosconf,*backmap;
529  casu_tfits *outmoscatg,*matchstds;
530  cpl_table *stdscat,*tab;
531  float gain;
532 
533  /* Check validity of the input frameset */
534 
535  if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
536  cpl_msg_error(fctid,"Input framelist NULL or has no input data");
537  return(-1);
538  }
539 
540  /* Initialise some things */
541 
542  vircam_sci_postproc_init();
543  (void)strncpy(vircam_recipename,fctid,VIRCAM_PATHSZ);
544  (void)snprintf(vircam_recipepaf,VIRCAM_PATHSZ,"VIRCAM/%s",fctid);
545 
546  /* Stacking special parameters */
547 
548  p = cpl_parameterlist_find(parlist,
549  "vircam.vircam_science_postprocess.nebulise");
550  vircam_sci_postproc_config.nebulise = cpl_parameter_get_bool(p);
551  p = cpl_parameterlist_find(parlist,
552  "vircam.vircam_science_postprocess.grout");
553  vircam_sci_postproc_config.grout = cpl_parameter_get_bool(p);
554  p = cpl_parameterlist_find(parlist,
555  "vircam.vircam_science_postprocess.minphotom");
556  vircam_sci_postproc_config.minphotom = cpl_parameter_get_int(p);
557  p = cpl_parameterlist_find(parlist,
558  "vircam.vircam_science_postprocess.prettynames");
559  vircam_sci_postproc_config.prettynames = cpl_parameter_get_bool(p);
560  p = cpl_parameterlist_find(parlist,
561  "vircam.vircam_science_postprocess.cdssearch");
562  vircam_sci_postproc_config.cdssearch = (cpl_parameter_get_bool(p) ? 1 : 0);
563  p = cpl_parameterlist_find(parlist,
564  "vircam.vircam_science_postprocess.neb_medfilt");
565  vircam_sci_postproc_config.neb_medfilt = cpl_parameter_get_int(p);
566  p = cpl_parameterlist_find(parlist,
567  "vircam.vircam_science_postprocess.neb_linfilt");
568  vircam_sci_postproc_config.neb_linfilt = cpl_parameter_get_int(p);
569 
570  p = cpl_parameterlist_find(parlist,
571  "vircam.vircam_science_postprocess.cat_ipix");
572  vircam_sci_postproc_config.cat_ipix = cpl_parameter_get_int(p);
573  p = cpl_parameterlist_find(parlist,
574  "vircam.vircam_science_postprocess.cat_thresh");
575  vircam_sci_postproc_config.cat_thresh = (float)cpl_parameter_get_double(p);
576  p = cpl_parameterlist_find(parlist,
577  "vircam.vircam_science_postprocess.cat_icrowd");
578  vircam_sci_postproc_config.cat_icrowd = cpl_parameter_get_bool(p);
579  p = cpl_parameterlist_find(parlist,
580  "vircam.vircam_science_postprocess.cat_rcore");
581  vircam_sci_postproc_config.cat_rcore = (float)cpl_parameter_get_double(p);
582  p = cpl_parameterlist_find(parlist,
583  "vircam.vircam_science_postprocess.cat_nbsize");
584  vircam_sci_postproc_config.cat_nbsize = cpl_parameter_get_int(p);
585 
586  /* Cache location */
587 
588  p = cpl_parameterlist_find(parlist,
589  "vircam.vircam_science_postprocess.cacheloc");
590  vircam_sci_postproc_config.cacheloc = (char *)cpl_parameter_get_string(p);
591 
592  /* Magnitude error cut */
593 
594  p = cpl_parameterlist_find(parlist,
595  "vircam.vircam_science_postprocess.magerrcut");
596  vircam_sci_postproc_config.magerrcut = (float)cpl_parameter_get_double(p);
597 
598  /* Sort out raw from calib frames */
599 
600  if (vircam_dfs_set_groups(framelist) != CASU_OK) {
601  cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
602  vircam_sci_postproc_tidy();
603  return(-1);
604  }
605 
606  /* Label the input frames */
607 
608  if ((ps.labels = cpl_frameset_labelise(framelist,casu_compare_tags,
609  &nlab)) == NULL) {
610  cpl_msg_error(fctid,"Cannot labelise the input frames");
611  vircam_sci_postproc_tidy();
612  return(-1);
613  }
614 
615  /* Get the input science frames and their confidence maps */
616 
617  if ((ps.paws =
618  casu_frameset_subgroup(framelist,ps.labels,(int)nlab,
619  VIRCAM_PRO_JITTERED_SCI)) == NULL) {
620  cpl_msg_error(fctid,"No science images to process!");
621  vircam_sci_postproc_tidy();
622  return(-1);
623  }
624  if ((ps.confs =
625  casu_frameset_subgroup(framelist,ps.labels,(int)nlab,
626  VIRCAM_PRO_CONF_SCI)) == NULL) {
627  cpl_msg_error(fctid,"No science confidence maps to process!");
628  vircam_sci_postproc_tidy();
629  return(-1);
630  }
631  if ((ps.cats =
632  casu_frameset_subgroup(framelist,ps.labels,(int)nlab,
633  VIRCAM_PRO_OBJCAT_SCI)) == NULL) {
634  cpl_msg_error(fctid,"No science object catalogues to process!");
635  vircam_sci_postproc_tidy();
636  return(-1);
637  }
638 
639  /* Check to see if there is a photometric table */
640 
641  nfail = 0;
642  if ((ps.phottab = casu_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
643  VIRCAM_CAL_PHOTTAB)) == NULL) {
644  cpl_msg_error(fctid,"No photometric table found");
645  vircam_sci_postproc_tidy();
646  return(-1);
647  }
648  n = cpl_frame_get_nextensions(ps.phottab);
649  nfail += vircam_sci_testfrm_1(ps.phottab,n,0);
650 
651 
652  /* Is the 2mass index file specified? */
653 
654  if (vircam_sci_postproc_config.cdssearch == 0) {
655  if ((ps.catindex = casu_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
656  VIRCAM_CAL_2MASS)) == NULL) {
657  cpl_msg_error(fctid,"No 2MASS index found -- cannot continue");
658  vircam_sci_postproc_tidy();
659  return(-1);
660  }
661  nfail += vircam_sci_testfrm_1(ps.catindex,1,0);
662  }
663 
664  /* Is the Northern Schlegel file specified? */
665 
666  if ((ps.schlf_n = casu_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
667  VIRCAM_CAL_SCHL_N)) == NULL) {
668  cpl_msg_error(fctid,"Schlegel North map not found -- cannot continue");
669  vircam_sci_postproc_tidy();
670  return(-1);
671  }
672  nfail += vircam_sci_testfrm_1(ps.schlf_n,0,1);
673 
674  /* Is the Southern Schlegel file specified? */
675 
676  if ((ps.schlf_s = casu_frameset_subgroup_1(framelist,ps.labels,(int)nlab,
677  VIRCAM_CAL_SCHL_S)) == NULL) {
678  cpl_msg_error(fctid,"Schlegel South map not found -- cannot continue");
679  vircam_sci_postproc_tidy();
680  return(-1);
681  }
682  nfail += vircam_sci_testfrm_1(ps.schlf_s,0,1);
683 
684  /* Check the cache location is writable */
685 
686  if (access(vircam_sci_postproc_config.cacheloc,R_OK+W_OK+X_OK) != 0) {
687  cpl_msg_error(fctid,"Cache location %s inacessible",
688  vircam_sci_postproc_config.cacheloc);
689  nfail++;
690  }
691 
692  /* Ok if any of this failed, then get out of here. This makes it a bit
693  simpler later on since we now know that all of the specified files
694  have the correct number of extensions and will load properly */
695 
696  if (nfail > 0) {
697  cpl_msg_error(fctid,
698  "There are %" CPL_SIZE_FORMAT " input file errors -- cannot continue",
699  (cpl_size)nfail);
700  vircam_sci_postproc_tidy();
701  return(-1);
702  }
703 
704  /* Get catalogue parameters */
705 
706  if (ps.catindex != NULL) {
707  if (casu_catpars(ps.catindex,&(ps.catpath),&(ps.catname)) == CASU_FATAL) {
708  vircam_sci_postproc_tidy();
709  return(-1);
710  }
711  freeframe(ps.catindex);
712  }
713 
714  /* Using the nebuliser before doing the catalogue, then create a frameset
715  of nebulised pawprints */
716 
717  status = CASU_OK;
718  if (vircam_sci_postproc_config.nebulise) {
719  tmpframeset = cpl_frameset_new();
720  n = (int)cpl_frameset_get_size(ps.paws);
721  cpl_msg_info(fctid,"Nebulising pawprints");
722  cpl_msg_indent_more();
723  for (i = 0; i < n; i++) {
724  cpl_msg_info(fctid,"Doing pawprint %" CPL_SIZE_FORMAT "",
725  (cpl_size)(i+1));
726  frm = cpl_frameset_get_position(ps.paws,(cpl_size)i);
727  frmc = cpl_frameset_get_position(ps.confs,(cpl_size)i);
728  (void)sprintf(tmpfilename,"tmp_%s",basename((char *)cpl_frame_get_filename(frm)));
729  newfrm = cpl_frame_new();
730  cpl_frame_set_tag(newfrm,VIRCAM_SCI_OBJECT_RAW);
731  cpl_frame_set_filename(newfrm,tmpfilename);
732  cpl_frameset_insert(tmpframeset,newfrm);
733  for (j = 1; j <= VIRCAM_NEXTN; j++) {
734  inf = casu_fits_load(frm,CPL_TYPE_FLOAT,j);
735  infc = casu_fits_load(frmc,CPL_TYPE_INT,j);
736 
737  (void)casu_nebuliser(inf,infc,101,33,3,1,0,0,0,0,10.0,3.0,
738  &backmap,&status);
739  if (status != CASU_OK) {
740  vircam_sci_postproc_tidy();
741  freefits(inf);
742  freefits(infc);
743  freeframeset(tmpframeset);
744  return(-1);
745  }
746  if (j == 1) {
747  if (access(tmpfilename,F_OK))
748  remove(tmpfilename);
749  cpl_image_save(NULL,tmpfilename,CPL_TYPE_UCHAR,
750  casu_fits_get_phu(inf),CPL_IO_DEFAULT);
751  }
752  cpl_image_save(casu_fits_get_image(inf),tmpfilename,
753  CPL_TYPE_FLOAT,casu_fits_get_ehu(inf),
754  CPL_IO_EXTEND);
755  freefits(inf);
756  freefits(infc);
757  }
758  }
759  cpl_msg_indent_less();
760 
761  /* Mosaic the nebulised files */
762 
763  cpl_msg_info(fctid,"Tiling nebulised pawprints");
764  (void)vircam_mosaic(tmpframeset,ps.confs,1,2,0.0,"EXPTIME",
765  25,&tmpoutmos,&tmpoutmosconf,&status);
766  if (status != CASU_OK) {
767  vircam_sci_postproc_tidy();
768  freeframeset(tmpframeset);
769  freefits(tmpoutmos);
770  freefits(tmpoutmosconf);
771  return(-1);
772  }
773 
774  /* Chuck nebulised pawprints */
775 
776  for (i = 0; i < n; i++) {
777  frm = cpl_frameset_get_position(tmpframeset,i);
778  remove(cpl_frame_get_filename(frm));
779  }
780  freeframeset(tmpframeset);
781 
782  /* Now do an imcore to create a catalogue from the nebulised mosaic. */
783 
784  cpl_msg_info(fctid,"Creating catalogue from nebulised mosaic");
785  (void)vircam_pfits_get_gain(casu_fits_get_ehu(tmpoutmos),&gain);
786  (void)casu_imcore(tmpoutmos,tmpoutmosconf,
787  vircam_sci_postproc_config.cat_ipix,
788  vircam_sci_postproc_config.cat_thresh,
789  vircam_sci_postproc_config.cat_icrowd,
790  vircam_sci_postproc_config.cat_rcore,
791  vircam_sci_postproc_config.cat_nbsize,6,
792  2.0,&(ps.outmoscat),gain,&status);
793  if (status != CASU_OK) {
794  vircam_sci_postproc_tidy();
795  freeframeset(tmpframeset);
796  freefits(tmpoutmos);
797  freefits(tmpoutmosconf);
798  return(-1);
799  }
800 
801  /* Chuck the nebulised tile and confidence map */
802 
803  freefits(tmpoutmos);
804  freefits(tmpoutmosconf);
805 
806  /* Do the real mosaic */
807 
808  cpl_msg_info(fctid,"Creating the real mosaic");
809  (void)vircam_mosaic(ps.paws,ps.confs,1,2,0.0,"EXPTIME",25,&(ps.outmos),
810  &(ps.outmosconf),&status);
811  if (status != CASU_OK) {
812  vircam_sci_postproc_tidy();
813  return(-1);
814  }
815 
816  /* Not using the nebuliser, so just do an imcore to create a catalogue
817  from the real mosaic */
818 
819  } else {
820 
821  /* First do the real mosaic */
822 
823  cpl_msg_info(fctid,"Creating the real mosaic");
824  (void)vircam_mosaic(ps.paws,ps.confs,1,2,0.0,"EXPTIME",25,&(ps.outmos),
825  &(ps.outmosconf),&status);
826  if (status != CASU_OK) {
827  vircam_sci_postproc_tidy();
828  return(-1);
829  }
830 
831  /* Now the imcore */
832 
833  cpl_msg_info(fctid,"Creating catalogue from mosaic");
834  (void)vircam_pfits_get_gain(casu_fits_get_ehu(ps.outmos),&gain);
835  (void)casu_imcore(ps.outmos,ps.outmosconf,
836  vircam_sci_postproc_config.cat_ipix,
837  vircam_sci_postproc_config.cat_thresh,
838  vircam_sci_postproc_config.cat_icrowd,
839  vircam_sci_postproc_config.cat_rcore,
840  vircam_sci_postproc_config.cat_nbsize,6,
841  2.0,&(ps.outmoscat),gain,&status);
842  }
843 
844  /* Get some standard stars and match it against the catalogue. Do
845  the WCS fit */
846 
847  cpl_msg_info(fctid,"Doing WCS on mosaic");
848  (void)casu_getstds(casu_fits_get_ehu(ps.outmos),1,
849  ps.catpath,ps.catname,
850  vircam_sci_postproc_config.cdssearch,
851  vircam_sci_postproc_config.cacheloc,&stdscat,&status);
852  (void)casu_matchstds(casu_tfits_get_table(ps.outmoscat),stdscat,300.0,
853  &tab,&status);
854  (void)casu_platesol(casu_fits_get_ehu(ps.outmos),
855  casu_tfits_get_ehu(ps.outmoscat),tab,6,1,
856  &status);
857  if (status != CASU_OK) {
858  freetable(stdscat);
859  freetable(tab);
860  vircam_sci_postproc_tidy();
861  return(-1);
862  }
863  freetable(tab);
864 
865  /* Grout the output catalogue (if requested) */
866 
867  if (vircam_sci_postproc_config.grout) {
868  n = (int)cpl_frameset_get_size(ps.paws);
869  if (n != 6) {
870  cpl_msg_info(fctid,
871  "Only %" CPL_SIZE_FORMAT " paws. No grout possible",
872  (cpl_size)n);
873  } else {
874  cpl_msg_info(fctid,"Grouting catalogue");
875  (void)vircam_grout(ps.outmoscat,ps.cats,ps.confs,&outmoscatg,
876  &status);
877  freetfits(ps.outmoscat);
878  ps.outmoscat = outmoscatg;
879  }
880  }
881 
882  /* Now do the photometry */
883 
884  cpl_msg_info(fctid,"Doing photometry on mosaic");
885  (void)casu_matchstds(casu_tfits_get_table(ps.outmoscat),stdscat,300.0,
886  &tab,&status);
887  freetable(stdscat);
888  ps.tphottab = cpl_table_load(cpl_frame_get_filename(ps.phottab),1,0);
890  matchstds = casu_tfits_wrap(tab,ps.outmoscat,NULL,NULL);
891  casu_photcal_extinct(&(ps.outmos),&matchstds,&(ps.outmoscat),1,
892  filt,ps.tphottab,
893  vircam_sci_postproc_config.minphotom,
894  ps.schlf_n,ps.schlf_s,"EXPTIME","ESO TEL AIRM START",
895  vircam_sci_postproc_config.magerrcut,&status);
896  cpl_table_save(tab,NULL,NULL,"mstds.fits",CPL_IO_DEFAULT);
897  if (status != CASU_OK) {
898  freetfits(matchstds);
899  vircam_sci_postproc_tidy();
900  return(-1);
901  }
902  freetfits(matchstds);
903 
904  /* Save the mosaic and its confidence map */
905 
906  cpl_msg_info(fctid,"Saving mosaic, confidence map and catalogue");
907  (void)vircam_sci_postproc_save_image(ps.outmos,framelist,parlist,
908  cpl_frameset_get_position(ps.paws,0),
909  1);
910  (void)vircam_sci_postproc_save_image(ps.outmosconf,framelist,parlist,
911  cpl_frameset_get_position(ps.paws,0),
912  0);
913  (void)vircam_sci_postproc_save_cat(ps.outmoscat,framelist,parlist,
914  cpl_frameset_get_position(ps.paws,0));
915 
916  /* Tidy up */
917 
918  vircam_sci_postproc_tidy();
919  return(0);
920 }
921 
922 /*---------------------------------------------------------------------------*/
947 /*---------------------------------------------------------------------------*/
948 
949 static int vircam_sci_postproc_save_image(casu_fits *outim,
950  cpl_frameset *framelist,
951  cpl_parameterlist *parlist,
952  cpl_frame *template, int isim) {
953  char fname[VIRCAM_PATHSZ];
954  cpl_frame *product_frame;
955  cpl_propertylist *plist,*plist2;
956  cpl_type type;
957  int ptype;
958  const char *fctid="vircam_sci_postproc_save_image";
959 
960  /* Get some information so we can set a file name */
961 
962  ptype = (isim ? 0 : 1);
963  vircam_sci_product_name(cpl_frame_get_filename(template),ptype,
964  vircam_sci_postproc_config.prettynames,1,fname);
965 
966  /* Set up the file */
967 
968  if (access(fname,F_OK))
969  remove(fname);
970  product_frame = cpl_frame_new();
971  cpl_frame_set_filename(product_frame,fname);
972  if (isim)
973  cpl_frame_set_tag(product_frame,VIRCAM_PRO_MOSAIC);
974  else
975  cpl_frame_set_tag(product_frame,VIRCAM_PRO_MOSAIC_CONF);
976  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
977  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
978  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
979 
980  /* Set up the PHU header */
981 
982  plist = cpl_propertylist_duplicate(casu_fits_get_phu(outim));
983  plist2 = cpl_propertylist_duplicate(casu_fits_get_ehu(outim));
984  casu_merge_propertylists(plist,plist2);
985  freepropertylist(plist2);
986  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,parlist,
987  vircam_recipename,"PRO-1.15",
988  template,1);
989 
990  /* Now save the data */
991 
992  if (isim)
993  type = CPL_TYPE_FLOAT;
994  else
995  type = CPL_TYPE_INT;
996  if (cpl_image_save(casu_fits_get_image(outim),fname,type,
997  plist,CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
998  cpl_msg_error(fctid,"Cannot save product image extension -- %s",
999  cpl_error_get_message());
1000  return(-1);
1001  }
1002  cpl_frameset_insert(framelist,product_frame);
1003  freepropertylist(plist);
1004  return(0);
1005 }
1006 
1007 /*---------------------------------------------------------------------------*/
1030 /*---------------------------------------------------------------------------*/
1031 
1032 static int vircam_sci_postproc_save_cat(casu_tfits *outcat,
1033  cpl_frameset *framelist,
1034  cpl_parameterlist *parlist,
1035  cpl_frame *template) {
1036  char fname[VIRCAM_PATHSZ];
1037  cpl_frame *product_frame;
1038  cpl_propertylist *plist;
1039  const char *fctid = "vircam_sci_postproc_save_cat";
1040 
1041  /* Get some information so we can set a file name */
1042 
1043  vircam_sci_product_name(cpl_frame_get_filename(template),2,
1044  vircam_sci_postproc_config.prettynames,1,fname);
1045 
1046  /* Set up the file */
1047 
1048  if (access(fname,F_OK))
1049  remove(fname);
1050  product_frame = cpl_frame_new();
1051  cpl_frame_set_filename(product_frame,fname);
1052  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OBJCAT_SCI);
1053  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_TABLE);
1054  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
1055  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
1056 
1057  /* Set up the PHU header */
1058 
1059  plist = casu_tfits_get_phu(outcat);
1060  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,parlist,
1061  vircam_recipename,"PRO-1.15",NULL,0);
1062 
1063  /* 'Save' the PHU image */
1064 
1065  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
1066  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
1067  cpl_msg_error(fctid,"Cannot save product PHU");
1068  cpl_frame_delete(product_frame);
1069  return(-1);
1070  }
1071  cpl_frameset_insert(framelist,product_frame);
1072 
1073  /* Now save the extension */
1074 
1075  plist = casu_tfits_get_ehu(outcat);
1076  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
1077  parlist,vircam_recipename,
1078  "PRO-1.15",template);
1079  if (cpl_table_save(casu_tfits_get_table(outcat),NULL,plist,fname,
1080  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
1081  cpl_msg_error(fctid,"Cannot save product table extension -- %s",
1082  cpl_error_get_message());
1083  return(-1);
1084  }
1085  return(0);
1086 }
1087 
1088 /*---------------------------------------------------------------------------*/
1110 /*---------------------------------------------------------------------------*/
1111 
1112 static int vircam_sci_testfrm_1(cpl_frame *fr, int nextn_expected, int isimg) {
1113  int nextn,nerr,j;
1114  casu_fits *test;
1115  casu_tfits *testt;
1116  const char *fctid="vircam_sci_testfrm";
1117 
1118  /* Return immediately if given nonsense */
1119 
1120  if (fr == NULL)
1121  return(0);
1122 
1123  /* Test to see how many extensions there are and compare to see
1124  if it matches the number expected */
1125 
1126  nextn = cpl_frame_get_nextensions(fr);
1127  if (nextn != nextn_expected) {
1128  cpl_msg_error(fctid,"Frame %s has %" CPL_SIZE_FORMAT " extensions, expected %" CPL_SIZE_FORMAT "\n",
1129  cpl_frame_get_filename(fr),(cpl_size)nextn,
1130  (cpl_size)nextn_expected);
1131  return(1);
1132  }
1133 
1134  /* Test to see if you can load each of the extensions */
1135 
1136  nerr = 0;
1137  for (j = 1; j <= nextn; j++) {
1138  if (isimg) {
1139  test = casu_fits_load(fr,CPL_TYPE_FLOAT,j);
1140  if (test == NULL) {
1141  cpl_msg_error(fctid,
1142  "Frame image %s[%" CPL_SIZE_FORMAT "] won't load\n",
1143  cpl_frame_get_filename(fr),(cpl_size)j);
1144  nerr++;
1145  continue;
1146  }
1147  freefits(test);
1148  } else {
1149  testt = casu_tfits_load(fr,j);
1150  if (testt == NULL) {
1151  cpl_msg_error(fctid,
1152  "Frame table %s[%" CPL_SIZE_FORMAT "] won't load\n",
1153  cpl_frame_get_filename(fr),(cpl_size)j);
1154  nerr++;
1155  continue;
1156  }
1157  freetfits(testt);
1158  }
1159  }
1160  return(nerr);
1161 }
1162 
1163 /*---------------------------------------------------------------------------*/
1192 /*---------------------------------------------------------------------------*/
1193 
1194 static void vircam_sci_product_name(const char *template, int producttype,
1195  int nametype, int fnumber, char *outfname) {
1196  const char *esonames[] = {"tile_","tile_conf_","tile_cat_"};
1197  const char *suffix[] = {"_tl","_tl_conf","_tl_cat"};
1198  char *fname,*bname,*dot;
1199 
1200  /* If the name type is the ESO predictable sort, then it's easy. Just
1201  use the esonames defined above and append the correct number */
1202 
1203  switch (nametype) {
1204  case 0:
1205  (void)sprintf(outfname,"%s%d.fits",esonames[producttype],fnumber);
1206  break;
1207 
1208  /* If this is a temporary file, then just append tmp_ to the template
1209  name and return that */
1210 
1211  case 2:
1212  fname = cpl_strdup(template);
1213  bname = basename(fname);
1214  (void)sprintf(outfname,"tmp_%s",bname);
1215  freespace(fname);
1216  break;
1217 
1218  /* Ok, we want a pretty name... */
1219 
1220  case 1:
1221  fname = cpl_strdup(template);
1222  bname = basename(fname);
1223  (void)sprintf(outfname,"%s",bname);
1224  dot = strrchr(outfname,'.');
1225  (void)sprintf(dot,"%s.fits",suffix[producttype]);
1226  freespace(fname);
1227  break;
1228 
1229  /* something else ?? */
1230 
1231  default:
1232  (void)strcpy(outfname,"");
1233  break;
1234  }
1235  return;
1236 }
1237 
1240 /*---------------------------------------------------------------------------*/
1255 /*---------------------------------------------------------------------------*/
1256 
1257 static void vircam_sci_postproc_init(void) {
1258  ps.labels = NULL;
1259  ps.paws = NULL;
1260  ps.confs = NULL;
1261  ps.cats = NULL;
1262  ps.phottab = NULL;
1263  ps.tphottab = NULL;
1264  ps.catindex = NULL;
1265  ps.catpath = NULL;
1266  ps.catname = NULL;
1267  ps.schlf_n = NULL;
1268  ps.schlf_s = NULL;
1269  ps.outmos = NULL;
1270  ps.outmosconf = NULL;
1271  ps.outmoscat = NULL;
1272 }
1273 
1274 /*---------------------------------------------------------------------------*/
1289 /*---------------------------------------------------------------------------*/
1290 
1291 static void vircam_sci_postproc_tidy(void) {
1292  freespace(ps.labels);
1293  freeframeset(ps.paws);
1294  freeframeset(ps.confs);
1295  freeframeset(ps.cats);
1296  freeframe(ps.phottab);
1297  freetable(ps.tphottab);
1298  freeframe(ps.catindex);
1299  freespace(ps.catpath);
1300  freespace(ps.catname);
1301  freeframe(ps.schlf_n);
1302  freeframe(ps.schlf_s);
1303  freefits(ps.outmos);
1304  freefits(ps.outmosconf);
1305  freetfits(ps.outmoscat);
1306 }
1307 
1308 /*
1309 
1310 $Log: not supported by cvs2svn $
1311 Revision 1.1 2013/10/15 17:01:44 jim
1312 new entry
1313 
1314 
1315 */
cpl_image * casu_fits_get_image(casu_fits *p)
Definition: casu_fits.c:436
casu_fits * casu_fits_load(cpl_frame *frame, cpl_type type, int nexten)
Definition: casu_fits.c:80
cpl_propertylist * casu_fits_get_phu(casu_fits *p)
Definition: casu_fits.c:531
cpl_propertylist * casu_fits_get_ehu(casu_fits *p)
Definition: casu_fits.c:576
int casu_imcore(casu_fits *infile, casu_fits *conf, int ipix, float threshold, int icrowd, float rcore, int nbsize, int cattype, float filtfwhm, casu_tfits **outtab, float gainloc, int *status)
Generate object catalogues from input images.
Definition: casu_imcore.c:149
int casu_nebuliser(casu_fits *infile, casu_fits *inconf, int medfilt, int linfilt, int niter, int axis, int twod, int takeout_sky, int norm, int wantback, float signeg, float sigpos, casu_fits **backmap, int *status)
Remove small scale background variations.
int casu_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: casu_match.c:300
int casu_photcal_extinct(casu_fits **images, casu_tfits **mstds, casu_tfits **cats, int nimages, char *filt, cpl_table *phottab, int minstars, cpl_frame *schlf_n, cpl_frame *schlf_s, const char *expkey, const char *amkey, float magerrcut, int *status)
Do photometric calibration.
int casu_platesol(cpl_propertylist *plist, cpl_propertylist *tlist, cpl_table *matchedstds, int nconst, int shiftan, int *status)
Work out a WCS for an image.
int casu_getstds(cpl_propertylist *plist, int cache, char *path, char *catname, int cdssearch, char *cacheloc, cpl_table **stds, int *status)
Get a table of standard stars that appear on an image from a catalogue.
Definition: casu_getstds.c:159
cpl_table * casu_tfits_get_table(casu_tfits *p)
Definition: casu_tfits.c:364
cpl_propertylist * casu_tfits_get_phu(casu_tfits *p)
Definition: casu_tfits.c:432
cpl_propertylist * casu_tfits_get_ehu(casu_tfits *p)
Definition: casu_tfits.c:473
casu_tfits * casu_tfits_load(cpl_frame *table, int nexten)
Definition: casu_tfits.c:78
casu_tfits * casu_tfits_wrap(cpl_table *tab, casu_tfits *model, cpl_propertylist *phu, cpl_propertylist *ehu)
Definition: casu_tfits.c:739
cpl_frame * casu_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Extract a frame of a given label from a frameset.
Definition: casu_utils.c:206
int casu_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Compare input tags.
Definition: casu_utils.c:96
void casu_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
Merge two propertylists.
Definition: casu_utils.c:399
int casu_catpars(cpl_frame *indx, char **catpath, char **catname)
Find the name of the standard catalogue and its location.
Definition: casu_utils.c:899
cpl_frameset * casu_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Extract a frameset from another frameset.
Definition: casu_utils.c:149
int vircam_mosaic(cpl_frameset *infiles, cpl_frameset *inconf, int interp, int skyflag, float skywish_in, const char *expkey, int conflim, casu_fits **out, casu_fits **outc, int *status)
Create a vircam mosaic.
int vircam_grout(casu_tfits *intab, cpl_frameset *input_cats, cpl_frameset *input_confs, casu_tfits **outtab, int *status)
Correct input tile catalogues.
Definition: vircam_grout.c:108
int vircam_dfs_set_groups(cpl_frameset *set)
Definition: vircam_dfs.c:115
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:227
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:299
int vircam_pfits_get_gain(const cpl_propertylist *plist, float *gain)
Get the value of the detector gain.
Definition: vircam_pfits.c:713
int vircam_pfits_get_filter(const cpl_propertylist *plist, char *filt)
Get the name of the current filter.
Definition: vircam_pfits.c:649
const char * vircam_get_license(void)
Definition: vircam_utils.c:116