Skip to content

Commit

Permalink
ttools: Modify the way that DataGeom works with PlotLayers.
Browse files Browse the repository at this point in the history
DataGeom is now OK to use if it only has some coordinates, i.e. it
might specify a point, or a line, or a plane or whatever.
It has a new hasPosition() method to report which of these it's doing.
This means that non-point-plotting layers (such as spectrogram) can use
the DataGeom machinery to report ranges.  Users of DataGeom have to
be a bit more careful now.

Rename Plotter.getDataGeoms to getPointDataGeoms, to emphasise
that these ones must be full-point (hasPosition=true) instances.

Also add PlotLayer.extendCoordinateRanges which gives you the chance to
report non-point-like range extensions (like a spectrogram channel array).
  • Loading branch information
mbtaylor committed Jul 15, 2013
1 parent 8139219 commit 79f4376
Show file tree
Hide file tree
Showing 21 changed files with 124 additions and 35 deletions.
Expand Up @@ -36,7 +36,8 @@ private static class CubePlotTypeGui
return new CubeAxisControl( false, stack );
}
public PositionCoordPanel createPositionCoordPanel() {
return new SimplePositionCoordPanel( PLOT_TYPE.getDataGeoms()[ 0 ],
return new SimplePositionCoordPanel( PLOT_TYPE
.getPointDataGeoms()[ 0 ],
true );
}
}
Expand Down
Expand Up @@ -37,7 +37,8 @@ private static class PlanePlotTypeGui
return new PlaneAxisControl( stack );
}
public PositionCoordPanel createPositionCoordPanel() {
return new SimplePositionCoordPanel( PLOT_TYPE.getDataGeoms()[ 0 ],
return new SimplePositionCoordPanel( PLOT_TYPE
.getPointDataGeoms()[ 0 ],
true );
}
}
Expand Down
Expand Up @@ -37,7 +37,8 @@ private static class SpherePlotTypeGui
return new CubeAxisControl( true, stack );
}
public PositionCoordPanel createPositionCoordPanel() {
return new SimplePositionCoordPanel( PLOT_TYPE.getDataGeoms()[ 0 ],
return new SimplePositionCoordPanel( PLOT_TYPE
.getPointDataGeoms()[ 0 ],
true );
}
}
Expand Down
10 changes: 8 additions & 2 deletions topcat/src/main/uk/ac/starlink/topcat/plot2/StackPlotWindow.java
Expand Up @@ -480,7 +480,8 @@ private void identifyPoint( Point point ) {
PlotLayer layer = visibleLayers[ il ];
DataGeom geom = layer.getDataGeom();
DataSpec dataSpec = layer.getDataSpec();
if ( dataSpec != null && geom != null ) {
if ( dataSpec != null &&
geom != null && geom.hasPosition() ) {
cloudMap.put( new PointCloud( geom, dataSpec ), layer );
}
}
Expand All @@ -498,6 +499,7 @@ private void identifyPoint( Point point ) {

/* Iterate over each visible point in the layer. */
DataGeom geom = layer.getDataGeom();
assert geom != null && geom.hasPosition();
DataSpec dataSpec = layer.getDataSpec();
TopcatModel tcModel = getTopcatModel( dataSpec );
TupleSequence tseq = dataStore.getTupleSequence( dataSpec );
Expand Down Expand Up @@ -604,6 +606,9 @@ private void highlightRow( TopcatModel tcModel, long irow ) {
private static double[] getDataPos( PlotLayer layer, long irow,
DataStore dataStore ) {
DataGeom geom = layer.getDataGeom();
if ( geom == null || ! geom.hasPosition() ) {
return null;
}
double[] dpos = new double[ geom.getDataDimCount() ];
TupleSequence tseq = dataStore.getTupleSequence( layer.getDataSpec() );

Expand Down Expand Up @@ -654,7 +659,8 @@ public Map<TopcatModel,BitSet> getItem() {
DataGeom geom = layer.getDataGeom();
DataSpec dataSpec = layer.getDataSpec();
TopcatModel tcModel = tcModels[ il ];
if ( tcModel != null && geom != null ) {
if ( tcModel != null &&
geom != null && geom.hasPosition() ) {
if ( ! maskMap.containsKey( tcModel ) ) {
int nrow =
Tables.checkedLongToInt( tcModel.getDataModel()
Expand Down
16 changes: 14 additions & 2 deletions ttools/src/main/uk/ac/starlink/ttools/plot2/DataGeom.java
Expand Up @@ -28,11 +28,23 @@ public interface DataGeom {
*/
Coord[] getPosCoords();

/**
* Indicates whether the values read by the <code>readDataPos</code>
* method correspond to a point position in the data space.
* If true, a successful read will result in a position array
* with a definite value for each coordinate. If false, some of
* the coordinates may be NaN. A false return value would be
* appropriate for instance if each tuple row for the plot layer
* represented by this geom corresponds to a line rather than a
* point in the data space.
*
* @return true iff this geom represents point positions
*/
boolean hasPosition();

/**
* Determines the base positional coordinates in data space
* for the current row of a supplied tuple sequence.
* The positional coordinates are assumed to start at column
* zero of the supplied tuple sequence.
*
* <p>An array of (at least) {@link #getDataDimCount} elements is
* supplied, and on success the data space coordinate values of the
Expand Down
29 changes: 26 additions & 3 deletions ttools/src/main/uk/ac/starlink/ttools/plot2/PlotLayer.java
Expand Up @@ -5,12 +5,14 @@
import uk.ac.starlink.ttools.plot.Range;
import uk.ac.starlink.ttools.plot.Style;
import uk.ac.starlink.ttools.plot2.data.DataSpec;
import uk.ac.starlink.ttools.plot2.data.DataStore;
import uk.ac.starlink.ttools.plot2.paper.PaperType;

/**
* Represents a layered element of the plot.
* When combined with certain other information it can draw data or
* other graphical elements onto a Surface.
* other graphical elements onto a Surface, and report on the surface
* region covered by such graphics.
*
* @author Mark Taylor
* @since 11 Feb 2013
Expand All @@ -35,12 +37,33 @@ public interface PlotLayer {
/**
* Returns the data geometry used by this layer.
* This can be used in conjunction with the DataSpec to determine the
* base positions in data space of all the points plotted.
* base positions in data space of what has been plotted.
* Depending on the nature of the returned object, these positions may
* be actual points in the data space, or some higher-dimensional object.
* If null is returned, no such information is available.
*
* @return data geom
* @return data geom, or null
*/
DataGeom getDataGeom();

/**
* Gives this layer a chance to adjust the coordinate ranges
* assembled during data ranging. Supplied is an array of range
* objects, each corresponding to one of the data position dimensions
* (it has <code>surface.getDataDimCount</code> elements).
* If this layer needs to adjust these ranges beyond what is implied
* by the result of <code>getDataGeom</code>, it may be done here.
* The implementation may or may not need to acquire
* a tuple sequence from the supplied <code>dataStore</code>.
*
* <p>In many cases (especially for point-plotting type layers)
* the implementation of this method will be a no-operation.
*
* @param ranges array of data space dimension ranges, may be adjusted
* @param dataStore data storage object
*/
void extendCoordinateRanges( Range[] ranges, DataStore dataStore );

/**
* Returns the data spec that defines the data used by this layer.
* May be null if no tabular data is required.
Expand Down
6 changes: 4 additions & 2 deletions ttools/src/main/uk/ac/starlink/ttools/plot2/PlotType.java
Expand Up @@ -18,13 +18,15 @@ public interface PlotType {

/**
* Returns a list of one or more geometry variants which describe
* how user-supplied coordinates map to the data space.
* how user-supplied point coordinates map to the data space.
* The geoms returned from this method will return true from their
* {@link DataGeom#hasPosition} method.
* If multiple values are returned, the first one may be used as some kind
* of default.
*
* @return data geom option list
*/
DataGeom[] getDataGeoms();
DataGeom[] getPointDataGeoms();

/**
* Returns an object that can construct the plot surface including
Expand Down
34 changes: 27 additions & 7 deletions ttools/src/main/uk/ac/starlink/ttools/plot2/PlotUtil.java
Expand Up @@ -149,28 +149,48 @@ public void paintPicture( Graphics2D g2 ) {
}

/**
* Determines range information for each of the coordinates of the
* data positions in a PointCloud.
* Determines range information for a set of layers which have
* Cartesian (or similar) coordinates.
*
* @param cloud point cloud
* @param nDataDim dimensionality of data points in the point cloud
* @param layers plot layers
* @param nDataDim dimensionality of data points
* @param dataStore data storage
* @return nDataDim-element array of ranges, each containing the
* range of data position coordinate values for
* the corresponding dimension
*/
@Slow
public static Range[] readCoordinateRanges( PointCloud cloud, int nDataDim,
public static Range[] readCoordinateRanges( PlotLayer[] layers,
int nDataDim,
DataStore dataStore ) {

/* Set up an array of range objects, one for each data dimension. */
Range[] ranges = new Range[ nDataDim ];
for ( int idim = 0; idim < nDataDim; idim++ ) {
ranges[ idim ] = new Range();
}
}

/* Create a point cloud containing all the point positions
* represented by the supplied layers. If there are several
* layers using the same basic positions, this should combine
* them efficiently. */
PointCloud cloud = new PointCloud( layers, true );

/* Iterate over the represented points to mark out the basic
* range of data positions covered by the layers. */
for ( double[] dpos : cloud.createDataPosIterable( dataStore ) ) {
for ( int idim = 0; idim < nDataDim; idim++ ) {
ranges[ idim ].submit( dpos[ idim ] );
}
}
}

/* If any of the layers wants to supply non-data-position points
* to mark out additional space, take account of those too. */
for ( int il = 0; il < layers.length; il++ ) {
layers[ il ].extendCoordinateRanges( ranges, dataStore );
}

/* Return the ranges. */
return ranges;
}

Expand Down
12 changes: 7 additions & 5 deletions ttools/src/main/uk/ac/starlink/ttools/plot2/Plotter.java
Expand Up @@ -84,21 +84,23 @@ public interface Plotter<S extends Style> {
* <code>dataGeom.getPosCoords</code> and
* {@link #getExtraCoords}.
*
* <p>The <code>dataGeom</code> (and probably <code>dataSpec</code>)
* <p>The <code>pointDataGeom</code>
* parameter is only used if {@link #hasPosition} returns true,
* otherwise the plot is dataless and those parameters are ignored.
* otherwise the plot does not have point positions.
*
* <p>It is legal to supply null for any of the parameters;
* if insufficient data is supplied to generate a plot, then
* the method should return null.
*
* <p>Creating a layer should be cheap; layers may be created and not used.
*
* @param dataGeom indicates base position coordinates and their
* mapping to the data space
* @param pointDataGeom indicates base position coordinates and their
* mapping to points in the data space;
* if non-null, the data geom's
* {@link DataGeom#hasPosition} method will return true
* @param dataSpec specifies the data required for the plot
* @param style data style as obtained from <code>createStyle</code>
* @return new plot layer, or null if no drawing will take place
*/
PlotLayer createLayer( DataGeom dataGeom, DataSpec dataSpec, S style );
PlotLayer createLayer( DataGeom pointDataGeom, DataSpec dataSpec, S style );
}
Expand Up @@ -34,6 +34,10 @@ public int getDataDimCount() {
return 3;
}

public boolean hasPosition() {
return true;
}

public String getVariantName() {
return "Cartesian";
}
Expand Down
Expand Up @@ -56,7 +56,7 @@ private CubePlotType() {
}
}

public DataGeom[] getDataGeoms() {
public DataGeom[] getPointDataGeoms() {
return dataGeoms_;
}

Expand Down
Expand Up @@ -11,7 +11,6 @@
import uk.ac.starlink.ttools.plot2.Captioner;
import uk.ac.starlink.ttools.plot2.PlotLayer;
import uk.ac.starlink.ttools.plot2.PlotUtil;
import uk.ac.starlink.ttools.plot2.PointCloud;
import uk.ac.starlink.ttools.plot2.Subrange;
import uk.ac.starlink.ttools.plot2.Surface;
import uk.ac.starlink.ttools.plot2.SurfaceFactory;
Expand Down Expand Up @@ -317,8 +316,7 @@ public CubeAspect createAspect( Profile profile, ConfigMap config,
}

public Range[] readRanges( PlotLayer[] layers, DataStore dataStore ) {
return PlotUtil.readCoordinateRanges( new PointCloud( layers, true ),
3, dataStore );
return PlotUtil.readCoordinateRanges( layers, 3, dataStore );
}

public CubeAspect pan( Surface surface, Point pos0, Point pos1 ) {
Expand Down
Expand Up @@ -35,6 +35,10 @@ public int getDataDimCount() {
return 2;
}

public boolean hasPosition() {
return true;
}

public String getVariantName() {
return "Cartesian";
}
Expand Down
Expand Up @@ -55,7 +55,7 @@ private PlanePlotType() {
};
}

public DataGeom[] getDataGeoms() {
public DataGeom[] getPointDataGeoms() {
return dataGeoms_;
}

Expand Down
Expand Up @@ -9,7 +9,6 @@
import uk.ac.starlink.ttools.plot2.Captioner;
import uk.ac.starlink.ttools.plot2.PlotLayer;
import uk.ac.starlink.ttools.plot2.PlotUtil;
import uk.ac.starlink.ttools.plot2.PointCloud;
import uk.ac.starlink.ttools.plot2.Subrange;
import uk.ac.starlink.ttools.plot2.Surface;
import uk.ac.starlink.ttools.plot2.SurfaceFactory;
Expand Down Expand Up @@ -178,8 +177,7 @@ public PlaneAspect createAspect( Profile profile, ConfigMap config,
}

public Range[] readRanges( PlotLayer[] layers, DataStore dataStore ) {
return PlotUtil.readCoordinateRanges( new PointCloud( layers, true ),
2, dataStore );
return PlotUtil.readCoordinateRanges( layers, 2, dataStore );
}

public PlaneAspect pan( Surface surface, Point pos0, Point pos1 ) {
Expand Down
Expand Up @@ -36,6 +36,10 @@ public int getDataDimCount() {
return 3;
}

public boolean hasPosition() {
return true;
}

public String getVariantName() {
return variantName_;
}
Expand Down
Expand Up @@ -47,7 +47,7 @@ private SkyPlotType() {
};
}

public DataGeom[] getDataGeoms() {
public DataGeom[] getPointDataGeoms() {
return dataGeoms_;
}

Expand Down
Expand Up @@ -34,6 +34,10 @@ public int getDataDimCount() {
return 3;
}

public boolean hasPosition() {
return true;
}

public String getVariantName() {
return "Polar";
}
Expand Down
Expand Up @@ -43,7 +43,7 @@ private SpherePlotType() {
dataGeoms_ = new DataGeom[] { SphereDataGeom.INSTANCE };
}

public DataGeom[] getDataGeoms() {
public DataGeom[] getPointDataGeoms() {
return dataGeoms_;
}

Expand Down
Expand Up @@ -2,6 +2,7 @@

import java.util.HashMap;
import java.util.Map;
import uk.ac.starlink.ttools.plot.Range;
import uk.ac.starlink.ttools.plot.Style;
import uk.ac.starlink.ttools.plot2.AuxReader;
import uk.ac.starlink.ttools.plot2.AuxScale;
Expand All @@ -10,6 +11,7 @@
import uk.ac.starlink.ttools.plot2.PlotLayer;
import uk.ac.starlink.ttools.plot2.Plotter;
import uk.ac.starlink.ttools.plot2.data.DataSpec;
import uk.ac.starlink.ttools.plot2.data.DataStore;

/**
* Partial PlotLayer implementation.
Expand Down Expand Up @@ -54,6 +56,12 @@ public DataGeom getDataGeom() {
return geom_;
}

/**
* This implementation does nothing.
*/
public void extendCoordinateRanges( Range[] ranges, DataStore dataStore ) {
}

public DataSpec getDataSpec() {
return dataSpec_;
}
Expand Down

0 comments on commit 79f4376

Please sign in to comment.