File Coverage

blib/lib/Astro/Catalog/IO/Simple.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Astro::Catalog::IO::Simple;
2              
3             =head1 NAME
4              
5             Astro::Catalog::IO::Simple - Simple Input/Output format
6              
7             =head1 SYNOPSIS
8              
9             $catalog = Astro::Catalog::IO::Simple->_read_catalog( \@lines );
10             \@lines = Astro::Catalog::IO::Simple->_write_catalog( $catalog );
11             Astro::Catalog::IO::Cluster->_default_file();
12              
13             =head1 DESCRIPTION
14              
15             Performs simple IO, reading or writing "id_string hh mm ss.s +dd mm ss.s"
16             formated strings for each Astro::Catalog::Star object in the catalog.
17              
18             =cut
19              
20              
21             # L O A D M O D U L E S --------------------------------------------------
22              
23 1     1   3519237 use 5.006;
  1         18  
  1         72  
24 1     1   13 use strict;
  1         9  
  1         88  
25 1     1   52 use warnings;
  1         2  
  1         101  
26 1     1   16 use warnings::register;
  1         2  
  1         423  
27 1     1   8 use vars qw/ $VERSION /;
  1         2  
  1         110  
28 1     1   6 use Carp;
  1         1  
  1         182  
29              
30 1     1   867 use Astro::Catalog;
  0            
  0            
