    001/*-
    002 * Copyright (c) 2016 Diamond Light Source Ltd.
    003 *
    004 * All rights reserved. This program and the accompanying materials
    005 * are made available under the terms of the Eclipse Public License v1.0
    006 * which accompanies this distribution, and is available at
    007 * http://www.eclipse.org/legal/epl-v10.html
    008 */
    009
    010package org.eclipse.january.dataset;
    011
    012import java.lang.reflect.Array;
    013import java.util.Date;
    014import java.util.HashMap;
    015import java.util.LinkedHashMap;
    016import java.util.List;
    017import java.util.Map;
    018import java.util.Map.Entry;
    019
    020import org.apache.commons.math3.complex.Complex;
    021import org.slf4j.Logger;
    022import org.slf4j.LoggerFactory;
    023
    024public class DTypeUtils {
    025        private static final Logger logger = LoggerFactory.getLogger(DTypeUtils.class);
    026
    027        private static Map<Class<? extends Dataset>, Integer> createInterfaceMap() {
    028                Map<Class<? extends Dataset>, Integer> map = new LinkedHashMap<>();
    029                map.put(BooleanDatasetBase.class, Dataset.BOOL);
    030                map.put(BooleanDataset.class, Dataset.BOOL);
    031                map.put(ByteDataset.class, Dataset.INT8);
    032                map.put(ShortDataset.class, Dataset.INT16);
    033                map.put(IntegerDataset.class, Dataset.INT32);
    034                map.put(LongDataset.class, Dataset.INT64);
    035                map.put(FloatDataset.class, Dataset.FLOAT32);
    036                map.put(DoubleDataset.class, Dataset.FLOAT64);
    037                map.put(ComplexFloatDataset.class, Dataset.COMPLEX64);
    038                map.put(ComplexDoubleDataset.class, Dataset.COMPLEX128);
    039                map.put(CompoundByteDataset.class, Dataset.ARRAYINT8);
    040                map.put(CompoundShortDataset.class, Dataset.ARRAYINT16);
    041                map.put(CompoundIntegerDataset.class, Dataset.ARRAYINT32);
    042                map.put(CompoundLongDataset.class, Dataset.ARRAYINT64);
    043                map.put(CompoundFloatDataset.class, Dataset.ARRAYFLOAT32);
    044                map.put(CompoundDoubleDataset.class, Dataset.ARRAYFLOAT64);
    045                map.put(StringDatasetBase.class, Dataset.STRING);
    046                map.put(StringDataset.class, Dataset.STRING);
    047                map.put(ObjectDatasetBase.class, Dataset.OBJECT);
    048                map.put(ObjectDataset.class, Dataset.OBJECT);
    049                map.put(DateDatasetImpl.class, Dataset.DATE);
    050                map.put(DateDataset.class, Dataset.DATE);
    051                map.put(RGBByteDataset.class, Dataset.RGB8);
    052                map.put(RGBDataset.class, Dataset.RGB);
    053                return map;
    054        }
    055
    056        static final Map<Class<? extends Dataset>, Integer> interface2DTypes; // map interface to dataset type
    057        private static final Map<Integer, Class<? extends Dataset>> dtype2Interface; // map dataset type to interface
    058        static {
    059                interface2DTypes = createInterfaceMap();
    060                dtype2Interface = new HashMap<>();
    061                for (Entry<Class<? extends Dataset>, Integer> e : interface2DTypes.entrySet()) {
    062                        dtype2Interface.put(e.getValue(), e.getKey());
    063                }
    064        }
    065
    066        /**
    067         * @param a input
    068         * @return name of dataset type
    069         */
    070        public static String getDTypeName(Dataset a) {
    071                return getDatasetName(a);
    072        }
    073
    074        /**
    075         * @param a input
    076         * @return name of dataset type
    077         */
    078        public static String getDTypeName(ILazyDataset a) {
    079                return getDatasetName(a);
    080        }
    081
    082        /**
    083         * @param dtype dataset type
    084         * @param itemSize item size
    085         * @return name of dataset type
    086         */
    087        public static String getDTypeName(int dtype, int itemSize) {
    088                return getDatasetName(dtype2Interface.get(dtype), itemSize);
    089        }
    090
    091        /**
    092         * @param clazz dataset class
    093         * @return dataset type for dataset class
    094         */
    095        public static int getDType(Class<? extends Dataset> clazz) {
    096                Class<? extends Dataset> c = findInterface(clazz);
    097                if (c == null) {
    098                        throw new IllegalArgumentException("Interface class not allowed or supported");
    099                }
    100                return interface2DTypes.get(c);
    101        }
    102
    103        private static Class<? extends Dataset> findInterface(Class<? extends Dataset> clazz) {
    104                if (interface2DTypes.containsKey(clazz)) {
    105                        return clazz;
    106                }
    107
    108                Class<? extends Dataset> c = InterfaceUtils.findSubInterface(clazz);
    109                if (c != null) {
    110                        return findInterface(c);
    111                }
    112
    113                return null;
    114        }
    115
    116        /**
    117         * @param dtype dataset type
    118         * @return true if each dataset item has single element
    119         */
    120        public static boolean isDTypeElemental(int dtype) {
    121                return dtype <= Dataset.DATE;
    122        }
    123
    124        /**
    125         * @param dtype dataset type
    126         * @return true if dataset elements are integers
    127         */
    128        public static boolean isDTypeInteger(int dtype) {
    129                return dtype == Dataset.INT8 || dtype == Dataset.INT16 || dtype == Dataset.INT32 || dtype == Dataset.INT64 ||
    130                                dtype == Dataset.ARRAYINT8 || dtype == Dataset.ARRAYINT16 || dtype == Dataset.ARRAYINT32 || dtype == Dataset.ARRAYINT64 || dtype == Dataset.RGB8 || dtype == Dataset.RGB;
    131        }
    132
    133        /**
    134         * @param dtype dataset type
    135         * @return true if dataset elements are floats
    136         */
    137        public static boolean isDTypeFloating(int dtype) {
    138                return dtype == Dataset.FLOAT32 || dtype == Dataset.FLOAT64 || dtype == Dataset.COMPLEX64 || dtype == Dataset.COMPLEX128 ||
    139                                dtype == Dataset.ARRAYFLOAT32 || dtype == Dataset.ARRAYFLOAT64;
    140        }
    141
    142        /**
    143         * @param dtype dataset type
    144         * @return true if each dataset itema are complex
    145         */
    146        public static boolean isDTypeComplex(int dtype) {
    147                return dtype == Dataset.COMPLEX64 || dtype == Dataset.COMPLEX128;
    148        }
    149
    150        /**
    151         * @param dtype dataset type
    152         * @return true if dataset type is numerical, i.e. a dataset contains numbers
    153         */
    154        public static boolean isDTypeNumerical(int dtype) {
    155                return isDTypeInteger(dtype) || isDTypeFloating(dtype) || dtype == Dataset.BOOL;
    156        }
    157
    158        /**
    159         * Find dataset type that best fits given types The best type takes into account complex and array datasets
    160         *
    161         * @param atype
    162         *            first dataset type
    163         * @param btype
    164         *            second dataset type
    165         * @return best dataset type
    166         */
    167        public static int getBestDType(final int atype, final int btype) {
    168                return interface2DTypes.get(InterfaceUtils.getBestInterface(getInterface(atype), getInterface(btype)));
    169        }
    170
    171        /**
    172         * Find floating point dataset type that best fits given types. The best type takes into account complex and array
    173         * datasets
    174         *
    175         * @param dtype
    176         *            dataset type
    177         * @return best dataset type
    178         */
    179        public static int getBestFloatDType(final int dtype) {
    180                return getDType(InterfaceUtils.getBestFloatInterface(getInterface(dtype)));
    181        }
    182
    183        /**
    184         * Find floating point dataset type that best fits given class The best type takes into account complex and array
    185         * datasets
    186         *
    187         * @param cls
    188         *            of an item or element
    189         * @return best dataset type
    190         */
    191        public static int getBestFloatDType(Class<? extends Object> cls) {
    192                return getBestFloatDType(getDTypeFromClass(cls));
    193        }
    194
    195        /**
    196         * Get dataset type from an element class
    197         *
    198         * @param cls element class
    199         * @return dataset type
    200         */
    201        public static int getDTypeFromClass(Class<? extends Object> cls) {
    202                return getDTypeFromClass(cls, 1);
    203        }
    204
    205        /**
    206         * Get dataset type from an element class
    207         *
    208         * @param cls element class
    209         * @param itemSize item size
    210         * @return dataset type
    211         */
    212        public static int getDTypeFromClass(Class<? extends Object> cls, int itemSize) {
    213                return getDType(InterfaceUtils.getInterfaceFromClass(itemSize, cls));
    214        }
    215
    216        /**
    217         * Get dataset type from an object. The following are supported: Java Number objects, Apache common math Complex
    218         * objects, Java arrays and lists
    219         *
    220         * @param obj input
    221         * @return dataset type
    222         */
    223        public static int getDTypeFromObject(Object obj) {
    224                int dtype = -1;
    225
    226                if (obj == null) {
    227                        return Dataset.OBJECT;
    228                }
    229
    230                if (obj instanceof List<?>) {
    231                        List<?> jl = (List<?>) obj;
    232                        int l = jl.size();
    233                        for (int i = 0; i < l; i++) {
    234                                int ldtype = getDTypeFromObject(jl.get(i));
    235                                if (ldtype > dtype) {
    236                                        dtype = ldtype;
    237                                }
    238                        }
    239                } else if (obj.getClass().isArray()) {
    240                        Class<?> ca = obj.getClass().getComponentType();
    241                        if (InterfaceUtils.isElementSupported(ca)) {
    242                                return getDTypeFromClass(ca);
    243                        }
    244                        int l = Array.getLength(obj);
    245                        for (int i = 0; i < l; i++) {
    246                                Object lo = Array.get(obj, i);
    247                                int ldtype = getDTypeFromObject(lo);
    248                                if (ldtype > dtype) {
    249                                        dtype = ldtype;
    250                                }
    251                        }
    252                } else if (obj instanceof Dataset) {
    253                        return interface2DTypes.get(obj.getClass());
    254                } else if (obj instanceof ILazyDataset) {
    255                        dtype = getDTypeFromClass(((ILazyDataset) obj).getElementClass(), ((ILazyDataset) obj).getElementsPerItem());
    256                } else {
    257                        dtype = getDTypeFromClass(obj.getClass());
    258                }
    259                return dtype;
    260        }
    261
    262        /**
    263         * Get dataset type from given dataset
    264         * @param d dataset
    265         * @return dataset type
    266         */
    267        public static int getDType(ILazyDataset d) {
    268                if (d instanceof LazyDatasetBase)
    269                        return ((LazyDatasetBase) d).getDType();
    270                return getDTypeFromClass(d.getElementClass(), d.getElementsPerItem());
    271        }
    272
    273        /**
    274         * The largest dataset type suitable for a summation of around a few thousand items without changing from the "kind"
    275         * of dataset
    276         *
    277         * @param dtype dataset type
    278         * @return largest dataset type available for given dataset type
    279         */
    280        public static int getLargestDType(final int dtype) {
    281                switch (dtype) {
    282                case Dataset.BOOL:
    283                case Dataset.INT8:
    284                case Dataset.INT16:
    285                        return Dataset.INT32;
    286                case Dataset.INT32:
    287                case Dataset.INT64:
    288                        return Dataset.INT64;
    289                case Dataset.FLOAT32:
    290                case Dataset.FLOAT64:
    291                        return Dataset.FLOAT64;
    292                case Dataset.COMPLEX64:
    293                case Dataset.COMPLEX128:
    294                        return Dataset.COMPLEX128;
    295                case Dataset.ARRAYINT8:
    296                case Dataset.ARRAYINT16:
    297                        return Dataset.ARRAYINT32;
    298                case Dataset.ARRAYINT32:
    299                case Dataset.ARRAYINT64:
    300                        return Dataset.ARRAYINT64;
    301                case Dataset.ARRAYFLOAT32:
    302                case Dataset.ARRAYFLOAT64:
    303                        return Dataset.ARRAYFLOAT64;
    304                case Dataset.DATE:
    305                case Dataset.STRING:
    306                case Dataset.RGB8:
    307                case Dataset.RGB:
    308                case Dataset.OBJECT:
    309                        return dtype;
    310                }
    311                throw new IllegalArgumentException("Unsupported dataset type");
    312        }
    313
    314        /**
    315         * The largest dataset class suitable for a summation of around a few thousand items without changing from the "kind"
    316         * of dataset
    317         *
    318         * @param clazz dataset sub-interface
    319         * @return largest dataset class available for given dataset class
    320         * @since 2.3
    321         */
    322        public static Class<? extends Dataset> getLargestDataset(final Class<? extends Dataset> clazz) {
    323                if (BooleanDataset.class.isAssignableFrom(clazz) || ByteDataset.class.isAssignableFrom(clazz) || ShortDataset.class.isAssignableFrom(clazz)) {
    324                        return IntegerDataset.class;
    325                } else if (IntegerDataset.class.isAssignableFrom(clazz) || LongDataset.class.isAssignableFrom(clazz)) {
    326                        return LongDataset.class;
    327                } else if (FloatDataset.class.isAssignableFrom(clazz) || DoubleDataset.class.isAssignableFrom(clazz)) {
    328                        return DoubleDataset.class;
    329                } else if (ComplexFloatDataset.class.isAssignableFrom(clazz) || ComplexDoubleDataset.class.isAssignableFrom(clazz)) {
    330                        return ComplexDoubleDataset.class;
    331                } else if (CompoundByteDataset.class.isAssignableFrom(clazz) || CompoundShortDataset.class.isAssignableFrom(clazz)) {
    332                        return CompoundIntegerDataset.class;
    333                } else if (CompoundIntegerDataset.class.isAssignableFrom(clazz) || CompoundLongDataset.class.isAssignableFrom(clazz)) {
    334                        return CompoundLongDataset.class;
    335                } else if (CompoundFloatDataset.class.isAssignableFrom(clazz) || CompoundDoubleDataset.class.isAssignableFrom(clazz)) {
    336                        return CompoundDoubleDataset.class;
    337                }
    338
    339                return clazz;
    340        }
    341
    342        /**
    343         * @param dtype dataset type
    344         * @return elemental dataset type available for given dataset type
    345         */
    346        public static int getElementalDType(final int dtype) {
    347                switch (dtype) {
    348                case Dataset.COMPLEX64:
    349                        return Dataset.FLOAT32;
    350                case Dataset.COMPLEX128:
    351                        return Dataset.FLOAT64;
    352                case Dataset.ARRAYINT8:
    353                case Dataset.RGB8:
    354                        return Dataset.INT8;
    355                case Dataset.ARRAYINT16:
    356                case Dataset.RGB:
    357                        return Dataset.INT16;
    358                case Dataset.ARRAYINT32:
    359                        return Dataset.INT32;
    360                case Dataset.ARRAYINT64:
    361                        return Dataset.INT64;
    362                case Dataset.ARRAYFLOAT32:
    363                        return Dataset.FLOAT32;
    364                case Dataset.ARRAYFLOAT64:
    365                        return Dataset.FLOAT64;
    366                default:
    367                        return dtype;
    368                }
    369        }
    370
    371        /**
    372         * @param dtype dataset type
    373         * @return number of elements per item
    374         */
    375        public static int getElementsPerItem(final int dtype) {
    376                switch (dtype) {
    377                case Dataset.ARRAYINT8:
    378                case Dataset.ARRAYINT16:
    379                case Dataset.ARRAYINT32:
    380                case Dataset.ARRAYINT64:
    381                case Dataset.ARRAYFLOAT32:
    382                case Dataset.ARRAYFLOAT64:
    383                        throw new UnsupportedOperationException("Multi-element type unsupported");
    384                case Dataset.COMPLEX64:
    385                case Dataset.COMPLEX128:
    386                        return 2;
    387                case Dataset.RGB8:
    388                case Dataset.RGB:
    389                        return 3;
    390                }
    391                return 1;
    392        }
    393
    394        /**
    395         * @param dtype dataset type
    396         * @return length of single item in bytes
    397         */
    398        public static int getItemBytes(final int dtype) {
    399                return getItemBytes(dtype, getElementsPerItem(dtype));
    400        }
    401
    402        /**
    403         * @param dtype dataset type
    404         * @param isize
    405         *            number of elements in an item
    406         * @return length of single item in bytes
    407         */
    408        public static int getItemBytes(final int dtype, final int isize) {
    409                int size;
    410
    411                switch (dtype) {
    412                case Dataset.BOOL:
    413                        size = 1; // How is this defined?
    414                        break;
    415                case Dataset.INT8:
    416                case Dataset.ARRAYINT8:
    417                case Dataset.RGB8:
    418                        size = Byte.SIZE / 8;
    419                        break;
    420                case Dataset.INT16:
    421                case Dataset.ARRAYINT16:
    422                case Dataset.RGB:
    423                        size = Short.SIZE / 8;
    424                        break;
    425                case Dataset.INT32:
    426                case Dataset.ARRAYINT32:
    427                        size = Integer.SIZE / 8;
    428                        break;
    429                case Dataset.INT64:
    430                case Dataset.ARRAYINT64:
    431                        size = Long.SIZE / 8;
    432                        break;
    433                case Dataset.FLOAT32:
    434                case Dataset.ARRAYFLOAT32:
    435                case Dataset.COMPLEX64:
    436                        size = Float.SIZE / 8;
    437                        break;
    438                case Dataset.FLOAT64:
    439                case Dataset.ARRAYFLOAT64:
    440                case Dataset.COMPLEX128:
    441                        size = Double.SIZE / 8;
    442                        break;
    443                default:
    444                        size = 0;
    445                        break;
    446                }
    447
    448                return size * isize;
    449        }
    450
    451        /**
    452         * @param b input
    453         * @return converted boolean
    454         */
    455        public static boolean toBoolean(final Object b) {
    456                if (b instanceof Number) {
    457                        return ((Number) b).longValue() != 0;
    458                } else if (b instanceof Boolean) {
    459                        return ((Boolean) b).booleanValue();
    460                } else if (b instanceof Complex) {
    461                        return ((Complex) b).getReal() != 0;
    462                } else if (b instanceof Dataset) {
    463                        Dataset db = (Dataset) b;
    464                        if (db.getSize() != 1) {
    465                                logger.error("Given dataset must have only one item");
    466                                throw new IllegalArgumentException("Given dataset must have only one item");
    467                        }
    468                        return db.getBoolean();
    469                } else if (b instanceof IDataset) {
    470                        IDataset db = (IDataset) b;
    471                        if (db.getSize() != 1) {
    472                                logger.error("Given dataset must have only one item");
    473                                throw new IllegalArgumentException("Given dataset must have only one item");
    474                        }
    475                        return db.getBoolean(new int[db.getRank()]);
    476                } else {
    477                        logger.error("Argument is of unsupported class");
    478                        throw new IllegalArgumentException("Argument is of unsupported class");
    479                }
    480        }
    481
    482        /**
    483         * @param d value
    484         * @return returns a long or 0 if d is NaN or infinite
    485         * @since 2.1
    486         */
    487        public static final long toLong(double d) {
    488                if (Double.isInfinite(d) || Double.isNaN(d))
    489                        return 0l;
    490                return (long) d;
    491        }
    492
    493        /**
    494         * @param d value
    495         * @return returns a long or 0 if d is NaN or infinite
    496         * @since 2.1
    497         */
    498        public static final long toLong(float d) {
    499                if (Float.isInfinite(d) || Float.isNaN(d))
    500                        return 0l;
    501                return (long) d;
    502        }
    503
    504        /**
    505         * @param b input
    506         * @return converted long
    507         */
    508        public static long toLong(final Object b) {
    509                if (b instanceof Number) {
    510                        final Number n = (Number) b;
    511                        return (n instanceof Double || n instanceof Float) ? toLong(n.doubleValue()) : n.longValue();
    512                } else if (b instanceof Boolean) {
    513                        return ((Boolean) b).booleanValue() ? 1 : 0;
    514                } else if (b instanceof Complex) {
    515                        return (long) ((Complex) b).getReal();
    516                } else if (b instanceof Dataset) {
    517                        Dataset db = (Dataset) b;
    518                        if (db.getSize() != 1) {
    519                                logger.error("Given dataset must have only one item");
    520                                throw new IllegalArgumentException("Given dataset must have only one item");
    521                        }
    522                        return db.getLong();
    523                } else if (b instanceof IDataset) {
    524                        IDataset db = (IDataset) b;
    525                        if (db.getSize() != 1) {
    526                                logger.error("Given dataset must have only one item");
    527                                throw new IllegalArgumentException("Given dataset must have only one item");
    528                        }
    529                        return db.getLong(new int[db.getRank()]);
    530                } else {
    531                        logger.error("Argument is of unsupported class");
    532                        throw new IllegalArgumentException("Argument is of unsupported class");
    533                }
    534        }
    535
    536        /**
    537         * @param b input
    538         * @return real part of input
    539         */
    540        public static double toReal(final Object b) {
    541                if (b instanceof Number) {
    542                        return ((Number) b).doubleValue();
    543                } else if (b instanceof Boolean) {
    544                        return ((Boolean) b).booleanValue() ? 1 : 0;
    545                } else if (b instanceof Complex) {
    546                        return ((Complex) b).getReal();
    547                } else if (b.getClass().isArray()) {
    548                        if (Array.getLength(b) == 0)
    549                                return 0;
    550                        return toReal(Array.get(b, 0));
    551                } else if (b instanceof Dataset) {
    552                        Dataset db = (Dataset) b;
    553                        if (db.getSize() != 1) {
    554                                logger.error("Given dataset must have only one item");
    555                                throw new IllegalArgumentException("Given dataset must have only one item");
    556                        }
    557                        return db.getDouble();
    558                } else if (b instanceof IDataset) {
    559                        IDataset db = (Dataset) b;
    560                        if (db.getSize() != 1) {
    561                                logger.error("Given dataset must have only one item");
    562                                throw new IllegalArgumentException("Given dataset must have only one item");
    563                        }
    564                        return db.getDouble(new int[db.getRank()]);
    565                } else {
    566                        logger.error("Argument is of unsupported class");
    567                        throw new IllegalArgumentException("Argument is of unsupported class");
    568                }
    569        }
    570
    571        /**
    572         * @param b input
    573         * @return imaginary part of input
    574         */
    575        public static double toImag(final Object b) {
    576                if (b instanceof Number) {
    577                        return 0;
    578                } else if (b instanceof Boolean) {
    579                        return 0;
    580                } else if (b instanceof Complex) {
    581                        return ((Complex) b).getImaginary();
    582                } else if (b.getClass().isArray()) {
    583                        if (Array.getLength(b) < 2)
    584                                return 0;
    585                        return toReal(Array.get(b, 1));
    586                } else if (b instanceof Dataset) {
    587                        Dataset db = (Dataset) b;
    588                        if (db.getSize() != 1) {
    589                                logger.error("Given dataset must have only one item");
    590                                throw new IllegalArgumentException("Given dataset must have only one item");
    591                        }
    592                        return toImag(db.getObject());
    593                } else if (b instanceof IDataset) {
    594                        IDataset db = (Dataset) b;
    595                        if (db.getSize() != 1) {
    596                                logger.error("Given dataset must have only one item");
    597                                throw new IllegalArgumentException("Given dataset must have only one item");
    598                        }
    599                        return toImag(db.getObject(new int[db.getRank()]));
    600                } else {
    601                        logger.error("Argument is of unsupported class");
    602                        throw new IllegalArgumentException("Argument is of unsupported class");
    603                }
    604        }
    605
    606        /**
    607         * @param b input
    608         * @param itemSize item size
    609         * @return converted doubles
    610         */
    611        public static double[] toDoubleArray(final Object b, final int itemSize) {
    612                double[] result = null;
    613
    614                // ensure array is of given length
    615                if (b instanceof Number) {
    616                        result = new double[itemSize];
    617                        final double val = ((Number) b).doubleValue();
    618                        for (int i = 0; i < itemSize; i++) {
    619                                result[i] = val;
    620                        }
    621                } else if (b instanceof double[]) {
    622                        final double[] old = (double[]) b;
    623                        result = old;
    624                        final int ilen = old.length;
    625                        if (ilen < itemSize) {
    626                                result = new double[itemSize];
    627                                for (int i = 0; i < ilen; i++) {
    628                                        result[i] = old[i];
    629                                }
    630                        }
    631                } else if (b instanceof List<?>) {
    632                        result = new double[itemSize];
    633                        List<?> jl = (List<?>) b;
    634                        int ilen = jl.size();
    635                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    636                                logger.error("Given array was not of a numerical primitive type");
    637                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    638                        }
    639                        ilen = Math.min(itemSize, ilen);
    640                        for (int i = 0; i < ilen; i++) {
    641                                result[i] = toReal(jl.get(i));
    642                        }
    643                } else if (b.getClass().isArray()) {
    644                        result = new double[itemSize];
    645                        int ilen = Array.getLength(b);
    646                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    647                                logger.error("Given array was not of a numerical primitive type");
    648                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    649                        }
    650                        ilen = Math.min(itemSize, ilen);
    651                        for (int i = 0; i < ilen; i++) {
    652                                result[i] = ((Number) Array.get(b, i)).doubleValue();
    653                        }
    654                } else if (b instanceof Complex) {
    655                        if (itemSize > 2) {
    656                                logger.error("Complex number will not fit in compound dataset");
    657                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    658                        }
    659                        Complex cb = (Complex) b;
    660                        switch (itemSize) {
    661                        default:
    662                        case 0:
    663                                break;
    664                        case 1:
    665                                result = new double[] {cb.getReal()};
    666                                break;
    667                        case 2:
    668                                result = new double[] {cb.getReal(), cb.getImaginary()};
    669                                break;
    670                        }
    671                } else if (b instanceof Dataset) {
    672                        Dataset db = (Dataset) b;
    673                        if (db.getSize() != 1) {
    674                                logger.error("Given dataset must have only one item");
    675                                throw new IllegalArgumentException("Given dataset must have only one item");
    676                        }
    677                        return toDoubleArray(db.getObject(), itemSize);
    678                } else if (b instanceof IDataset) {
    679                        IDataset db = (Dataset) b;
    680                        if (db.getSize() != 1) {
    681                                logger.error("Given dataset must have only one item");
    682                                throw new IllegalArgumentException("Given dataset must have only one item");
    683                        }
    684                        return toDoubleArray(db.getObject(new int[db.getRank()]), itemSize);
    685                }
    686
    687                return result;
    688        }
    689
    690        /**
    691         * @param b input
    692         * @param itemSize item size
    693         * @return converted floats
    694         */
    695        public static float[] toFloatArray(final Object b, final int itemSize) {
    696                float[] result = null;
    697
    698                if (b instanceof Number) {
    699                        result = new float[itemSize];
    700                        final float val = ((Number) b).floatValue();
    701                        for (int i = 0; i < itemSize; i++)
    702                                result[i] = val;
    703                } else if (b instanceof float[]) {
    704                        final float[] old = (float[]) b;
    705                        result = old;
    706                        final int ilen = old.length;
    707                        if (ilen < itemSize) {
    708                                result = new float[itemSize];
    709                                for (int i = 0; i < ilen; i++) {
    710                                        result[i] = old[i];
    711                                }
    712                        }
    713                } else if (b instanceof double[]) {
    714                        final double[] old = (double[]) b;
    715                        final int ilen = Math.min(itemSize, old.length);
    716                        result = new float[itemSize];
    717                        for (int i = 0; i < ilen; i++) {
    718                                result[i] = (float) old[i];
    719                        }
    720                } else if (b instanceof List<?>) {
    721                        result = new float[itemSize];
    722                        List<?> jl = (List<?>) b;
    723                        int ilen = jl.size();
    724                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    725                                logger.error("Given array was not of a numerical primitive type");
    726                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    727                        }
    728                        ilen = Math.min(itemSize, ilen);
    729                        for (int i = 0; i < ilen; i++) {
    730                                result[i] = (float) toReal(jl.get(i));
    731                        }
    732                } else if (b.getClass().isArray()) {
    733                        result = new float[itemSize];
    734                        int ilen = Array.getLength(b);
    735                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    736                                logger.error("Given array was not of a numerical primitive type");
    737                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    738                        }
    739                        ilen = Math.min(itemSize, ilen);
    740                        for (int i = 0; i < ilen; i++) {
    741                                result[i] = ((Number) Array.get(b, i)).floatValue();
    742                        }
    743                } else if (b instanceof Complex) {
    744                        if (itemSize > 2) {
    745                                logger.error("Complex number will not fit in compound dataset");
    746                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    747                        }
    748                        Complex cb = (Complex) b;
    749                        switch (itemSize) {
    750                        default:
    751                        case 0:
    752                                break;
    753                        case 1:
    754                                result = new float[] {(float) cb.getReal()};
    755                                break;
    756                        case 2:
    757                                result = new float[] {(float) cb.getReal(), (float) cb.getImaginary()};
    758                                break;
    759                        }
    760                } else if (b instanceof Dataset) {
    761                        Dataset db = (Dataset) b;
    762                        if (db.getSize() != 1) {
    763                                logger.error("Given dataset must have only one item");
    764                                throw new IllegalArgumentException("Given dataset must have only one item");
    765                        }
    766                        return toFloatArray(db.getObject(), itemSize);
    767                } else if (b instanceof IDataset) {
    768                        IDataset db = (Dataset) b;
    769                        if (db.getSize() != 1) {
    770                                logger.error("Given dataset must have only one item");
    771                                throw new IllegalArgumentException("Given dataset must have only one item");
    772                        }
    773                        return toFloatArray(db.getObject(new int[db.getRank()]), itemSize);
    774                }
    775
    776                return result;
    777        }
    778
    779        /**
    780         * @param b input
    781         * @param itemSize item size
    782         * @return converted longs
    783         */
    784        public static long[] toLongArray(final Object b, final int itemSize) {
    785                long[] result = null;
    786
    787                if (b instanceof Number) {
    788                        result = new long[itemSize];
    789                        final long val = toLong(b);
    790                        for (int i = 0; i < itemSize; i++) {
    791                                result[i] = val;
    792                        }
    793                } else if (b instanceof long[]) {
    794                        final long[] old = (long[]) b;
    795                        result = old;
    796                        final int ilen = result.length;
    797                        if (ilen < itemSize) {
    798                                result = new long[itemSize];
    799                                for (int i = 0; i < ilen; i++) {
    800                                        result[i] = old[i];
    801                                }
    802                        }
    803                } else if (b instanceof double[]) {
    804                        final double[] old = (double[]) b;
    805                        final int ilen = Math.min(itemSize, old.length);
    806                        result = new long[itemSize];
    807                        for (int i = 0; i < ilen; i++) {
    808                                result[i] = toLong(old[i]);
    809                        }
    810                } else if (b instanceof List<?>) {
    811                        result = new long[itemSize];
    812                        List<?> jl = (List<?>) b;
    813                        int ilen = jl.size();
    814                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    815                                logger.error("Given array was not of a numerical primitive type");
    816                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    817                        }
    818                        ilen = Math.min(itemSize, ilen);
    819                        for (int i = 0; i < ilen; i++) {
    820                                result[i] = toLong(jl.get(i));
    821                        }
    822                } else if (b.getClass().isArray()) {
    823                        result = new long[itemSize];
    824                        int ilen = Array.getLength(b);
    825                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    826                                logger.error("Given array was not of a numerical primitive type");
    827                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    828                        }
    829                        ilen = Math.min(itemSize, ilen);
    830                        for (int i = 0; i < ilen; i++) {
    831                                result[i] = toLong(Array.get(b, i));
    832                        }
    833                } else if (b instanceof Complex) {
    834                        if (itemSize > 2) {
    835                                logger.error("Complex number will not fit in compound dataset");
    836                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    837                        }
    838                        Complex cb = (Complex) b;
    839                        switch (itemSize) {
    840                        default:
    841                        case 0:
    842                                break;
    843                        case 1:
    844                                result = new long[] {(long) cb.getReal()};
    845                                break;
    846                        case 2:
    847                                result = new long[] {(long) cb.getReal(), (long) cb.getImaginary()};
    848                                break;
    849                        }
    850                } else if (b instanceof Dataset) {
    851                        Dataset db = (Dataset) b;
    852                        if (db.getSize() != 1) {
    853                                logger.error("Given dataset must have only one item");
    854                                throw new IllegalArgumentException("Given dataset must have only one item");
    855                        }
    856                        return toLongArray(db.getObject(), itemSize);
    857                } else if (b instanceof IDataset) {
    858                        IDataset db = (Dataset) b;
    859                        if (db.getSize() != 1) {
    860                                logger.error("Given dataset must have only one item");
    861                                throw new IllegalArgumentException("Given dataset must have only one item");
    862                        }
    863                        return toLongArray(db.getObject(new int[db.getRank()]), itemSize);
    864                }
    865
    866                return result;
    867        }
    868
    869        /**
    870         * @param b input
    871         * @param itemSize item size
    872         * @return converted integers
    873         */
    874        public static int[] toIntegerArray(final Object b, final int itemSize) {
    875                int[] result = null;
    876
    877                if (b instanceof Number) {
    878                        result = new int[itemSize];
    879                        final int val = (int) toLong(b);
    880                        for (int i = 0; i < itemSize; i++) {
    881                                result[i] = val;
    882                        }
    883                } else if (b instanceof int[]) {
    884                        final int[] old = (int[]) b;
    885                        result = old;
    886                        final int ilen = result.length;
    887                        if (ilen < itemSize) {
    888                                result = new int[itemSize];
    889                                for (int i = 0; i < ilen; i++) {
    890                                        result[i] = old[i];
    891                                }
    892                        }
    893                } else if (b instanceof double[]) {
    894                        final double[] old = (double[]) b;
    895                        final int ilen = Math.min(itemSize, old.length);
    896                        result = new int[itemSize];
    897                        for (int i = 0; i < ilen; i++) {
    898                                result[i] = (int) toLong(old[i]);
    899                        }
    900                } else if (b instanceof List<?>) {
    901                        result = new int[itemSize];
    902                        List<?> jl = (List<?>) b;
    903                        int ilen = jl.size();
    904                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    905                                logger.error("Given array was not of a numerical primitive type");
    906                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    907                        }
    908                        ilen = Math.min(itemSize, ilen);
    909                        for (int i = 0; i < ilen; i++) {
    910                                result[i] = (int) toLong(jl.get(i));
    911                        }
    912                } else if (b.getClass().isArray()) {
    913                        result = new int[itemSize];
    914                        int ilen = Array.getLength(b);
    915                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    916                                logger.error("Given array was not of a numerical primitive type");
    917                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    918                        }
    919                        ilen = Math.min(itemSize, ilen);
    920                        for (int i = 0; i < ilen; i++) {
    921                                result[i] = (int) toLong(Array.get(b, i));
    922                        }
    923                } else if (b instanceof Complex) {
    924                        if (itemSize > 2) {
    925                                logger.error("Complex number will not fit in compound dataset");
    926                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    927                        }
    928                        Complex cb = (Complex) b;
    929                        switch (itemSize) {
    930                        default:
    931                        case 0:
    932                                break;
    933                        case 1:
    934                                result = new int[] {(int) cb.getReal()};
    935                                break;
    936                        case 2:
    937                                result = new int[] {(int) cb.getReal(), (int) cb.getImaginary()};
    938                                break;
    939                        }
    940                } else if (b instanceof Dataset) {
    941                        Dataset db = (Dataset) b;
    942                        if (db.getSize() != 1) {
    943                                logger.error("Given dataset must have only one item");
    944                                throw new IllegalArgumentException("Given dataset must have only one item");
    945                        }
    946                        return toIntegerArray(db.getObject(), itemSize);
    947                } else if (b instanceof IDataset) {
    948                        IDataset db = (Dataset) b;
    949                        if (db.getSize() != 1) {
    950                                logger.error("Given dataset must have only one item");
    951                                throw new IllegalArgumentException("Given dataset must have only one item");
    952                        }
    953                        return toIntegerArray(db.getObject(new int[db.getRank()]), itemSize);
    954                }
    955
    956                return result;
    957        }
    958
    959        /**
    960         * @param b input
    961         * @param itemSize item size
    962         * @return converted shorts
    963         */
    964        public static short[] toShortArray(final Object b, final int itemSize) {
    965                short[] result = null;
    966
    967                if (b instanceof Number) {
    968                        result = new short[itemSize];
    969                        final short val = (short) toLong(b);
    970                        for (int i = 0; i < itemSize; i++) {
    971                                result[i] = val;
    972                        }
    973                } else if (b instanceof short[]) {
    974                        final short[] old = (short[]) b;
    975                        result = old;
    976                        final int ilen = result.length;
    977                        if (ilen < itemSize) {
    978                                result = new short[itemSize];
    979                                for (int i = 0; i < ilen; i++) {
    980                                        result[i] = old[i];
    981                                }
    982                        }
    983                } else if (b instanceof double[]) {
    984                        final double[] old = (double[]) b;
    985                        final int ilen = Math.min(itemSize, old.length);
    986                        result = new short[itemSize];
    987                        for (int i = 0; i < ilen; i++) {
    988                                result[i] = (short) toLong(old[i]);
    989                        }
    990                } else if (b instanceof List<?>) {
    991                        result = new short[itemSize];
    992                        List<?> jl = (List<?>) b;
    993                        int ilen = jl.size();
    994                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    995                                logger.error("Given array was not of a numerical primitive type");
    996                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    997                        }
    998                        ilen = Math.min(itemSize, ilen);
    999                        for (int i = 0; i < ilen; i++) {
    1000                                result[i] = (short) toLong(jl.get(i));
    1001                        }
    1002                } else if (b.getClass().isArray()) {
    1003                        result = new short[itemSize];
    1004                        int ilen = Array.getLength(b);
    1005                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    1006                                logger.error("Given array was not of a numerical primitive type");
    1007                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    1008                        }
    1009                        ilen = Math.min(itemSize, ilen);
    1010                        for (int i = 0; i < ilen; i++) {
    1011                                result[i] = (short) toLong(Array.get(b, i));
    1012                        }
    1013                } else if (b instanceof Complex) {
    1014                        if (itemSize > 2) {
    1015                                logger.error("Complex number will not fit in compound dataset");
    1016                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    1017                        }
    1018                        Complex cb = (Complex) b;
    1019                        switch (itemSize) {
    1020                        default:
    1021                        case 0:
    1022                                break;
    1023                        case 1:
    1024                                result = new short[] {(short) cb.getReal()};
    1025                                break;
    1026                        case 2:
    1027                                result = new short[] {(short) cb.getReal(), (short) cb.getImaginary()};
    1028                                break;
    1029                        }
    1030                } else if (b instanceof Dataset) {
    1031                        Dataset db = (Dataset) b;
    1032                        if (db.getSize() != 1) {
    1033                                logger.error("Given dataset must have only one item");
    1034                                throw new IllegalArgumentException("Given dataset must have only one item");
    1035                        }
    1036                        return toShortArray(db.getObject(), itemSize);
    1037                } else if (b instanceof IDataset) {
    1038                        IDataset db = (Dataset) b;
    1039                        if (db.getSize() != 1) {
    1040                                logger.error("Given dataset must have only one item");
    1041                                throw new IllegalArgumentException("Given dataset must have only one item");
    1042                        }
    1043                        return toShortArray(db.getObject(new int[db.getRank()]), itemSize);
    1044                }
    1045
    1046                return result;
    1047        }
    1048
    1049        /**
    1050         * @param b input
    1051         * @param itemSize item size
    1052         * @return converted bytes
    1053         */
    1054        public static byte[] toByteArray(final Object b, final int itemSize) {
    1055                byte[] result = null;
    1056
    1057                if (b instanceof Number) {
    1058                        result = new byte[itemSize];
    1059                        final byte val = (byte) toLong(b);
    1060                        for (int i = 0; i < itemSize; i++) {
    1061                                result[i] = val;
    1062                        }
    1063                } else if (b instanceof byte[]) {
    1064                        final byte[] old = (byte[]) b;
    1065                        result = old;
    1066                        final int ilen = result.length;
    1067                        if (ilen < itemSize) {
    1068                                result = new byte[itemSize];
    1069                                for (int i = 0; i < ilen; i++) {
    1070                                        result[i] = old[i];
    1071                                }
    1072                        }
    1073                } else if (b instanceof double[]) {
    1074                        final double[] old = (double[]) b;
    1075                        final int ilen = Math.min(itemSize, old.length);
    1076                        result = new byte[itemSize];
    1077                        for (int i = 0; i < ilen; i++) {
    1078                                result[i] = (byte) toLong(old[i]);
    1079                        }
    1080                } else if (b instanceof List<?>) {
    1081                        result = new byte[itemSize];
    1082                        List<?> jl = (List<?>) b;
    1083                        int ilen = jl.size();
    1084                        if (ilen > 0 && !(jl.get(0) instanceof Number)) {
    1085                                logger.error("Given array was not of a numerical primitive type");
    1086                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    1087                        }
    1088                        ilen = Math.min(itemSize, ilen);
    1089                        for (int i = 0; i < ilen; i++) {
    1090                                result[i] = (byte) toLong(jl.get(i));
    1091                        }
    1092                } else if (b.getClass().isArray()) {
    1093                        result = new byte[itemSize];
    1094                        int ilen = Array.getLength(b);
    1095                        if (ilen > 0 && !(Array.get(b, 0) instanceof Number)) {
    1096                                logger.error("Given array was not of a numerical primitive type");
    1097                                throw new IllegalArgumentException("Given array was not of a numerical primitive type");
    1098                        }
    1099                        ilen = Math.min(itemSize, ilen);
    1100                        for (int i = 0; i < ilen; i++) {
    1101                                result[i] = (byte) toLong(Array.get(b, i));
    1102                        }
    1103                } else if (b instanceof Complex) {
    1104                        if (itemSize > 2) {
    1105                                logger.error("Complex number will not fit in compound dataset");
    1106                                throw new IllegalArgumentException("Complex number will not fit in compound dataset");
    1107                        }
    1108                        Complex cb = (Complex) b;
    1109                        switch (itemSize) {
    1110                        default:
    1111                        case 0:
    1112                                break;
    1113                        case 1:
    1114                                result = new byte[] {(byte) cb.getReal()};
    1115                                break;
    1116                        case 2:
    1117                                result = new byte[] {(byte) cb.getReal(), (byte) cb.getImaginary()};
    1118                                break;
    1119                        }
    1120                } else if (b instanceof Dataset) {
    1121                        Dataset db = (Dataset) b;
    1122                        if (db.getSize() != 1) {
    1123                                logger.error("Given dataset must have only one item");
    1124                                throw new IllegalArgumentException("Given dataset must have only one item");
    1125                        }
    1126                        return toByteArray(db.getObject(), itemSize);
    1127                } else if (b instanceof IDataset) {
    1128                        IDataset db = (Dataset) b;
    1129                        if (db.getSize() != 1) {
    1130                                logger.error("Given dataset must have only one item");
    1131                                throw new IllegalArgumentException("Given dataset must have only one item");
    1132                        }
    1133                        return toByteArray(db.getObject(new int[db.getRank()]), itemSize);
    1134                }
    1135
    1136                return result;
    1137        }
    1138
    1139        /**
    1140         * @param x input
    1141         * @param dtype dataset type primitive array
    1142         * @return array of biggest primitives
    1143         */
    1144        public static Object fromDoublesToBiggestPrimitives(double[] x, int dtype) {
    1145                switch (dtype) {
    1146                case Dataset.BOOL:
    1147                case Dataset.INT8:
    1148                case Dataset.INT16:
    1149                case Dataset.INT32:
    1150                        int[] i32 = new int[x.length];
    1151                        for (int i = 0; i < x.length; i++)
    1152                                i32[i] = (int) (long) x[i];
    1153                        return i32;
    1154                case Dataset.INT64:
    1155                        long[] i64 = new long[x.length];
    1156                        for (int i = 0; i < x.length; i++)
    1157                                i64[i] = (long) x[i];
    1158                        return i64;
    1159                case Dataset.FLOAT32:
    1160                        float[] f32 = new float[x.length];
    1161                        for (int i = 0; i < x.length; i++)
    1162                                f32[i] = (float) x[i];
    1163                        return f32;
    1164                case Dataset.FLOAT64:
    1165                        return x;
    1166                }
    1167                return null;
    1168        }
    1169
    1170        /**
    1171         * @param dtype dataset type
    1172         * @return (boxed) class of constituent element
    1173         */
    1174        public static Class<?> getElementClass(final int dtype) {
    1175                switch (dtype) {
    1176                case Dataset.BOOL:
    1177                        return Boolean.class;
    1178                case Dataset.INT8:
    1179                case Dataset.ARRAYINT8:
    1180                case Dataset.RGB8:
    1181                        return Byte.class;
    1182                case Dataset.INT16:
    1183                case Dataset.ARRAYINT16:
    1184                case Dataset.RGB:
    1185                        return Short.class;
    1186                case Dataset.INT32:
    1187                case Dataset.ARRAYINT32:
    1188                        return Integer.class;
    1189                case Dataset.INT64:
    1190                case Dataset.ARRAYINT64:
    1191                        return Long.class;
    1192                case Dataset.FLOAT32:
    1193                case Dataset.ARRAYFLOAT32:
    1194                        return Float.class;
    1195                case Dataset.FLOAT64:
    1196                case Dataset.ARRAYFLOAT64:
    1197                        return Double.class;
    1198                case Dataset.COMPLEX64:
    1199                        return Float.class;
    1200                case Dataset.COMPLEX128:
    1201                        return Double.class;
    1202                case Dataset.STRING:
    1203                        return String.class;
    1204                case Dataset.DATE:
    1205                        return Date.class;
    1206                }
    1207                return Object.class;
    1208        }
    1209
    1210        /**
    1211         * @param dtype dataset type
    1212         * @return dataset interface can be null
    1213         * @since 2.3
    1214         */
    1215        public static Class<? extends Dataset> getInterface(final int dtype) {
    1216                return dtype2Interface.get(dtype);
    1217        }
    1218
    1219        /**
    1220         * @param x value
    1221         * @param dtype dataset type
    1222         * @return biggest native primitive if integer (should test for 64bit?)
    1223         * @since 2.2
    1224         */
    1225        public static Number fromDoubleToBiggestNumber(double x, int dtype) {
    1226                switch (dtype) {
    1227                case Dataset.BOOL:
    1228                case Dataset.INT8:
    1229                case Dataset.INT16:
    1230                case Dataset.INT32:
    1231                        return Integer.valueOf((int) (long) x);
    1232                case Dataset.INT64:
    1233                        return Long.valueOf((long) x);
    1234                case Dataset.FLOAT32:
    1235                        return Float.valueOf((float) x);
    1236                case Dataset.FLOAT64:
    1237                        return Double.valueOf(x);
    1238                }
    1239                return null;
    1240        }
    1241
    1242        /**
    1243         * @param clazz element class
    1244         * @return true if supported
    1245         * @deprecated Use {@link InterfaceUtils#isElementSupported(Class)}
    1246         */
    1247        @Deprecated
    1248        public static boolean isClassSupportedAsElement(Class<? extends Object> clazz) {
    1249                return InterfaceUtils.isElementSupported(clazz);
    1250        }
    1251
    1252        /**
    1253         * @param b input
    1254         * @return length of object
    1255         */
    1256        public static final int getLength(final Object b) {
    1257                if (b instanceof Number) {
    1258                        return 1;
    1259                } else if (b instanceof Complex) {
    1260                        return 1;
    1261                } else if (b instanceof List<?>) {
    1262                        List<?> jl = (List<?>) b;
    1263                        return jl.size();
    1264                } else if (b.getClass().isArray()) {
    1265                        return Array.getLength(b);
    1266                } else if (b instanceof IDataset) {
    1267                        IDataset db = (Dataset) b;
    1268                        return db.getSize();
    1269                }
    1270
    1271                throw new IllegalArgumentException("Cannot find length as object not supported");
    1272        }
    1273
    1274        /**
    1275         * @param a input
    1276         * @return name of dataset interface
    1277         * @since 2.3
    1278         */
    1279        public static String getDatasetName(Dataset a) {
    1280                return getDatasetName(a.getClass(), a.getElementsPerItem());
    1281        }
    1282
    1283        /**
    1284         * @param a input
    1285         * @return name of dataset interface
    1286         * @since 2.3
    1287         */
    1288        public static String getDatasetName(ILazyDataset a) {
    1289                if (a instanceof Dataset) {
    1290                        return getDatasetName((Dataset) a);
    1291                }
    1292                int isize = a.getElementsPerItem();
    1293                return getDatasetName(InterfaceUtils.getInterfaceFromClass(isize, a.getElementClass()), isize);
    1294        }
    1295
    1296        /**
    1297         * @param clazz dataset interface
    1298         * @param itemSize item size
    1299         * @return name of dataset interface
    1300         * @since 2.3
    1301         */
    1302        public static String getDatasetName(final Class<? extends Dataset> clazz, int itemSize) {
    1303                int bytes = InterfaceUtils.getItemBytes(1, clazz);
    1304                if (InterfaceUtils.isComplex(clazz)) {
    1305                        return "COMPLEX" + bytes*16;
    1306                } else if (RGBByteDataset.class.isAssignableFrom(clazz)) {
    1307                        return "RGB8";
    1308                } else if (RGBDataset.class.isAssignableFrom(clazz)) {
    1309                        return "RGB";
    1310                }
    1311
    1312                String prefix = itemSize > 1 ? ("ARRAY of " + itemSize + " ") : "";
    1313                if (InterfaceUtils.isFloating(clazz)) {
    1314                        return prefix + "FLOAT" + bytes*8;
    1315                }
    1316                if (BooleanDataset.class.isAssignableFrom(clazz)) {
    1317                        return prefix + "BOOLEAN";
    1318                }
    1319                if (StringDataset.class.isAssignableFrom(clazz)) {
    1320                        return prefix + "STRING";
    1321                }
    1322                if (DateDataset.class.isAssignableFrom(clazz)) {
    1323                        return prefix + "DATE";
    1324                }
    1325                if (ObjectDataset.class.isAssignableFrom(clazz)) {
    1326                        return prefix + "OBJECT";
    1327                }
    1328
    1329                return prefix + "INT" + bytes*8;
    1330        }
    1331}