Skip to content

Commit

Permalink
Move the kotlin files into the correct directory and port tests
Browse files Browse the repository at this point in the history
All tests are now in kotlin and pass!  If only there were full test coverage...
  • Loading branch information
cjfuller committed Mar 11, 2017
1 parent 8105714 commit f05bcc6
Show file tree
Hide file tree
Showing 198 changed files with 482 additions and 930 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ jar {
attributes "Main-Class": mainClassName
}
}

test {
environment "PROJECT_ROOT", "$projectDir"
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class BandpassFilter : Filter() {
return PlugInFilter.DONE
}
stackSize = imp.stackSize
fht = imp.getProperty("FHT") as FHT
fht = imp.getProperty("FHT") as FHT?
if (fht != null) {
IJ.error("FFT Filter", "Spatial domain image required")
return PlugInFilter.DONE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import ij.process.FloatProcessor
* A type of WritablePixelData that uses an ImageJ ImagePlus as its underlying representation.
* @author Colin J. Fuller
*/
class ImagePlusPixelData : WritablePixelData {
class ImagePlusPixelData private constructor() : WritablePixelData() {
private var imPl: ImagePlus? = null
internal var currentStackIndex: Int = 0
internal val dimensionSizes: MutableMap<String, Int> = mutableMapOf()
override val dataType: Int = loci.formats.FormatTools.FLOAT
override var dataType: Int = loci.formats.FormatTools.FLOAT
internal var x_offset: Int = 0
internal var y_offset: Int = 0
internal var z_offset: Int = 0
Expand All @@ -21,7 +21,7 @@ class ImagePlusPixelData : WritablePixelData {
internal val offsetSizes: MutableMap<String, Int> = mutableMapOf()
internal var byteOrder: java.nio.ByteOrder = java.nio.ByteOrder.BIG_ENDIAN

override fun init(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) {
fun init(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) {
var dimensionOrder = dimensionOrder
dimensionOrder = dimensionOrder.toUpperCase()

Expand Down Expand Up @@ -72,32 +72,17 @@ class ImagePlusPixelData : WritablePixelData {
this.imPl = imPl
}

/* (non-Javadoc)
* @see edu.stanford.cfuller.imageanalysistools.image.PixelData#PixelData(edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate, int, String)
*/
constructor(sizes: ImageCoordinate, data_type: Int, dimensionOrder: String) : super(sizes, dimensionOrder) {
if (data_type != this.dataType) {
throw UnsupportedOperationException("Data type must be float.")
}
this.initNewImagePlus()
}

/* (non-Javadoc)
* @see edu.stanford.cfuller.imageanalysistools.image.PixelData#PixelData(int, int, int, int, int, int, String)
*/
constructor(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, data_type: Int, dimensionOrder: String) : super(size_x, size_y, size_z, size_c, size_t, dimensionOrder) {
if (data_type != this.dataType) {
throw UnsupportedOperationException("Data type must be float.")
}
constructor(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, data_type: Int, dimensionOrder: String) : this() {
init(size_x, size_y, size_z, size_c, size_t, dimensionOrder)
this.dataType = data_type
this.initNewImagePlus()
}

/**
* Creates a new ImagePlusPixelData from an existing ImagePlus.
* @param imPl The ImagePlus to use. This will not be copied, but used and potentially modified in place.
*/
constructor(imPl: ImagePlus) {
constructor(imPl: ImagePlus) : this() {
this.imPl = imPl
this.init(imPl.width, imPl.height, imPl.nSlices, imPl.nChannels, imPl.nFrames, imagePlusDimensionOrder)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import net.imglib2.RandomAccess
* A type of WritablePixelData that uses an ImgLib2 ImgPlus as its underlying representation.
* @author Colin J. Fuller
*/
class ImgLibPixelData : WritablePixelData {
class ImgLibPixelData private constructor() : WritablePixelData() {
/**
* Gets the underlying ImgLib Img object.
* @return the Img object that is used to store the pixel data (not a copy).
Expand Down Expand Up @@ -42,7 +42,7 @@ class ImgLibPixelData : WritablePixelData {
internal var ci: Int = 0
internal var ti: Int = 0

override fun init(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) {
fun init(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) {
var size_x = size_x
var size_y = size_y
var size_z = size_z
Expand Down Expand Up @@ -132,28 +132,12 @@ class ImgLibPixelData : WritablePixelData {
this.ra = this.img!!.randomAccess()
}

private constructor() {}

/* (non-Javadoc)
* @see edu.stanford.cfuller.imageanalysistools.image.PixelData#PixelData(edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate, int, String)
*/
constructor(sizes: ImageCoordinate, dimensionOrder: String) : super(sizes, dimensionOrder) {
this.initNewImgPlus()
}

/* (non-Javadoc)
* @see edu.stanford.cfuller.imageanalysistools.image.PixelData#PixelData(int, int, int, int, int, String)
*/
constructor(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) : super(size_x, size_y, size_z, size_c, size_t, dimensionOrder) {
this.initNewImgPlus()
}

/**
* Creates a new ImgLibPixelData from an existing ImgPlus and a specified dimension order.
* @param imPl The ImgPlus to use. This will not be copied, but used and potentially modified in place.
* @param dimensionOrder a String containing the five characters XYZCT in the order they are in the image (if some dimensions are not present, the can be specified in any order)
*/
constructor(imPl: ImgPlus<FloatType>, dimensionOrder: String) {
constructor(imPl: ImgPlus<FloatType>, dimensionOrder: String) : this() {
this.img = imPl
this.init(1, 1, 1, 1, 1, dimensionOrder)
this.fixDimensionOrder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,6 @@ abstract class PixelData : java.io.Serializable {
open var dimensionOrder: String = "XYZCT"
internal set

protected constructor() {}

/**
* Constructs a new pixeldata object using an [ImageCoordinate] to specify the size of the pixeldata.
* @param sizes An ImageCoordinate that specifies the size of the pixeldata in all 5 (XYZCT) dimensions.
* @param dimensionOrder A string made up of the characters "XYZCT" in any order that specifies the order of the dimensions in the on-disk representation.
*/
constructor(sizes: ImageCoordinate, dimensionOrder: String) {
init(sizes[ImageCoordinate.X], sizes[ImageCoordinate.Y], sizes[ImageCoordinate.Z], sizes[ImageCoordinate.C], sizes[ImageCoordinate.T], dimensionOrder)
}

/**
* Convenience constructor for creating a PixelData object with individual dimension sizes instead of the sizes lumped into an ImageCoordinate.
* @param size_x Size of the pixel data in the X-dimension.
* @param size_y Size of the pixel data in the Y-dimension.
* @param size_z Size of the pixel data in the Z-dimension.
* @param size_c Size of the pixel data in the C-dimension.
* @param size_t Size of the pixel data in the T-dimension.
* @param dimensionOrder A string made up of the characters "XYZCT" in any order that specifies the order of the dimensions in the on-disk representation.
*/
constructor(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String) {
init(size_x, size_y, size_z, size_c, size_t, dimensionOrder)
}

/**
* Initializes the internals of the PixelData object using the specified parameters.
* @param size_x The size of the PixelData in the x-dimension (in pixels).
* @param size_y The size of the PixelData in the y-dimension (in pixels).
* @param size_z The size of the PixelData in the z-dimension (in pixels).
* @param size_c The size of the PixelData in the c-dimension (in pixels).
* @param size_t The size of the PixelData in the t-dimension (in pixels).
* @param dimensionOrder A string containing the 5 characters "XYZCT" in some order specifying the order in which the dimensions
* are stored in the underlying byte representation.
*/
protected abstract fun init(size_x: Int, size_y: Int, size_z: Int, size_c: Int, size_t: Int, dimensionOrder: String)

/**
* Queries whether the PixelData object has a non-singleton Z dimension.
* @return true if the Z-dimension size is greater than 1, false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,30 @@ open class ReadOnlyImageImpl(m: loci.formats.meta.IMetadata, p: PixelData) : Ima
* @param p A PixelData object containing the actual values at each pixel in the Image.
*/

internal val defaultDimensionOrder = "xyzct"
internal final val defaultDimensionOrder = "xyzct"

/**
* Gets the metadata associated with this Image. (The object returned is an [loci.formats.meta.IMetadata] to facilitate
* use with the LOCI bio-formats library.
* @return The metadata object associated with the Image.
*/
override var metadata: loci.formats.meta.IMetadata = m
override final var metadata: loci.formats.meta.IMetadata = m
protected set

/**
* Gets a PixelData instance that holds the image data.
*/
override var pixelData: PixelData = p
override final var pixelData: PixelData = p
protected set
protected var writablePixelData: WritablePixelData? = null // this is null if it can be written, and the same as pixelData otherwise
var writablePixelData: WritablePixelData? = null // this is null if it can be written, and the same as pixelData otherwise

/**
* Returns an ImageCoordinate that contains the size of each dimension of the Image.
*
* This ImageCoordinate should not be modified by users, nor should it be recycled by users.
* @return An ImageCoordinate containing the size of each dimension of the Image.
*/
override var dimensionSizes: ImageCoordinate = ImageCoordinate.createCoordXYZCT(p.sizeX, p.sizeY, p.sizeZ, p.sizeC, p.sizeT)
override final var dimensionSizes: ImageCoordinate = ImageCoordinate.createCoordXYZCT(p.sizeX, p.sizeY, p.sizeZ, p.sizeC, p.sizeT)
protected set

/**
Expand All @@ -65,7 +65,7 @@ open class ReadOnlyImageImpl(m: loci.formats.meta.IMetadata, p: PixelData) : Ima
* As per the specification in [ImageCoordinate], users should *not* recycle the ImageCoordinate returned.
* @return The ImageCoordinate whose components are the lower bound on the region of interest, or null if there is no region of interest.
*/
override var boxMin: ImageCoordinate? = null
override final var boxMin: ImageCoordinate? = null
protected set
/**
* Gets the (exclusive) upper bound of any region of interest currently set on this Image, or null if no region is currently
Expand All @@ -75,14 +75,14 @@ open class ReadOnlyImageImpl(m: loci.formats.meta.IMetadata, p: PixelData) : Ima
* As per the specification in [ImageCoordinate], users should *not* recycle the ImageCoordinate returned.
* @return The ImageCoordinate whose components are the upper bound on the region of interest, or null if there is no region of interest.
*/
override var boxMax: ImageCoordinate? = null
override final var boxMax: ImageCoordinate? = null
protected set

/**
* Queries whether the Image is currently boxed with a region of interest.
* @return true if there is currently a region of interest set, false otherwise.
*/
override var isBoxed: Boolean = false
override final var isBoxed: Boolean = false
protected set

protected var coordinateArrayStorage: Array<ImageCoordinate>? = null
Expand Down Expand Up @@ -190,11 +190,13 @@ open class ReadOnlyImageImpl(m: loci.formats.meta.IMetadata, p: PixelData) : Ima
dimensionSizes.recycle()
}

// TODO(colin): this should be an ImageFactory.createEmpty() method instead of a constructor I
// think
protected constructor() : this(
loci.common.services.ServiceFactory()
.getInstance(loci.formats.services.OMEXMLService::class.java)
.createOMEXMLMetadata(),
PixelDataFactory.createPixelData(ImageCoordinate.createCoord())
PixelDataFactory.createPixelData(ImageCoordinate.createCoordXYZCT(1, 1, 1, 1, 1))
) { }

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package edu.stanford.cfuller.imageanalysistools.image

/**
* An extension of a PixelData object that also supports writing of image data.
* @see PixelData
* @author Colin J. Fuller
*/
abstract class WritablePixelData : PixelData(), java.io.Serializable {
/**
* Gets the value of a single pixel at the specified coordinates.
*
* Note that the parameters are passed in the order x,y,z,c,t regardless of the ordering in the underlying byte array representation and
* will be converted to the correct ordering automatically.
*
* Likewise, though the value is passed as a float, it will be converted automatically to the underlying byte representation in the correct format.
* This may lead to the truncation of the passed float value when retrieving the byte array representation. However, the float passed in can still be retreived
* without truncation by calling [.getPixel].
*
* (All coordinates are zero-indexed.)
* @param x The x-coordinate of the pixel to return.
* @param y The y-coordinate of the pixel to return.
* @param z The z-coordinate of the pixel to return.
* @param c The c-coordinate of the pixel to return.
* @param t The t-coordinate of the pixel to return.
* @param value The value to which the pixel at the specified coordinates will be set.
*/
abstract fun setPixel(x: Int, y: Int, z: Int, c: Int, t: Int, value: Float)
companion object {
internal const val serialVersionUID = 7975917259L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import edu.stanford.cfuller.imageanalysistools.filter.morph.ErosionFilter

/**
* A metric that takes each region in a mask and calculates its area and perimeter.
*
* For regions with holes, the perimeter will be the total boundary size both to the
* outside of the region and to the holes.
*
* Area and perimeter are both calculated in units of pixels (# of pixels in the
* region and # of pixels on the border, respectively)
*
* TODO(colin): # of pixels on the border is very odd for small regions (e.g. a 2x2 box has a
* perimeter of 4...). Consider fixing.
* @author Colin J. Fuller
*/
class AreaAndPerimeterMetric : Metric {
Expand All @@ -43,7 +45,7 @@ class AreaAndPerimeterMetric : Metric {
measurement = h.getCounts(it + 1).toDouble(),
name = "area",
type = Measurement.TYPE_SIZE,
image = images.markerImageName!!)
image = images.markerImageName ?: "Marker image")
}
.forEach { q.addMeasurement(it) }

Expand Down Expand Up @@ -71,10 +73,8 @@ class AreaAndPerimeterMetric : Metric {
measurement = hPerim.getCounts(it + 1).toDouble(),
name = "perimeter",
type = Measurement.TYPE_SIZE,
image = images.markerImageName!!) }
image = images.markerImageName ?: "Marker image") }
.forEach { q.addMeasurement(it) }
return q
}
}


Loading

0 comments on commit f05bcc6

Please sign in to comment.