What happened?
Writing an ImageSeries/OpticalSeries that was constructed with data and timestamps (but no explicit num_samples) emits an HDMF DtypeConversionWarning on write:
Spec 'OpticalSeries/num_samples': Value with data type int64 is being converted to data type uint64 (min specification: uint32).
This fires 14 times across the integration suite (e.g. tests/integration/hdf5/test_image.py).
Root cause
ImageSeries.num_samples auto-derives len(data) as a Python int (int64) when num_samples was not explicitly set. pynwb then writes this derived value against the schema's uint32 num_samples dataset (core/nwb.image.yaml), so HDMF widens int64 → uint64 and warns.
The schema doc for num_samples states it is only required when format='external' and timing uses starting_time/rate, and that "when timestamps is provided, len(timestamps) already serves this." So pynwb likely should not be writing an auto-derived num_samples at all when the user did not set one.
Proposed fix
Only write num_samples when it was explicitly provided (i.e. self._num_samples is not None), rather than writing the property's auto-derived fallback. Add round-trip tests confirming: (a) no dtype-conversion warning for the derived case, (b) an explicitly set num_samples still round-trips as uint32.
Notes
Deferred out of the 4.1.0 release prep (#2226) because it is a write-behavior change that warrants its own review and round-trip tests.
What happened?
Writing an
ImageSeries/OpticalSeriesthat was constructed withdataandtimestamps(but no explicitnum_samples) emits an HDMFDtypeConversionWarningon write:This fires 14 times across the integration suite (e.g.
tests/integration/hdf5/test_image.py).Root cause
ImageSeries.num_samplesauto-deriveslen(data)as a Pythonint(int64) whennum_sampleswas not explicitly set. pynwb then writes this derived value against the schema'suint32num_samplesdataset (core/nwb.image.yaml), so HDMF widens int64 → uint64 and warns.The schema doc for
num_samplesstates it is only required whenformat='external'and timing usesstarting_time/rate, and that "when timestamps is provided,len(timestamps)already serves this." So pynwb likely should not be writing an auto-derivednum_samplesat all when the user did not set one.Proposed fix
Only write
num_sampleswhen it was explicitly provided (i.e.self._num_samples is not None), rather than writing the property's auto-derived fallback. Add round-trip tests confirming: (a) no dtype-conversion warning for the derived case, (b) an explicitly setnum_samplesstill round-trips asuint32.Notes
Deferred out of the 4.1.0 release prep (#2226) because it is a write-behavior change that warrants its own review and round-trip tests.