From 2c5e1ffa9ef85eaa7f4c1eca2f24ad7317aa5b2a Mon Sep 17 00:00:00 2001 From: Wim Pomp Date: Mon, 28 Apr 2025 20:38:21 +0200 Subject: [PATCH] code --- .github/workflows/publish.yml | 54 + .gitignore | 73 + Cargo.toml | 32 + LICENSE | 19 + ome.xsd | 4898 ++++++ py/ome_metadata/__init__.py | 38 + pyproject.toml | 32 + src/lib.rs | 51 + src/ome.rs | 2765 +++ src/py.rs | 13 + tests/1xp53-01-AP1.xml | 416 + ...-CMV-1min-4h-01-Airyscan Processing-01.xml | 14468 ++++++++++++++++ tests/4-Pos_001_002.xml | 88 + tests/Experiment-2029.xml | 121 + ...1-01-Airyscan Processing-01-Scene-2-P1.xml | 3176 ++++ .../YTL1841B2-2-1_1hr_DMSO_galinduction_1.xml | 11 + ...11_2023_05_04__14_46_19_cellnr_1_track.xml | 21 + tests/YTL1849A131_2023_05_04__13_36_36.xml | 1499 ++ tests/YTL378_JF552.xml | 106 + tests/beads_2023_05_04__19_00_22.xml | 652 + tests/test.xml | 12 + 21 files changed, 28545 insertions(+) create mode 100644 .github/workflows/publish.yml create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 ome.xsd create mode 100644 py/ome_metadata/__init__.py create mode 100644 pyproject.toml create mode 100644 src/lib.rs create mode 100644 src/ome.rs create mode 100644 src/py.rs create mode 100644 tests/1xp53-01-AP1.xml create mode 100644 tests/20230511-p53-4x-CMV-1min-4h-01-Airyscan Processing-01.xml create mode 100644 tests/4-Pos_001_002.xml create mode 100644 tests/Experiment-2029.xml create mode 100644 tests/MK022_cE9_1-01-Airyscan Processing-01-Scene-2-P1.xml create mode 100644 tests/YTL1841B2-2-1_1hr_DMSO_galinduction_1.xml create mode 100644 tests/YTL1849A111_2023_05_04__14_46_19_cellnr_1_track.xml create mode 100644 tests/YTL1849A131_2023_05_04__13_36_36.xml create mode 100644 tests/YTL378_JF552.xml create mode 100644 tests/beads_2023_05_04__19_00_22.xml create mode 100644 tests/test.xml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..18d0e47 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,54 @@ +name: Publish + +on: [push, pull_request, workflow_call] + +permissions: + contents: read + +jobs: + crates_io_publish: + name: Publish (crates.io) + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + + - name: cargo-release Cache + id: cargo_release_cache + uses: actions/cache@v3 + with: + path: ~/.cargo/bin/cargo-release + key: ${{ runner.os }}-cargo-release + + - run: cargo install cargo-release + if: steps.cargo_release_cache.outputs.cache-hit != 'true' + + - name: cargo login + run: cargo login ${{ secrets.CRATES_IO_API_TOKEN }} + + # allow-branch HEAD is because GitHub actions switches + # to the tag while building, which is a detached head + + # Publishing is currently messy, because: + # + # * `peace_rt_model_core` exports `NativeError` or `WebError` depending on the target. + # * `peace_rt_model_web` fails to build when publishing the workspace for a native target. + # * `peace_rt_model_web` still needs its dependencies to be published before it can be + # published. + # * `peace_rt_model_hack` needs `peace_rt_model_web` to be published before it can be + # published. + # + # We *could* pass through `--no-verify` so `cargo` doesn't build the crate before publishing, + # which is reasonable, since this job only runs after the Linux, Windows, and WASM builds + # have passed. + - name: "cargo release publish" + run: |- + cargo release \ + publish \ + --workspace \ + --all-features \ + --allow-branch "main" \ + --no-confirm \ + --no-verify \ + --execute diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cec2916 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +/target + +# Byte-compiled / optimized / DLL files +__pycache__/ +.pytest_cache/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +.venv/ +env/ +bin/ +build/ +develop-eggs/ +dist/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +include/ +man/ +venv/ +*.egg-info/ +.installed.cfg +*.egg + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt +pip-selfcheck.json + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Rope +.ropeproject + +# Django stuff: +*.log +*.pot + +.DS_Store + +# Sphinx documentation +docs/_build/ + +# PyCharm +.idea/ + +# VSCode +.vscode/ + +# Pyenv +.python-version +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ec5cbc3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "ome-metadata" +version = "0.1.0" +edition = "2024" +rust-version = "1.85.1" +authors = ["Wim Pomp "] +license = "MIT" +description = "Ome metadata as a rust/python structure." +homepage = "https://github.com/wimpomp/ome-metadata" +repository = "https://github.com/wimpomp/ome-metadata" +readme = "README.md" +keywords = ["bioformats", "imread", "ome", "metadata"] +categories = ["multimedia::images", "science"] +exclude = ["/tests"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "ome_metadata" +crate-type = ["cdylib", "rlib"] + +[dependencies] +anyhow = "1.0.98" +serde = { version = "1.0.219", features = ["derive"] } +quick-xml = { version = "0.37.5", features = ["serialize"] } + +[dependencies.pyo3] +version = "0.24.2" +features = ["extension-module", "abi3-py310", "generate-import-lib", "anyhow"] +optional = true + +[features] +python = ["dep:pyo3"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f9b7904 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2025 Wim Pomp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/ome.xsd b/ome.xsd new file mode 100644 index 0000000..56c8ddc --- /dev/null +++ b/ome.xsd @@ -0,0 +1,4898 @@ + + + + + + + + + Open Microscopy Environment + OME XML Schema June 2016 + + + + + + + + The OME element is a container for all information objects accessible by OME. + These information objects include descriptions of the imaging experiments + and the people who perform them, descriptions of the microscope, the resulting + images and how they were acquired, the analyses performed on those images, + and the analysis results themselves. + An OME file may contain any or all of this information. + + With the creation of the Metadata Only Companion OME-XML and Binary Only OME-TIFF files + the top level OME node has changed slightly. + It can EITHER: + Contain all the previously expected elements + OR: + Contain a single BinaryOnly element that points at + its Metadata Only Companion OME-XML file. + + + + + + + + + + + + + + + + + + + + + + + + + Pointer to an external metadata file. If this + element is present, then no other metadata may be present in this + file, i.e. this file is a place-holder. + + + + + Filename of the OME-XML metadata file for + this binary data. If the file cannot be found, a search can + be performed based on the UUID. + + + + + The unique identifier of another OME-XML + block whose metadata describes the binary data in this file. + This UUID is considered authoritative regardless of + mismatches in the filename. + + + + + + + + + + + This unique identifier is used to keep track of multi part files. + It allows the links between files to survive renaming. + + While OPTIONAL in the general case this is REQUIRED in a + MetadataOnly Companion to a collection of BinaryOnly files. + + + + + + + This is the name of the creating application of the OME-XML + and preferably its full version. + e.g "CompanyName, SoftwareName, V2.6.3456" + This is optional but we hope it will be set by applications + writing out OME-XML from scratch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Images + + This element describes the actual image and its meta-data. + The elements that are references (ending in Ref or Settings) refer to + elements defined outside of the Image element. Ref elements are simple + links, while Settings elements are links with additional values. + + If any of the required Image attributes or elements are missing, its + guaranteed to be an invalid document. The required attributes and + elements are ID and Pixels. + + ExperimenterRef is required for all Images with well formed LSIDs. + ImageType is a vendor-specific designation of the type of image this is. + Examples of ImageType include 'STK', 'SoftWorx', etc. + The Name attributes are in all cases the name of the element + instance. In this case, the name of the image, not necessarily the filename. + Physical size of pixels are microns[µm]. + + + + + + + + The acquisition date of the Image. + The element contains an xsd:dateTime string based on the ISO 8601 format (i.e. 1988-04-07T18:39:09.359) + + YYYY-MM-DDTHH:mm:SS.sssZ + Y - Year + M - Month + D - Day + H - Hour + m - minutes + S - Seconds + s - sub-seconds (optional) + Z - Zone (optional) +HH:mm or -HH:mm or Z for UTC + + Note: xsd:dataTime supports a very wide date range with unlimited precision. The full date range + and precision are not typically supported by platform- and language-specific libraries. + Where the supported time precision is less than the precision used by the xsd:dateTime + timestamp there will be loss of precision; this will typically occur via direct truncation + or (less commonly) rounding. + + The year value can be large and/or negative. Any value covering the current or last century + should be correctly processed, but some systems cannot process earlier dates. + + The sub-second value is defined as an unlimited number of digits after the decimal point. + In Java a minimum of millisecond precision is guaranteed. + In C++ microsecond precision is guaranteed, with nanosecond precision being available on + some platforms. + + Time zones are supported, eg '2013-10-24T11:52:33+01:00' for Paris, but in most cases it will + be converted to UTC when the timestamp is written. + + + + + + + + A description for the image. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pixels + + Pixels is going to be removed in the future, but it is still required. + + This is just notice that the contents of Pixels will be + moved up to Image in a future release. This is because there + has only been 1 Pixels object in each Image for some time. + The concept of multiple Pixels sets for one Image failed to + take off. It is therefore redundant. + + The Image will be unreadable if any of the required Pixel attributes are missing. + + The Pixels themselves can be stored within the OME-XML compressed by plane, and encoded + in Base64. + Or the Pixels may be stored in TIFF format. + + The Pixels element should contain a list of BinData or TiffData, each containing a + single plane of pixels. These Pixels elements, when read in document order, + must produce a 5-D pixel array of the size specified in this element, and in the + dimension order specified by 'DimensionOrder'. + + All of the values in the Pixels object when present should match the same value + stored in any associated TIFF format (e.g. SizeX should be the same). Where there + is a mismatch our readers will take the value from the TIFF structure as overriding + the value in the OME-XML. This is simply a pragmatic decision as it increases the + likelihood of reading data from a slightly incorrect file. + + + + + + + + + + + + + + + + + + + + + The order in which the individual planes of data are interleaved. + + + + + + + + + + + + + + + + + The variable type used to represent each pixel in the image. + + + + + + + The number of bits within the type storing each pixel that are significant. + e.g. you can store 12 bit data within a 16 bit type. + This does not reduce the storage requirements but can be a useful indicator + when processing or viewing the image data. + + + + + + + How the channels are arranged within the data block: + true if channels are stored RGBRGBRGB...; + false if channels are stored RRR...GGG...BBB... + + + + + + + This is true if the pixels data was written in BigEndian order. + + If this value is present it should match the value used in BinData + or TiffData. If it does not a reader should honour the value used + in the BinData or TiffData. This values is useful for MetadataOnly + files and is to allow for future storage solutions. + + + + + + Dimensional size of pixel data array [units:none] + + + + + Dimensional size of pixel data array [units:none] + + + + + Dimensional size of pixel data array [units:none] + + + + + Dimensional size of pixel data array [units:none] + + + + + Dimensional size of pixel data array [units:none] + + + + + Physical size of a pixel. Units are set by PhysicalSizeXUnit. + + + + + The units of the physical size of a pixel - default:microns[µm]. + + + + + Physical size of a pixel. Units are set by PhysicalSizeYUnit. + + + + + The units of the physical size of a pixel - default:microns[µm]. + + + + + Physical size of a pixel. Units are set by PhysicalSizeZUnit. + + + + + The units of the physical size of a pixel - default:microns[µm]. + + + + + + TimeIncrement is used for time series that have a global + timing specification instead of per-timepoint timing info. + For example in a video stream. Units are set by TimeIncrementUnit. + + + + + + The units of the TimeIncrement - default:seconds[s]. + + + + + + + Planes + + The Plane object holds microscope stage and image timing data + for a given channel/z-section/timepoint. + + + + + + + + This optional element is a hash of the plane's image data. + It is a choice between all the support hash types. + Currently the only method supported is SHA1. + + + + + + + + + + + + + + The Z-section this plane is for. [units:none] + This is numbered from 0. + + + + + + + The timepoint this plane is for. [units:none] + This is numbered from 0. + + + + + + + The channel this plane is for. [units:none] + This is numbered from 0. + + + + + + + Time since the beginning of the experiment. + Units are set by DeltaTUnit. + + + + + + The units of the DeltaT - default:seconds[s]. + + + + + + The length of the exposure. + Units are set by ExposureTimeUnit. + + + + + + The units of the ExposureTime - default:seconds[s]. + + + + + + The X position of the stage. Units are set by PositionXUnit. + + + + + + The units of the X stage position - default:[reference frame]. + + + + + + The Y position of the stage. Units are set by PositionYUnit. + + + + + + The units of the Y stage position - default:[reference frame]. + + + + + + The Z position of the stage. Units are set by PositionZUnit. + + + + + + The units of the Z stage position - default:[reference frame]. + + + + + + + Channels + + There must be one per channel in the Image, even for a single-plane image. + And information about how each of them was acquired is stored in the various optional *Ref elements. Each Logical Channel is composed of one or more + ChannelComponents. For example, an entire spectrum in an FTIR experiment may be stored in a single Logical Channel with each discrete wavenumber of the spectrum + constituting a ChannelComponent of the FTIR Logical Channel. An RGB image where the Red, Green and Blue components do not reflect discrete probes but are + instead the output of a color camera would be treated similarly - one Logical channel with three ChannelComponents in this case. + The total number of ChannelComponents for a set of pixels must equal SizeC. + The IlluminationType attribute is a string enumeration which may be set to 'Transmitted', 'Epifluorescence', 'Oblique', or 'NonLinear'. + The user interface logic for labeling a given channel for the user should use the first existing attribute in the following sequence: + Name -> Fluor -> EmissionWavelength -> ChannelComponent/Index. + + + + + + + + + + + + + + + + + + + A name for the channel that is suitable for presentation to the user. + + + + + + + The number of samples the detector takes to form each pixel value. [units:none] + Note: This is not the same as "Frame Averaging" - see Integration in DetectorSettings + + + + + + + The method of illumination used to capture the channel. + + + + + + + + + + + + + + + + The optional PinholeSize attribute allows specifying adjustable + pin hole diameters for confocal microscopes. Units are set by PinholeSizeUnit. + + + + + + The units of the pin hole diameter for confocal microscopes - default:microns[µm]. + + + + + + AcquisitionMode describes the type of microscopy performed for each channel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContrastMethod describes the technique used to achieve contrast for each channel + + + + + + + + + + + + + + + + + + + + Wavelength of excitation for a particular channel. Units are set by ExcitationWavelengthUnit. + + + + + + The units of the wavelength of excitation - default:nanometres[nm]. + + + + + + Wavelength of emission for a particular channel. Units are set by EmissionWavelengthUnit. + + + + + + The units of the wavelength of emission - default:nanometres[nm]. + + + + + + The Fluor attribute is used for fluorescence images. + This is the name of the fluorophore used to produce this channel [plain text string] + + + + + + + The NDfilter attribute is used to specify the combined effect of any neutral density filters used. + The amount of light the filter transmits at a maximum [units:none] + A fraction, as a value from 0.0 to 1.0. + + NOTE: This was formerly described as "units optical density expressed as a PercentFraction". + This was how the field had been described in the schema from the beginning but all + the use of it has been in the opposite direction, i.e. as a amount transmitted, + not the amount blocked. This change has been made to make the model reflect this usage. + + + + + + + The PockelCellSetting used for this channel. This is the amount the polarization of the beam is rotated by. [units:none] + + + + + + + A color used to render this channel - encoded as RGBA + The default value "-1" is #FFFFFFFF so solid white (it is a signed 32 bit value) + NOTE: Prior to the 2012-06 schema the default value was incorrect and produced a transparent red not solid white. + + + + + + + + + + MetadataOnlyMarkers + + This place holder means there is no pixel data in this file. + + + + + + TiffDataBlocks + + This describes the location of the pixel data in a tiff file. + + + + + + + + This must be used when the IFDs are located in another file. + Note: It is permissible for this to be self referential. + + + + + + + + + This can be used when the IFDs are located in another file. + The / (forward slash) is used as the path separator. + A relative path is recommended. However an absolute path can be specified. + Default is to use the file the ome-xml data has been pulled from. + Note: It is permissible for this to be self referential. The file image1.tiff + may contain ome-xml data that has FilePath="image1.tiff" or "./image1.tiff" + + + + + + + + + + + + Gives the IFD(s) for which this element is applicable. Indexed from 0. + Default is 0 (the first IFD). [units:none] + + + + + + + Gives the Z position of the image plane at the specified IFD. Indexed from 0. + Default is 0 (the first Z position). [units:none] + + + + + + + Gives the T position of the image plane at the specified IFD. Indexed from 0. + Default is 0 (the first T position). [units:none] + + + + + + + Gives the C position of the image plane at the specified IFD. Indexed from 0. + Default is 0 (the first C position). [units:none] + + + + + + + Gives the number of IFDs affected. Dimension order of IFDs is given by the enclosing + Pixels element's DimensionOrder attribute. Default is the number of IFDs in the TIFF + file, unless an IFD is specified, in which case the default is 1. [units:none] + + + + + + + + StageLabels + + The StageLabel is used to specify a name and position for a stage position in the microscope's reference frame. + + + + + + + + The X position of the stage label. Units are set by XUnit. + + + + + + The units of the X stage position - default:[reference frame]. + + + + + + The Y position of the stage label. Units are set by YUnit. + + + + + + The units of the Y stage position - default:[reference frame]. + + + + + + The Z position of the stage label. Units are set by ZUnit. + + + + + + The units of the Z stage position - default:[reference frame]. + + + + + + + + + MicrobeamManipulations + + Defines a microbeam operation type and the region of the image it was applied to. + The LightSourceRef element is a reference to a LightSource specified in the Instrument element which was used for a technique other than illumination for + the purpose of imaging. For example, a laser used for photobleaching. + + + + + + + + A description for the Microbeam Manipulation. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + The type of manipulation performed. + + + + + + + + + + + + + + + + + + + + + + + + + + Instruments + + This element describes the instrument used to capture the Image. + It is primarily a container for manufacturer's model and catalog + numbers for the Microscope, LightSource, Detector, Objective and + Filters components. + The Objective element contains the additional elements LensNA and Magnification. + The Filters element can be composed either of separate excitation, + emission filters and a dichroic mirror or a single filter set. + Within the Image itself, a reference is made to this one Filter element. + There may be multiple light sources, detectors, objectives and filters on a microscope. + Each of these has their own ID attribute, which can be referred to from Channel. + It is understood that the light path configuration can be different + for each channel, but cannot be different for each timepoint or + each plane of an XYZ stack. + + + + + + + + + + + + + + + + + + + + + + + Microscopes + The microscope's manufacturer specification. + + + + + + + + + + + + + + + + + + + + + + + + ImagingEnvironments + + This describes the environment that the biological sample was in + during the experiment. + + + + + + + + + + The Temperature is the define units. + + + + + + + The units the Temperature is in - default:Celsius[°C]. + + + + + + + AirPressure is the define units. + + + + + + + The units the AirPressure is in - default:millibars[mbar]. + + + + + + + Humidity around the sample [units:none] + A fraction, as a value from 0.0 to 1.0. + + + + + + + Carbon Dioxide concentration around the sample [units:none] + A fraction, as a value from 0.0 to 1.0. + + + + + + + + + + Projects + + The Project ID is required. + Datasets can be grouped into projects using a many-to-many relationship. + A Dataset may belong to one or more Projects by including one or more ProjectRef elements which refer to Project IDs. + Projects do not directly contain images - only by virtue of containing datasets, which themselves contain images. + + + + + + + + A description for the project. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + + + + + + + + ExperimenterGroups + + The ExperimenterGroupID is required. + Information should ideally be specified for at least one Leader as a contact for the group. + The Leaders are themselves Experimenters. + + + + + + + + A description for the group. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Leaders + + Contact information for a ExperimenterGroup leader specified using a reference + to an Experimenter element defined elsewhere in the document. + + + + + + + + + + + + + Datasets + + An element specifying a collection of images that are always processed together. + Images can belong to more than one Dataset, and a Dataset may contain more than one Image. + Images contain one or more DatasetRef elements to specify what datasets they belong to. + Once a Dataset has been processed in any way, its collection of images cannot be altered. + The ExperimenterRef and ExperimenterGroupRef elements specify the person and group this Dataset belongs to. + Projects may contain one or more Datasets, and Datasets may belong to one or more Projects. + This relationship is specified by listing DatasetRef elements within the Project element. + + + + + + + + A description for the dataset. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + + + + + A name for the dataset that is suitable for presentation to the user. + + + + + + + + + Experiments + + This element describes the type of experiment. The required Type attribute must contain one or more entries from the following list: + FP FRET Time-lapse 4-D+ Screen Immunocytochemistry FISH Electrophysiology Ion-Imaging Colocalization PGI/Documentation + FRAP Photoablation Optical-Trapping Photoactivation Fluorescence-Lifetime Spectral-Imaging Other + FP refers to fluorescent proteins, PGI/Documentation is not a 'data' image. + The optional Description element may contain free text to further describe the experiment. + + + + + + + + A description for the experiment. [plain-text multi-line string] + + + + + + + + + + + + This is a link to the Experimenter who conducted the experiment + + + + + + + + + A term to describe the type of experiment. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Experimenters + + This element describes a person who performed an imaging experiment. + This person may also be a user of the OME system, in which case the UserName element contains their login name. + Experimenters may belong to one or more groups which are specified using one or more ExperimenterGroupRef elements. + + + + + + + + + + + + + + First name, sometime called christian name or given name or forename. [plain text string] + + + + + Any other names. [plain text string] + + + + + A person's last name sometimes called surname or family name. [plain text string] + + + + + A person's email address. [valid email address as string] + + + + + + A person's Institution + The organizing structure that people belong to other than groups. A university, or company, etc. + We do not specify a department element, and do not mean for Institution to be used in this way. + We simply wish to say XXX at YYY. Where YYY has a better chance of being tied to a geographically fixed location + and of being more recognizable than a group of experimenters. [plain text string] + + + + + + + This is the username of the experimenter (in a 'unix' or 'database' sense). [plain text string] + + + + + + + Folders + + An element specifying a possibly heterogeneous collection of data. + Folders may contain Folders so that data may be organized within a tree of Folders. + Data may be in multiple Folders but a Folder may not be in more than one other Folder. + + + + + + + + A description for the folder. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A name for the folder that is suitable for presentation to the user. + + + + + + + + + + + + This is the base from which many microscope components are extended. E.g Objective, Filter etc. + Provides attributes for recording common properties of these components such as Manufacturer name, Model etc, + all of which are optional. + + + + + + The manufacturer of the component. [plain text string] + + + + + + + The Model of the component. [plain text string] + + + + + + + The serial number of the component. [plain text string] + + + + + + + The lot number of the component. [plain text string] + + + + + + + + Binary contents coded in hexadecimal (20 characters long) + + + + + + + + + + A simple type that restricts the value to a float between >=0 and max 32-bit float {i.e. (2−2^-23) × 2^27 ≈ 3.4 × 10^38} + + + + + + + + + + A simple type that restricts the value to a long between 0 and 9223372036854775807 (inclusive). + + + + + + + + + + A simple type that restricts the value to an integer between 0 and 2,147,483,647 (inclusive). + + + + + + + + + + A simple type that restricts the value to an integer between 1 and 2,147,483,647 (inclusive). + + + + + + + + + + A simple type that restricts the value to a float between >0 and max 32-bit float {i.e. (2−2^-23) × 2^27 ≈ 3.4 × 10^38} + + + + + + + + + + A simple type that restricts the value to a float between 0 and 1 (inclusive). + + + + + + + + + + + This is a unique ID for the file but does not conform to the ID pattern used in the rest of the file. + The rest of the IDs are either an full LSID or an internal ID which is a string that is simply unique in this file. + As the UniversallyUniqueIdentifier is used from outside this file to identify it having the same ID in another file could cause problems. + A UUID is 32 hexadecimal digits, in 5 groups, 8-4-4-4-12, separated by hyphens + e.g. urn:uuid:3e450fae-b8f2-4d35-aa54-702168b2487f + There are methods to generate these in most modern languages. + http://www.ietf.org/rfc/rfc4122.txt + + + + + + + + + + Maps + + This is a Mapping of key/value pairs. + + + + + + Ms + This is a key/value pair used to build up a Mapping. The + Element and Attribute name are kept to single letters to minimize the + length at the expense of readability as they are likely to occur many + times. + + + + + + + + + + + + + + + + Represents the number of pixels that are combined to form larger pixels. {used:CCD,EMCCD} + + + + + + No binning. + + + + + + + + 2×2 binning. + + + + + + + + 4×4 binning. + + + + + + + + 8×8 binning. + + + + + + + + Other binning value. + + + + + + + + + + + + The font family used to draw the text. [enumeration] + Note: these values are all lower case so they match + the standard HTML/CSS values. "fantasy" has been + included for completeness we do not recommended its + regular use. + + + + + + serif. + + + + + + + + sans-serif. + + + + + + + + cursive. + + + + + + + + fantasy. + + + + + + + + monospace. + + + + + + + + + + + + The number size/kind used to represent a pixel + + + + + + 8 bit signed integer. + + + + + + 16 bit signed integer. + + + + + + 32 bit signed integer. + + + + + + 8 bit unsigned integer. + + + + + + 16 bit unsigned integer. + + + + + + 32 bit unsigned integer. + + + + + + single-precision floating point. + + + + + + double-precision floating point. + + + + + + complex single-precision floating point. + + + + + + complex double-precision floating point. + + + + + + bit mask. + + + + + + + + + A simple type that identifies itself as a Color, the value is an integer between -2,147,483,648 and 2,147,483,647 (inclusive). + The value is a signed 32 bit encoding of RGBA so "-1" is #FFFFFFFF or solid white. + NOTE: Prior to the 2012-06 schema the default values were incorrect and produced a transparent red not solid white. + + + + + + + + + + The units used to represent a length + + + + yottameter SI unit. + zettameter SI unit. + exameter SI unit. + petameter SI unit. + terameter SI unit. + gigameter SI unit. + megameter SI unit. + kilometer SI unit. + hectometer SI unit. + decameter SI unit. + meter SI unit. + decimeter SI unit. + centimeter SI unit. + millimeter SI unit. + micrometer SI unit. + nanometer SI unit. + picometer SI unit. + femtometer SI unit. + attometer SI unit. + zeptometer SI unit. + yoctometer SI unit. + + ångström SI-derived unit. + + thou Imperial unit (or mil, 1/1000 inch). + line Imperial unit (1/12 inch). + inch Imperial unit. + foot Imperial unit. + yard Imperial unit. + terrestrial mile Imperial unit. + + astronomical unit SI-derived unit. The official term is ua as the SI standard assigned AU to absorbance unit. + light year. + parsec. + + typography point Imperial-derived unit (1/72 inch). Use of this unit should be limited to font sizes. + pixel abstract unit. This is not convertible to any other length unit without a calibrated scaling factor. Its use should should be limited to ROI objects, and converted to an appropriate length units using the PhysicalSize units of the Image the ROI is attached to. + + reference frame abstract unit. This is not convertible to any other length unit without a scaling factor. Its use should be limited to uncalibrated stage positions, and converted to an appropriate length unit using a calibrated scaling factor. + + + + + + + The units used to represent a time interval + + + + yottasecond SI unit. + zettasecond SI unit. + exasecond SI unit. + petasecond SI unit. + terasecond SI unit. + gigasecond SI unit. + megasecond SI unit. + kilosecond SI unit. + hectosecond SI unit. + decasecond SI unit. + second SI unit. + decisecond SI unit. + centisecond SI unit. + millisecond SI unit. + microsecond SI unit. + nanosecond SI unit. + picosecond SI unit. + femtosecond SI unit. + attosecond SI unit. + zeptosecond SI unit. + yoctosecond SI unit. + + minute SI-derived unit. + hour SI-derived unit. + day SI-derived unit. + + + + + + + The units used to represent a pressure + + + + yottapascal SI unit. + zettapascal SI unit. + exapascal SI unit. + petapascal SI unit. + terapascal SI unit. + gigapascal SI unit. + megapascal SI unit. + kilopascal SI unit. + hectopascal SI unit. + decapascal SI unit. + pascal SI unit. Note the C++ enum is mixed case due to PASCAL being a macro used by the Microsoft C and C++ compiler. + decipascal SI unit. + centipascal SI unit. + millipascal SI unit. + micropascal SI unit. + nanopascal SI unit. + picopascal SI unit. + femtopascal SI unit. + attopascal SI unit. + zeptopascal SI unit. + yoctopascal SI unit. + bar SI-derived unit. + megabar SI-derived unit. + kilobar SI-derived unit. + decibar SI-derived unit. + centibar SI-derived unit. + millibar SI-derived unit. + + standard atmosphere SI-derived unit. + + pound-force per square inch Imperial unit. + + torr SI-derived unit. + millitorr SI-derived unit. + + millimetre of mercury SI-derived unit + + + + + + + The units used to represent an angle + + + + degree unit. + radian unit. + gradian unit. + + + + + + + The units used to represent a temperature + + + + degree Celsius unit. + degree Fahrenheit unit. + Kelvin unit. + degree Rankine unit. + + + + + + + The units used to represent an electric potential + + + + yottavolt unit. + zettavolt unit. + exavolt unit. + petavolt unit. + teravolt unit. + gigavolt unit. + megavolt unit. + kilovolt unit. + hectovolt unit. + decavolt unit. + volt unit. + decivolt unit. + centivolt unit. + millivolt unit. + microvolt unit. + nanovolt unit. + picovolt unit. + femtovolt unit. + attovolt unit. + zeptovolt unit. + yoctovolt unit. + + + + + + + The units used to represent power + + + + yottawatt unit. + zettawatt unit. + exawatt unit. + petawatt unit. + terawatt unit. + gigawatt unit. + megawatt unit. + kilowatt unit. + hectowatt unit. + decawatt unit. + watt unit. + deciwatt unit. + centiwatt unit. + milliwatt unit. + microwatt unit. + nanowatt unit. + picowatt unit. + femtowatt unit. + attowatt unit. + zeptowatt unit. + yoctowatt unit. + + + + + + + The units used to represent frequency + + + + yottahertz unit. + zettahertz unit. + exahertz unit. + petahertz unit. + terahertz unit. + gigahertz unit. + megahertz unit. + kilohertz unit. + hectohertz unit. + decahertz unit. + hertz unit. + decihertz unit. + centihertz unit. + millihertz unit. + microhertz unit. + nanohertz unit. + picohertz unit. + femtohertz unit. + attohertz unit. + zeptohertz unit. + yoctohertz unit. + + + + + + + Objectives + + A description of the microscope's objective lens. + Required elements include the lens numerical aperture, + and the magnification, both of which a floating + point (real) numbers. + The values are those that are fixed for a particular + objective: either because it has been manufactured to + this specification or the value has been measured on + this particular objective. + Correction: This is the type of correction coating applied to this lens. + Immersion: This is the types of immersion medium the lens is designed to + work with. It is not the same as 'Medium' in ObjectiveRef (a + single type) as here Immersion can have compound values like 'Multi'. + LensNA: The numerical aperture of the lens (as a float) + NominalMagnification: The specified magnification e.g. x10 + CalibratedMagnification: The measured magnification e.g. x10.3 + WorkingDistance: WorkingDistance of the lens. + + + + + + + + + + + + + + + + The correction applied to the lens + + + + + + + + + + + + + + + + + + + + + + + + The immersion medium the lens is designed for + + + + + + + + + + + + + + + + + The numerical aperture of the lens expressed as a floating point (real) number. + Expected range 0.02 - 1.5 [units:none] + + + + + + + The magnification of the lens as specified by the manufacturer - i.e. '60' is a 60X lens. [units:none] + Note: The type of this has been changed from int to float to allow + the specification of additional lenses e.g. 0.5X lens + + + + + + + The magnification of the lens as measured by a calibration process- i.e. '59.987' for a 60X lens. [units:none] + + + + + + + The working distance of the lens expressed as a floating point (real) number. Units are set by WorkingDistanceUnit. + + + + + + The units of the working distance - default:microns[µm]. + + + + + + Records whether or not the objective was fitted with an Iris. [flag] + + + + + + + + + + Detectors + + The type of detector used to capture the image. + The Detector ID can be used as a reference within the Channel element in the Image element. + The values stored in Detector represent the fixed values, + variable values modified during the acquisition go in DetectorSettings + + Each attribute now has an indication of what type of detector + it applies to. This is preparatory work for cleaning up and + possibly splitting this object into sub-types. + + + + + + + + + + + + + + + + The Detector Gain for this detector, as a float. [units:none] {used:CCD,EMCCD,PMT} + + + + + + + The Voltage of the detector (e.g. PMT voltage) as a float. {used:PMT} + Units are set by VoltageUnit. + + + + + + The units of the Voltage - default:volts[V]. + + + + + + The Detector Offset. [units:none] {used:CCD,EMCCD} + + + + + + + The fixed Zoom for a detector. [units:none] {used:PMT} + + + + + + + Gain applied to the detector signal. + This is the electronic gain (as apposed to the inherent gain) that is set for the detector. [units:none] {used:EMCCD#EMGain} + + + + + + + + The Type of detector. E.g. CCD, PMT, EMCCD etc. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FilterSets + Filter set manufacturer specification + + + + + + + + ExcitationFilters + + The Filters placed in the Excitation light path. + + + + + + + EmissionFilters + + The Filters placed in the Emission light path. + + + + + + + + + + + + Filters + + A filter is either an excitation or emission filters. + There should be one filter element specified per wavelength in the image. + The channel number associated with a filter set is specified in Channel. + It is based on the FilterSpec type, so has the required attributes Manufacturer, Model, and LotNumber. + It may also contain a Type attribute which may be set to + 'LongPass', 'ShortPass', 'BandPass', 'MultiPass', + 'Dichroic', 'NeutralDensity', 'Tuneable' or 'Other'. + It can be associated with an optional FilterWheel - Note: this is not the same as a FilterSet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A filter 'wheel' in OME can refer to any arrangement of filters in a filter holder of any shape. It could, for example, be a filter slider. [plain text string] + + + + + + + + + + + TransmittanceRanges + + This records the range of wavelengths that are transmitted by the filter. It also records the maximum amount of light transmitted. + + + + + + + CutIn is the wavelength below which there is less than 50% transmittance for a filter. Units are set by CutInUnit. + + + + + + The units of the CutIn - default:nanometres[nm]. + + + + + + CutOut is the wavelength above which there is less than 50% transmittance for a filter. Units are set by CutOutUnit. + + + + + + The units of the CutOut - default:nanometres[nm]. + + + + + + CutInTolerance. Units are set by CutInToleranceUnit. + + + + + + The units of the CutInTolerance - default:nanometres[nm]. + + + + + + CutOutTolerance. Units are set by CutOutToleranceUnit. + + + + + + The units of the CutOutTolerance - default:nanometres[nm]. + + + + + + The amount of light the filter transmits at a maximum [units:none] + A fraction, as a value from 0.0 to 1.0. + + + + + + + + Dichroics + The dichromatic beamsplitter or dichroic mirror used for this filter combination. + + + + + + + + + + + + + + + + + + + LightPaths + A description of the light path + + + + + + ExcitationFilters + + The Filters placed in the Excitation light path. + + + + + + + EmissionFilters + + The Filters placed in the Emission light path. + + + + + + + + + + + + + + + + + + + + + + + + + + LightSources + + The lightsource for the instrument. An instrument may have several light sources. + The type of lightsource is specified by one of the child-elements which are 'Laser', 'Filament', 'Arc' or 'LightEmittingDiode'. + Each of the light source types has its own Type attribute to further differentiate the light source + (eg, Nd-YAG for Laser or Hg for Arc). + + + + + + + + + + + + + + + A LightSource ID must be specified for each light source, and the individual + light sources can be referred to by their LightSource IDs (eg from Channel). + + + + + + + The light-source power. Units are set by PowerUnit. + + + + + + The units of the Power - default:milliwatts[mW]. + + + + + + + + Lasers + + Laser types are specified using two attributes - the Type and the LaserMedium. + + + + + + + + + + The Laser element may contain a Pump sub-element which refers to + a LightSource used as a laser pump. + + + + + + + + Type is the general category of laser. + + + + + + + + + + + + + + + + + + + The Medium attribute specifies the actual lasing medium + for a given laser type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Wavelength of the laser. Units are set by WavelengthUnit. + + + + + + The units of the Wavelength - default:nanometres[nm]. + + + + + + FrequencyMultiplication that may be specified. [units:none] + + + + + + + Whether or not the laser is Tuneable [flag] + + + + + + + The Pulse mode of the laser. + + + + + + + + + + + + + + + + + If true the laser has a PockelCell to rotate the polarization of the beam. [flag] + + + + + + + The is the rate in Hz at which the laser pulses if + the Pulse type is 'Repetitive'. hertz[Hz] + Units are set by RepetitionRateUnit. + + + + + + The units of the RepetitionRate - default:hertz[Hz]. + + + + + + + + + Arcs + + The Arc element is used to describe various kinds of Arc lamps - Hg, Xe, HgXe. + The Power of the Arc is now stored in the LightSource. + + + + + + + + + The type of Arc lamp. + + + + + + + + + + + + + + + + + + Filaments + + The Filament element is used to describe various kinds of filament bulbs such as Incadescent or Halogen. + The Power of the Filament is now stored in the LightSource. + + + + + + + + + The type of filament. + + + + + + + + + + + + + + + + + LightEmittingDiodes + + The LightEmittingDiode element is used to describe + various kinds of LED lamps. + + As the LightEmittingDiode is inside a LightSource it already has + available the values from ManufacturerSpec + (Manufacturer, Model, SerialNumber, LotNumber) + And the values from LightSource which includes Power in milliwatts + + We have looked at extending this element but have had a problem + producing a generic solution. + + Possible attributes talked about adding include: + Power in lumens - but this is complicated by multi-channel + devices like CoolLED where each channel's power is different + Wavelength Range - not a simple value so would require + multiple attributes or a child element + Angle of Projection - this would be further affected by the + optics used for filtering the naked LED or that combine + power from multiple devices + + These values are further affected if you over-drive the LED + resulting in a more complex system + + Another issue is that LED's may not be used directly for + illumination but as drivers for secondary emissions from doped + fiber optics. This would require the fiber optics to be modeled. + + Thanks to Paul Goodwin of Applied Precision of information about + this topic. + + + + + + + + + + + GenericExcitationSources + + The GenericExcitationSource element is used to represent + a source as a collection of key/value pairs, stored + in a Map. The other lightsource objects should + always be used in preference to this if possible. + + + + + + + + + + + + + + + Pumps + + The Pump element is a reference to a LightSource. It is used within the Laser element to specify the light source for the laser's pump (if any). + + + + + + + + + + + + + + Rights + + The rights holder of this data and the rights held. + + + + + + + The rights holder for this data. [plain-text multi-line string] + e.g. "Copyright (C) 2002 - 2016 Open Microscopy Environment" + + + + + + + + + + + + The rights held by the rights holder. [plain-text multi-line string] + e.g. "All rights reserved" or "Creative Commons Attribution 3.0 Unported License" + + + + + + + + + + + + + + + + + + Reference is an empty complex type that is contained and extended by all the *Ref elements and also the Settings Complex Type + Each *Ref element defines an attribute named ID of simple type *ID and no other information + Each simple type *ID is restricted to the base type LSID with an appropriate pattern + + + + + + + + The ImageRef element is a reference to an Image element. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + There may be one or more of these in a Dataset. + This empty element has a required Project ID attribute that refers to Projects defined within the OME element. + + + + + + + + + + + + + + This empty element has a required Experimenter ID and an optional DocumentID attribute which refers to one of the Experimenters defined within OME. + + + + + + + + + + + + + This empty element has a reference (the ExperimenterGroup ID attribute) to a ExperimenterGroup defined within OME. + + + + + + + + + + + + + This empty element can be used (via the required Instrument ID attribute) to refer to an Instrument defined within OME. + + + + + + + + + + + + + + The DatasetRef element refers to a Dataset by specifying the Dataset ID attribute. + One or more DatasetRef elements may be listed within the Image element to specify what Datasets + the Image belongs to. + + + + + + + + + + + + + + The FolderRef element refers to a Folder by specifying the Folder ID attribute. + One or more FolderRef elements may be listed within the Folder element to specify what Folders + the Folder contains. This tree hierarchy must be acyclic. + + + + + + + + + + + + + + + + + + + + + + + + + + Settings is an empty complex type that is contained and extended by all the *Settings elements + Each *Settings element defines an attribute named ID of simple type *ID and the other information that is needed. + Each simple type *ID is restricted to the base type LSID with an appropriate pattern + + + + + + + + + + LightSourceSettingsCombinations + + + + + + + + + The Attenuation of the light source [units:none] + A fraction, as a value from 0.0 to 1.0. + + + + + + + The Wavelength of the light source. Units are set by WavelengthUnit. + + + + + + + The units of the Wavelength of the light source - default:nanometres[nm] + + + + + + + + + + DetectorSettingsCombinations + + This holds the setting applied to a detector as well as a + reference to the detector. + The ID is the detector used in this case. + The values stored in DetectorSettings represent the variable values, + fixed values not modified during the acquisition go in Detector. + + Each attribute now has an indication of what type of detector + it applies to. This is preparatory work for cleaning up and + possibly splitting this object into sub-types. + + + + + + + + + + The Offset of the detector. [units none] {used:CCD,EMCCD} + + + + + + + The Gain of the detector. [units:none] {used:CCD,EMCCD,PMT} + + + + + + + The Voltage of the detector. {used:PMT} + Units are set by VoltageUnit. + + + + + + + The units of the Voltage of the detector - default:volts[V] + + + + + + + The Zoom or "Confocal Zoom" or "Scan Zoom" for a detector. [units:none] {used:PMT} + + + + + + + The speed at which the detector can count pixels. {used:CCD,EMCCD} + This is the bytes per second that + can be read from the detector (like a baud rate). + Units are set by ReadOutRateUnit. + + + + + + The units of the ReadOutRate - default:megahertz[Hz]. + + + + + + Represents the number of pixels that are combined to form larger pixels. {used:CCD,EMCCD} + + + + + + + This is the number of sequential frames that get averaged, + to improve the signal-to-noise ratio. [units:none] {used:CCD,EMCCD} + + + + + + + + + + ObjectiveSettingsCombinations + + This holds the setting applied to an objective as well as a + reference to the objective. + The ID is the objective used in this case. + + + + + + + + + + The CorrectionCollar is normally an adjustable ring on the + objective. Each has an arbitrary scale on it so the values + is unit-less. [units:none] + + + + + + + + A description of a Medium used for the lens. + The Medium is the actual immersion medium used in this case. + + + + + + + + + + + + + + + The RefractiveIndex is that of the immersion medium. This is + a ratio so it also unit-less. [units:none] + + + + + + + + + + + + + Either LSID or internal consistent IDs for the file + See: http://www.openmicroscopy.org/site/support/file-formats/working-with-ome-xml/id-and-lsid + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Externals + Describes a file location. Can optionally specify a portion of a file using Offset and a ReadLength. + If Offset and ReadLength are specified in conjunction with Compression, then they point into the uncompressed file. + + + + + + file location + + + + + The digest of the file specified in href. + + + + + Specifies the compression scheme used to encode the data. + + + + + + + + + + + + + + BinDataBlocks + The contents of this element are base64-encoded. These are not CDATA sections, just a base64 stream. + + + + + + + Specifies the compression scheme used to encode the data. + + + + + + + + + + + + + This is true if the binary data was written in BigEndian order. This is dependent on the system architecture of the machine that wrote the pixels. True for essentially all modern CPUs other than Intel and Alpha. All Binary data must be written in the same endian order. + + + + + + + Character count attribute for the BinData field. This is the length of the base-64 encoded block. It allows easy skipping of the block when parsing the file. [unit:bytes] + + + + + + + + + + + + + + BinaryFiles + Describes a binary file. + + + + + + + + + + + Size of the uncompressed file. [unit:bytes] + + + + + + + + + + + + + + An unordered collection of annotation attached to objects in the OME data model. + + + + + + + + + + + + + + + + + + + + + + The AnnotationRef element is a reference to an element derived + from the CommonAnnotation element. + + + + + + + + + + + + + + + Annotations + + An annotation from which all others are ultimately derived. + + + + + + + A description for the annotation. [plain-text multi-line string] + + + + + + + + + + + + + + + + + + + + + We recommend the inclusion of a namespace for annotations you + define. If it is absent then we assume the annotation is to + use our (OME's) default interpretation for this type. + + + + + + + The Annotator is the person who attached this annotation. + e.g. If UserA annotates something with TagB, owned by UserB, + UserA is still the Annotator. + + + + + + + + + + + + + + BasicAnnotations + + An abstract Basic Annotation from which some others are derived. + + + + + + + + + NumericAnnotations + + An abstract Numeric Annotation from which some others are derived. + + + + + + + + + TextAnnotations + + An abstract Text Annotation from which some others are derived. + + + + + + + + + TypeAnnotations + + An abstract Type Annotation from which some others are derived. + + + + + + + + + + + + FileAnnotations + + A file object annotation + + + + + + + + + + + + + + + XMLAnnotations + + An general xml annotation. The contents of this is not processed as OME XML but should still be well-formed XML. + + + + + + + + + + + + + + + + + + + + + ListAnnotations + + This annotation is a grouping object. It uses the sequence of + annotation refs from the base Annotation to form the list. + + + + + + + + + + + CommentAnnotations + + A simple comment annotation + + + + + + + + + + + + + + + LongAnnotations + + A simple numerical annotation of type xsd:long + + + + + + + + + + + + + + + DoubleAnnotations + + A simple numerical annotation of type xsd:double + + + + + + + + + + + + + + + BooleanAnnotations + + A simple boolean annotation of type xsd:boolean + + + + + + + + + + + + + + + TimestampAnnotations + + A date/time annotation of type xsd:dateTime + + + + + + + + + + + + + + + TagAnnotations + + A tag annotation (represents a tag or a tagset) + + + + + + + + + + + + + + + TermAnnotations + + A ontology term annotation + + + + + + + + + + + + + + + MapAnnotations + + An map annotation. The contents of this is a list of key/value pairs. + + + + + + + + + + + + + + + + + ROIs + + A four dimensional 'Region of Interest'. + If they are not used, and the Image has more than one plane, + the entire set of planes is assumed to be included in the ROI. + Multiple ROIs may be specified. + + + + + + + + + + + + + + + + + + + + + + A description for the ROI. [plain-text multi-line string] + + + + + + + + + + + + + + The Name identifies the ROI to the user. [plain-text string] + + + + + + + + + Shapes + + The shape element contains a single specific ROI shape and links + that to any channels, and a timepoint and a z-section. It also + records any transform applied to the ROI shape. + + + + + + + This is a matrix used to transform the shape. + The element has 6 xsd:float attributes. If the element + is present then all 6 values must be included. + + + + + + + + + + + + + The color of the fill - encoded as RGBA + The value "-1" is #FFFFFFFF so solid white (it is a signed 32 bit value) + NOTE: Prior to the 2012-06 schema the default value was incorrect and produced a transparent red not solid white. + + + + + + + + The rule used to decide which parts of the shape to + fill. [enumeration] + + + + + + + + + + + + The color of the stroke - encoded as RGBA + The value "-1" is #FFFFFFFF so solid white (it is a signed 32 bit value) + NOTE: Prior to the 2012-06 schema the default value was incorrect and produced a transparent red not solid white. + + + + + + + The width of the stroke. Units are set by StrokeWidthUnit. + + + + + + + The units used for the stroke width. + + + + + + + e.g. "none", "10 20 30 10" + + + + + + + + + The font family used to draw the text. [enumeration] + Note: these values are all lower case so they match + the standard HTML/CSS values. "fantasy" has been + included for completeness; we do not recommend its + regular use. This attribute is under consideration + for removal from the OME-XML schema. + + + + + + + + + + + + + + + Size of the font. Units are set by FontSizeUnit. + + + + + + + The units used for the font size. + + + + + + + + The style and weight applied to the text. [enumeration] + This is a simplified combination of the HTML/CSS + attributes font-style AND font-weight. + + + + + + + + + + + + + + Controls whether the shape is locked and read only, + true is locked, false is editable. + + + + + + + + The z-section the ROI applies to. If not specified then + the ROI applies to all the z-sections of the image. [units:none] + This is numbered from 0. + + + + + + + The timepoint the ROI applies to. If not specified then + the ROI applies to all the timepoints of the image. [units:none] + This is numbered from 0. + + + + + + + The channel the ROI applies to. If not specified then + the ROI applies to all the channels of the image. [units:none] + This is numbered from 0. + + + + + + + + Rectangles + + A simple rectangle object. If rotation is required apply a + transformation at the Shape level. + + + + + + + + + The X value of the left edge or the rectangle. [units pixels] + + + + + + + The y value of the top edge or the rectangle. [units pixels] + + + + + + + The width of the rectangle. [units pixels] + + + + + + + The height of the rectangle. [units pixels] + + + + + + + + + + + Masks + + The Mask ROI shape is a link to a BinData object that is + a BIT mask drawn on top of the image as an ROI. It is applied + at the same scale, pixel to pixel, as the Image the ROI is + applied to, unless a transform is applied at the shape level. + + + + + + + + + + + + The X coordinate of the left side of the image. [units pixels] + + + + + + + The Y coordinate of the top side of the image. [units pixels] + + + + + + + The width of the mask. [units pixels] + + + + + + + The height of the mask. [units pixels] + + + + + + + + + + + Points + + + + + + + + The X coordinate of the point. [units pixels] + + + + + + + The Y coordinate of the point. [units pixels] + + + + + + + + + + + Ellipses + + A simple ellipse object. If rotation is required apply a + transformation at the Shape level. + + + + + + + + + The X coordinate of the center of the ellipse. [units pixels] + + + + + + + The Y coordinate of the center of the ellipse. [units pixels] + + + + + + + The horizontal radius of the ellipse. [units pixels] + + + + + + + The vertical radius of the ellipse. [units pixels] + + + + + + + + + + + Lines + + A straight line defined by it's end points. + + + + + + + + The X coordinate of the start of the line. [units pixels] + + + + + + The Y coordinate of the start of the line. [units pixels] + + + + + + The X coordinate of the end of the line. [units pixels] + + + + + + The Y coordinate of the end of the line. [units pixels] + + + + + + + + + + + + + Polylines + + The Polyline defines open shapes formed of straight + lines. Note: Polyline uses counterclockwise winding (this is the + default OpenGL behavior) + + + + + + + + The points of the polyline are defined as a list of comma + separated x,y coordinates separated by spaces like "x1,y1 x2,y2 x3,y3" e.g. + "0,0 1,2 3,5" + + + + + + + + + + + + Polygons + + The Polygon defines closed shapes formed of straight + lines. Note: Polygon uses counterclockwise winding (this is the + default OpenGL behavior) + + + + + + + + The points of the Polygon are defined as a list of comma + separated x,y coordinates separated by spaces like "x1,y1 x2,y2 x3,y3" e.g. + "0,0 1,2 3,5" + + + + + + + + + + Labels + + The text label. Any transformation should be applied at the + shape level. + + + + + + + + This defines the X coordinate of the current text position + of the first character in the string. [units pixels] + + + + + This defines the Y coordinate of the current text position + of the first character in the string. [units pixels] + + + + + + + + + + + + + + + + + + + + + + A matrix used to transform the shape. + ⎡ A00, A01, A02 ⎤ + ⎢ A10, A11, A12 ⎥ + ⎣ 0, 0, 1 ⎦ + + + + + + + + + + + + + + + + + + + + + + + + + Markers + + Shape of marker on the end of a line. [enumeration] + + + + + + + + + + + Plates + + This element identifies microtiter plates within a screen. + A plate can belong to more than one screen. + The Screen(s) that a plate belongs to are specified by the ScreenRef element. + The Plate ID and Name attributes are required. + The Wells in a plate are numbers from the top-left corner in a grid starting at zero. + i.e. The top-left well of a plate is index (0,0) + + + + + + + + A description for the plate. + + + + + + + + + + + + + + + + + + + + + The Name identifies the plate to the user. + It is used much like the ID, and so must be + unique within the document. + + If a plate name is not available when one is needed + it will be constructed in the following order: + 1. If name is available use it. + 2. If not use "Start time - End time" + (NOTE: Not a subtraction! A string representation + of the two times separated by a dash.) + 3. If these times are not available use the Plate ID. + + + + + + + A textual annotation of the current state of the plate with respect to the + experiment work-flow; e.g. + 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. + + + + + + + The ExternalIdentifier attribute may contain a reference to an external database. + + + + + + + The ColumnNamingConvention + + + + + + + The RowNamingConvention + + + + + + + This defines the X position to use for the origin of the + fields (individual images) taken in a well. It is used + with the X in the WellSample to display the fields + in the correct position relative to each other. Each Well + in the plate has the same well origin. Units are set by WellOriginXUnit. + + In the OMERO clients by convention we display the WellOrigin + in the center of the view. + + + + + + The units of the well origin in X - default:reference frame. + + + + + + This defines the Y position to use for the origin of the + fields (individual images) taken in a well. It is used + with the Y in the WellSample to display the fields + in the correct position relative to each other. Each Well + in the plate has the same well origin. Units are set by WellOriginYUnit. + + In the OMERO clients by convention we display the WellOrigin + in the center of the view. + + + + + + The units of the well origin in Y - default:reference frame. + + + + + + The number of rows in the plate + + + + + + + The number of columns in the plate + + + + + + + The index of the WellSample to display as the default Field + + + + + + + + + + + + + Predefined list of values for the well labels + + + + + + + While the label type 'number' has a clear meaning the 'letter' + type is more complex. + + If you have less than 26 values use letters A to Z. + Once you get more than 26 values there are several different + approaches in use. + One we have see include: + + Single letter, then double letter each running A to Z, right first + e.g. A, B, C, ... X, Y, Z, AA, AB, AC, ... AY, AZ, BA, BB, ... + This is the format used by Microsoft Excel so users may be familiar with it. + This is the approach we use in the OMERO client applications. + + CAPITALsmall, each running A to Z, small first + e.g. Aa, Ab, Ac, ... Ax, Ay, Az, Ba, Bb, Bc, ... By, Bz, Ca, Cb, ... + This is in use by some plate manufactures. + + Single letter, then double letter, then triple letter, and so on + e.g. A, B, C, ... X, Y, Z, AA, BB, CC, ... YY, ZZ, AAA, BBB, ... + This has the advantage that the first 26 are the same as the standard + but has a problem an the labels get wider and wider leading to user + interface problems. + + + + + + + 1, 2, 3, ... + + + + + + + + + + + + + + + Reagents + + Reagent is used to describe a chemical or some other physical experimental parameter. + + + + + + + + A long description for the reagent. + + + + + + + + + + + + + + + + + + + A short name for the reagent + + + + + + + This is a reference to an external (to OME) representation of the Reagent. + It serves as a foreign key into an external database. - It is sometimes referred to as ExternalIdentifier. + + + + + + + + + + + + + + + + + + + + + + + + + Screens + + The Screen element is a grouping for Plates. + The required attribute is the Screen's Name and ID - both must be unique within the document. + The Screen element may contain an ExternalRef attribute that refers to an external database. + A description of the screen may be specified in the Description element. + Screens may contain overlapping sets of Plates i.e. Screens and Plates have a many-to-many relationship. + Plates contain one or more ScreenRef elements to specify what screens they belong to. + + + + + + + + A description for the screen. + + + + + + + + + + + + + + The PlateRef element is a reference to a Plate element. + Screen elements may have one or more PlateRef elements to define the plates that are part of the screen. + Plates may belong to more than one screen. + + + + + + + + + + + + + + + + + + + + + + A pointer to an externally defined protocol, usually in a screening database. + + + + + + + A description of the screen protocol; may contain very detailed information to + reproduce some of that found in a screening database. + + + + + + + A description of the set of reagents; may contain very detailed information to + reproduce some of that information found in a screening database. + + + + + + + A pointer to an externally defined set of reagents, usually in a screening + database/automation database. + + + + + + + A human readable identifier for the screen type; e.g. RNAi, cDNA, SiRNA, etc. + This string is likely to become an enumeration in future releases. + + + + + + + + + + + + + + + PlateAcquisitions + + PlateAcquisition is used to describe a single acquisition run for a plate. + This object is used to record the set of images acquired in a single + acquisition run. The Images for this run are linked to PlateAcquisition + through WellSample. + + + + + + + + A description for the PlateAcquisition. + + + + + + + + + + + + + + + + + + + + + Time when the last image of this acquisition was collected + + + + + + + Time when the first image of this acquisition was collected + + + + + + + The maximum number of fields (well samples) in any well + in this PlateAcquisition. + This is only used to speed up user interaction by stopping + the reading of every well sample. + + + + + + + + + + + + + + + Wells + + A Well is a component of the Well/Plate/Screen construct to describe screening applications. + A Well has a number of WellSample elements that link to the Images collected in this well. + The ReagentRef links any Reagents that were used in this Well. A well is part of only one Plate. + The origin for the row and column identifiers is the top left corner of the plate starting at zero. + i.e The top left well of a plate is index (0,0) + + + + + + + + + + + + + + + + + + + + + This is the column index of the well, the origin is the top left corner of the plate + with the first column of cells being column zero. i.e top left is (0,0) + The combination of Row, Column has to be unique for each well in a plate. + + + + + + + This is the row index of the well, the origin is the top left corner of the plate + with the first row of wells being row zero. i.e top left is (0,0) + The combination of Row, Column has to be unique for each well in a plate. + + + + + + + A description of the externally defined identifier for this plate. + + + + + + + The ExternalIdentifier attribute may contain a reference to an external database. + + + + + + + A human readable identifier for the screening status. + e.g. empty, positive control, negative control, control, experimental, etc. + + + + + + + A marker color used to highlight the well - encoded as RGBA + The default value "-1" is #FFFFFFFF so solid white (it is a signed 32 bit value) + NOTE: Prior to the 2012-06 schema the default value was incorrect and produced a transparent red not solid white. + + + + + + + + + + + + + + + WellSamples + + WellSample is an individual image that has been captured within a Well. + + + + + + + + + This is the main link to the core Image element + + + + + + + + + The X position of the field (image) within the well relative to + the well origin defined on the Plate. Units are set by PositionXUnit. + + + + + + The units of the position in X - default:reference frame. + + + + + + The Y position of the field (image) within the well relative to + the well origin defined on the Plate. Units are set by PositionYUnit. + + + + + + The units of the position in Y - default:reference frame. + + + + + + The time-point at which the image started to be collected + + + + + + + This records the order of the well samples. Each + index should be unique for a given plate but they do not + have to be sequential, there may be gaps if part of the + dataset is missing. In the user interface the displayed + value of the index will be calculated modulo the number + of PlateAcquisitions for the plate. + + + + + + + + + + + + + + + + The WellSampleRef element is a reference to a WellSample element. + + + + + + + + + + + + diff --git a/py/ome_metadata/__init__.py b/py/ome_metadata/__init__.py new file mode 100644 index 0000000..6025a15 --- /dev/null +++ b/py/ome_metadata/__init__.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from . import ome_metadata_rs as rs # noqa + + +class Ome(dict): + @staticmethod + def from_xml(xml: str) -> Ome: + """Create the OME structure from an XML string""" + new = Ome() + new.update(rs.ome(str(xml))) + return new + + def __dir__(self) -> list[str]: + return list(self.keys()) + list(super().__dir__()) + + def __getattr__(self, key: str) -> Ome | OmeList | int | float | str: + try: + new = self.__getitem__(key) + except KeyError: + raise AttributeError(f"'Ome' object has no attribute '{key}'") + if isinstance(new, dict): + return Ome(**new) + elif isinstance(new, list): + return OmeList(new) + else: + return new + + +class OmeList(list): + def __getitem__(self, item: int) -> Ome | OmeList | int | float | str: + new = super().__getitem__(item) + if isinstance(new, dict): + return Ome(**new) + elif isinstance(new, list): + return OmeList(new) + else: + return new diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..20d2ce6 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,32 @@ +[build-system] +requires = ["maturin>=1.8,<2.0"] +build-backend = "maturin" + +[project] +name = "ome-metadata" +keywords = ["bioformats", "imread", "ome", "metadata"] +requires-python = ">=3.10" +classifiers = [ + "License :: OSI Approved :: MIT License", + "Programming Language :: Rust", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +dynamic = ["version", "description", "authors", "license", "readme"] + +[project.urls] +Repository = "https://github.com/wimpomp/ome-metadata" + +[tool.maturin] +python-source = "py" +features = ["pyo3/extension-module", "python"] +module-name = "ome_metadata.ome_metadata_rs" + +[tool.isort] +line_length = 119 diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..bfa3bed --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,51 @@ +#![allow(non_camel_case_types)] +pub mod ome; + +#[cfg(feature = "python")] +mod py; + +use anyhow::{Error, Result}; +pub use ome::Ome; +use quick_xml::de::from_str; +use std::str::FromStr; + +impl FromStr for Ome { + type Err = Error; + + fn from_str(s: &str) -> Result { + Ok(from_str(s)?) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs::read_to_string; + + macro_rules! test_read { + ($($name:ident: $file:expr $(,)?)*) => { + $( + #[test] + fn $name() -> Result<()> { + let file = read_to_string(format!("tests/{}.xml", $file))?; + let _ome: Ome = file.parse()?; + Ok(()) + } + )* + }; + } + + test_read!( + a: "YTL1849A111_2023_05_04__14_46_19_cellnr_1_track" + b: "Experiment-2029" + c: "test" + d: "4-Pos_001_002" + e: "YTL1841B2-2-1_1hr_DMSO_galinduction_1" + f: "1xp53-01-AP1" + g: "YTL378_JF552" + h: "MK022_cE9_1-01-Airyscan Processing-01-Scene-2-P1" + i: "beads_2023_05_04__19_00_22" + j: "20230511-p53-4x-CMV-1min-4h-01-Airyscan Processing-01" + k: "YTL1849A131_2023_05_04__13_36_36" + ); +} diff --git a/src/ome.rs b/src/ome.rs new file mode 100644 index 0000000..3ed7da5 --- /dev/null +++ b/src/ome.rs @@ -0,0 +1,2765 @@ +#[cfg(feature = "python")] +use pyo3::types::{PyDict, PyInt, PyString}; +#[cfg(feature = "python")] +use pyo3::{Bound, IntoPyObject, PyErr, PyResult, Python}; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "python")] +macro_rules! impl_enum_into_py_object { + ($($t:ty $(,)?)*) => { + $( + impl<'py> IntoPyObject<'py> for $t { + type Target = PyString; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> PyResult { + Ok(format!("{:?}", self).into_pyobject(py)?) + } + } + )* + }; +} + +#[cfg(feature = "python")] +macro_rules! impl_empty_struct_into_py_object { + ($($t:ty $(,)?)*) => { + $( + impl<'py> IntoPyObject<'py> for $t { + type Target = PyInt; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> PyResult { + Ok(0usize.into_pyobject(py)?) + } + } + )* + }; +} + +#[cfg(feature = "python")] +macro_rules! impl_boxed_struct_into_py_object { + ($($t:ty $(,)?)*) => { + $( + impl<'py> IntoPyObject<'py> for Box<$t> { + type Target = PyDict; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> PyResult { + (*self).into_pyobject(py) + } + } + )* + }; +} + +#[cfg(feature = "python")] +impl_enum_into_py_object!( + ArcType, + BinDataCompressionType, + BinningType, + ChannelIlluminationType, + ChannelAcquisitionModeType, + ChannelContrastMethodType, + DetectorType, + ExperimentItemType, + FilamentType, + FilterType, + FontFamilyType, + LaserType, + LaserLaserMediumType, + LaserPulseType, + MarkerType, + MicrobeamManipulationItemType, + MicroscopeType, + NamingConventionType, + ObjectiveCorrectionType, + ObjectiveImmersionType, + ObjectiveSettingsMediumType, + PixelsDimensionOrderType, + PixelType, + ShapeFillRuleType, + ShapeFontStyleType + UnitsElectricPotentialType, + UnitsFrequencyType, + UnitsLengthType, + UnitsPowerType, + UnitsPressureType, + UnitsTemperatureType, + UnitsTimeType, +); + +#[cfg(feature = "python")] +impl_empty_struct_into_py_object!(MetadataOnly, XmlAnnotationValue); +#[cfg(feature = "python")] +impl_boxed_struct_into_py_object!(Channel, Image); + +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AffineTransform { + #[serde(rename = "@A00")] + pub a00: f32, + #[serde(rename = "@A10")] + pub a10: f32, + #[serde(rename = "@A01")] + pub a01: f32, + #[serde(rename = "@A11")] + pub a11: f32, + #[serde(rename = "@A02")] + pub a02: f32, + #[serde(rename = "@A12")] + pub a12: f32, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Annotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AnnotationRef { + #[serde(rename = "@ID")] + pub id: String, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Arc { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde(default = "Arc::default_power_unit", rename = "@PowerUnit")] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Arc { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::W + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ArcType { + #[serde(rename = "Hg")] + Hg, + #[serde(rename = "Xe")] + Xe, + #[serde(rename = "HgXe")] + HgXe, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BinData { + #[serde(default = "BinData::default_compression", rename = "@Compression")] + pub compression: BinDataCompressionType, + #[serde(rename = "@BigEndian")] + pub big_endian: bool, + #[serde(rename = "@Length")] + pub length: i64, + #[serde(rename = "$text")] + pub content: String, +} +impl BinData { + pub fn default_compression() -> BinDataCompressionType { + BinDataCompressionType::None + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum BinDataCompressionType { + #[serde(rename = "zlib")] + Zlib, + #[serde(rename = "bzip2")] + Bzip2, + #[serde(rename = "none")] + None, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BinaryFile { + #[serde(rename = "@FileName")] + pub file_name: String, + #[serde(rename = "@Size")] + pub size: i64, + #[serde(default, rename = "@MIMEType")] + pub mime_type: Option, + #[serde(rename = "$value")] + pub content: BinaryFileContent, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum BinaryFileContent { + #[serde(rename = "External")] + External(External), + #[serde(rename = "BinData")] + BinData(BinData), +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum BinningType { + #[serde(rename = "1x1")] + _1X1, + #[serde(rename = "2x2")] + _2X2, + #[serde(rename = "4x4")] + _4X4, + #[serde(rename = "8x8")] + _8X8, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BooleanAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: bool, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Channel { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "@SamplesPerPixel")] + pub samples_per_pixel: Option, + #[serde(default, rename = "@IlluminationType")] + pub illumination_type: Option, + #[serde(default, rename = "@PinholeSize")] + pub pinhole_size: Option, + #[serde( + default = "Channel::default_pinhole_size_unit", + rename = "@PinholeSizeUnit" + )] + pub pinhole_size_unit: UnitsLengthType, + #[serde(default, rename = "@AcquisitionMode")] + pub acquisition_mode: Option, + #[serde(default, rename = "@ContrastMethod")] + pub contrast_method: Option, + #[serde(default, rename = "@ExcitationWavelength")] + pub excitation_wavelength: Option, + #[serde( + default = "Channel::default_excitation_wavelength_unit", + rename = "@ExcitationWavelengthUnit" + )] + pub excitation_wavelength_unit: UnitsLengthType, + #[serde(default, rename = "@EmissionWavelength")] + pub emission_wavelength: Option, + #[serde( + default = "Channel::default_emission_wavelength_unit", + rename = "@EmissionWavelengthUnit" + )] + pub emission_wavelength_unit: UnitsLengthType, + #[serde(default, rename = "@Fluor")] + pub fluor: Option, + #[serde(default, rename = "@NDFilter")] + pub nd_filter: Option, + #[serde(default, rename = "@PockelCellSetting")] + pub pockel_cell_setting: Option, + #[serde(default = "Channel::default_color", rename = "@Color")] + pub color: i32, + #[serde(default, rename = "LightSourceSettings")] + pub light_source_settings: Option, + #[serde(default, rename = "DetectorSettings")] + pub detector_settings: Option, + #[serde(default, rename = "FilterSetRef")] + pub filter_set_ref: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(default, rename = "LightPath")] + pub light_path: Option, +} +impl Channel { + pub fn default_pinhole_size_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_color() -> i32 { + 0 + } + pub fn default_excitation_wavelength_unit() -> UnitsLengthType { + UnitsLengthType::nm + } + pub fn default_emission_wavelength_unit() -> UnitsLengthType { + UnitsLengthType::nm + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ChannelAcquisitionModeType { + #[serde(rename = "WideField")] + WideField, + #[serde(rename = "LaserScanningConfocalMicroscopy")] + LaserScanningConfocalMicroscopy, + #[serde(rename = "SpinningDiskConfocal")] + SpinningDiskConfocal, + #[serde(rename = "SlitScanConfocal")] + SlitScanConfocal, + #[serde(rename = "MultiPhotonMicroscopy")] + MultiPhotonMicroscopy, + #[serde(rename = "StructuredIllumination")] + StructuredIllumination, + #[serde(rename = "SingleMoleculeImaging")] + SingleMoleculeImaging, + #[serde(rename = "TotalInternalReflection")] + TotalInternalReflection, + #[serde(rename = "FluorescenceLifetime")] + FluorescenceLifetime, + #[serde(rename = "SpectralImaging")] + SpectralImaging, + #[serde(rename = "FluorescenceCorrelationSpectroscopy")] + FluorescenceCorrelationSpectroscopy, + #[serde(rename = "NearFieldScanningOpticalMicroscopy")] + NearFieldScanningOpticalMicroscopy, + #[serde(rename = "SecondHarmonicGenerationImaging")] + SecondHarmonicGenerationImaging, + #[serde(rename = "PALM")] + Palm, + #[serde(rename = "STORM")] + Storm, + #[serde(rename = "STED")] + Sted, + #[serde(rename = "TIRF")] + Tirf, + #[serde(rename = "FSM")] + Fsm, + #[serde(rename = "LCM")] + Lcm, + #[serde(rename = "Other")] + Other, + #[serde(rename = "BrightField")] + BrightField, + #[serde(rename = "SweptFieldConfocal")] + SweptFieldConfocal, + #[serde(rename = "SPIM")] + Spim, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ChannelContrastMethodType { + #[serde(rename = "Brightfield")] + Brightfield, + #[serde(rename = "Phase")] + Phase, + #[serde(rename = "DIC")] + Dic, + #[serde(rename = "HoffmanModulation")] + HoffmanModulation, + #[serde(rename = "ObliqueIllumination")] + ObliqueIllumination, + #[serde(rename = "PolarizedLight")] + PolarizedLight, + #[serde(rename = "Darkfield")] + Darkfield, + #[serde(rename = "Fluorescence")] + Fluorescence, + #[serde(rename = "Other")] + Other, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ChannelIlluminationType { + #[serde(rename = "Transmitted")] + Transmitted, + #[serde(rename = "Epifluorescence")] + Epifluorescence, + #[serde(rename = "Oblique")] + Oblique, + #[serde(rename = "NonLinear")] + NonLinear, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CommentAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: String, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Dataset { + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ExperimenterRef")] + pub experimenter_ref: Option, + #[serde(default, rename = "ExperimenterGroupRef")] + pub experimenter_group_ref: Option, + #[serde(default, rename = "ImageRef")] + pub image_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Detector { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(default, rename = "@Gain")] + pub gain: Option, + #[serde(default, rename = "@Voltage")] + pub voltage: Option, + #[serde(default = "Detector::default_voltage_unit", rename = "@VoltageUnit")] + pub voltage_unit: UnitsElectricPotentialType, + #[serde(default, rename = "@Offset")] + pub offset: Option, + #[serde(default, rename = "@Zoom")] + pub zoom: Option, + #[serde(default, rename = "@AmplificationGain")] + pub amplification_gain: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Detector { + pub fn default_voltage_unit() -> UnitsElectricPotentialType { + UnitsElectricPotentialType::V + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DetectorSettings { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Offset")] + pub offset: Option, + #[serde(default, rename = "@Gain")] + pub gain: Option, + #[serde(default, rename = "@Voltage")] + pub voltage: Option, + #[serde( + default = "DetectorSettings::default_voltage_unit", + rename = "@VoltageUnit" + )] + pub voltage_unit: UnitsElectricPotentialType, + #[serde(default, rename = "@Zoom")] + pub zoom: Option, + #[serde(default, rename = "@ReadOutRate")] + pub read_out_rate: Option, + #[serde( + default = "DetectorSettings::default_read_out_rate_unit", + rename = "@ReadOutRateUnit" + )] + pub read_out_rate_unit: UnitsFrequencyType, + #[serde(default, rename = "@Binning")] + pub binning: Option, + #[serde(default, rename = "@Integration")] + pub integration: Option, +} +impl DetectorSettings { + pub fn default_voltage_unit() -> UnitsElectricPotentialType { + UnitsElectricPotentialType::V + } + pub fn default_read_out_rate_unit() -> UnitsFrequencyType { + UnitsFrequencyType::Hz + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum DetectorType { + #[serde(rename = "CCD")] + Ccd, + #[serde(rename = "IntensifiedCCD")] + IntensifiedCcd, + #[serde(rename = "AnalogVideo")] + AnalogVideo, + #[serde(rename = "PMT")] + Pmt, + #[serde(rename = "Photodiode")] + Photodiode, + #[serde(rename = "Spectroscopy")] + Spectroscopy, + #[serde(rename = "LifetimeImaging")] + LifetimeImaging, + #[serde(rename = "CorrelationSpectroscopy")] + CorrelationSpectroscopy, + #[serde(rename = "FTIR")] + Ftir, + #[serde(rename = "EMCCD")] + Emccd, + #[serde(rename = "APD")] + Apd, + #[serde(rename = "CMOS")] + Cmos, + #[serde(rename = "EBCCD")] + Ebccd, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Dichroic { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DoubleAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: f64, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Ellipse { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Ellipse::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Ellipse::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@X")] + pub x: f32, + #[serde(rename = "@Y")] + pub y: f32, + #[serde(rename = "@RadiusX")] + pub radius_x: f32, + #[serde(rename = "@RadiusY")] + pub radius_y: f32, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Ellipse { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Experiment { + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ExperimenterRef")] + pub experimenter_ref: Option, + #[serde(default, rename = "MicrobeamManipulation")] + pub microbeam_manipulation: Vec, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ExperimentItemType { + #[serde(rename = "FP")] + Fp, + #[serde(rename = "FRET")] + Fret, + #[serde(rename = "TimeLapse")] + TimeLapse, + #[serde(rename = "FourDPlus")] + FourDPlus, + #[serde(rename = "Screen")] + Screen, + #[serde(rename = "Immunocytochemistry")] + Immunocytochemistry, + #[serde(rename = "Immunofluorescence")] + Immunofluorescence, + #[serde(rename = "FISH")] + Fish, + #[serde(rename = "Electrophysiology")] + Electrophysiology, + #[serde(rename = "IonImaging")] + IonImaging, + #[serde(rename = "Colocalization")] + Colocalization, + #[serde(rename = "PGIDocumentation")] + PgiDocumentation, + #[serde(rename = "FluorescenceLifetime")] + FluorescenceLifetime, + #[serde(rename = "SpectralImaging")] + SpectralImaging, + #[serde(rename = "Photobleaching")] + Photobleaching, + #[serde(rename = "SPIM")] + Spim, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct ExperimentType(pub Vec); +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Experimenter { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@FirstName")] + pub first_name: Option, + #[serde(default, rename = "@MiddleName")] + pub middle_name: Option, + #[serde(default, rename = "@LastName")] + pub last_name: Option, + #[serde(default, rename = "@Email")] + pub email: Option, + #[serde(default, rename = "@Institution")] + pub institution: Option, + #[serde(default, rename = "@UserName")] + pub user_name: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ExperimenterGroup { + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ExperimenterRef")] + pub experimenter_ref: Vec, + #[serde(default, rename = "Leader")] + pub leader: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct External { + #[serde(rename = "@href")] + pub href: String, + #[serde(rename = "@SHA1")] + pub sha_1: String, + #[serde(default = "External::default_compression", rename = "@Compression")] + pub compression: BinDataCompressionType, +} +impl External { + pub fn default_compression() -> BinDataCompressionType { + BinDataCompressionType::None + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Filament { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde(default = "Filament::default_power_unit", rename = "@PowerUnit")] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Filament { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::W + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum FilamentType { + #[serde(rename = "Incandescent")] + Incandescent, + #[serde(rename = "Halogen")] + Halogen, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct FileAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "BinaryFile")] + pub binary_file: BinaryFile, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Filter { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "@FilterWheel")] + pub filter_wheel: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "TransmittanceRange")] + pub transmittance_range: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct FilterSet { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "ExcitationFilterRef")] + pub excitation_filter_ref: Vec, + #[serde(default, rename = "DichroicRef")] + pub dichroic_ref: Option, + #[serde(default, rename = "EmissionFilterRef")] + pub emission_filter_ref: Vec, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum FilterType { + #[serde(rename = "Dichroic")] + Dichroic, + #[serde(rename = "LongPass")] + LongPass, + #[serde(rename = "ShortPass")] + ShortPass, + #[serde(rename = "BandPass")] + BandPass, + #[serde(rename = "MultiPass")] + MultiPass, + #[serde(rename = "NeutralDensity")] + NeutralDensity, + #[serde(rename = "Tuneable")] + Tuneable, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Folder { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "FolderRef")] + pub folder_ref: Vec, + #[serde(default, rename = "ImageRef")] + pub image_ref: Vec, + #[serde(default, rename = "ROIRef")] + pub roi_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum FontFamilyType { + #[serde(rename = "serif")] + Serif, + #[serde(rename = "sans-serif")] + SansSerif, + #[serde(rename = "cursive")] + Cursive, + #[serde(rename = "fantasy")] + Fantasy, + #[serde(rename = "monospace")] + Monospace, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct GenericExcitationSource { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde( + default = "GenericExcitationSource::default_power_unit", + rename = "@PowerUnit" + )] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(default, rename = "Map")] + pub map: Option, +} +impl GenericExcitationSource { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::W + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Image { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "AcquisitionDate")] + pub acquisition_date: Option, + #[serde(default, rename = "ExperimenterRef")] + pub experimenter_ref: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ExperimentRef")] + pub experiment_ref: Option, + #[serde(default, rename = "ExperimenterGroupRef")] + pub experimenter_group_ref: Option, + #[serde(default, rename = "InstrumentRef")] + pub instrument_ref: Option, + #[serde(default, rename = "ObjectiveSettings")] + pub objective_settings: Option, + #[serde(default, rename = "ImagingEnvironment")] + pub imaging_environment: Option, + #[serde(default, rename = "StageLabel")] + pub stage_label: Option, + #[serde(rename = "Pixels")] + pub pixels: Pixels, + #[serde(default, rename = "ROIRef")] + pub roi_ref: Vec, + #[serde(default, rename = "MicrobeamManipulationRef")] + pub microbeam_manipulation_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ImagingEnvironment { + #[serde(default, rename = "@Temperature")] + pub temperature: Option, + #[serde( + default = "ImagingEnvironment::default_temperature_unit", + rename = "@TemperatureUnit" + )] + pub temperature_unit: UnitsTemperatureType, + #[serde(default, rename = "@AirPressure")] + pub air_pressure: Option, + #[serde( + default = "ImagingEnvironment::default_air_pressure_unit", + rename = "@AirPressureUnit" + )] + pub air_pressure_unit: UnitsPressureType, + #[serde(default, rename = "@Humidity")] + pub humidity: Option, + #[serde(default, rename = "@CO2Percent")] + pub co_2_percent: Option, + #[serde(default, rename = "Map")] + pub map: Option, +} +impl ImagingEnvironment { + pub fn default_temperature_unit() -> UnitsTemperatureType { + UnitsTemperatureType::C + } + pub fn default_air_pressure_unit() -> UnitsPressureType { + UnitsPressureType::atm + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Instrument { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "Microscope")] + pub microscope: Option, + #[serde(default, rename = "LightSourceGroup")] + pub light_source_group: Vec, + #[serde(default, rename = "Detector")] + pub detector: Vec, + #[serde(default, rename = "Objective")] + pub objective: Vec, + #[serde(default, rename = "FilterSet")] + pub filter_set: Vec, + #[serde(default, rename = "Filter")] + pub filter: Vec, + #[serde(default, rename = "Dichroic")] + pub dichroic: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Label { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Label::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Label::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@X")] + pub x: f32, + #[serde(rename = "@Y")] + pub y: f32, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Label { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Laser { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde(default = "Laser::default_power_unit", rename = "@PowerUnit")] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "@LaserMedium")] + pub laser_medium: Option, + #[serde(default, rename = "@Wavelength")] + pub wavelength: Option, + #[serde(default = "Laser::default_wavelength_unit", rename = "@WavelengthUnit")] + pub wavelength_unit: UnitsLengthType, + #[serde(default, rename = "@FrequencyMultiplication")] + pub frequency_multiplication: Option, + #[serde(default, rename = "@Tuneable")] + pub tuneable: Option, + #[serde(default, rename = "@Pulse")] + pub pulse: Option, + #[serde(default, rename = "@PockelCell")] + pub pockel_cell: Option, + #[serde(default, rename = "@RepetitionRate")] + pub repetition_rate: Option, + #[serde( + default = "Laser::default_repetition_rate_unit", + rename = "@RepetitionRateUnit" + )] + pub repetition_rate_unit: UnitsFrequencyType, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(default, rename = "Pump")] + pub pump: Option, +} +impl Laser { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::mW + } + pub fn default_wavelength_unit() -> UnitsLengthType { + UnitsLengthType::nm + } + pub fn default_repetition_rate_unit() -> UnitsFrequencyType { + UnitsFrequencyType::Hz + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum LaserLaserMediumType { + #[serde(rename = "Cu")] + Cu, + #[serde(rename = "Ag")] + Ag, + #[serde(rename = "ArFl")] + ArFl, + #[serde(rename = "ArCl")] + ArCl, + #[serde(rename = "KrFl")] + KrFl, + #[serde(rename = "KrCl")] + KrCl, + #[serde(rename = "XeFl")] + XeFl, + #[serde(rename = "XeCl")] + XeCl, + #[serde(rename = "XeBr")] + XeBr, + #[serde(rename = "N")] + N, + #[serde(rename = "Ar")] + Ar, + #[serde(rename = "Kr")] + Kr, + #[serde(rename = "Xe")] + Xe, + #[serde(rename = "HeNe")] + HeNe, + #[serde(rename = "HeCd")] + HeCd, + #[serde(rename = "CO")] + Co, + #[serde(rename = "CO2")] + Co2, + #[serde(rename = "H2O")] + H2O, + #[serde(rename = "HFl")] + Hfl, + #[serde(rename = "NdGlass")] + NdGlass, + #[serde(rename = "NdYAG")] + NdYag, + #[serde(rename = "ErGlass")] + ErGlass, + #[serde(rename = "ErYAG")] + ErYag, + #[serde(rename = "HoYLF")] + HoYlf, + #[serde(rename = "HoYAG")] + HoYag, + #[serde(rename = "Ruby")] + Ruby, + #[serde(rename = "TiSapphire")] + TiSapphire, + #[serde(rename = "Alexandrite")] + Alexandrite, + #[serde(rename = "Rhodamine6G")] + Rhodamine6G, + #[serde(rename = "CoumarinC30")] + CoumarinC30, + #[serde(rename = "GaAs")] + GaAs, + #[serde(rename = "GaAlAs")] + GaAlAs, + #[serde(rename = "EMinus")] + Eminus, + #[serde(rename = "Other")] + Other, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum LaserPulseType { + #[serde(rename = "CW")] + Cw, + #[serde(rename = "Single")] + Single, + #[serde(rename = "QSwitched")] + Qswitched, + #[serde(rename = "Repetitive")] + Repetitive, + #[serde(rename = "ModeLocked")] + ModeLocked, + #[serde(rename = "Other")] + Other, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum LaserType { + #[serde(rename = "Excimer")] + Excimer, + #[serde(rename = "Gas")] + Gas, + #[serde(rename = "MetalVapor")] + MetalVapor, + #[serde(rename = "SolidState")] + SolidState, + #[serde(rename = "Dye")] + Dye, + #[serde(rename = "Semiconductor")] + Semiconductor, + #[serde(rename = "FreeElectron")] + FreeElectron, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LightEmittingDiode { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde( + default = "LightEmittingDiode::default_power_unit", + rename = "@PowerUnit" + )] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl LightEmittingDiode { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::mW + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LightPath { + #[serde(default, rename = "ExcitationFilterRef")] + pub excitation_filter_ref: Vec, + #[serde(default, rename = "DichroicRef")] + pub dichroic_ref: Option, + #[serde(default, rename = "EmissionFilterRef")] + pub emission_filter_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LightSourceType { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Power")] + pub power: Option, + #[serde(default = "LightSourceType::default_power_unit", rename = "@PowerUnit")] + pub power_unit: UnitsPowerType, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl LightSourceType { + pub fn default_power_unit() -> UnitsPowerType { + UnitsPowerType::mW + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum LightSourceGroup { + #[serde(rename = "Laser")] + Laser(Laser), + #[serde(rename = "Arc")] + Arc(Arc), + #[serde(rename = "Filament")] + Filament(Filament), + #[serde(rename = "LightEmittingDiode")] + LightEmittingDiode(LightEmittingDiode), + #[serde(rename = "GenericExcitationSource")] + GenericExcitationSource(GenericExcitationSource), +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LightSourceSettings { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Attenuation")] + pub attenuation: Option, + #[serde(default, rename = "@Wavelength")] + pub wavelength: Option, + #[serde( + default = "LightSourceSettings::default_wavelength_unit", + rename = "@WavelengthUnit" + )] + pub wavelength_unit: UnitsLengthType, +} +impl LightSourceSettings { + pub fn default_wavelength_unit() -> UnitsLengthType { + UnitsLengthType::nm + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Line { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Line::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Line::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@X1")] + pub x1: f32, + #[serde(rename = "@Y1")] + pub y1: f32, + #[serde(rename = "@X2")] + pub x2: f32, + #[serde(rename = "@Y2")] + pub y2: f32, + #[serde(default, rename = "@MarkerStart")] + pub marker_start: Option, + #[serde(default, rename = "@MarkerEnd")] + pub marker_end: Option, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Line { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LongAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: i64, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MapType { + #[serde(default, rename = "M")] + pub m: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MapAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: MapType, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MapM { + #[serde(default, rename = "@K")] + pub k: Option, + #[serde(rename = "$text")] + pub content: String, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum MarkerType { + #[serde(rename = "Arrow")] + Arrow, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Mask { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Mask::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Mask::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@X")] + pub x: f32, + #[serde(rename = "@Y")] + pub y: f32, + #[serde(rename = "@Width")] + pub width: f32, + #[serde(rename = "@Height")] + pub height: f32, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "BinData")] + pub bin_data: BinData, +} +impl Mask { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MetadataOnly; +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MicrobeamManipulation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ROIRef")] + pub roi_ref: Vec, + #[serde(rename = "ExperimenterRef")] + pub experimenter_ref: AnnotationRef, + #[serde(default, rename = "LightSourceSettings")] + pub light_source_settings: Vec, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum MicrobeamManipulationItemType { + #[serde(rename = "FRAP")] + Frap, + #[serde(rename = "FLIP")] + Flip, + #[serde(rename = "InverseFRAP")] + InverseFrap, + #[serde(rename = "Photoablation")] + Photoablation, + #[serde(rename = "Photoactivation")] + Photoactivation, + #[serde(rename = "Uncaging")] + Uncaging, + #[serde(rename = "OpticalTrapping")] + OpticalTrapping, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct MicrobeamManipulationType(pub Vec); +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Microscope { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(default, rename = "@Type")] + pub r#type: Option, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum MicroscopeType { + #[serde(rename = "Upright")] + Upright, + #[serde(rename = "Inverted")] + Inverted, + #[serde(rename = "Dissection")] + Dissection, + #[serde(rename = "Electrophysiology")] + Electrophysiology, + #[serde(rename = "Other")] + Other, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum NamingConventionType { + #[serde(rename = "letter")] + Letter, + #[serde(rename = "number")] + Number, +} + +/// The root of the metadata, create this by parsing an XML string. +/// ``` +/// use ome_metadata::Ome; +/// +/// let xml = r#" +/// +/// 2025-01-29T14:42:42 +/// +/// +/// +/// +/// +/// +/// +/// +/// "#; +/// +/// let ome: Ome = xml.parse().unwrap(); +/// let image = &ome.image.unwrap()[0]; +/// println!("acquisition date: {:#?}", image.acquisition_date); +/// ``` +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Ome { + #[serde(default, rename = "@UUID")] + pub uuid: Option, + #[serde(default, rename = "@Creator")] + pub creator: Option, + #[serde(rename = "Rights")] + pub rights: Option, + #[serde(rename = "Project")] + pub project: Option>, + #[serde(rename = "Dataset")] + pub dataset: Option>, + #[serde(rename = "Folder")] + pub folder: Option>, + #[serde(rename = "Experiment")] + pub experiment: Option>, + #[serde(rename = "Plate")] + pub plate: Option>, + #[serde(rename = "Screen")] + pub screen: Option>, + #[serde(rename = "Experimenter")] + pub experimenter: Option>, + #[serde(rename = "ExperimenterGroup")] + pub experimenter_group: Option>, + #[serde(rename = "Instrument")] + pub instrument: Option>, + #[serde(rename = "Image")] + pub image: Option>, + #[serde(rename = "StructuredAnnotations")] + pub structured_annotations: Option, + #[serde(rename = "ROI")] + pub roi: Option>, + #[serde(rename = "BinaryOnly")] + pub binary_only: Option, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Objective { + #[serde(default, rename = "@Manufacturer")] + pub manufacturer: Option, + #[serde(default, rename = "@Model")] + pub model: Option, + #[serde(default, rename = "@SerialNumber")] + pub serial_number: Option, + #[serde(default, rename = "@LotNumber")] + pub lot_number: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Correction")] + pub correction: Option, + #[serde(default, rename = "@Immersion")] + pub immersion: Option, + #[serde(default, rename = "@LensNA")] + pub lens_na: Option, + #[serde(default, rename = "@NominalMagnification")] + pub nominal_magnification: Option, + #[serde(default, rename = "@CalibratedMagnification")] + pub calibrated_magnification: Option, + #[serde(default, rename = "@WorkingDistance")] + pub working_distance: Option, + #[serde( + default = "Objective::default_working_distance_unit", + rename = "@WorkingDistanceUnit" + )] + pub working_distance_unit: UnitsLengthType, + #[serde(default, rename = "@Iris")] + pub iris: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Objective { + pub fn default_working_distance_unit() -> UnitsLengthType { + UnitsLengthType::um + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ObjectiveCorrectionType { + #[serde(rename = "UV")] + Uv, + #[serde(rename = "PlanApo")] + PlanApo, + #[serde(rename = "PlanFluor")] + PlanFluor, + #[serde(rename = "SuperFluor")] + SuperFluor, + #[serde(rename = "VioletCorrected")] + VioletCorrected, + #[serde(rename = "Achro")] + Achro, + #[serde(rename = "Achromat")] + Achromat, + #[serde(rename = "Fluor")] + Fluor, + #[serde(rename = "Fl")] + Fl, + #[serde(rename = "Fluar")] + Fluar, + #[serde(rename = "Neofluar")] + Neofluar, + #[serde(rename = "Fluotar")] + Fluotar, + #[serde(rename = "Apo")] + Apo, + #[serde(rename = "PlanNeofluar")] + PlanNeofluar, + #[serde(rename = "Other")] + Other, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ObjectiveImmersionType { + #[serde(rename = "Oil")] + Oil, + #[serde(rename = "Water")] + Water, + #[serde(rename = "WaterDipping")] + WaterDipping, + #[serde(rename = "Air")] + Air, + #[serde(rename = "Multi")] + Multi, + #[serde(rename = "Glycerol")] + Glycerol, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ObjectiveSettings { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@CorrectionCollar")] + pub correction_collar: Option, + #[serde(default, rename = "@Medium")] + pub medium: Option, + #[serde(default, rename = "@RefractiveIndex")] + pub refractive_index: Option, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ObjectiveSettingsMediumType { + #[serde(rename = "Air")] + Air, + #[serde(rename = "Oil")] + Oil, + #[serde(rename = "Water")] + Water, + #[serde(rename = "Glycerol")] + Glycerol, + #[serde(rename = "Other")] + Other, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct OmeBinaryOnly { + #[serde(rename = "@MetadataFile")] + pub metadata_file: String, + #[serde(rename = "@UUID")] + pub uuid: String, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum PixelType { + #[serde(rename = "int8")] + Int8, + #[serde(rename = "int16")] + Int16, + #[serde(rename = "int32")] + Int32, + #[serde(rename = "uint8")] + Uint8, + #[serde(rename = "uint16")] + Uint16, + #[serde(rename = "uint32")] + Uint32, + #[serde(rename = "float")] + Float, + #[serde(rename = "double")] + Double, + #[serde(rename = "complex")] + Complex, + #[serde(rename = "double-complex")] + DoubleComplex, + #[serde(rename = "bit")] + Bit, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Pixels { + #[serde(rename = "@ID")] + pub id: String, + #[serde(rename = "@DimensionOrder")] + pub dimension_order: PixelsDimensionOrderType, + #[serde(rename = "@Type")] + pub r#type: PixelType, + #[serde(default, rename = "@SignificantBits")] + pub significant_bits: Option, + #[serde(default, rename = "@Interleaved")] + pub interleaved: Option, + #[serde(default, rename = "@BigEndian")] + pub big_endian: Option, + #[serde(rename = "@SizeX")] + pub size_x: i32, + #[serde(rename = "@SizeY")] + pub size_y: i32, + #[serde(rename = "@SizeZ")] + pub size_z: i32, + #[serde(rename = "@SizeC")] + pub size_c: i32, + #[serde(rename = "@SizeT")] + pub size_t: i32, + #[serde(default, rename = "@PhysicalSizeX")] + pub physical_size_x: Option, + #[serde( + default = "Pixels::default_physical_size_x_unit", + rename = "@PhysicalSizeXUnit" + )] + pub physical_size_x_unit: UnitsLengthType, + #[serde(default, rename = "@PhysicalSizeY")] + pub physical_size_y: Option, + #[serde( + default = "Pixels::default_physical_size_y_unit", + rename = "@PhysicalSizeYUnit" + )] + pub physical_size_y_unit: UnitsLengthType, + #[serde(default, rename = "@PhysicalSizeZ")] + pub physical_size_z: Option, + #[serde( + default = "Pixels::default_physical_size_z_unit", + rename = "@PhysicalSizeZUnit" + )] + pub physical_size_z_unit: UnitsLengthType, + #[serde(default, rename = "@TimeIncrement")] + pub time_increment: Option, + #[serde( + default = "Pixels::default_time_increment_unit", + rename = "@TimeIncrementUnit" + )] + pub time_increment_unit: UnitsTimeType, + #[serde(rename = "Channel")] + pub channel: Vec, + #[serde(rename = "BinData")] + pub bin_data: Option, + #[serde(rename = "TiffData")] + pub tiff_data: Option, + #[serde(rename = "MetadataOnly")] + pub metadata_only: Option, + #[serde(rename = "Plane")] + pub plane: Option>, +} +impl Pixels { + pub fn default_physical_size_x_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_physical_size_y_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_physical_size_z_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_time_increment_unit() -> UnitsTimeType { + UnitsTimeType::s + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum PixelsDimensionOrderType { + #[serde(rename = "XYZCT")] + Xyzct, + #[serde(rename = "XYZTC")] + Xyztc, + #[serde(rename = "XYCTZ")] + Xyctz, + #[serde(rename = "XYCZT")] + Xyczt, + #[serde(rename = "XYTCZ")] + Xytcz, + #[serde(rename = "XYTZC")] + Xytzc, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Plane { + #[serde(rename = "@TheZ")] + pub the_z: i32, + #[serde(rename = "@TheT")] + pub the_t: i32, + #[serde(rename = "@TheC")] + pub the_c: i32, + #[serde(default, rename = "@DeltaT")] + pub delta_t: Option, + #[serde(default = "Plane::default_delta_t_unit", rename = "@DeltaTUnit")] + pub delta_t_unit: UnitsTimeType, + #[serde(default, rename = "@ExposureTime")] + pub exposure_time: Option, + #[serde( + default = "Plane::default_exposure_time_unit", + rename = "@ExposureTimeUnit" + )] + pub exposure_time_unit: UnitsTimeType, + #[serde(default, rename = "@PositionX")] + pub position_x: Option, + #[serde(default = "Plane::default_position_x_unit", rename = "@PositionXUnit")] + pub position_x_unit: UnitsLengthType, + #[serde(default, rename = "@PositionY")] + pub position_y: Option, + #[serde(default = "Plane::default_position_y_unit", rename = "@PositionYUnit")] + pub position_y_unit: UnitsLengthType, + #[serde(default, rename = "@PositionZ")] + pub position_z: Option, + #[serde(default = "Plane::default_position_z_unit", rename = "@PositionZUnit")] + pub position_z_unit: UnitsLengthType, + #[serde(rename = "HashSHA1")] + pub hash_sha1: Option, + #[serde(rename = "AnnotationRef")] + pub annotation_ref: Option, +} +impl Plane { + pub fn default_delta_t_unit() -> UnitsTimeType { + UnitsTimeType::s + } + pub fn default_exposure_time_unit() -> UnitsTimeType { + UnitsTimeType::s + } + pub fn default_position_x_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_position_y_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_position_z_unit() -> UnitsLengthType { + UnitsLengthType::um + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Plate { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "@Status")] + pub status: Option, + #[serde(default, rename = "@ExternalIdentifier")] + pub external_identifier: Option, + #[serde(default, rename = "@ColumnNamingConvention")] + pub column_naming_convention: Option, + #[serde(default, rename = "@RowNamingConvention")] + pub row_naming_convention: Option, + #[serde(default, rename = "@WellOriginX")] + pub well_origin_x: Option, + #[serde( + default = "Plate::default_well_origin_x_unit", + rename = "@WellOriginXUnit" + )] + pub well_origin_x_unit: UnitsLengthType, + #[serde(default, rename = "@WellOriginY")] + pub well_origin_y: Option, + #[serde( + default = "Plate::default_well_origin_y_unit", + rename = "@WellOriginYUnit" + )] + pub well_origin_y_unit: UnitsLengthType, + #[serde(default, rename = "@Rows")] + pub rows: Option, + #[serde(default, rename = "@Columns")] + pub columns: Option, + #[serde(default, rename = "@FieldIndex")] + pub field_index: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "Well")] + pub well: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(default, rename = "PlateAcquisition")] + pub plate_acquisition: Vec, +} +impl Plate { + pub fn default_well_origin_x_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_well_origin_y_unit() -> UnitsLengthType { + UnitsLengthType::um + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct PlateAcquisition { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "@EndTime")] + pub end_time: Option, + #[serde(default, rename = "@StartTime")] + pub start_time: Option, + #[serde(default, rename = "@MaximumFieldCount")] + pub maximum_field_count: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "WellSampleRef")] + pub well_sample_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Polygon { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Polygon::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Polygon::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@Points")] + pub points: String, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Polygon { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Polyline { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Polyline::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde(default = "Polyline::default_font_size_unit", rename = "@FontSizeUnit")] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@Points")] + pub points: String, + #[serde(default, rename = "@MarkerStart")] + pub marker_start: Option, + #[serde(default, rename = "@MarkerEnd")] + pub marker_end: Option, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Polyline { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Project { + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "ExperimenterRef")] + pub experimenter_ref: Option, + #[serde(default, rename = "ExperimenterGroupRef")] + pub experimenter_group_ref: Option, + #[serde(default, rename = "DatasetRef")] + pub dataset_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Roi { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(rename = "Union")] + pub union: Option, + #[serde(rename = "AnnotationRef")] + pub annotation_ref: Option, + #[serde(rename = "Description")] + pub description: Option, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Reagent { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "@ReagentIdentifier")] + pub reagent_identifier: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Rectangle { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "Rectangle::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde( + default = "Rectangle::default_font_size_unit", + rename = "@FontSizeUnit" + )] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(rename = "@X")] + pub x: f32, + #[serde(rename = "@Y")] + pub y: f32, + #[serde(rename = "@Width")] + pub width: f32, + #[serde(rename = "@Height")] + pub height: f32, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Rectangle { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Rights { + #[serde(default, rename = "RightsHolder")] + pub rights_holder: Option, + #[serde(default, rename = "RightsHeld")] + pub rights_held: Option, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RoiUnion { + #[serde(default, rename = "ShapeGroup")] + pub shape_group: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Screen { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Name")] + pub name: Option, + #[serde(default, rename = "@ProtocolIdentifier")] + pub protocol_identifier: Option, + #[serde(default, rename = "@ProtocolDescription")] + pub protocol_description: Option, + #[serde(default, rename = "@ReagentSetDescription")] + pub reagent_set_description: Option, + #[serde(default, rename = "@ReagentSetIdentifier")] + pub reagent_set_identifier: Option, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "Reagent")] + pub reagent: Vec, + #[serde(default, rename = "PlateRef")] + pub plate_ref: Vec, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ShapeType { + #[serde(default, rename = "@FillColor")] + pub fill_color: Option, + #[serde(default, rename = "@FillRule")] + pub fill_rule: Option, + #[serde(default, rename = "@StrokeColor")] + pub stroke_color: Option, + #[serde(default, rename = "@StrokeWidth")] + pub stroke_width: Option, + #[serde( + default = "ShapeType::default_stroke_width_unit", + rename = "@StrokeWidthUnit" + )] + pub stroke_width_unit: UnitsLengthType, + #[serde(default, rename = "@StrokeDashArray")] + pub stroke_dash_array: Option, + #[serde(default, rename = "@Text")] + pub text: Option, + #[serde(default, rename = "@FontFamily")] + pub font_family: Option, + #[serde(default, rename = "@FontSize")] + pub font_size: Option, + #[serde( + default = "ShapeType::default_font_size_unit", + rename = "@FontSizeUnit" + )] + pub font_size_unit: UnitsLengthType, + #[serde(default, rename = "@FontStyle")] + pub font_style: Option, + #[serde(default, rename = "@Locked")] + pub locked: Option, + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@TheZ")] + pub the_z: Option, + #[serde(default, rename = "@TheT")] + pub the_t: Option, + #[serde(default, rename = "@TheC")] + pub the_c: Option, + #[serde(default, rename = "Transform")] + pub transform: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl ShapeType { + pub fn default_stroke_width_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } + pub fn default_font_size_unit() -> UnitsLengthType { + UnitsLengthType::Pixel + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ShapeFillRuleType { + #[serde(rename = "EvenOdd")] + EvenOdd, + #[serde(rename = "NonZero")] + NonZero, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ShapeFontStyleType { + #[serde(rename = "Bold")] + Bold, + #[serde(rename = "BoldItalic")] + BoldItalic, + #[serde(rename = "Italic")] + Italic, + #[serde(rename = "Normal")] + Normal, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ShapeGroup { + #[serde(rename = "Rectangle")] + Rectangle(Rectangle), + #[serde(rename = "Mask")] + Mask(Mask), + #[serde(rename = "Point")] + Point(Label), + #[serde(rename = "Ellipse")] + Ellipse(Ellipse), + #[serde(rename = "Line")] + Line(Line), + #[serde(rename = "Polyline")] + Polyline(Polyline), + #[serde(rename = "Polygon")] + Polygon(Polygon), + #[serde(rename = "Label")] + Label(Label), +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct StageLabel { + #[serde(rename = "@Name")] + pub name: String, + #[serde(default, rename = "@X")] + pub x: Option, + #[serde(default = "StageLabel::default_x_unit", rename = "@XUnit")] + pub x_unit: UnitsLengthType, + #[serde(default, rename = "@Y")] + pub y: Option, + #[serde(default = "StageLabel::default_y_unit", rename = "@YUnit")] + pub y_unit: UnitsLengthType, + #[serde(default, rename = "@Z")] + pub z: Option, + #[serde(default = "StageLabel::default_z_unit", rename = "@ZUnit")] + pub z_unit: UnitsLengthType, +} +impl StageLabel { + pub fn default_x_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_y_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_z_unit() -> UnitsLengthType { + UnitsLengthType::um + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct StructuredAnnotations { + #[serde(default, rename = "$value")] + pub content: Option, +} +#[allow(clippy::enum_variant_names)] +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum StructuredAnnotationsContent { + #[serde(rename = "XMLAnnotation")] + XmlAnnotation(XmlAnnotation), + #[serde(rename = "FileAnnotation")] + FileAnnotation(FileAnnotation), + #[serde(rename = "ListAnnotation")] + ListAnnotation(Annotation), + #[serde(rename = "LongAnnotation")] + LongAnnotation(LongAnnotation), + #[serde(rename = "DoubleAnnotation")] + DoubleAnnotation(DoubleAnnotation), + #[serde(rename = "CommentAnnotation")] + CommentAnnotation(CommentAnnotation), + #[serde(rename = "BooleanAnnotation")] + BooleanAnnotation(BooleanAnnotation), + #[serde(rename = "TimestampAnnotation")] + TimestampAnnotation(CommentAnnotation), + #[serde(rename = "TagAnnotation")] + TagAnnotation(CommentAnnotation), + #[serde(rename = "TermAnnotation")] + TermAnnotation(CommentAnnotation), + #[serde(rename = "MapAnnotation")] + MapAnnotation(MapAnnotation), +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct TiffData { + #[serde(default = "TiffData::default_ifd", rename = "@IFD")] + pub ifd: i32, + #[serde(default = "TiffData::default_first_z", rename = "@FirstZ")] + pub first_z: i32, + #[serde(default = "TiffData::default_first_t", rename = "@FirstT")] + pub first_t: i32, + #[serde(default = "TiffData::default_first_c", rename = "@FirstC")] + pub first_c: i32, + #[serde(default, rename = "@PlaneCount")] + pub plane_count: Option, + #[serde(default, rename = "UUID")] + pub uuid: Option, +} +impl TiffData { + pub fn default_ifd() -> i32 { + 0 + } + pub fn default_first_z() -> i32 { + 0 + } + pub fn default_first_t() -> i32 { + 0 + } + pub fn default_first_c() -> i32 { + 0 + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct TiffDataUuid { + #[serde(default, rename = "@FileName")] + pub file_name: Option, + #[serde(rename = "$text")] + pub content: String, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct TransmittanceRange { + #[serde(default, rename = "@CutIn")] + pub cut_in: Option, + #[serde( + default = "TransmittanceRange::default_cut_in_unit", + rename = "@CutInUnit" + )] + pub cut_in_unit: UnitsLengthType, + #[serde(default, rename = "@CutOut")] + pub cut_out: Option, + #[serde( + default = "TransmittanceRange::default_cut_out_unit", + rename = "@CutOutUnit" + )] + pub cut_out_unit: UnitsLengthType, + #[serde(default, rename = "@CutInTolerance")] + pub cut_in_tolerance: Option, + #[serde( + default = "TransmittanceRange::default_cut_in_tolerance_unit", + rename = "@CutInToleranceUnit" + )] + pub cut_in_tolerance_unit: UnitsLengthType, + #[serde(default, rename = "@CutOutTolerance")] + pub cut_out_tolerance: Option, + #[serde( + default = "TransmittanceRange::default_cut_out_tolerance_unit", + rename = "@CutOutToleranceUnit" + )] + pub cut_out_tolerance_unit: UnitsLengthType, + #[serde(default, rename = "@Transmittance")] + pub transmittance: Option, +} +impl TransmittanceRange { + pub fn default_cut_in_unit() -> UnitsLengthType { + UnitsLengthType::m + } + pub fn default_cut_out_unit() -> UnitsLengthType { + UnitsLengthType::m + } + pub fn default_cut_in_tolerance_unit() -> UnitsLengthType { + UnitsLengthType::m + } + pub fn default_cut_out_tolerance_unit() -> UnitsLengthType { + UnitsLengthType::m + } +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsElectricPotentialType { + YV, + ZV, + EV, + PV, + TV, + GV, + MV, + kV, + hV, + daV, + V, + dV, + cV, + mV, + #[serde(rename = "µV")] + uV, + nV, + pV, + fV, + aV, + zV, + yV, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsFrequencyType { + YHz, + ZHz, + EHz, + PHz, + THz, + GHz, + MHz, + kHz, + hHz, + daHz, + Hz, + dHz, + cHz, + mHz, + #[serde(rename = "µHz")] + uHz, + nHz, + pHz, + fHz, + aHz, + zHz, + yHz, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsLengthType { + Ym, + Zm, + Em, + Pm, + Tm, + Gm, + Mm, + km, + hm, + dam, + m, + dm, + cm, + mm, + #[serde(rename = "µm")] + um, + nm, + pm, + fm, + am, + zm, + ym, + #[serde(rename = "Å")] + A, + #[serde(rename = "thou")] + Thou, + #[serde(rename = "li")] + Li, + #[serde(rename = "in")] + In, + #[serde(rename = "ft")] + Ft, + #[serde(rename = "yd")] + Yd, + #[serde(rename = "mi")] + Mi, + #[serde(rename = "ua")] + Ua, + #[serde(rename = "ly")] + Ly, + #[serde(rename = "pc")] + Pc, + #[serde(rename = "pt")] + Pt, + #[serde(rename = "pixel")] + Pixel, + #[serde(rename = "reference frame")] + ReferenceFrame, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsPowerType { + YW, + ZW, + EW, + PW, + TW, + GW, + MW, + kW, + hW, + daW, + W, + dW, + cW, + mW, + #[serde(rename = "µW")] + uW, + nW, + pW, + fW, + aW, + zW, + yW, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsPressureType { + YPa, + ZPa, + EPa, + PPa, + TPa, + GPa, + MPa, + kPa, + hPa, + daPa, + Pa, + dPa, + cPa, + mPa, + #[serde(rename = "µPa")] + uPa, + nPa, + pPa, + fPa, + aPa, + zPa, + yPa, + bar, + Mbar, + kbar, + dbar, + cbar, + mbar, + atm, + psi, + Torr, + mTorr, + #[serde(rename = "mm Hg")] + mmHg, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsTemperatureType { + #[serde(rename = "°C")] + C, + #[serde(rename = "°F")] + F, + #[serde(rename = "K")] + K, + #[serde(rename = "°R")] + R, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum UnitsTimeType { + Ys, + Zs, + Es, + Ps, + Ts, + Gs, + Ms, + ks, + hs, + das, + s, + ds, + cs, + ms, + #[serde(rename = "µs")] + us, + ns, + ps, + fs, + r#as, + zs, + ys, + min, + h, + d, +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Well { + #[serde(rename = "@ID")] + pub id: String, + #[serde(rename = "@Column")] + pub column: i32, + #[serde(rename = "@Row")] + pub row: i32, + #[serde(default, rename = "@ExternalDescription")] + pub external_description: Option, + #[serde(default, rename = "@ExternalIdentifier")] + pub external_identifier: Option, + #[serde(default, rename = "@Type")] + pub r#type: Option, + #[serde(default = "Well::default_color", rename = "@Color")] + pub color: i32, + #[serde(default, rename = "WellSample")] + pub well_sample: Vec, + #[serde(default, rename = "ReagentRef")] + pub reagent_ref: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, +} +impl Well { + pub fn default_color() -> i32 { + 0 + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WellSample { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@PositionX")] + pub position_x: Option, + #[serde( + default = "WellSample::default_position_x_unit", + rename = "@PositionXUnit" + )] + pub position_x_unit: UnitsLengthType, + #[serde(default, rename = "@PositionY")] + pub position_y: Option, + #[serde( + default = "WellSample::default_position_y_unit", + rename = "@PositionYUnit" + )] + pub position_y_unit: UnitsLengthType, + #[serde(default, rename = "@Timepoint")] + pub timepoint: Option, + #[serde(rename = "@Index")] + pub index: i32, + #[serde(default, rename = "ImageRef")] + pub image_ref: Option, +} +impl WellSample { + pub fn default_position_x_unit() -> UnitsLengthType { + UnitsLengthType::um + } + pub fn default_position_y_unit() -> UnitsLengthType { + UnitsLengthType::um + } +} +#[cfg_attr(feature = "python", derive(IntoPyObject))] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct XmlAnnotation { + #[serde(rename = "@ID")] + pub id: String, + #[serde(default, rename = "@Namespace")] + pub namespace: Option, + #[serde(default, rename = "@Annotator")] + pub annotator: Option, + #[serde(default, rename = "Description")] + pub description: Option, + #[serde(default, rename = "AnnotationRef")] + pub annotation_ref: Vec, + #[serde(rename = "Value")] + pub value: XmlAnnotationValue, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct XmlAnnotationValue; diff --git a/src/py.rs b/src/py.rs new file mode 100644 index 0000000..6fbd65d --- /dev/null +++ b/src/py.rs @@ -0,0 +1,13 @@ +use crate::Ome; +use pyo3::prelude::*; + +#[pymodule] +#[pyo3(name = "ome_metadata_rs")] +fn ome_metadata_rs(m: &Bound<'_, PyModule>) -> PyResult<()> { + #[pyfn(m)] + fn ome(text: &str) -> PyResult { + Ok(text.parse()?) + } + + Ok(()) +} diff --git a/tests/1xp53-01-AP1.xml b/tests/1xp53-01-AP1.xml new file mode 100644 index 0000000..9bc7239 --- /dev/null +++ b/tests/1xp53-01-AP1.xml @@ -0,0 +1,416 @@ + + + + + + + + + + + + + 2023-12-20T09:44:49.746 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/20230511-p53-4x-CMV-1min-4h-01-Airyscan Processing-01.xml b/tests/20230511-p53-4x-CMV-1min-4h-01-Airyscan Processing-01.xml new file mode 100644 index 0000000..c2c6a07 --- /dev/null +++ b/tests/20230511-p53-4x-CMV-1min-4h-01-Airyscan Processing-01.xml @@ -0,0 +1,14468 @@ + + + + + + + + + + + + + 2023-05-11T15:04:26.646 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-11T15:04:26.646 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-11T15:04:26.646 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-11T15:04:26.646 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/4-Pos_001_002.xml b/tests/4-Pos_001_002.xml new file mode 100644 index 0000000..9c92a4f --- /dev/null +++ b/tests/4-Pos_001_002.xml @@ -0,0 +1,88 @@ + + + + + + OT/DAPI_filter/DAPI 20% 25 ms/Cy3_filter/Cy3 100% 250 ms/Cy5_filter/Cy5 100% 250ms/40x optovar 1.25/ Z -3 to 3/OD0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Experiment-2029.xml b/tests/Experiment-2029.xml new file mode 100644 index 0000000..aaada63 --- /dev/null +++ b/tests/Experiment-2029.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-11-27T13:35:29.360 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/MK022_cE9_1-01-Airyscan Processing-01-Scene-2-P1.xml b/tests/MK022_cE9_1-01-Airyscan Processing-01-Scene-2-P1.xml new file mode 100644 index 0000000..07da9c4 --- /dev/null +++ b/tests/MK022_cE9_1-01-Airyscan Processing-01-Scene-2-P1.xml @@ -0,0 +1,3176 @@ + + + + + + + + + + + + + 2022-07-26T08:44:34.565 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/YTL1841B2-2-1_1hr_DMSO_galinduction_1.xml b/tests/YTL1841B2-2-1_1hr_DMSO_galinduction_1.xml new file mode 100644 index 0000000..29dd2c4 --- /dev/null +++ b/tests/YTL1841B2-2-1_1hr_DMSO_galinduction_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/YTL1849A111_2023_05_04__14_46_19_cellnr_1_track.xml b/tests/YTL1849A111_2023_05_04__14_46_19_cellnr_1_track.xml new file mode 100644 index 0000000..e2e7e21 --- /dev/null +++ b/tests/YTL1849A111_2023_05_04__14_46_19_cellnr_1_track.xml @@ -0,0 +1,21 @@ + + + 2023-05-10T21:20:56 + + + + + + + + + + + + + + + + + + diff --git a/tests/YTL1849A131_2023_05_04__13_36_36.xml b/tests/YTL1849A131_2023_05_04__13_36_36.xml new file mode 100644 index 0000000..8ac99e6 --- /dev/null +++ b/tests/YTL1849A131_2023_05_04__13_36_36.xml @@ -0,0 +1,1499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Annotation + + diff --git a/tests/YTL378_JF552.xml b/tests/YTL378_JF552.xml new file mode 100644 index 0000000..6df81aa --- /dev/null +++ b/tests/YTL378_JF552.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 2018-10-09T13:14:54 + + + + + + + + + + + + + + + + + + + + 2018-10-09T13:53:56 + + + + + + + + + + + + + + + + + + + + 2018-10-09T13:54:44 + + + + + + + + + + + + + + + + + + + + 2018-10-09T13:55:44 + + + + + + + + + + + + + + + + + + + diff --git a/tests/beads_2023_05_04__19_00_22.xml b/tests/beads_2023_05_04__19_00_22.xml new file mode 100644 index 0000000..8303737 --- /dev/null +++ b/tests/beads_2023_05_04__19_00_22.xml @@ -0,0 +1,652 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test.xml b/tests/test.xml new file mode 100644 index 0000000..78c618e --- /dev/null +++ b/tests/test.xml @@ -0,0 +1,12 @@ + + + 2025-01-29T14:42:42 + + + + + + + + +