VIRCAM Pipeline  1.3.3
vircam_jmp_utils.c
1 /* $Id: vircam_jmp_utils.c,v 1.57 2012-01-15 17:40:09 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2005 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: 2012-01-15 17:40:09 $
24  * $Revision: 1.57 $
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 <cpl.h>
35 #include <math.h>
36 #include <string.h>
37 
38 #include "vircam_utils.h"
39 #include "vircam_pfits.h"
40 #include "vircam_dfs.h"
41 #include "vircam_mods.h"
42 #include "vircam_stats.h"
43 #include "vircam_fits.h"
44 #include "vircam_tfits.h"
45 #include "vircam_wcsutils.h"
46 #include "vircam_paf.h"
47 #include "vircam_sky.h"
48 
49 #include "vircam_jmp_utils.h"
50 
51 static char *vircam_jmp_outfile(const char *bname, int ind, int isfits);
52 
66 /*---------------------------------------------------------------------------*/
85 /*---------------------------------------------------------------------------*/
86 
87 extern int vircam_jmp_save_simple(cpl_frameset *framelist,
88  cpl_parameterlist *parlist) {
89  cpl_propertylist *plist;
90  int i,isdummy;
91  cpl_frame *product_frame,*template;
92  char *fname;
93  const char *base[] = {"","simple_jmp","simple_std","simple_mes"};
94  const char *fctid = "vircam_jmp_save_simple";
95 
96  /* Initialise the product frameset */
97 
98  if (ps.product_frames_simple == NULL)
99  ps.product_frames_simple = cpl_malloc(ps.nscience*sizeof(cpl_frame *));
100 
101  /* Loop for each of the frames in the ustep sequence */
102 
103  for (i = 0; i < ps.nscience; i++) {
104  fname = vircam_jmp_outfile(base[recflag],i,1);
105  isdummy = (vircam_fits_get_status(ps.sci_fits[i]) != VIR_OK);
106  template = cpl_frameset_get_frame(ps.science_frames,i);
107 
108  /* If we need to make a PHU then do that now based on the first frame
109  in the input frame list */
110 
111  if (isfirst) {
112 
113  /* Create a new product frame object and define some tags */
114 
115  product_frame = cpl_frame_new();
116  cpl_frame_set_filename(product_frame,fname);
117  switch (recflag) {
118  case RECSCI:
119  cpl_frame_set_tag(product_frame,VIRCAM_PRO_SIMPLE_SCI);
120  break;
121  case RECSTD:
122  cpl_frame_set_tag(product_frame,VIRCAM_PRO_SIMPLE_STD);
123  break;
124  default:
125  cpl_frame_set_tag(product_frame,VIRCAM_PRO_SIMPLE_SCI);
126  break;
127  }
128  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
129  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
130  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
131 
132  /* Set up the PHU header */
133 
134  plist = vircam_fits_get_phu(ps.sci_fits[i]);
135  vircam_dfs_set_product_primary_header(plist,product_frame,
136  framelist,parlist,
137  vircam_recipename,
138  "PRO-1.15",template,1);
139 
140  /* 'Save' the PHU image */
141 
142  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
143  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
144  cpl_msg_error(fctid,"Cannot save product PHU");
145  cpl_frame_delete(product_frame);
146  freespace(fname);
147  return(-1);
148  }
149  cpl_frameset_insert(framelist,product_frame);
150  ps.product_frames_simple[i] = product_frame;
151  }
152 
153  /* Get the extension property list */
154 
155  plist = vircam_fits_get_ehu(ps.sci_fits[i]);
156  if (isdummy)
157  vircam_dummy_property(plist);
158 
159  /* Fiddle with the header now */
160 
161  product_frame = ps.product_frames_simple[i];
162  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
163  parlist,vircam_recipename,
164  "PRO-1.15",template);
165  if (cpl_image_save(vircam_fits_get_image(ps.sci_fits[i]),fname,
166  CPL_TYPE_FLOAT,plist,
167  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
168  cpl_msg_error(fctid,"Cannot save product image extension");
169  freespace(fname);
170  return(-1);
171  }
172 
173  /* Clear the allocated workspace */
174 
175  freespace(fname);
176  }
177 
178  /* Get out of here */
179 
180  return(0);
181 }
182 
183 /*---------------------------------------------------------------------------*/
202 /*---------------------------------------------------------------------------*/
203 
204 extern int vircam_jmp_save_simple_offsets(cpl_frameset *framelist,
205  cpl_parameterlist *parlist) {
206  cpl_propertylist *plist;
207  int i,isdummy;
208  cpl_frame *product_frame,*template;
209  char *fname;
210  const char *base = "simple_off";
211  const char *fctid = "vircam_jmp_save_simple_offsets";
212 
213  /* Initialise the product frameset */
214 
215  if (ps.product_frames_simple_off == NULL)
216  ps.product_frames_simple_off =
217  cpl_malloc(ps.noffsets*sizeof(cpl_frame *));
218 
219  /* Loop for each of the frames in the ustep sequence */
220 
221  for (i = 0; i < ps.noffsets; i++) {
222  fname = vircam_jmp_outfile(base,i,1);
223  isdummy = (vircam_fits_get_status(ps.offsky_fits[i]) != VIR_OK);
224  template = cpl_frameset_get_frame(ps.offset_skies,i);
225 
226  /* If we need to make a PHU then do that now based on the first frame
227  in the input frame list */
228 
229  if (isfirst) {
230 
231  /* Create a new product frame object and define some tags */
232 
233  product_frame = cpl_frame_new();
234  cpl_frame_set_filename(product_frame,fname);
235  cpl_frame_set_tag(product_frame,VIRCAM_PRO_SIMPLE_SKY);
236  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
237  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
238  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
239 
240  /* Set up the PHU header */
241 
242  plist = vircam_fits_get_phu(ps.offsky_fits[i]);
243  vircam_dfs_set_product_primary_header(plist,product_frame,
244  framelist,parlist,
245  vircam_recipename,
246  "PRO-1.15",template,1);
247 
248  /* 'Save' the PHU image */
249 
250  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
251  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
252  cpl_msg_error(fctid,"Cannot save product PHU");
253  cpl_frame_delete(product_frame);
254  freespace(fname);
255  return(-1);
256  }
257  cpl_frameset_insert(framelist,product_frame);
258  ps.product_frames_simple_off[i] = product_frame;
259  }
260 
261  /* Get the extension property list */
262 
263  plist = vircam_fits_get_ehu(ps.offsky_fits[i]);
264  if (isdummy)
265  vircam_dummy_property(plist);
266 
267  /* Fiddle with the header now */
268 
269  product_frame = ps.product_frames_simple_off[i];
270  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
271  parlist,vircam_recipename,
272  "PRO-1.15",template);
273  if (cpl_image_save(vircam_fits_get_image(ps.offsky_fits[i]),fname,
274  CPL_TYPE_FLOAT,plist,
275  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
276  cpl_msg_error(fctid,"Cannot save product image extension");
277  freespace(fname);
278  return(-1);
279  }
280 
281  /* Clear the allocated workspace */
282 
283  freespace(fname);
284  }
285 
286  /* Get out of here */
287 
288  return(0);
289 }
290 
291 /*---------------------------------------------------------------------------*/
310 /*---------------------------------------------------------------------------*/
311 
312 extern int vircam_jmp_save_offsky(cpl_frameset *framelist,
313  cpl_parameterlist *parlist) {
314  cpl_propertylist *p;
315  int isdummy;
316  vir_fits *ff;
317  cpl_image *fim;
318  cpl_frame *product_frame,*template;
319  char *fname;
320  const char *base = "offsky";
321  const char *fctid = "vircam_jmp_save_offsky";
322 
323  /* Work out which frame to base the output on. If this particular
324  sequence failed for whatever reason, there will be a dummy sky frame. */
325 
326  ff = ps.outsky;
327  fim = vircam_fits_get_image(ff);
328  isdummy = (vircam_fits_get_status(ff) != VIR_OK);
329  template = cpl_frameset_get_frame(ps.offset_skies,0);
330 
331  /* Create some names */
332 
333  fname = vircam_jmp_outfile(base,0,1);
334 
335  /* If we need to make a PHU then do that now based on the first frame
336  in the input frame list */
337 
338  if (isfirst) {
339 
340  /* Create a new product frame object and define some tags */
341 
342  product_frame = cpl_frame_new();
343  cpl_frame_set_filename(product_frame,fname);
344  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OFFSET_SKY);
345  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
346  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
347  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
348  ps.product_frame_sky = product_frame;
349 
350  /* Set up the PHU header. */
351 
352  p = vircam_fits_get_phu(ff);
353  vircam_dfs_set_product_primary_header(p,product_frame,framelist,
354  parlist,vircam_recipename,
355  "PRO-1.15",template,0);
356 
357  /* 'Save' the PHU image */
358 
359  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,p,
360  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
361  cpl_msg_error(fctid,"Cannot save product PHU");
362  cpl_frame_delete(product_frame);
363  freespace(fname);
364  return(-1);
365  }
366  cpl_frameset_insert(framelist,product_frame);
367  }
368 
369  /* Get the extension property list */
370 
371  p = cpl_propertylist_duplicate(vircam_fits_get_ehu(ff));
372  if (isdummy)
374 
375  /* Fiddle with the header now */
376 
377  product_frame = ps.product_frame_sky;
378  vircam_dfs_set_product_exten_header(p,product_frame,framelist,parlist,
379  vircam_recipename,"PRO-1.15",template);
380  if (cpl_image_save(fim,fname,CPL_TYPE_FLOAT,p,CPL_IO_EXTEND) !=
381  CPL_ERROR_NONE) {
382  cpl_msg_error(fctid,"Cannot save product image extension");
383  freespace(fname);
384  return(-1);
385  }
386 
387  /* Quick tidy */
388 
389  cpl_propertylist_delete(p);
390  freespace(fname);
391 
392  /* Get out of here */
393 
394  return(0);
395 }
396 
397 
398 
399 /*---------------------------------------------------------------------------*/
418 /*---------------------------------------------------------------------------*/
419 
420 extern int vircam_jmp_save_super(cpl_frameset *framelist,
421  cpl_parameterlist *parlist) {
422  cpl_propertylist *plist,*p;
423  int i,isdummy,isdummyc,j,jref;
424  cpl_frame *product_frame,*template;
425  char *fname,*fnamec;
426  const char *base[] = {"","super_jmp","super_std","super_mes"};
427  const char *basec[] = {"","superc_jmp","superc_std","superc_mes"};
428  vir_fits *ff,*ffc;
429  cpl_image *fim,*fimc;
430  const char *fctid = "vircam_jmp_save_super";
431 
432  /* Initialise the product frameset */
433 
434  if (ps.product_frames_super == NULL)
435  ps.product_frames_super = cpl_malloc(ps.nustep_sets*sizeof(cpl_frame *));
436  if (ps.product_frames_superc == NULL)
437  ps.product_frames_superc = cpl_malloc(ps.nustep_sets*sizeof(cpl_frame *));
438 
439  /* Loop for each of the ustep sequences */
440 
441  for (i = 0; i < ps.nustep_sets; i++) {
442 
443  /* Work out which frame to base the output on. If this particular
444  microstep sequence failed for whatever reason, there will be
445  a dummy super frame. */
446 
447  ff = ps.ustep_sets[i].super;
448  fim = vircam_fits_get_image(ff);
449  ffc = ps.ustep_sets[i].superc;
450  fimc = vircam_fits_get_image(ffc);
451  isdummy = (vircam_fits_get_status(ff) != VIR_OK);
452  isdummyc = (vircam_fits_get_status(ffc) != VIR_OK);
453 
454  /* Create some names */
455 
456  fname = vircam_jmp_outfile(base[recflag],i,1);
457  fnamec = vircam_jmp_outfile(basec[recflag],i,1);
458 
459  /* Get a reference to the first frame in this set */
460 
461  jref = -1;
462  for (j = 0; j < ps.ustep_sets[i].nframes; j++) {
463  if (ps.sci_fits[j] == ps.ustep_sets[i].f[j]) {
464  jref = j;
465  break;
466  }
467  }
468  if (jref != -1)
469  template = cpl_frameset_get_frame(ps.science_frames,jref);
470  else
471  template = NULL;
472 
473  /* If we need to make a PHU then do that now based on the first frame
474  in the input frame list */
475 
476  if (isfirst) {
477 
478  /* Create a new product frame object and define some tags */
479 
480  product_frame = cpl_frame_new();
481  cpl_frame_set_filename(product_frame,fname);
482  switch (recflag) {
483  case RECSCI:
484  cpl_frame_set_tag(product_frame,VIRCAM_PRO_INTER_SCI);
485  break;
486  case RECSTD:
487  cpl_frame_set_tag(product_frame,VIRCAM_PRO_INTER_STD);
488  break;
489  default:
490  cpl_frame_set_tag(product_frame,VIRCAM_PRO_INTER_SCI);
491  break;
492  }
493  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
494  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
495  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
496 
497  /* Set up the PHU header. */
498 
499  plist = vircam_fits_get_phu(ff);
500  vircam_dfs_set_product_primary_header(plist,product_frame,
501  framelist,parlist,
502  vircam_recipename,
503  "PRO-1.15",template,1);
504 
505  /* 'Save' the PHU image */
506 
507  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
508  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
509  cpl_msg_error(fctid,"Cannot save product PHU");
510  cpl_frame_delete(product_frame);
511  freespace(fname);
512  freespace(fnamec);
513  return(-1);
514  }
515  cpl_frameset_insert(framelist,product_frame);
516  ps.product_frames_super[i] = product_frame;
517 
518  /* Now do exactly the same thing for the confidence map */
519 
520  product_frame = cpl_frame_new();
521  cpl_frame_set_filename(product_frame,fnamec);
522  switch (recflag) {
523  case RECSCI:
524  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_INTER_SCI);
525  break;
526  case RECSTD:
527  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_INTER_STD);
528  break;
529  default:
530  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_INTER_SCI);
531  break;
532  }
533  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
534  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
535  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
536 
537  /* Set up the PHU header. */
538 
539  plist = vircam_fits_get_phu(ffc);
540  vircam_dfs_set_product_primary_header(plist,product_frame,
541  framelist,parlist,
542  vircam_recipename,
543  "PRO-1.15",template,1);
544 
545  /* 'Save' the PHU image */
546 
547  if (cpl_image_save(NULL,fnamec,CPL_TYPE_UCHAR,plist,
548  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
549  cpl_msg_error(fctid,"Cannot save product PHU");
550  cpl_frame_delete(product_frame);
551  freespace(fname);
552  freespace(fnamec);
553  return(-1);
554  }
555  cpl_frameset_insert(framelist,product_frame);
556  ps.product_frames_superc[i] = product_frame;
557  }
558 
559 
560  /* Get the extension property list */
561 
562  p = cpl_propertylist_duplicate(vircam_fits_get_ehu(ff));
563  if (isdummy)
565 
566  /* Fiddle with the header now */
567 
568  product_frame = ps.product_frames_super[i];
569  vircam_dfs_set_product_exten_header(p,product_frame,framelist,parlist,
570  vircam_recipename,"PRO-1.15",
571  template);
572  if (cpl_image_save(fim,fname,CPL_TYPE_FLOAT,p,CPL_IO_EXTEND) !=
573  CPL_ERROR_NONE) {
574  cpl_msg_error(fctid,"Cannot save product image extension");
575  freespace(fname);
576  freespace(fnamec);
577  return(-1);
578  }
579  cpl_propertylist_delete(p);
580 
581  /* And now for the confidence map */
582 
583  p = cpl_propertylist_duplicate(vircam_fits_get_ehu(ffc));
584  if (isdummyc)
586 
587  /* Fiddle with the header now */
588 
589  product_frame = ps.product_frames_superc[i];
590  vircam_dfs_set_product_exten_header(p,product_frame,framelist,parlist,
591  vircam_recipename,"PRO-1.15",
592  template);
593  if (cpl_image_save(fimc,fnamec,CPL_TYPE_SHORT,p,CPL_IO_EXTEND) !=
594  CPL_ERROR_NONE) {
595  cpl_msg_error(fctid,"Cannot save confidence map image extension");
596  freespace(fname);
597  freespace(fnamec);
598  return(-1);
599  }
600  cpl_propertylist_delete(p);
601 
602  /* Clear the allocated workspace */
603 
604  freespace(fname);
605  freespace(fnamec);
606  }
607 
608  /* Get out of here */
609 
610  return(0);
611 }
612 
613 /*---------------------------------------------------------------------------*/
632 /*---------------------------------------------------------------------------*/
633 
634 extern int vircam_jmp_save_stack(cpl_frameset *framelist,
635  cpl_parameterlist *parlist) {
636  cpl_propertylist *plist,*p,*pafprop;
637  int isdummy,isdummyc;
638  vir_fits *ff,*ffc;
639  cpl_image *fim,*fimc;
640  cpl_frame *product_frame;
641  char *fname,*fnamec,*fnamepaf;
642  const char *base[] = {"","stack_jmp","stack_std","stack_mes"};
643  const char *basec[] = {"","stackc_jmp","stackc_std","stackc_mes"};
644  const char *fctid = "vircam_jmp_save_stack";
645 
646  /* Work out which frame to base the output on. If this particular
647  jitter sequence failed for whatever reason, there will be
648  a dummy stack frame. */
649 
650  ff = ps.stack_frame;
651  fim = vircam_fits_get_image(ff);
652  ffc = ps.stackc_frame;
653  fimc = vircam_fits_get_image(ffc);
654  isdummy = (vircam_fits_get_status(ff) != VIR_OK);
655  isdummyc = (vircam_fits_get_status(ffc) != VIR_OK);
656 
657  /* Create some names */
658 
659  fname = vircam_jmp_outfile(base[recflag],0,1);
660  fnamec = vircam_jmp_outfile(basec[recflag],0,1);
661  fnamepaf = vircam_jmp_outfile(base[recflag],0,0);
662 
663  /* If we need to make a PHU then do that now based on the first frame
664  in the input frame list */
665 
666  if (isfirst) {
667 
668  /* Create a new product frame object and define some tags */
669 
670  product_frame = cpl_frame_new();
671  cpl_frame_set_filename(product_frame,fname);
672  switch (recflag) {
673  case RECSCI:
674  cpl_frame_set_tag(product_frame,VIRCAM_PRO_JITTERED_SCI);
675  break;
676  case RECSTD:
677  cpl_frame_set_tag(product_frame,VIRCAM_PRO_JITTERED_STD);
678  break;
679  default:
680  cpl_frame_set_tag(product_frame,VIRCAM_PRO_JITTERED_SCI);
681  break;
682  }
683  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
684  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
685  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
686  ps.product_frame_stack = product_frame;
687 
688  /* Set up the PHU header. */
689 
690  plist = vircam_fits_get_phu(ff);
691  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,
692  parlist,vircam_recipename,
693  "PRO-1.15",NULL,0);
694 
695  /* 'Save' the PHU image */
696 
697  if (cpl_image_save(NULL,fname,CPL_TYPE_UCHAR,plist,
698  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
699  cpl_msg_error(fctid,"Cannot save product PHU");
700  cpl_frame_delete(product_frame);
701  freespace(fname);
702  freespace(fnamec);
703  return(-1);
704  }
705  cpl_frameset_insert(framelist,product_frame);
706 
707  /* Now do exactly the same thing for the confidence map */
708 
709  product_frame = cpl_frame_new();
710  cpl_frame_set_filename(product_frame,fnamec);
711  switch (recflag) {
712  case RECSCI:
713  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_SCI);
714  break;
715  case RECSTD:
716  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_STD);
717  break;
718  default:
719  cpl_frame_set_tag(product_frame,VIRCAM_PRO_CONF_SCI);
720  break;
721  }
722  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
723  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
724  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
725  ps.product_frame_stackc = product_frame;
726 
727  /* Set up the PHU header. */
728 
729  plist = vircam_fits_get_phu(ffc);
730  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,
731  parlist,vircam_recipename,
732  "PRO-1.15",NULL,0);
733 
734  /* 'Save' the PHU image */
735 
736  if (cpl_image_save(NULL,fnamec,CPL_TYPE_UCHAR,plist,
737  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
738  cpl_msg_error(fctid,"Cannot save product PHU");
739  cpl_frame_delete(product_frame);
740  freespace(fname);
741  freespace(fnamec);
742  return(-1);
743  }
744  cpl_frameset_insert(framelist,product_frame);
745  }
746 
747  /* Get the extension property list */
748 
749  p = cpl_propertylist_duplicate(vircam_fits_get_ehu(ff));
750  if (isdummy) {
752  vircam_merge_propertylists(p,dummyqc);
753  }
754 
755  /* Fiddle with the header now */
756 
757  product_frame = ps.product_frame_stack;
758  vircam_dfs_set_product_exten_header(p,product_frame,framelist,parlist,
759  vircam_recipename,"PRO-1.15",NULL);
760  if (cpl_image_save(fim,fname,CPL_TYPE_FLOAT,p,CPL_IO_EXTEND) !=
761  CPL_ERROR_NONE) {
762  cpl_msg_error(fctid,"Cannot save product image extension");
763  freespace(fname);
764  freespace(fnamec);
765  return(-1);
766  }
767 
768  /* Write PAF */
769 
770  pafprop = vircam_paf_req_items(p);
771  vircam_merge_propertylists(pafprop,ps.phupaf);
772  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"ESO INS FILT1 NAME");
773  vircam_paf_append(pafprop,p,"ESO DET NDIT");
774  vircam_paf_append(pafprop,p,"ESO PRO CATG");
775  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"RA");
776  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"DEC");
777  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"ESO TEL AIRM START");
778  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"ESO TEL GUID FWHM");
779  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"ESO TEL AMBI RHUM");
780  vircam_paf_append(pafprop,vircam_fits_get_phu(ff),"ESO OBS TARG NAME");
781  if (vircam_paf_print(fnamepaf,vircam_recipepaf,"QC file",
782  pafprop) != VIR_OK)
783  cpl_msg_warning(fctid,"Unable to save PAF for stack");
784  cpl_propertylist_delete(pafprop);
785 
786  /* Quick tidy */
787 
788  cpl_propertylist_delete(p);
789 
790  /* And now for the confidence map. Erase any stray QC headers
791  that might exist if you've used a BPM instead of a confidence
792  map. This only occurs if this is a dummy output */
793 
794  p = cpl_propertylist_duplicate(vircam_fits_get_ehu(ffc));
795  if (isdummyc) {
797  cpl_propertylist_erase_regexp(p,"ESO QC",0);
798  }
799 
800  /* Fiddle with the header now */
801 
802  product_frame = ps.product_frame_stackc;
803  vircam_dfs_set_product_exten_header(p,product_frame,framelist,parlist,
804  vircam_recipename,"PRO-1.15",NULL);
805  if (cpl_image_save(fimc,fnamec,CPL_TYPE_SHORT,p,CPL_IO_EXTEND) !=
806  CPL_ERROR_NONE) {
807  cpl_msg_error(fctid,"Cannot save product image extension");
808  freespace(fname);
809  freespace(fnamec);
810  freepropertylist(p);
811  return(-1);
812  }
813  cpl_propertylist_delete(p);
814 
815  /* Clear the allocated workspace */
816 
817  freespace(fname);
818  freespace(fnamec);
819  freespace(fnamepaf);
820 
821  /* Get out of here */
822 
823  return(0);
824 }
825 
826 /*---------------------------------------------------------------------------*/
845 /*---------------------------------------------------------------------------*/
846 
847 extern int vircam_jmp_save_catalogue(cpl_frameset *framelist,
848  cpl_parameterlist *parlist) {
849  cpl_frame *product_frame;
850  int isdummy,i,status;
851  cpl_table *ftab;
852  cpl_propertylist *ehu,*phu,*ehu2,*pafprop;
853  char *fname,*fnamepaf;
854  const char *base[] = {"","catalogue_jmp","catalogue_std","catalogue_mes"};
855  const char *fctid = "vircam_jmp_save_catalogue";
856 
857  /* Work out whether you have a table to save or not. If you don't
858  then create a dummy table and save it */
859 
860  isdummy = 0;
861  if (ps.outcat != NULL) {
862  ftab = vircam_tfits_get_table(ps.outcat);
863  } else {
864  ftab = vircam_dummy_catalogue(2);
865  isdummy = 1;
866  }
867 
868  /* Make an attempt to get some header information */
869 
870  ehu = NULL;
871  phu = NULL;
872  if (ps.outcat != NULL) {
873  ehu = vircam_tfits_get_ehu(ps.outcat);
874  } else if (ps.stack_frame != NULL) {
875  ehu = vircam_fits_get_ehu(ps.stack_frame);
876  } else {
877  for (i = 0; i < ps.nscience; i++) {
878  if ((ehu = vircam_fits_get_ehu(ps.sci_fits[i])) != NULL)
879  break;
880  }
881  }
882  if (ps.outcat != NULL) {
883  phu = vircam_tfits_get_phu(ps.outcat);
884  } else if (ps.stack_frame != NULL) {
885  phu = vircam_fits_get_phu(ps.stack_frame);
886  } else {
887  for (i = 0; i < ps.nscience; i++) {
888  if ((phu = vircam_fits_get_phu(ps.sci_fits[i])) != NULL)
889  break;
890  }
891  }
892 
893  /* Create a name */
894 
895  fname = vircam_jmp_outfile(base[recflag],0,1);
896  fnamepaf = vircam_jmp_outfile(base[recflag],0,0);
897 
898  /* If we need to make a PHU then do that now based on the first frame
899  in the input frame list */
900 
901  if (isfirst) {
902 
903  /* Create a new product frame object and define some tags */
904 
905  product_frame = cpl_frame_new();
906  cpl_frame_set_filename(product_frame,fname);
907  switch (recflag) {
908  case RECSCI:
909  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OBJCAT_SCI);
910  break;
911  case RECSTD:
912  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OBJCAT_STD);
913  break;
914  default:
915  cpl_frame_set_tag(product_frame,VIRCAM_PRO_OBJCAT_SCI);
916  break;
917  }
918  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_TABLE);
919  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
920  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
921  ps.product_frame_cat = product_frame;
922 
923  /* Set up the PHU header. */
924 
925  vircam_dfs_set_product_primary_header(phu,product_frame,framelist,
926  parlist,vircam_recipename,
927  "PRO-1.15",NULL,0);
928 
929  /* Copy the header and delete any WCS info */
930 
931  ehu2 = cpl_propertylist_duplicate(ehu);
932  status = VIR_OK;
933  if (isdummy) {
934  vircam_dummy_property(ehu2);
935  vircam_merge_propertylists(ehu2,dummyqc);
936  (void)vircam_removewcs(ehu2,&status);
937  }
938 
939  /* Setup the extension header */
940 
941  vircam_dfs_set_product_exten_header(ehu2,product_frame,framelist,
942  parlist,vircam_recipename,
943  "PRO-1.15",NULL);
944 
945  /* 'Save' the PHU image */
946 
947  if (cpl_table_save(ftab,phu,ehu2,fname,CPL_IO_DEFAULT) !=
948  CPL_ERROR_NONE) {
949  cpl_msg_error(fctid,"Cannot save product PHU");
950  cpl_frame_delete(product_frame);
951  freepropertylist(ehu2);
952  freespace(fname);
953  return(-1);
954  }
955 
956  /* Write PAF */
957 
958  pafprop = vircam_paf_req_items(ehu2);
959  vircam_merge_propertylists(pafprop,ps.phupaf);
960  vircam_paf_append(pafprop,ehu2,"ESO PRO CATG");
961  vircam_paf_append(pafprop,phu,"ESO INS FILT1 NAME");
962  vircam_paf_append(pafprop,ehu,"ESO DET NDIT");
963  vircam_paf_append(pafprop,phu,"RA");
964  vircam_paf_append(pafprop,phu,"DEC");
965  vircam_paf_append(pafprop,phu,"ESO TEL AIRM START");
966  vircam_paf_append(pafprop,phu,"ESO TEL GUID FWHM");
967  vircam_paf_append(pafprop,phu,"ESO TEL AMBI RHUM");
968  vircam_paf_append(pafprop,phu,"ESO OBS TARG NAME");
969  if (vircam_paf_print(fnamepaf,vircam_recipepaf,"QC file",
970  pafprop) != VIR_OK)
971  cpl_msg_warning(fctid,"Unable to save PAF for catalogue");
972  cpl_propertylist_delete(pafprop);
973 
974  /* Quick tidy */
975 
976  freepropertylist(ehu2);
977  if (isdummy)
978  cpl_table_delete(ftab);
979  cpl_frameset_insert(framelist,product_frame);
980 
981  } else {
982 
983  /* Fiddle with the header now */
984 
985  product_frame = ps.product_frame_cat;
986  vircam_dfs_set_product_exten_header(ehu,product_frame,framelist,
987  parlist,vircam_recipename,
988  "PRO-1.15",NULL);
989 
990  /* Copy the header and delete any WCS info */
991 
992  ehu2 = cpl_propertylist_duplicate(ehu);
993  status = VIR_OK;
994  if (isdummy) {
995  vircam_dummy_property(ehu2);
996  vircam_merge_propertylists(ehu2,dummyqc);
997  (void)vircam_removewcs(ehu2,&status);
998  }
999 
1000  /* Save the table */
1001 
1002  if (cpl_table_save(ftab,NULL,ehu2,fname,CPL_IO_EXTEND) !=
1003  CPL_ERROR_NONE) {
1004  cpl_msg_error(fctid,"Cannot save product table extension");
1005  freepropertylist(ehu2);
1006  freespace(fname);
1007  return(-1);
1008  }
1009 
1010  /* Write PAF */
1011 
1012  pafprop = vircam_paf_req_items(ehu2);
1013  vircam_merge_propertylists(pafprop,ps.phupaf);
1014  vircam_paf_append(pafprop,ehu2,"ESO PRO CATG");
1015  vircam_paf_append(pafprop,phu,"ESO INS FILT1 NAME");
1016  vircam_paf_append(pafprop,ehu,"ESO DET NDIT");
1017  vircam_paf_append(pafprop,phu,"RA");
1018  vircam_paf_append(pafprop,phu,"DEC");
1019  vircam_paf_append(pafprop,phu,"ESO TEL AIRM START");
1020  vircam_paf_append(pafprop,phu,"ESO TEL GUID FWHM");
1021  vircam_paf_append(pafprop,phu,"ESO TEL AMBI RHUM");
1022  vircam_paf_append(pafprop,phu,"ESO OBS TARG NAME");
1023  if (vircam_paf_print(fnamepaf,vircam_recipepaf,"QC file",
1024  pafprop) != VIR_OK)
1025  cpl_msg_warning(fctid,"Unable to save PAF for catalogue");
1026  cpl_propertylist_delete(pafprop);
1027 
1028  /* Quick tidy */
1029 
1030  freepropertylist(ehu2);
1031  if (isdummy)
1032  cpl_table_delete(ftab);
1033  }
1034  freespace(fname);
1035  freespace(fnamepaf);
1036 
1037  /* Get out of here */
1038 
1039  return(0);
1040 }
1041 
1042 /*---------------------------------------------------------------------------*/
1061 /*---------------------------------------------------------------------------*/
1062 
1063 extern int vircam_jmp_save_illum(cpl_frameset *framelist,
1064  cpl_parameterlist *parlist) {
1065  cpl_frame *product_frame;
1066  int isdummy,i,status,isnew;
1067  cpl_table *ftab;
1068  cpl_propertylist *ehu,*phu,*ehu2,*pafprop;
1069  const char *fname = "illum.fits";
1070  const char *fnamepaf = "illum";
1071  const char *fctid = "vircam_jmp_save_illum";
1072 
1073  /* Work out whether you have a table to save or not. If you don't
1074  then create a dummy table and save it */
1075 
1076  isdummy = 0;
1077  if (ps.illcor != NULL) {
1078  ftab = vircam_tfits_get_table(ps.illcor);
1079  } else {
1080  ftab = vircam_illcor_newtab(1);
1081  isdummy = 1;
1082  }
1083 
1084  /* Make an attempt to get some header information */
1085 
1086  phu = NULL;
1087  ehu = NULL;
1088  if (ps.illcor != NULL) {
1089  ehu = vircam_tfits_get_ehu(ps.illcor);
1090  } else {
1091  for (i = 0; i < ps.nscience; i++) {
1092  if ((ehu = vircam_fits_get_ehu(ps.sci_fits[i])) != NULL)
1093  break;
1094  }
1095  }
1096  if (ps.illcor != NULL) {
1097  phu = vircam_tfits_get_phu(ps.illcor);
1098  } else {
1099  for (i = 0; i < ps.nscience; i++) {
1100  if ((phu = vircam_fits_get_phu(ps.sci_fits[i])) != NULL)
1101  break;
1102  }
1103  }
1104 
1105  /* If we need to make a PHU then do that now based on the first frame
1106  in the input frame list */
1107 
1108  if (isfirst) {
1109 
1110  /* Create a new product frame object and define some tags */
1111 
1112  product_frame = cpl_frame_new();
1113  cpl_frame_set_filename(product_frame,fname);
1114  switch (recflag) {
1115  case RECSTD:
1116  cpl_frame_set_tag(product_frame,VIRCAM_PRO_ILLCOR_STD);
1117  break;
1118  case RECMES:
1119  cpl_frame_set_tag(product_frame,VIRCAM_PRO_ILLCOR_MES);
1120  break;
1121  default:
1122  cpl_frame_set_tag(product_frame,VIRCAM_PRO_ILLCOR_STD);
1123  break;
1124  }
1125  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_TABLE);
1126  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
1127  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
1128  ps.product_frame_illcor = product_frame;
1129 
1130  /* Set up the PHU header. */
1131 
1132  isnew = 0;
1133  if (ps.phupaf == NULL) {
1134  ps.phupaf = vircam_paf_phu_items(phu);
1135  isnew = 1;
1136  }
1137  vircam_dfs_set_product_primary_header(phu,product_frame,framelist,
1138  parlist,vircam_recipename,
1139  "PRO-1.15",NULL,0);
1140 
1141  /* Copy the header and delete any WCS info */
1142 
1143  ehu2 = cpl_propertylist_duplicate(ehu);
1144  status = VIR_OK;
1145  (void)vircam_removewcs(ehu2,&status);
1146  if (isdummy) {
1147  vircam_dummy_property(ehu2);
1148  vircam_merge_propertylists(ehu2,dummyqc);
1149  }
1150 
1151 
1152  /* Setup the extension header */
1153 
1154  vircam_dfs_set_product_exten_header(ehu2,product_frame,framelist,
1155  parlist,vircam_recipename,
1156  "PRO-1.15",NULL);
1157 
1158  /* 'Save' the PHU image */
1159 
1160  if (cpl_table_save(ftab,phu,ehu2,fname,CPL_IO_DEFAULT) !=
1161  CPL_ERROR_NONE) {
1162  cpl_msg_error(fctid,"Cannot save product PHU");
1163  cpl_frame_delete(product_frame);
1164  freepropertylist(ehu2);
1165  return(-1);
1166  }
1167 
1168  /* Write the PAF */
1169 
1170  pafprop = vircam_paf_req_items(ehu2);
1171  vircam_merge_propertylists(pafprop,ps.phupaf);
1172  vircam_paf_append(pafprop,ehu2,"ESO PRO CATG");
1173  vircam_paf_append(pafprop,phu,"ESO INS FILT1 NAME");
1174  vircam_paf_append(pafprop,ehu,"ESO DET NDIT");
1175  vircam_paf_append(pafprop,phu,"RA");
1176  vircam_paf_append(pafprop,phu,"DEC");
1177  vircam_paf_append(pafprop,phu,"ESO TEL AIRM START");
1178  vircam_paf_append(pafprop,phu,"ESO TEL GUID FWHM");
1179  vircam_paf_append(pafprop,phu,"ESO TEL AMBI RHUM");
1180  vircam_paf_append(pafprop,phu,"ESO OBS TARG NAME");
1181  if (vircam_paf_print((char *)fnamepaf,vircam_recipepaf,"QC file",
1182  pafprop) != VIR_OK)
1183  cpl_msg_warning(fctid,"Unable to save PAF for illcor table");
1184  cpl_propertylist_delete(pafprop);
1185 
1186  /* Quick tidy */
1187 
1188  if (isdummy)
1189  cpl_table_delete(ftab);
1190  freepropertylist(ehu2);
1191  cpl_frameset_insert(framelist,product_frame);
1192 
1193  } else {
1194 
1195 
1196  /* Fiddle with the header now */
1197 
1198  product_frame = ps.product_frame_illcor;
1199  vircam_dfs_set_product_exten_header(ehu,product_frame,framelist,
1200  parlist,vircam_recipename,
1201  "PRO-1.15",NULL);
1202 
1203  /* Copy the header and delete any WCS info */
1204 
1205  ehu2 = cpl_propertylist_duplicate(ehu);
1206  status = VIR_OK;
1207  (void)vircam_removewcs(ehu2,&status);
1208  if (isdummy) {
1209  vircam_dummy_property(ehu2);
1210  vircam_merge_propertylists(ehu2,dummyqc);
1211  }
1212 
1213  /* Save the table */
1214 
1215  if (cpl_table_save(ftab,NULL,ehu2,fname,CPL_IO_EXTEND) !=
1216  CPL_ERROR_NONE) {
1217  cpl_msg_error(fctid,"Cannot save product image extension");
1218  freepropertylist(ehu2);
1219  return(-1);
1220  }
1221 
1222  /* Write the PAF */
1223 
1224  pafprop = vircam_paf_req_items(ehu2);
1225  vircam_merge_propertylists(pafprop,ps.phupaf);
1226  vircam_paf_append(pafprop,ehu2,"ESO PRO CATG");
1227  vircam_paf_append(pafprop,phu,"ESO INS FILT1 NAME");
1228  vircam_paf_append(pafprop,ehu,"ESO DET NDIT");
1229  vircam_paf_append(pafprop,phu,"RA");
1230  vircam_paf_append(pafprop,phu,"DEC");
1231  vircam_paf_append(pafprop,phu,"ESO TEL AIRM START");
1232  vircam_paf_append(pafprop,phu,"ESO TEL GUID FWHM");
1233  vircam_paf_append(pafprop,phu,"ESO TEL AMBI RHUM");
1234  vircam_paf_append(pafprop,phu,"ESO OBS TARG NAME");
1235  if (vircam_paf_print((char *)fnamepaf,vircam_recipepaf,"QC file",
1236  pafprop) != VIR_OK)
1237  cpl_msg_warning(fctid,"Unable to save PAF for illcor table");
1238  cpl_propertylist_delete(pafprop);
1239 
1240  /* Quick tidy */
1241 
1242  freepropertylist(ehu2);
1243  if (isdummy)
1244  cpl_table_delete(ftab);
1245  }
1246 
1247  /* Get out of here */
1248 
1249  return(0);
1250 }
1251 
1252 /*---------------------------------------------------------------------------*/
1268 /*---------------------------------------------------------------------------*/
1269 
1270 extern void vircam_jmp_ustep_seq(void) {
1271  int nalloc,i,match,j,ustepnum,nustep;
1272  vir_fits *ff;
1273  cpl_propertylist *plist;
1274  const char *fctid = "vircam_jmp_ustep_seq";
1275 
1276  /* Allocate an initial amount of workspace for the microstep sequence
1277  image sets */
1278 
1279  nalloc = INITALLOC;
1280  ps.ustep_sets = cpl_malloc(nalloc*sizeof(ustep_set));
1281  ps.nustep_sets = 0;
1282 
1283  /* Loop for each frame and get the microstep sequence number from the
1284  primary header */
1285 
1286  for (i = 0; i < ps.nscience; i++) {
1287  ff = ps.sci_fits[i];
1288  plist = vircam_fits_get_phu(ff);
1289  if (vircam_pfits_get_ustepnum(plist,&ustepnum) != VIR_OK) {
1290  cpl_msg_error(fctid,"No microstep number in %s",
1292  vircam_fits_set_error(ff,VIR_FATAL);
1293  continue;
1294  }
1295 
1296  /* See if this sequence number matches any of the others we've
1297  already defined. If it does, then simply add this frame into
1298  that sequences frameset */
1299 
1300  match = 0;
1301  for (j = 0; j < ps.nustep_sets; j++) {
1302  if (ustepnum == ps.ustep_sets[j].ustep_number) {
1303  match = 1;
1304  ps.ustep_sets[j].f[ps.ustep_sets[j].nframes] = ff;
1305  ps.ustep_sets[j].nframes += 1;
1306  if (vircam_fits_get_status(ff) != VIR_FATAL)
1307  ps.ustep_sets[j].ngood += 1;
1308  break;
1309  }
1310  }
1311 
1312  /* If it doesn't match increment the number of sets and check to
1313  make sure that we haven't overrun our allocation for ustep sets. */
1314 
1315  if (! match) {
1316  if (ps.nustep_sets+1 == nalloc) {
1317  nalloc += INITALLOC;
1318  ps.ustep_sets = cpl_realloc(ps.ustep_sets,nalloc*sizeof(ustep_set));
1319  }
1320 
1321  /* Now define this ustep set */
1322 
1323  (void)vircam_pfits_get_nusteps(plist,&nustep);
1324  ps.ustep_sets[ps.nustep_sets].f = cpl_malloc(nustep*sizeof(vir_fits *));
1325  ps.ustep_sets[ps.nustep_sets].ustep_number = ustepnum;
1326  ps.ustep_sets[ps.nustep_sets].nustep = nustep;
1327  ps.ustep_sets[ps.nustep_sets].status = VIR_OK;
1328  ps.ustep_sets[ps.nustep_sets].super = NULL;
1329  ps.ustep_sets[ps.nustep_sets].superc = NULL;
1330  ps.ustep_sets[ps.nustep_sets].nframes = 0;
1331  ps.ustep_sets[ps.nustep_sets].f[0] = ff;
1332  ps.ustep_sets[ps.nustep_sets].nframes = 1;
1333  ps.ustep_sets[ps.nustep_sets].ngood = 0;
1334  if (vircam_fits_get_status(ff) != VIR_FATAL)
1335  ps.ustep_sets[ps.nustep_sets].ngood += 1;
1336  ps.nustep_sets++;
1337  }
1338  }
1339 
1340  /* Fix the allocation to what we need and throw the rest away */
1341 
1342  ps.ustep_sets = cpl_realloc(ps.ustep_sets,
1343  ps.nustep_sets*sizeof(ustep_set));
1344 
1345  /* Loop through each of the defined sets and see if each is complete */
1346 
1347  for (i = 0; i < ps.nustep_sets; i++) {
1348  if (ps.ustep_sets[i].ngood == 0) {
1349  cpl_msg_warning(fctid,
1350  "Microstep sequence %" CPL_SIZE_FORMAT " has no input",
1351  (cpl_size)(ps.ustep_sets[i].ustep_number));
1352  ps.ustep_sets[i].status = VIR_FATAL;
1353  } else if (ps.ustep_sets[i].ngood != ps.ustep_sets[i].nustep) {
1354  cpl_msg_warning(fctid,"Microstep sequence %" CPL_SIZE_FORMAT " incomplete",
1355  (cpl_size)(ps.ustep_sets[i].ustep_number));
1356  ps.ustep_sets[i].status = VIR_WARN;
1357  }
1358  }
1359 }
1360 
1361 
1362 /*---------------------------------------------------------------------------*/
1378 /*---------------------------------------------------------------------------*/
1379 
1380 extern void vircam_jmp_interleave(void) {
1381  int i,refset,k,nstep,status,nk;
1382  const int *d;
1383  long npts;
1384  float val;
1385  double refx,refy,refra,refdec,x,y;
1386  cpl_image *fi,*outimage,*outconf;
1387  cpl_propertylist *plist;
1388  vir_fits *ff,**tmp;
1389  cpl_wcs *wcs;
1390  const char *fctid = "vircam_jmp_interleave";
1391 
1392  /* Work out the microstep sequences */
1393 
1395 
1396  /* Get workspace to contain the output superframes */
1397 
1398  ps.dith_input = cpl_malloc(ps.nustep_sets*sizeof(vir_fits*));
1399  ps.dithc_input = cpl_malloc(ps.nustep_sets*sizeof(vir_fits*));
1400 
1401  /* Loop for each of the ustep sets */
1402 
1403  ps.ndith = 0;
1404  for (i = 0; i < ps.nustep_sets; i++) {
1405  if (ps.ustep_sets[i].status == VIR_FATAL) {
1406  outimage = vircam_dummy_image(ps.ustep_sets[i].f[0]);
1407  outconf = vircam_dummy_image(ps.fconf);
1408  ff = vircam_fits_wrap(outimage,ps.ustep_sets[i].f[0],NULL,NULL);
1409  ps.dith_input[ps.ndith] = ff;
1410  vircam_fits_set_error(ff,VIR_FATAL);
1411  ps.ustep_sets[i].super = ff;
1412  ff = vircam_fits_wrap(outconf,ps.ustep_sets[i].f[0],NULL,NULL);
1413  ps.dithc_input[ps.ndith++] = ff;
1414  vircam_fits_set_error(ff,VIR_FATAL);
1415  ps.ustep_sets[i].superc = ff;
1416  continue;
1417  }
1418 
1419  /* Work out the offsets in the sequence from the WCS in the header.
1420  Fail the ustep sequence if any of it's components have an
1421  unreadable WCS */
1422 
1423  refset = 0;
1424  refx = 0.0;
1425  refy = 0.0;
1426  for (k = 0; k < ps.ustep_sets[i].nframes; k++) {
1427  ff = ps.ustep_sets[i].f[k];
1428  if (vircam_fits_get_status(ff) == VIR_FATAL)
1429  continue;
1430  wcs = cpl_wcs_new_from_propertylist(vircam_fits_get_ehu(ff));
1431  if (wcs == NULL) {
1432  cpl_msg_error(fctid,"Unable to open WCS structure %s",
1434  vircam_fits_set_error(ff,VIR_FATAL);
1435  continue;
1436  }
1437 
1438  /* Get the background value for this image */
1439 
1440  fi = vircam_fits_get_image(ff);
1441  npts = vircam_getnpts(fi);
1442  val = vircam_med(cpl_image_get_data_float(fi),NULL,npts);
1443  cpl_propertylist_update_float(vircam_fits_get_ehu(ff),
1444  "ESO DRS BACKMED",val);
1445 
1446  /* If this is the first frame, then set up the reference coords. */
1447 
1448  if (refset == 0) {
1449  refset = 1;
1450  d = cpl_array_get_data_int_const(cpl_wcs_get_image_dims(wcs));
1451  refx = 0.5*(double)d[0];
1452  refy = 0.5*(double)d[1];
1453  vircam_xytoradec(wcs,refx,refy,&refra,&refdec);
1454  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1455  "ESO DRS XOFFMICRO",0.0);
1456  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1457  "ESO DRS YOFFMICRO",0.0);
1458  cpl_wcs_delete(wcs);
1459  continue;
1460  }
1461 
1462  /* Take the reference ra and dec and see where that occurs on
1463  the program image in x,y space */
1464 
1465  vircam_radectoxy(wcs,refra,refdec,&x,&y);
1466  x = refx - x;
1467  y = refy - y;
1468  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1469  "ESO DRS XOFFMICRO",x);
1470  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1471  "ESO DRS YOFFMICRO",y);
1472  cpl_wcs_delete(wcs);
1473  }
1474 
1475  /* Get a temporary workspace to hold all the good files in the list */
1476 
1477  tmp = cpl_malloc(ps.ustep_sets[i].nframes*sizeof(vir_fits *));
1478  nk = 0;
1479  for (k = 0; k < ps.ustep_sets[i].nframes; k++) {
1480  ff = ps.ustep_sets[i].f[k];
1481  if (vircam_fits_get_status(ff) != VIR_FATAL)
1482  tmp[nk++] = ff;
1483  }
1484  if (nk < ps.ustep_sets[i].nframes) {
1485  cpl_msg_error(fctid,"A frame in this ustep sequence failed");
1486  ps.ustep_sets[i].status = VIR_WARN;
1487  }
1488 
1489  /* Otherwise interleave them */
1490 
1491  status = VIR_OK;
1492  nstep = (int)sqrt((double)(ps.ustep_sets[i].nustep));
1493  (void)vircam_interleave(tmp,nk,&(ps.fconf),1,nstep,&plist,&outimage,
1494  &outconf,&status);
1495  freespace(tmp);
1496  if (status != VIR_OK) {
1497  cpl_msg_error(fctid,
1498  "Interleaving failed for ugroup %" CPL_SIZE_FORMAT " extn %" CPL_SIZE_FORMAT,
1499  (cpl_size)(ps.ustep_sets[i].ustep_number),
1500  (cpl_size)(vircam_fits_get_nexten(ps.ustep_sets[i].f[0])));
1501  freepropertylist(plist);
1502  freeimage(outimage);
1503  freeimage(outconf);
1504  outimage = vircam_dummy_image(ps.ustep_sets[i].f[0]);
1505  outconf = vircam_dummy_image(ps.fconf);
1506  ff = vircam_fits_wrap(outimage,ps.ustep_sets[i].f[0],NULL,NULL);
1507  vircam_fits_set_error(ff,VIR_FATAL);
1508  ps.ustep_sets[i].super = ff;
1509  ff = vircam_fits_wrap(outconf,ps.ustep_sets[i].f[0],NULL,NULL);
1510  vircam_fits_set_error(ff,VIR_FATAL);
1511  ps.ustep_sets[i].superc = ff;
1512  }
1513 
1514  /* Wrap the output results and store them away into the list of
1515  frames that will be dithered later on. */
1516 
1517  ps.dith_input[ps.ndith] = vircam_fits_wrap(outimage,
1518  ps.ustep_sets[i].f[0],NULL,
1519  plist);
1520  ps.dithc_input[ps.ndith++] = vircam_fits_wrap(outconf,
1521  ps.ustep_sets[i].f[0],
1522  NULL,plist);
1523  ps.ndithc = ps.ndith;
1524  ps.ustep_sets[i].super = ps.dith_input[ps.ndith - 1];
1525  ps.ustep_sets[i].superc = ps.dithc_input[ps.ndithc - 1];
1526  freepropertylist(plist);
1527  }
1528 }
1529 
1530 /*---------------------------------------------------------------------------*/
1550 /*---------------------------------------------------------------------------*/
1551 
1552 extern void vircam_jmp_dither_offsets(void) {
1553  int status,i,ustepnum,nmatch,refset;
1554  float *xoffs,*yoffs,xoff,yoff,filtfwhm;
1555  cpl_wcs *wcsref,*wcs;
1556  vir_fits *ff,*ffc;
1557  vir_tfits *catref,*outcat;
1558  cpl_table *cr,*oc,*outxy;
1559  const char *fctid = "vircam_jmp_dither_offsets";
1560  const double maxoffset = 2048;
1561 
1562  /* Is there anything to dither? If not, then get out of here. NB: We
1563  don't have to check the status of the input dither files as the
1564  calling routine won't have included any files with bad status in
1565  the input list for this routine. */
1566 
1567  if (ps.ndith == 0)
1568  return;
1569 
1570  /* If there is only 1 then set the offsets to zero and get out of here */
1571 
1572  if (ps.ndith == 1) {
1573  cpl_propertylist_update_double(vircam_fits_get_ehu(ps.dith_input[0]),
1574  "ESO DRS XOFFDITHER",(double)0.0);
1575  cpl_propertylist_update_double(vircam_fits_get_ehu(ps.dith_input[0]),
1576  "ESO DRS YOFFDITHER",(double)0.0);
1577  return;
1578  }
1579 
1580  /* Initialise the status variable and get some workspace for the offsets */
1581 
1582  status = VIR_OK;
1583  xoffs = cpl_malloc(ps.ndith*sizeof(float));
1584  yoffs = cpl_malloc(ps.ndith*sizeof(float));
1585 
1586  /* Loop for all the input files and get the FITS WCS information. */
1587 
1588  refset = 0;
1589  wcsref = NULL;
1590  for (i = 0; i < ps.ndith; i++) {
1591  ff = ps.dith_input[i];
1592  if (vircam_fits_get_status(ff) == VIR_FATAL)
1593  continue;
1594  wcs = cpl_wcs_new_from_propertylist(vircam_fits_get_ehu(ff));
1595  (void)vircam_pfits_get_ustepnum(vircam_fits_get_phu(ff),&ustepnum);
1596 
1597  /* If we can't get a WCS for this image, then signal that with
1598  a warning */
1599 
1600  if (wcs == NULL) {
1601  cpl_msg_warning(fctid,
1602  "Unable to get WCS for ustep %" CPL_SIZE_FORMAT,
1603  (cpl_size)ustepnum);
1604  xoffs[i] = 0.0;
1605  yoffs[i] = 0.0;
1606  vircam_fits_set_error(ff,VIR_WARN);
1607  continue;
1608  }
1609 
1610  /* If we don't have a reference WCS yet, then make the current frame
1611  WCS the reference and move on */
1612 
1613  if (! refset) {
1614  xoffs[i] = 0.0;
1615  yoffs[i] = 0.0;
1616  refset = 1;
1617  wcsref = wcs;
1618  continue;
1619  }
1620 
1621  /* Right, assuming we're here, then we need to work out the xy
1622  differences */
1623 
1624  (void)vircam_diffxywcs(wcs,wcsref,&xoff,&yoff,&status);
1625 
1626  /* Did it work? If not the set a warning status for this file */
1627 
1628  if (status != VIR_OK) {
1629  xoffs[i] = 0.0;
1630  yoffs[i] = 0.0;
1631  cpl_msg_warning(fctid,
1632  "Unable to WCS difference for %" CPL_SIZE_FORMAT,
1633  (cpl_size)ustepnum);
1634  } else if (fabs((double)xoff) > maxoffset ||
1635  fabs((double)yoff) > maxoffset) {
1636  cpl_msg_warning(fctid,
1637  "WCS offsets for %" CPL_SIZE_FORMAT " are > %g: %g %g -- ignoring",
1638  (cpl_size)ustepnum,maxoffset,xoff,yoff);
1639  xoffs[i] = 0.0;
1640  yoffs[i] = 0.0;
1641  } else {
1642  xoffs[i] = xoff;
1643  yoffs[i] = yoff;
1644  }
1645  cpl_wcs_delete(wcs);
1646  }
1647  if (wcsref != NULL)
1648  cpl_wcs_delete(wcsref);
1649 
1650  /* Now generate a catalogue for each of the input images */
1651 
1652  catref = NULL;
1653  cr = NULL;
1654  filtfwhm = (interlv ? 3.5 : 2.0);
1655  for (i = 0; i < ps.ndith; i++) {
1656  ff = ps.dith_input[i];
1657  if (vircam_fits_get_status(ff) == VIR_FATAL)
1658  continue;
1659  status = VIR_OK;
1660  if (ps.ndithc != 1)
1661  ffc = ps.dithc_input[i];
1662  else
1663  ffc = ps.dithc_input[0];
1664  (void)vircam_pfits_get_ustepnum(vircam_fits_get_phu(ff),&ustepnum);
1665  outcat = NULL;
1666  (void)vircam_imcore(ff,ffc,25,5.0,0,3.5,64,1,filtfwhm,&outcat,
1667  &status);
1668 
1669  /* If we get a bad status from imcore and this frame has already
1670  failed in the WCS stage, then mark it with VIR_FATAL status
1671  and move to the next one */
1672 
1673  if (status != VIR_OK && vircam_fits_get_status(ff) != VIR_OK) {
1674  vircam_fits_set_error(ff,VIR_FATAL);
1675  freetfits(outcat);
1676  cpl_msg_error(fctid,
1677  "Unable to get offsets for %" CPL_SIZE_FORMAT,
1678  (cpl_size)ustepnum);
1679  continue;
1680 
1681  /* If we get bad status, but this file has a perfectly good offset
1682  from the WCS then just go with it that and issue a warning */
1683 
1684  } else if (status != VIR_OK && vircam_fits_get_status(ff) == VIR_OK) {
1685  vircam_fits_set_error(ff,VIR_WARN);
1686  freetfits(outcat);
1687  cpl_msg_error(fctid,
1688  "Unable to get object offset for %" CPL_SIZE_FORMAT ". Going with WCS offset",
1689  (cpl_size)ustepnum);
1690  continue;
1691 
1692  /* OK, we got a good status from imcore. See if the reference
1693  catalogue has already been defined. If it hasn't then this
1694  catalogue becomes the reference */
1695 
1696  } else {
1697  oc = vircam_tfits_get_table(outcat);
1698  cpl_table_add_scalar(oc,"X_coordinate",(double)xoffs[i]);
1699  cpl_table_add_scalar(oc,"Y_coordinate",(double)yoffs[i]);
1700  if (catref == NULL) {
1701  catref = outcat;
1702  cr = oc;
1703  continue;
1704  }
1705 
1706  /* If this isn't the reference file, then do the cross match */
1707 
1708  (void)vircam_matchxy(oc,cr,100.0,&xoff,&yoff,&nmatch,&outxy,&status);
1709  freetable(outxy);
1710  freetfits(outcat);
1711 
1712  /* If we got a bad result with the cross match and this current
1713  file is already got a warning status, then flag it as fatal
1714  status */
1715 
1716  if ((nmatch == 0 || status == VIR_FATAL) &&
1717  vircam_fits_get_status(ff) != VIR_OK) {
1718  xoff = 0.0;
1719  yoff = 0.0;
1720  vircam_fits_set_error(ff,VIR_FATAL);
1721  cpl_msg_error(fctid,
1722  "Unable to match stars for %" CPL_SIZE_FORMAT,
1723  (cpl_size)ustepnum);
1724 
1725  /* If we got a bad result with the cross match and this current
1726  file has a good status, then just go with the WCS offset
1727  we already have */
1728 
1729  } else if ((nmatch == 0 || status == VIR_FATAL) &&
1730  vircam_fits_get_status(ff) == VIR_OK) {
1731  vircam_fits_set_error(ff,VIR_WARN);
1732  xoff = 0.0;
1733  yoff = 0.0;
1734  cpl_msg_warning(fctid,
1735  "Unable to match stars for %" CPL_SIZE_FORMAT ". Going with WCS offsets",
1736  (cpl_size)ustepnum);
1737  }
1738 
1739  /* Add the current offsets to what we already have */
1740 
1741  xoffs[i] += xoff;
1742  yoffs[i] += yoff;
1743  }
1744  }
1745 
1746  /* Write the results to the headers */
1747 
1748  for (i = 0; i < ps.ndith; i++) {
1749  if (vircam_fits_get_status(ps.dith_input[i]) == VIR_FATAL)
1750  continue;
1751  ff = ps.dith_input[i];
1752  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1753  "ESO DRS XOFFDITHER",(double)xoffs[i]);
1754  cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
1755  "ESO DRS YOFFDITHER",(double)yoffs[i]);
1756  }
1757 
1758  /* Get rid of some workspace */
1759 
1760  freespace(xoffs);
1761  freespace(yoffs);
1762  freetfits(catref);
1763 }
1764 
1765 /*---------------------------------------------------------------------------*/
1781 /*---------------------------------------------------------------------------*/
1782 
1783 extern void vircam_jmp_dither_images(void) {
1784  int status,ngood,i,n;
1785  vir_fits **d,**dc,*ff;
1786  cpl_propertylist *dither_ehu,*dither_phu;
1787  cpl_image *outdither,*outditherc;
1788  const char *fctid = "vircam_jmp_dither_images";
1789 
1790  /* Count how many good input images there are. */
1791 
1792  ngood = 0;
1793  for (i = 0; i < ps.ndith; i++)
1794  if (vircam_fits_get_status(ps.dith_input[i]) != VIR_FATAL)
1795  ngood++;
1796 
1797  /* If there are none, then get out of here. The output jittered image
1798  and it's confidence map should still be set to NULL */
1799 
1800  if (ngood == 0) {
1801  cpl_msg_error(fctid,"No good input images for jittering");
1802 
1803 
1804  outdither = vircam_dummy_image(ps.sci_fits[0]);
1805  outditherc = vircam_dummy_image(ps.dithc_input[0]);
1806  ff = vircam_fits_wrap(outdither,ps.sci_fits[0],NULL,NULL);
1807  ps.stack_frame = ff;
1808  vircam_fits_set_error(ff,VIR_FATAL);
1809  ff = vircam_fits_wrap(outditherc,ps.dithc_input[0],NULL,NULL);
1810  vircam_fits_set_error(ff,VIR_FATAL);
1811  ps.stackc_frame = ff;
1812  return;
1813  }
1814 
1815  /* Now transfer the input images over to new arrays... */
1816 
1817  d = cpl_malloc(ngood*sizeof(vir_fits *));
1818  dc = cpl_malloc(ngood*sizeof(vir_fits *));
1819  n = 0;
1820  for (i = 0; i < ps.ndith; i++) {
1821  if (vircam_fits_get_status(ps.dith_input[i]) != VIR_FATAL) {
1822  d[n] = ps.dith_input[i];
1823  if (ps.ndithc != 1)
1824  dc[n++] = ps.dithc_input[i];
1825  else
1826  dc[n++] = ps.dithc_input[0];
1827  }
1828  }
1829 
1830  /* Dither the remaining images */
1831 
1832  status = VIR_OK;
1833  (void)vircam_imdither(d,dc,ngood,ngood,5.0,5.0,&dither_ehu,&outdither,
1834  &outditherc,&status);
1835  dither_phu = cpl_propertylist_duplicate(vircam_fits_get_phu(d[0]));
1836  if (status != VIR_OK) {
1837  freeimage(outdither);
1838  freeimage(outditherc);
1839  cpl_msg_error(fctid,"Error jittering to output");
1840  } else {
1841  ps.stack_frame = vircam_fits_wrap(outdither,d[0],dither_phu,
1842  dither_ehu);
1843  ps.stackc_frame = vircam_fits_wrap(outditherc,dc[0],dither_phu,
1844  dither_ehu);
1845  }
1846 
1847  /* Tidy and exit */
1848 
1849  freepropertylist(dither_phu);
1850  freepropertylist(dither_ehu);
1851  freespace(d);
1852  freespace(dc);
1853 }
1854 
1855 /*---------------------------------------------------------------------------*/
1870 /*---------------------------------------------------------------------------*/
1871 
1872 extern void vircam_jmp_catalogue(void) {
1873  const char *fctid = "vircam_jmp_catalogue";
1874  int status;
1875  vir_tfits *outtab;
1876  float filtfwhm;
1877 
1878  /* Check to see if there has been a jitter frame defined */
1879 
1880  if (ps.stack_frame == NULL || vircam_fits_get_status(ps.stack_frame) == VIR_FATAL) {
1881  cpl_msg_error(fctid,"No stack image available. No catalogue generated");
1882  return;
1883  }
1884 
1885  /* Generate the catalogue */
1886 
1887  status = VIR_OK;
1888  filtfwhm = (interlv ? 3.5 : 2);
1889  (void)vircam_imcore(ps.stack_frame,ps.stackc_frame,
1890  vircam_jmp_config.ipix,
1891  vircam_jmp_config.threshold,
1892  vircam_jmp_config.icrowd,
1893  vircam_jmp_config.rcore,
1894  vircam_jmp_config.nbsize,2,filtfwhm,
1895  &outtab,&status);
1896 
1897  /* If it failed, then get rid of workspaces and get out of here with
1898  an error message. If it went well, then wrap the result in a
1899  vir_tfits object */
1900 
1901  if (status != VIR_OK) {
1902  cpl_msg_error(fctid,"Error generating catalogue");
1903  freetfits(outtab);
1904  vircam_fits_set_error(ps.stack_frame,VIR_FATAL);
1905  } else {
1906  ps.outcat = outtab;
1907  }
1908 
1909  return;
1910 }
1911 
1912 /*---------------------------------------------------------------------------*/
1928 /*---------------------------------------------------------------------------*/
1929 
1930 extern void vircam_jmp_matched_stds(void) {
1931  int status,ncat,nstd,level;
1932  const char *fctid = "vircam_jmp_matched_stds";
1933  cpl_table *stdscat,*newstds,*tmp,*tmp2,*cat;
1934  cpl_propertylist *p;
1935 
1936  /* Initialise status */
1937 
1938  status = VIR_OK;
1939 
1940  /* Check that we have a catalogue */
1941 
1942  if (ps.outcat == NULL) {
1943  cpl_msg_error(fctid,"No input catalogue found");
1944  return;
1945  }
1946 
1947  /* Get some standard stars */
1948 
1949  (void)vircam_getstds(vircam_fits_get_ehu(ps.stack_frame),1,
1950  current_catpath,current_cat,&stdscat,&status);
1951  if (status != VIR_OK) {
1952  freetable(stdscat);
1953  cpl_msg_error(fctid,"Failed to find any standards");
1954  return;
1955  }
1956 
1957  /* Restrict to stars with good photometry */
1958 
1959  (void)cpl_table_or_selected_float(stdscat,"j_msig",CPL_LESS_THAN,0.2);
1960  (void)cpl_table_and_selected_float(stdscat,"k_msig",CPL_LESS_THAN,0.2);
1961  newstds = cpl_table_extract_selected(stdscat);
1962  nstd = (int)cpl_table_get_nrow(newstds);
1963 
1964  /* If there are too many objects in the catalogue then first restrict
1965  ourselves by ellipticity. Cut so that there are similar numbers of
1966  objects in the standards and the object catalogues by retaining the
1967  brighter objects */
1968 
1969  cat = vircam_tfits_get_table(ps.outcat);
1970  ncat = (int)cpl_table_get_nrow(cat);
1971  if (ncat > 500 && ncat > 2.0*nstd) {
1972  tmp = cpl_table_duplicate(cat);
1973  (void)cpl_table_or_selected_float(tmp,"Ellipticity",CPL_LESS_THAN,0.5);
1974  tmp2 = cpl_table_extract_selected(tmp);
1975  ncat = (int)cpl_table_get_nrow(tmp2);
1976  freetable(tmp);
1977  p = cpl_propertylist_new();
1978  cpl_propertylist_append_bool(p,"Aper_flux_3",TRUE);
1979  cpl_table_sort(tmp2,(const cpl_propertylist *)p);
1980  cpl_propertylist_delete(p);
1981  level = min(ncat,max(1,min(5000,max(500,2*nstd))));
1982  tmp = cpl_table_extract(tmp2,1,(cpl_size)level);
1983  freetable(tmp2);
1984  ncat = (int)cpl_table_get_nrow(tmp);
1985  cat = tmp;
1986  } else {
1987  tmp = NULL;
1988  }
1989 
1990  /* Now match this against the catalogue */
1991 
1992  (void)vircam_matchstds(cat,newstds,300.0,&(ps.matchstds),&status);
1993  freetable(stdscat);
1994  freetable(newstds);
1995  freetable(tmp);
1996  if (status != VIR_OK) {
1997  freetable(ps.matchstds);
1998  cpl_msg_error(fctid,"Failed to match standards to catalogue");
1999  return;
2000  }
2001 }
2002 
2003 /*---------------------------------------------------------------------------*/
2020 /*---------------------------------------------------------------------------*/
2021 
2022 extern void vircam_jmp_wcsfit(void) {
2023  int status,n,i;
2024  const char *fctid = "vircam_jmp_wcsfit";
2025  float *ra,*dec,*x,*y;
2026  double r,d;
2027  cpl_table *cat;
2028  cpl_wcs *wcs;
2029 
2030  /* Initialise status */
2031 
2032  status = VIR_OK;
2033 
2034  /* Check that we have a catalogue */
2035 
2036  if (ps.matchstds == NULL) {
2037  cpl_msg_error(fctid,"No input matched standards catalogue found");
2038  return;
2039  }
2040 
2041  /* Fit the plate solution */
2042 
2043  (void)vircam_platesol(vircam_fits_get_ehu(ps.stack_frame),
2044  vircam_tfits_get_ehu(ps.outcat),ps.matchstds,
2045  6,1,&status);
2046  if (status != VIR_OK) {
2047  cpl_msg_error(fctid,"Failed to fit WCS");
2048  return;
2049  }
2050 
2051  /* Update the RA and DEC of the objects in the object catalogue */
2052 
2053  cat = vircam_tfits_get_table(ps.outcat);
2054  n = (int)cpl_table_get_nrow(cat);
2055  wcs = cpl_wcs_new_from_propertylist(vircam_fits_get_ehu(ps.stack_frame));
2056  if (wcs == NULL) {
2057  cpl_msg_error(fctid,"Failed to fill RA and Dec in catalogue");
2058  return;
2059  }
2060  x = cpl_table_get_data_float(cat,"X_coordinate");
2061  y = cpl_table_get_data_float(cat,"Y_coordinate");
2062  ra = cpl_table_get_data_float(cat,"RA");
2063  dec = cpl_table_get_data_float(cat,"DEC");
2064  for (i = 0; i < n; i++) {
2065  vircam_xytoradec(wcs,x[i],y[i],&r,&d);
2066  ra[i] = (float)r;
2067  dec[i] = (float)d;
2068  }
2069  cpl_wcs_delete(wcs);
2070 }
2071 
2072 /*---------------------------------------------------------------------------*/
2088 /*---------------------------------------------------------------------------*/
2089 
2090 extern void vircam_jmp_photcal(void) {
2091  int status;
2092  const char *fctid = "vircam_jmp_photcal";
2093  char filt[32];
2094  cpl_propertylist *pl;
2095 
2096  /* Initialise status */
2097 
2098  status = VIR_OK;
2099 
2100  /* Check that we have a catalogue */
2101 
2102  if (ps.matchstds == NULL || (int)cpl_table_get_nrow(ps.matchstds) == 0) {
2103  cpl_msg_error(fctid,"No input matched standards catalogue found");
2104  return;
2105  }
2106 
2107  /* What filter is this? */
2108 
2109  if (vircam_pfits_get_filter(vircam_fits_get_phu(ps.stack_frame),filt) != VIR_OK) {
2110  cpl_msg_error(fctid,"No filter name in stack header");
2111  return;
2112  }
2113 
2114  /* Fit the photometric calibration */
2115 
2116  pl = vircam_tfits_get_ehu(ps.outcat);
2117  (void)vircam_photcal(&(ps.stack_frame),&(ps.matchstds),&pl,1,filt,
2118  ps.tphottab,&status);
2119  if (status != VIR_OK) {
2120  cpl_msg_error(fctid,"Failed to fit photometric zeropoint");
2121  return;
2122  }
2123 }
2124 
2125 /*---------------------------------------------------------------------------*/
2142 /*---------------------------------------------------------------------------*/
2143 
2144 extern void vircam_jmp_bpm2conf(void) {
2145  cpl_image *im;
2146  int i,n,*data;
2147 
2148  /* Get the image */
2149 
2150  im = vircam_fits_get_image(ps.fconf);
2151  n = (int)cpl_image_get_size_x(im)*(int)cpl_image_get_size_y(im);
2152  data = cpl_image_get_data_int(im);
2153 
2154  /* Convert it now */
2155 
2156  for (i = 0; i < n; i++)
2157  data[i] = (data[i] == 1 ? 0 : 100);
2158 
2159 }
2160 
2161 /*---------------------------------------------------------------------------*/
2178 /*---------------------------------------------------------------------------*/
2179 
2180 extern void vircam_jmp_skycor(void) {
2181  int i,ngood,status,nfrms;
2182  long npts;
2183  vir_fits **ftmp,*ff,**frms;
2184  const char *fctid = "vircam_jmp_skycor";
2185  unsigned char *rejmask,*rejplus;
2186  cpl_propertylist *drs;
2187  cpl_image *skyimg,*fim;
2188  float *data,med,sig;
2189 
2190  /* If we need to do a sky combination... */
2191 
2192  if (offsky == 0 || offsky == 1) {
2193 
2194  /* Which array are we combining? */
2195 
2196  if (offsky == 1) {
2197  nfrms = ps.noffsets;
2198  frms = ps.offsky_fits;
2199  } else {
2200  nfrms = ps.nscience;
2201  frms = ps.sci_fits;
2202  }
2203 
2204  /* Sort out all images with good status */
2205 
2206  ftmp = cpl_malloc(nfrms*sizeof(vir_fits *));
2207  ngood = 0;
2208  for (i = 0; i < nfrms; i++) {
2209  ff = frms[i];
2210  if (vircam_fits_get_status(ff) != VIR_FATAL)
2211  ftmp[ngood++] = ff;
2212  }
2213 
2214  /* If there aren't any good images, then get out of here now */
2215 
2216  if (ngood == 0) {
2217  freespace(ftmp);
2218  cpl_msg_error(fctid,"Sky correction impossible. No good sky frames available");
2219  return;
2220  }
2221 
2222  /* Combine all the good science images */
2223 
2224  status = VIR_OK;
2225  (void)vircam_imcombine(ftmp,ngood,1,1,1,2.0,&skyimg,&rejmask,&rejplus,
2226  &drs,&status);
2227  freespace(rejmask);
2228  freespace(rejplus);
2229  if (offsky == 0)
2230  freepropertylist(drs);
2231  freespace(ftmp);
2232  } else {
2233  skyimg = vircam_fits_get_image(ps.fsky);
2234  }
2235 
2236  /* Normalise the sky frame to zero median */
2237 
2238  data = cpl_image_get_data_float(skyimg);
2239  npts = (long)cpl_image_get_size_x(skyimg)*(long)cpl_image_get_size_y(skyimg);
2240  vircam_qmedsig(data,NULL,npts,5.0,3,-1000.0,65535.0,&med,&sig);
2241  for (i = 0; i < npts; i++)
2242  data[i] -= med;
2243 
2244  /* Save the sky frame if it's an offset sky */
2245 
2246  if (offsky == 1) {
2247  ps.outsky = vircam_fits_wrap(skyimg,frms[0],NULL,NULL);
2249  freepropertylist(drs);
2250  drs = vircam_fits_get_ehu(ps.outsky);
2251  cpl_propertylist_update_float(drs,"ESO QC SKYMED",med);
2252  cpl_propertylist_set_comment(drs,"ESO QC SKYMED",
2253  "Median sky background");
2254  cpl_propertylist_update_float(drs,"ESO QC SKYSIG",sig);
2255  cpl_propertylist_set_comment(drs,"ESO QC SKYSIG",
2256  "Sky background sigma");
2257  }
2258 
2259  /* Subtract the normalised sky frame from the science images and do the
2260  same for the sky images */
2261 
2262  for (i = 0; i < ps.nscience; i++) {
2263  ff = ps.sci_fits[i];
2264  fim = vircam_fits_get_image(ff);
2265  if (vircam_fits_get_status(ff) != VIR_FATAL) {
2266  drs = vircam_fits_get_ehu(ff);
2267  cpl_image_subtract(fim,skyimg);
2268  if (offsky == 0) {
2269  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR","internal");
2270  } else if (offsky == 1) {
2271  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR","offsky");
2272  } else if (offsky == -1) {
2273  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR",
2274  vircam_fits_get_fullname(ps.fsky));
2275  }
2276  cpl_propertylist_set_comment(drs,"ESO DRS SKYCOR",
2277  "Sky correction method");
2278  }
2279  }
2280  for (i = 0; i < ps.noffsets; i++) {
2281  ff = ps.offsky_fits[i];
2282  fim = vircam_fits_get_image(ff);
2283  if (vircam_fits_get_status(ff) != VIR_FATAL) {
2284  drs = vircam_fits_get_ehu(ff);
2285  cpl_image_subtract(fim,skyimg);
2286  if (offsky == 0) {
2287  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR","internal");
2288  } else if (offsky == 1) {
2289  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR","offsky");
2290  } else if (offsky == -1) {
2291  cpl_propertylist_update_string(drs,"ESO DRS SKYCOR",
2292  vircam_fits_get_fullname(ps.fsky));
2293  }
2294  cpl_propertylist_set_comment(drs,"ESO DRS SKYCOR",
2295  "Image has been sky corrected");
2296  }
2297  }
2298 
2299  /* Clean up and get out of here */
2300 
2301  if (offsky == 0)
2302  cpl_image_delete(skyimg);
2303  else if (offsky == 1)
2304  cpl_image_add_scalar(skyimg,med);
2305  return;
2306 }
2307 
2308 /*---------------------------------------------------------------------------*/
2324 /*---------------------------------------------------------------------------*/
2325 
2326 extern void vircam_jmp_get_readnoise_gain(int jext, float *readnoise,
2327  float *gain) {
2328  cpl_propertylist *p_rg;
2329  const char *fctid = "vircam_jmp_get_readnoise_gain";
2330 
2331  /* Load the propertylist */
2332 
2333  p_rg = cpl_propertylist_load(cpl_frame_get_filename(ps.readgain_file),
2334  (cpl_size)jext);
2335 
2336  /* Check the readnoise property type and read it */
2337 
2338  switch (cpl_propertylist_get_type(p_rg,"ESO QC READNOISE")) {
2339  case CPL_TYPE_FLOAT:
2340  *readnoise = cpl_propertylist_get_float(p_rg,"ESO QC READNOISE");
2341  break;
2342  case CPL_TYPE_DOUBLE:
2343  *readnoise = (float)cpl_propertylist_get_double(p_rg,
2344  "ESO QC READNOISE");
2345  break;
2346  default:
2347  cpl_error_reset();
2348  *readnoise = 25.0;
2349  cpl_msg_error(fctid,"Unable to get READNOISE estimate, guessing %g\n",
2350  *readnoise);
2351  }
2352 
2353  /* Now the gain */
2354 
2355  switch (cpl_propertylist_get_type(p_rg,"ESO QC CONAD")) {
2356  case CPL_TYPE_FLOAT:
2357  *gain = cpl_propertylist_get_float(p_rg,"ESO QC CONAD");
2358  break;
2359  case CPL_TYPE_DOUBLE:
2360  *gain = (float)cpl_propertylist_get_double(p_rg,"ESO QC CONAD");
2361  break;
2362  default:
2363  cpl_error_reset();
2364  *gain = 1.0;
2365  cpl_msg_error(fctid,"Unable to get GAIN estimate, guessing %g\n",
2366  *gain);
2367  }
2368  cpl_propertylist_delete(p_rg);
2369 }
2370 
2371 /*---------------------------------------------------------------------------*/
2386 /*---------------------------------------------------------------------------*/
2387 
2388 extern void vircam_jmp_illum(void) {
2389  int ngood,i,status,ii;
2390  float illcor_rms;
2391  vir_fits **ftmp,*ff,*ffc;
2392  char filt[32];
2393  cpl_table **mstds,*stdscat,*ms,*illcor,*ot;
2394  vir_tfits *outtab;
2395  cpl_propertylist **pl,*phu,*ehu;
2396  const char *fctid = "vircam_jmp_illum";
2397 
2398  /* Set some default values */
2399 
2400  ps.illcor = NULL;
2401 
2402  /* Sort out all images with good status */
2403 
2404  ftmp = cpl_malloc(ps.nscience*sizeof(vir_fits *));
2405  ngood = 0;
2406  for (i = 0; i < ps.nscience; i++) {
2407  ff = ps.sci_fits[i];
2408  if (vircam_fits_get_status(ff) != VIR_FATAL)
2409  ftmp[ngood++] = ff;
2410  }
2411 
2412  /* If there aren't any good images, then get out of here now */
2413 
2414  if (ngood == 0) {
2415  freespace(ftmp);
2416  cpl_msg_error(fctid,"Illumination correction impossible. No good science frames available");
2417  return;
2418  }
2419 
2420  /* What filter is this? */
2421 
2422  if (vircam_pfits_get_filter(vircam_fits_get_phu(ftmp[0]),filt) != VIR_OK) {
2423  cpl_msg_error(fctid,"No filter name in stack header");
2424  freespace(ftmp);
2425  return;
2426  }
2427 
2428  /* Get some workspace for the various arrays you need for the
2429  illumination correction routine */
2430 
2431  mstds = cpl_malloc(ngood*sizeof(cpl_table *));
2432  for (i = 0; i < ngood; i++)
2433  mstds[i] = NULL;
2434  pl = cpl_malloc(ngood*sizeof(cpl_propertylist *));
2435  for (i = 0; i < ngood; i++)
2436  pl[i] = NULL;
2437 
2438  /* For each of the good input frames, do a catalogue generation and
2439  get some matched standards */
2440 
2441  ffc = ps.fconf;
2442  for (i = 0; i < ngood; i++) {
2443  status = VIR_OK;
2444  ff = ftmp[i];
2445  (void)vircam_imcore(ff,ffc,vircam_jmp_config.ipix,
2446  1.5*vircam_jmp_config.threshold,0,
2447  vircam_jmp_config.rcore,vircam_jmp_config.nbsize,2,
2448  3.5,&outtab,&status);
2449  if (status != VIR_OK)
2450  cpl_error_reset();
2451  pl[i] = cpl_propertylist_duplicate(vircam_tfits_get_ehu(outtab));
2452 
2453  /* Get some standard stars */
2454 
2455  (void)vircam_getstds(vircam_fits_get_ehu(ff),1,current_catpath,
2456  current_cat,&stdscat,&status);
2457  if (status == VIR_FATAL) {
2458  freetfits(outtab);
2459  freespace(ftmp);
2460  for (ii = 0; ii < ngood; ii++) {
2461  freetable(mstds[ii]);
2462  freepropertylist(pl[ii]);
2463  }
2464  freespace(mstds);
2465  freespace(pl);
2466  cpl_msg_error(fctid,"Illumination correction fails");
2467  return;
2468  } else if (status == VIR_WARN) {
2469  cpl_error_reset();
2470  freetfits(outtab);
2471  continue;
2472  }
2473 
2474  /* Now match this against the catalogue */
2475 
2476  ot = vircam_tfits_get_table(outtab);
2477  (void)vircam_matchstds(ot,stdscat,300.0,&ms,&status);
2478  if (status == VIR_FATAL) {
2479  freetable(stdscat);
2480  freetfits(outtab);
2481  freespace(ftmp);
2482  for (ii = 0; ii < ngood; ii++) {
2483  freetable(mstds[ii]);
2484  freepropertylist(pl[ii]);
2485  }
2486  freespace(mstds);
2487  freespace(pl);
2488  cpl_msg_error(fctid,"%s",cpl_error_get_message());
2489  return;
2490  }
2491  mstds[i] = ms;
2492  freetfits(outtab);
2493  freetable(stdscat);
2494  }
2495 
2496  /* Call the illumination routine */
2497 
2498  status = VIR_OK;
2499  (void)vircam_illum(ftmp,mstds,pl,ngood,filt,ps.tphottab,128,&illcor,
2500  &illcor_rms,&status);
2501 
2502  /* Wrap the result */
2503 
2504  phu = cpl_propertylist_duplicate(vircam_fits_get_phu(ftmp[0]));
2505  ehu = cpl_propertylist_duplicate(vircam_fits_get_ehu(ftmp[0]));
2506  ps.illcor = vircam_tfits_wrap(illcor,NULL,phu,ehu);
2507  cpl_propertylist_update_float(ehu,"ESO QC ILLUMCOR_RMS",illcor_rms);
2508  cpl_propertylist_set_comment(ehu,"ESO QC ILLUMCOR_RMS",
2509  "RMS of illumination correction map");
2510 
2511  /* Tidy up */
2512 
2513  for (i = 0; i < ngood; i++) {
2514  freetable(mstds[i]);
2515  freepropertylist(pl[i]);
2516  }
2517  freespace(mstds);
2518  freespace(pl);
2519  freespace(ftmp);
2520 }
2521 
2522 /*---------------------------------------------------------------------------*/
2544 /*---------------------------------------------------------------------------*/
2545 
2546 static char *vircam_jmp_outfile(const char *bname, int ind, int isfits) {
2547  int nf;
2548  char *fname;
2549 
2550  /* Count up how much space you need for the output string. The 'isfits'
2551  block accounts for ".fits", an underscore and an EOS*/
2552 
2553  nf = strlen(bname);
2554  if (ind == 0)
2555  nf++;
2556  else
2557  nf += ((int)log10((double)ind)+1);
2558  if (isfits)
2559  nf += 7;
2560  else
2561  nf += 2;
2562 
2563  /* Get the space for the filename */
2564 
2565  fname = cpl_malloc(nf);
2566 
2567  /* Now write the name */
2568 
2569  if (isfits)
2570  (void)snprintf(fname,nf,"%s_%d.fits",bname,ind);
2571  else
2572  (void)snprintf(fname,nf,"%s_%d",bname,ind);
2573  return(fname);
2574 }
2575 
2576 /*---------------------------------------------------------------------------*/
2591 /*---------------------------------------------------------------------------*/
2592 
2593 extern void vircam_jmp_init(void) {
2594 
2595  /* Level 0 stuff */
2596 
2597  ps.labels = NULL;
2598  ps.master_dark = NULL;
2599  ps.master_twilight_flat = NULL;
2600  ps.master_conf = NULL;
2601  ps.master_sky = NULL;
2602  ps.mask = NULL;
2603  ps.chantab = NULL;
2604  ps.phottab = NULL;
2605  ps.tphottab = NULL;
2606  ps.readgain_file = NULL;
2607  ps.science_frames = NULL;
2608  ps.offset_skies = NULL;
2609  ps.product_frames_simple = NULL;
2610  ps.product_frames_simple_off = NULL;
2611  ps.product_frames_super = NULL;
2612  ps.product_frames_superc = NULL;
2613  ps.product_frame_stack = NULL;
2614  ps.product_frame_stackc = NULL;
2615  ps.product_frame_cat = NULL;
2616  ps.product_frame_illcor = NULL;
2617  ps.product_frame_sky = NULL;
2618  ps.phupaf = NULL;
2619  ps.gaincors = NULL;
2620  ps.catpath = NULL;
2621  ps.catname = NULL;
2622  ps.catpath2 = NULL;
2623  ps.catname2 = NULL;
2624 
2625  /* Level 1 stuff */
2626 
2627  ps.fdark = NULL;
2628  ps.fflat = NULL;
2629  ps.fconf = NULL;
2630  ps.fsky = NULL;
2631  ps.fchantab = NULL;
2632  ps.nscience = 0;
2633  ps.sci_fits = NULL;
2634  ps.noffsets = 0;
2635  ps.offsky_fits = NULL;
2636  ps.nustep_sets = 0;
2637  ps.ustep_sets = NULL;
2638  ps.ndith = 0;
2639  ps.ndithc = 0;
2640  ps.dith_input = NULL;
2641  ps.dithc_input = NULL;
2642  ps.stack_frame = NULL;
2643  ps.stackc_frame = NULL;
2644  ps.outcat = NULL;
2645  ps.outsky = NULL;
2646  ps.illcor = NULL;
2647 }
2648 
2649 /*---------------------------------------------------------------------------*/
2670 /*---------------------------------------------------------------------------*/
2671 
2672 extern void vircam_jmp_tidy(int level) {
2673  int i;
2674 
2675  /* Level 1 stuff */
2676 
2677  freefits(ps.fdark);
2678  freefits(ps.fflat);
2679  freefits(ps.fconf);
2680  freefits(ps.fsky);
2681  freetfits(ps.fchantab);
2682  freefitslist(ps.sci_fits,ps.nscience);
2683  freefitslist(ps.offsky_fits,ps.noffsets);
2684  ps.nscience = 0;
2685  for (i = 0; i < ps.nustep_sets; i++) {
2686  freespace(ps.ustep_sets[i].f);
2687  freefits(ps.ustep_sets[i].super);
2688  freefits(ps.ustep_sets[i].superc);
2689  }
2690  freespace(ps.ustep_sets);
2691  ps.nustep_sets = 0;
2692  freespace(ps.dith_input);
2693  ps.ndith = 0;
2694  freespace(ps.dithc_input);
2695  ps.ndithc = 0;
2696 
2697  freefits(ps.stack_frame);
2698  freefits(ps.stackc_frame);
2699  freetfits(ps.outcat);
2700  freetable(ps.matchstds);
2701  freetfits(ps.illcor);
2702  freefits(ps.outsky);
2703 
2704  if (level == 1)
2705  return;
2706 
2707  /* Level 0 stuff */
2708 
2709  freespace(ps.labels);
2710  freeframe(ps.master_dark);
2711  freeframe(ps.master_twilight_flat);
2712  freeframe(ps.master_conf);
2713  freeframe(ps.master_sky);
2714  freemask(ps.mask);
2715  freeframe(ps.chantab);
2716  freeframe(ps.phottab);
2717  freeframe(ps.readgain_file);
2718  freetable(ps.tphottab);
2719  freeframeset(ps.science_frames);
2720  freeframeset(ps.offset_skies);
2721  freepropertylist(ps.phupaf);
2722  freespace(ps.product_frames_simple); /* NB: We only have to delete */
2723  freespace(ps.product_frames_super); /* the arrays and not the frames */
2724  freespace(ps.product_frames_superc); /* as these get passed back */
2725  freespace(ps.product_frames_simple_off); /* to esorex */
2726  freespace(ps.gaincors);
2727  freespace(ps.catpath);
2728  freespace(ps.catname);
2729  freespace(ps.catpath2);
2730  freespace(ps.catname2);
2731 }
2732 
2735 /*
2736 
2737 $Log: not supported by cvs2svn $
2738 Revision 1.56 2010/09/13 11:50:18 jim
2739 removed unnecessary declaration
2740 
2741 Revision 1.55 2010/09/13 11:40:33 jim
2742 Fixed the way DRS SKYCOR is written to header
2743 
2744 Revision 1.54 2010/09/10 11:24:35 jim
2745 Modified skycor so that if a master sky exists, then it uses it rather than
2746 create a new one.
2747 
2748 Revision 1.53 2010/06/07 12:42:40 jim
2749 Modifications to get rid of compiler gripes
2750 
2751 Revision 1.52 2010/06/03 11:33:29 jim
2752 Opened up matching radius in call to vircam_matchxy to deal with the case
2753 where the input WCS is poorly defined.
2754 
2755 Revision 1.51 2010/02/08 16:35:26 jim
2756 Moved the definition of propertylist ps.phupaf to the recipes so that
2757 this doesn't fail when we don't save the simple images
2758 
2759 Revision 1.50 2010/02/08 10:50:09 jim
2760 Fixed GAIN -> CONAD bug
2761 
2762 Revision 1.49 2010/01/31 19:28:46 jim
2763 SKYMED and SKYSIG are moved from DRS to QC in offset skies
2764 
2765 Revision 1.48 2009/11/18 21:08:46 jim
2766 Mods made to wcsfit to restrict standards to those with good photometry and to
2767 limit the number of entries in catalogue to use in matching up with the
2768 standards
2769 
2770 Revision 1.47 2009/09/22 12:29:12 jim
2771 Modified to do offset sky exposures
2772 
2773 Revision 1.46 2009/09/21 14:45:54 jim
2774 Fixed bug in _save_simple where template frame wasn't being defined for
2775 each image extension
2776 
2777 Revision 1.45 2009/09/09 09:46:33 jim
2778 modified in attempt to get headers right
2779 
2780 Revision 1.44 2008/12/09 11:36:45 jim
2781 Fixed _illcor routine so that if the imcore fails the cpl error is reset
2782 
2783 Revision 1.43 2008/12/08 13:04:24 jim
2784 Fixed PRO CATG for catalogue and illumination correction pafs
2785 
2786 Revision 1.42 2008/12/08 06:41:18 jim
2787 Fixed problem where wrong PRO CATG was being written to pafs
2788 
2789 Revision 1.41 2008/11/27 09:13:47 jim
2790 Changed PRO CATG values for interleaved confidence maps so they are different
2791 for science and standard recipes
2792 
2793 Revision 1.40 2008/11/25 18:54:45 jim
2794 removed extra sky stuff
2795 
2796 Revision 1.39 2008/11/25 11:56:38 jim
2797 Routine skycor now allows for either standard or masked object sky correction.
2798 Modification was done to routine which saves superframes to define the
2799 output confidence map as officially a different type from the confidence
2800 maps generated from jittering.
2801 
2802 Revision 1.38 2008/11/21 10:10:06 jim
2803 Patched in newer version of vircam_matchxy
2804 
2805 Revision 1.37 2008/09/30 11:35:01 jim
2806 Added PRO CATG to the pafs
2807 
2808 Revision 1.36 2008/09/29 11:29:46 jim
2809 Some cosmetic fixes. Also define a maximum shift between dither frames
2810 
2811 Revision 1.35 2008/08/28 09:05:37 jim
2812 Fixed bug where QC was being duplicated from master BPM on rare occasions.
2813 Fixed bug where ARCFILE wasn't being written to the paf file for illum_cor
2814 tables. Sky combine is done with medians
2815 
2816 Revision 1.34 2008/08/05 14:07:01 jim
2817 Relaxed matching criteria
2818 
2819 Revision 1.33 2008/07/10 13:05:53 jim
2820 Modified to use v4.2 version of cpl_wcs
2821 
2822 Revision 1.32 2008/06/20 11:13:35 jim
2823 Fixed dodgy call to cpl_wcs_get_image_dims
2824 
2825 Revision 1.31 2008/05/06 08:40:10 jim
2826 Modified to use cpl_wcs interface
2827 
2828 Revision 1.30 2007/11/22 12:34:08 jim
2829 Added line to vircam_jmp_save_illum to make sure that phupaf is defined
2830 when _save_simple isn't called
2831 
2832 Revision 1.29 2007/10/25 17:34:00 jim
2833 Modified to remove lint warnings
2834 
2835 Revision 1.28 2007/10/19 09:25:10 jim
2836 Fixed problems with missing includes
2837 
2838 Revision 1.27 2007/10/19 06:55:06 jim
2839 Modifications made to use new method for directing the recipes to the
2840 standard catalogues using the sof
2841 
2842 Revision 1.26 2007/10/15 12:50:28 jim
2843 Modified for compatibility with cpl_4.0
2844 
2845 Revision 1.25 2007/06/13 08:10:49 jim
2846 Modified to allow for different output file names depending upon the calling
2847 recipe
2848 
2849 Revision 1.24 2007/05/15 08:54:07 jim
2850 Fixed small bug in stack_save and dither_offsets. Also modified dither_offsets
2851 to just send back zeros if there is only one dither frame
2852 
2853 Revision 1.23 2007/05/08 10:41:49 jim
2854 Added gaincor variables
2855 
2856 Revision 1.22 2007/05/02 09:15:37 jim
2857 Modified to use new api for vircam_imcore and vircam_platesol
2858 
2859 Revision 1.21 2007/04/30 09:40:01 jim
2860 Added vircam_paf_append
2861 
2862 Revision 1.20 2007/04/13 12:29:11 jim
2863 Fixed bug in save_simple which mean that ps.pafphu was allocated for every
2864 file rather than just the first one
2865 
2866 Revision 1.19 2007/04/04 16:05:59 jim
2867 Modified to make paf information a bit more correct
2868 
2869 Revision 1.18 2007/04/04 10:34:55 jim
2870 Modified to use new dfs tags
2871 
2872 Revision 1.17 2007/03/14 22:08:54 jim
2873 Fixed typo
2874 
2875 Revision 1.16 2007/03/14 14:49:13 jim
2876 Fixed problem with missing paf files in jmp recipes if detlive = F. Also
2877 fixed problem where extra dummy products were being created
2878 
2879 Revision 1.15 2007/03/13 09:50:53 jim
2880 Fixed bug in vircam_jmp_save_illum where PAF wasn't being saved for the
2881 first extension
2882 
2883 Revision 1.14 2007/03/06 14:06:24 jim
2884 Fixed missing paf write
2885 
2886 Revision 1.13 2007/03/06 13:49:48 jim
2887 Created static routine vircam_jmp_outfile to create a 'predictable'
2888 output filename for each product
2889 
2890 Revision 1.12 2007/03/01 12:42:42 jim
2891 Modified slightly after code checking
2892 
2893 Revision 1.11 2007/02/25 06:34:20 jim
2894 Plugged memory leak
2895 
2896 Revision 1.10 2007/02/15 06:59:38 jim
2897 Added ability to write QC paf files
2898 
2899 Revision 1.9 2007/02/06 13:11:12 jim
2900 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
2901 
2902 Revision 1.8 2007/01/17 23:54:00 jim
2903 Plugged some memory leaks
2904 
2905 Revision 1.7 2006/12/19 13:30:01 jim
2906 Fixed vircam_jmp_illum to initialise pointers
2907 
2908 Revision 1.6 2006/12/18 12:51:20 jim
2909 Tightened up some of the error reporting
2910 
2911 Revision 1.5 2006/12/15 09:58:28 jim
2912 read noise and gain keywords were wrong...
2913 
2914 Revision 1.4 2006/11/29 12:28:45 jim
2915 Modified so that the correct recipe names would appear in the headers of
2916 data products
2917 
2918 Revision 1.3 2006/11/28 22:10:22 jim
2919 Added illcor_rms to calling sequence of vircam_illum
2920 
2921 Revision 1.2 2006/11/28 20:56:31 jim
2922 Added vircam_jmp_illum and vircam_jmp_save_illum
2923 
2924 Revision 1.1 2006/11/27 11:54:37 jim
2925 Initial entry
2926 
2927 
2928 */
2929