From 9ba48be49d5bc57e54e95372e97e44d80c878300 Mon Sep 17 00:00:00 2001 From: disheng222 Date: Thu, 10 Jun 2021 22:51:37 -0500 Subject: [PATCH] add roibin-example --- example/roibin_example/Makefile | 10 ++ example/roibin_example/ROIBIN-SZ.markdown | 38 +++++++ example/roibin_example/example_lp.c | 129 ++++++++++++++++++++++ example/roibin_example/example_sz.c | 110 ++++++++++++++++++ 4 files changed, 287 insertions(+) create mode 100644 example/roibin_example/Makefile create mode 100644 example/roibin_example/ROIBIN-SZ.markdown create mode 100644 example/roibin_example/example_lp.c create mode 100644 example/roibin_example/example_sz.c diff --git a/example/roibin_example/Makefile b/example/roibin_example/Makefile new file mode 100644 index 0000000..f3f79ae --- /dev/null +++ b/example/roibin_example/Makefile @@ -0,0 +1,10 @@ +.PHONY: all clean +ALL=example_sz example_lp +all: $(ALL) +clean: + $(RM) $(ALL) $(wildcard *.o) +example_sz: CFLAGS=$(shell pkg-config --cflags sz) +example_sz: LDFLAGS=$(shell pkg-config --libs sz) +example_lp: CFLAGS=$(shell pkg-config --cflags libpressio) +example_lp: LDFLAGS=$(shell pkg-config --libs libpressio) + diff --git a/example/roibin_example/ROIBIN-SZ.markdown b/example/roibin_example/ROIBIN-SZ.markdown new file mode 100644 index 0000000..fb55517 --- /dev/null +++ b/example/roibin_example/ROIBIN-SZ.markdown @@ -0,0 +1,38 @@ +# Using ROIBIN-SZ + +## Installing ROIBIN-SZ + +ROIBIN-SZ is included in SZ after release 2.1.11.1. + +The easiest and recommended way to use ROIBIN-SZ is to use libpressio which provides additional error checking and ease of use above the SZ C interface. + +They can both can be installed easily via [spack](https://github.com/spack/spack) on Linux and MacOS: + +```bash +git clone https://github.com/spack/spack +git clone https://github.com/robertu94/spack_packages robertu94_packages # only for libpressio +source ./spack/share/spack/setup-env.sh +spack compiler find +spack repo add ./robertu94_packages + +spack install libpressio^sz +``` + +## Using ROIBIN-SZ + + +Examples for both can be found in `example_lp.c` and `example_sz.c` respectively. +These files will need to be customized to load data for your specific detector. + +Here are a few of the important configuration parameters: + ++ `bin_size ` for ROIBIN-SZ, the size of the binning applied ++ `calib_panel ` for ROIBIN-SZ the size of the calibration panel. Expects a array of the same dimensions as the input with a 1 to indicate that an entry should be ignored. ++ `num_peaks ` for ROIBIN-SZ the number of peaks. ++ `peak_size ` for ROIBIN-SZ the size of the region of interest around the peaks. Must be odd. ++ `peaks_cols ` for ROIBIN-SZ the list of columns peaks appear in ++ `peaks_rows ` for ROIBIN-SZ the list of rows peaks appear in ++ `peaks_segs ` for ROIBIN-SZ the segments peaks appear in ++ `sz_dim ` for ROIBIN-SZ the SZ dimensionality prefered. 3 is recommended ++ `tolerance ` for ROIBIN-SZ the tolerance used after binning + diff --git a/example/roibin_example/example_lp.c b/example/roibin_example/example_lp.c new file mode 100644 index 0000000..b698398 --- /dev/null +++ b/example/roibin_example/example_lp.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include "libpressio.h" +#include "libpressio_ext/io/pressio_io.h" + +size_t determine_n_peaks() { + assert(0 && "remove this asssert after you have the code to determine the number of peaks"); + return 0; +} + +struct pressio_data* load_calib(const char* path, size_t n_dims, size_t dims[]) { + struct pressio_data* calib_panel = pressio_data_new_owning(pressio_uint8_dtype, n_dims, dims); + uint8_t* calib_panel_ptr = pressio_data_ptr(calib_panel, NULL); + + //TODO fill in the calibration panel + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect each index to be a 8bit 0/1 mask which is 1 when a pixel should be IGNORED + // it should be the same size and shape as the input + (void)path; + assert(0 && "remove this assert after you have the load_calib function"); + + return calib_panel; +} + +struct pressio_data* load_location_info(const char* path, size_t n_peaks) { + struct pressio_data* location_data = pressio_data_new_owning(pressio_uint16_dtype, 1, &n_peaks); + uint16_t* location_data_ptr = pressio_data_ptr(location_data, NULL); + + //TODO fill in the location_data panel + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect each index to be a 16bit unsigned integer that indicates one part of of a location of a peak + + //TODO ignore the path parameter, until it is filled in sanely + assert(0 && "remove this assert after you have the load_location_info function"); + (void)path; + + return location_data; +} + +struct pressio_data* load_input_data(const char* path, size_t n_dims, size_t dims[]) { + struct pressio_data* input_data = pressio_data_new_owning(pressio_float_dtype, n_dims, dims); + float* input_data_ptr = pressio_data_ptr(input_data, NULL); + + //TODO fill in the input data + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect this to be the actual float 32bit data with 3 or 4 dimensions + // if it is 3d, we expect it to be panels, rows, cols from slowest to fastest incrementing index; we assume a single event for 3d + // if it is 4d, we expect it to be events, panels, rows, cols from slowest to fastest incrementing index + (void) path; + assert(0 && "remove this assert after you have the load_input_data function"); + + return input_data; +} + +int main(int argc, char *argv[]) +{ + struct pressio* library = pressio_instance(); + assert(library != NULL && "something is gravely wrong with your installation of libpressio"); + struct pressio_compressor* compressor = pressio_get_compressor(library, "sz"); + assert(library != NULL && "you build libpressio without sz"); + + //TODO fill in code that sets the input dimensions + const size_t n_dims = 4; + size_t dims[4] = {0,0,0,0}; + assert(0 && "remove this asssert after you have the code to determine input data dimensions"); + + struct pressio_data* input = load_input_data("input.f32", n_dims, dims); + struct pressio_data* calib_panel = load_calib("calib.u8", n_dims, dims); + assert(calib_panel != NULL && "remove this assert after you have the code to determine calib_panel"); + + const size_t n_peaks = determine_n_peaks(); + struct pressio_data* peak_rows = load_location_info("rows.u16", n_peaks); + struct pressio_data* peak_cols = load_location_info("cols.u16", n_peaks); + struct pressio_data* peak_segs = load_location_info("segs.u16", n_peaks); + assert(peak_rows != NULL && "remote this assert fill in the code to determine the number of peaks"); + assert(peak_cols != NULL && "remove this assert after you have the code to determine the number of peaks"); + assert(peak_segs != NULL && "remove this assert after you have the code to determine the number of peaks"); + + + + struct pressio_options* options = pressio_options_new(); + assert(options != NULL && "failed to create options; something is gravely wrong"); + pressio_options_set_string(options, "sz:app", "ExaFEL"); + pressio_options_set_uinteger(options, "sz:exafel:bin_size", 2); + pressio_options_set_uinteger(options, "sz:exafel:num_peaks", n_peaks); + pressio_options_set_uinteger(options, "sz:exafel:sz_dim", 3); + pressio_options_set_uinteger(options, "sz:exafel:peak_size", 3); //must be odd + pressio_options_set_double(options, "sz:exafel:tolerance", 1e-6); + pressio_options_set_data(options, "sz:exafel:calib_panel", calib_panel); + pressio_options_set_data(options, "sz:exafel:peak_cols", peak_rows); + pressio_options_set_data(options, "sz:exafel:peak_rows", peak_cols); + pressio_options_set_data(options, "sz:exafel:peak_segs", peak_segs); + + if(pressio_compressor_check_options(compressor, options) != 0) { + fprintf(stderr, "%s\n", pressio_compressor_error_msg(compressor)); + exit(pressio_compressor_error_code(compressor)); + } + if(pressio_compressor_set_options(compressor, options) != 0) { + fprintf(stderr, "%s\n", pressio_compressor_error_msg(compressor)); + exit(pressio_compressor_error_code(compressor)); + } + pressio_data_free(calib_panel); + pressio_data_free(peak_segs); + pressio_data_free(peak_rows); + pressio_data_free(peak_cols); + pressio_options_free(options); + + struct pressio_data* compressed = pressio_data_new_empty(pressio_byte_dtype, 0, NULL); + if(pressio_compressor_compress(compressor, input, compressed) != 0) { + fprintf(stderr, "%s\n", pressio_compressor_error_msg(compressor)); + exit(pressio_compressor_error_code(compressor)); + } + + struct pressio_data* output = pressio_data_new_clone(input); + if(pressio_compressor_decompress(compressor, compressed, output) != 0) { + fprintf(stderr, "%s\n", pressio_compressor_error_msg(compressor)); + exit(pressio_compressor_error_code(compressor)); + } + + + pressio_data_free(input); + pressio_data_free(compressed); + pressio_data_free(output); + pressio_compressor_release(compressor); + pressio_release(library); + + return 0; +} diff --git a/example/roibin_example/example_sz.c b/example/roibin_example/example_sz.c new file mode 100644 index 0000000..a5ace6a --- /dev/null +++ b/example/roibin_example/example_sz.c @@ -0,0 +1,110 @@ +#include +#include +#include "sz.h" + +size_t determine_n_peaks() { + assert(0 && "remove this asssert after you have the code to determine the number of peaks"); + return 0; +} + +uint8_t* load_calib(const char* path, size_t n_dims, size_t dims[]) { + size_t total_dims = 1; + for (size_t i = 0; i < n_dims; ++i) { + total_dims *= dims[i]; + } + uint8_t* calib_panel_ptr = malloc(total_dims * sizeof(uint8_t)); + + //TODO fill in the calibration panel + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect each index to be a 8bit 0/1 mask which is 1 when a pixel should be IGNORED + // it should be the same size and shape as the input + (void)path; + assert(0 && "remove this assert after you have the load_calib function"); + + return calib_panel_ptr; +} + +uint16_t* load_location_info(const char* path, size_t n_peaks) { + uint16_t* location_data_ptr = malloc(n_peaks*sizeof(uint16_t)); + + //TODO fill in the location_data panel + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect each index to be a 16bit unsigned integer that indicates one part of of a location of a peak + + //TODO ignore the path parameter, until it is filled in sanely + assert(0 && "remove this assert after you have the load_location_info function"); + (void)path; + + return location_data_ptr; +} + +float* load_input_data(const char* path, size_t n_dims, size_t dims[]) { + size_t total_dims = 1; + for (size_t i = 0; i < n_dims; ++i) { + total_dims *= dims[i]; + } + float* input_data = malloc(total_dims*sizeof(float)); + + //TODO fill in the input data + // In reality this is known from HDF5 and conversions have to be done for some formats + // we expect this to be the actual float 32bit data with 3 or 4 dimensions + // if it is 3d, we expect it to be panels, rows, cols from slowest to fastest incrementing index; we assume a single event for 3d + // if it is 4d, we expect it to be events, panels, rows, cols from slowest to fastest incrementing index + (void) path; + assert(0 && "remove this assert after you have the load_input_data function"); + + return input_data; +} + + +int main(int argc, char *argv[]) +{ + SZ_Init(NULL); + exafelSZ_params params; + + //TODO fill in code that sets the input dimensions + const size_t n_dims = 4; + size_t dims[4] = {0,0,0,0}; + assert(0 && "remove this asssert after you have the code to determine input data dimensions"); + + const size_t n_peaks = determine_n_peaks(); + + float* input = load_input_data("input.f32", n_dims, dims); + params.binSize = 2; + params.numPeaks = n_peaks; + params.szDim = 3; + params.peakSize = 3; //must be odd + params.tolerance = 1e-6; + params.calibPanel = load_calib("calib.u8", n_dims, dims); + params.peaksCols = load_location_info("cols.u16", n_peaks); + params.peaksRows = load_location_info("rows.u16", n_peaks); + params.peaksSegs = load_location_info("segs.u16", n_peaks); + assert(params.peaksRows != NULL && "remote this assert fill in the code to determine the number of peaks"); + assert(params.peaksCols != NULL && "remove this assert after you have the code to determine the number of peaks"); + assert(params.peaksSegs != NULL && "remove this assert after you have the code to determine the number of peaks"); + assert(params.calibPanel != NULL && "remove this assert after you have the code to determine the number of peaks"); + + + size_t output_size = 0; + int status = 0; + unsigned char* compressed = SZ_compress_customize("ExaFEL", ¶ms, SZ_FLOAT, input, 0, dims[0], dims[1], dims[2], dims[3], &output_size, &status); + if(status) { + fprintf(stderr, "something went wrong during compression\n"); + exit(1); + } + float * output = SZ_decompress_customize("ExaFEL", ¶ms, SZ_FLOAT, compressed, output_size, 0, dims[0], dims[1], dims[2], dims[3], &status); + if(status) { + fprintf(stderr, "something went wrong during compression\n"); + exit(1); + } + + free(params.peaksSegs); + free(params.peaksCols); + free(params.peaksRows); + free(params.calibPanel); + free(input); + free(compressed); + free(output); + + return 0; +}