Skip to content

Identify and Create Elements by Type

Every generated class carries a type identifier from the ENBOType enumeration. That identifier is what generic code works with: it identifies an element, travels outside Python, and creates elements on demand.

Overview

ENBOType has one member per element of the schema, in three interchangeable representations.

Representation Example Obtained with
Enumeration member ENBOType.CMOS element.getNBOType()
Schema name "CMOS" NBOUtils.NBOTypeToString(), NBOUtils.stringToNBOType()
Numeric value 0x0079B13B NBOUtils.NBOTypeToValue(), NBOUtils.valueToNBOType()

The numeric value is the form used outside Python: the Inscoper firmware and the Inscoper API exchange it when they refer to an NBO element, so it is the representation to store or transmit.

Unrecognized names and values resolve to ENBOType.UNKNOWN instead of raising, so a document produced by a newer schema can be inspected without stopping at the first unfamiliar element.

NBOUtils.createElementFromType() turns a type value back into an object. It returns the element through its base class, and the concrete class casts it back with a static fromBase(). That pair is what a deserializer or a dispatcher needs, instead of a table of constructors.

Note

createElementFromType() returns None for ENBOType.UNKNOWN, and fromBase() returns None on a type mismatch. Neither raises, so check the result before use.

Identify, convert, and instantiate

import inscoper_nbo

# ── Step 1: Every element reports its own type
instrument = inscoper_nbo.Instrument()
print(instrument.getNBOType() == inscoper_nbo.ENBOType.INSTRUMENT)

camera = inscoper_nbo.CMOS()
print(camera.getNBOType() == inscoper_nbo.ENBOType.CMOS)

# Enumeration values print as their schema name
print(str(inscoper_nbo.ENBOType.CMOS))

# ── Step 2: Convert between names, numeric values, and enumeration members
print(inscoper_nbo.NBOUtils.stringToNBOType("CMOS") == inscoper_nbo.ENBOType.CMOS)
print(inscoper_nbo.NBOUtils.NBOTypeToString(inscoper_nbo.ENBOType.CMOS))

# The numeric value is the identifier shared with the firmware and the API
value = inscoper_nbo.NBOUtils.NBOTypeToValue(inscoper_nbo.ENBOType.PLATE_ID_TYPE)
print(hex(value))
print(inscoper_nbo.NBOUtils.valueToNBOType(value) == inscoper_nbo.ENBOType.PLATE_ID_TYPE)

# Unknown names and unknown values resolve to UNKNOWN instead of raising
print(inscoper_nbo.NBOUtils.stringToNBOType("NoSuchElement") == inscoper_nbo.ENBOType.UNKNOWN)

# ── Step 3: Create an element from a type value
# createElementFromType() returns the element as its base class. Cast it to the
# concrete class with fromBase() to reach the type-specific accessors.
base = inscoper_nbo.NBOUtils.createElementFromType(inscoper_nbo.ENBOType.CMOS)
print(base.getXMLName(), base.getTypeName())

cmos = inscoper_nbo.CMOS.fromBase(base)
cmos.setPixelWidth(6.5)
print(cmos.getPixelWidth())

# A cast to the wrong class returns None rather than raising
print(inscoper_nbo.Instrument.fromBase(base) is None)

# An unknown type produces no element at all
print(inscoper_nbo.NBOUtils.createElementFromType(inscoper_nbo.ENBOType.UNKNOWN) is None)

#include <NBO/NBO/CMOS.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBO/Instrument.h>
#include <NBO/NBO/NBOUtils.h>

#include <iostream>

using namespace Inscoper;

int main() {
    std::cout << std::boolalpha;

    // Step 1: Every element reports its own type
    NBO::Instrument instrument;
    std::cout << (instrument.getNBOType() == NBO::ENBOType::INSTRUMENT) << std::endl;

    NBO::CMOS camera;
    std::cout << (camera.getNBOType() == NBO::ENBOType::CMOS) << std::endl;

    // Step 2: Convert between names, numeric values, and enumeration members
    std::cout << (NBO::NBOUtils::stringToNBOType("CMOS") == NBO::ENBOType::CMOS) << std::endl;
    std::cout << NBO::NBOUtils::NBOTypeToString(NBO::ENBOType::CMOS) << std::endl;

    // The numeric value is the identifier shared with the firmware and the API
    unsigned int value = NBO::NBOUtils::NBOTypeToValue(NBO::ENBOType::PLATE_ID_TYPE);
    std::cout << std::hex << "0x" << value << std::dec << std::endl;
    std::cout << (NBO::NBOUtils::valueToNBOType(value) == NBO::ENBOType::PLATE_ID_TYPE) << std::endl;

    // Unknown names and unknown values resolve to UNKNOWN instead of throwing
    std::cout << (NBO::NBOUtils::stringToNBOType("NoSuchElement") == NBO::ENBOType::UNKNOWN)
              << std::endl;

    // Step 3: Create an element from a type value
    // createElementFromType() returns the element as its base class. Cast it to the
    // concrete class with fromBase(), or with std::dynamic_pointer_cast.
    NBO::NBOBaseClassPtr base = NBO::NBOUtils::createElementFromType(NBO::ENBOType::CMOS);
    std::cout << base->getXMLName() << " " << base->getTypeName() << std::endl;

    NBO::CMOSPtr cmos = NBO::CMOS::fromBase(base);
    cmos->setPixelWidth(6.5f);
    std::cout << cmos->getPixelWidth() << std::endl;

    // A cast to the wrong class returns nullptr rather than throwing
    std::cout << (NBO::Instrument::fromBase(base) == nullptr) << std::endl;

    // An unknown type produces no element at all
    std::cout << (NBO::NBOUtils::createElementFromType(NBO::ENBOType::UNKNOWN) == nullptr)
              << std::endl;

    return 0;
}

import com.inscoper.nbo.CMOS;
import com.inscoper.nbo.ENBOType;
import com.inscoper.nbo.Instrument;
import com.inscoper.nbo.NBOBaseClass;
import com.inscoper.nbo.NBOUtils;

public class NboTypes {
    public static void main(String[] args) {
        // Step 1: Every element reports its own type
        Instrument instrument = new Instrument();
        System.out.println(instrument.getNBOType() == ENBOType.INSTRUMENT);

        CMOS camera = new CMOS();
        System.out.println(camera.getNBOType() == ENBOType.CMOS);

        // Step 2: Convert between names, numeric values, and enumeration members
        System.out.println(NBOUtils.stringToNBOType("CMOS") == ENBOType.CMOS);
        System.out.println(NBOUtils.NBOTypeToString(ENBOType.CMOS));

        // The numeric value is the identifier shared with the firmware and the API
        int value = NBOUtils.NBOTypeToValue(ENBOType.PLATE_ID_TYPE);
        System.out.println("0x" + Integer.toHexString(value));
        System.out.println(NBOUtils.valueToNBOType(value) == ENBOType.PLATE_ID_TYPE);

        // Unknown names and unknown values resolve to UNKNOWN instead of throwing
        System.out.println(NBOUtils.stringToNBOType("NoSuchElement") == ENBOType.UNKNOWN);

        // Step 3: Create an element from a type value
        // createElementFromType() returns the element as its base class. Cast it to
        // the concrete class with the static fromBase() of that class.
        NBOBaseClass base = NBOUtils.createElementFromType(ENBOType.CMOS);
        System.out.println(base.getXMLName() + " " + base.getTypeName());

        CMOS cmos = CMOS.fromBase(base);
        cmos.setPixelWidth(6.5f);
        System.out.println(cmos.getPixelWidth());

        // A cast to the wrong class returns null rather than throwing
        System.out.println(Instrument.fromBase(base) == null);

        // An unknown type produces no element at all
        System.out.println(NBOUtils.createElementFromType(ENBOType.UNKNOWN) == null);
    }
}