From d3f8e640fec2b91bba761930b46d13170486b9f5 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 2 May 2013 16:23:27 -0500 Subject: [PATCH] Add classes for unioning multiple typed spaces The CombinedSpace provides a union of TypedSpaces. The CombinedRealInterval provides a union of TypedRealIntervals. The union is constructed by combining axes of the same AxisType. In the case of the CombinedRealInterval, the realMin and realMax of each dimension is computed by taking the lower and upper bounds, respectively, of the constitent intervals' associated dimensions. --- .../imglib2/meta/CombinedRealInterval.java | 145 ++++++++++++++++++ .../java/net/imglib2/meta/CombinedSpace.java | 127 +++++++++++++++ .../net/imglib2/meta/TypedRealInterval.java | 51 ++++++ 3 files changed, 323 insertions(+) create mode 100644 meta/src/main/java/net/imglib2/meta/CombinedRealInterval.java create mode 100644 meta/src/main/java/net/imglib2/meta/CombinedSpace.java create mode 100644 meta/src/main/java/net/imglib2/meta/TypedRealInterval.java diff --git a/meta/src/main/java/net/imglib2/meta/CombinedRealInterval.java b/meta/src/main/java/net/imglib2/meta/CombinedRealInterval.java new file mode 100644 index 0000000000..9f3ffc2abf --- /dev/null +++ b/meta/src/main/java/net/imglib2/meta/CombinedRealInterval.java @@ -0,0 +1,145 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of any organization. + * #L% + */ + +package net.imglib2.meta; + +import java.util.HashMap; + +import net.imglib2.RealInterval; +import net.imglib2.RealPositionable; + +/** + * A {@code CombinedRealInterval} is a {@link RealInterval} (specifically a + * {@link TypedRealInterval}) which is a union of other + * {@link TypedRealInterval}s. Dimensions with the same {@link AxisType} are + * combined; see {@link CombinedSpace} for further details. + *

