Skip to content
Snippets Groups Projects
Commit d60f5acf authored by Vojtech Moravec's avatar Vojtech Moravec
Browse files

WIP: HyperStackDimensions improvements. Separate version in pom.

parent 90514ea6
Branches extended_loader_api
No related tags found
No related merge requests found
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
<groupId>cz.it4i</groupId> <groupId>cz.it4i</groupId>
<artifactId>QcmpCompression</artifactId> <artifactId>QcmpCompression</artifactId>
<version>0.5-SNAPSHOT</version> <version>0.5.5-EXP-SNAPSHOT</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>RELEASE</version> <version>5.7.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
......
...@@ -37,6 +37,7 @@ public class SQBenchmark extends BenchmarkBase { ...@@ -37,6 +37,7 @@ public class SQBenchmark extends BenchmarkBase {
if (planes.length < 1) { if (planes.length < 1) {
return; return;
} }
final boolean dirCreated = new File(this.outputDirectory).mkdirs(); final boolean dirCreated = new File(this.outputDirectory).mkdirs();
System.out.println(String.format("|CODEBOOK| = %d", codebookSize)); System.out.println(String.format("|CODEBOOK| = %d", codebookSize));
ScalarQuantizer quantizer = null; ScalarQuantizer quantizer = null;
......
package cz.it4i.qcmp.data; package cz.it4i.qcmp.data;
import cz.it4i.qcmp.utilities.Utils;
import java.util.Objects; import java.util.Objects;
/** /**
...@@ -11,6 +13,7 @@ public class HyperStackDimensions { ...@@ -11,6 +13,7 @@ public class HyperStackDimensions {
private final int height; private final int height;
private final int planeCount; private final int planeCount;
private final int numberOfTimepoints; private final int numberOfTimepoints;
private final int numberOfChannels;
/** /**
* Create HyperStackDimensions. * Create HyperStackDimensions.
...@@ -19,37 +22,34 @@ public class HyperStackDimensions { ...@@ -19,37 +22,34 @@ public class HyperStackDimensions {
* @param height Height of the plane. * @param height Height of the plane.
* @param planeCount Plane count in the stack. * @param planeCount Plane count in the stack.
* @param numberOfTimepoints Number of stack timepoints. * @param numberOfTimepoints Number of stack timepoints.
* @param channelCount Number of image channels.
*/ */
public HyperStackDimensions(final int width, final int height, final int planeCount, final int numberOfTimepoints) { public HyperStackDimensions(final int width,
final int height,
final int planeCount,
final int numberOfTimepoints,
final int channelCount) {
assert (channelCount == 1) : "QcmpCompressionLibrary support only single channel datasets.";
this.width = width; this.width = width;
this.height = height; this.height = height;
this.planeCount = planeCount; this.planeCount = planeCount;
this.numberOfTimepoints = numberOfTimepoints; this.numberOfTimepoints = numberOfTimepoints;
this.numberOfChannels = channelCount;
} }
/** /**
* Get number of elements in hyperstack with dimensionality = dimension. * Create HyperStackDimensions.
* When calculating the element count, overflow is checked. This is because result of this
* function is usually used in places where we want to allocate memory.
* *
* @param dimension Maximum dimension. * @param width Width of the plane.
* @return Number of elements. * @param height Height of the plane.
* @param planeCount Plane count in the stack.
* @param numberOfTimepoints Number of stack timepoints.
*/ */
@SuppressWarnings("DuplicateExpressions") public HyperStackDimensions(final int width,
public int getNumberOfElementsInDimension(final int dimension) { final int height,
switch (dimension) { final int planeCount,
case 1: final int numberOfTimepoints) {
return width; this(width, height, planeCount, numberOfTimepoints, 1);
case 2:
return Math.multiplyExact(width, height);
case 3:
return Math.multiplyExact(planeCount, Math.multiplyExact(width, height));
case 4:
return Math.multiplyExact(numberOfTimepoints, Math.multiplyExact(planeCount, Math.multiplyExact(width, height)));
default:
assert (false) : "Wrong dimension in getNumberOfElementsInDimension";
return -1;
}
} }
/** /**
...@@ -60,7 +60,7 @@ public class HyperStackDimensions { ...@@ -60,7 +60,7 @@ public class HyperStackDimensions {
* @param planeCount Plane count in the stack. * @param planeCount Plane count in the stack.
*/ */
public HyperStackDimensions(final int width, final int height, final int planeCount) { public HyperStackDimensions(final int width, final int height, final int planeCount) {
this(width, height, planeCount, 1); this(width, height, planeCount, 1, 1);
} }
/** /**
...@@ -70,7 +70,46 @@ public class HyperStackDimensions { ...@@ -70,7 +70,46 @@ public class HyperStackDimensions {
* @param height Height of the plane. * @param height Height of the plane.
*/ */
public HyperStackDimensions(final int width, final int height) { public HyperStackDimensions(final int width, final int height) {
this(width, height, 1, 1); this(width, height, 1, 1, 1);
}
/**
* Create HyperStackDimensions from ij.ImagePlus dimensions array.
*
* @param imagePlusDimensions ImagePlus dimensions.
* @return Correct HyperStackDimensions.
*/
public static HyperStackDimensions createFromImagePlusDimensions(final int[] imagePlusDimensions) {
// NOTE(Moravec): ij.ImagePlus dimensions array = (width, height, nChannels, nSlices, nFrames)
return new HyperStackDimensions(imagePlusDimensions[0],
imagePlusDimensions[1],
imagePlusDimensions[3],
imagePlusDimensions[4],
imagePlusDimensions[2]);
}
/**
* Get number of elements in hyperstack with dimensionality = dimension.
* When calculating the element count, overflow is checked. This is because result of this
* function is usually used in places where we want to allocate memory.
*
* @param dimension Maximum dimension.
* @return Number of elements.
*/
public int getNumberOfElementsInDimension(final int dimension) {
switch (dimension) {
case 1:
return width;
case 2:
return Math.multiplyExact(width, height);
case 3:
return Utils.multiplyExact(width, height, planeCount);
case 4:
return Utils.multiplyExact(width, height, planeCount, numberOfChannels);
default:
assert (false) : "Wrong dimension in getNumberOfElementsInDimension";
return -1;
}
} }
/** /**
...@@ -109,6 +148,14 @@ public class HyperStackDimensions { ...@@ -109,6 +148,14 @@ public class HyperStackDimensions {
return new V2i(width, height); return new V2i(width, height);
} }
/**
* Get number of channels in the dataset.
*
* @return Channel count.
*/
public int getNumberOfChannels() {
return numberOfChannels;
}
/** /**
* Get number of timepoints of the stack. * Get number of timepoints of the stack.
......
...@@ -160,4 +160,36 @@ public class Utils { ...@@ -160,4 +160,36 @@ public class Utils {
} }
return Math.sqrt(sum); return Math.sqrt(sum);
} }
/**
* Returns the product of the arguments,
* throwing an exception if the result overflows an {@code int}.
*
* @param numbers values to multiply
* @return the result
* @throws ArithmeticException if the result overflows an int
*/
public static int multiplyExact(final int... numbers) throws ArithmeticException {
int result = numbers[0];
for (int i = 1; i < numbers.length; i++) {
result = Math.multiplyExact(result, numbers[i]);
}
return result;
}
/**
* Returns the product of the arguments,
* throwing an exception if the result overflows an {@code int}.
*
* @param numbers values to multiply
* @return the result
* @throws ArithmeticException if the result overflows an int
*/
public static long multiplyExact(final long... numbers) throws ArithmeticException {
long result = numbers[0];
for (int i = 1; i < numbers.length; i++) {
result = Math.multiplyExact(result, numbers[i]);
}
return result;
}
} }
\ No newline at end of file
package cz.it4i.qcmp.utilities;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class UtilsTest {
@Test
void multiplyExact() {
final int a = 200;
final int b = 54;
final int c = 783;
final int refResult = Math.multiplyExact(a, Math.multiplyExact(b, c));
final int result = Utils.multiplyExact(a, b, c);
Assertions.assertEquals(refResult, result);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment