Starlink / starjava

Java applications initially developed for the Starlink Project but now developed independently
Other
95 stars 24 forks source link

Boolean array not supported? #59

Closed vforchi closed 3 years ago

vforchi commented 3 years ago

Hi,

I'm using STIL in my TAP server, and I noticed that I cannot serialize a boolean array to FITS (works fine with VOTABLE). If I try I get this error:

java.lang.ClassCastException: class [Ljava.lang.Boolean; cannot be cast to class [Z ([Ljava.lang.Boolean; and [Z are in module java.base of loader 'bootstrap')
    at uk.ac.starlink.table.storage.Codec$BooleanCodec1.encode1(Codec.java:976) ~[table.jar:na]
    at uk.ac.starlink.table.storage.Codec$FixedArrayCodec.encode(Codec.java:627) ~[table.jar:na]
    at uk.ac.starlink.table.storage.Codec$FlaggedCodec.encode(Codec.java:508) ~[table.jar:na]
    at uk.ac.starlink.table.storage.ByteStoreRowStore.acceptRow(ByteStoreRowStore.java:96) ~[table.jar:na]
    at uk.ac.starlink.table.StoragePolicy.copyTable(StoragePolicy.java:184) ~[table.jar:na]

I don't see a boolean array in the codecs:

    public static final Codec BYTE = new Codec.ByteCodec();
    public static final Codec SHORT = new Codec.ShortCodec();
    public static final Codec INT = new Codec.IntCodec();
    public static final Codec LONG = new Codec.LongCodec();
    public static final Codec FLOAT = new Codec.FloatCodec();
    public static final Codec DOUBLE = new Codec.DoubleCodec();
    public static final Codec CHAR = new Codec.CharCodec();
    public static final Codec BOOLEAN = new Codec.BooleanCodec();
    public static final Codec BYTE_ARRAY = new Codec.VariableArrayCodec(new Codec.ByteCodec1());
    public static final Codec SHORT_ARRAY = new Codec.VariableArrayCodec(new Codec.ShortCodec1());
    public static final Codec INT_ARRAY = new Codec.VariableArrayCodec(new Codec.IntCodec1());
    public static final Codec LONG_ARRAY = new Codec.VariableArrayCodec(new Codec.LongCodec1());
    public static final Codec FLOAT_ARRAY = new Codec.VariableArrayCodec(new Codec.FloatCodec1());
    public static final Codec DOUBLE_ARRAY = new Codec.VariableArrayCodec(new Codec.DoubleCodec1());
    public static final Codec STRING = new Codec.VariableStringCodec();

Is this the reason?

Cheers, Vincenzo

mbtaylor commented 3 years ago

In general, STIL doesn't like working with arrays of wrapper classes like java.lang.Boolean where primitive arrays can be used instead. You should present it with a boolean[] array instead of a java.lang.Boolean[] array. It is possible to write boolean[] arrays to FITS:

% stilts tpipe in=:test:3,f cmd='keepcols f_boolean' out=x.fits
% stilts tpipe in=x.fits
Table name: votable
+-----------------------+
| f_boolean             |
+-----------------------+
| (false, false, false) |
| (true, false, false)  |
| (false, true, false)  |
+-----------------------+

Having said that, I'm not sure why there's a difference between VOTable and FITS handling here. If you still have problems, get back to me.

vforchi commented 3 years ago

I see, thanks.