/* *------------------------------------------------------------------------------ * Copyright (C) 2015 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package omero.gateway.util; import java.util.HashMap; import java.util.Map; import omero.gateway.exception.DSAccessException; import omero.gateway.model.TableResult; import omero.grid.BoolColumn; import omero.grid.Column; import omero.grid.Data; import omero.grid.DoubleColumn; import omero.grid.ImageColumn; import omero.grid.LongColumn; import omero.grid.RoiColumn; import omero.grid.StringColumn; import omero.grid.TablePrx; import omero.grid.WellColumn; /** * Collection of utility classes to convert OMERO tables. * * @author Dominik Lindner      <a * href="mailto:d.lindner@dundee.ac.uk">d.lindner@dundee.ac.uk</a> * @since 5.1 */ public class PyTablesUtils { /** Maximum number of rows to retrieve at one time from a table. */ private static final int MAX_TABLE_ROW_RETRIEVAL = 100000; /** * Transforms the passed table data for a given image. * * @param table * The table to convert. * @param key * The key of the <code>where</code> clause. * @param id * The identifier of the object to retrieve rows for. * @return See above * @throws DSAccessException * If an error occurred while trying to retrieve data from OMEDS * service. */ public static TableResult createTableResult(TablePrx table, String key, long id) throws DSAccessException { if (table == null) return null; try { key = "(" + key + "==%d)"; long totalRowCount = table.getNumberOfRows(); long[] rows = table.getWhereList(String.format(key, id), null, 0, totalRowCount, 1L); return createTableResult(table, rows); } catch (Exception e) { throw new DSAccessException("Unable to read the table.", e); } } /** * Transforms a set of rows for the passed table. * * @param table * The table to convert. * @param rows * The rows of the table to convert. * @return See above * @throws DSAccessException * If an error occurred while trying to retrieve data from OMEDS * service. */ public static TableResult createTableResult(TablePrx table, long[] rows) throws DSAccessException { if (table == null) return null; try { Column[] cols = table.getHeaders(); String[] headers = new String[cols.length]; String[] headersDescriptions = new String[cols.length]; for (int i = 0; i < cols.length; i++) { headers[i] = cols[i].name; headersDescriptions[i] = cols[i].description; } int totalRowCount = rows.length; Object[][] data = new Object[totalRowCount][cols.length]; Data d; long[] columns = new long[cols.length]; for (int i = 0; i < cols.length; i++) { columns[i] = i; } int rowOffset = 0; int rowCount = 0; int rowsToGo = totalRowCount; long[] rowSubset; Map<Integer, Integer> indexes = new HashMap<Integer, Integer>(); while (rowsToGo > 0) { rowCount = (int) Math.min(MAX_TABLE_ROW_RETRIEVAL, totalRowCount - rowOffset); rowSubset = new long[rowCount]; System.arraycopy(rows, rowOffset, rowSubset, 0, rowCount); d = table.slice(columns, rowSubset); for (int i = 0; i < cols.length; i++) { translateTableResult(d, data, rowOffset, rowCount, indexes); } rowOffset += rowCount; rowsToGo -= rowCount; } TableResult tr = new TableResult(data, headers); tr.setIndexes(indexes); return tr; } catch (Exception e) { try { if (table != null) table.close(); } catch (Exception ex) { // Digest exception } throw new DSAccessException("Unable to read the table.", e); } finally { if (table != null) { try { table.close(); } catch (Exception e2) { //ignore } } } } /** * Translates a set of table results into an array. * * @param src * Source data from the table. * @param dst * Destination array. * @param offset * Offset within the destination array from which to copy data * into. * @param length * Number of rows of data to be copied. */ private static void translateTableResult(Data src, Object[][] dst, int offset, int length, Map<Integer, Integer> indexes) { Column[] cols = src.columns; Column column; for (int i = 0; i < cols.length; i++) { column = cols[i]; if (column instanceof LongColumn) { for (int j = 0; j < length; j++) { dst[j + offset][i] = ((LongColumn) column).values[j]; } } else if (column instanceof DoubleColumn) { for (int j = 0; j < length; j++) { dst[j + offset][i] = ((DoubleColumn) column).values[j]; } } else if (column instanceof StringColumn) { for (int j = 0; j < length; j++) { dst[j + offset][i] = ((StringColumn) column).values[j]; } } else if (column instanceof BoolColumn) { for (int j = 0; j < length; j++) { dst[j + offset][i] = ((BoolColumn) column).values[j]; } } else if (column instanceof RoiColumn) { indexes.put(TableResult.ROI_COLUMN_INDEX, i); for (int j = 0; j < length; j++) { dst[j + offset][i] = ((RoiColumn) column).values[j]; } } else if (column instanceof ImageColumn) { indexes.put(TableResult.IMAGE_COLUMN_INDEX, i); for (int j = 0; j < length; j++) { dst[j + offset][i] = ((ImageColumn) column).values[j]; } } else if (column instanceof WellColumn) { indexes.put(TableResult.WELL_COLUMN_INDEX, i); for (int j = 0; j < length; j++) { dst[j + offset][i] = ((WellColumn) column).values[j]; } } } } }