File Coverage

blib/lib/Astro/FITS/HdrTrans/NIRI.pm
Criterion Covered Total %
statement 18 78 23.0
branch 0 20 0.0
condition n/a
subroutine 7 14 50.0
pod 2 8 25.0
total 27 120 22.5


line stmt bran cond sub pod time code
1             package Astro::FITS::HdrTrans::NIRI;
2              
3             =head1 NAME
4              
5             Astro::FITS::HdrTrans::NIRI - Gemini NIRI translations
6              
7             =head1 SYNOPSIS
8              
9             use Astro::FITS::HdrTrans::NIRI;
10              
11             %gen = Astro::FITS::HdrTrans::NIRI->translate_from_FITS( %hdr );
12              
13             =head1 DESCRIPTION
14              
15             This class provides a generic set of translations that are specific to
16             NIRI on the Gemini Observatory.
17              
18             =cut
19              
20 10     10   6112743 use 5.006;
  10         41  
21 10     10   67 use warnings;
  10         28  
  10         368  
22 10     10   66 use strict;
  10         30  
  10         252  
23 10     10   58 use Carp;
  10         20  
  10         824  
24              
25             # Inherit from GEMINI
26 10     10   74 use base qw/ Astro::FITS::HdrTrans::GEMINI /;
  10         37  
  10         1778  
27              
28 10     10   71 use vars qw/ $VERSION /;
  10         32  
  10         7398  
