diff --git a/guideGlobalMetadata.json b/guideGlobalMetadata.json index 1b4fabc8d..bfce304a0 100644 --- a/guideGlobalMetadata.json +++ b/guideGlobalMetadata.json @@ -14,6 +14,12 @@ "CellExplorerSortingInterface", "KiloSortSortingInterface", "Spike2RecordingInterface", - "BrukerTiffSinglePlaneImagingInterface" + "BrukerTiffSinglePlaneImagingInterface", + "BrukerTiffMultiPlaneImagingInterface", + "MicroManagerTiffImagingInterface", + "ScanImageImagingInterface", + "TiffImagingInterface", + "MiniscopeImagingInterface", + "SbxImagingInterface" ] } diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py index 807229b97..df6aa4a3d 100644 --- a/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/pyflask/manageNeuroconv/manage_neuroconv.py @@ -69,22 +69,32 @@ def replace_none_with_nan(json_object, json_schema): dict: The modified JSON object with None values replaced by NaN. """ - def replace_none_recursive(obj, schema): + def coerce_schema_compliance_recursive(obj, schema): if isinstance(obj, dict): for key, value in obj.items(): if key in schema.get("properties", {}): prop_schema = schema["properties"][key] if prop_schema.get("type") == "number" and value is None: - obj[key] = math.nan + obj[ + key + ] = ( + math.nan + ) # Turn None into NaN if a number is expected (JavaScript JSON.stringify turns NaN into None) + elif prop_schema.get("type") == "number" and isinstance(value, int): + obj[key] = float( + value + ) # Turn integer into float if a number, the JSON Schema equivalent to float, is expected (JavaScript coerces floats with trailing zeros to integers) else: - replace_none_recursive(value, prop_schema) + coerce_schema_compliance_recursive(value, prop_schema) elif isinstance(obj, list): for item in obj: - replace_none_recursive(item, schema.get("items", {})) + coerce_schema_compliance_recursive(item, schema.get("items", {})) return obj - return replace_none_recursive(copy.deepcopy(json_object), resolve_references(copy.deepcopy(json_schema))) + return coerce_schema_compliance_recursive( + copy.deepcopy(json_object), resolve_references(copy.deepcopy(json_schema)) + ) def locate_data(info: dict) -> dict: @@ -363,7 +373,7 @@ def update_conversion_progress(**kwargs): info["metadata"].update(Ecephys=dict()) resolved_metadata = replace_none_with_nan( - info["metadata"], converter.get_metadata_schema() + info["metadata"], resolve_references(converter.get_metadata_schema()) ) # Ensure Ophys NaN values are resolved # if is_supported_recording_interface(recording_interface, info["metadata"]): diff --git a/schemas/json/generated/BrukerTiffMultiPlaneImagingInterface.json b/schemas/json/generated/BrukerTiffMultiPlaneImagingInterface.json new file mode 100644 index 000000000..a4383d177 --- /dev/null +++ b/schemas/json/generated/BrukerTiffMultiPlaneImagingInterface.json @@ -0,0 +1,33 @@ +{ + "required": [], + "properties": { + "BrukerTiffMultiPlaneImagingInterface": { + "required": [ + "folder_path" + ], + "properties": { + "folder_path": { + "format": "directory", + "type": "string", + "description": "The path that points to the folder containing the Bruker volumetric TIF image files and configuration files." + }, + "stream_name": { + "type": "string" + }, + "verbose": { + "type": "boolean", + "default": true + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/schemas/json/generated/MicroManagerTiffImagingInterface.json b/schemas/json/generated/MicroManagerTiffImagingInterface.json new file mode 100644 index 000000000..fb0cd8876 --- /dev/null +++ b/schemas/json/generated/MicroManagerTiffImagingInterface.json @@ -0,0 +1,30 @@ +{ + "required": [], + "properties": { + "MicroManagerTiffImagingInterface": { + "required": [ + "folder_path" + ], + "properties": { + "folder_path": { + "format": "directory", + "type": "string", + "description": "The path that points to the folder containing the OME-TIF image files." + }, + "verbose": { + "type": "boolean", + "default": true + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/schemas/json/generated/MiniscopeImagingInterface.json b/schemas/json/generated/MiniscopeImagingInterface.json new file mode 100644 index 000000000..33171beb5 --- /dev/null +++ b/schemas/json/generated/MiniscopeImagingInterface.json @@ -0,0 +1,25 @@ +{ + "required": [], + "properties": { + "MiniscopeImagingInterface": { + "required": [ + "folder_path" + ], + "properties": { + "folder_path": { + "format": "directory", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/schemas/json/generated/SbxImagingInterface.json b/schemas/json/generated/SbxImagingInterface.json new file mode 100644 index 000000000..d02d2c0e7 --- /dev/null +++ b/schemas/json/generated/SbxImagingInterface.json @@ -0,0 +1,32 @@ +{ + "required": [], + "properties": { + "SbxImagingInterface": { + "required": [ + "file_path" + ], + "properties": { + "file_path": { + "format": "file", + "type": "string" + }, + "sampling_frequency": { + "type": "number" + }, + "verbose": { + "type": "boolean", + "default": true + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/schemas/json/generated/ScanImageImagingInterface.json b/schemas/json/generated/ScanImageImagingInterface.json new file mode 100644 index 000000000..71b3cb59a --- /dev/null +++ b/schemas/json/generated/ScanImageImagingInterface.json @@ -0,0 +1,33 @@ +{ + "required": [], + "properties": { + "ScanImageImagingInterface": { + "required": [ + "file_path" + ], + "properties": { + "file_path": { + "format": "file", + "type": "string", + "description": "Path to Tiff file." + }, + "fallback_sampling_frequency": { + "type": "number" + }, + "verbose": { + "type": "boolean", + "default": true + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/schemas/json/generated/TiffImagingInterface.json b/schemas/json/generated/TiffImagingInterface.json new file mode 100644 index 000000000..036de528a --- /dev/null +++ b/schemas/json/generated/TiffImagingInterface.json @@ -0,0 +1,34 @@ +{ + "required": [], + "properties": { + "TiffImagingInterface": { + "required": [ + "file_path", + "sampling_frequency" + ], + "properties": { + "file_path": { + "format": "file", + "type": "string", + "description": "Path to Tiff file." + }, + "sampling_frequency": { + "type": "number" + }, + "verbose": { + "type": "boolean", + "default": true + } + }, + "type": "object", + "additionalProperties": false + } + }, + "type": "object", + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "source.schema.json", + "title": "Source data schema", + "description": "Schema for the source data, files and directories", + "version": "0.1.0" +} diff --git a/src/renderer/src/stories/pages/guided-mode/SourceData.stories.js b/src/renderer/src/stories/pages/guided-mode/SourceData.stories.js index 59b3acc74..9ac3dd511 100644 --- a/src/renderer/src/stories/pages/guided-mode/SourceData.stories.js +++ b/src/renderer/src/stories/pages/guided-mode/SourceData.stories.js @@ -14,6 +14,12 @@ import CellExplorerSortingInterfaceSchema from "../../../../../../schemas/json/g import KiloSortSortingInterfaceSchema from "../../../../../../schemas/json/generated/KiloSortSortingInterface.json"; import Spike2RecordingInterfaceSchema from "../../../../../../schemas/json/generated/Spike2RecordingInterface.json"; import BrukerTiffSinglePlaneImagingInterfaceSchema from "../../../../../../schemas/json/generated/BrukerTiffSinglePlaneImagingInterface.json"; +import BrukerTiffMultiPlaneImagingInterfaceSchema from "../../../../../../schemas/json/generated/BrukerTiffMultiPlaneImagingInterface.json"; +import MicroManagerTiffImagingInterfaceSchema from "../../../../../../schemas/json/generated/MicroManagerTiffImagingInterface.json"; +import ScanImageImagingInterfaceSchema from "../../../../../../schemas/json/generated/ScanImageImagingInterface.json"; +import TiffImagingInterfaceSchema from "../../../../../../schemas/json/generated/TiffImagingInterface.json"; +import MiniscopeImagingInterfaceSchema from "../../../../../../schemas/json/generated/MiniscopeImagingInterface.json"; +import SbxImagingInterfaceSchema from "../../../../../../schemas/json/generated/SbxImagingInterface.json"; export default { title: "Pages/Guided Mode/Source Data", @@ -55,6 +61,18 @@ globalStateCopy.schema.source_data.properties.Spike2RecordingInterface = Spike2RecordingInterfaceSchema.properties.Spike2RecordingInterface; globalStateCopy.schema.source_data.properties.BrukerTiffSinglePlaneImagingInterface = BrukerTiffSinglePlaneImagingInterfaceSchema.properties.BrukerTiffSinglePlaneImagingInterface; +globalStateCopy.schema.source_data.properties.BrukerTiffMultiPlaneImagingInterface = + BrukerTiffMultiPlaneImagingInterfaceSchema.properties.BrukerTiffMultiPlaneImagingInterface; +globalStateCopy.schema.source_data.properties.MicroManagerTiffImagingInterface = + MicroManagerTiffImagingInterfaceSchema.properties.MicroManagerTiffImagingInterface; +globalStateCopy.schema.source_data.properties.ScanImageImagingInterface = + ScanImageImagingInterfaceSchema.properties.ScanImageImagingInterface; +globalStateCopy.schema.source_data.properties.TiffImagingInterface = + TiffImagingInterfaceSchema.properties.TiffImagingInterface; +globalStateCopy.schema.source_data.properties.MiniscopeImagingInterface = + MiniscopeImagingInterfaceSchema.properties.MiniscopeImagingInterface; +globalStateCopy.schema.source_data.properties.SbxImagingInterface = + SbxImagingInterfaceSchema.properties.SbxImagingInterface; const results = globalStateCopy.results; for (let sub in results) { @@ -157,3 +175,39 @@ BrukerTiffSinglePlaneImagingInterface.args = { activePage, globalState: BrukerTiffSinglePlaneImagingInterfaceGlobalCopy, }; + +export const BrukerTiffMultiPlaneImagingInterface = PageTemplate.bind({}); +const BrukerTiffMultiPlaneImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +BrukerTiffMultiPlaneImagingInterfaceGlobalCopy.interfaces.interface = BrukerTiffMultiPlaneImagingInterface; +BrukerTiffMultiPlaneImagingInterfaceGlobalCopy.schema.source_data = BrukerTiffMultiPlaneImagingInterfaceSchema; +BrukerTiffMultiPlaneImagingInterface.args = { activePage, globalState: BrukerTiffMultiPlaneImagingInterfaceGlobalCopy }; + +export const MicroManagerTiffImagingInterface = PageTemplate.bind({}); +const MicroManagerTiffImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +MicroManagerTiffImagingInterfaceGlobalCopy.interfaces.interface = MicroManagerTiffImagingInterface; +MicroManagerTiffImagingInterfaceGlobalCopy.schema.source_data = MicroManagerTiffImagingInterfaceSchema; +MicroManagerTiffImagingInterface.args = { activePage, globalState: MicroManagerTiffImagingInterfaceGlobalCopy }; + +export const ScanImageImagingInterface = PageTemplate.bind({}); +const ScanImageImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +ScanImageImagingInterfaceGlobalCopy.interfaces.interface = ScanImageImagingInterface; +ScanImageImagingInterfaceGlobalCopy.schema.source_data = ScanImageImagingInterfaceSchema; +ScanImageImagingInterface.args = { activePage, globalState: ScanImageImagingInterfaceGlobalCopy }; + +export const TiffImagingInterface = PageTemplate.bind({}); +const TiffImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +TiffImagingInterfaceGlobalCopy.interfaces.interface = TiffImagingInterface; +TiffImagingInterfaceGlobalCopy.schema.source_data = TiffImagingInterfaceSchema; +TiffImagingInterface.args = { activePage, globalState: TiffImagingInterfaceGlobalCopy }; + +export const MiniscopeImagingInterface = PageTemplate.bind({}); +const MiniscopeImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +MiniscopeImagingInterfaceGlobalCopy.interfaces.interface = MiniscopeImagingInterface; +MiniscopeImagingInterfaceGlobalCopy.schema.source_data = MiniscopeImagingInterfaceSchema; +MiniscopeImagingInterface.args = { activePage, globalState: MiniscopeImagingInterfaceGlobalCopy }; + +export const SbxImagingInterface = PageTemplate.bind({}); +const SbxImagingInterfaceGlobalCopy = JSON.parse(JSON.stringify(globalState)); +SbxImagingInterfaceGlobalCopy.interfaces.interface = SbxImagingInterface; +SbxImagingInterfaceGlobalCopy.schema.source_data = SbxImagingInterfaceSchema; +SbxImagingInterface.args = { activePage, globalState: SbxImagingInterfaceGlobalCopy };