File Coverage

blib/lib/Astro/FITS/HdrTrans/LCOSPECTRAL.pm
Criterion Covered Total %
statement 18 91 19.7
branch 0 24 0.0
condition 0 9 0.0
subroutine 7 16 43.7
pod 9 10 90.0
total 34 150 22.6


line stmt bran cond sub pod time code
1             # -*-perl-*-
2              
3             package Astro::FITS::HdrTrans::LCOSPECTRAL;
4              
5             =head1 NAME
6              
7             Astro::FITS::HdrTrans::LCOSPECTRAL - LCO 2.0m Spectral translations
8              
9             =head1 SYNOPSIS
10              
11             use Astro::FITS::HdrTrans::LCOSPECTRAL;
12              
13             %gen = Astro::FITS::HdrTrans::LCOSPECTRAL->translate_from_FITS( %hdr );
14              
15             =head1 DESCRIPTION
16              
17             This class provides a generic set of translations that are specific to
18             2.0m Spectrals at LCO.
19              
20             =cut
21              
22 10     10   20134668 use 5.006;
  10         48  
23 10     10   65 use warnings;
  10         28  
  10         385  
24 10     10   67 use strict;
  10         29  
  10         246  
25 10     10   60 use Carp;
  10         18  
  10         777  
26              
27             # Inherit from LCO base class.
28 10     10   104 use base qw/ Astro::FITS::HdrTrans::LCO /;
  10         58  
  10         1788  
29              
30 10     10   69 use vars qw/ $VERSION /;
  10         21  
  10         9598  
