-
Notifications
You must be signed in to change notification settings - Fork 76
Description
NDPluginPvxs does not work with ImageJ when the NDArrays are compressed. ImageJ reports the following errors:
31-Dec-2025 12:30:51.982: handleEvents caught exception java.lang.NullPointerException
and the images do not update.
This is the output of pvget, which does have the data and report the correct compression.
(base) [epics@corvette ADSimDetector]$ pvget 13SIM1:Pva1:Image
13SIM1:Pva1:Image epics:nt/NTNDArray:1.0
union value
ubyte[] [0,0,2,164,31,85,1,0,108,31,170,1,0,108,15,255,0,108,31,85,255,0,108,15,0,1,255,239,31,153,1,0,108,31,204,1,0,108,31,102,1,0,108,31,51,
1,0,108,15,255,1,108,31,153,255,1,108,31,204,255,1,108,31,102,255,1,108,47,51,30,1,0,108,31,15,1,0,108,31,135,1,0,108,31,195,1,0,108,31,225,1,0,108,
31,240,1,0,108,31,120,1,0,108,31,60,1,0,108,47,31,224,2,0,107,47,15,240,2,0,107,47,7,248,2,0,107,47,3,252,2,0,107,47,1,254,2,0,107,47,0,255,2,0,107,47,
...
codec_t codec
string name bslz4
any parameters
long 1
long compressedSize 86556
long uncompressedSize 1048576
int uniqueId 4300
time_t dataTimeStamp 2025-12-31 12:35:14.685
long secondsPastEpoch 1767206114
int nanoseconds 685011863
time_t timeStamp 2025-12-31 12:35:14.685
long secondsPastEpoch 1767206114
int nanoseconds 685011894
dimension_t[] dimension
dimension_t
int size 1024
int offset 0
int fullSize 1024
int binning 1
boolean reverse false
dimension_t
int size 1024
int offset 0
int fullSize 1024
int binning 1
boolean reverse false
epics:nt/NTAttribute:1.0[] attribute
epics:nt/NTAttribute:1.0
string name ColorMode
any value
long 0
string[] tags []
string descriptor Color mode
alarm_t alarm
int severity 0
int status 0
string message
time_t timeStamp
long secondsPastEpoch 0
int nanoseconds 0
int userTag 0
int sourceType 0
string source Driver
...
NDPluginPVA does not have these issues. It correctly displays the compressed images in ImageJ with no error messages.
This is the output of pvget when I switch back to using NDPluginPVA.
(base) [epics@corvette ADSimDetector]$ pvget 13SIM1:Pva1:Image
13SIM1:Pva1:Image epics:nt/NTNDArray:1.0
union value
ubyte[] [0,0,2,155,31,85,1,0,108,31,170,1,0,108,15,255,0,108,31,85,255,0,108,15,0,1,255,239,31,102,1,0,108,31,51,1,0,108,31,153,1,0,108,31,204,1,0,108,15,255,
1,108,31,102,255,1,108,31,51,255,1,108,31,153,255,1,108,47,204,135,1,0,108,31,195,1,0,108,31,225,1,0,108,31,240,1,0,108,31,120,1,0,108,31,60,1,0,108,31,30,1,0,108,31,15,1,0,108,47,7,248,2,0,107,47,3,252,2,0,107,47,1,254,2,0,107,47,0,255,2,0,107,47,128,127,2,0,107,47,192,63,2,0,107,47,224,31,2,0,107,4
...
codec_t codec
string name bslz4
any parameters
int 5
long compressedSize 86556
long uncompressedSize 1048576
dimension_t[] dimension
dimension_t
int size 1024
int offset 0
int fullSize 1024
int binning 1
boolean reverse false
dimension_t
int size 1024
int offset 0
int fullSize 1024
int binning 1
boolean reverse false
int uniqueId 270
time_t dataTimeStamp 2025-12-31 12:47:19.827
long secondsPastEpoch 1767206839
int nanoseconds 826854944
int userTag 0
epics:nt/NTAttribute:1.0[] attribute
epics:nt/NTAttribute:1.0
string name ColorMode
any value
int 0
string descriptor Color mode
int sourceType 0
string source Driver
...
The reason for the failure to display the compressed images is that the codec "parameters" are "int 5" for PVA but "long 1" for PVXS.
The codec parameters value should be ScalarType enum as defined here:
https://docs.epics-controls.org/projects/pvdata-cpp/en/latest/doxygen/namespaceepics_1_1pv_data.html#ad70edb4f86fc7bb84d73c5e44f344125
The unsigned 8 bit integer data type, which is the case here, has enum value 5 (pvUByte). That is what PVA is using. PVXS is using 1, which is a different set of enums, where 0= signed byte, 1=unsigned byte, etc.
ntndArrayConverter.cpp defines this mapping from the NDArray datatype to the PVA datatype:
| static const ScalarType NDDataTypeToScalar[NDFloat64 + 1] = { |
That is used to set the codec.parameters in the 4 lines starting here:
| uncompressedType->putFrom<int32>(NDDataTypeToScalar[src->dataType]); |
ntndArrayConverterPvxs is not doing that, it is putting the NDArray datatype into codec.parameters here:
| m_value["codec.parameters"] = (int32_t) src->dataType; |
That will not work, because ImageJ is using the Java version of PVA, and uses the same ScalarType enum that the C++ version uses:
PVXS does not support the ScalarType enum. We need to define it in ntndArrayConverterPvxs so we can do the required mapping.