Closed garrettmflynn closed 2 months ago
Thanks for getting the issue started @garrettmflynn
For next time I'd also love to see the raw output of that JSON dump, which is what I'm actually interested in knowing 'why we need or have NaNs there already'
Here's the output from print(json.dumps(metadata, cls=NWBMetaDataEncoder, indent=4))
{
"NWBFile": {
"session_description": "Auto-generated by neuroconv",
"identifier": "85131ea3-4d27-44dc-b83a-d55e784ffb1b",
"session_start_time": "2023-02-20T15:58:25"
},
"Ophys": {
"Device": [
{
"name": "BrukerFluorescenceMicroscope",
"description": "Version 5.6.64.400"
}
],
"ImagingPlane": [
{
"name": "ImagingPlane",
"description": "The plane imaged at 5e-06 meters depth.",
"excitation_lambda": NaN,
"indicator": "unknown",
"location": "unknown",
"device": "BrukerFluorescenceMicroscope",
"optical_channel": [
{
"name": "Ch2",
"emission_lambda": NaN,
"description": "An optical channel of the microscope."
}
],
"imaging_rate": 30.345939461428763,
"grid_spacing": [
1.1078125e-06,
1.1078125e-06
]
}
],
"TwoPhotonSeries": [
{
"name": "TwoPhotonSeries",
"description": "Imaging data acquired from the Bruker Two-Photon Microscope.",
"unit": "px",
"imaging_plane": "ImagingPlane",
"dimension": [
512,
512
],
"format": "tiff",
"scan_line_rate": 15840.580398865815,
"field_of_view": [
0.0005672,
0.0005672,
5e-06
]
}
]
}
}
And so the culprits are revealed to be the excitation and emission lambdas. This should be a problem for any ophys interface, was Bruker the first you've tested?
If so, then I'd hold off for a second on trying any other ophys interfaces until we can resolve this
Yep my bad, just slipped from my mind.
Bruker was just the first I've tested, and you're correct that it shows up for all other ophys interfaces.
Yeah it looks like it's part of the roiextractors.py
tool.
@garrettmflynn Realizing this will be a problem as we add more ophys interfaces in the coming weeks
See https://stackoverflow.com/a/6602204/13616096, they seem to indicate NaN
, though not a part of JSON, can be interpreted by JavaScript just fine with the right approach, which would be great since then we can consider NeuroConv as producing 'extended JSON' rather than 'pure JSON'
Is there a reason that it is unreasonable for NaN
to be converted into None
by NeuroConv? While it is possible to run eval('(' + '{"test":NaN}' + ')')
to parse out the JS object from a non-compliant JSON string, it's still definitely hacky / outdated—as well as requires some knowledge of this decision by any API consumers.
Is there a reason that it is unreasonable for NaN to be converted into None by NeuroConv?
None
isn't the issue, mapping onto null
is - would have to schematically define it to be either float or null, if you know how to do that really quickly/easily feel free to open direct PR to edit the base schema
Because the type of the field is a float
- it makes sense for it to be NaN, at least in Python land. There I can dump and load NaN
with a single flag
Probably a divisive issue for crossing into JS land, where even the JSON.parse package doesn't do that?
So JSON.stringify({test: NaN})
will produce {"test":null}
, which is the string I'd want from the API. Loading NaN directly from the string would require using eval
, which just treats the string as JS code (in which NaN is acceptable).
Here is how you'd declare that joint type in the schema: https://stackoverflow.com/questions/22565005/json-schema-validate-a-number-or-null-value
In this case, however, would it be possible to keep the schema the same and simply undeclare (i.e remove from the object) the key/value pairs provided as a NaN
in the metadata? Are these fields actually required to begin with?
Are these fields actually required to begin with?
Yeah, which is why we include it here in the first place: https://nwb-schema.readthedocs.io/en/latest/format.html#sec-imagingplane-src
Here is how you'd declare that joint type in the schema: https://stackoverflow.com/questions/22565005/json-schema-validate-a-number-or-null-value
OK, so for NeuroConv fix we would need to find all the right places to inject that - which could take a bit of time
So the question is, for the time being, what is the easiest/quickest fix? How long would it take to implement the hacky solution on the GUIDE side?
A good 20min for implementation and full tests. I'll do that now.
Is this going to only crop up for resolved metadata or other requests as well?
Is this going to only crop up for resolved metadata or other requests as well?
I don't know the difference 😆
You might see NaN
for any numeric value output from API calls involving the .get_metadata
method called on an Interface/Converter
But this is the number one case of it and I can't even think of any others off the top of my head
Okay we should be good for now then.
It seems that this was fixed with #393? @CodyCBakerPhD
393 is the next step in cloud development
But I think this was resolved over on GUIDE; it was an issue as I recall with interoperability of JSON validation between Java/TypeScript and Python
What happened?
When trying to decode the metadata results received from the
BrukerTif/NCCR32_2023_02_20_Into_the_void_t_series_baseline-000
dataset (ophys_testing_data/imaging_dataset
) on the browser for the NWB GUIDE, there are breaking errors becauseNaN
values are not part of the JSON specification but allowed withjson.dumps
andjson.loads
.Steps to Reproduce
Run the following script on the DANDI Hub using an environment with
neuroconv[ophys]
installed.The
jsonWithNaN
is a JSON object that will be sent to the browser with NaN values.If you'd like to get an error on the Python side, you can simply run json.dumps with the
allow_nan
kwarg set to False:Traceback
This is an error from the Chrome Developer Console as a result of trying to parse the invalid JSON string:
The traceback for using
allow_nan=False
is as follows:Operating System
macOS
Python Executable
Conda
Python Version
3.7
Package Versions
No response
Code of Conduct