content: /*
   * 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();
  	
  }
  
  
  