bool plot_from_PyObject(PyObject* value, Plot& plot) {
    static PyObject* PY_NAME = PyString_FromString("name");
    static PyObject* PY_VARIABLE = PyString_FromString("variable");
    static PyObject* PY_PLOT_CUT = PyString_FromString("plot_cut");
    static PyObject* PY_BINNING = PyString_FromString("binning");
    static PyObject* PY_TITLE = PyString_FromString("title");
    static PyObject* PY_X_AXIS = PyString_FromString("x-axis");
    static PyObject* PY_Y_AXIS = PyString_FromString("y-axis");
    static PyObject* PY_Z_AXIS = PyString_FromString("z-axis");

    if (! PyDict_Check(value)) {
        std::cerr << "Error: plots dictionnary value must be a dictionnary" << std::endl;
    }

    CHECK_AND_GET(plot.name, PY_NAME);
    CHECK_AND_GET(plot.variable, PY_VARIABLE);
    CHECK_AND_GET(plot.plot_cut, PY_PLOT_CUT);
    CHECK_AND_GET(plot.binning, PY_BINNING);

    GET(plot.title, PY_TITLE);
    GET(plot.x_axis, PY_X_AXIS);
    GET(plot.y_axis, PY_Y_AXIS);
    GET(plot.z_axis, PY_Z_AXIS);

    return true;
}
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, double & value, int count)
{
    CHECK_AND_GET(TYPE_DOUBLE, d);
}
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, int64_t & value, int count)
{
    CHECK_AND_GET(TYPE_INT64, i64);
}
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, float & value, int count)
{
    CHECK_AND_GET(TYPE_FLOAT, f);
}
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, uint8_t & value, int count)
{
    CHECK_AND_GET(TYPE_BYTE, u8);
}