use Carp; # # find appropriate CFITSIO datatype for a given piddle type. # Can be passed the piddle itself or a PDL::Type token (e.g., # float() with no args). # sub match_datatype { my $arg = shift; my $pdl_type; if (UNIVERSAL::isa($arg,'PDL')) { $pdl_type = $arg->get_datatype; } elsif (UNIVERSAL::isa($arg,'PDL::Type')) { $pdl_type = $arg->[0]; } else { croak "argument should be a PDL object or PDL::Type token"; } my $pdl_size = PDL::Core::howbig($pdl_type); my @cfitsio_possible_types; # test for real datatypes if ($pdl_type == float(1)->get_datatype or $pdl_type == double(1)->get_datatype ) { @cfitsio_possible_types = ( Astro::FITS::CFITSIO::TDOUBLE(), Astro::FITS::CFITSIO::TFLOAT(), ); } elsif ($pdl_type == short(1)->get_datatype or $pdl_type == long(1)->get_datatype ) { @cfitsio_possible_types = ( Astro::FITS::CFITSIO::TSHORT(), Astro::FITS::CFITSIO::TINT(), Astro::FITS::CFITSIO::TLONG(), ); } elsif ($pdl_type == ushort(1)->get_datatype or $pdl_type == byte(1)->get_datatype ) { @cfitsio_possible_types = ( Astro::FITS::CFITSIO::TBYTE(), Astro::FITS::CFITSIO::TUSHORT(), Astro::FITS::CFITSIO::TUINT(), Astro::FITS::CFITSIO::TULONG(), ); } else { croak "cannot handle PDL type $pdl_type"; } foreach my $cfitsio_type (@cfitsio_possible_types) { return $cfitsio_type if $pdl_size == Astro::FITS::CFITSIO::sizeof_datatype($cfitsio_type); } croak "no CFITSIO type for PDL type $pdl_type"; } 1; =head1 match_datatype( ) $cfitsio_type = match_datatype($piddle); $cfitsio_type = match_datatype(long); # or short, or float, etc. PDL datatypes are always guaranteed to be the same size on all architectures, whereas CFITSIO datatypes (TLONG, for example), will vary on some architectures since they correspond to the C datatypes on that system. This poses a problem for Perl scripts which wish to read FITS data into piddles, and do so in a portable manner. This routine takes a PDL object or PDL::Types token (returned by float() and friends when given no arguments), and returns the same-sized CFITSIO datatype, suitable for passing to routines such as fits_read_col(). =cut