File Coverage

blib/lib/Astro/FITS/HdrTrans/LCOSBIG_1m0.pm
Criterion Covered Total %
statement 15 92 16.3
branch 0 28 0.0
condition 0 57 0.0
subroutine 6 15 40.0
pod 9 10 90.0
total 30 202 14.8


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