31              
32             $VERSION = "1.64";
33              
34             # for a constant mapping, there is no FITS header, just a generic
35             # header that is constant
36             my %CONST_MAP = (
37             );
38              
39             # NULL mappings used to override base-class implementations.
40             my @NULL_MAP = qw/ /;
41              
42             my %UNIT_MAP = (
43             );
44              
45              
46             # Create the translation methods
47             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP, \@NULL_MAP );
48              
49             =head1 METHODS
50              
51             =over 4
52              
53             =item B<this_instrument>
54              
55             The name of the instrument required to match (case insensitively)
56             against the INSTRUME/INSTRUMENT keyword to allow this class to
57             translate the specified headers. Called by the default
58             C<can_translate> method.
59              
60             $inst = $class->this_instrument();
61              
62             =cut
63              
64             sub this_instrument {
65 20     20 1 93 return qr/^fs0/i
66              
67             }
68              
69             =back
70              
71             =head1 COMPLEX CONVERSIONS
72              
73             These methods are more complicated than a simple mapping. We have to
74             provide both from- and to-FITS conversions All these routines are
75             methods and the to_ routines all take a reference to a hash and return
76             the translated value (a many-to-one mapping) The from_ methods take a
77             reference to a generic hash and return a translated hash (sometimes
78             these are many-to-many)
79              
80             =over 4
81              
82             =cut
83              
84             =item B<to_DEC_SCALE>
85              
86             Sets the declination scale in arcseconds per pixel. The C<PIXSCALE>
87             is used when it's defined. Otherwise it returns a default value of 0.1520
88             arcsec/pixel, multiplied by C<YBINNING> assuming this is defined
89              
90             =cut
91              
92             sub to_DEC_SCALE {
93 0     0 1   my $self = shift;
94 0           my $FITS_headers = shift;
95 0           my $decscale = 0.1520;
96              
97             # Assumes either x-y scales the same or the y corresponds to
98             # declination.
99 0           my $ccdscale = $self->via_subheader( $FITS_headers, "PIXSCALE" );
100 0 0         if ( defined $ccdscale ) {
101 0           $decscale = $ccdscale;
102             } else {
103 0           my $ybinning = $self->via_subheader( $FITS_headers, "YBINNING" );
104 0 0         if ( defined $ybinning ) {
105 0           $decscale = $decscale * $ybinning;
106             }
107             }
108 0           return $decscale;
109             }
110              
111             =item B<to_DEC_TELESCOPE_OFFSET>
112              
113             Sets the declination telescope offset in arcseconds. It uses the
114             C<CAT-DEC> and C<DEC> keywords to derive the offset, and if either
115             does not exist, it returns a default of 0.0.
116              
117             =cut
118              
119             sub to_DEC_TELESCOPE_OFFSET {
120 0     0 1   my $self = shift;
121 0           my $FITS_headers = shift;
122 0           my $decoffset = 0.0;
123 0 0 0       if ( exists $FITS_headers->{"CAT-DEC"} && exists $FITS_headers->{DEC} ) {
124              
125             # Obtain the reference and telescope declinations positions measured in degrees.
126 0           my $refdec = $self->dms_to_degrees( $FITS_headers->{"CAT-DEC"} );
127 0           my $dec = $self->dms_to_degrees( $FITS_headers->{DEC} );
128              
129             # Find the offsets between the positions in arcseconds on the sky.
130 0           $decoffset = 3600.0 * ( $dec - $refdec );
131             }
132              
133             # The sense is reversed compared with UKIRT, as these measure the
134             # places on the sky, not the motion of the telescope.
135 0           return -1.0 * $decoffset;
136             }
137              
138             =item B<to_RA_SCALE>
139              
140             Sets the RA scale in arcseconds per pixel. The C<PIXSCALE>
141             is used when it's defined. Otherwise it returns a default value of 0.1520
142             arcsec/pixel, multiplied by C<XBINNING> assuming this is defined (1.0 otherwise)
143              
144             =cut
145              
146             sub to_RA_SCALE {
147 0     0 1   my $self = shift;
148 0           my $FITS_headers = shift;
149 0           my $rascale = 0.1520;
150              
151             # Assumes either x-y scales the same or the x corresponds to
152             # ra.
153 0           my $ccdscale = $self->via_subheader( $FITS_headers, "PIXSCALE" );
154 0 0         if ( defined $ccdscale ) {
155 0           $rascale = $ccdscale;
156             } else {
157 0           my $xbinning = $self->via_subheader( $FITS_headers, "XBINNING" );
158 0 0         if ( defined $xbinning ) {
159 0           $rascale = $rascale * $xbinning;
160             }
161             }
162 0           return $rascale;
163             }
164              
165              
166             =item B<to_RA_TELESCOPE_OFFSET>
167              
168             Sets the right-ascension telescope offset in arcseconds. It uses the
169             C<CAT-RA>, C<RA>, C<CAT-DEC> keywords to derive the offset, and if any
170             of these keywords does not exist, it returns a default of 0.0.
171              
172             =cut
173              
174             sub to_RA_TELESCOPE_OFFSET {
175 0     0 1   my $self = shift;
176 0           my $FITS_headers = shift;
177 0           my $raoffset = 0.0;
178              
179 0 0 0       if ( exists $FITS_headers->{"CAT-DEC"} &&
      0        
180             exists $FITS_headers->{"CAT-RA"} && exists $FITS_headers->{RA} ) {
181              
182             # Obtain the reference and telescope sky positions measured in degrees.
183 0           my $refra = $self->hms_to_degrees( $FITS_headers->{"CAT-RA"} );
184 0           my $ra = $self->hms_to_degrees( $FITS_headers->{RA} );
185 0           my $refdec = $self->dms_to_degrees( $FITS_headers->{"CAT-DEC"} );
186              
187             # Find the offset between the positions in arcseconds on the sky.
188 0           $raoffset = 3600.0 * ( $ra - $refra ) * $self->cosdeg( $refdec );
189             }
190              
191             # The sense is reversed compared with UKIRT, as these measure the
192             # place son the sky, not the motion of the telescope.
193 0           return -1.0 * $raoffset;
194             }
195              
196             =item B<to_X_LOWER_BOUND>
197              
198             Returns the lower bound along the X-axis of the area of the detector
199             as a pixel index.
200              
201             =cut
202              
203             sub to_X_LOWER_BOUND {
204 0     0 1   my $self = shift;
205 0           my $FITS_headers = shift;
206 0           my @bounds = $self->getbounds( $FITS_headers );
207 0           return $bounds[ 0 ];
208             }
209              
210             =item B<to_X_UPPER_BOUND>
211              
212             Returns the upper bound along the X-axis of the area of the detector
213             as a pixel index.
214              
215             =cut
216              
217             sub to_X_UPPER_BOUND {
218 0     0 1   my $self = shift;
219 0           my $FITS_headers = shift;
220 0           my @bounds = $self->getbounds( $FITS_headers );
221 0           return $bounds[ 1 ];
222             }
223              
224             =item B<to_Y_LOWER_BOUND>
225              
226             Returns the lower bound along the Y-axis of the area of the detector
227             as a pixel index.
228              
229             =cut
230              
231             sub to_Y_LOWER_BOUND {
232 0     0 1   my $self = shift;
233 0           my $FITS_headers = shift;
234 0           my @bounds = $self->getbounds( $FITS_headers );
235 0           return $bounds[ 2 ];
236             }
237              
238              
239             =item B<to_Y_UPPER_BOUND>
240              
241             Returns the upper bound along the Y-axis of the area of the detector
242             as a pixel index.
243              
244             =cut
245              
246             sub to_Y_UPPER_BOUND {
247 0     0 1   my $self = shift;
248 0           my $FITS_headers = shift;
249 0           my @bounds = $self->getbounds( $FITS_headers );
250 0           return $bounds[ 3 ];
251             }
252              
253             # Supplementary methods for the translations
254             # ------------------------------------------
255              
256             # Obtain the detector bounds from a section in [xl:xu,yl:yu] syntax.
257             # If the TRIMSEC header is absent, use a default which corresponds
258             # to the useful part of the array (minus bias strips).
259             sub getbounds{
260 0     0 0   my $self = shift;
261 0           my $FITS_headers = shift;
262 0           my @bounds = ( 21, 2028, 21, 2028 );
263             # if ( $FITS_headers->{INSTRUME} =~ /^fs0X/i ) {
264             # @bounds = ( 1 , 2048, 1, 2048 );
265             # }
266 0 0         if ( exists $FITS_headers->{CCDSUM} ) {
267 0           my $binning = $FITS_headers->{CCDSUM};
268 0 0         if ( $binning eq '1 1' ) {
269 0           @bounds = ( 41, 4056, 41, 4056 );
270             # if ( $FITS_headers->{INSTRUME} =~ /^fs0X/i ) {
271             # @bounds = ( 1, 4096, 1, 4096 );
272             # }
273             }
274             }
275 0 0         if ( exists $FITS_headers->{TRIMSEC} ) {
276 0           my $section = $FITS_headers->{TRIMSEC};
277 0 0         if ( $section !~ /UNKNOWN/i ) {
278 0           $section =~ s/\[//;
279 0           $section =~ s/\]//;
280 0           $section =~ s/,/:/g;
281 0           my @newbounds = split( /:/, $section );
282 0 0         if (@newbounds == grep { $_ == 0 } @newbounds) {
  0            
283 0           print "ERR: TRIMSEC all 0\n";
284             } else {
285 0 0         if ( $FITS_headers->{INSTRUME} !~ /^fs0X/i ) {
286             # Unless this is (potentially bad) data (which has a bad TRIMSEC), update bounds array
287 0           @bounds = @newbounds;
288             }
289             }
290             }
291             }
292             # print("DBG: Bounds=@bounds\n");
293 0           return @bounds;
294             }
295              
296             =back
297              
298             =head1 SEE ALSO
299              
300             C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::LCO>.
301              
302             =head1 AUTHOR
303              
304             Tim Lister E<lt>tlister@lcogt.netE<gt>
305              
306             =head1 COPYRIGHT
307              
308             =cut
309              
310             1;