File Coverage

blib/lib/Astro/FITS/HdrTrans/JAC.pm
Criterion Covered Total %
statement 51 69 73.9
branch 6 18 33.3
condition 3 12 25.0
subroutine 12 13 92.3
pod 2 2 100.0
total 74 114 64.9


line stmt bran cond sub pod time code
1             package Astro::FITS::HdrTrans::JAC;
2              
3             =head1 NAME
4              
5             Astro::FITS::HdrTrans::JAC - Base class for translation of Joint
6             Astronomy Centre instruments.
7              
8             =head1 SYNOPSIS
9              
10             use Astro::FITS::HdrTrans::JAC;
11              
12             =head1 DESCRIPTION
13              
14             This class provides a generic set of translations that are common to
15             instrumentation from the Joint Astronomy Centre. It should not be used
16             directly for translation of instrument FITS headers.
17              
18             =cut
19              
20 27     27   19289993 use 5.006;
  27         266  
21 27     27   179 use warnings;
  27         102  
  27         950  
22 27     27   160 use strict;
  27         96  
  27         770  
23 27     27   203 use Carp;
  27         142  
  27         2052  
24              
25 27     27   17115 use DateTime;
  27         7782094  
  27         1157  
26 27     27   283 use DateTime::TimeZone;
  27         109  
  27         1711  
27             # Cache UTC definition
28             our $UTC = DateTime::TimeZone->new( name => 'UTC' );
29              
30             # Inherit from the Base translation class and not HdrTrans itself
31             # (which is just a class-less wrapper).
32              
33 27     27   197 use base qw/ Astro::FITS::HdrTrans::FITS /;
  27         74  
  27         16588  
34              
35 27     27   222 use vars qw/ $VERSION /;
  27         56  
  27         24276  
