File Coverage

blib/lib/Astro/FITS/HdrTrans/UIST.pm
Criterion Covered Total %
statement 65 76 85.5
branch 10 18 55.5
condition 3 12 25.0
subroutine 14 14 100.0
pod 8 8 100.0
total 100 128 78.1


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             Astro::FITS::HdrTrans::UIST - UKIRT UIST translations
5              
6             =head1 SYNOPSIS
7              
8             use Astro::FITS::HdrTrans::UIST;
9              
10             %gen = Astro::FITS::HdrTrans::UIST->translate_from_FITS( %hdr );
11              
12             =head1 DESCRIPTION
13              
14             This class provides a generic set of translations that are specific to
15             the UIST camera and spectrometer of the United Kingdom Infrared
16             Telescope.
17              
18             =cut
19              
20             use 5.006;
21 11     11   2473263 use warnings;
  11         33  
22 11     11   59 use strict;
  11         17  
  11         269  
23 11     11   47 use Carp;
  11         26  
  11         209  
24 11     11   43  
  11         18  
  11         787  
25             # Inherit from UKIRTNew
26             use base qw/ Astro::FITS::HdrTrans::UKIRTNew /;
27 11     11   62  
  11         29  
  11         4306  
28             use vars qw/ $VERSION /;
29 11     11   60  
  11         22  
  11         5769  
