Import a MicroMetaApp Configuration¶
MicroMetaApp describes a microscope visually and saves the result as JSON. The library reads that file directly, so a complete Instrument is obtained without a single accessor call.
Overview¶
| Method | Description |
|---|---|
fromMicroMetaAppJsonFile(path) |
Fills the instrument from a MicroMetaApp JSON configuration |
fromJsonFile(path) |
Fills the element from a JSON file written by the library itself |
fromJsonString(json) |
Fills the element from a JSON string written by the library itself |
The import maps every MicroMetaApp component to its NBO counterpart — stand, objectives, detectors, light sources, filters, and the settings attached to them. A missing or unreadable file raises InscoperNBOException.
The mapping is checked against a published dataset of real microscope configurations. For every instrument in that dataset, Inscoper maintains a manually reviewed ground-truth NBO-XML document; the test suite imports the JSON, re-exports it as XML, and requires an exact match, in all three languages.
This is the shortest path to a compliant instrument description: describe the microscope once in MicroMetaApp, and generate the metadata from it for every acquisition afterwards.
Note
This example reads a MicroMetaApp configuration of a Nikon Ti2. Download it below to run the example as it is, or point MMA_JSON_PATH at your own configuration.
Import and inspect a configuration¶
MMA_JSON_PATH = "micrometaapp_nikon_ti2.json"
# Step 1: Import the configuration
# fromMicroMetaAppJsonFile() parses the JSON produced by MicroMetaApp, maps every
# component to its NBO counterpart, and fills the instrument in a single call.
instrument = inscoper_nbo.Instrument()
instrument.fromMicroMetaAppJsonFile(MMA_JSON_PATH)
# A missing or unreadable file raises InscoperNBOException
try:
inscoper_nbo.Instrument().fromMicroMetaAppJsonFile("does_not_exist.json")
except inscoper_nbo.InscoperNBOException as error:
print(f"Import failed: {error}")
# Step 2: Inspect what the import produced
print(f"Instrument: {instrument.getID().get()}")
for stand in instrument.getMicroscopeStandGroup_List():
print(f"Stand: {stand.getXMLName()} {stand.getManufacturer()} {stand.getModel()}")
for objective in instrument.getObjective_List():
print(f"Objective: {objective.getModel()} - {objective.getMagnification()}x")
for detector in instrument.getDetectorGroup_List():
print(f"Detector: {detector.getXMLName()} {detector.getModel()}")
for light_source in instrument.getLightSourceGroup_List():
print(f"Light source: {light_source.getXMLName()} {light_source.getModel()}")
# Step 3: Export the imported instrument as NBO-XML
# Pass False to write exactly what the import produced, without validating the
# document and without filling in schema default values.
output_path = os.path.join(tempfile.gettempdir(), "instrument_from_mma.xml")
instrument.toXmlFile(output_path, False)
print(f"NBO-XML written to {output_path}")
const std::string MMA_JSON_PATH = "micrometaapp_nikon_ti2.json";
int main() {
// Step 1: Import the configuration
// fromMicroMetaAppJsonFile() parses the JSON produced by MicroMetaApp, maps every
// component to its NBO counterpart, and fills the instrument in a single call.
NBO::Instrument instrument;
instrument.fromMicroMetaAppJsonFile(MMA_JSON_PATH);
// A missing or unreadable file throws InscoperNBOException
try {
NBO::Instrument missing;
missing.fromMicroMetaAppJsonFile("does_not_exist.json");
} catch (const NBO::InscoperNBOException &error) {
std::cout << "Import failed: " << error.what() << std::endl;
}
// Step 2: Inspect what the import produced
std::cout << "Instrument: " << instrument.getID()->get() << std::endl;
for (const auto &stand : instrument.getMicroscopeStandGroup_List()) {
std::cout << "Stand: " << stand->getXMLName() << " " << stand->getManufacturer() << " "
<< stand->getModel() << std::endl;
}
for (const auto &objective : instrument.getObjective_List()) {
std::cout << "Objective: " << objective->getModel() << " - "
<< objective->getMagnification() << "x" << std::endl;
}
for (const auto &detector : instrument.getDetectorGroup_List()) {
std::cout << "Detector: " << detector->getXMLName() << " " << detector->getModel()
<< std::endl;
}
for (const auto &lightSource : instrument.getLightSourceGroup_List()) {
std::cout << "Light source: " << lightSource->getXMLName() << " "
<< lightSource->getModel() << std::endl;
}
// Step 3: Export the imported instrument as NBO-XML
// Pass false to write exactly what the import produced, without validating the
// document and without filling in schema default values.
std::filesystem::path outputPath =
std::filesystem::temp_directory_path() / "instrument_from_mma.xml";
instrument.toXmlFile(outputPath.string(), false);
std::cout << "NBO-XML written to " << outputPath.string() << std::endl;
return 0;
}
static final String MMA_JSON_PATH = "micrometaapp_nikon_ti2.json";
public static void main(String[] args) {
// Step 1: Import the configuration
// fromMicroMetaAppJsonFile() parses the JSON produced by MicroMetaApp, maps
// every component to its NBO counterpart, and fills the instrument in one call.
Instrument instrument = new Instrument();
instrument.fromMicroMetaAppJsonFile(MMA_JSON_PATH);
// A missing or unreadable file throws InscoperNBOException. The generated
// method carries no throws clause, so catch Exception and read its message.
try {
new Instrument().fromMicroMetaAppJsonFile("does_not_exist.json");
} catch (Exception error) {
System.out.println("Import failed: " + error.getMessage());
}
// Step 2: Inspect what the import produced
System.out.println("Instrument: " + instrument.getID().get());
for (var stand : instrument.getMicroscopeStandGroup_List()) {
System.out.println("Stand: " + stand.getXMLName() + " " + stand.getManufacturer() + " "
+ stand.getModel());
}
for (Objective objective : instrument.getObjective_List()) {
System.out.println(
"Objective: " + objective.getModel() + " - " + objective.getMagnification() + "x");
}
for (var detector : instrument.getDetectorGroup_List()) {
System.out.println("Detector: " + detector.getXMLName() + " " + detector.getModel());
}
for (var lightSource : instrument.getLightSourceGroup_List()) {
System.out.println(
"Light source: " + lightSource.getXMLName() + " " + lightSource.getModel());
}
// Step 3: Export the imported instrument as NBO-XML
// Pass false to write exactly what the import produced, without validating the
// document and without filling in schema default values.
Path outputPath = Paths.get(System.getProperty("java.io.tmpdir"), "instrument_from_mma.xml");
instrument.toXmlFile(outputPath.toString(), false);
System.out.println("NBO-XML written to " + outputPath);
}
Next steps
The imported instrument is an ordinary NBO object. Extend it with values MicroMetaApp does not cover, using the accessors of Describe an Instrument, then reference its identifiers from the image metadata of Describe an Acquired Image.