""" This module define some functions that can be used to
define the common section of the CSP configure schema.
"""
from inspect import cleandoc
from re import Pattern, compile
from schema import Regex
from .._common import TMSchema, get_unique_id_schema, split_interface_version
from . import version as csp_version
MAX_STREAMS_PER_FSP = 744
MAX_CHANNELS_PER_STREAM = 20
MAX_CHANNELS_PER_FSP = 14880
MAX_SIGNED_32BIT_INT = 2**31 - 1
MAX_PORT_VALUE = 65535
MAX_CORR_CHANNELS = MAX_SIGNED_32BIT_INT
CHANNEL_WIDTH_VALUES = [
210,
420,
840,
1680,
3360,
6720,
13440,
26880,
40320,
53760,
80640,
107520,
161280,
215040,
322560,
416640,
430080,
645120,
]
IPV4_REGEX_PATTERN: Pattern = compile(
r"^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$"
)
[docs]
def use_camel_case(version: str) -> bool:
"""Checks whether the given CSP schema version uses camel-case
attribute names.
Low CSP schema has been developed after the changes to
keyword case. This method returns always False for Low CSP
schema versions.
:param version: Interface Version URI
:returns: True or False according to schema version number
"""
return not (
version.startswith(csp_version.CSP_CONFIG_VER0)
or version.startswith(csp_version.CSP_CONFIG_VER1)
)
[docs]
def add_common_frequency_band(
version: str, strict: bool, schema: TMSchema
) -> None:
"""
Add the frequency band field to the low schema.
:param version: Interface Version URI
:param strict: Schema strictness
:param schema: the schema to which the field is to be added
"""
camel_case = use_camel_case(version)
schema.add_field(
("frequency_band" if camel_case else "frequencyBand"),
(Regex(r"^(1|2|3|4|5(a|b)|low)$") if strict else str),
description=cleandoc(
"""
Frequency band applies for all the receptors (VCCs)
that belong to the sub-array.
The value of 'low' is used to only within SKA Low.
As this field is a mandatory field but bands 1, 2,
3, 4, 5a and 5b only make sense for SKA Mid.
"""
),
)
[docs]
def add_mid_frequency_band(
version: str, strict: bool, schema: TMSchema
) -> None:
"""
Add the frequency band field to the mid schema.
:param version: Interface Version URI
:param strict: Schema strictness
:param schema: the schema to which the field is to be added
"""
camel_case = use_camel_case(version)
(major, minor) = split_interface_version(version)
if (major, minor) <= (2, 3):
schema.add_field(
("frequency_band" if camel_case else "frequencyBand"),
(Regex(r"^(1|2|3|4|5(a|b))$") if strict else str),
description=cleandoc(
"""
Frequency band applies for all the receptors (VCCs)
that belong to the sub-array.
"""
),
)
elif (major, minor) < (3, 0):
schema.add_field(
("frequency_band" if camel_case else "frequencyBand"),
(Regex(r"^(1|2|3|4|5(a|b)|low)$") if strict else str),
description=cleandoc(
"""
Frequency band applies for all the receptors (VCCs)
that belong to the sub-array.
The value of ‘low’ is used to only within SKA Low. As this
field is a mandatory field but bands 1, 2, 3, 4, 5a and 5b
only make sense for SKA Mid.
"""
),
)
elif (major, minor) < (5, 0):
schema.add_field(
("frequency_band" if camel_case else "frequencyBand"),
(Regex(r"^(1|2|5(a|b))$") if strict else str),
description=cleandoc(
"""
Frequency band applies for all the receptors (VCCs)
that belong to the sub-array.
Valid bands include: 1, 2, 5a, 5b. Bands 3 and 4 are not
included in the current implementation but could be supported
in the future.
"""
),
)
else:
schema.add_field(
("frequency_band" if camel_case else "frequencyBand"),
(Regex(r"^(1|2|5(a|b))$") if strict else str),
description=cleandoc(
"""
Frequency band applies for all the receptors (VCCs)
that belong to the sub-array.
.. list-table::
:widths: auto
:header-rows: 1
* - Frequency Band
- Sky Frequency Range (GHz)
* - 1
- 0.35 - 1.05
* - 2
- 0.95 - 1.76
* - 5a
- 4.60 - 8.50
* - 5b
- 8.30 - 15.30
Valid bands include: 1, 2, 5a, 5b. Bands 3 and 4 are not
included in the current implementation but could be supported
in the future.
"""
),
)
def _get_common_config_schema_without_band(
version: str, strict: bool
) -> TMSchema:
"""CSP Subarray common configuration schema.
This schema is valid for Mid and Low CSP.
NOTE: Low CSP version starts from 2.0
:param version: Interface Version URI
:param strict: Schema strictness
:return: the JSON Schema for the CSP subarray common
configuration (ADR-18).
"""
camel_case = use_camel_case(version)
(major, minor) = split_interface_version(version)
# Elements
elems = TMSchema.new(
"Common configuration schema",
version,
strict,
description=cleandoc(
"""
Common section, containing the parameters and the sections
belonging to all CSP subsystems. This section is forwarded to
all sub-elements.
"""
),
as_reference=True,
)
if (major, minor) < (3, 0):
elems.add_opt_field("config_id" if camel_case else "id", str)
else:
elems.add_field("config_id" if camel_case else "id", str)
if (major, minor) >= (3, 0):
elems.add_field(
"subarray_id",
int,
check_strict=lambda n: n >= 1 and n <= 16,
description=cleandoc(
"""
The Subarray ID that the list of receptors will be
assigned to.
For Mid, there are a maximum of 16 subarrays.
Range: Integer from 1-16 inclusive
"""
),
)
elif (major, minor) >= (2, 0):
# In version 2.0, subarray_id was added
elems.add_field("subarray_id", int, description="Subarray number")
elems.add_opt_field(
"eb_id",
get_unique_id_schema(strict, r"eb"),
description=cleandoc(
"""
Execution block ID to associate scan configs to an observation.
This ID is used for associating generated data, especially
data products, for a given observation. Multiple scans can
be linked to one observation and this ID is used as metadata
to associate the data products from all scans of the same
observation.
This ID does not have to be unique for a scan configuration but
should be unique for different observations.
For example, all the data and weights files will have an
EB_ID header value populated with the value supplied in this
field.
"""
),
)
return elems