Inscoper NBO Library Documentation
The Inscoper NBO Library provides a comprehensive, type-safe data model for microscopy metadata, automatically generated from the NBO (4DN-BINA-OME) XSD schema. It offers a unified API across C++, Python, and Java, enabling developers to build applications that meet the rigorous traceability and reproducibility standards increasingly required by scientific publishers [1][2][3][4].
Overview
This library is designed to facilitate the adoption of the 4DN-BINA-OME specification, which extends the classic OME-XML model to provide enhanced descriptions of imaging techniques and production variability. By mapping the XSD schema directly to object-oriented classes, the library acts as a bridge between complex metadata specifications and practical software implementation.
Key Capabilities
- Unified Data Model: Provides a consistent object model across multiple languages (C++, Python, Java).
- Standards Compliance: Ensures metadata adheres to modern quality control requirements.
- MicroMetaApp Integration: Features direct import capabilities for MicroMetaApp configurations, instantly converting visual microscope setups into valid NBO Instrument objects.
The NBO Model
The NBO (4DN Nucleome BINA OME) model represents a significant evolution of the OME Data Model, developed jointly by the 4D Nucleome (4DN) Imaging Standards Working Group and the Bioimaging North America (BINA) Quality Control and Data Management Working Group.
It is engineered to capture granular details regarding: * Instrument Hardware: Precise definitions of microscopes, detectors, light sources, objectives, and filters. * Acquisition Settings: Exact parameters such as exposure times, laser power, and channel configurations. * Experimental Context: Comprehensive tracking of sample preparation, reagents, and distinct experimental runs.
The library maps this XML schema directly into object-oriented classes, preserving the hierarchy and relationships defined in the XSD.
Code Generation
This library is auto-generated from the official nbo.xsd schema file using a custom generator script (xsd2cpp.py).
How it Works
- Parser: The script analyzes the XSD file, identifying all complex types, simple types, and element definitions.
- Mapping: It maps XSD types to C++ equivalents (e.g.,
#!xml xsd:string$\rightarrow$#!cpp std::string,#!xml xsd:float$\rightarrow$#!cpp float). - Generation:
- C++ Classes: creation of header (
.h) and implementation (.cpp) files for every entity in the schema. - SWIG Interfaces: creation of
.iinterface files to establish bindings for Python and Java.
- C++ Classes: creation of header (
This approach guarantees that the code remains perfectly synchronized with the schema definition.
Adaptations & Design
While the library faithfully adheres to the XSD structure, several strategic adaptations ensure the generated C++ code is modern, robust, and intuitive to use.
1. Modern C++ Standards
The generated code utilizes modern C++ (C++17/20) features:
* Standard Types: XSD primitives are mapped to standard C++ types (#!cpp std::string, #!cpp int, #!cpp double, #!cpp bool, #!cpp long long).
* Smart Pointers: All complex objects are managed via #!cpp std::shared_ptr. You rarely need to manage memory manually.
* Example: #!cpp Inscoper::NBO::InstrumentPtr is an alias for #!cpp std::shared_ptr<Inscoper::NBO::Instrument>.
* Optionals: Optional XSD attributes and elements are wrapped in #!cpp std::optional<>, allowing you to check for their existence explicitly.
* Vectors: Repeated elements (#!xml maxOccurs="unbounded") are stored in #!cpp std::vector<>.
2. Handling 'Choice' Elements
XSD <choice> elements, where a field can be one of several types, are implemented using #!cpp std::variant.
* Type Safety: The library ensures you can only assign valid types to a choice field.
* Utility Methods: Helper methods like #!cpp is<Type>(), #!cpp as<Type>(), and #!cpp set<Type>() are generated to simplify interacting with variants without writing complex visitors.
3. Serialization
The library includes built-in support for serializing and deserializing data:
* XML: Full support for reading/writing OME-XML (via pugixml).
4. Code Stability & Compilation Speed
The library employs the Pimpl (Pointer to Implementation) Idiom: * Encapsulation: Private members are hidden from the public header files. * ABI Stability: Changes to the internal implementation do not affect the binary interface (ABI). * Faster Compilation: Reducing dependencies in header files speeds up the build process for consumer applications.
5. MicroMetaApp Import
The library includes a powerful feature to initialize an Instrument directly from a MicroMetaApp configuration file.
- Concept: MicroMetaApp (MMA) allows users to visually configure their microscope hardware. This library can read the resulting JSON configuration and automatically populate the corresponding NBO Instrument object.
- Mechanism: The
#!cpp fromMicroMetaAppJsonFile()method parses the JSON, maps MMA components to NBO elements, and fills in all available metadata (detectors, objectives, etc.) in compliance with the generated schema. - Usage: This turns a potentially complex manual setup into a single function call, ensuring that your metadata model matches the physical instrument configuration defined in MMA.
- Validation: This feature is rigorously unit-tested across all three languages using a dataset of real-world microscope configurations. For every microscope in the dataset, we have created a manually verified "ground truth" XML. The tests automatically import the JSON configuration, re-export it as XML, and confirm that the result matches the ground truth exactly.
Multi-Language Support
Through SWIG (Simplified Wrapper and Interface Generator), the native C++ library is wrapped for high-level languages.
Python
- Installation:
#!bash pip install inscoper_nbo(see specific version) - Usage: The Python bindings feel 'pythonic'. You can iterate over lists, access properties as attributes, and use standard Python types.
- Dependencies: Requires the matching C++ shared libraries to be present or packaged (wheels accommodate this).
Java
- Usage: Java classes mirror the C++ hierarchy.
- Memory Management: The underlying C++ memory is managed automatically, but standard Java garbage collection rules apply to the wrappers.
Installation
C++
Work in progress
Java
Work in progress
Python
Future Work
OME Compliance / Backwards Compatibility
Currently, the library focuses on the full NBO extension model, which offers richer metadata than the standard OME model. We are actively working on a feature to export these model objects as standard, OME-compliant XML. This will ensure full backwards compatibility with legacy OME tools and viewers that do not yet support the NBO extensions.