File Coverage

blib/lib/Astro/Catalog/IO/Cluster.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Astro::Catalog::IO::Cluster;
2              
3             =head1 NAME
4              
5             Astro::Catalog::IO::Cluster - Input/Output in ARK Cluster format
6              
7             =head1 SYNOPSIS
8              
9             $catalog = Astro::Catalog::IO::Cluster->_read_catalog( \@lines );
10             \@lines = Astro::Catalog::IO::Cluster->_write_catalog( $catalog, %opts );
11             Astro::Catalog::IO::Cluster->_default_file();
12              
13             =head1 DESCRIPTION
14              
15             Performs ARK Cluster specific tasks for input/output of ARK Cluster format
16             files.
17              
18             =cut
19              
20              
21             # L O A D M O D U L E S --------------------------------------------------
22              
23 1     1   1942910 use 5.006;
  1         5  
  1         91  
24 1     1   6 use strict;
  1         2  
  1         77  
25 1     1   1408 use warnings;
  1         3  
  1         119  
26 1     1   12 use warnings::register;
  1         2  
  1         378  
27 1     1   7 use vars qw/ $VERSION /;
  1         3  
  1         1229  
28 1     1   6 use Scalar::Util;
  1         2  
  1         271  
29 1     1   5 use Carp;
  1         2  
  1         120  
30              
31 1     1   2115 use Astro::Catalog;
  0            
  0            
32             use Astro::Catalog::Star;
33             use Astro::Coords;
34              
35             use Astro::FluxColor;
36             use Astro::Flux;
37             use Astro::Fluxes;
38              
39             use Number::Uncertainty;
40              
41             use base qw/ Astro::Catalog::IO::ASCII /;
42              
43             use Data::Dumper;
44              
45             $VERSION = "4.31";
46              
47              
48             # C O N S T R U C T O R ----------------------------------------------------
49              
50             =head1 REVISION
51              
52             $Id: Cluster.pm,v 1.19 2006/01/18 01:29:33 cavanagh Exp $
53              
54             =begin __PRIVATE_METHODS__
55              
56             =head1 Private methods
57              
58             These methods are for internal use only and are called from the
59             Astro::Catalog module. Its not expected that anyone would want to
60             call them from utside that module.
61              
62             =over 4
63              
64             =item B<_read_cluster>
65              
66             Parses a reference to an array containing an ARK Cluster format
67             catalog, returns an Astro::Catalog object.
68              
69             $catalog = Astro::Catalog::IO::Cluster->_read_catalog( \@lines );
70              
71             =cut
72              
73             sub _read_catalog {
74             croak( 'Usage: _read_catalog( \@lines )' ) unless scalar(@_) >= 1;
75             my $class = shift;
76             my $arg = shift;
77             my @lines = @{$arg};
78              
79             # create am Astro::Catalog object;
80             my $catalog = new Astro::Catalog();
81              
82             # loop through lines
83             foreach my $i ( 3 .. $#lines ) {
84              
85             # remove leading spaces
86             $lines[$i] =~ s/^\s+//;
87              
88             # split each line
89             my @separated = split( /\s+/, $lines[$i] );
90              
91             # debugging (leave in)
92             #print "$i # id $separated[1]\n";
93             #foreach my $thing ( 0 .. $#separated ) {
94             # print " $thing # $separated[$thing] #\n";
95             #}
96              
97             # temporary star object
98             my $star = new Astro::Catalog::Item();
99              
100             # field
101             $star->field( $separated[0] );
102              
103             # id
104             $star->id( $separated[1] );
105              
106             # ra
107             my $objra = "$separated[2] $separated[3] $separated[4]";
108              
109             # dec
110             my $objdec = "$separated[5] $separated[6] $separated[7]";
111              
112             # Assume J2000 and create an Astro::Coords object
113             my $coords = new Astro::Coords( type => 'J2000',
114             units => 'sex',
115             ra => $objra,
116             dec => $objdec,
117             name => $star->id() );
118              
119             # and push it into the Astro::Catalog::Star object
120             $star->coords( $coords );
121              
122             # x & y
123             if( $separated[8] ne '0.000' ) {
124             $star->x( $separated[8] );
125             }
126             if( $separated[9] ne '0.000' ) {
127             $star->y( $separated[9] );
128             }
129              
130             # number of magnitudes and colours
131             $lines[1] =~ s/^\s+//;
132             my @colours = split( /\s+/, $lines[1] );
133              
134             my @quality;
135             my ( @colors, @fluxes );
136             foreach my $j ( 0 .. $#colours ) {
137              
138             # colours have minus signs
139             if( lc($colours[$j]) =~ "-" ) {
140              
141             # build a colour object and push it into the @colors array
142             my @filters = split "-", $colours[$j];
143             my $color = new Astro::FluxColor(
144             upper => new Astro::WaveBand( Filter => $filters[0] ),
145             lower => new Astro::WaveBand( Filter => $filters[1] ),
146             quantity => new Number::Uncertainty(
147             Value => $separated[3*$j+10],
148             Error => $separated[3*$j+11] ) );
149             push @colors, $color;
150              
151             # quality flags
152             $quality[$j] = $separated[3*$j+12];
153              
154              
155             } else {
156              
157              
158              
159             my $mag = new Astro::Flux(
160             new Number::Uncertainty(
161             Value => $separated[3*$j+10],
162             Error => $separated[3*$j+11] ),
163             'mag', $colours[$j] );
164             push @fluxes, $mag;
165              
166              
167             # quality flags
168             $quality[$j] = $separated[3*$j+12];
169              
170             # increment counter
171             $j = $j + 2;
172              
173             }
174              
175             }
176              
177             $star->fluxes( new Astro::Fluxes( @fluxes, @colors ) );
178              
179             # set default "good" quality
180             $star->quality( 0 );
181              
182             # check and set quality flag
183             foreach my $k( 0 .. $#colours ) {
184              
185             # if quality not good then set bad flag
186             if ( Scalar::Util::looks_like_number($quality[$k]) ) {
187             if( defined $quality[$k] && $quality[$k] != 0 ) {
188             $star->quality( 1 );
189             }
190             } else {
191             if( defined $quality[$k] && $quality[$k] ne "OO") {
192             $star->quality( 1 );
193             }
194             }
195             }
196              
197             # push it onto the stack
198             $catalog->pushstar( $star );
199              
200             }
201              
202             $catalog->origin( 'IO::Cluster' );
203             return $catalog;
204              
205             }
206              
207             =item B<_write_catalog>
208              
209             Will write the catalogue object to an standard ARK Cluster format file
210              
211             \@lines = Astro::Catalog::IO::Cluster->_write_catalog( $catalog, %opts );
212              
213             where $catalog is an Astro::Catalog object and allowable options are
214             currently C and C, e.g.
215              
216             \@lines = Astro::Catalog::IO::Cluster->_write_catalog(
217             $catalog, Magnitudes => \@mags, Colours => \@colours );
218              
219             where magnitudes and colours passed in the array will be used in the catalog
220             despite the presence of other
221              
222             my @mags = ( 'R' );
223             my @colour = ( 'B-R', 'B-V' );
224             \@lines = Astro::Catalog::IO::Cluster->write_catalog(
225             $catalog, Magnitudes => \@mags, Colours => \@colours );
226              
227             will write a catalogue with R, B-R and B-V.
228              
229             =cut
230              
231             sub _write_catalog {
232             croak ( 'Usage: _write_catalog( $catalog, [%opts] ') unless scalar(@_) >= 1;
233             my $class = shift;
234             my $catalog = shift;
235              
236             # real list of filters and colours in the catalogue
237             my @filters = $catalog->starbyindex(0)->what_filters();
238             my @colours = $catalog->starbyindex(0)->what_colours();
239              
240             # number of stars in catalogue
241             my $number = $catalog->sizeof();
242              
243             # number of filters & colours
244             my $num_mags = $catalog->starbyindex(0)->what_filters();
245             my $num_cols = $catalog->starbyindex(0)->what_colours();
246              
247             # reference to the $self->{STARS} array in Astro::Catalog
248             my $stars = $catalog->stars();
249              
250             # figure out what magnitudes and colours we're going to output
251             my ( $mags, $cols );
252             if ( @_ ) {
253             my %args = @_;
254              
255             if( defined $args{colours} ) {
256             $cols = $args{colours};
257             }
258             if( defined $args{magnitudes} ) {
259             $mags = $args{magnitudes};
260             }
261              
262             } else {
263             $mags = \@filters;
264             $cols = \@colours;
265             }
266              
267             # define varaibles for output filters and colours
268             my ( @out_mags, @out_cols );
269              
270             # Filter the output magnitudes and colours for uniqueness.
271              
272             # if we want fewer magnitudes than we have in the object
273             # to be written to the cluster file
274             my %seen_mag;
275             foreach my $m ( 0 .. $#{$mags} ) {
276             next if $seen_mag{$mags->[$m]} ++;
277             foreach my $n ( 0 .. $num_mags-1 ) {
278             if ( ${$mags}[$m] eq $filters[$n] ) {
279             push( @out_mags, ${$mags}[$m] );
280             last;
281             }
282             }
283             }
284              
285             # same for colours
286             my %seen_col;
287             foreach my $k ( 0 .. $#{$cols} ) {
288             next if $seen_col{$cols->[$k]} ++;
289             foreach my $l ( 0 .. $num_cols-1 ) {
290             if ( ${$cols}[$k] eq $colours[$l] ) {
291             push( @out_cols, ${$cols}[$k] );
292             last;
293             }
294             }
295             }
296              
297             # write header
298             # ------------
299             my @output;
300             my $output_line;
301              
302             # check to see if we're outputing all the filters and colours
303             my $total = scalar(@out_mags) + scalar(@out_cols);
304              
305             push( @output, "$total colours were created" );
306             push( @output, "@out_mags @out_cols" );
307              
308             # wierd and odd
309             $output_line =
310             "Origin: " . $catalog->origin() . " " if defined $catalog->origin();
311              
312             if( defined $catalog->get_ra() && defined $catalog->get_dec() ) {
313             $output_line = $output_line .
314             " Field Centre: RA " . $catalog->get_ra() .
315             ", Dec " . $catalog->get_dec() . " ";
316             }
317              
318             $output_line = $output_line .
319             " Catalogue Radius: " . $catalog->get_radius() .
320             " arcmin" if defined $catalog->get_radius();
321              
322             $output_line = $output_line;
323             push( @output, $output_line );
324              
325             # write body
326             # ----------
327              
328             # loop through all the stars in the catalogue
329             foreach my $star ( 0 .. $#$stars ) {
330              
331             $output_line = undef;
332              
333             # field, number, ra, dec and x&y position
334             my $field = ${$stars}[$star]->field;
335             if ( defined $field ) {
336             $output_line = $field . " ";
337             } else {
338             $output_line = "0 ";
339             }
340              
341             my $id = ${$stars}[$star]->id;
342             if ( defined $id &&
343             Scalar::Util::looks_like_number( $id ) ) {
344             $output_line = $output_line . $id . " ";
345             } else {
346             $output_line = $output_line . $star . " ";
347             }
348              
349             # fiddle with the dec, olv versions of the Fortran Cluster
350             # parser don't like + signs for northern hemisphere dec's
351             my $dec = ${$stars}[$star]->dec();
352             $dec =~ s/\+//;
353              
354             $output_line = $output_line . ${$stars}[$star]->ra() . " ";
355             $output_line = $output_line . $dec . " ";
356              
357             my $x = ${$stars}[$star]->x;
358             my $y = ${$stars}[$star]->y;
359              
360             if ( defined $x && defined $y ) {
361             $output_line = $output_line . $x . " " . $y . " ";
362             } else {
363             $output_line = $output_line . "0.000 0.000 ";
364             }
365              
366             # magnitudes
367             foreach my $out_mag ( @out_mags ) {
368              
369             # Grab each magnitude listed in the @out_mags array and append
370             # it to the output line.
371             my $out_mag_value = ${$stars}[$star]->get_magnitude( $out_mag );
372             if( defined( $out_mag_value ) ) {
373             $output_line .= $out_mag_value . " ";
374             } else {
375             $output_line .= "0.000 ";
376             }
377              
378             # And get the error, if it exists.
379             my $out_mag_error = ${$stars}[$star]->get_errors( $out_mag );
380             if( defined( $out_mag_error ) ) {
381             $output_line .= $out_mag_error . " ";
382             } else {
383             $output_line .= "0.000 ";
384             }
385              
386             # And the quality.
387             my $quality = ${$stars}[$star]->quality;
388             if ( defined $quality ) {
389             $output_line .= $quality . " ";
390             } else {
391             $output_line .= "0 ";
392             }
393             }
394              
395             # Now for the colours.
396             foreach my $out_col ( @out_cols ) {
397              
398             # Grab each colour listed in the @out_cols array and append it
399             # to the output line.
400             my $out_col_value = ${$stars}[$star]->get_colour( $out_col );
401             if( defined( $out_col_value ) ) {
402             $output_line .= $out_col_value . " ";
403             } else {
404             $output_line .= "0.000 ";
405             }
406              
407             # And get the error, if it exists.
408             my $out_col_error = ${$stars}[$star]->get_colourerr( $out_col );
409             if( defined( $out_col_error ) ) {
410             $output_line .= $out_col_error . " ";
411             } else {
412             $output_line .= "0.000 ";
413             }
414              
415             # And the quality.
416             my $quality = ${$stars}[$star]->quality;
417             if ( defined $quality ) {
418             $output_line .= $quality . " ";
419             } else {
420             $output_line .= "0 ";
421             }
422             }
423              
424             # next star
425             $output_line = $output_line;
426             push (@output, $output_line );
427              
428             }
429              
430             # clean up
431             return \@output;
432              
433             }
434              
435             =item B<_default_file>
436              
437             If Astro::Catalog is created with a Format but no Filename or other data
438             source it checked this routine to see whether there is a default file
439             that should be read. This is mainly for Astro::Catalo::IO::JCMT and the
440             JAC, but might prive useful elsewhere.
441              
442             =cut
443              
444             sub _default_file {
445              
446             # returns an empty list
447             return;
448             }
449              
450             =back
451              
452             =head1 COPYRIGHT
453              
454             Copyright (C) 2001-2003 University of Exeter. All Rights Reserved.
455             Some modificiations Copyright (C) 2003-2005 Particle Physics and
456             Astronomy Research Council.
457             Some modifications Copyright (C) 2013 Science & Technology Facilities Council.
458             All Rights Reserved.
459              
460             This module was written as part of the eSTAR project in collaboration
461             with the Joint Astronomy Centre (JAC) in Hawaii and is free software;
462             you can redistribute it and/or modify it under the terms of the GNU
463             Public License.
464              
465             =head1 AUTHORS
466              
467             Alasdair Allan Eaa@astro.ex.ac.ukE
468             Brad Cavanagh Eb.cavanagh@jach.hawaii.eduE
469              
470             =cut
471              
472             # L A S T O R D E R S ------------------------------------------------------
473              
474             1;