29              
30             $VERSION = "1.64";
31              
32             # for a constant mapping, there is no FITS header, just a generic
33             # header that is constant
34             my %CONST_MAP = (
35             GAIN => 12.3, # hardwire for now
36             OBSERVATION_MODE => 'imaging',
37             SPEED_GAIN => "NA",
38             STANDARD => 0, # hardwire for now as all objects not a standard.
39             WAVEPLATE_ANGLE => 0, # hardwire for now
40             );
41              
42             # NULL mappings used to override base class implementations
43             my @NULL_MAP = qw/ /;
44              
45             # unit mapping implies that the value propogates directly
46             # to the output with only a keyword name change
47              
48             my %UNIT_MAP = (
49             DETECTOR_READ_TYPE => "MODE",
50             );
51              
52              
53             # Create the translation methods
54             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP, \@NULL_MAP );
55              
56             =head1 METHODS
57              
58             =over 4
59              
60             =item B<this_instrument>
61              
62             The name of the instrument required to match (case insensitively)
63             against the INSTRUME/INSTRUMENT keyword to allow this class to
64             translate the specified headers. Called by the default
65             C<can_translate> method.
66              
67             $inst = $class->this_instrument();
68              
69             Returns "NIRI".
70              
71             =cut
72              
73             sub this_instrument {
74 20     20 1 103 return qr/^NIRI/;
75             }
76              
77             =back
78              
79             =head1 COMPLEX CONVERSIONS
80              
81             =over 4
82              
83             =cut
84              
85             sub to_EXPOSURE_TIME {
86 0     0 0   my $self = shift;
87 0           my $FITS_headers = shift;
88 0           my $et = $FITS_headers->{EXPTIME};
89 0           my $co = $FITS_headers->{COADDS};
90 0           return $et *= $co;
91             }
92              
93             sub to_OBSERVATION_NUMBER {
94 0     0 0   my $self = shift;
95 0           my $FITS_headers = shift;
96 0           my $obsnum = 0;
97 0 0         if ( exists ( $FITS_headers->{FRMNAME} ) ) {
98 0           my $fname = $FITS_headers->{FRMNAME};
99 0           $obsnum = substr( $fname, index( $fname, ":" ) - 4, 4 );
100             }
101 0           return $obsnum;
102             }
103              
104             =item B<to_ROTATION>
105              
106             Converts a linear transformation CD matrix into a single rotation angle.
107             This angle is measured counter-clockwise from the positive x-axis.
108             It uses the SLALIB routine slaDcmpf obtain the rotation angle without
109             assuming perpendicular axes.
110              
111             This routine also copes with errors in the matrix that can generate angles
112             +/-90 degrees instead of near 0 that they should be.
113              
114             =cut
115              
116             sub to_ROTATION {
117 0     0 1   my $self = shift;
118 0           my $FITS_headers = shift;
119 0           my $rotation = 0.0;
120 0 0         if ( exists( $FITS_headers->{CD1_1} ) ) {
121              
122             # Access the CD matrix.
123 0           my $cd11 = $FITS_headers->{"CD1_1"};
124 0           my $cd12 = $FITS_headers->{"CD1_2"};
125 0           my $cd21 = $FITS_headers->{"CD2_1"};
126 0           my $cd22 = $FITS_headers->{"CD2_2"};
127              
128             # Determine the orientation using PAL routine. This has the
129             # advantage of not assuming perpendicular axes (i.e. allows for
130             # shear).
131 0           my ( $xz, $yz, $xs, $ys, $perp );
132 0           my @coeffs = ( 0.0, $cd11, $cd21, 0.0, $cd12, $cd22 );
133 0           eval {
134 0           require Astro::PAL;
135 0           ( $xz, $yz, $xs, $ys, $perp, $rotation ) = Astro::PAL::palDcmpf( \@coeffs );
136             };
137 0 0         if (!defined $perp) {
138 0           croak "NIRI translations require Astro::PAL";
139             }
140              
141             # Convert from radians to degrees.
142 0           my $rtod = 45 / atan2( 1, 1 );
143 0           $rotation *= $rtod;
144              
145             # The actual WCS matrix has errors and sometimes the angle which
146             # should be near 0 degrees, can be out by 90 degrees. So for this
147             # case we hardwire the main rotation and merely apply the small
148             # deviation from the cardinal orientations.
149 0 0         if ( abs( abs( $rotation ) - 90 ) < 2 ) {
150 0           my $delta_rho = 0.0;
151              
152 0           $delta_rho = $rotation - ( 90 * int( $rotation / 90 ) );
153 0 0         $delta_rho -= 90 if ( $delta_rho > 45 );
154 0 0         $delta_rho += 90 if ( $delta_rho < -45 );
155              
156             # Setting to near 180 is a fudge because the CD matrix appears is wrong
157             # occasionally by 90 degrees, judging by the telescope offsets, CTYPEn, and
158             # the support astronomer.
159 0           $rotation = 180.0 + $delta_rho;
160             }
161              
162             }
163 0           return $rotation;
164             }
165              
166             # Shift the bounds to GRID co-ordinates.
167             sub to_X_LOWER_BOUND {
168 0     0 0   my $self = shift;
169 0           my $FITS_headers = shift;
170 0           my $bound = 1;
171 0 0         if ( exists( $FITS_headers->{LOWCOL} ) ) {
172 0           $bound = $self->nint( $FITS_headers->{LOWCOL} + 1 );
173             }
174 0           return $bound;
175             }
176              
177             sub to_Y_LOWER_BOUND {
178 0     0 0   my $self = shift;
179 0           my $FITS_headers = shift;
180 0           my $bound = 1;
181 0 0         if ( exists( $FITS_headers->{LOWROW} ) ) {
182 0           $bound = $self->nint( $FITS_headers->{LOWROW} + 1 );
183             }
184 0           return $bound;
185             }
186              
187             sub to_X_UPPER_BOUND {
188 0     0 0   my $self = shift;
189 0           my $FITS_headers = shift;
190 0           my $bound = 1024;
191 0 0         if ( exists( $FITS_headers->{HICOL} ) ) {
192 0           $bound = $self->nint( $FITS_headers->{HICOL} + 1 );
193             }
194 0           return $bound;
195             }
196              
197             sub to_Y_UPPER_BOUND {
198 0     0 0   my $self = shift;
199 0           my $FITS_headers = shift;
200 0           my $bound = 1024;
201 0 0         if ( exists( $FITS_headers->{HIROW} ) ) {
202 0           $bound = $self->nint( $FITS_headers->{HIROW} + 1 );
203             }
204 0           return $bound;
205             }
206              
207              
208             =back
209              
210             =head1 SEE ALSO
211              
212             C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::UKIRT>.
213              
214             =head1 AUTHOR
215              
216             Malcolm J. Currie E<lt>mjc@star.rl.ac.ukE<gt>
217             Paul Hirst E<lt>p.hirst@jach.hawaii.eduE<gt>,
218             Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>.
219              
220             =head1 COPYRIGHT
221              
222             Copyright (C) 2008 Science and Technology Facilities Council
223             Copyright (C) 1998-2005 Particle Physics and Astronomy Research Council.
224             All Rights Reserved.
225              
226             This program is free software; you can redistribute it and/or modify it under
227             the terms of the GNU General Public License as published by the Free Software
228             Foundation; either Version 2 of the License, or (at your option) any later
229             version.
230              
231             This program is distributed in the hope that it will be useful,but WITHOUT ANY
232             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
233             PARTICULAR PURPOSE. See the GNU General Public License for more details.
234              
235             You should have received a copy of the GNU General Public License along with
236             this program; if not, write to the Free Software Foundation, Inc., 59 Temple
237             Place, Suite 330, Boston, MA 02111-1307, USA.
238              
239             =cut
240              
241             1;