File Coverage

blib/lib/Astro/FITS/HdrTrans/SCUBA2.pm
Criterion Covered Total %
statement 65 68 95.5
branch 15 26 57.6
condition 2 6 33.3
subroutine 15 15 100.0
pod 8 8 100.0
total 105 123 85.3


line stmt bran cond sub pod time code
1             package Astro::FITS::HdrTrans::SCUBA2;
2              
3             =head1 NAME
4              
5             Astro::FITS::HdrTrans::SCUBA2 - JCMT SCUBA-2 translations
6              
7             =head1 DESCRIPTION
8              
9             Converts information contained in SCUBA-2 FITS headers to and from
10             generic headers. See L<Astro::FITS::HdrTrans> for a list of generic
11             headers.
12              
13             =cut
14              
15 10     10   34654438 use 5.006;
  10         65  
16 10     10   59 use warnings;
  10         20  
  10         423  
17 10     10   56 use strict;
  10         42  
  10         233  
18 10     10   66 use Carp;
  10         22  
  10         842  
19              
20 10     10   87 use base qw/ Astro::FITS::HdrTrans::JCMT /;
  10         42  
  10         1865  
21              
22 10     10   66 use vars qw/ $VERSION /;
  10         26  
  10         7775  
23              
24             $VERSION = "1.63";
25              
26             # For a constant mapping, there is no FITS header, just a generic
27             # header that is constant.
28             my %CONST_MAP = (
29             BACKEND => 'SCUBA-2',
30             DATA_UNITS => 'pW',
31             );
32              
33             # NULL mappings used to override base class implementations
34             my @NULL_MAP = ();
35              
36             # Unit mapping implies that the value propogates directly
37             # to the output with only a keyword name change.
38              
39             my %UNIT_MAP = (
40             FILTER => "FILTER",
41             INSTRUMENT => "INSTRUME",
42             DR_GROUP => "DRGROUP",
43             OBSERVATION_TYPE => "OBS_TYPE",
44             UTDATE => "UTDATE",
45             TELESCOPE => "TELESCOP",
46             AMBIENT_TEMPERATURE => 'ATSTART',
47             );
48              
49             # Values that are derived from the last subheader entry
50             my %ENDOBS_MAP = (
51             AIRMASS_END => 'AMEND',
52             AZIMUTH_END => 'AZEND',
53             ELEVATION_END => 'ELEND',
54             );
55              
56             # Create the translation methods
57             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP, \@NULL_MAP, \%ENDOBS_MAP );
58              
59             =head1 METHODS
60              
61             =over 4
62              
63             =item B<this_instrument>
64              
65             The name of the instrument required to match (case insensitively)
66             against the INSTRUME/INSTRUMENT keyword to allow this class to
67             translate the specified headers. Called by the default
68             C<can_translate> method.
69              
70             $inst = $class->this_instrument();
71              
72             Returns "SCUBA-2".
73              
74             =cut
75              
76             sub this_instrument {
77 21     21 1 54 return "SCUBA-2";
78             }
79              
80             =back
81              
82             =head1 COMPLEX CONVERSIONS
83              
84             These methods are more complicated than a simple mapping. We have to
85             provide both from- and to-FITS conversions All these routines are
86             methods and the to_ routines all take a reference to a hash and return
87             the translated value (a many-to-one mapping) The from_ methods take a
88             reference to a generic hash and return a translated hash (sometimes
89             these are many-to-many)
90              
91             =over 4
92              
93             =item B<to_OBSERVATION_MODE>
94              
95             If Observation type is SCIENCE, return the sample mode, else
96             return the sample mode and observation type. For example, "STARE",
97             "SCAN", "SCAN_POINTING".
98              
99             Do not currently take into account polarimeter or FTS.
100              
101             =cut
102              
103             sub to_OBSERVATION_MODE {
104 3     3 1 8 my $self = shift;
105 3         8 my $FITS_headers = shift;
106              
107 3         4 my $return;
108 3 50 33     12 if ( exists( $FITS_headers->{'SAM_MODE'} ) &&
109             exists( $FITS_headers->{'OBS_TYPE'} ) ) {
110 3         166 my $sam_mode = $FITS_headers->{'SAM_MODE'};
111 3         236 $sam_mode =~ s/\s//g;
112 3         13 my $obs_type = $FITS_headers->{'OBS_TYPE'};
113 3         198 $obs_type =~ s/\s//g;
114              
115 3         9 $return = $sam_mode;
116 3 100       14 if ($obs_type !~ /science/i) {
117 2 50       8 if ($obs_type =~ /(setup)/i) {
118 0         0 $return = lc($1);
119             } else {
120 2         9 $return .= "_$obs_type";
121             }
122             }
123             }
124 3         25 return $return;
125             }
126              
127             =item B<to_SUBSYSTEM_IDKEY>
128              
129             =cut
130              
131             sub to_SUBSYSTEM_IDKEY {
132 3     3 1 22 my $self = shift;
133 3         8 my $FITS_headers = shift;
134              
135             # Try the general headers first
136 3         27 my $general = $self->SUPER::to_SUBSYSTEM_IDKEY( $FITS_headers );
137 3 50       15 return ( defined $general ? $general : "FILTER" );
138             }
139              
140             =item B<to_DR_RECIPE>
141              
142             Fix up recipes that were incorrect in the early years of the
143             observing tool.
144              
145             Converts SASSy survey data to use the SASSy recipe.
146              
147             =cut
148              
149             sub to_DR_RECIPE {
150 3     3 1 11 my $class = shift;
151 3         7 my $FITS_headers = shift;
152 3         13 my $dr = $FITS_headers->{RECIPE};
153 3         196 my $survey = $FITS_headers->{SURVEY};
154              
155 3 50 33     199 if (defined $survey && $survey =~ /sassy/i) {
156 0 0       0 if ($dr !~ /sassy/i) {
157 0         0 $dr = "REDUCE_SASSY";
158             }
159             }
160 3         11 return $dr;
161             }
162              
163             =item B<to_POLARIMETER>
164              
165             Determine if POL-2 is in the beam, based on the INBEAM header.
166              
167             =cut
168              
169             sub to_POLARIMETER {
170 3     3 1 9 my $class = shift;
171 3         7 my $FITS_headers = shift;
172              
173 3         13 my $inbeam = $FITS_headers->{'INBEAM'};
174              
175 3 100       203 return 0 unless defined $inbeam;
176              
177 2 50       16 return ($inbeam =~ /\bpol/i) ? 1 : 0;
178             }
179              
180             =item B<from_POLARIMETER>
181              
182             Attempt to recreate the INBEAM header. Since this also
183             depends on FTS-2, use the _reconstruct_INBEAM method.
184              
185             =cut
186              
187             sub from_POLARIMETER {
188 1     1 1 13 my $class = shift;
189 1         3 my $generic_headers = shift;
190              
191 1         4 return $class->_reconstruct_INBEAM($generic_headers);
192             }
193              
194             =item B<to_FOURIER_TRANSFORM_SPECTROMETER>
195              
196             Determine if FTS-2 is in the beam, based on the INBEAM header.
197              
198             =cut
199              
200             sub to_FOURIER_TRANSFORM_SPECTROMETER {
201 3     3 1 12 my $class = shift;
202 3         6 my $FITS_headers = shift;
203              
204 3         15 my $inbeam = $FITS_headers->{'INBEAM'};
205              
206 3 100       207 return 0 unless defined $inbeam;
207              
208 2 50       15 return ($inbeam =~ /\bfts/i) ? 1 : 0;
209             }
210              
211             =item B<from_FOURIER_TRANSFORM_SPECTROMETER>
212              
213             Attempt to recreate the INBEAM header. Since this also
214             depends on POL-2, use the _reconstruct_INBEAM method.
215              
216             =cut
217              
218             sub from_FOURIER_TRANSFORM_SPECTROMETER {
219 1     1 1 3 my $class = shift;
220 1         2 my $generic_headers = shift;
221              
222 1         4 return $class->_reconstruct_INBEAM($generic_headers);
223             }
224              
225              
226             =item B<_reconstruct_INBEAM>
227              
228             Since the INBEAM header becomes multiple generic headers, we need to look at
229             them all to reconstruct it. In order to work within the confines of the
230             Astro::FITS::HdrTrans::Base::translate_to_FITS method, we need to work
231             on a per-generic header basis. This internal method can then be used for
232             the "from_" method for each of these. It will end up returning the same
233             INBEAM header each time -- the versions generated from different generic
234             headers will overwrite eachother in the Base translate_to_FITS method
235             but that shouldn't be a problem.
236              
237             Note that the INBEAM header may not be reconstructed exactly. For example
238             it will just include the short form "pol" even if it would originally have
239             included specific POL-2 components instead.
240              
241             =cut
242              
243             sub _reconstruct_INBEAM {
244 2     2   4 my $class = shift;
245 2         3 my $generic_headers = shift;
246              
247 2         3 my @components;
248              
249 2 50       16 push @components, 'fts2' if $generic_headers->{'FOURIER_TRANSFORM_SPECTROMETER'};
250              
251 2 50       8 push @components, 'pol' if $generic_headers->{'POLARIMETER'};
252              
253 2         5 my $inbeam = undef;
254              
255 2 50       8 $inbeam = join(' ', @components) if scalar @components;
256              
257 2         20 return (INBEAM => $inbeam);
258             }
259              
260             =back
261              
262             =head1 SEE ALSO
263              
264             C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::Base>
265              
266             =head1 AUTHOR
267              
268             Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt>
269              
270             =head1 COPYRIGHT
271              
272             Copyright (C) 2007-2009,2011,2013 Science & Technology Facilities Council.
273             Copyright (C) 2003-2005 Particle Physics and Astronomy Research Council.
274             All Rights Reserved.
275              
276             This program is free software; you can redistribute it and/or modify it under
277             the terms of the GNU General Public License as published by the Free Software
278             Foundation; either Version 2 of the License, or (at your option) any later
279             version.
280              
281             This program is distributed in the hope that it will be useful,but WITHOUT ANY
282             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
283             PARTICULAR PURPOSE. See the GNU General Public License for more details.
284              
285             You should have received a copy of the GNU General Public License along with
286             this program; if not, write to the Free Software Foundation, Inc., 59 Temple
287             Place, Suite 330, Boston, MA 02111-1307, USA.
288              
289             =cut
290              
291             1;