File Coverage

blib/lib/Astro/FITS/Header/CFITSIO.pm
Criterion Covered Total %
statement 65 75 86.6
branch 18 34 52.9
condition 2 3 66.6
subroutine 8 8 100.0
pod 2 2 100.0
total 95 122 77.8


line stmt bran cond sub pod time code
1             package Astro::FITS::Header::CFITSIO;
2              
3             # ---------------------------------------------------------------------------
4              
5             =head1 NAME
6              
7             Astro::FITS::Header::CFITSIO - Manipulates FITS headers from a FITS file
8              
9             =head1 SYNOPSIS
10              
11             use Astro::FITS::Header::CFITSIO;
12              
13             $header = new Astro::FITS::Header::CFITSIO( Cards => \@array );
14             $header = new Astro::FITS::Header::CFITSIO( File => $file );
15             $header = new Astro::FITS::Header::CFITSIO( fitsID => $ifits );
16              
17             $header->writehdr( File => $file );
18             $header->writehdr( fitsID => $ifits );
19              
20             =head1 DESCRIPTION
21              
22             This module makes use of the L module to read and write
23             directly to a FITS HDU.
24              
25             It stores information about a FITS header block in an object. Takes an
26             hash as an argument, with either an array reference pointing to an
27             array of FITS header cards, or a filename, or (alternatively) and FITS
28             identifier.
29              
30             =cut
31              
32             # L O A D M O D U L E S --------------------------------------------------
33              
34 2     2   1233296 use strict;
  2         7  
  2         139  
35 2     2   13 use vars qw/ $VERSION /;
  2         15  
  2         248  
36              
37 2     2   1191 use Astro::FITS::Header::Item;
  2         5  
  2         80  
38 2     2   34 use base qw/ Astro::FITS::Header /;
  2         5  
  2         1460  
39              
40 2     2   726 use Astro::FITS::CFITSIO qw / :longnames :constants /;
  2         10588  
  2         7657  
41 2     2   17 use Carp;
  2         4  
  2         1493  
