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

Added custom function method.

parent d4cf4ff8
No related branches found
No related tags found
No related merge requests found
...@@ -2,11 +2,12 @@ package azgracompress; ...@@ -2,11 +2,12 @@ package azgracompress;
import azgracompress.benchmark.CompressionBenchmark; import azgracompress.benchmark.CompressionBenchmark;
import azgracompress.cli.CliConstants; import azgracompress.cli.CliConstants;
import azgracompress.cli.CustomFunctionBase;
import azgracompress.cli.ParsedCliOptions; import azgracompress.cli.ParsedCliOptions;
import azgracompress.cli.functions.MeasurePlaneErrorFunction;
import azgracompress.compression.ImageCompressor; import azgracompress.compression.ImageCompressor;
import azgracompress.compression.ImageDecompressor; import azgracompress.compression.ImageDecompressor;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
...@@ -14,7 +15,7 @@ public class DataCompressor { ...@@ -14,7 +15,7 @@ public class DataCompressor {
public static void main(String[] args) { public static void main(String[] args) {
Options options = getOptions(); Options options = CliConstants.getOptions();
HelpFormatter formatter = new HelpFormatter(); HelpFormatter formatter = new HelpFormatter();
CommandLineParser parser = new DefaultParser(); CommandLineParser parser = new DefaultParser();
...@@ -67,6 +68,17 @@ public class DataCompressor { ...@@ -67,6 +68,17 @@ public class DataCompressor {
} }
return; return;
} }
case CustomFunction: {
// NOTE(Moravec): Custom function class here |
// V
CustomFunctionBase customFunction = new MeasurePlaneErrorFunction(parsedCliOptions);
if (!customFunction.run()) {
System.err.println("Errors occurred during custom function.");
}
return;
}
case PrintHelp: { case PrintHelp: {
formatter.printHelp(CliConstants.MAIN_HELP, options); formatter.printHelp(CliConstants.MAIN_HELP, options);
} }
...@@ -85,74 +97,4 @@ public class DataCompressor { ...@@ -85,74 +97,4 @@ public class DataCompressor {
} }
return; return;
} }
@NotNull
private static Options getOptions() {
Options options = new Options();
OptionGroup methodGroup = new OptionGroup();
methodGroup.setRequired(true);
methodGroup.addOption(new Option(CliConstants.COMPRESS_SHORT,
CliConstants.COMPRESS_LONG,
false,
"Compress 16 bit raw image"));
methodGroup.addOption(new Option(CliConstants.DECOMPRESS_SHORT,
CliConstants.DECOMPRESS_LONG,
false,
"Decompress 16 bit raw image"));
methodGroup.addOption(new Option(CliConstants.INSPECT_SHORT,
CliConstants.INSPECT_LONG,
false,
"Inspect the compressed file"));
methodGroup.addOption(new Option(CliConstants.BENCHMARK_SHORT,
CliConstants.BENCHMARK_LONG,
false,
"Benchmark"));
methodGroup.addOption(new Option(CliConstants.TRAIN_SHORT,
CliConstants.TRAIN_LONG,
false,
"Train codebook and save learned codebook to cache file."));
methodGroup.addOption(new Option(CliConstants.HELP_SHORT, CliConstants.HELP_LONG, false, "Print help"));
OptionGroup compressionMethodGroup = new OptionGroup();
compressionMethodGroup.addOption(new Option(CliConstants.SCALAR_QUANTIZATION_SHORT,
CliConstants.SCALAR_QUANTIZATION_LONG,
false,
"Use scalar quantization."));
compressionMethodGroup.addOption(new Option(CliConstants.VECTOR_QUANTIZATION_SHORT,
CliConstants.VECTOR_QUANTIZATION_LONG,
true,
"Use vector quantization. Need to pass vector size eg. 9,9x1,3x3"));
options.addOptionGroup(methodGroup);
options.addOptionGroup(compressionMethodGroup);
options.addOption(CliConstants.BITS_SHORT, CliConstants.BITS_LONG, true, "Bit count per pixel [Default 8]");
options.addOption(CliConstants.REFERENCE_PLANE_SHORT,
CliConstants.REFERENCE_PLANE_LONG,
true,
"Reference plane index");
options.addOption(new Option(CliConstants.VERBOSE_SHORT,
CliConstants.VERBOSE_LONG,
false,
"Make program verbose"));
options.addOption(new Option(CliConstants.WORKER_COUNT_SHORT,
CliConstants.WORKER_COUNT_LONG,
true,
"Number of worker threads"));
options.addOption(new Option(CliConstants.CODEBOOK_CACHE_FOLDER_SHORT,
CliConstants.CODEBOOK_CACHE_FOLDER_LONG,
true,
"Folder of codebook caches"));
options.addOption(CliConstants.OUTPUT_SHORT, CliConstants.OUTPUT_LONG, true, "Custom output file");
return options;
}
} }
package azgracompress.cli; package azgracompress.cli;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.jetbrains.annotations.NotNull;
public class CliConstants { public class CliConstants {
public static final String MAIN_HELP = "azgracompress.DataCompressor [options] input"; public static final String MAIN_HELP = "azgracompress.DataCompressor [options] input";
...@@ -22,6 +27,9 @@ public class CliConstants { ...@@ -22,6 +27,9 @@ public class CliConstants {
public static final String INSPECT_SHORT = "i"; public static final String INSPECT_SHORT = "i";
public static final String INSPECT_LONG = "inspect"; public static final String INSPECT_LONG = "inspect";
public static final String CUSTOM_FUNCTION_SHORT = "cf";
public static final String CUSTOM_FUNCTION_LONG = "custom-function";
public static final String BITS_SHORT = "b"; public static final String BITS_SHORT = "b";
public static final String BITS_LONG = "bits"; public static final String BITS_LONG = "bits";
...@@ -46,4 +54,79 @@ public class CliConstants { ...@@ -46,4 +54,79 @@ public class CliConstants {
public static final String REFERENCE_PLANE_SHORT = "rp"; public static final String REFERENCE_PLANE_SHORT = "rp";
public static final String REFERENCE_PLANE_LONG = "reference-plane"; public static final String REFERENCE_PLANE_LONG = "reference-plane";
@NotNull
public static Options getOptions() {
Options options = new Options();
OptionGroup methodGroup = new OptionGroup();
methodGroup.setRequired(true);
methodGroup.addOption(new Option(CliConstants.COMPRESS_SHORT,
CliConstants.COMPRESS_LONG,
false,
"Compress 16 bit raw image"));
methodGroup.addOption(new Option(CliConstants.DECOMPRESS_SHORT,
CliConstants.DECOMPRESS_LONG,
false,
"Decompress 16 bit raw image"));
methodGroup.addOption(new Option(CliConstants.INSPECT_SHORT,
CliConstants.INSPECT_LONG,
false,
"Inspect the compressed file"));
methodGroup.addOption(new Option(CliConstants.BENCHMARK_SHORT,
CliConstants.BENCHMARK_LONG,
false,
"Benchmark"));
methodGroup.addOption(new Option(CliConstants.TRAIN_SHORT,
CliConstants.TRAIN_LONG,
false,
"Train codebook and save learned codebook to cache file."));
methodGroup.addOption(new Option(CliConstants.CUSTOM_FUNCTION_SHORT,
CliConstants.CUSTOM_FUNCTION_LONG,
false,
"Run user compiled custom code."));
methodGroup.addOption(new Option(CliConstants.HELP_SHORT, CliConstants.HELP_LONG, false, "Print help"));
OptionGroup compressionMethodGroup = new OptionGroup();
compressionMethodGroup.addOption(new Option(CliConstants.SCALAR_QUANTIZATION_SHORT,
CliConstants.SCALAR_QUANTIZATION_LONG,
false,
"Use scalar quantization."));
compressionMethodGroup.addOption(new Option(CliConstants.VECTOR_QUANTIZATION_SHORT,
CliConstants.VECTOR_QUANTIZATION_LONG,
true,
"Use vector quantization. Need to pass vector size eg. 9,9x1,3x3"));
options.addOptionGroup(methodGroup);
options.addOptionGroup(compressionMethodGroup);
options.addOption(CliConstants.BITS_SHORT, CliConstants.BITS_LONG, true, "Bit count per pixel [Default 8]");
options.addOption(CliConstants.REFERENCE_PLANE_SHORT,
CliConstants.REFERENCE_PLANE_LONG,
true,
"Reference plane index");
options.addOption(new Option(CliConstants.VERBOSE_SHORT,
CliConstants.VERBOSE_LONG,
false,
"Make program verbose"));
options.addOption(new Option(CliConstants.WORKER_COUNT_SHORT,
CliConstants.WORKER_COUNT_LONG,
true,
"Number of worker threads"));
options.addOption(new Option(CliConstants.CODEBOOK_CACHE_FOLDER_SHORT,
CliConstants.CODEBOOK_CACHE_FOLDER_LONG,
true,
"Folder of codebook caches"));
options.addOption(CliConstants.OUTPUT_SHORT, CliConstants.OUTPUT_LONG, true, "Custom output file");
return options;
}
} }
package azgracompress.cli;
public abstract class CustomFunctionBase {
protected final ParsedCliOptions options;
/**
* Base constructor with parsed CLI options.
* @param options Parsed cli options.
*/
public CustomFunctionBase(ParsedCliOptions options) {
this.options = options;
}
/**
* Run custom function.
* @return True if no errors occurred.
*/
public abstract boolean run();
}
...@@ -46,9 +46,13 @@ public class ParsedCliOptions { ...@@ -46,9 +46,13 @@ public class ParsedCliOptions {
} }
private String getDefaultOutputFilePath(final String inputPath) { private String getDefaultOutputFilePath(final String inputPath) {
if (method == ProgramMethod.CustomFunction)
return "";
final File inputFile = new File(inputPath); final File inputFile = new File(inputPath);
final File outputFile = new File(Paths.get("").toAbsolutePath().toString(), inputFile.getName()); final File outputFile = new File(Paths.get("").toAbsolutePath().toString(), inputFile.getName());
String defaultValue = outputFile.getAbsolutePath(); String defaultValue = outputFile.getAbsolutePath();
switch (method) { switch (method) {
...@@ -67,7 +71,6 @@ public class ParsedCliOptions { ...@@ -67,7 +71,6 @@ public class ParsedCliOptions {
defaultValue = new File(inputFile.getParent(), "benchmark").getAbsolutePath(); defaultValue = new File(inputFile.getParent(), "benchmark").getAbsolutePath();
} }
break; break;
case PrintHelp: case PrintHelp:
break; break;
case InspectFile: case InspectFile:
...@@ -130,6 +133,9 @@ public class ParsedCliOptions { ...@@ -130,6 +133,9 @@ public class ParsedCliOptions {
// We require the file path and dimensions, like input.raw 1920x1080x5 // We require the file path and dimensions, like input.raw 1920x1080x5
if (fileInfo.length < 2) { if (fileInfo.length < 2) {
if (method == ProgramMethod.CustomFunction) {
return;
}
errorOccurred = true; errorOccurred = true;
errorBuilder.append("Both filepath and file dimensions are required arguments\n"); errorBuilder.append("Both filepath and file dimensions are required arguments\n");
} else { } else {
...@@ -320,6 +326,8 @@ public class ParsedCliOptions { ...@@ -320,6 +326,8 @@ public class ParsedCliOptions {
method = ProgramMethod.TrainCodebook; method = ProgramMethod.TrainCodebook;
} else if (cmd.hasOption(CliConstants.INSPECT_LONG)) { } else if (cmd.hasOption(CliConstants.INSPECT_LONG)) {
method = ProgramMethod.InspectFile; method = ProgramMethod.InspectFile;
} else if (cmd.hasOption(CliConstants.CUSTOM_FUNCTION_LONG)) {
method = ProgramMethod.CustomFunction;
} else { } else {
errorOccurred = true; errorOccurred = true;
errorBuilder.append("No program method was matched\n"); errorBuilder.append("No program method was matched\n");
......
...@@ -6,5 +6,6 @@ public enum ProgramMethod { ...@@ -6,5 +6,6 @@ public enum ProgramMethod {
Benchmark, Benchmark,
TrainCodebook, TrainCodebook,
PrintHelp, PrintHelp,
CustomFunction,
InspectFile InspectFile
} }
package azgracompress.cli.functions;
import azgracompress.cli.CustomFunctionBase;
import azgracompress.cli.ParsedCliOptions;
import azgracompress.data.ImageU16;
import azgracompress.data.V3i;
import azgracompress.io.RawDataIO;
import azgracompress.utilities.Utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
public class MeasurePlaneErrorFunction extends CustomFunctionBase {
public MeasurePlaneErrorFunction(ParsedCliOptions options) {
super(options);
}
@Override
public boolean run() {
final String referenceFile = "D:\\biology\\tiff_data\\benchmark\\fused_tp_10_ch_0_16bit.raw";
final String compressedFile = "D:\\biology\\tiff_data\\quantized\\fused_tp_10_ch_0_16bit_sq_cb256.raw";
final String reportFile = "D:\\biology\\tiff_data\\quantized\\sq_cb256_plane_log.data";
final V3i dims = new V3i(1041, 996, 946);
final int planePixelCount = dims.getX() * dims.getY();
System.out.println(options.report());
System.out.println("Run custom function.");
ImageU16 compressedPlane = null;
ImageU16 originalPlane = null;
ImageU16 differencePlane = null;
PlaneError[] planeErrors = new PlaneError[dims.getZ()];
for (int planeIndex = 0; planeIndex < dims.getZ(); planeIndex++) {
try {
originalPlane = RawDataIO.loadImageU16(referenceFile, dims, planeIndex);
compressedPlane = RawDataIO.loadImageU16(compressedFile, dims, planeIndex);
} catch (IOException e) {
e.printStackTrace();
return false;
}
final int[] diffData = Utils.getDifference(originalPlane.getData(), compressedPlane.getData());
Utils.applyAbsFunction(diffData);
final double absDiffSum = Arrays.stream(diffData).mapToDouble(v -> v).sum();
final double meanPixelError = absDiffSum / (double) planePixelCount;
planeErrors[planeIndex] = new PlaneError(planeIndex, absDiffSum, meanPixelError);
System.out.println("Finished plane: " + planeIndex);
}
try (FileOutputStream fos = new FileOutputStream(reportFile, false);
OutputStreamWriter writer = new OutputStreamWriter(fos)) {
writer.write("PlaneIndex\tErrorSum\tMeanError\n");
for (final PlaneError planeError : planeErrors) {
writer.write(String.format("%d\t%.4f\t%.4f\n",
planeError.getPlaneIndex(),
planeError.getAbsoluteError(),
planeError.getMeanAbsoluteError()));
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
package azgracompress.cli.functions;
public class PlaneError {
private final int planeIndex;
private final double absoluteError;
private final double meanAbsoluteError;
public PlaneError(int planeIndex, double absoluteError, double meanAbsoluteError) {
this.planeIndex = planeIndex;
this.absoluteError = absoluteError;
this.meanAbsoluteError = meanAbsoluteError;
}
public int getPlaneIndex() {
return planeIndex;
}
public double getAbsoluteError() {
return absoluteError;
}
public double getMeanAbsoluteError() {
return meanAbsoluteError;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment