File Coverage

blib/lib/Astro/FITS/HdrTrans/GEMINI.pm
Criterion Covered Total %
statement 23 137 16.7
branch 0 42 0.0
condition 0 18 0.0
subroutine 8 24 33.3
pod 5 16 31.2
total 36 237 15.1


line stmt bran cond sub pod time code
1             package Astro::FITS::HdrTrans::GEMINI;
2              
3             =head1 NAME
4              
5             Astro::FITS::HdrTrans::GEMINI - Base class for translation of Gemini instruments
6              
7             =head1 SYNOPSIS
8              
9             use Astro::FITS::HdrTrans::GEMINI;
10              
11             =head1 DESCRIPTION
12              
13             This class provides a generic set of translations that are common to
14             instrumentation from the Gemini Observatory. It should not be used
15             directly for translation of instrument FITS headers.
16              
17             =cut
18              
19 12     12   6939688 use 5.006;
  12         58  
20 12     12   88 use warnings;
  12         45  
  12         508  
21 12     12   69 use strict;
  12         47  
  12         352  
22 12     12   71 use Carp;
  12         32  
  12         1099  
23              
24             # Inherit from the Base translation class and not HdrTrans itself
25             # (which is just a class-less wrapper).
26              
27 12     12   96 use base qw/ Astro::FITS::HdrTrans::FITS /;
  12         53  
  12         3375  
28              
29 12     12   93 use Scalar::Util qw/ looks_like_number /;
  12         26  
  12         885  
30 12     12   105 use Astro::FITS::HdrTrans::FITS;
  12         35  
  12         154  
31              
32 12     12   76 use vars qw/ $VERSION /;
  12         27  
  12         17234  
33              
34             $VERSION = "1.63";
35              
36             # in each class we have three sets of data.
37             # - constant mappings
38             # - unit mappings
39             # - complex mappings
40              
41             # for a constant mapping, there is no FITS header, just a generic
42             # header that is constant
43             my %CONST_MAP = (
44             );
45              
46             # unit mapping implies that the value propogates directly
47             # to the output with only a keyword name change
48              
49             my %UNIT_MAP = (
50             AIRMASS_END => "AMEND",
51             AIRMASS_START => "AMSTART",
52             DEC_BASE => "CRVAL2",
53             EXPOSURE_TIME => "EXPTIME",
54             EQUINOX => "EQUINOX",
55             INSTRUMENT => "INSTRUME",
56             NUMBER_OF_EXPOSURES => "NSUBEXP",
57             NUMBER_OF_EXPOSURES => "COADDS",
58             OBJECT => "OBJECT",
59             X_REFERENCE_PIXEL => "CRPIX1",
60             Y_REFERENCE_PIXEL => "CRPIX2"
61             );
62              
63             # Create the translation methods
64             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP );
65              
66             =head1 COMPLEX CONVERSIONS
67              
68             These methods are more complicated than a simple mapping. We have to
69             provide both from- and to-FITS conversions All these routines are
70             methods and the to_ routines all take a reference to a hash and return
71             the translated value (a many-to-one mapping) The from_ methods take a
72             reference to a generic hash and return a translated hash (sometimes
73             these are many-to-many)
74              
75             =over 4
76              
77             =cut
78              
79             # Note use list context as there are multiple CD matrices in
80             # the header. We want scalar context.
81             sub to_DEC_SCALE {
82 0     0 0   my $self = shift;
83 0           my $FITS_headers = shift;
84 0           my $cd11 = $FITS_headers->{"CD1_1"};
85 0           my $cd12 = $FITS_headers->{"CD1_2"};
86 0           my $cd21 = $FITS_headers->{"CD2_1"};
87 0           my $cd22 = $FITS_headers->{"CD2_2"};
88 0           my $sgn;
89 0 0         if ( ( $cd11 * $cd22 - $cd12 * $cd21 ) < 0 ) {
90 0           $sgn = -1;
91             } else {
92 0           $sgn = 1;
93             }
94 0           abs( sqrt( $cd11**2 + $cd21**2 ) );
95             }
96              
97             sub to_DEC_TELESCOPE_OFFSET {
98 0     0 0   my $self = shift;
99 0           my $FITS_headers = shift;
100              
101             # It's simple when there's a header.
102 0           my $offset = $FITS_headers->{ "DECOFFSE" };
103              
104             # Otherwise for older data have to derive an offset from the source
105             # position and the frame position. This does assume that the
106             # reference pixel is unchanged in the group. The other headers
107             # are measured in degrees, but the offsets are in arceseconds.
108 0 0         if ( !defined( $offset ) ) {
109 0           my $decbase = $FITS_headers->{ "CRVAL2" } ;
110 0           my $dec = $FITS_headers->{ "DEC" };
111 0 0 0       if ( defined( $decbase ) && defined( $dec ) ) {
112 0           $offset = 3600.0 * ( $dec - $decbase );
113             } else {
114 0           $offset = 0.0;
115             }
116             }
117 0           return $offset;
118             }
119              
120             sub from_DEC_TELESCOPE_OFFSET {
121 0     0 0   my $self = shift;
122 0           my $generic_headers = shift;
123 0           "DECOFFSE", $generic_headers->{ "DEC_TELESCOPE_OFFSET" };
124             }
125              
126             sub to_FILTER {
127 0     0 0   my $self = shift;
128 0           my $FITS_headers = shift;
129 0           my $filter = "";
130 0           my $filter1 = $FITS_headers->{ "FILTER1" };
131 0           my $filter2 = $FITS_headers->{ "FILTER2" };
132 0           my $filter3 = $FITS_headers->{ "FILTER3" };
133              
134 0 0         if ( $filter1 =~ "open" ) {
135 0           $filter = $filter2;
136             }
137              
138 0 0         if ( $filter2 =~ "open" ) {
139 0           $filter = $filter1;
140             }
141              
142 0 0 0       if ( ( $filter1 =~ "blank" ) ||
      0        
143             ( $filter2 =~ "blank" ) ||
144             ( $filter3 =~ "blank" ) ) {
145 0           $filter = "blank";
146             }
147 0           return $filter;
148             }
149              
150             sub to_OBSERVATION_TYPE {
151 0     0 0   my $self = shift;
152 0           my $FITS_headers = shift;
153 0           my $type = $FITS_headers->{ "OBSTYPE" };
154 0 0 0       if ( $type eq "SCI" || $type eq "OBJECT-OBS" ) {
155 0           $type = "OBJECT";
156             }
157 0           return $type;
158             }
159              
160             sub to_RA_BASE {
161 0     0 0   my $self = shift;
162 0           my $FITS_headers = shift;
163 0           my $ra = 0.0;
164 0 0         if ( exists ( $FITS_headers->{CRVAL1} ) ) {
165 0           $ra = $FITS_headers->{CRVAL1};
166             }
167 0 0         $ra = defined( $ra ) ? $ra: 0.0;
168 0           return $ra;
169             }
170              
171             sub to_RA_SCALE {
172 0     0 0   my $self = shift;
173 0           my $FITS_headers = shift;
174 0           my $cd12 = $FITS_headers->{"CD1_2"};
175 0           my $cd22 = $FITS_headers->{"CD2_2"};
176 0           sqrt( $cd12**2 + $cd22**2 );
177             }
178              
179             sub to_RA_TELESCOPE_OFFSET {
180 0     0 0   my $self = shift;
181 0           my $FITS_headers = shift;
182              
183             # It's simple when there's a header.
184 0           my $offset = $FITS_headers->{ "RAOFFSET" };
185              
186             # Otherwise for older data have to derive an offset from the source
187             # position and the frame position. This does assume that the
188             # reference pixel is unchanged in the group. The other headers
189             # are measured in degrees, but the offsets are in arceseconds.
190 0 0         if ( !defined( $offset ) ) {
191 0           my $rabase = $FITS_headers->{ "CRVAL1" };
192 0           my $ra = $FITS_headers->{ "RA" };
193 0           my $dec = $FITS_headers->{ "DEC" };
194 0 0 0       if ( defined( $rabase ) && defined( $ra ) && defined( $dec ) ) {
      0        
195 0           $offset = 3600* ( $ra - $rabase ) * cosdeg( $dec );
196             } else {
197 0           $offset = 0.0;
198             }
199             }
200 0           return $offset;
201             }
202              
203             sub from_RA_TELESCOPE_OFFSET {
204 0     0 0   my $self = shift;
205 0           my $generic_headers = shift;
206 0           "RAOFFSE", $generic_headers->{ "RA_TELESCOPE_OFFSET" };
207             }
208              
209             sub to_UTSTART {
210 0     0 1   my $self = shift;
211 0           my $FITS_headers = shift;
212 0           my $return;
213 0 0         if (exists $FITS_headers->{'DATE-OBS'}) {
214 0           my $iso;
215 0 0         if ( $FITS_headers->{'DATE-OBS'} =~ /T/ ) {
    0          
    0          
216             # standard format
217 0           $iso = $FITS_headers->{'DATE-OBS'};
218             } elsif ( exists $FITS_headers->{UTSTART} ) {
219 0           $iso = $FITS_headers->{'DATE-OBS'}. "T" . $FITS_headers->{UTSTART};
220             } elsif ( exists $FITS_headers->{UT} ) {
221 0           $iso = $FITS_headers->{'DATE-OBS'}. "T" . $FITS_headers->{UT};
222             }
223 0 0         $return = $self->_parse_iso_date( $iso ) if $iso;
224             }
225 0           return $return;
226             }
227              
228             sub to_UTEND {
229 0     0 1   my $self = shift;
230 0           my $FITS_headers = shift;
231 0           my $return;
232 0 0         if ( exists $FITS_headers->{'DATE-END'} ) {
    0          
233 0           $return = $self->_parse_iso_date( $FITS_headers->{'DATE-END'} );
234             } elsif (exists $FITS_headers->{'DATE-OBS'}) {
235 0           my $iso;
236             my $ut;
237 0 0         if ( $FITS_headers->{'DATE-OBS'} =~ /T/ ) {
238 0           $ut = $FITS_headers->{'DATE-OBS'};
239 0           $ut =~ s/T.*$//;
240             } else {
241 0           $ut = $FITS_headers->{'DATE-OBS'};
242             }
243 0 0         if (exists $FITS_headers->{UTEND}) {
244 0           $iso = $ut. "T" . $FITS_headers->{UTEND};
245             }
246 0 0         $return = $self->_parse_iso_date( $iso ) if $iso;
247             }
248 0           return $return;
249             }
250              
251              
252             sub to_UTDATE {
253 0     0 1   my $self = shift;
254 0           my $FITS_headers = shift;
255 0           return $self->get_UT_date( $FITS_headers );
256             }
257              
258             sub from_UTEND {
259 0     0 1   my $self = shift;
260 0           my $generic_headers = shift;
261 0           my $utend = $generic_headers->{UTEND}->strptime( '%T' );
262 0           return ( "UTEND"=> $utend );
263             }
264              
265             sub from_UTSTART {
266 0     0 1   my $self = shift;
267 0           my $generic_headers = shift;
268 0           my $utstart = $generic_headers->{UTSTART}->strptime('%T');
269 0           return ( "UTSTART"=> $utstart );
270             }
271              
272             sub from_UTDATE {
273 0     0 0   my $self = shift;
274 0           my $generic_headers = shift;
275 0           my $ymd = $generic_headers->{UTDATE};
276 0           my $dobs = substr( $ymd, 0, 4 ) . "-" . substr( $ymd, 4, 2 ) ."-" . substr( $ymd, 6, 2 );
277 0           return ( "DATE-OBS"=>$dobs );
278             }
279              
280             # Supplementary methods for the translations
281             # ------------------------------------------
282              
283             # Returns the UT date in YYYYMMDD format.
284             sub get_UT_date {
285 0     0 0   my $self = shift;
286 0           my $FITS_headers = shift;
287              
288             # This is UT start and time.
289 0           my $dateobs = $FITS_headers->{"DATE-OBS"};
290              
291             # Extract out the data in yyyymmdd format.
292 0           return substr( $dateobs, 0, 4 ) . substr( $dateobs, 5, 2 ) . substr( $dateobs, 8, 2 );
293             }
294              
295             =back
296              
297             =head1 SEE ALSO
298              
299             C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::Base>.
300              
301             =head1 AUTHOR
302              
303             Paul Hirst <p.hirst@jach.hawaii.edu>
304             Malcolm J. Currie <mjc@star.rl.ac.uk>
305             Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>
306              
307             =head1 COPYRIGHT
308              
309             Copyright (C) 2007-2008 Science and Technology Facilities Council.
310             Copyright (C) 2006-2007 Particle Physics and Astronomy Research Council.
311             All Rights Reserved.
312              
313             This program is free software; you can redistribute it and/or modify
314             it under the terms of the GNU General Public License as published by
315             the Free Software Foundation; either Version 2 of the License, or (at
316             your option) any later version.
317              
318             This program is distributed in the hope that it will be useful,but
319             WITHOUT ANY WARRANTY; without even the implied warranty of
320             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
321             General Public License for more details.
322              
323             You should have received a copy of the GNU General Public License
324             along with this program; if not, write to the Free Software
325             Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
326             USA.
327              
328             =cut
329              
330             1;