31             use Astro::Catalog::Star;
32             use Astro::Coords;
33              
34             use base qw/ Astro::Catalog::IO::ASCII /;
35              
36             use Data::Dumper;
37              
38             $VERSION = "4.31";
39              
40              
41             # C O N S T R U C T O R ----------------------------------------------------
42              
43             =head1 REVISION
44              
45             $Id: Simple.pm,v 1.6 2005/03/31 01:24:53 cavanagh Exp $
46              
47             =begin __PRIVATE_METHODS__
48              
49             =head1 Private methods
50              
51             These methods are for internal use only and are called from the
52             Astro::Catalog module. It is not expected that anyone would want to
53             call them from outside that module.
54              
55             =over 4
56              
57             =item B<_read_catalog>
58              
59             Parses a reference to an array containing a simply formatted catalogue
60              
61             $catalog = Astro::Catalog::IO::Simple->_read_catalog( \@lines );
62              
63             =cut
64              
65             sub _read_catalog {
66             croak( 'Usage: _read_catalog( \@lines )' ) unless scalar(@_) >= 1;
67             my $class = shift;
68             my $arg = shift;
69             my @lines = @{$arg};
70              
71             # create an Astro::Catalog object;
72             my $catalog = new Astro::Catalog();
73              
74             # loop through lines
75             MAINLOOP:
76             foreach my $i ( 0 .. $#lines ) {
77              
78             # Skip commented and blank lines
79             next if ($lines[$i] =~ /^\s*[\#\*\%]/);
80             next if ($lines[$i] =~ /^\s*$/);
81              
82             # temporary star object
83             my $star = new Astro::Catalog::Star();
84              
85             # Use a pattern match parser
86             my @match = ( $lines[$i] =~ m/^(.*?) # Target name (non greedy)
87             \s* # optional trailing space
88             (\d{1,2}) # 1 or 2 digits [RA:h] [greedy]
89             [:\s]+ # separator
90             (\d{1,2}) # 1 or 2 digits [RA:m]
91             [:\s]+ # separator
92             (\d{1,2}(?:\.\d*)?) # 1|2 digits opt .fraction [RA:s]
93             # no capture on fraction
94             [:\s]+
95             ([+-]?\s*\d{1,2}) # 1|2 digit [dec:d] inc sign
96             [:\s]+
97             (\d{1,2}) # 1|2 digit [dec:m]
98             [:\s]+
99             (\d{1,2}(?:\.\d*)?) # arcsecond (optional fraction)
100             # no capture on fraction
101             \s*
102             (RB|RJ|AZ|GA|AZEL|J2000|B1950|Galactic)? # coordinate type
103              
104             # most everything else is optional
105             \s*
106             (?:\#\s*(.*))?$ # comment [8]
107             /xi);
108              
109             # Abort if we do not have matches for the first 8 fields
110             # type is optional
111             for (0 ... 6) {
112             next MAINLOOP unless defined $match[$_];
113             }
114              
115             # Read the values
116             my $target = $match[0];
117             my $ra = join(":",@match[1..3]);
118             my $dec = join(":",@match[4..6]);
119             $dec =~ s/\s//g; # remove space between the sign and number
120              
121             # Type defaults to J2000
122             my $type = $match[7] || "J2000";
123             $type = uc($type);
124              
125             # Comment can be undefined
126             my $comment = $match[8];
127              
128             # push the target id
129             $star->id( $target );
130              
131             # push the comment
132             $star->comment( $comment ) if defined $comment;
133              
134             # Allow simple mapping of TYPE from JCMT abbreviations.
135             # This does not hurt things or break simplicity of the format.
136             # The form of the hash depends on the type
137             my %c;
138             if ($type =~ /(RB|RJ|J2000|B1950)/ ) {
139             # Standard RADEC
140             $c{ra} = $ra;
141             $c{dec} = $dec;
142              
143             if ($type =~ /B/) {
144             $c{type} = "B1950";
145             } else {
146             $c{type} = "J2000";
147             }
148              
149             } elsif ($type =~ /^(GA|SUPERGAL)/) {
150              
151             $c{long} = $ra;
152             $c{lat} = $dec;
153             if ($type =~ /S/) {
154             $c{type} = "SUPERGALACTIC";
155             } else {
156             $c{type} = "GALACTIC";
157             }
158              
159             } elsif ($type =~ /^AZ/) {
160              
161             $c{az} = $ra;
162             $c{el} = $dec;
163              
164             } else {
165             croak "Unexpected coordinate type: $type\n";
166             }
167              
168             # Assume J2000 and create an Astro::Coords object
169             my $coords = new Astro::Coords( units => 'sex',
170             name => $star->id(),
171             %c );
172              
173             croak "Error creating coordinate object from $ra / $dec "
174             unless defined $coords;
175              
176             # and push it into the Astro::Catalog::Star object
177             $star->coords( $coords );
178              
179             # push it onto the stack
180             $catalog->pushstar( $star );
181              
182             }
183              
184             $catalog->origin( 'IO::Simple' );
185             return $catalog;
186              
187             }
188              
189             =item B<_write_catalog>
190              
191             Will write the catalogue object to an simple output format
192              
193             \@lines = Astro::Catalog::IO::Simple->_write_catalog( $catalog );
194              
195             where $catalog is an Astro::Catalog object.
196              
197             =cut
198              
199             sub _write_catalog {
200             croak ( 'Usage: _write_catalog( $catalog )') unless scalar(@_) >= 1;
201             my $class = shift;
202             my $catalog = shift;
203              
204             # write header
205             # ------------
206             my @output;
207             my $output_line;
208              
209             push (@output, "# Catalog written automatically by class ". __PACKAGE__ ."\n");
210             push (@output, "# on date " . gmtime . "UT\n" );
211             push (@output, "# Origin of catalogue: ". $catalog->origin ."\n");
212              
213              
214             # write body
215             # ----------
216              
217             # Keep track of star count for unnamed stars
218             my $starcnt = 0;
219              
220             # loop through all the stars in the catalogue
221             foreach my $star ($catalog->stars) {
222              
223             # Extract the information into an array for later formatting
224             my @chunks;
225             my $comment; # in case we need to create a whole comment line
226              
227             # Star ID
228             push(@chunks, (defined $star->id() ? $star->id : $starcnt));
229              
230             # Get the coordinate information
231             my $c = $star->coords;
232              
233             if (defined $c) {
234             my $type = $c->type;
235              
236             if ($type eq 'RADEC') {
237             # Standard J2000
238             push(@chunks, $c->ra(format=>'s'),$c->dec(format=>'s'), "J2000");
239             } elsif ($type eq 'FIXED') {
240             push(@chunks, $c->az(format=>'s'),$c->el(format=>'s'),"AZEL");
241             } else {
242             $comment = "Can not represent star $chunks[0] in catalogue since it is of type $type";
243             }
244              
245             } else {
246             $comment = "Star $chunks[0] has no coordinates.";
247             }
248              
249             # now the line. If we have comment set this is just a comment line
250             if (defined $comment) {
251             push(@output, "# $comment");
252             } else {
253             my $cmt = '';
254             $cmt = " # " .$star->comment()
255             if $star->comment();
256              
257             push(@output, sprintf("%-15s %s %s %s", @chunks) . $cmt);
258              
259             }
260              
261             }
262              
263             # clean up
264             return \@output;
265              
266             }
267              
268             =item B<_default_file>
269              
270             If Astro::Catalog is created with a Format but no Filename or other data
271             source it checked this routine to see whether there is a default file
272             that should be read. This is mainly for Astro::Catalo::IO::JCMT and the
273             JAC, but might prive useful elsewhere.
274              
275             =cut
276              
277             sub _default_file {
278              
279             # returns an empty list
280             return;
281             }
282              
283             =back
284              
285             =end __PRIVATE_METHODS__
286              
287             =head1 FORMAT
288              
289             The Simple format is defined as follows: Any line that looks like
290              
291             ID HH MM SS.SS +/-DD MM SS.SS TYPE # Comment
292              
293             will be matched. A space is allowed between the sign and the
294             declination. The type is optional (as is the comment) and
295             can be one of J2000, B1950, GALACTIC, AZEL or SUPERGALACTIC
296             or the JCMT abbreviations (RJ, RB, GA or AZ). If TYPE is not
297             present J2000 is assumed.
298              
299             =head1 COPYRIGHT
300              
301             Copyright (C) 2001-2003 University of Exeter. All Rights Reserved.
302             Some modificiations Copyright (C) 2003 Particle Physics and Astronomy
303             Research Council. All Rights Reserved.
304              
305             This module was written as part of the eSTAR project in collaboration
306             with the Joint Astronomy Centre (JAC) in Hawaii and is free software;
307             you can redistribute it and/or modify it under the terms of the GNU
308             Public License.
309              
310             =head1 AUTHORS
311              
312             Alasdair Allan Eaa@astro.ex.ac.ukE
313             Tim Jenness Etjenness@cpan.orgE
314              
315             =cut
316              
317             # L A S T O R D E R S ------------------------------------------------------
318              
319             1;