Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions discos_client/initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,33 @@ def _enrich_named_property(
out["value"] = value
return out

def _collect_init_keys(
self,
schema: dict[str, Any]
) -> tuple[set[str], set[str]]:
"""
Recursively collect all ``required`` and ``initialize`` fields declared
in a schema, including those defined inside ``anyOf`` branches.

:param schema: A JSON Schema object, potentially containing ``anyOf``
branches and local ``required`` / ``initialize``
sections.
:return: A tuple where each element is a set of field names
aggregated from the entire schema hierarchy.
"""
required: set[str] = set(schema.get("required", []))
initialize: set[str] = set(schema.get("initialize", []))

any_of = schema.get("anyOf")
if isinstance(any_of, list):
for alt in any_of:
if isinstance(alt, dict):
r_alt, i_alt = self._collect_init_keys(alt)
required |= r_alt
initialize |= i_alt

return required, initialize

def _initialize_from_schema(
self,
schema: dict[str, Any]
Expand All @@ -589,21 +616,21 @@ def _initialize_from_schema(
:param schema: Fully normalized JSON schema.
:return: Initial structured payload used to construct a namespace.
"""
required: set[str] = set(schema.get("required", []))
initialize: set[str] = set(schema.get("initialize", []))
fake_values: dict[str, Any] = {}
required, initialize = self._collect_init_keys(schema)
result: dict[str, Any] = {}

for key in required.union(initialize):
prop_schema = self._find_property_schema(schema, key)
if prop_schema is None: # pragma: no cover
continue
prop_schema = self._replace_patterns_with_properties(
prop_schema,
{}
)
result[key] = self._enrich_named_property(
key,
prop_schema,
fake_values
{}
)
meta = self._meta(schema)
meta.update(result)
Expand All @@ -627,4 +654,11 @@ def _find_property_schema(
props = schema.get("properties", {})
if key in props:
return props[key]
any_of = schema.get("anyOf")
if isinstance(any_of, list):
for alt in any_of:
if isinstance(alt, dict):
found = self._find_property_schema(alt, key)
if found is not None:
return found
return None # pragma: no cover
163 changes: 163 additions & 0 deletions discos_client/schemas/common/derotators.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "common/derotators.json",
"title": "Derotators status",
"type": "object",
"description": "Status of the telescope derotators.",
"node": "derotators",
"$defs": {
"derotator": {
"title": "Derotator",
"type": "object",
"description": "Derotator status.",
"node": "derotators.<derotatorName>",
"properties": {
"commandedPosition": {
"type": "number",
"title": "Commanded Position",
"description": "Commanded position of the derotator",
"unit": "degrees"
},
"currentPosition": {
"type": "number",
"title": "Current Position",
"description": "Current position of the derotator.",
"unit": "degrees"
},
"maxLimit": {
"type": "number",
"title": "Max Limit",
"description": "Maximum limit of the derotator's range.",
"unit": "degrees"
},
"minLimit": {
"type": "number",
"title": "Min Limit",
"description": "Minimum limit of the derotator's range",
"unit": "degrees"
},
"ready": {
"type": "boolean",
"title": "Ready",
"description": "Indicates whether the derotator is ready or not."
},
"rewindingStep": {
"type": "number",
"title": "Rewinding Step",
"description": "Derotator's angle between two external feeds.",
"unit": "degrees"
},
"slewing": {
"type": "boolean",
"title": "Slewing",
"description": "Indicates whether the derotator is currently slewing."
},
"timestamp": {
"$ref": "../definitions/timestamp.json"
},
"tracking": {
"type": "boolean",
"title": "Tracking",
"description": "Indicates whether the derotator is tracking the commanded position."
},
"trackingError": {
"type": "number",
"title": "Tracking Error",
"description": "Derotator tracking error.",
"unit": "degrees"
}
},
"required": [
"commandedPosition",
"currentPosition",
"maxLimit",
"minLimit",
"ready",
"rewindingStep",
"slewing",
"timestamp",
"tracking",
"trackingError"
]
}
},
"anyOf": [
{
"type": "object",
"properties": {
"currentConfiguration": {
"type": "string",
"title": "Current Configuration",
"description": "Currently selected derotator configuration."
},
"currentDerotator": {
"type": "string",
"title": "Current Derotator",
"description": "Currently selected derotator's name."
},
"currentSetup": {
"type": "string",
"title": "Current setup",
"description": "Current DISCOS setup code."
},
"rewinding": {
"type": "boolean",
"title": "Rewinding",
"description": "Indicates whether the current derotator is rewinding."
},
"rewindingMode": {
"type": "string",
"title": "Rewinding Mode",
"description": "The derotator positioner rewinding mode.",
"enum": [
"AUTO",
"MANUAL",
"NONE"
]
},
"rewindingRequired": {
"type": "boolean",
"title": "Rewinding Required",
"description": "Indicates whether the current derotator requires to be rewinded."
},
"status": {
"$ref": "../definitions/status.json"
},
"timestamp": {
"$ref": "../definitions/timestamp.json"
},
"tracking": {
"type": "boolean",
"title": "Tracking",
"description": "Indicates whether the current derotator is tracking the commanded position."
},
"updating": {
"type": "boolean",
"title": "Updating",
"description": "Indicates whether the derotator positioner is updating the position."
}
},
"required": [
"currentConfiguration",
"currentDerotator",
"currentSetup",
"rewinding",
"rewindingMode",
"rewindingRequired",
"status",
"timestamp",
"tracking",
"updating"
]
},
{
"type": "object",
"patternProperties": {
"^[A-Za-z0-9_]+$": { "$ref": "#/$defs/derotator" }
},
"minProperties": 1,
"maxProperties": 1,
"additionalProperties": false
}
]
}
21 changes: 21 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,24 @@
.rst-content table.docutils th {
white-space: pre-wrap;
}
.rst-content table.docutils tr.row-border-0 td,
.rst-content table.docutils tr.row-border-0 th,
.rst-content table.docutils tr.row-border-1 td:nth-child(n+2),
.rst-content table.docutils tr.row-border-1 th:nth-child(n+2),
.rst-content table.docutils tr.row-border-2 td:nth-child(n+3),
.rst-content table.docutils tr.row-border-2 th:nth-child(n+3)
{
border-top: 2px solid #777;
font-size: 0 !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.rst-content table.docutils tr.row-hidden-0 td,
.rst-content table.docutils tr.row-hidden-0 th,
.rst-content table.docutils tr.row-hidden-1 td:nth-child(n+2),
.rst-content table.docutils tr.row-hidden-1 th:nth-child(n+2),
.rst-content table.docutils tr.row-hidden-2 td:nth-child(n+3),
.rst-content table.docutils tr.row-hidden-2 th:nth-child(n+3)
{
display: none;
}
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
sys.path.insert(0, os.path.abspath('../discos_client'))

from patches import _simpletype, _complexstructures, _reference
from patches import _simpletype, _complexstructures, _reference, _transform

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
Expand Down Expand Up @@ -93,3 +93,4 @@ def setup(app):
sjs_wide_format.WideFormat._simpletype = _simpletype
sjs_wide_format.WideFormat._complexstructures = _complexstructures
sjs_wide_format.WideFormat._reference = _reference
sjs_wide_format.WideFormat.transform = _transform
Loading