36              
37             $VERSION = "1.63";
38              
39             # in each class we have three sets of data.
40             # - constant mappings
41             # - unit mappings
42             # - complex mappings
43              
44             # For a constant mapping, there is no FITS header, just a generic
45             # header that is constant.
46             my %CONST_MAP = (
47             );
48              
49             # Unit mapping implies that the value propagates directly
50             # to the output with only a keyword name change.
51              
52             my %UNIT_MAP = (
53             MSBID => 'MSBID',
54             MSB_TRANSACTION_ID => 'MSBTID',
55             SHIFT_TYPE => "OPER_SFT",
56             );
57              
58             # Create the translation methods.
59             __PACKAGE__->_generate_lookup_methods( \%CONST_MAP, \%UNIT_MAP );
60              
61             =head1 METHODS
62              
63             =over 4
64              
65             =item B<translate_from_FITS>
66              
67             This routine overrides the base class implementation to enable the
68             caches to be cleared and for the location of the DATE-OBS/DATE-END field to
69             be found so that base class implementations will work correctly.
70              
71             This means that some conversion methods (in particular those using time in
72             a base class) may not work properly outside the context of a full translation
73             unless they have been subclassed locally.
74              
75             =cut
76              
77             sub translate_from_FITS {
78 19     19 1 46 my $class = shift;
79 19         39 my $headers = shift;
80              
81             # sort out DATE-OBS and DATE-END
82 19         193 $class->_fix_dates( $headers );
83              
84             # Go to the base class
85 19         134 return $class->SUPER::translate_from_FITS( $headers, @_ );
86             }
87              
88             =back
89              
90             =head1 COMPLEX CONVERSIONS
91              
92             These methods are more complicated than a simple mapping. We have to
93             provide both from- and to-FITS conversions All these routines are
94             methods and the to_ routines all take a reference to a hash and return
95             the translated value (a many-to-one mapping). The from_ methods take
96             a reference to a generic hash and return a translated hash (sometimes
97             these are many-to-many).
98              
99             =over 4
100              
101             =item B<to_OBSERVATION_ID>
102              
103             Converts the C<OBSID> header directly into the C<OBSERVATION_ID>
104             generic header, or if that header does not exist, converts the
105             C<INSTRUME>, C<RUNNR>, and C<DATE-OBS> headers into C<OBSERVATION_ID>.
106              
107             The form of the observation ID string is documented in
108             JSA/ANA/001 (http://docs.jach.hawaii.edu/JCMT/JSA/ANA/001/jsa_ana_001.pdf).
109              
110             =cut
111              
112             sub to_OBSERVATION_ID {
113 18     18 1 55 my $self = shift;
114 18         38 my $FITS_headers = shift;
115              
116 18         55 my $return;
117 18 100 66     82 if ( exists( $FITS_headers->{'OBSID'} ) &&
118             defined( $FITS_headers->{'OBSID'} ) ) {
119 3         287 $return = $FITS_headers->{'OBSID'};
120             } else {
121              
122 15         464 my $instrume = lc( $self->to_INSTRUMENT( $FITS_headers ) );
123 15         389 my $obsnum = $self->to_OBSERVATION_NUMBER( $FITS_headers );
124 15         137 my $dateobs = $self->to_UTSTART( $FITS_headers );
125              
126 15         32 my $datetime;
127 15 50 33     85 if ( defined $dateobs && defined $obsnum ) {
128 15         87 $datetime = $dateobs->datetime;
129 15         1056 $datetime =~ s/-//g;
130 15         52 $datetime =~ s/://g;
131              
132 15         95 $return = join '_', $instrume, $obsnum, $datetime;
133             }
134             }
135              
136 18         241 return $return;
137              
138             }
139              
140             =item B<_fix_dates>
141              
142             Sort out DATE-OBS and DATE-END in cases where they are not available directly.
143             This is mainly an issue with database retrievals where the date format is not
144             FITS compliant.
145              
146             Astro::FITS::HdrTrans::JAC->_fix_dates( \%headers );
147              
148             =cut
149              
150             sub _fix_dates {
151 45     45   124 my ( $class, $FITS_headers ) = @_;
152              
153             # DATE-OBS can be from DATE_OBS
154             # For compatability with Sybase database, also accept LONGDATEOBS LONGDATE
155 45         171 __PACKAGE__->_try_dates( $FITS_headers, 'DATE-OBS', qw/ DATE_OBS LONGDATEOBS LONGDATE / );
156              
157             # DATE-END can be from DATE_END
158             # For compatability with Sybase database, also accept LONGDATEEND
159 45         140 __PACKAGE__->_try_dates( $FITS_headers, 'DATE-END', qw/ DATE_END LONGDATEEND / );
160              
161 45         71 return;
162             }
163              
164             # helper routine for _fix_dates
165             sub _try_dates {
166 90     90   220 my ( $class, $FITS_headers, $outkey, @tests ) = @_;
167              
168 90 100       255 if (!exists $FITS_headers->{$outkey}) {
169 16         153 for my $key (@tests) {
170 40 50       261 if ( exists( $FITS_headers->{$key} ) ) {
171 0         0 my $date = _convert_mysql_date( $FITS_headers->{$key} );
172 0 0       0 if( defined( $date ) ) {
173 0         0 $FITS_headers->{$outkey} = $date->datetime;
174 0         0 last;
175             }
176             }
177             }
178             }
179 90         1808 return;
180             }
181              
182             # Convert MySQL date string to DateTime object.
183             # For compatability, also accepts Sybase date strings.
184             sub _convert_mysql_date {
185 0     0     my $date = shift;
186              
187 0           $date =~ s/\s*$//;
188              
189 0 0         if ($date =~ /\s*(\d\d\d\d)-(\d\d)-(\d\d)\s+(\d{1,2}):(\d\d):(\d\d)/) {
    0          
190              
191 0           my $return = DateTime->new( year => $1,
192             month => $2,
193             day => $3,
194             hour => $4,
195             minute => $5,
196             second => $6,
197             time_zone => $UTC,
198             );
199 0           return $return;
200              
201             } elsif ($date =~ /\s*(\w+)\s+(\d{1,2})\s+(\d{4})\s+(\d{1,2}):(\d\d):(\d\d)(?::\d\d\d)?(AM|PM)/) {
202              
203 0           my $hour = $4;
204 0 0 0       if (uc($7) eq 'AM' && $hour == 12) {
    0 0        
205 0           $hour = 0;
206             } elsif ( uc($7) eq 'PM' && $hour < 12 ) {
207 0           $hour += 12;
208             }
209              
210 0           my %mon_lookup = ( 'Jan' => 1,
211             'Feb' => 2,
212             'Mar' => 3,
213             'Apr' => 4,
214             'May' => 5,
215             'Jun' => 6,
216             'Jul' => 7,
217             'Aug' => 8,
218             'Sep' => 9,
219             'Oct' => 10,
220             'Nov' => 11,
221             'Dec' => 12 );
222 0           my $month = $mon_lookup{$1};
223              
224 0           my $return = DateTime->new( year => $3,
225             month => $month,
226             day => $2,
227             hour => $hour,
228             minute => $5,
229             second => $6,
230             time_zone => $UTC,
231             );
232 0           return $return;
233              
234             } else {
235 0           return undef;
236             }
237             }
238              
239             =back
240              
241             =head1 SEE ALSO
242              
243             C<Astro::FITS::HdrTrans>, C<Astro::FITS::HdrTrans::Base>.
244              
245             =head1 AUTHOR
246              
247             Brad Cavanagh E<lt>b.cavanagh@jach.hawaii.eduE<gt>.
248              
249             =head1 COPYRIGHT
250              
251             Copyright (C) 2007 Science and Technology Facilities Council.
252             Copyright (C) 2006 Particle Physics and Astronomy Research Council.
253             All Rights Reserved.
254              
255             This program is free software; you can redistribute it and/or modify
256             it under the terms of the GNU General Public License as published by
257             the Free Software Foundation; either Version 2 of the License, or (at
258             your option) any later version.
259              
260             This program is distributed in the hope that it will be useful,but
261             WITHOUT ANY WARRANTY; without even the implied warranty of
262             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
263             General Public License for more details.
264              
265             You should have received a copy of the GNU General Public License
266             along with this program; if not, write to the Free Software
267             Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
268             USA.
269              
270             =cut
271              
272             1;