File Coverage

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