Astro-FITS-HdrTrans

 view release on metacpan or  search on metacpan

lib/Astro/FITS/HdrTrans/ESO.pm  view on Meta::CPAN

  return $slitangle;
}

sub from_SLIT_ANGLE {
  my $self = shift;
  my $generic_headers = shift;
  "HIERARCH.ESO.ADA.POSANG",  $generic_headers->{ "SLIT_ANGLE" };
}

sub to_STANDARD {
  my $self = shift;
  my $FITS_headers = shift;
  my $standard = 0;
  my $type = $FITS_headers->{"HIERARCH.ESO.DPR.TYPE"};
  if ( uc( $type ) =~ /STD/ ) {
    $standard = 1;
  }
  return $standard;
}

sub from_STANDARD {
  my $self = shift;
  my $generic_headers = shift;
  "STANDARD",  $generic_headers->{ "STANDARD" };
}

sub to_UTDATE {
  my $self = shift;
  my $FITS_headers = shift;
  return $self->get_UT_date( $FITS_headers );
}

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

  # Obtain the start time.
  my $start = $self->to_UTSTART( $FITS_headers );

  # Approximate end time.
  return $self->_add_seconds( $start, $FITS_headers->{EXPTIME} );
}

sub to_UTSTART {
  my $self = shift;
  my $FITS_headers = shift;
  my $return;
  if ( exists $FITS_headers->{'DATE-OBS'} ) {
    $return = $self->_parse_iso_date( $FITS_headers->{'DATE-OBS'} );
  } elsif (exists $FITS_headers->{UTC}) {

    # Converts the UT date in YYYYMMDD format obytained from the headers to a
    # date object at midnight.  Then add the seconds past midnight to the
    # object.
    my $base = $self->to_UTDATE( $FITS_headers );
    my $basedate = $self->_utdate_to_object( $base );
    $return = $self->_add_seconds( $basedate, $FITS_headers->{UTC} );

  } elsif ( exists( $FITS_headers->{"HIERARCH.ESO.OBS.START"} ) ) {

    # Use the backup of the observation start header, which is encoded in
    # FITS data format, i.e. yyyy-mm-ddThh:mm:ss.
    $return = $self->_parse_iso_date( $FITS_headers->{"HIERARCH.ESO.OBS.START"});
  }
  return $return;
}

sub to_WAVEPLATE_ANGLE {
  my $self = shift;
  my $FITS_headers = shift;
  my $polangle = 0.0;
  if ( exists $FITS_headers->{"HIERARCH.ESO.ADA.POSANG"} ) {
    $polangle = $FITS_headers->{"HIERARCH.ESO.ADA.POSANG"};
  } elsif ( exists $FITS_headers->{"HIERARCH.ESO.SEQ.ROT.OFFANGLE"} ) {
    $polangle = $FITS_headers->{"HIERARCH.ESO.SEQ.ROT.OFFANGLE"};
  } elsif ( exists $FITS_headers->{CROTA1} ) {
    $polangle = abs( $FITS_headers->{CROTA1} );
  }
  return $polangle;
}

sub from_WAVEPLATE_ANGLE {
  my $self = shift;
  my $generic_headers = shift;
  "HIERARCH.ESO.ADA.POSANG",  $generic_headers->{ "WAVEPLATE_ANGLE" };
}

# Use the nominal reference pixel if correctly supplied, failing that
# take the average of the bounds, and if these headers are also absent,
# use a default which assumes the full array.
sub to_X_REFERENCE_PIXEL{
  my $self = shift;
  my $FITS_headers = shift;
  my $xref;
  if ( exists $FITS_headers->{CRPIX1} ) {
    $xref = $FITS_headers->{CRPIX1};
  } elsif ( exists $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTX"} && exists $FITS_headers->{"HIERARCH.ESO.DET.WIN.NX"} ) {
    my $xl = $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTX"};
    my $xu = $FITS_headers->{"HIERARCH.ESO.DET.WIN.NX"};
    $xref = $self->nint( ( $xl + $xu ) / 2 );
  } else {
    $xref = 504;
  }
  return $xref;
}

sub to_X_LOWER_BOUND {
  my $self = shift;
  my $FITS_headers = shift;
  return $self->nint( $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTX"} );
}

sub from_X_REFERENCE_PIXEL {
  my $self = shift;
  my $generic_headers = shift;
  "CRPIX1", $generic_headers->{"X_REFERENCE_PIXEL"};
}

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

lib/Astro/FITS/HdrTrans/ESO.pm  view on Meta::CPAN

  } elsif ( exists $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTY"} && exists $FITS_headers->{"HIERARCH.ESO.DET.WIN.NY"} ) {
    my $yl = $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTY"};
    my $yu = $FITS_headers->{"HIERARCH.ESO.DET.WIN.NY"};
    $yref = $self->nint( ( $yl + $yu ) / 2 );
  } else {
    $yref = 491;
  }
  return $yref;
}