+ * The {@link #realMin} of a dimension will be the lower bound of all + * constituent interval {@link #realMin}s for dimensions of that type. + * Similarly, the {@link #realMax} of a dimension will be the upper bound of all + * constituent interval {@link #realMax}s. + *

+ *

+ * In the case of {@link TypedUnitRealInterval}s, no reconciliation is done to + * ensure that overlapping axes have equal units or calibrations; it is assumed + * that each axis has already been standardized to a common calibration via the + * {@link CalibratedViews#recalibrate} method. + *

+ * + * @author Curtis Rueden + */ +public class CombinedRealInterval> + extends CombinedSpace implements TypedRealInterval +{ + + /** Combined min and max values for each axis. */ + private final HashMap minMax = + new HashMap(); + + // -- CombinedRealInterval methods -- + + @Override + public void update() { + minMax.clear(); + super.update(); + for (final TypedRealInterval interval : this) { + for (int d = 0; d < interval.numDimensions(); d++) { + final AxisType axisType = interval.axis(d).type(); + if (!minMax.containsKey(axisType)) { + // new axis; add to the hash + minMax.put(axisType, new MinMax()); + } + final MinMax mm = minMax.get(axisType); + mm.expand(interval.realMin(d), interval.realMax(d)); + } + } + } + + // -- RealInterval methods -- + + @Override + public double realMin(final int d) { + return minMax.get(axis(d).type()).min(); + } + + @Override + public void realMin(final double[] min) { + for (int i = 0; i < min.length; i++) + min[i] = realMin(i); + } + + @Override + public void realMin(final RealPositionable min) { + for (int i = 0; i < min.numDimensions(); i++) + min.setPosition(realMin(i), i); + } + + @Override + public double realMax(final int d) { + return minMax.get(axis(d).type()).max(); + } + + @Override + public void realMax(final double[] max) { + for (int i = 0; i < max.length; i++) + max[i] = realMax(i); + } + + @Override + public void realMax(final RealPositionable max) { + for (int i = 0; i < max.numDimensions(); i++) + max.setPosition(realMax(i), i); + } + + // -- Helper classes -- + + protected class MinMax { + + private double minMin = Double.POSITIVE_INFINITY; + private double maxMax = Double.NEGATIVE_INFINITY; + + public void expand(final double min, final double max) { + if (min < minMin) minMin = min; + if (max > maxMax) maxMax = max; + } + + public double min() { return minMin; } + public double max() { return maxMax; } + + } + +} diff --git a/meta/src/main/java/net/imglib2/meta/CombinedSpace.java b/meta/src/main/java/net/imglib2/meta/CombinedSpace.java new file mode 100644 index 0000000000..ebd89d2b40 --- /dev/null +++ b/meta/src/main/java/net/imglib2/meta/CombinedSpace.java @@ -0,0 +1,127 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of any organization. + * #L% + */ + +package net.imglib2.meta; + +import java.util.ArrayList; + +import net.imglib2.EuclideanSpace; + +/** + * A {@code CombinedSpace} is a {@link EuclideanSpace} (specifically a + * {@link TypedSpace}) which is a union of other {@link TypedSpace}s. Common + * axes are merged as appropriate by matching the {@link AxisType}s of each + * {@link TypedAxis}. + *

+ * For example, combining three spaces with dimensions (X, Y, Z, CHANNEL), + * (X, Y, CHANNEL, TIME) and (X, Z, LIFETIME, TIME) will result in a coordinate + * space with dimensions (X, Y, Z, CHANNEL, TIME, LIFETIME). + *

+ * + * @author Curtis Rueden + */ +public class CombinedSpace
> + extends ArrayList implements TypedSpace +{ + + /** List of axis types for the combined space. */ + private final ArrayList axisTypes = new ArrayList(); + + // -- CombinedSpace methods -- + + /** Recomputes the combined space based on its current constituents. */ + public void update() { + axisTypes.clear(); + for (final TypedSpace space : this) { + for (int d = 0; d < space.numDimensions(); d++) { + final AxisType axisType = space.axis(d).type(); + if (!axisTypes.contains(axisType)) { + // new axis; add to the list + axisTypes.add(axisType); + } + } + } + } + + // -- TypedSpace methods -- + + @Override + public int dimensionIndex(final AxisType axis) { + return axisTypes.indexOf(axis); + } + + // -- AnnotatedSpace methods -- + + @Override + public A axis(final int d) { + final AxisType type = axisTypes.get(d); + + // find the first axis of a constituent space that matches the type + for (final TypedSpace space : this) { + final int id = space.dimensionIndex(type); + if (id < 0) continue; + return space.axis(id); + } + throw new IllegalStateException("No compatible constituent space"); + } + + @Override + public void axes(final A[] axes) { + for (int i = 0; i < axes.length; i++) + axes[i] = axis(i); + } + + @Override + public void setAxis(final A axis, final int d) { + final AxisType type = axisTypes.get(d); + + // assign the axis to all constituent spaces of matching type + for (final TypedSpace space : this) { + final int id = space.dimensionIndex(type); + if (id < 0) continue; + space.setAxis(axis, id); + } + } + + // -- EuclideanSpace methods -- + + @Override + public int numDimensions() { + return axisTypes.size(); + } + +} diff --git a/meta/src/main/java/net/imglib2/meta/TypedRealInterval.java b/meta/src/main/java/net/imglib2/meta/TypedRealInterval.java new file mode 100644 index 0000000000..f92cadc7dc --- /dev/null +++ b/meta/src/main/java/net/imglib2/meta/TypedRealInterval.java @@ -0,0 +1,51 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of any organization. + * #L% + */ + +package net.imglib2.meta; + +import net.imglib2.RealInterval; + +/** + * A {@link RealInterval} over a {@link TypedSpace}. + * + * @author Curtis Rueden + */ +public interface TypedRealInterval extends RealInterval, + TypedSpace +{ + // NB: Marker interface. +}