diff --git a/src/firefly/java/edu/caltech/ipac/astro/FITSTableReader.java b/src/firefly/java/edu/caltech/ipac/astro/FITSTableReader.java index af117536f6..75a6b1388b 100644 --- a/src/firefly/java/edu/caltech/ipac/astro/FITSTableReader.java +++ b/src/firefly/java/edu/caltech/ipac/astro/FITSTableReader.java @@ -3,6 +3,8 @@ */ package edu.caltech.ipac.astro; +import edu.caltech.ipac.firefly.server.util.Logger; +import edu.caltech.ipac.firefly.util.DataSetParser; import edu.caltech.ipac.util.DataGroup; import edu.caltech.ipac.util.DataObject; import edu.caltech.ipac.util.DataType; @@ -13,24 +15,32 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; /** * Convert an FITS file or FITS binary table(s) to list of DataGroup. */ public final class FITSTableReader { + private static final Logger.LoggerImpl logger = Logger.getLogger(); + public static boolean debug = true; /** - * Declare the strategies to handle the FITS data: + * Strategies to handle FITS data with column-repeat-count greater than 1(TFORMn = rT): + * where n = column index, T = data type, r = repeat count + * + * DEFAULT: Set DataType to 'ary'. Store the full array in DataGroup as an object. + * When DataGroup is written out into IPAC format, it should only describe the data + * as type = 'char' and value as type[length]. This is the default strategy if not given. * * TOP_MOST: Ignore the repeat count portion of the TFORMn Keyword * returning only the first datum of the field, even if repeat count is more than 1. - * This should produce exactly one DataGroup per table. This is the default strategy if not given. + * This should produce exactly one DataGroup per table. + * + * * + * ( experiemental.. not sure how it would be use ) * FULLY_FLATTEN: Generates one DataGroup row for each value of an HDU field. * Because each field may have different repeat count (dimension), insert blank * when no data is available. This should produce exactly one DataGroup per table. @@ -39,10 +49,11 @@ public final class FITSTableReader * EXPAND_BEST_FIT: Expands each HDU row into one DataGroup. Fields with lesser count (dimension) will be filled with blanks. * EXPAND_REPEAT: Expands each HDU row into one DataGroup. Fields with lesser dimension will be filled with previous values. */ - private static final String TOP_MOST = "TOP_MOST"; - private static final String EXPAND_BEST_FIT = "EXPAND_BEST_FIT"; - private static final String EXPAND_REPEAT = "EXPAND_REPEAT"; - private static final String FULLY_FLATTEN = "FULLY_FLATTEN"; + public static final String DEFAULT = "DEFAULT"; + public static final String TOP_MOST = "TOP_MOST"; + public static final String FULLY_FLATTEN = "FULLY_FLATTEN"; + public static final String EXPAND_BEST_FIT = "EXPAND_BEST_FIT"; + public static final String EXPAND_REPEAT = "EXPAND_REPEAT"; private static final int maxNumAttributeValues = 80; @@ -140,7 +151,7 @@ else if (strategy == FULLY_FLATTEN) { try { //List dgList = fits_to_ipac.convertFITSToDataGroup(fits_filename, null); - List dgList = fits_to_ipac.convertFitsToDataGroup(fits_filename, null, null, "TOP_MOST"); + List dgList = fits_to_ipac.convertFitsToDataGroup(fits_filename, null, null, TOP_MOST); File output_file = new File(ipac_filename); DataGroup dg = dgList.get(0); @@ -185,8 +196,8 @@ public static List convertFitsToDataGroup(String fits_filename, //for (int i = 4; i < tList.size(); i++) { for (int i = 0; i < tList.size(); i++) { StarTable table = (StarTable) tList.get(i); - List dgList = convertFitsToDataGroup(table, dataCols, headerCols, strategy); - dgListTotal.addAll(dgList); + DataGroup dataGroup = convertStarTableToDataGroup(table, dataCols, headerCols, strategy); + dgListTotal.add(dataGroup); } return dgListTotal; } @@ -226,150 +237,116 @@ public static List convertFitsToDataGroup(int index, */ - /** Convert a binary table (StarTable) into a list of DataGroup. + /** + * Convert a StarTable into DataGroup(s). Depending on the strategy, this function may return + * more then one DataGroup. * @param table input StarTable from one HDU - * @param dataCols: The names of the columns which will be copied to the data section of the DataGroups. - * If dataCols = null, get all the columns into the data group. - * @param headerCols: The names of the columns which will be copied to the header section of the DataGroups. - * If headerCols = null, get none of the columns into the header of the data group. - * @param strategy A list of strategies used to deal with the repeat count (dimension) of the data in the given dataCols columns. + * @param inclCols: The names of the columns to include in the DataGroups. + * If inclCols = null, includes all the columns into the DataGroup. + * @param inclHeaders: The names of the headers to include in the DataGroups. + * If inclHeaders = null, includes all headers into the DataGroup. + * @param strategy The strategy used to deal with column(s) with repeat count (dimension) > 1. * @return List A list of DataGroups */ - public static List convertFitsToDataGroup(StarTable table, - String[] dataCols, - String[] headerCols, - String strategy) - throws FitsException, TableFormatException, IllegalArgumentException, IOException { - if ((strategy == null) || - (!(strategy.equals(FULLY_FLATTEN)) && !(strategy.equals(EXPAND_BEST_FIT)) && !(strategy.equals(EXPAND_REPEAT)))){ - strategy = TOP_MOST; + /** + * + * @param table + * @param inclCols + * @param inclHeaders + * @param strategy + * @return + * @throws FitsException + * @throws IllegalArgumentException + * @throws IOException + */ + public static DataGroup convertStarTableToDataGroup(StarTable table, + String[] inclCols, + String[] inclHeaders, + String strategy) + throws FitsException, IllegalArgumentException, IOException { + + if (strategy == null) { + strategy = DEFAULT; } - int nColumns = table.getColumnCount(); - long nRows = table.getRowCount(); - String tableName = table.getName(); - - //Handle the data types: - List columnInfoList = new ArrayList(nColumns); - String colName[] = new String[nColumns]; - int[] repeats = new int[nColumns]; - int maxRepeat = 0; - List dataTypeList = new ArrayList(); + //creating DataType list ... column info + ArrayList dataTypes = new ArrayList<>(); + LinkedHashMap colIdxMap = new LinkedHashMap<>(); + List colList = inclCols == null ? null : Arrays.asList(inclCols); - for (int col = 0; col < nColumns; col++) { + for (int col = 0; col < table.getColumnCount(); col++) { ColumnInfo colInfo = table.getColumnInfo(col); - colName[col] = colInfo.getName(); - columnInfoList.add(colInfo); - if (colInfo.getShape() != null) { - repeats[col] = colInfo.getShape()[0]; - } else { - repeats[col] = 1; - } - if ((dataCols == null) || (Arrays.asList(dataCols).contains(colName[col]))){ - if (repeats[col] > maxRepeat) { - maxRepeat = repeats[col]; + if ( colList == null || colList.contains(colInfo.getName() ) ) { + DataType dt = convertToDataType(colInfo, strategy); + if ( StringUtils.isEmpty(dt.getShortDesc()) ) { + // fill in column's description if not given + DescribedValue p = table.getParameterByName("TDOC" + (col+1)); // this is for LSST.. not sure it applies to others. + if (p != null) { + dt.setShortDesc(p.getValueAsString(200)); + table.getParameters().remove(p); + } } - dataTypeList.add(convertToDataType(colInfo)); + + dataTypes.add(dt); + colIdxMap.put(colInfo, col); } } - //Build the data objects and put them into the data groups: - List dataGroupList = new ArrayList(); - if (strategy.equals(TOP_MOST)) { - /** - * "TOP_MOST": Ignore the repeat count portion of the TFORMn Keyword - * returning only the first datum of the field, even if repeat count is more than 1. - * This should produce exactly one DataGroup per table. This is the default strategy if not given. - */ - - // One data group per table: - DataGroup dataGroup = new DataGroup(tableName, dataTypeList); - for (long row = 0; row < nRows; row++){ - dataGroup = fillDataGroup(table, dataTypeList, maxRepeat, row, dataCols, strategy, dataGroup); + // creating DataGroup rows. + DataGroup dataGroup = new DataGroup(table.getName(), dataTypes); + for (long row = 0; row < table.getRowCount(); row++){ + addRowToDataGroup(table, dataGroup, colIdxMap, row, strategy); + } + + // setting DataGroup meta info + for(DataType dt : dataTypes) { + if (!StringUtils.isEmpty(dt.getShortDesc())) { + dataGroup.addAttribute(DataSetParser.makeAttribKey(DataSetParser.DESC_TAG, dt.getKeyName()), dt.getShortDesc()); } + } - // Add attributes to dataGroup: - for (int col = 0; col < nColumns; col++) { - if ((headerCols != null) && (Arrays.asList(headerCols).contains(colName[col]))) { - ColumnInfo colInfo = columnInfoList.get(col); - boolean isArray = colInfo.isArray(); - String classType = DefaultValueInfo.formatClass(colInfo.getContentClass()); //Q: need it? - String originalType = (String)((DescribedValue)colInfo.getAuxData().get(0)).getValue(); - List data = new ArrayList(); - for (long row = 0; row < nRows; row ++) { - Object cell = table.getCell(row, col); - if (isArray){ - data.add(Array.get(cell, 0)); - } - else { - data.add(cell); - } + List hdList = inclHeaders == null ? null : Arrays.asList(inclHeaders); + List params = table.getParameters(); + if (params != null) { + for (Object p : params) { + if (p instanceof DescribedValue) { + DescribedValue dv = (DescribedValue) p; + String n = dv.getInfo().getName(); + String v = dv.getValueAsString(200); + if (hdList == null || hdList.contains(n)) { + dataGroup.addAttribute(n, v); } - String attributeValue = getAttributeValue(data.toArray(), true, classType, originalType); - dataGroup.addAttribute(colName[col], attributeValue); } } + } + dataGroup.shrinkToFitData(); + return dataGroup; + } - // Add the dataGroup to the dataGroupList: - dataGroupList.add(dataGroup); - - } else if (strategy.equals(FULLY_FLATTEN)) { - /** - * FULLY_FLATTEN: Generates one DataGroup row for each value of an HDU field. - * Because each field may have different repeat count (dimension), insert blank - * when no data is available. This should produce exactly one DataGroup per table. - * - * No attribute data added to DataGroup for FULLY_FLATTEN. - */ - - if (!(headerCols == null)) { - throw new IllegalArgumentException("If the strategy is FULLY_FLATTEN, please define headerCols as null, as no attribute data will be written out."); - } - - // define one whole data group per table: - DataGroup dataGroup = new DataGroup(tableName, dataTypeList); - - for (long row = 0; row < nRows; row++) { - // Fill the data into the dataGroup: - dataGroup = fillDataGroup(table, dataTypeList, maxRepeat, row, dataCols, strategy, dataGroup); - } - - //Only one dataGroup for each table: - dataGroupList.add(dataGroup); - - } else if ((strategy.equals(EXPAND_BEST_FIT)) || strategy.equals(EXPAND_REPEAT)) { - /** - * EXPAND_BEST_FIT: Expands each HDU row into one DataGroup. Fields with lesser count (dimension) will be filled with blanks. - * EXPAND_REPEAT: Expands each HDU row into one DataGroup. Fields with lesser dimension will be filled with previous values. - */ - - for (int row = 0; row < nRows; row++) { - // define dataGroup per row: - String dgTitle = tableName + " Row #: " + row; - - //One data group per row: - DataGroup dataGroup = new DataGroup(dgTitle, dataTypeList); - dataGroup = fillDataGroup(table, dataTypeList, maxRepeat, row, dataCols, strategy, dataGroup); - - // Add attributes to dataGroup: - for (int col = 0; col < nColumns; col++) { - if ((headerCols != null) && (Arrays.asList(headerCols).contains(colName[col]))) { - ColumnInfo colInfo = columnInfoList.get(col); - boolean isArray = colInfo.isArray(); - String classType = DefaultValueInfo.formatClass(colInfo.getContentClass()); //Q: need it? - String originalType = (String)((DescribedValue)colInfo.getAuxData().get(0)).getValue(); - Object cell = table.getCell(row, col); - String attributeValue = getAttributeValue(cell, isArray, classType, originalType); - dataGroup.addAttribute(colName[col], attributeValue); + private static void addRowToDataGroup(StarTable table, DataGroup dataGroup, LinkedHashMap colIdxMap, long rowIdx, String strategy) { + DataObject aRow = new DataObject(dataGroup); + ColumnInfo[] colAry = colIdxMap.keySet().toArray(new ColumnInfo[colIdxMap.size()]); + try { + for (int dtIdx = 0; dtIdx < dataGroup.getDataDefinitions().length; dtIdx++) { + DataType dt = dataGroup.getDataDefinitions()[dtIdx]; + ColumnInfo colInfo = colAry[dtIdx]; + int colIdx = colIdxMap.get(colInfo); + Object data = table.getCell(rowIdx, colIdx); + if (colInfo.isArray()) { + if (Objects.equals(strategy, DEFAULT)) { + String desc = DefaultValueInfo.formatClass(colInfo.getContentClass()); + data = desc.replace("[]", "[" + Array.getLength(data) + "]"); + } else if (Objects.equals(strategy, TOP_MOST)) { + data = Array.get(data, 0); } } - - //one data group per row; add to the list. - dataGroupList.add(dataGroup); + aRow.setDataElement(dt, data); } + dataGroup.add(aRow); + } catch (IOException e) { + logger.error("Unable to read StarTable row:" + rowIdx + " msg:" + e.getMessage()); } - return dataGroupList; } /** @@ -384,28 +361,24 @@ public static List convertFitsToDataGroup(StarTable table, * Set unit. * * @param colInfo + * @param strategy * @return dataType * @throws FitsException */ - public static DataType convertToDataType (ColumnInfo colInfo) + public static DataType convertToDataType(ColumnInfo colInfo, String strategy) throws FitsException{ String colName = colInfo.getName(); String classType = DefaultValueInfo.formatClass(colInfo.getContentClass()); String originalType = (String)((DescribedValue)colInfo.getAuxData().get(0)).getValue(); String unit = colInfo.getUnitString(); + String nullString = null; DataType dataType = new DataType(colName, null); Class java_class = null; if ((classType.contains("boolean")) || (classType.contains("Boolean"))) { - if (originalType.contains("L")) { - //Logical: - java_class = String.class; - } else if (originalType.contains("X")) { - //Bits: - java_class = Integer.class; - } + java_class = Boolean.class; } else if ((classType.contains("byte")) || (classType.contains("Byte"))) { java_class = Integer.class; } else if ((classType.contains("short")) || (classType.contains("Short"))) { @@ -416,16 +389,26 @@ public static DataType convertToDataType (ColumnInfo colInfo) java_class = Long.class; } else if ((classType.contains("float")) || (classType.contains("Float"))) { java_class = Float.class; + nullString = "NaN"; } else if ((classType.contains("double")) || (classType.contains("Double"))) { java_class = Double.class; + nullString = "NaN"; } else if ((classType.contains("char")) || (classType.contains("String"))) { java_class = String.class; } else { throw new FitsException( "Unrecognized format character in FITS table file: " + classType); } + + if (Objects.equals(strategy, DEFAULT) && colInfo.isArray()) { + java_class = String.class; + } + dataType.setDataType(java_class); dataType.setUnits(unit); + dataType.setNullString(nullString); + dataType.setShortDesc(colInfo.getDescription()); + return dataType; } diff --git a/src/firefly/java/edu/caltech/ipac/astro/IpacTableReader.java b/src/firefly/java/edu/caltech/ipac/astro/IpacTableReader.java index bad5e450e5..57fe523097 100644 --- a/src/firefly/java/edu/caltech/ipac/astro/IpacTableReader.java +++ b/src/firefly/java/edu/caltech/ipac/astro/IpacTableReader.java @@ -44,6 +44,7 @@ public final class IpacTableReader { "r", "float", "f"}; private static final String INT_TYPE[]= { "int.*", "i"} ; private static final String LONG_TYPE[]= { "long", "l"} ; + private static final String BOOL_TYPE[]= { "bool", "b"} ; private static final String STRING_TYPE[]= {"cha.*", "str.*", "s", "c"}; private String _line; // to keep the line read from file @@ -513,6 +514,10 @@ else if (itc._type!=null && ServerStringUtil.matchesRegExpList(itc._type, LONG_TYPE, true)) { itc._foundType= Long.class; } + else if (itc._type!=null && + ServerStringUtil.matchesRegExpList(itc._type, BOOL_TYPE, true)) { + itc._foundType= Boolean.class; + } else { itc._foundType= String.class; } @@ -665,6 +670,7 @@ public static boolean isRecongnizedType(String type) { return ServerStringUtil.matchesRegExpList(type, DOUBLE_TYPE, true) || ServerStringUtil.matchesRegExpList(type, INT_TYPE, true) || ServerStringUtil.matchesRegExpList(type, LONG_TYPE, true) || + ServerStringUtil.matchesRegExpList(type, BOOL_TYPE, true) || ServerStringUtil.matchesRegExpList(type, STRING_TYPE, true); } @@ -675,6 +681,8 @@ public static Class resolveClass(String type) { return Integer.class; } else if ( ServerStringUtil.matchesRegExpList(type, LONG_TYPE, true) ) { return Long.class; + } else if ( ServerStringUtil.matchesRegExpList(type, BOOL_TYPE, true) ) { + return Boolean.class; } return String.class; } diff --git a/src/firefly/java/edu/caltech/ipac/firefly/data/TableServerRequest.java b/src/firefly/java/edu/caltech/ipac/firefly/data/TableServerRequest.java index 994c86a1bf..125a73635b 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/data/TableServerRequest.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/data/TableServerRequest.java @@ -27,6 +27,7 @@ public class TableServerRequest extends ServerRequest implements Serializable, D public static final String META_INFO = "META_INFO"; public static final String SYS_PARAMS = "|" + StringUtils.toString(new String[]{FILTERS,SORT_INFO,PAGE_SIZE,START_IDX,INCL_COLUMNS,FIXED_LENGTH,META_INFO,TBL_ID,DECIMATE_INFO}, "|") + "|"; + public static final String TBL_INDEX = "tbl_index"; // the table to show if it's a multi-table file. private int pageSize; private int startIdx; diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTablePartProcessor.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTablePartProcessor.java index 029c7c6542..0f791b97a4 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTablePartProcessor.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTablePartProcessor.java @@ -619,6 +619,7 @@ protected static void writeLine(BufferedWriter writer, String text) throws IOExc protected static File convertToIpacTable(File tblFile, TableServerRequest request) throws IOException, DataAccessException{ // if the file is not in IPAC table format - convert DataGroupReader.Format format = DataGroupReader.guessFormat(tblFile); + int tblIdx = request.getIntParam(TableServerRequest.TBL_INDEX, 0); boolean isFixedLength = request.getBooleanParam(TableServerRequest.FIXED_LENGTH, true); if (format == DataGroupReader.Format.IPACTABLE && isFixedLength) { // file is already in ipac table format @@ -626,7 +627,7 @@ protected static File convertToIpacTable(File tblFile, TableServerRequest reques } else { if ( format != DataGroupReader.Format.UNKNOWN) { // format is unknown.. convert it into ipac table format - DataGroup dg = DataGroupReader.readAnyFormat(tblFile); + DataGroup dg = DataGroupReader.readAnyFormat(tblFile, tblIdx); File convertedFile; //= createFile(request, ".tbl"); if (format == DataGroupReader.Format.IPACTABLE) { convertedFile = FileUtil.createUniqueFileFromFile(tblFile); @@ -636,7 +637,7 @@ protected static File convertToIpacTable(File tblFile, TableServerRequest reques convertedFile = FileUtil.createUniqueFileFromFile(convertedFile); } - DataGroupWriter.write(convertedFile, dg, 0); + DataGroupWriter.write(convertedFile, dg, 0, request.getMeta()); return convertedFile; } else { throw new DataAccessException("Source file has an unknown format:" + ServerContext.replaceWithPrefix(tblFile)); diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java index 68bf15fce2..7fc2937681 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java @@ -28,6 +28,7 @@ public class IpacTableFromSource extends IpacTablePartProcessor { public static final String TBL_TYPE = "tblType"; public static final String TYPE_CATALOG = "catalog"; + public static final String TBL_INDEX = TableServerRequest.TBL_INDEX; // the table to show if it's a multi-table file. protected File loadDataFile(TableServerRequest request) throws IOException, DataAccessException { diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/DataGroupReader.java b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/DataGroupReader.java index 5dd92a619e..1a8225715f 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/DataGroupReader.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/DataGroupReader.java @@ -34,6 +34,10 @@ public static enum Format { TSV(CSVFormat.TDF), CSV(CSVFormat.DEFAULT), IPACTABL } public static DataGroup readAnyFormat(File inf) throws IOException { + return readAnyFormat(inf, 0); + } + + public static DataGroup readAnyFormat(File inf, int tableIndex) throws IOException { Format format = guessFormat(inf); if (format == Format.IPACTABLE) { return read(inf, false, false); @@ -42,10 +46,9 @@ public static DataGroup readAnyFormat(File inf) throws IOException { } else if (format == Format.FITS ) { try { // Switch to the new function: - //List retval = FITSTableReader.convertFITSToDataGroup(inf.getAbsolutePath(), null); - List retval = FITSTableReader.convertFitsToDataGroup(inf.getAbsolutePath(), null, null, "TOP_MOST"); + List retval = FITSTableReader.convertFitsToDataGroup(inf.getAbsolutePath(), null, null, FITSTableReader.DEFAULT); if (retval != null && retval.size() > 0) { - return retval.get(0); + return retval.get(tableIndex); } else { return null; } diff --git a/src/firefly/java/edu/caltech/ipac/util/DataGroup.java b/src/firefly/java/edu/caltech/ipac/util/DataGroup.java index dce7569e9c..f91b9d13cf 100644 --- a/src/firefly/java/edu/caltech/ipac/util/DataGroup.java +++ b/src/firefly/java/edu/caltech/ipac/util/DataGroup.java @@ -140,7 +140,12 @@ public void shrinkToFitData(boolean force) { int maxDataWidth = dt.getMaxDataWidth(); if (force || maxDataWidth == 0) { for (DataObject row : this) { - int vlength = Number.class.isAssignableFrom(dt.getDataType()) ? row.getFormatedData(dt).length() : String.valueOf(row.getDataElement(dt)).length(); + int vlength = 0; + if (Number.class.isAssignableFrom(dt.getDataType())) { + vlength = dt.getFormatInfo().formatDataOnly(row.getDataElement(dt)).length(); + } else { + vlength = String.valueOf(row.getDataElement(dt)).length(); + } maxDataWidth = Math.max(maxDataWidth, vlength); } } diff --git a/src/firefly/java/edu/caltech/ipac/util/DataType.java b/src/firefly/java/edu/caltech/ipac/util/DataType.java index 951fbf25d3..01ff351679 100644 --- a/src/firefly/java/edu/caltech/ipac/util/DataType.java +++ b/src/firefly/java/edu/caltech/ipac/util/DataType.java @@ -17,11 +17,13 @@ public enum Importance { HIGH, MEDIUM, LOW, IGNORE} private static final String INTEGER = "int"; private static final String LONG = "long"; private static final String CHAR = "char"; + private static final String BOOL = "bool"; private static final String S_DOUBLE = "d"; private static final String S_FLOAT = "f"; private static final String S_INTEGER = "i"; private static final String S_LONG = "l"; private static final String S_CHAR = "c"; + private static final String S_BOOL = "b"; private Class _type; private String _units; @@ -221,6 +223,8 @@ else if (dt.equals(Integer.class) || dt.equals(Short.class)) _typeDesc = useShortType ? S_INTEGER : INTEGER; else if (dt.equals(Long.class)) _typeDesc = useShortType ? S_LONG : LONG; + else if (dt.equals(Boolean.class)) + _typeDesc = useShortType ? S_BOOL : BOOL; else _typeDesc = useShortType ? S_CHAR : CHAR; } diff --git a/src/firefly/js/charts/ChartUtil.js b/src/firefly/js/charts/ChartUtil.js index cf962c1916..ddfaadcff3 100644 --- a/src/firefly/js/charts/ChartUtil.js +++ b/src/firefly/js/charts/ChartUtil.js @@ -120,7 +120,7 @@ function colWithName(cols, name) { function getNumericCols(cols) { const ncols = []; cols.forEach((c) => { - if (c.type !== 'char') { + if (c.type.match(/^[dfil]/) != null) { // int, float, double, long .. or their short form. ncols.push(c); } }); diff --git a/src/firefly/js/tables/ui/BasicTableView.jsx b/src/firefly/js/tables/ui/BasicTableView.jsx index d17dbe49ad..15b5deb37f 100644 --- a/src/firefly/js/tables/ui/BasicTableView.jsx +++ b/src/firefly/js/tables/ui/BasicTableView.jsx @@ -295,10 +295,16 @@ function tableToText(columns, dataAry, showUnits=false) { const colWidths = calcColumnWidths(columns, dataAry); + // column's name var textHead = columns.reduce( (pval, col, idx) => { return pval + (get(columns, [idx,'visibility'], 'show') === 'show' ? `${padEnd(col.name, colWidths[idx])}|` : ''); }, '|'); + // column's type + textHead += '\n' + columns.reduce( (pval, col, idx) => { + return pval + (get(columns, [idx,'visibility'], 'show') === 'show' ? `${padEnd(col.type || '', colWidths[idx])}|` : ''); + }, '|'); + if (showUnits) { textHead += '\n' + columns.reduce( (pval, col, idx) => { return pval + (get(columns, [idx,'visibility'], 'show') === 'show' ? `${padEnd(col.units || '', colWidths[idx])}|` : ''); diff --git a/src/firefly/js/ui/SearchPanel.jsx b/src/firefly/js/ui/SearchPanel.jsx index 625dd7d6f6..08e9a8a91f 100644 --- a/src/firefly/js/ui/SearchPanel.jsx +++ b/src/firefly/js/ui/SearchPanel.jsx @@ -54,9 +54,21 @@ export const SearchPanel = (props) => { + @@ -83,7 +95,7 @@ function hideSearchPanel() { function onSearchSubmit(request) { if (request.fileUpload) { - const treq = TblUtil.makeFileRequest(null, request.fileUpload, null, {filters: request.filters}); + const treq = TblUtil.makeFileRequest(null, request.fileUpload, null, {...request}); dispatchTableSearch(treq); } else if (request.srcTable) { const treq = TblUtil.makeFileRequest(null, request.srcTable, null, {filters: request.filters});