| Astro-FITS-HdrTrans documentation | Contained in the Astro-FITS-HdrTrans distribution. |
Astro::FITS::HdrTrans::NACO - ESO NACO translations
use Astro::FITS::HdrTrans::NACO; %gen = Astro::FITS::HdrTrans::NACO->translate_from_FITS( %hdr );
This class provides a generic set of translations that are specific to the NACO camera of the European Southern Observatory.
The name of the instrument required to match (case insensitively)
against the INSTRUME/INSTRUMENT keyword to allow this class to
translate the specified headers. Called by the default
can_translate method.
$inst = $class->this_instrument();
Returns "NAOS+CONICA".
$Id: SOFI.pm 14879 2008-02-13 21:51:31Z timj $
Astro::FITS::HdrTrans, Astro::FITS::HdrTrans::UKIRT.
Malcolm J. Currie <mjc@star.rl.ac.uk> Brad Cavanagh <b.cavanagh@jach.hawaii.edu>, Tim Jenness <t.jenness@jach.hawaii.edu>.
Copyright (C) 2008 Science and Technology Facilities Council. Copyright (C) 2003-2005 Particle Physics and Astronomy Research Council. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either Version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
| Astro-FITS-HdrTrans documentation | Contained in the Astro-FITS-HdrTrans distribution. |
package Astro::FITS::HdrTrans::NACO;
use 5.006; use warnings; use strict; use Carp; # Inherit from ESO use base qw/ Astro::FITS::HdrTrans::ESO /; use vars qw/ $VERSION /; $VERSION = "1.50"; # for a constant mapping, there is no FITS header, just a generic # header that is constant my %CONST_MAP = ( POLARIMETRY => 0, ); # NULL mappings used to override base class implementations my @NULL_MAP = qw/ /; # unit mapping implies that the value propogates directly # to the output with only a keyword name change my %UNIT_MAP = ( ); # Create the translation methods __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP, \@NULL_MAP );
sub this_instrument { return "NAOS+CONICA"; }
sub to_DEC_SCALE { my $self = shift; my $FITS_headers = shift; my $scale; my $scale_def = 0.0271; if ( exists ( $FITS_headers->{CDELT2} ) ) { $scale = $FITS_headers->{CDELT2}; } elsif ( exists ( $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} ) ) { $scale = $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} / 3600.0; } $scale = defined( $scale ) ? $scale: $scale_def; return $scale; } # If the telescope ofset exists in arcsec, then use it. Otherwise # convert the Cartesian offsets to equatorial offsets. sub to_DEC_TELESCOPE_OFFSET { my $self = shift; my $FITS_headers = shift; my $decoffset = 0.0; if ( exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETD"} ) { $decoffset = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETD"}; } elsif ( exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETX"} && exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETY"} ) { my $pixscale = 0.0271; if ( exists $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} ) { $pixscale = $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"}; } # Sometimes the first cumulative offsets are non-zero contrary to the # documentation. my $expno = 1; if ( exists $FITS_headers->{"HIERARCH.ESO.TPL.EXPNO"} ) { $expno = $FITS_headers->{"HIERARCH.ESO.TPL.EXPNO"}; } my ( $x_as, $y_as ); if ( $expno == 1 ) { $x_as = 0.0; $y_as = 0.0; } else { $x_as = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETX"} * $pixscale; $y_as = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETY"} * $pixscale; } # Define degrees to radians conversion and obtain the rotation angle. my $dtor = atan2( 1, 1 ) / 45.0; my $rotangle = $self->rotation($FITS_headers); my $cosrot = cos( $rotangle * $dtor ); my $sinrot = sin( $rotangle * $dtor ); # Apply the rotation matrix to obtain the equatorial pixel offset. $decoffset = -$x_as * $sinrot + $y_as * $cosrot; } # The sense is reversed compared with UKIRT, as these measure the # place on the sky, not the motion of the telescope. return -1.0 * $decoffset; } # Derive the translation between observing template and recipe name. sub to_DR_RECIPE { my $self = shift; my $FITS_headers = shift; my $recipe = "QUICK_LOOK"; # Obtain the observing template. These are equivalent # to the UKIRT OT science programmes and their tied DR recipes. # However, there are some wrinkles and variations to be tested. my $template = $FITS_headers->{"HIERARCH.ESO.TPL.ID"}; my $seq = $FITS_headers->{"HIERARCH.ESO.TPL.PRESEQ"}; if ( $template =~ /_img_obs_AutoJitter/ || $template =~ /_img_obs_GenericOffset/ ) { $recipe = "JITTER_SELF_FLAT"; } elsif ( $template =~ /_img_cal_StandardStar/ || $template =~ /_img_cal_StandardStarOff/ || $template =~ /_img_tec_Zp/ || $template =~ /_img_tec_ZpNoChop/ || $seq =~ /_img_cal_StandardStar/ || $seq =~ /_img_cal_StandardStarOff/ ) { $recipe = "JITTER_SELF_FLAT_APHOT"; } elsif ( $template =~ /_img_obs_AutoJitterOffset/ || $template =~ /_img_obs_FixedSkyOffset/ ) { $recipe = "CHOP_SKY_JITTER"; # The following two perhaps should be using NOD_CHOP and a variant of # NOD_CHOP_APHOT to cope with the three source images (central double # flux) rather than four. } elsif ( $template =~ /_img_obs_AutoChopNod/ || $seq =~ /_img_obs_AutoChopNod/ ) { $recipe = "NOD_SELF_FLAT_NO_MASK"; } elsif ( $template =~ /_img_cal_ChopStandardStar/ ) { $recipe = "NOD_SELF_FLAT_NO_MASK_APHOT"; } elsif ( $template =~ /_cal_Darks/ || $seq =~ /_cal_Darks/ ) { $recipe = "REDUCE_DARK"; } elsif ( $template =~ /_img_cal_TwFlats/ || $template =~ /_img_cal_SkyFlats/ ) { $recipe = "SKY_FLAT_MASKED"; } elsif ( $template =~ /_img_cal_LampFlats/ ) { $recipe = "LAMP_FLAT"; # Imaging spectroscopy. There appears to be no distinction # for flats from target, hence no division into POL_JITTER and # SKY_FLAT_POL. } elsif ( $template =~ /_pol_obs_GenericOffset/ || $template =~ /_pol_cal_StandardStar/ ) { $recipe = "POL_JITTER"; } elsif ( $template =~ /_pol_obs_AutoChopNod/ || $template =~ /_pol_cal_ChopStandardStar/ ) { $recipe = "POL_NOD_CHOP"; } elsif ( $template =~ /_pol_cal_LampFlats/ ) { $recipe = "POL_JITTER"; # Spectroscopy. EXTENDED_SOURCE may be more appropriate for # the NACO_spec_obs_GenericOffset template. } elsif ( $template =~ /_spec_obs_AutoNodOnSlit/ || $template =~ /_spec_obs_GenericOffset/ || $template =~ /_spec_obs_AutoChopNod/ ) { $recipe = "POINT_SOURCE"; } elsif ( $template =~ /_spec_cal_StandardStar/ || $template =~ /_spec_cal_StandardStarNod/ || $template =~ /_spec_cal_AutoNodOnSlit/ ) { $recipe = "STANDARD_STAR"; } elsif ( $template =~ /_spec_cal_NightCalib/ ) { $recipe = "REDUCE_SINGLE_FRAME"; } elsif ( $template =~ /_spec_cal_Arcs/ || $seq =~ /_spec_cal_Arcs/ ) { $recipe = "REDUCE_ARC"; } elsif ( $template =~ /_spec_cal_LampFlats/ ) { $recipe = "LAMP_FLAT"; } return $recipe; } # Filters appear to be in wheels 4 to 6. It appears the filter # in just one of the three. sub to_FILTER { my $self = shift; my $FITS_headers = shift; my $filter = "empty"; my $id = 4; while ( $filter eq "empty" && $id < 7 ) { if ( exists $FITS_headers->{"HIERARCH.ESO.INS.OPTI${id}.NAME"} ) { $filter = $FITS_headers->{"HIERARCH.ESO.INS.OPTI${id}.NAME"}; } $id++; } return $filter; } # Fixed value for the gain, as that's all the documentation gives. # the readout mode. sub to_GAIN { 10; } # Using Table 10 of the NACO USer's Guide. sub to_GRATING_DISPERSION { my $self = shift; my $FITS_headers = shift; my $dispersion = 0.0; if ( exists $FITS_headers->{CDELT1} ) { $dispersion = $FITS_headers->{CDELT1}; } else { if ( exists $FITS_headers->{"HIERARCH.ESO.INS.GRAT.NAME"} && exists $FITS_headers->{"HIERARCH.ESO.OPTI7.NAME"} ) { my $order = $FITS_headers->{"HIERARCH.ESO.INS.GRAT.ORDER"}; my $camera = $FITS_headers->{"HIERARCH.ESO.OPTI7.NAME"}; if ( $camera eq "S54" ) { if ( $order == 1 ) { $dispersion = 1.98e-3; } elsif ( $order == 2 ) { $dispersion = 6.8e-4; } elsif ( $order == 3 ) { $dispersion = 9.7e-4; } } elsif ( $camera eq "L54" ) { $dispersion = 3.20e-3; } elsif ( $camera eq "S27" ) { if ( $order == 1 ) { $dispersion = 9.5e-4; } elsif ( $order == 2 ) { $dispersion = 5.0e-4; } } } } return $dispersion; } sub to_RA_SCALE { my $self = shift; my $FITS_headers = shift; my $scale; my $scale_def = -0.0271; if ( exists ( $FITS_headers->{CDELT1} ) ) { $scale = $FITS_headers->{CDELT1}; } elsif ( exists ( $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} ) ) { $scale = - $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} / 3600.0; } $scale = defined( $scale ) ? $scale: $scale_def; return $scale; } # If the telescope offset exists in arcsec, then use it. Otherwise # convert the Cartesian offsets to equatorial offsets. sub to_RA_TELESCOPE_OFFSET { my $self = shift; my $FITS_headers = shift; my $raoffset = 0.0; if ( exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETA"} ) { $raoffset = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETA"}; } elsif ( exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETX"} && exists $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETY"} ) { my $pixscale = 0.0271; if ( exists $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"} ) { $pixscale = $FITS_headers->{"HIERARCH.ESO.INS.PIXSCALE"}; } # Sometimes the first cumulative offsets are non-zero contrary to the # documentation. my $expno = 1; if ( exists $FITS_headers->{"HIERARCH.ESO.TPL.EXPNO"} ) { $expno = $FITS_headers->{"HIERARCH.ESO.TPL.EXPNO"}; } my ( $x_as, $y_as ); if ( $expno == 1 ) { $x_as = 0.0; $y_as = 0.0; } else { $x_as = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETX"} * $pixscale; $y_as = $FITS_headers->{"HIERARCH.ESO.SEQ.CUMOFFSETY"} * $pixscale; } # Define degrees to radians conversion and obtain the rotation angle. my $dtor = atan2( 1, 1 ) / 45.0; my $rotangle = $self->rotation($FITS_headers); my $cosrot = cos( $rotangle * $dtor ); my $sinrot = sin( $rotangle * $dtor ); # Apply the rotation matrix to obtain the equatorial pixel offset. $raoffset = -$x_as * $cosrot + $y_as * $sinrot; } # The sense is reversed compared with UKIRT, as these measure the # place on the sky, not the motion of the telescope. return -1.0 * $raoffset; } # Just translate to shorter strings for ease and to fit within the # night log. sub to_SPEED_GAIN { my $self = shift; my $FITS_headers = shift; my $spd_gain = "HighSens"; my $detector_mode = exists( $FITS_headers->{"HIERARCH.ESO.DET.MODE.NAME"} ) ? $FITS_headers->{"HIERARCH.ESO.DET.MODE.NAME"} : $spd_gain; if ( $detector_mode eq "HighSensitivity" ) { $spd_gain = "HighSens"; } elsif ( $detector_mode eq "HighDynamic" ) { $spd_gain = "HighDyn"; } elsif ( $detector_mode eq "HighBackground" ) { $spd_gain = "HighBack"; } return $spd_gain; } # Translate to the SLALIB name for reference frame in spectroscopy. sub to_TELESCOPE { my $self = shift; my $FITS_headers = shift; my $telescope = "VLT4"; if ( exists $FITS_headers->{TELESCOP} ) { my $scope = $FITS_headers->{TELESCOP}; if ( defined( $scope ) ) { $telescope = $scope; $telescope =~ s/ESO-//; $telescope =~ s/-U//g; } } return $telescope; }
1;