42              
43             $VERSION = '3.09';
44              
45             # C O N S T R U C T O R ----------------------------------------------------
46              
47             =head1 REVISION
48              
49             $Id$
50              
51             =head1 METHODS
52              
53             =over 4
54              
55             =item B
56              
57             Reads a FITS header from a FITS HDU
58              
59             $header->configure( Cards => \@cards );
60             $header->configure( fitsID => $ifits );
61             $header->configure( File => $file );
62             $header->configure( File => $file, ReadOnly => $bool );
63              
64             Accepts an FITS identifier or a filename. If both fitsID and File keys
65             exist, fitsID key takes priority.
66              
67             If C is specified, the file is normally opened in ReadWrite
68             mode. The C argument takes a boolean value which determines
69             whether the file is opened ReadOnly.
70              
71             =cut
72              
73             sub configure {
74 3     3 1 10 my $self = shift;
75              
76 3         10 my %args = ( ReadOnly => 0, @_ );
77              
78             # itialise the inherited status to OK.
79 3         4 my $status = 0;
80 3         6 my $ifits;
81              
82             return $self->SUPER::configure(%args)
83 3 100 66     15 if exists $args{Cards} or exists $args{Items};
84              
85             # read the args hash
86 2 50       7 if (exists $args{fitsID}) {
    50          
87 0         0 $ifits = $args{fitsID};
88             } elsif (exists $args{File}) {
89             $ifits = Astro::FITS::CFITSIO::open_file( $args{File},
90 2 50       10 $args{ReadOnly} ? Astro::FITS::CFITSIO::READONLY() :
91             Astro::FITS::CFITSIO::READWRITE(),
92             $status );
93             } else {
94 0         0 croak("Arguement hash does not contain fitsID, File or Cards");
95             }
96              
97             # file sucessfully opened?
98 2 50       1913 if( $status == 0 ) {
99              
100             # Get size of FITS header
101 2         4 my ($numkeys, $morekeys);
102 2         13 $ifits->get_hdrspace( $numkeys, $morekeys, $status);
103              
104             # Set the FITS array to empty
105 2         3 my @fits = ();
106              
107             # read the cards. Note that CFITSIO doesn't include the END card
108             # in it's counting
109 2         7 for my $i (1 .. $numkeys) {
110 65         228 $ifits->read_record($i, my $card, $status);
111 65         129 push(@fits, $card);
112             }
113              
114             # add an END card. previously this was extracted from CFITSIO
115             # by reading an extra card. however, the header may not have
116             # been completed by CFITSIO, so that extra card might not exist.
117 2         10 push @fits, Astro::FITS::Header::Item->new( Keyword => 'END')->card;
118              
119 2 50       28 if ($status == 0) {
120             # Parse the FITS array
121 2         10 $self->SUPER::configure( Cards => \@fits );
122             } else {
123             # Report bad exit status
124 0         0 croak("Error $status reading FITS array");
125             }
126              
127             # Look at the name of the file as it was passed in. If there is a FITS
128             # extension specified, then this is a single fits image that you want
129             # read. If there isn't one specified, then we should read each of the
130             # extensions that exist in the file, if in fact there are any.
131              
132 2 50       6 if ( exists $args{File} )
133             {
134 2         3 my $ext;
135 2         27 fits_parse_extnum($args{File},$ext,$status);
136 2         5 my @subfrms = ();
137 2 50       6 if ($ext == -99) {
138 2         3 my $nhdus;
139 2         11 $ifits->get_num_hdus($nhdus,$status);
140 2         6 foreach my $ihdu (1 .. $nhdus-1) {
141 0         0 my $subfr = sprintf("%s[%d]",$args{File},$ihdu);
142 0         0 my $sself = $self->new(File=>$subfr, ReadOnly => $args{ReadOnly});
143 0         0 push @subfrms,$sself;
144             }
145             }
146 2         8 $self->subhdrs(@subfrms);
147             }
148             }
149              
150             # clean up
151 2 50       5 if ( $status != 0 ) {
152 0         0 croak("Error $status opening FITS file");
153             }
154              
155             # close file, but only if we opened it
156             $ifits->close_file( $status )
157 2 50       120 unless exists $args{fitsID};
158              
159 2         17 return;
160              
161             }
162              
163             # W R I T E H D R -----------------------------------------------------------
164              
165             =item B
166              
167             Write a FITS header to a FITS file
168              
169             $header->writehdr( File => $file );
170             $header->writehdr( fitsID => $ifits );
171              
172             Its accepts a FITS identifier or a filename. If both fitsID and File keys
173             exist, fitsID key takes priority.
174              
175             Throws an exception (croaks) on error.
176              
177             =cut
178              
179             sub writehdr {
180 1     1 1 6 my $self = shift;
181 1         3 my %args = @_;
182              
183 1 50       3 return $self->SUPER::configure(%args) if exists $args{Cards};
184              
185             # itialise the inherited status to OK.
186 1         2 my $status = 0;
187 1         1 my $ifits;
188              
189             # read the args hash
190 1 50       3 if (exists $args{fitsID}) {
    50          
191 0         0 $ifits = $args{fitsID};
192             } elsif (exists $args{File}) {
193             $ifits = Astro::FITS::CFITSIO::open_file( $args{File},
194 1         3 Astro::FITS::CFITSIO::READWRITE(), $status );
195             } else {
196 0         0 croak("Argument hash does not contain fitsID, File or Cards");
197             }
198              
199             # file sucessfully opened?
200 1 50       259 if( $status == 0 ) {
201              
202             # Get size of FITS header
203 1         3 my ($numkeys, $morekeys);
204 1         4 $ifits->get_hdrspace( $numkeys, $morekeys, $status);
205              
206             # delete the cards in the current header. as cards are deleted the
207             # ones below it are shifted up (according to the CFITSIO docs).
208             # we thus delete from the bottom up to avoid all of that work.
209 1         41 $ifits->delete_record( $numkeys--, $status )
210             while $numkeys;
211              
212             # write the new cards, not including END card if it exists
213 1         10 my @cards = $self->cards;
214 1 50       7 if ( defined (my $end_card = $self->index('END')) )
215 1         2 { splice( @cards, $end_card, 1 ) }
216 1         134 $ifits->write_record($_, $status ) foreach @cards;
217              
218             }
219              
220             # clean up
221 1 50       5 if ( $status != 0 ) {
222 0         0 croak("Error $status opening FITS file");
223             }
224              
225             # close file, but only if we opened it
226             $ifits->close_file( $status )
227 1 50       188 unless exists $args{fitsID};
228              
229 1         10 return;
230              
231             }
232              
233             # T I M E A T T H E B A R --------------------------------------------
234              
235             =back
236              
237             =head1 NOTES
238              
239             This module requires Pete Ratzlaff's L module,
240             and William Pence's C subroutine library (v2.1 or greater).
241              
242             =head1 SEE ALSO
243              
244             L, L, L, L
245              
246             =head1 AUTHORS
247              
248             Alasdair Allan Eaa@astro.ex.ac.ukE,
249             Jim Lewis Ejrl@ast.cam.ac.ukE,
250             Diab Jerius.
251              
252             =head1 COPYRIGHT
253              
254             Copyright (C) 2007-2009 Science & Technology Facilities Council.
255             Copyright (C) 2001-2006 Particle Physics and Astronomy Research Council.
256             All Rights Reserved.
257              
258             This program is free software; you can redistribute it and/or modify it under
259             the terms of the GNU General Public License as published by the Free Software
260             Foundation; either version 3 of the License, or (at your option) any later
261             version.
262              
263             This program is distributed in the hope that it will be useful,but WITHOUT ANY
264             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
265             PARTICULAR PURPOSE. See the GNU General Public License for more details.
266              
267             You should have received a copy of the GNU General Public License along with
268             this program; if not, write to the Free Software Foundation, Inc., 59 Temple
269             Place,Suite 330, Boston, MA 02111-1307, USA
270              
271             =cut
272              
273             # L A S T O R D E R S ------------------------------------------------------
274              
275             1;