File Coverage

blib/lib/Astro/FITS/HdrTrans/UIST.pm
Criterion Covered Total %
statement 62 73 84.9
branch 10 18 55.5
condition 3 12 25.0
subroutine 13 13 100.0
pod 8 8 100.0
total 96 124 77.4


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