v1.0.0-rc.40
This commit is contained in:
@@ -109,6 +109,21 @@ namespace {
|
||||
return map_len;
|
||||
}
|
||||
|
||||
Coord GetCoord(CborValue &value) {
|
||||
CborValue array_value;
|
||||
Coord c;
|
||||
|
||||
if (GetCBORArrayLen(value) != 3)
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Vector of 3 elements expected");
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &array_value));
|
||||
c.x = GetCBORFloat(array_value);
|
||||
c.y = GetCBORFloat(array_value);
|
||||
c.z = GetCBORFloat(array_value);
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
return c;
|
||||
}
|
||||
|
||||
std::pair<uint64_t, uint64_t> GetRational(CborValue &value) {
|
||||
std::pair<uint64_t, uint64_t> ret;
|
||||
if (GetCBORArrayLen(value) != 2)
|
||||
@@ -168,21 +183,15 @@ namespace {
|
||||
return unit_cell;
|
||||
}
|
||||
|
||||
std::pair<uint64_t, uint64_t> GetCBORDimension2DArray(CborValue &value) {
|
||||
std::pair<uint64_t, uint64_t> ret;
|
||||
|
||||
if (GetCBORArrayLen(value) != 2)
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Only 2D arrays allowed");
|
||||
|
||||
std::vector<uint64_t> GetCBORDimensionArray(CborValue &value) {
|
||||
std::vector<uint64_t> ret;
|
||||
CborValue array_value;
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &array_value));
|
||||
|
||||
ret.second = GetCBORUInt(array_value);
|
||||
ret.first = GetCBORUInt(array_value);
|
||||
while (!cbor_value_at_end(&array_value))
|
||||
ret.push_back(GetCBORUInt(array_value));
|
||||
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -256,49 +265,38 @@ namespace {
|
||||
memcpy(v.data(), ptr, len);
|
||||
}
|
||||
|
||||
void GetCBORTypedArray(CompressedImage &v, CborValue &value) {
|
||||
CborTag tag = GetCBORTag(value);
|
||||
|
||||
switch (tag) {
|
||||
CompressedImageMode GetImageMode(CborTag input) {
|
||||
switch (input) {
|
||||
case TagHalfLE:
|
||||
return CompressedImageMode::Float16;
|
||||
case TagFloatLE:
|
||||
v.pixel_is_signed = true;
|
||||
v.pixel_depth_bytes = sizeof(float);
|
||||
v.pixel_is_float = true;
|
||||
break;
|
||||
return CompressedImageMode::Float32;
|
||||
case TagDoubleLE:
|
||||
return CompressedImageMode::Float64;
|
||||
case TagSignedInt8Bit:
|
||||
v.pixel_is_signed = true;
|
||||
v.pixel_depth_bytes = 1;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Int8;
|
||||
case TagUnsignedInt8Bit:
|
||||
v.pixel_is_signed = false;
|
||||
v.pixel_depth_bytes = 1;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Uint8;
|
||||
case TagSignedInt16BitLE:
|
||||
v.pixel_is_signed = true;
|
||||
v.pixel_depth_bytes = 2;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Int16;
|
||||
case TagUnsignedInt16BitLE:
|
||||
v.pixel_is_signed = false;
|
||||
v.pixel_depth_bytes = 2;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Uint16;
|
||||
case TagSignedInt32BitLE:
|
||||
v.pixel_is_signed = true;
|
||||
v.pixel_depth_bytes = 4;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Int32;
|
||||
case TagUnsignedInt32BitLE:
|
||||
v.pixel_is_signed = false;
|
||||
v.pixel_depth_bytes = 4;
|
||||
v.pixel_is_float = false;
|
||||
break;
|
||||
return CompressedImageMode::Uint32;
|
||||
default:
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError,
|
||||
"Only int/uint arrays of 1, 2, 4 bytes per element allowed");
|
||||
}
|
||||
}
|
||||
|
||||
CompressedImage GetCBORTypedArray(CborValue &value, const std::vector<uint64_t> &dim) {
|
||||
CompressedImageMode mode = GetImageMode(GetCBORTag(value));
|
||||
CompressionAlgorithm algorithm = CompressionAlgorithm::NO_COMPRESSION;
|
||||
size_t xpixel, ypixel;
|
||||
size_t size;
|
||||
const uint8_t *ptr = nullptr;
|
||||
|
||||
if (cbor_value_is_tag(&value)) {
|
||||
if (GetCBORTag(value) != TagDECTRISCompression)
|
||||
@@ -313,29 +311,41 @@ namespace {
|
||||
|
||||
auto algorithm_text = GetCBORString(array_value);
|
||||
if (algorithm_text == "bslz4")
|
||||
v.algorithm = CompressionAlgorithm::BSHUF_LZ4;
|
||||
algorithm = CompressionAlgorithm::BSHUF_LZ4;
|
||||
else if (algorithm_text == "bszstd")
|
||||
v.algorithm = CompressionAlgorithm::BSHUF_ZSTD;
|
||||
algorithm = CompressionAlgorithm::BSHUF_ZSTD;
|
||||
else
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Unsupported compression algorithm");
|
||||
|
||||
v.pixel_depth_bytes = GetCBORUInt(array_value);
|
||||
auto pixel_depth_bytes = GetCBORUInt(array_value);
|
||||
auto ret = GetCBORByteString(array_value);
|
||||
v.data = ret.first;
|
||||
v.size = ret.second;
|
||||
ptr = ret.first;
|
||||
size = ret.second;
|
||||
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
|
||||
} else if (cbor_value_is_byte_string(&value)) {
|
||||
v.algorithm = CompressionAlgorithm::NO_COMPRESSION;
|
||||
algorithm = CompressionAlgorithm::NO_COMPRESSION;
|
||||
auto ret = GetCBORByteString(value);
|
||||
v.data = ret.first;
|
||||
v.size = ret.second;
|
||||
ptr = ret.first;
|
||||
size = ret.second;
|
||||
} else
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Byte string or compressed array expected");
|
||||
|
||||
if (dim.size() == 2) {
|
||||
xpixel = dim[1];
|
||||
ypixel = dim[0];
|
||||
} else if (dim.size() == 3 && dim[0] == 3 && mode == CompressedImageMode::Uint8) {
|
||||
mode = CompressedImageMode::RGB;
|
||||
xpixel = dim[2];
|
||||
ypixel = dim[1];
|
||||
} else
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Image dimension not supported");
|
||||
|
||||
return CompressedImage(ptr, size, xpixel, ypixel, mode, algorithm);
|
||||
}
|
||||
|
||||
void GetCBORMultidimTypedArray(CompressedImage &v, CborValue &value) {
|
||||
CompressedImage GetCBORMultidimTypedArray(CborValue &value) {
|
||||
|
||||
if (GetCBORTag(value) != TagMultiDimArray)
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Multidim array expected");
|
||||
@@ -346,13 +356,12 @@ namespace {
|
||||
CborValue array_value;
|
||||
cborErr(cbor_value_enter_container(&value, &array_value));
|
||||
|
||||
auto [x, y] = GetCBORDimension2DArray(array_value);
|
||||
v.xpixel = x;
|
||||
v.ypixel = y;
|
||||
|
||||
GetCBORTypedArray(v, array_value);
|
||||
auto dim = GetCBORDimensionArray(array_value);
|
||||
|
||||
CompressedImage image = GetCBORTypedArray(array_value, dim);
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void CheckMagicNumber(CborValue &v) {
|
||||
@@ -361,7 +370,7 @@ namespace {
|
||||
"Inconsistency between Jungfraujoch server and writer");
|
||||
}
|
||||
|
||||
void ProcessImageData(CborValue &value, CompressedImage &image) {
|
||||
CompressedImage ProcessImageData(CborValue &value) {
|
||||
if (!cbor_value_is_map(&value))
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Map expected");
|
||||
|
||||
@@ -373,10 +382,12 @@ namespace {
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
|
||||
image.channel = GetCBORString(map_value);
|
||||
GetCBORMultidimTypedArray(image, map_value);
|
||||
std::string channel = GetCBORString(map_value);
|
||||
CompressedImage image = GetCBORMultidimTypedArray(map_value);
|
||||
image.Channel(channel);
|
||||
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
return image;
|
||||
}
|
||||
|
||||
// Data message
|
||||
@@ -489,7 +500,7 @@ namespace {
|
||||
else if (key == "original_image_id")
|
||||
message.original_number = GetCBORInt(value);
|
||||
else if (key == "data")
|
||||
ProcessImageData(value, message.image);
|
||||
message.image = ProcessImageData(value);
|
||||
else if (key == "series_unique_id")
|
||||
message.run_name = GetCBORString(value);
|
||||
else if (key == "series_id")
|
||||
@@ -519,6 +530,8 @@ namespace {
|
||||
message.indexing_result = GetCBORBool(value);
|
||||
else if (key == "indexing_lattice")
|
||||
GetCBORFloatArray(value, message.indexing_lattice);
|
||||
else if (key == "indexing_time")
|
||||
message.indexing_time_s = GetCBORFloat(value);
|
||||
else if (key == "indexing_unit_cell")
|
||||
message.indexing_unit_cell = ProcessUnitCellElement(value);
|
||||
else if (key == "jf_info")
|
||||
@@ -628,9 +641,48 @@ namespace {
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
}
|
||||
|
||||
GoniometerAxis ProcessGoniometerOmega(std::string &name, CborValue &value) {
|
||||
GoniometerAxis ret{};
|
||||
ret.name = name;
|
||||
std::optional<GridScanSettings> ProcessGridScan(CborValue &value) {
|
||||
int64_t n_fast = 0;
|
||||
int64_t n_slow = 0;
|
||||
float step_x_um = 0;
|
||||
float step_y_um = 0;
|
||||
bool snake = false;
|
||||
bool vertical = false;
|
||||
|
||||
CborValue map_value;
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
auto key = GetCBORString(map_value);
|
||||
|
||||
if (key == "n_fast")
|
||||
n_fast = GetCBORInt(map_value);
|
||||
else if (key == "n_slow")
|
||||
n_slow = GetCBORInt(map_value);
|
||||
else if (key == "step_x_axis")
|
||||
step_x_um = GetCBORFloat(map_value) * 1e6f;
|
||||
else if (key == "step_y_axis")
|
||||
step_y_um = GetCBORFloat(map_value) * 1e6f;
|
||||
else if (key == "snake_scan")
|
||||
snake = GetCBORBool(map_value);
|
||||
else if (key == "vertical_scan")
|
||||
vertical = GetCBORBool(map_value);
|
||||
else
|
||||
cbor_value_advance(&map_value);
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
|
||||
GridScanSettings grid(n_fast, step_x_um, step_y_um,
|
||||
snake, vertical);
|
||||
grid.ImageNum(n_fast * n_slow);
|
||||
return grid;
|
||||
}
|
||||
|
||||
std::optional<GoniometerAxis> ProcessGoniometer(std::string &name, CborValue &value) {
|
||||
float start = 0;
|
||||
float increment = 1;
|
||||
Coord axis = {1,0,0};
|
||||
std::optional<Coord> helical;
|
||||
|
||||
CborValue map_value;
|
||||
|
||||
@@ -638,15 +690,22 @@ namespace {
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
auto key = GetCBORString(map_value);
|
||||
if (key == "increment")
|
||||
ret.increment = GetCBORFloat(map_value);
|
||||
increment = GetCBORFloat(map_value);
|
||||
else if (key == "start")
|
||||
ret.start = GetCBORFloat(map_value);
|
||||
start = GetCBORFloat(map_value);
|
||||
else if (key == "axis")
|
||||
axis = GetCoord(map_value);
|
||||
else if (key == "helical_step")
|
||||
helical = GetCoord(map_value);
|
||||
else
|
||||
cbor_value_advance(&value);
|
||||
cbor_value_advance(&map_value);
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
|
||||
return ret;
|
||||
if (increment == 0)
|
||||
return {};
|
||||
else
|
||||
return GoniometerAxis(name, start, increment, axis, helical);
|
||||
}
|
||||
|
||||
void ProcessROIConfig(StartMessage &message, const nlohmann::json &j) {
|
||||
@@ -692,9 +751,8 @@ namespace {
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
GoniometerAxis axis;
|
||||
auto key = GetCBORString(map_value);
|
||||
message.goniometer = ProcessGoniometerOmega(key, map_value);
|
||||
message.goniometer = ProcessGoniometer(key, map_value);
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
}
|
||||
@@ -706,16 +764,16 @@ namespace {
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
auto key = GetCBORString(map_value);
|
||||
CompressedImage image;
|
||||
image.channel = key;
|
||||
GetCBORMultidimTypedArray(image, map_value);
|
||||
CompressedImage image = GetCBORMultidimTypedArray(map_value);
|
||||
image.Channel(key);
|
||||
|
||||
if (image.pixel_is_float || image.pixel_is_signed || (image.pixel_depth_bytes != sizeof(uint32_t)))
|
||||
if (image.GetMode() != CompressedImageMode::Uint32)
|
||||
continue;
|
||||
|
||||
std::vector<uint32_t> mask_uncompressed;
|
||||
JFJochDecompress(mask_uncompressed, image.algorithm, image.data, image.size,
|
||||
image.xpixel * image.ypixel);
|
||||
JFJochDecompress(mask_uncompressed, image.GetCompressionAlgorithm(),
|
||||
image.GetCompressed(), image.GetCompressedSize(),
|
||||
image.GetWidth() * image.GetHeight());
|
||||
message.pixel_mask[key] = mask_uncompressed;
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
@@ -759,11 +817,6 @@ namespace {
|
||||
message.total_flux = j["total_flux"];
|
||||
if (j.contains("attenuator_transmission"))
|
||||
message.attenuator_transmission = j["attenuator_transmission"];
|
||||
if (j.contains("rotation_axis") && j["rotation_axis"].is_array() &&
|
||||
(j["rotation_axis"].size() == 3)) {
|
||||
for (int i = 0; i < 3; i++)
|
||||
message.rotation_axis[i] = j["rotation_axis"][i];
|
||||
}
|
||||
if (j.contains("space_group_number"))
|
||||
message.space_group_number = j["space_group_number"];
|
||||
if (j.contains("roi"))
|
||||
@@ -857,6 +910,8 @@ namespace {
|
||||
ProcessAxis(value, message.detector_translation);
|
||||
else if (key == "goniometer")
|
||||
ProcessGoniometerMap(message, value);
|
||||
else if (key == "grid_scan")
|
||||
message.grid_scan = ProcessGridScan(value);
|
||||
else if (key == "pixel_mask_enabled")
|
||||
message.pixel_mask_enabled = GetCBORBool(value);
|
||||
else if (key == "jungfrau_conversion_enabled")
|
||||
@@ -926,7 +981,7 @@ namespace {
|
||||
auto key = GetCBORString(value);
|
||||
try {
|
||||
if (key == "data") {
|
||||
ProcessImageData(value, message);
|
||||
message = ProcessImageData(value);
|
||||
} else {
|
||||
if (cbor_value_is_tag(&value))
|
||||
cbor_value_advance(&value);
|
||||
|
||||
Reference in New Issue
Block a user