File Coverage

blib/lib/Astro/Catalog/IO/LCOGTFITSTable.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Astro::Catalog::IO::LCOGTFITSTable;
2              
3             =head1 NAME
4              
5             Astro::Catalog::IO::LCOGTFITSTable - Binary LCOGT FITS table I/O for Astro::Catalog.
6              
7             =head1 SYNOPSIS
8              
9             $cat = Astro::Catalog::IO::LCOGTFITSTable->_read_catalog( $whatever );
10              
11             =cut
12              
13 1     1   3999804 use 5.006;
  1         52  
  1         1109  
14 1     1   13 use warnings;
  1         94  
  1         148  
15 1     1   64 use warnings::register;
  1         12  
  1         653  
16 1     1   8 use Carp;
  1         2  
  1         334  
17 1     1   8 use strict;
  1         2  
  1         62  
18              
19 1     1   1797 use Astro::Catalog;
  0            
  0            
20             use Astro::Catalog::Item;
21             use Astro::Catalog::Item::Morphology;
22             use Astro::Coords;
23             use Astro::FITS::CFITSIO qw/ :longnames :constants /;
24             use File::Temp qw/ tempfile /;
25              
26             use Astro::Flux;
27             use Astro::FluxColor;
28             use Astro::Fluxes;
29              
30             use DateTime;
31             use DateTime::Format::ISO8601;
32              
33             use POSIX qw/ log10 /;
34             use base qw/ Astro::Catalog::IO::Binary /;
35              
36             use vars qw/ $VERSION $DEBUG /;
37              
38             $VERSION = '4.31';
39             $DEBUG = 0;
40              
41             =begin __PUBLIC_METHODS__
42              
43             =head1 PUBLIC METHODS
44              
45             These methods are usually called automatically from the C
46             constructor, but are available for public use.
47              
48             =over 4
49              
50             =item B
51              
52             Returns the requested input format for the FITSTable class, which is
53             'name', meaning the name of the file to be turned into an C
54             object.
55              
56             $input_format = Astro::Catalog::IO::LCOGTFITSTable->input_format;
57              
58             =cut
59              
60             sub input_format {
61             return "name";
62             }
63              
64             =back
65              
66             =begin __PRIVATE_METHODS__
67              
68             =head1 PRIVATE METHODS
69              
70             These methods are usually called automatically from the C
71             constructor.
72              
73             =item B<_read_catalog>
74              
75             Parses the binary FITS table and returns a new C object
76             containing the catalogue entries.
77              
78             $cat = Astro::Catalog::IO::LCOGTFITSTable->_read_catalog( $whatever );
79              
80             The current translations from FITS table column names to
81             C properties are:
82              
83             =over 4
84              
85             =item No. - ID
86              
87             =item X_coordinate - X
88              
89             =item Y_coordinate - Y
90              
91             =item RA & DEC - Coords
92              
93             =item Isophotal_flux, Total_flux, Total_flux_err, Core_flux, Core1_flux, Core2_flux,
94             Core3_flux, Core4_flux - C objects pushed into
95             the C fluxes accessor.
96              
97             =item Isoarea, Ellipticity & Position_angle - Morphology
98              
99             =item Flags - Quality
100              
101             =back
102              
103             RA and Dec are assumed to be in J2000 coordinates, and are in units
104             of degrees. The total flux is assumed to be in units of counts,
105             and is converted into a magnitude through the formula -2.5 * log10( flux ).
106             The position angle is assumed to be the angle measured counter-
107             clockwise from the positive x axis, in degrees.
108              
109             An attempt to read in the DATE-OBS header is made so that flux measurements
110             can be timestamped. If the DATE-OBS header does not exist, then the current
111             date and time will be used for the flux timestamps.
112              
113             There are optional named parameters. These are case-sensitive, and are:
114              
115             =item Filter - An Astro::WaveBand object denoting the waveband that
116             the catalogue values were measured in.
117              
118             =cut
119              
120             sub _read_catalog {
121             my $class = shift;
122             my %args = @_;
123              
124             if ( ! defined( $args{'filename'} ) ) {
125             croak "Must supply a filename to read";
126             }
127             my $filename = $args{'filename'};
128              
129             my $obsid;
130             if ( defined( $args{'obsid'} ) ) {
131             $obsid = $args{'obsid'};
132             } else {
133             $obsid = [];
134             }
135              
136             if ( defined( $args{'Filter'} ) &&
137             ! UNIVERSAL::isa( $args{'Filter'}, "Astro::WaveBand" ) ) {
138             croak "Filter as passed to LCOGTFITSTable->_read_catalog must be an Astro::WaveBand object";
139             }
140              
141             my $filter;
142             if ( defined( $args{'Filter'} ) ) {
143             print "Filter defined\n" if $DEBUG;
144             $filter = $args{'Filter'}->natural;
145             } else {
146             $filter = 'unknown';
147             }
148             print "Input Filter=$filter\n" if $DEBUG;
149             # A lookup table for column name mappings.
150             my %column_name = ( 'ID' => 'NUMBER',
151             'X' => 'X_IMAGE',
152             'Y' => 'Y_IMAGE',
153             'RA' => 'ALPHA_J2000',
154             'Dec' => 'DELTA_J2000',
155             'isophotal_flux' => 'FLUX_ISO',
156             'total_flux' => 'FLUX_AUTO',
157             'total_flux_err' => 'FLUXERR_AUTO',
158             'core_flux' => 'FLUX_APER',
159             'core1_flux' => 'FLUX_APER1',
160             'core2_flux' => 'FLUX_APER2',
161             'core3_flux' => 'FLUX_APER3',
162             'core4_flux' => 'FLUX_APER4',
163             'isoarea' => 'ISOAREA_IMAGE',
164             'ellipticity' => 'ELLIPTICITY',
165             'position_angle' => 'THETA_IMAGE',
166             'flags' => 'FLAGS',
167             );
168              
169             # The new Astro::Catalog object.
170             my $catalog = new Astro::Catalog;
171              
172             # CFITSIO status variable.
173             my $status = 0;
174              
175             # Open the file using CFITSIO.
176             my $fptr = Astro::FITS::CFITSIO::open_file( $filename,
177             Astro::FITS::CFITSIO::READONLY(),
178             $status );
179             if ( $status != 0 ) {
180             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
181             croak "Error opening FITS file: $status $text";
182             }
183              
184             # Get the number of HDUs in the FITS file.
185             $fptr->get_num_hdus( my $num_hdus, $status );
186             if ( $status != 0 ) {
187             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
188             croak "Error retrieving number of HDUs from FITS file: $status $text";
189             }
190              
191             $fptr->get_hdu_num( my $hdu_pos );
192              
193             my $datetime;
194             my $waveband;
195             while ( $hdu_pos <= $num_hdus ) {
196              
197             # Get the type of HDU for the one we're at.
198             $fptr->get_hdu_type( my $hdutype, $status );
199             if ( $status != 0 ) {
200             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
201             croak "Error retrieving HDU type from FITS file: $status $text";
202             }
203             print "hdutype=$hdutype\n" if $DEBUG;
204             if ( $hdutype == IMAGE_HDU ) {
205              
206             # Try to retrieve the DATE-OBS header. This will be used
207             # to give each flux measurement a datetime stamp. If DATE-OBS
208             # cannot be determined, then set the datetime to the current
209             # time.
210              
211             $fptr->read_keyword( 'DATE-OBS', my $dateobs, my $comment, $status );
212             if ( $status != 0 ) {
213             if ( $status == KEY_NO_EXIST ) {
214             # We can deal with this, just take the current time and set
215             # the status back to 0 (good).
216             $datetime = DateTime->now;
217             $status = 0;
218             } else {
219             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
220             croak "Error retrieving DATE-OBS header from FITS file: $status $text";
221             }
222             } else {
223             # Strip out any characters that aren't meant to be there.
224             # read_keyword() puts single quotes around strings, so we need
225             # to get rid of those, along with any trailing Zs.
226             $dateobs =~ s/['Z]//g;
227             $datetime = DateTime::Format::ISO8601->parse_datetime( $dateobs );
228             }
229             print "DATE-OBS=$datetime\n" if $DEBUG;
230              
231             if ( ! defined( $filter ) ) {
232             $fptr->read_keyword( 'FILTER', my $filter, my $filtercomment, $status );
233             if ( $status != 0 ) {
234             if ( $status == KEY_NO_EXIST ) {
235             # We can deal with this, just set the filter to be 'unknown'.
236             $filter = 'unknown';
237             $status = 0;
238             } else {
239             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
240             croak "Error retrieving FILTER header from FITS file: $status $text";
241             }
242             } else {
243             # Strip out any characters that aren't meant to be there.
244             $filter =~ s/'//g;
245             $filter =~ s/^\s+//;
246             $filter =~ s/\s+$//;
247             }
248             print "Filter from header=$filter\n" if $DEBUG;
249             }
250             $waveband = new Astro::WaveBand( Filter => $filter );
251             print "FILTER, waveband=$filter\n" if $DEBUG;
252              
253             } elsif ( $hdutype == BINARY_TBL ) {
254             print "2 Wavelength= " . $waveband->wavelength . ", Frequency=" . $waveband->frequency . "\n" if $DEBUG;
255             # Get the number of rows in this table.
256             $fptr->get_num_rows( my $nrows, $status );
257             if ( $status != 0 ) {
258             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
259             croak "Error retrieving number of rows from HDU $hdu_pos from FITS file: $status $text";
260             }
261              
262             # Grab all the information we can from this HDU.
263             # First, get the column numbers for the ID, RA, Dec, flux,
264             # ellipticity, position angle, and x and y position.
265             $fptr->get_colnum( CASEINSEN, $column_name{'ID'}, my $id_column, $status );
266             if ( $status == COL_NOT_FOUND ) {
267             $status = 0;
268             $id_column = -1;
269             } elsif ( $status != 0 ) {
270             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
271             croak "Error in finding ID column: $status $text";
272             }
273             if ( $id_column == 0 ) {
274             $id_column = -1;
275             }
276             print "ID column: $id_column\n" if $DEBUG;
277              
278             $fptr->get_colnum( CASEINSEN, $column_name{'RA'}, my $ra_column, $status );
279             if ( $status == COL_NOT_FOUND ) {
280             $status = 0;
281             $ra_column = -1;
282             } elsif ( $status != 0 ) {
283             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
284             croak "Error in finding RA column: $status $text";
285             }
286             if ( $ra_column == 0 ) {
287             $ra_column = -1;
288             }
289             print "RA column: $ra_column\n" if $DEBUG;
290              
291             $fptr->get_colnum( CASEINSEN, $column_name{'Dec'}, my $dec_column, $status );
292             if ( $status == COL_NOT_FOUND ) {
293             $status = 0;
294             $dec_column = -1;
295             } elsif ( $status != 0 ) {
296             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
297             croak "Error in finding Dec column: $status $text";
298             }
299             if ( $dec_column == 0 ) {
300             $dec_column = -1;
301             }
302             print "Dec column: $dec_column\n" if $DEBUG;
303              
304             $fptr->get_colnum( CASEINSEN, $column_name{'isophotal_flux'}, my $iso_flux_column, $status );
305             if ( $status == COL_NOT_FOUND ) {
306             $status = 0;
307             $iso_flux_column = -1;
308             } elsif ( $status != 0 ) {
309             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
310             croak "Error in finding isophotal flux column: $status $text";
311             }
312             if ( $iso_flux_column == 0 ) {
313             $iso_flux_column = -1;
314             }
315             print "Isophotal flux column: $iso_flux_column\n" if $DEBUG;
316              
317             $fptr->get_colnum( CASEINSEN, $column_name{'total_flux'}, my $total_flux_column, $status );
318             if ( $status == COL_NOT_FOUND ) {
319             $status = 0;
320             $total_flux_column = -1;
321             } elsif ( $status != 0 ) {
322             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
323             croak "Error in finding total flux column: $status $text";
324             }
325             if ( $total_flux_column == 0 ) {
326             $total_flux_column = -1;
327             }
328             print "Total flux column: $total_flux_column\n" if $DEBUG;
329              
330             $fptr->get_colnum( CASEINSEN, $column_name{'total_flux_err'}, my $total_flux_err_column, $status );
331             if ( $status == COL_NOT_FOUND ) {
332             $status = 0;
333             $total_flux_err_column = -1;
334             } elsif ( $status != 0 ) {
335             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
336             croak "Error in finding total flux err column: $status $text";
337             }
338             if ( $total_flux_err_column == 0 ) {
339             $total_flux_err_column = -1;
340             }
341             print "Total flux err column: $total_flux_err_column\n" if $DEBUG;
342              
343             $fptr->get_colnum( CASEINSEN, $column_name{'core_flux'}, my $core_flux_column, $status );
344             if ( $status == COL_NOT_FOUND ) {
345             $status = 0;
346             $core_flux_column = -1;
347             } elsif ( $status != 0 ) {
348             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
349             croak "Error in finding core flux column: $status $text";
350             }
351             if ( $core_flux_column == 0 ) {
352             $core_flux_column = -1;
353             }
354             print "Core flux column: $core_flux_column\n" if $DEBUG;
355              
356             $fptr->get_colnum( CASEINSEN, $column_name{'core1_flux'}, my $core1_flux_column, $status );
357             if ( $status == COL_NOT_FOUND ) {
358             $status = 0;
359             $core1_flux_column = -1;
360             } elsif ( $status != 0 ) {
361             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
362             croak "Error in finding core1 flux column: $status $text";
363             }
364             if ( $core1_flux_column == 0 ) {
365             $core1_flux_column = -1;
366             }
367             print "Core1 flux column: $core1_flux_column\n" if $DEBUG;
368              
369             $fptr->get_colnum( CASEINSEN, $column_name{'core2_flux'}, my $core2_flux_column, $status );
370             if ( $status == COL_NOT_FOUND ) {
371             $status = 0;
372             $core2_flux_column = -1;
373             } elsif ( $status != 0 ) {
374             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
375             croak "Error in finding core2 flux column: $status $text";
376             }
377             if ( $core2_flux_column == 0 ) {
378             $core2_flux_column = -1;
379             }
380             print "Core2 flux column: $core2_flux_column\n" if $DEBUG;
381              
382             $fptr->get_colnum( CASEINSEN, $column_name{'core3_flux'}, my $core3_flux_column, $status );
383             if ( $status == COL_NOT_FOUND ) {
384             $status = 0;
385             $core3_flux_column = -1;
386             } elsif ( $status != 0 ) {
387             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
388             croak "Error in finding core3 flux column: $status $text";
389             }
390             if ( $core3_flux_column == 0 ) {
391             $core3_flux_column = -1;
392             }
393             print "Core3 flux column: $core3_flux_column\n" if $DEBUG;
394              
395             $fptr->get_colnum( CASEINSEN, $column_name{'core4_flux'}, my $core4_flux_column, $status );
396             if ( $status == COL_NOT_FOUND ) {
397             $status = 0;
398             $core4_flux_column = -1;
399             } elsif ( $status != 0 ) {
400             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
401             croak "Error in finding core4 flux column: $status $text";
402             }
403             if ( $core4_flux_column == 0 ) {
404             $core4_flux_column = -1;
405             }
406             print "Core4 flux column: $core4_flux_column\n" if $DEBUG;
407              
408             $fptr->get_colnum( CASEINSEN, $column_name{'isoarea'}, my $isoarea_column, $status );
409             if ( $status == COL_NOT_FOUND ) {
410             $status = 0;
411             $isoarea_column = -1;
412             } elsif ( $status != 0 ) {
413             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
414             croak "Error in finding isoarea column: $status $text";
415             }
416             if ( $isoarea_column == 0 ) {
417             $isoarea_column = -1;
418             }
419             print "Isoarea column: $isoarea_column\n" if $DEBUG;
420              
421             $fptr->get_colnum( CASEINSEN, $column_name{'ellipticity'}, my $ell_column, $status );
422             if ( $status == COL_NOT_FOUND ) {
423             $status = 0;
424             $ell_column = -1;
425             } elsif ( $status != 0 ) {
426             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
427             croak "Error in finding ellipticity column: $status $text";
428             }
429             if ( $ell_column == 0 ) {
430             $ell_column = -1;
431             }
432             print "Ellipticity column: $ell_column\n" if $DEBUG;
433              
434             $fptr->get_colnum( CASEINSEN, $column_name{'position_angle'}, my $posang_column, $status );
435             if ( $status == COL_NOT_FOUND ) {
436             $status = 0;
437             $posang_column = -1;
438             } elsif ( $status != 0 ) {
439             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
440             croak "Error in finding position angle column: $status $text";
441             }
442             if ( $posang_column == 0 ) {
443             $posang_column = -1;
444             }
445             print "Position angle column: $posang_column\n" if $DEBUG;
446              
447             $fptr->get_colnum( CASEINSEN, $column_name{'X'}, my $x_column, $status );
448             if ( $status == COL_NOT_FOUND ) {
449             $status = 0;
450             $x_column = -1;
451             } elsif ( $status != 0 ) {
452             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
453             croak "Error in finding x-coordinate column: $status $text";
454             }
455             if ( $x_column == 0 ) {
456             $x_column = -1;
457             }
458             print "X-coordinate column: $x_column\n" if $DEBUG;
459              
460             $fptr->get_colnum( CASEINSEN, $column_name{'Y'}, my $y_column, $status );
461             if ( $status == COL_NOT_FOUND ) {
462             $status = 0;
463             $y_column = -1;
464             } elsif ( $status != 0 ) {
465             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
466             croak "Error in finding y-coordinate column: $status $text";
467             }
468             if ( $y_column == 0 ) {
469             $y_column = -1;
470             }
471             print "Y-coordinate column: $y_column\n" if $DEBUG;
472              
473             $fptr->get_colnum( CASEINSEN, $column_name{'flags'}, my $flag_column, $status );
474             if ( $status == COL_NOT_FOUND ) {
475             $status = 0;
476             $flag_column = -1;
477             } elsif ( $status != 0 ) {
478             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
479             croak "Error in finding flags column: $status $text";
480             }
481             if ( $flag_column == 0 ) {
482             $flag_column = -1;
483             }
484             print "Flags column: $flag_column\n" if $DEBUG;
485              
486             # Now that we've got all the columns defined, we need to grab each column
487             # in one big array, then take those arrays and stuff the information into
488             # Astro::Catalog::Item objects
489             my $id;
490             my $ra;
491             my $dec;
492             my ( $iso_flux, $total_flux, $total_flux_err, $core_flux, $core1_flux, $core2_flux );
493             my ( $core3_flux, $core4_flux );
494             my $isoarea;
495             my $ell;
496             my $posang;
497             my $x_pos;
498             my $y_pos;
499             my $flags;
500             if ( $id_column != -1 ) {
501             $fptr->read_col( TFLOAT, $id_column, 1, 1, $nrows, undef, $id, undef, $status );
502             if ( $status != 0 ) {
503             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
504             croak "Error in retrieving data for ID column: $status $text";
505             }
506             }
507             if ( $ra_column != -1 ) {
508             $fptr->read_col( TFLOAT, $ra_column, 1, 1, $nrows, undef, $ra, undef, $status );
509             if ( $status != 0 ) {
510             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
511             croak "Error in retrieving data for RA column: $status $text";
512             }
513             }
514             if ( $dec_column != -1 ) {
515             $fptr->read_col( TFLOAT, $dec_column, 1, 1, $nrows, undef, $dec, undef, $status );
516             if ( $status != 0 ) {
517             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
518             croak "Error in retrieving data for Dec column: $status $text";
519             }
520             }
521             if ( $iso_flux_column != -1 ) {
522             $fptr->read_col( TFLOAT, $iso_flux_column, 1, 1, $nrows, undef, $iso_flux, undef, $status );
523             if ( $status != 0 ) {
524             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
525             croak "Error in retrieving data for isophotal flux column: $status $text";
526             }
527             }
528             if ( $total_flux_column != -1 ) {
529             $fptr->read_col( TFLOAT, $total_flux_column, 1, 1, $nrows, undef, $total_flux, undef, $status );
530             if ( $status != 0 ) {
531             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
532             croak "Error in retrieving data for total flux column: $status $text";
533             }
534             }
535             if ( $total_flux_err_column != -1 ) {
536             $fptr->read_col( TFLOAT, $total_flux_err_column, 1, 1, $nrows, undef, $total_flux_err, undef, $status );
537             if ( $status != 0 ) {
538             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
539             croak "Error in retrieving data for total flux err column: $status $text";
540             }
541             }
542             if ( $core_flux_column != -1 ) {
543             $fptr->read_col( TFLOAT, $core_flux_column, 1, 1, $nrows, undef, $core_flux, undef, $status );
544             if ( $status != 0 ) {
545             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
546             croak "Error in retrieving data for core flux column: $status $text";
547             }
548             }
549             if ( $core1_flux_column != -1 ) {
550             $fptr->read_col( TFLOAT, $core1_flux_column, 1, 1, $nrows, undef, $core1_flux, undef, $status );
551             if ( $status != 0 ) {
552             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
553             croak "Error in retrieving data for core1 flux column: $status $text";
554             }
555             }
556             if ( $core2_flux_column != -1 ) {
557             $fptr->read_col( TFLOAT, $core2_flux_column, 1, 1, $nrows, undef, $core2_flux, undef, $status );
558             if ( $status != 0 ) {
559             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
560             croak "Error in retrieving data for core2 flux column: $status $text";
561             }
562             }
563             if ( $core3_flux_column != -1 ) {
564             $fptr->read_col( TFLOAT, $core3_flux_column, 1, 1, $nrows, undef, $core3_flux, undef, $status );
565             if ( $status != 0 ) {
566             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
567             croak "Error in retrieving data for core3 flux column: $status $text";
568             }
569             }
570             if ( $core4_flux_column != -1 ) {
571             $fptr->read_col( TFLOAT, $core4_flux_column, 1, 1, $nrows, undef, $core4_flux, undef, $status );
572             if ( $status != 0 ) {
573             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
574             croak "Error in retrieving data for core4 flux column: $status $text";
575             }
576             }
577             if ( $isoarea_column != -1 ) {
578             $fptr->read_col( TINT, $isoarea_column, 1, 1, $nrows, undef, $isoarea, undef, $status );
579             if ( $status != 0 ) {
580             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
581             croak "Error in retrieving data for isoarea column: $status $text";
582             }
583             }
584             if ( $ell_column != -1 ) {
585             $fptr->read_col( TFLOAT, $ell_column, 1, 1, $nrows, undef, $ell, undef, $status );
586             if ( $status != 0 ) {
587             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
588             croak "Error in retrieving data for ellipticity column: $status $text";
589             }
590             }
591             if ( $posang_column != -1 ) {
592             $fptr->read_col( TFLOAT, $posang_column, 1, 1, $nrows, undef, $posang, undef, $status );
593             if ( $status != 0 ) {
594             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
595             croak "Error in retrieving data for position angle column: $status $text";
596             }
597             }
598             if ( $x_column != -1 ) {
599             $fptr->read_col( TFLOAT, $x_column, 1, 1, $nrows, undef, $x_pos, undef, $status );
600             if ( $status != 0 ) {
601             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
602             croak "Error in retrieving data for x-coordinate column: $status $text";
603             }
604             }
605             if ( $y_column != -1 ) {
606             $fptr->read_col( TFLOAT, $y_column, 1, 1, $nrows, undef, $y_pos, undef, $status );
607             if ( $status != 0 ) {
608             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
609             croak "Error in retrieving data for y-coordinate column: $status $text";
610             }
611             }
612             if ( $flag_column != -1 ) {
613             $fptr->read_col( TINT, $flag_column, 1, 1, $nrows, undef, $flags, undef, $status );
614             if ( $status != 0 ) {
615             Astro::FITS::CFITSIO::fits_get_errstatus( $status, my $text );
616             croak "Error in retrieving data for flags column: $status $text";
617             }
618             }
619              
620             # Go through each array, grabbing the information and creating a
621             # new Astro::Catalog::Item object each time through.
622             for ( my $i = 0; $i < $nrows; $i++ ) {
623             my $id_value;
624             if ( $id_column != -1 ) {
625             $id_value = $id->[$i];
626             }
627             my $ra_value;
628             if ( $ra_column != -1 ) {
629             $ra_value = $ra->[$i];
630             }
631             my $dec_value;
632             if ( $dec_column != -1 ) {
633             $dec_value = $dec->[$i];
634             }
635             my $iso_flux_value;
636             if ( $iso_flux_column != -1 ) {
637             $iso_flux_value = $iso_flux->[$i];
638             }
639             my $total_flux_value;
640             if ( $total_flux_column != -1 ) {
641             $total_flux_value = $total_flux->[$i];
642             }
643             my $total_flux_err_value;
644             if ( $total_flux_err_column != -1 ) {
645             $total_flux_err_value = $total_flux_err->[$i];
646             }
647             my $core_flux_value;
648             if ( $core_flux_column != -1 ) {
649             $core_flux_value = $core_flux->[$i];
650             }
651             my $core1_flux_value;
652             if ( $core1_flux_column != -1 ) {
653             $core1_flux_value = $core1_flux->[$i];
654             }
655             my $core2_flux_value;
656             if ( $core2_flux_column != -1 ) {
657             $core2_flux_value = $core2_flux->[$i];
658             }
659             my $core3_flux_value;
660             if ( $core3_flux_column != -1 ) {
661             $core3_flux_value = $core3_flux->[$i];
662             }
663             my $core4_flux_value;
664             if ( $core4_flux_column != -1 ) {
665             $core4_flux_value = $core4_flux->[$i];
666             }
667             my $isoarea_value;
668             if ( $isoarea_column != -1 ) {
669             $isoarea_value = $isoarea->[$i];
670             }
671             my $ell_value;
672             if ( $ell_column != -1 ) {
673             $ell_value = $ell->[$i];
674             }
675             my $posang_value;
676             if ( $posang_column != -1 ) {
677             $posang_value = $posang->[$i];
678             }
679             my $x_pos_value;
680             if ( $x_column != -1 ) {
681             $x_pos_value = $x_pos->[$i];
682             }
683             my $y_pos_value;
684             if ( $y_column != -1 ) {
685             $y_pos_value = $y_pos->[$i];
686             }
687             my $flags_value = 0;
688             if ( $flag_column != -1 ) {
689             $flags_value = $flags->[$i];
690             }
691              
692              
693             # Create a temporary Astro::Catalog::Item object.
694             my $star = new Astro::Catalog::Item();
695              
696             # Set up the Astro::Coords object, assuming our RA and Dec are in units
697             # of degrees.
698             my $coords;
699             if ( defined( $ra_value ) && defined( $dec_value ) ) {
700             $coords = new Astro::Coords( ra => $ra_value,
701             dec => $dec_value,
702             units => 'degrees',
703             type => 'J2000',
704             );
705             $star->coords( $coords );
706             }
707              
708             if ( $flag_column != -1 ) {
709             $star->quality( $flags_value );
710             } else {
711             $star->quality( 0 );
712             }
713              
714             if ( $id_column != -1 ) {
715             $star->id( $id_value );
716             }
717              
718             if ( $x_column != -1 ) {
719             $star->x( $x_pos_value );
720             }
721             if ( $y_column != -1 ) {
722             $star->y( $y_pos_value );
723             }
724              
725             # Set up the Astro::Flux objects.
726             if ( $iso_flux_column != -1 ) {
727             my $num;
728             $num = new Number::Uncertainty( Value => $iso_flux_value );
729             my $flux_iso = new Astro::Flux( $num, 'isophotal_flux', $waveband,
730             datetime => $datetime, obsid => $obsid );
731             $star->fluxes( new Astro::Fluxes( $flux_iso ) );
732             }
733              
734             if ( $total_flux_column != -1 ) {
735             my $num;
736             $num = new Number::Uncertainty( Value => $total_flux_value );
737             my $flux_total = new Astro::Flux( $num, 'total_flux', $waveband,
738             datetime => $datetime, obsid => $obsid );
739             $star->fluxes( new Astro::Fluxes( $flux_total ) );
740             }
741              
742             if ( $core_flux_column != -1 ) {
743             my $num;
744             $num = new Number::Uncertainty( Value => $core_flux_value );
745             my $core_flux_obj = new Astro::Flux( $num, 'core_flux', $waveband,
746             datetime => $datetime, obsid => $obsid );
747             $star->fluxes( new Astro::Fluxes( $core_flux_obj ) );
748             }
749              
750             if ( $core1_flux_column != -1 ) {
751             my $num;
752             $num = new Number::Uncertainty( Value => $core1_flux_value );
753             my $core1_flux_obj = new Astro::Flux( $num, 'core1_flux', $waveband,
754             datetime => $datetime, obsid => $obsid );
755             $star->fluxes( new Astro::Fluxes( $core1_flux_obj ) );
756             }
757              
758             if ( $core2_flux_column != -1 ) {
759             my $num;
760             $num = new Number::Uncertainty( Value => $core2_flux_value );
761             my $core2_flux_obj = new Astro::Flux( $num, 'core2_flux', $waveband,
762             datetime => $datetime, obsid => $obsid );
763             $star->fluxes( new Astro::Fluxes( $core2_flux_obj ) );
764             }
765              
766             if ( $core3_flux_column != -1 ) {
767             my $num;
768             $num = new Number::Uncertainty( Value => $core3_flux_value );
769             my $core3_flux_obj = new Astro::Flux( $num, 'core3_flux', $waveband,
770             datetime => $datetime, obsid => $obsid );
771             $star->fluxes( new Astro::Fluxes( $core3_flux_obj ) );
772             }
773              
774             if ( $core4_flux_column != -1 ) {
775             my $num;
776             $num = new Number::Uncertainty( Value => $core4_flux_value );
777             my $core4_flux_obj = new Astro::Flux( $num, 'core4_flux', $waveband,
778             datetime => $datetime, obsid => $obsid );
779             $star->fluxes( new Astro::Fluxes( $core4_flux_obj ) );
780             }
781              
782             # Compute a magnitude and mag. error from the total flux value and total
783             # flux error (if available).
784             if ( $total_flux_value > 0.0 and $total_flux_err_value > 0.0 ) {
785             my $mag = -2.5 * log10( $total_flux_value );
786             my $num;
787             if ( $total_flux_err_column != -1 ) {
788             my $magerr = 2.5 / log(10) * $total_flux_err_value / $total_flux_value;
789             $num = new Number::Uncertainty( Value => $mag,
790             Error => 2.0 * $magerr );
791             } else {
792             $num = new Number::Uncertainty( Value => $mag );
793             }
794             my $mag_obj = new Astro::Flux( $num, 'MAG', $waveband,
795             datetime => $datetime, obsid => $obsid );
796             $star->fluxes( new Astro::Fluxes( $mag_obj ) );
797             }
798             # And set up the Astro::Catalog::Item::Morphology object.
799             my $morphology = new Astro::Catalog::Item::Morphology( area => $isoarea_value,
800             ellipticity => $ell_value,
801             position_angle_pixel => $posang_value,
802             );
803             $star->morphology( $morphology );
804              
805              
806             # Push it onto the Astro::Catalog object.
807             $catalog->pushstar( $star );
808             }
809              
810             }
811             $status = 0;
812              
813             # Move to the next one.
814             $fptr->movrel_hdu( 1, $hdutype, $status );
815             last if ( $status == END_OF_FILE );
816              
817             # And set $hdu_pos.
818             $fptr->get_hdu_num( $hdu_pos );
819              
820             }
821              
822             # Set the origin.
823             $catalog->origin( 'IO::LCOGTFITSTable' );
824              
825             # And return.
826             return $catalog;
827              
828             }
829              
830             =item B<_write_catalog>
831              
832             Create an output catalog as a binary FITS table.
833              
834             $ref = Astro::Catalog::IO::LCOGTFITSTable->_write_catalog( $catalog );
835              
836             Argument is an C object.
837              
838             This method is not yet implemented.
839              
840             =cut
841              
842             sub _write_catalog {
843             croak "Not yet implemented.";
844             }
845              
846             =back
847              
848             =head1 REVISION
849              
850             $Id: LCOGTFITSTable.pm 5687 2012-05-16 16:43:56Z tlister $
851              
852             =head1 SEE ALSO
853              
854             L
855              
856             =head1 COPYRIGHT
857              
858             Copyright (C) 2012 Las Cumbres Observatory Global Telescope Network.
859             All Rights Reserved.
860              
861             This module is free software;
862             you can redistribute it and/or modify it under the terms of the GNU
863             Public License.
864              
865             =head1 AUTHORS
866              
867             Tim Lister Etlister@lcogt.netE
868              
869             =cut
870              
871             1;