sub from_Y_REFERENCE_PIXEL {
  my $self = shift;
  my $generic_headers = shift;
  "CRPIX2", $generic_headers->{"Y_REFERENCE_PIXEL"};
}

sub to_Y_UPPER_BOUND {
  my $self = shift;
  my $FITS_headers = shift;
  return $FITS_headers->{"HIERARCH.ESO.DET.WIN.STARTY"} - 1 + $FITS_headers->{"HIERARCH.ESO.DET.WIN.NY"};
}

# Supplementary methods for the translations
# ------------------------------------------

# Get the observation mode.
sub get_instrument_mode {
  my $self = shift;
  my $FITS_headers = shift;
  my $mode = uc( $FITS_headers->{"HIERARCH.ESO.DPR.TECH"} );
  if ( $mode eq "IMAGE" || $mode eq "POLARIMETRY" ) {
    $mode = "imaging";
  } elsif ( $mode =~ /SPECTRUM/ ) {
    $mode = "spectroscopy";
  }
  return $mode;
}

# Returns the UT date in YYYYMMDD format.
sub get_UT_date {
  my $self = shift;
  my $FITS_headers = shift;

  # This is UT start and time.
  my $dateobs = $FITS_headers->{"DATE-OBS"};

  # Extract out the data in yyyymmdd format.
  return substr( $dateobs, 0, 4 ) . substr( $dateobs, 5, 2 ) . substr( $dateobs, 8, 2 )
}

# Returns the UT time of start of observation in decimal hours.
sub get_UT_hours {
  my $self = shift;
  my $FITS_headers = shift;

  # This is approximate.  UTC is time in seconds.
  my $startsec = 0.0;
  if ( exists ( $FITS_headers->{UTC} ) ) {
    $startsec  = $FITS_headers->{UTC};

    # Use the backup of the observation start header, which is encoded in
    # FITS data format, i.e. yyyy-mm-ddThh:mm:ss.  So convert ot seconds.
  } elsif ( exists( $FITS_headers->{"HIERARCH.ESO.OBS.START"} ) ) {
    my $t = $FITS_headers->{"HIERARCH.ESO.OBS.START"};
    $startsec = substr( $t, 11, 2 ) * 3600.0 +
      substr( $t, 14, 2 ) * 60.0 + substr( $t, 17, 2  );
  }

  # Convert from seconds to decimal hours.
  return $startsec / 3600.0;
}

sub rotation {
  my $self = shift;
  my $FITS_headers = shift;
  my $rotangle;

  # Define degrees-to-radians conversion.
  my $dtor = atan2( 1, 1 ) / 45.0;

  # The PC matrix first.
  if ( exists $FITS_headers->{PC001001} ) {
    my $pc11 = $FITS_headers->{PC001001};
    my $pc21 = $FITS_headers->{PC002001};
    $rotangle = $dtor * atan2( -$pc21 / $dtor, $pc11 / $dtor );

    # Instead try CD matrix.  Testing for existence of first column should
    # be adequate.
  } elsif ( exists $FITS_headers->{CD1_1} && exists $FITS_headers->{CD2_1}) {

    my $cd11 = $FITS_headers->{CD1_1};
    my $cd12 = $FITS_headers->{CD1_2};
    my $cd21 = $FITS_headers->{CD2_1};
    my $cd22 = $FITS_headers->{CD2_2};
    my $sgn;
    if ( ( $cd11 * $cd22 - $cd12 * $cd21 ) < 0 ) {
      $sgn = -1;
    } else {
      $sgn = 1;
    }
    my $cdelt1 = $sgn * sqrt( $cd11**2 + $cd21**2 );
    my $sgn2;
    if ( $cdelt1 < 0 ) {
      $sgn2 = -1;
    } else {
      $sgn2 = 1;
    }
    $rotangle = atan2( -$cd21 * $dtor, $sgn2 * $cd11 * $dtor ) / $dtor;

    # Orientation may be encapsulated in the slit position angle for
    # spectroscopy.
  } else {
    if ( uc( $self->get_instrument_mode($FITS_headers) ) eq "SPECTROSCOPY" &&
         exists $FITS_headers->{"HIERARCH.ESO.ADA.POSANG"} ) {
      $rotangle = $FITS_headers->{"HIERARCH.ESO.ADA.POSANG"};
    } else {
      $rotangle = 180.0;
    }
  }
  return $rotangle;
}



( run in 2.909 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )