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