#!/star/Perl/bin/perl =head1 NAME orac_fits_fix.pl -- fix a set of FITS file headers for use with ORACDR =head1 SYNOPSIS orac_fits_fix.pl [-n NOFFSETS] [-r RECIPE] FITS_file FITS_file2 ... FITS_file2 =head1 DESCRIPTION This Perl script is modifies headers of a FITS file in situ to correct them for use with ORACDR. In normal circumstances this should not be necessary. Sometimes things go awry during your observing - the most common neing a sequence of observations which doesn't properly finish, and so you need to change the headers so it is treated (eg.) as a group of N-1 files instead of a group of N files. This script expects to receive a sequence of NOFFSETS files. It will then reassign the GRPNUM, OBSNUM, GRPMEM, GRPNUM, NOFFSETS and (if requested) the reduction RECIPE appropriately. it will complain if the number of files given is not a multiple of the provided NOFFSETS. If NOFFSETS is not provided it will set NOFFSETS to the number of files. =over 4 =item 1. Open the FITS file. You must have write access. =item 2. Read the relevant headers, one or more of OBSTYPE, OBSNUM, GRPNUM, GRPMEM, and RECIPE. The code and comments explain these further. Note that three are related by the formula GRPMEM = OBSNUM - GRPNUM + 1. =item 3. Perform the calculations or assign substitute values. =item 4. Update the headers to contain the modified values. =item 5. Close the file. =back =head1 ARGUMENTS A space-separated list of FITS files to modify. The usual shell file wildcards may be included. =head1 NOTES If you are squeamish and prefer not to edit the raw data frames, you can run the ORAC-DR pipeline oracdr -from 1 QUICK_LOOK -nodisplay to convert the FITS files to NDFs for the night's observations. Then use the FITSMOD task in KAPPA to edit the headers. See SUN/232 for examples. =head1 REQUIREMENTS The CFITSIO Perl module, available from http://www.cpan.org/. This may already be installed at your site. =head1 AUTHOR Malcolm J. Currie (JAC) =cut # We need the CFITSIO library to manipulate the FITS header. use Astro::FITS::CFITSIO qw( :longnames ); use Astro::FITS::CFITSIO qw( :constants ); # Declare variables. my ( $obstype, $grpnum, $grpmem, $obsnum, $recipe, $noffsets ); my ( $typscomment, $numcomment, $memcomment, $obscomment, $reccomment ); # Initialise the inherited status to OK. my $status = 0; my $usage = "Usage: orac_fits_fix [-n NOFFSETS] [-r RECIPE] FITS_file1 ... FITS_filen\n". " if specified number of files must be multiple of NOFFSETS\n"; if ($#ARGV < 0 ) { die $usage }; while ( $ARGV[0] =~ /^\-/ ) { my $mod = shift; if ( $mod =~ /\-n/ ) { $noffsets = shift; } elsif ( $mod =~ /\-r/ ) { $recipe = shift; } else { die "\nAborting: Unknown option $mod\n$usage\n"; } } $nfiles = $#ARGV + 1; if ( defined $noffsets ) { if ( ($nfiles/$noffsets) != int($nfiles/$noffsets) ) { die "\nAborting: $nfiles files is not a multiple of the specified NOFFSETS=$noffsets\n$usage"; } } else { $noffsets = $nfiles; } # Process each FITS file listed on the command line. foreach my $file ( @ARGV ) { # Open the FITS file. my $fitsfile = Astro::FITS::CFITSIO::open_file( $file, Astro::FITS::CFITSIO::READWRITE(), $status ); if ( $status ) { die "Can't open file: $!"; } # Obtain the headers pertinent to ORAC. # ===================================== # Obtain the OBSTYPE string value and associated comment. OBSTYPE # is the observation type, and will normally be "DARK", "OBJECT", or # "SKY". # # Note we ignore any bad status on reading those parameters, assuming that IF we # failed to read something, then we will create it anew when we update the file. # The exception to this is the OBSNUM which we NEED to know! # # $fitsfile->read_record( $i, $record, $status) $fitsfile->read_key( TSTRING, "OBSTYPE", $OBSTYPE, $typcomment, $status ); $status = 0; # Obtain the OBSNUM integer value and associated comment. OBSNUM is # the frame number of the observation, starting from 1 on each night. # Bad status on this item causes a default of 1 to be used as the starting # file number. $fitsfile->read_key( TINT, "OBSNUM", $OBSNUM, $obscomment, $status ); if (( $status ne 0) and !(defined $grpnum)) { $OBSNUM = 1; print "\n Warning: Failed to read FITS key from first file $file.\n". " Assigning fallback value of OBSNUM=1\n"; } # Obtain the GRPNUM integer value and associated comment. GRPNUM # specifies the number of observation (group of frames), and should be # given by the frame number (OBSNUM) of its first member. $fitsfile->read_key( TINT, "GRPNUM", $GRPNUM, $numcomment, $status ); $status = 0; # Obtain the GRPMEM integer value and associated comment. GRPMEM # specifies the sequence number within the group, counting from 1. $fitsfile->read_key( TINT, "GRPMEM", $GRPMEM, $memcomment, $status ); $status = 0; # Obtain the RECIPE name and assoicated comment. $fitsfile->read_key( TSTRING, "RECIPE", $RECIPE, $reccomment, $status ); $status = 0; # Obtain the RECIPE name and assoicated comment. $fitsfile->read_key( TINT, "NOFFSETS", $NOFFSETS, $nofcomment, $status ); $status = 0; # # If $grpnum is undefined, then this is the first file in the list. # So set grpnum to OBSNUM of that file from that file, and set obsnum # to the same number. # # OTHERWISE this is a subsequent file, so increment obsnum and grpmem. # if ( defined $grpnum ) { $obsnum++; $grpmem++; } else { $grpnum = $OBSNUM; $obsnum = $OBSNUM; $grpmem = 1; } # Make changes to values here. # ============================ $GRPNUM = $grpnum; $GRPMEM = $grpmem; $OBSNUM = $obsnum; $NOFFSETS = $noffsets; if ( defined $recipe ) {$RECIPE = $recipe}; # Note this equation. This defines the inter-relationships between # the integer counters. Rearrange as needed for your editing. # $grpnum = $obsnum - $grpmem + 1; # # Replace the revised items. print "$file : OBSNUM $OBSNUM GRPNUM $GRPNUM GRPMEM $GRPMEM NOFFSETS $NOFFSETS RECIPE $RECIPE\n"; $fitsfile->update_key( TINT, "OBSNUM", $OBSNUM, $obscomment, $status ); $fitsfile->update_key( TINT, "GRPNUM", $GRPNUM, $numcomment, $status ); $fitsfile->update_key( TINT, "GRPMEM", $GRPMEM, $memcomment, $status ); $fitsfile->update_key( TSTRING, "RECIPE", $RECIPE, $reccomment, $status ); $fitsfile->update_key( TINT, "NOFFSETS", $NOFFSETS, $nofcomment, $status ); # Close the FITS file. $fitsfile->close_file( $status ); if ($status ne 0) { print "Warning: Probable failure to write correct output to $file !!!\n"; $status=0; } }