/*
* Copyright (C) 2010-2014 - Andreas Maier, Andreas Keil
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/
package edu.stanford.rsl.conrad.data;
/**
* The Grid*D classes are to be used as wrappers for already allocated float buffers.
* A Grid then defines the properties of such a buffer (like the spacing and origin of
* the grid, how much of it is a boundary, ...) and provides some methods like interpolation
* and boundary filling. The Grids also keep a reference to their buffer. Note that a
* Grid's buffer, as well as its number of boundary pixels are fixed after the creation of
* this object. Therefore, whenever any size parameter should change, a new Grid has to
* be instantiated.
*
* @author Andreas Keil
*/
public abstract class Grid {
/** The Grid's size (excluding boundary pixels). */
protected int[] size;
/** The pixel spacing, i.e. the distance between two neighboring pixel centers. */
protected double[] spacing;
/** The Grid's origin, given in real world units (usually mm) of the first pixel's center (excluding borders). */
protected double[] origin;
/**
* @return The array's size (excluding borders).
*/
public int[] getSize() {
return this.size;
}
/**
* @return The array's spacings in all dimensions.
*/
public double[] getSpacing() {
return this.spacing;
}
/**
* Set the array's spacings.
*/
public void setSpacing(double... spacing) {
assert spacing.length == this.size.length : "The given spacing's dimension (" + spacing.length + ") does not match this Grid's dimension!";
for (double s : spacing) assert s >= 0.0 : "Spacing values have to be non-negative!";
if(this.spacing == null) this.spacing = new double[size.length];
System.arraycopy(spacing, 0, this.spacing, 0, spacing.length);
}
/**
* @return The array origin's world coordinates, given in real world units (usually mm) of the first pixel's center (excluding borders), in all dimensions.
*/
public double[] getOrigin() {
return this.origin;
}
/**
* Set the array origin's world coordinates, given in real world units (usually mm) of the first pixel's center (excluding borders), in all dimensions.
*/
public void setOrigin(double... origin) {
assert origin.length == this.size.length : "The given origin's dimension (" + origin.length + ") does not match this Grid's dimension!";
if(this.origin == null) this.origin = new double[size.length];
System.arraycopy(origin, 0, this.origin, 0, origin.length);
}
/**
* Show the object in an imageJ window
*/
public abstract void show();
/**
* Show the object in an imageJ window with title
*/
public abstract void show(String s);
/**
* Deep copy the object
*/
public abstract Grid clone();
/**
* Get number of float elements
*/
public int getNumberOfElements(){
int elements = this.size[0];
for (int i=1; i < this.size.length; ++i)
elements*=this.size[i];
return elements;
}
// // THE FOLLOWING METHODS TAKE A LONGER TIME TO EXECUTE THAN THEIR DIMENSION-SPECIFIC IMPLEMENTATIONS
// // (ABOUT 20x-30x LONGER IN SOME TEST ANDREAS KEIL DID). THAT'S WHY THEY ARE COMMENTED OUT.
// public double[] indexToPhysical(double... index) {
// assert index.length == this.size.length : "The given index's dimension (" + index.length + ") does not match this Grid's dimension!";
// double[] physical = new double[index.length];
// for (int i = 0; i < this.size.length; ++i) physical[i] = index[i] * this.spacing[i] + this.origin[i];
// return physical;
// }
// public double[] physicalToIndex(double... physical) {
// assert physical.length == this.size.length : "The given coordinate's dimension (" + physical.length + ") does not match this Grid's dimension!";
// double[] index = new double[physical.length];
// for (int i = 0; i < this.size.length; ++i) index[i] = (physical[i] - this.origin[i]) / this.spacing[i];
// return index;
// }
/**
* Serialize the grid's content to a String.
* @return the serialized String, created so that each dimension is wrapped in brackets and entries within one dimension are separated by commas, e.g., [[a, b, c], [d, e, f]]
*/
@Override
public abstract String toString();
}