Astro::FITS::HdrTrans::JAC - Base class for translation of Joint


Astro-FITS-HdrTrans documentation Contained in the Astro-FITS-HdrTrans distribution.

Index


Code Index:

NAME

Top

Astro::FITS::HdrTrans::JAC - Base class for translation of Joint Astronomy Centre instruments.

SYNOPSIS

Top

  use Astro::FITS::HdrTrans::JAC;

DESCRIPTION

Top

This class provides a generic set of translations that are common to instrumentation from the Joint Astronomy Centre. It should not be used directly for translation of instrument FITS headers.

This routine overrides the base class implementation to enable the caches to be cleared and for the location of the DATE-OBS/DATE-END field to be found so that base class implementations will work correctly.

This means that some conversion methods (in particular those using time in a base class) may not work properly outside the context of a full translation unless they have been subclassed locally.

COMPLEX CONVERSIONS

Top

These methods are more complicated than a simple mapping. We have to provide both from- and to-FITS conversions All these routines are methods and the to_ routines all take a reference to a hash and return the translated value (a many-to-one mapping). The from_ methods take a reference to a generic hash and return a translated hash (sometimes these are many-to-many).

to_OBSERVATION_ID

Converts the OBSID header directly into the OBSERVATION_ID generic header, or if that header does not exist, converts the INSTRUME, RUNNR, and DATE-OBS headers into OBSERVATION_ID.

The form of the observation ID string is documented in JSA/ANA/001 (http://docs.jach.hawaii.edu/JCMT/JSA/ANA/001/jsa_ana_001.pdf).

_fix_dates

Sort out DATE-OBS and DATE-END in cases where they are not available directly. This is mainly an issue with database retrievals where the date format is not FITS compliant.

  Astro::FITS::HdrTrans::JAC->_fix_dates( \%headers );

REVISION

Top

$Id$

SEE ALSO

Top

Astro::FITS::HdrTrans, Astro::FITS::HdrTrans::Base.

AUTHOR

Top

Brad Cavanagh <b.cavanagh@jach.hawaii.edu>.

COPYRIGHT

Top


Astro-FITS-HdrTrans documentation Contained in the Astro-FITS-HdrTrans distribution.
package Astro::FITS::HdrTrans::JAC;

use 5.006;
use warnings;
use strict;
use Carp;

use DateTime;
use DateTime::TimeZone;
# Cache UTC definition
our $UTC = DateTime::TimeZone->new( name => 'UTC' );

# Inherit from the Base translation class and not HdrTrans itself
# (which is just a class-less wrapper).

use base qw/ Astro::FITS::HdrTrans::FITS /;

use vars qw/ $VERSION /;

$VERSION = "1.50";

# in each class we have three sets of data.
#   - constant mappings
#   - unit mappings
#   - complex mappings

# For a constant mapping, there is no FITS header, just a generic
# header that is constant.
my %CONST_MAP = (
                );

# Unit mapping implies that the value propagates directly
# to the output with only a keyword name change.

my %UNIT_MAP = (
                MSBID              => 'MSBID',
                MSB_TRANSACTION_ID => 'MSBTID',
               );

# Create the translation methods.
__PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP );

sub translate_from_FITS {
  my $class = shift;
  my $headers = shift;

  # sort out DATE-OBS and DATE-END
  $class->_fix_dates( $headers );

  # Go to the base class
  return $class->SUPER::translate_from_FITS( $headers, @_ );
}



sub to_OBSERVATION_ID {
  my $self = shift;
  my $FITS_headers = shift;

  my $return;
  if ( exists( $FITS_headers->{'OBSID'} ) &&
       defined( $FITS_headers->{'OBSID'} ) ) {
    $return = $FITS_headers->{'OBSID'};
  } else {

    my $instrume = lc( $self->to_INSTRUMENT( $FITS_headers ) );
    my $obsnum = $self->to_OBSERVATION_NUMBER( $FITS_headers );
    my $dateobs = $self->to_UTSTART( $FITS_headers );

    my $datetime;
    if ( defined $dateobs && defined $obsnum ) {
      $datetime = $dateobs->datetime;
      $datetime =~ s/-//g;
      $datetime =~ s/://g;

      $return = join '_', $instrume, $obsnum, $datetime;
    }
  }

  return $return;

}

sub _fix_dates {
  my ( $class, $FITS_headers ) = @_;

  # DATE-OBS can be from LONGDATEOBS LONGDATE or DATE_OBS
  __PACKAGE__->_try_dates( $FITS_headers, 'DATE-OBS', qw/ LONGDATEOBS LONGDATE DATE_OBS / );

  # DATE-END can be from DATE_END or LONGDATEEND
  __PACKAGE__->_try_dates( $FITS_headers, 'DATE-END', qw/ LONGDATEEND DATE_END / );

  return;
}

# helper routine for _fix_dates
sub _try_dates {
  my ( $class, $FITS_headers, $outkey, @tests ) = @_;

  if (!exists $FITS_headers->{$outkey}) {
    for my $key (@tests) {
      if ( exists( $FITS_headers->{$key} ) ) {
        my $date = _convert_sybase_date( $FITS_headers->{$key} );
        if( defined( $date ) ) {
          $FITS_headers->{$outkey} = $date->datetime;
          last;
        }
      }
    }
  }
  return;
}

sub _convert_sybase_date {
  my $sybase_date = shift;

  $sybase_date =~ s/:\d\d\d//;
  $sybase_date =~ s/\s*$//;

  if( $sybase_date =~ /\s*(\w+)\s+(\d{1,2})\s+(\d{4})\s+(\d{1,2}):(\d\d):(\d\d)(AM|PM)/ ) {

    my $hour = $4;
    if (uc($7) eq 'AM' && $hour == 12) {
      $hour = 0;
    } elsif ( uc($7) eq 'PM' && $hour < 12 ) {
      $hour += 12;
    }

    my %mon_lookup = ( 'Jan' => 1,
                       'Feb' => 2,
                       'Mar' => 3,
                       'Apr' => 4,
                       'May' => 5,
                       'Jun' => 6,
                       'Jul' => 7,
                       'Aug' => 8,
                       'Sep' => 9,
                       'Oct' => 10,
                       'Nov' => 11,
                       'Dec' => 12 );
    my $month = $mon_lookup{$1};

    my $return = DateTime->new( year => $3,
                                month => $month,
                                day => $2,
                                hour => $hour,
                                minute => $5,
                                second => $6,
                                time_zone => $UTC,
                              );
    return $return;

  } else {
    return undef;
  }
}

1;