30             $VERSION = "1.65";
31              
32             # for a constant mapping, there is no FITS header, just a generic
33             # header that is constant
34             my %CONST_MAP = (
35             NSCAN_POSITIONS => 1,
36             SCAN_INCREMENT => 1,
37             );
38              
39             # NULL mappings used to override base class implementations
40             my @NULL_MAP = qw/ DETECTOR_INDEX /;
41              
42             # unit mapping implies that the value propogates directly
43             # to the output with only a keyword name change
44              
45             my %UNIT_MAP = (
46             RA_SCALE => "CDELT2",
47              
48             # UIST specific
49             GRATING_NAME => "GRISM",
50              
51             # Not imaging
52             GRATING_DISPERSION => "DISPERSN",
53             GRATING_NAME => "GRISM",
54             GRATING_ORDER => "GRATORD",
55             GRATING_WAVELENGTH => "CENWAVL",
56             SLIT_ANGLE => "SLIT_PA",
57             SLIT_WIDTH => "SLITWID",
58              
59             # MICHELLE compatible
60             CHOP_ANGLE => "CHPANGLE",
61             CHOP_THROW => "CHPTHROW",
62             DETECTOR_READ_TYPE => "DET_MODE",
63             NUMBER_OF_READS => "NREADS",
64             OBSERVATION_MODE => "INSTMODE",
65             POLARIMETRY => "POLARISE",
66             SLIT_NAME => "SLITNAME",
67              
68             # CGS4 + MICHELLE + WFCAM
69             CONFIGURATION_INDEX => 'CNFINDEX',
70             );
71              
72              
73             # Create the translation methods
74             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP, \@NULL_MAP );
75              
76             =head1 METHODS
77              
78             =over 4
79              
80             =item B<this_instrument>
81              
82             The name of the instrument required to match (case insensitively)
83             against the INSTRUME/INSTRUMENT keyword to allow this class to
84             translate the specified headers. Called by the default
85             C<can_translate> method.
86              
87             $inst = $class->this_instrument();
88              
89             Returns "UIST".
90              
91             =cut
92              
93             return "UIST";
94             }
95 22     22 1 56  
96             =back
97              
98             =head1 COMPLEX CONVERSIONS
99              
100             =over 4
101              
102             =item B<to_DEC_SCALE>
103              
104             Pixel scale in degrees. For imaging, the declination pixel scale is
105             in the CDELT1 header, and for spectroscopy and IFU, it's in CDELT3.
106              
107             =cut
108              
109             my $self = shift;
110             my $FITS_headers = shift;
111             my $return;
112 3     3 1 9 if ( $self->to_OBSERVATION_MODE($FITS_headers) eq 'imaging' ) {
113 3         6 $return = $FITS_headers->{CDELT1};
114 3         5 } else {
115 3 100       76 $return = $FITS_headers->{CDELT3};
116 1         4 }
117             return $return;
118 2         7 }
119              
120 3         149 =item B<from_DEC_SCALE>
121              
122             Generate the PIXLSIZE header.
123              
124             =cut
125              
126             my $self = shift;
127             my $generic_headers = shift;
128              
129             # Can calculate the pixel size...
130 3     3 1 7 my $scale = abs( $generic_headers->{DEC_SCALE} );
131 3         6 $scale *= 3600;
132             my %result = ( PIXLSIZE => $scale );
133              
134 3         22 # and either CDELT1 or CDELT3.
135 3         9 my $ckey = 'CDELT3';
136 3         20 if ( $generic_headers->{OBSERVATION_MODE} eq 'imaging' ) {
137             $ckey = 'CDELT1';
138             }
139 3         8 $result{$ckey} = $generic_headers->{DEC_SCALE};
140 3 100       14 return %result;
141 1         5 }
142              
143 3         10 =item B<to_ROTATION>
144 3         21  
145             ROTATION comprises the rotation matrix with respect to flipped axes,
146             i.e. x corresponds to declination and Y to right ascension. For other
147             UKIRT instruments this was not the case, the rotation being defined
148             in CROTA2. Here the effective rotation is that evaluated from the
149             PC matrix with a 90-degree counter-clockwise rotation for the rotated
150             axes. If there is a PC3_2 header, we assume that we're in spectroscopy
151             mode and use that instead.
152              
153             =cut
154              
155             my $self = shift;
156             my $FITS_headers = shift;
157             my $rotation;
158             if ( exists( $FITS_headers->{PC1_1} ) && exists( $FITS_headers->{PC2_1}) ) {
159             my $pc11;
160 3     3 1 8 my $pc21;
161 3         7 if ( exists ($FITS_headers->{PC3_2} ) && exists( $FITS_headers->{PC2_2} ) ) {
162 3         4  
163 3 100 66     13 # We're in spectroscopy mode.
    50          
164 1         44 $pc11 = $FITS_headers->{PC3_2};
165             $pc21 = $FITS_headers->{PC2_2};
166 1 50 33     4 } else {
167              
168             # We're in imaging mode.
169 0         0 $pc11 = $FITS_headers->{PC1_1};
170 0         0 $pc21 = $FITS_headers->{PC2_1};
171             }
172             my $rad = 57.2957795131;
173             $rotation = $rad * atan2( -$pc21 / $rad, $pc11 / $rad ) + 90.0;
174 1         16  
175 1         99 } elsif ( exists $FITS_headers->{CROTA2} ) {
176             $rotation = $FITS_headers->{CROTA2} + 90.0;
177 1         50 } else {
178 1         13 $rotation = 90.0;
179             }
180             return $rotation;
181 0         0 }
182              
183 2         97  
184             =item B<to_X_REFERENCE_PIXEL>
185 3         9  
186             Use the nominal reference pixel if correctly supplied, failing that
187             take the average of the bounds, and if these headers are also absent,
188             use a default which assumes the full array.
189              
190             =cut
191              
192             my $self = shift;
193             my $FITS_headers = shift;
194             my $xref;
195             if ( exists $FITS_headers->{CRPIX1} ) {
196             $xref = $FITS_headers->{CRPIX1};
197             } elsif ( exists $FITS_headers->{RDOUT_X1} &&
198 3     3 1 8 exists $FITS_headers->{RDOUT_X2} ) {
199 3         8 my $xl = $FITS_headers->{RDOUT_X1};
200 3         7 my $xu = $FITS_headers->{RDOUT_X2};
201 3 50 0     11 $xref = $self->nint( ( $xl + $xu ) / 2 );
    0          
202 3         63 } else {
203             $xref = 480;
204             }
205 0         0 return $xref;
206 0         0 }
207 0         0  
208             =item B<from_X_REFERENCE_PIXEL>
209 0         0  
210             Always returns the value as CRPIX1.
211 3         147  
212             =cut
213              
214             my $self = shift;
215             my $generic_headers = shift;
216             return ( "CRPIX1", $generic_headers->{"X_REFERENCE_PIXEL"} );
217             }
218              
219             =item B<to_Y_REFERENCE_PIXEL>
220              
221 3     3 1 492 Use the nominal reference pixel if correctly supplied, failing that
222 3         12 take the average of the bounds, and if these headers are also absent,
223 3         48 use a default which assumes the full array.
224              
225             =cut
226              
227             my $self = shift;
228             my $FITS_headers = shift;
229             my $yref;
230             if ( exists $FITS_headers->{CRPIX2} ) {
231             $yref = $FITS_headers->{CRPIX2};
232             } elsif ( exists $FITS_headers->{RDOUT_Y1} &&
233             exists $FITS_headers->{RDOUT_Y2} ) {
234             my $yl = $FITS_headers->{RDOUT_Y1};
235 3     3 1 9 my $yu = $FITS_headers->{RDOUT_Y2};
236 3         7 $yref = $self->nint( ( $yl + $yu ) / 2 );
237 3         5 } else {
238 3 50 0     11 $yref = 480;
    0          
239 3         65 }
240             return $yref;
241             }
242 0         0  
243 0         0 =item B<from_Y_REFERENCE_PIXEL>
244 0         0  
245             Always returns the value as CRPIX2.
246 0         0  
247             =cut
248 3         148  
249             my $self = shift;
250             my $generic_headers = shift;
251             return ( "CRPIX2", $generic_headers->{"Y_REFERENCE_PIXEL"} );
252             }
253              
254             =back
255              
256             =head1 SEE ALSO
257              
258 3     3 1 10 C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::UKIRT>.
259 3         5  
260 3         38 =head1 AUTHOR
261              
262             Malcolm J. Currie E<lt>mjc@star.rl.ac.ukE<gt>
263             Brad Cavanagh E<lt>b.cavanagh@jach.hawaii.eduE<gt>,
264             Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>.
265              
266             =head1 COPYRIGHT
267              
268             Copyright (C) 2008 Science and Technology Facilities Council.
269             Copyright (C) 2003-2005 Particle Physics and Astronomy Research Council.
270             All Rights Reserved.
271              
272             This program is free software; you can redistribute it and/or modify it under
273             the terms of the GNU General Public License as published by the Free Software
274             Foundation; either Version 2 of the License, or (at your option) any later
275             version.
276              
277             This program is distributed in the hope that it will be useful,but WITHOUT ANY
278             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
279             PARTICULAR PURPOSE. See the GNU General Public License for more details.
280              
281             You should have received a copy of the GNU General Public License along with
282             this program; if not, write to the Free Software Foundation, Inc., 59 Temple
283             Place, Suite 330, Boston, MA 02111-1307, USA.
284              
285             =cut
286              
287             1;