All Downloads are FREE. Search and download functionalities are using the official Maven repository.

timeBench.data.io.TextTableTemporalDatasetReader Maven / Gradle / Ivy

Go to download

TimeBench, a flexible, easy-to-use, and reusable software library written in Java that provides foundational data structures and algorithms for time- oriented data in Visual Analytics.

The newest version!
package timeBench.data.io;

import ieg.prefuse.data.DataHelper;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.TimeZone;
import java.util.TreeMap;

import javax.xml.bind.JAXBException;

import org.apache.log4j.Logger;
import org.timebench.util.xml.JaxbMarshaller;

import prefuse.data.Table;
import prefuse.data.Tuple;
import prefuse.data.io.DataIOException;
import prefuse.data.io.TableReader;
import prefuse.util.collections.IntIterator;
import timeBench.calendar.Granularity;
import timeBench.calendar.JavaDateCalendarManager;
import timeBench.data.GenericTemporalElement;
import timeBench.data.TemporalDataException;
import timeBench.data.TemporalDataset;
import timeBench.data.TemporalObject;
import timeBench.data.io.schema.DateInstantEncoding;
import timeBench.data.io.schema.TemporalDataColumnSpecification;
import timeBench.data.io.schema.TemporalObjectEncoding;

/**
 * Reads a TemporalDataset and either tries to automatically detect the temporal
 * column or use a given data format specification.
 * 
 * 

* Added: 2011-09-27 / AR
* Modifications: 2013-03-25 / AR / autoGranularity *

* * @author Alexander Rind */ public class TextTableTemporalDatasetReader extends AbstractTemporalDatasetReader { private static final Logger logger = Logger .getLogger(TextTableTemporalDatasetReader.class); private TemporalDataColumnSpecification spec = null; private Granularity autoGranularity = null; /** * Reads a TemporalDataset and tries to automatically detect the temporal * column. Granules of the bottom granularity are assumed. */ public TextTableTemporalDatasetReader() { this.spec = null; } /** * Reads a TemporalDataset and tries to automatically detect the temporal * column. The temporal elements will be instants based on the given * granularity. * * @param granularity */ public TextTableTemporalDatasetReader(Granularity granularity) { super(); this.autoGranularity = granularity; } public TextTableTemporalDatasetReader(TemporalDataColumnSpecification spec) { super(); this.spec = spec; } public TextTableTemporalDatasetReader(String xmlFile) throws IOException, JAXBException { super(); this.spec = (TemporalDataColumnSpecification) JaxbMarshaller.loadUser( xmlFile, TemporalDataColumnSpecification.class); } @Override public TemporalDataset readData(InputStream is) throws DataIOException, TemporalDataException { TemporalDataColumnSpecification spec = (this.spec != null) ? this.spec : new TemporalDataColumnSpecification(); TableReader tableReader = spec.getTableFormat().getTableReader(); // XXX hack to handle prefuse String -> Date conversion in UTC TimeZone oldDefault = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); Table table = tableReader.readTable(is); TimeZone.setDefault(oldDefault); if (logger.isInfoEnabled()) { logger.info("Metadata of raw table:"); DataHelper.printMetadata(System.out, table); } if (this.spec == null) scanTableForSpecification(table, spec); TemporalDataset tmpds = new TemporalDataset(); importTable(table, tmpds, spec); table = null; return tmpds; } // TODO should the class remember the spec or stay in auto-detection mode private void scanTableForSpecification(Table table, TemporalDataColumnSpecification spec) throws TemporalDataException { String temporalColumn = null; LinkedList dataColumns = new LinkedList(); for (int i = 0; i < table.getColumnCount(); i++) { String col = table.getColumnName(i); if (table.canGetDate(col) && temporalColumn == null) temporalColumn = col; else dataColumns.add(col); } if (temporalColumn == null) throw new TemporalDataException( "Imported data table does not have a recognized temporal column."); DateInstantEncoding enc = new DateInstantEncoding("default", temporalColumn); enc.setDataColumns(dataColumns.toArray(new String[0])); enc.setGranularity(autoGranularity != null ? autoGranularity : JavaDateCalendarManager.getSingleton().getDefaultCalendar().getBottomGranularity()); spec.addEncoding(enc); } public static void importTable(Table table, TemporalDataset tmpds, TemporalDataColumnSpecification spec) throws TemporalDataException { // 1. analyze & prepare schemata if (logger.isDebugEnabled()) logger.debug("start import " + table); spec.init(); // 1.2. prepare table for data elements for (TemporalObjectEncoding encoding : spec.getEncodings()) { try { prepareDataColumns(tmpds, table, encoding); } catch (TemporalDataException e) { // this is safe if the data element table has no column logger.fatal("Failed to build data columns on import", e); System.exit(1); } } // 2. for each data row // map of temporal elements extracted from 1 row: specKey -> row TreeMap elements = new TreeMap(); long temporalObjectId = 0; IntIterator rows = table.rows(); while (rows.hasNext()) { Tuple tuple = (Tuple) table.getTuple(rows.nextInt()); try { // 2.1. for each schema for (TemporalObjectEncoding encoding : spec.getEncodings()) { logger.trace(encoding.getKey()); // 2.1.1. extract temporal element & append to TempDS encoding.buildTemporalElement(tmpds, tuple, elements); // 2.1.2. if it has data columns if (encoding.getDataColumns().length > 0) { if (encoding.isTemporalObjectIdIncluded()) { temporalObjectId = tuple.getLong(TemporalObject.ID); } else { temporalObjectId++; } logger.debug("temporal object id " + temporalObjectId); // 2.1.2.1. link temporal element with data element in TempDS TemporalObject obj = tmpds.addTemporalObject( temporalObjectId, elements.get(encoding.getKey()).getId()); // 2.1.2.2. extract data element & append to TempDS copyDataElements(obj, tuple, encoding); } } } catch (TemporalDataException e) { if (spec.isFailOnIllegalRows()) throw e; else { if (logger.isInfoEnabled()) logger.info("skip row import: " + tuple + " Reason: ", e); } } // 2.2 clear cached temporal elements elements.clear(); } } private static void prepareDataColumns(TemporalDataset tmpds, Table table, TemporalObjectEncoding schema) throws TemporalDataException { Table dataElements = tmpds.getNodeTable(); for (String col : schema.getDataColumns()) { if (dataElements.getColumnNumber(col) == -1) { // column does not exist yet --> add it if (logger.isDebugEnabled()) logger.debug("prepare data col \"" + col + "\" type " + table.getColumnType(col)); tmpds.addDataColumn(col, table.getColumnType(col), null); } else if (dataElements.getColumnType(col) != table .getColumnType(col)) { // column exists but wrong data type throw new TemporalDataException("Data column " + col + " already exists with a different type: is " + dataElements.getColumnType(col) + " expected " + table.getColumnType(col)); } else if (col.equals(TemporalObject.TEMPORAL_ELEMENT_ID)) { // try to put data in foreign key column throw new TemporalDataException("Data column " + col + " is reserved for TimeBench."); } else if (logger.isDebugEnabled()) logger.debug("skip data col \"" + col + "\" type " + table.getColumnType(col)); } } private static void copyDataElements(TemporalObject obj, Tuple tuple, TemporalObjectEncoding schema) { for (String col : schema.getDataColumns()) { if (logger.isTraceEnabled()) logger.trace("add data item " + col + " value " + tuple.get(col)); // TODO insert switch (columnType) and call setInt(getInt()) // if we are more serious about performance obj.set(col, tuple.get(col)); } } public TemporalDataColumnSpecification getSpecification() { return spec; } public void setSpecification(TemporalDataColumnSpecification spec) { this.spec = spec; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy