File Coverage

blib/lib/Astro/FITS/HdrTrans/LCOSBIG_CC.pm
Criterion Covered Total %
statement 18 95 18.9
branch 0 28 0.0
condition 0 9 0.0
subroutine 7 16 43.7
pod 9 10 90.0
total 34 158 21.5


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