imas-python 0.1.dev1618__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of imas-python might be problematic. Click here for more details.

Files changed (108) hide show
  1. imas/__init__.py +34 -0
  2. imas/__main__.py +17 -0
  3. imas/_util.py +260 -0
  4. imas/_version.py +16 -0
  5. imas/assets/IDSDef2MDSpreTree.xsl +161 -0
  6. imas/assets/IDS_fake_toplevel.xml +318 -0
  7. imas/assets/IDS_minimal.xml +37 -0
  8. imas/assets/IDS_minimal_2.xml +37 -0
  9. imas/assets/IDS_minimal_struct_array.xml +43 -0
  10. imas/assets/IDS_minimal_types.xml +169 -0
  11. imas/assets/ITER_134173_106_core_profiles.ids +2438 -0
  12. imas/assets/ITER_134173_106_equilibrium.ids +3172 -0
  13. imas/assets/README.md +5 -0
  14. imas/assets/core_profiles.ids +2438 -0
  15. imas/assets/equilibrium.ids +3172 -0
  16. imas/backends/__init__.py +12 -0
  17. imas/backends/db_entry_impl.py +122 -0
  18. imas/backends/imas_core/__init__.py +4 -0
  19. imas/backends/imas_core/al_context.py +391 -0
  20. imas/backends/imas_core/db_entry_al.py +405 -0
  21. imas/backends/imas_core/db_entry_helpers.py +200 -0
  22. imas/backends/imas_core/imas_interface.py +216 -0
  23. imas/backends/imas_core/mdsplus_model.py +367 -0
  24. imas/backends/imas_core/uda_support.py +56 -0
  25. imas/backends/netcdf/__init__.py +4 -0
  26. imas/backends/netcdf/db_entry_nc.py +176 -0
  27. imas/backends/netcdf/ids2nc.py +306 -0
  28. imas/backends/netcdf/nc2ids.py +302 -0
  29. imas/backends/netcdf/nc_metadata.py +357 -0
  30. imas/backends/netcdf/nc_validate.py +53 -0
  31. imas/command/cli.py +239 -0
  32. imas/command/db_analysis.py +290 -0
  33. imas/command/helpers.py +45 -0
  34. imas/command/timer.py +77 -0
  35. imas/db_entry.py +802 -0
  36. imas/dd_helpers.py +300 -0
  37. imas/dd_zip.py +297 -0
  38. imas/exception.py +107 -0
  39. imas/ids_base.py +149 -0
  40. imas/ids_convert.py +920 -0
  41. imas/ids_coordinates.py +400 -0
  42. imas/ids_data_type.py +115 -0
  43. imas/ids_defs.py +171 -0
  44. imas/ids_factory.py +108 -0
  45. imas/ids_identifiers.py +125 -0
  46. imas/ids_metadata.py +307 -0
  47. imas/ids_path.py +254 -0
  48. imas/ids_primitive.py +510 -0
  49. imas/ids_struct_array.py +233 -0
  50. imas/ids_structure.py +331 -0
  51. imas/ids_toplevel.py +381 -0
  52. imas/setup_logging.py +64 -0
  53. imas/test/test_all_dd_versions.py +28 -0
  54. imas/test/test_cli.py +44 -0
  55. imas/test/test_dbentry.py +104 -0
  56. imas/test/test_dd_helpers.py +134 -0
  57. imas/test/test_dd_zip.py +29 -0
  58. imas/test/test_deepcopy.py +25 -0
  59. imas/test/test_exception.py +12 -0
  60. imas/test/test_get_sample.py +388 -0
  61. imas/test/test_hash.py +188 -0
  62. imas/test/test_helpers.py +354 -0
  63. imas/test/test_identifiers.py +105 -0
  64. imas/test/test_ids2nc.py +166 -0
  65. imas/test/test_ids_ascii_data.py +39 -0
  66. imas/test/test_ids_convert.py +415 -0
  67. imas/test/test_ids_coordinates.py +165 -0
  68. imas/test/test_ids_data_type.py +40 -0
  69. imas/test/test_ids_factory.py +35 -0
  70. imas/test/test_ids_metadata.py +66 -0
  71. imas/test/test_ids_mixin.py +20 -0
  72. imas/test/test_ids_path.py +192 -0
  73. imas/test/test_ids_primitive.py +109 -0
  74. imas/test/test_ids_struct_array.py +89 -0
  75. imas/test/test_ids_structure.py +70 -0
  76. imas/test/test_ids_toplevel.py +55 -0
  77. imas/test/test_ids_validate.py +343 -0
  78. imas/test/test_latest_dd_autofill.py +74 -0
  79. imas/test/test_latest_dd_manual.py +38 -0
  80. imas/test/test_latest_dd_resample.py +102 -0
  81. imas/test/test_lazy_loading.py +201 -0
  82. imas/test/test_list_occurrences.py +82 -0
  83. imas/test/test_minimal.py +37 -0
  84. imas/test/test_minimal_conversion.py +44 -0
  85. imas/test/test_minimal_io.py +21 -0
  86. imas/test/test_minimal_struct_array_io.py +60 -0
  87. imas/test/test_minimal_types.py +436 -0
  88. imas/test/test_minimal_types_io.py +70 -0
  89. imas/test/test_minimal_types_io_automatic.py +66 -0
  90. imas/test/test_nbc_change.py +408 -0
  91. imas/test/test_nc_autofill.py +13 -0
  92. imas/test/test_nc_entry.py +28 -0
  93. imas/test/test_nc_metadata.py +153 -0
  94. imas/test/test_nc_validation.py +197 -0
  95. imas/test/test_snippets.py +25 -0
  96. imas/test/test_static_ids.py +39 -0
  97. imas/test/test_str_1d.py +99 -0
  98. imas/test/test_time_slicing.py +182 -0
  99. imas/test/test_uda_support.py +12 -0
  100. imas/test/test_util.py +209 -0
  101. imas/training.py +45 -0
  102. imas/util.py +526 -0
  103. imas_python-0.1.dev1618.dist-info/LICENSE.txt +165 -0
  104. imas_python-0.1.dev1618.dist-info/METADATA +288 -0
  105. imas_python-0.1.dev1618.dist-info/RECORD +108 -0
  106. imas_python-0.1.dev1618.dist-info/WHEEL +5 -0
  107. imas_python-0.1.dev1618.dist-info/entry_points.txt +3 -0
  108. imas_python-0.1.dev1618.dist-info/top_level.txt +1 -0
imas/__init__.py ADDED
@@ -0,0 +1,34 @@
1
+ # This file is part of imas-python.
2
+ # You should have received the imas-python LICENSE file with this project.
3
+
4
+ # isort: skip_file
5
+
6
+ from packaging.version import Version as _V
7
+
8
+ from ._version import version as __version__ # noqa: F401
9
+ from ._version import version_tuple # noqa: F401
10
+
11
+ # Import logging _first_
12
+ from . import setup_logging
13
+
14
+ # Import main user API objects in the imas module
15
+ from .db_entry import DBEntry
16
+ from .ids_factory import IDSFactory
17
+ from .ids_convert import convert_ids
18
+ from .ids_identifiers import identifiers
19
+
20
+ # Load the imas-python IMAS AL/DD core
21
+ from . import (
22
+ db_entry,
23
+ dd_helpers,
24
+ dd_zip,
25
+ util,
26
+ )
27
+
28
+ PUBLISHED_DOCUMENTATION_ROOT = (
29
+ "https://sharepoint.iter.org/departments/POP/CM/IMDesign/"
30
+ "Code%20Documentation/imas-python-doc"
31
+ )
32
+ """URL to the published documentation."""
33
+ OLDEST_SUPPORTED_VERSION = _V("3.22.0")
34
+ """Oldest Data Dictionary version that is supported by imas-python."""
imas/__main__.py ADDED
@@ -0,0 +1,17 @@
1
+ # This file is part of imas-python.
2
+ # You should have received the imas-python LICENSE file with this project.
3
+ """Support module to run imas as a module:
4
+
5
+ .. code-block:: bash
6
+ :caption: Options to run imas CLI interface
7
+
8
+ # Run as a module (implemented in imas/__main__.py)
9
+ python -m imas
10
+
11
+ # Run as "program" (see project.scripts in pyproject.toml)
12
+ imas
13
+ """
14
+
15
+ from imas.command.cli import cli
16
+
17
+ cli()
imas/_util.py ADDED
@@ -0,0 +1,260 @@
1
+ # This file is part of imas-python.
2
+ # You should have received the imas-python LICENSE file with this project.
3
+ """This file contains the implementation of all utility functions that need external
4
+ modules. Implementation has been removed from util.py to improve the performance of
5
+ ``import imas``.
6
+ """
7
+
8
+ import copy
9
+ import logging
10
+ from difflib import Match, SequenceMatcher
11
+ from typing import Union
12
+
13
+ import numpy
14
+ import rich
15
+ import scipy.interpolate
16
+ from rich.columns import Columns
17
+ from rich.console import Group
18
+ from rich.panel import Panel
19
+ from rich.pretty import Pretty
20
+ from rich.table import Table
21
+ from rich.text import Text
22
+ from rich.tree import Tree
23
+
24
+ from imas.ids_base import IDSBase
25
+ from imas.ids_data_type import IDSDataType
26
+ from imas.ids_defs import IDS_TIME_MODE_HOMOGENEOUS
27
+ from imas.ids_metadata import IDSMetadata
28
+ from imas.ids_primitive import IDSPrimitive
29
+ from imas.ids_struct_array import IDSStructArray
30
+ from imas.ids_structure import IDSStructure
31
+ from imas.ids_toplevel import IDSToplevel
32
+ from imas.util import idsdiffgen, visit_children
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+
37
+ def resample_impl(node, old_time, new_time, homogeneousTime, inplace, **kwargs):
38
+ if homogeneousTime is None:
39
+ homogeneousTime = node._time_mode
40
+
41
+ if homogeneousTime is None:
42
+ raise ValueError(
43
+ "homogeneous_time is not specified in ids_properties nor given"
44
+ " as keyword argument"
45
+ )
46
+
47
+ if homogeneousTime != IDS_TIME_MODE_HOMOGENEOUS:
48
+ # TODO: implement also for IDS_TIME_MODE_INDEPENDENT
49
+ # (and what about converting between time modes? this gets tricky fast)
50
+ raise NotImplementedError(
51
+ "resample is only implemented for IDS_TIME_MODE_HOMOGENEOUS"
52
+ )
53
+
54
+ def visitor(el):
55
+ if not el.has_value:
56
+ return
57
+ if el.metadata.type.is_dynamic and el.metadata.name != "time":
58
+ # effectively a guard to get only idsPrimitive
59
+ # TODO: also support time axes as dimension of IDSStructArray
60
+ time_axis = None
61
+ if hasattr(el, "coordinates"):
62
+ time_axis = el.coordinates.time_index
63
+ if time_axis is None:
64
+ logger.warning(
65
+ "No time axis found for dynamic structure %s", node._path
66
+ )
67
+ interpolator = scipy.interpolate.interp1d(
68
+ old_time.value, el.value, axis=time_axis, **kwargs
69
+ )
70
+ el.value = interpolator(new_time)
71
+
72
+ if not inplace:
73
+ el = copy.deepcopy(node)
74
+ else:
75
+ el = node
76
+
77
+ visit_children(visitor, el)
78
+
79
+ if isinstance(el, IDSToplevel):
80
+ el.time = new_time
81
+ else:
82
+ logger.warning(
83
+ "Performing resampling on non-toplevel. "
84
+ "Be careful to adjust your time base manually"
85
+ )
86
+
87
+ return el
88
+
89
+
90
+ def print_tree_impl(structure, hide_empty_nodes):
91
+ with numpy.printoptions(threshold=5, linewidth=1024, precision=4):
92
+ rich.print(_make_tree(structure, hide_empty_nodes))
93
+
94
+
95
+ def _make_tree(structure, hide_empty_nodes=True, *, tree=None):
96
+ """Build the ``rich.tree.Tree`` for display in :py:meth:`print_tree`.
97
+
98
+ Args:
99
+ structure: IDS structure to add to the tree
100
+ hide_empty_nodes: Show or hide nodes without value.
101
+
102
+ Keyword Args:
103
+ tree: If provided, child items will be added to this Tree object. Otherwise a
104
+ new Tree is constructed.
105
+ """
106
+ if tree is None:
107
+ tree = Tree(f"[magenta]{structure.metadata.name}")
108
+
109
+ if not isinstance(structure, (IDSStructure, IDSStructArray)):
110
+ raise TypeError()
111
+
112
+ iterator = structure
113
+ if hide_empty_nodes and isinstance(structure, IDSStructure):
114
+ iterator = structure.iter_nonempty_(accept_lazy=True)
115
+ for child in iterator:
116
+ if isinstance(child, IDSPrimitive):
117
+ if not child.has_value:
118
+ value = "[bright_black]-"
119
+ else:
120
+ value = Pretty(child.value)
121
+ txt = f"[yellow]{child.metadata.name}[/]:"
122
+ group = Columns([txt, value])
123
+ tree.add(group)
124
+ else:
125
+ if isinstance(child, IDSStructure):
126
+ txt = f"[magenta]{child._path}[/]"
127
+ ntree = tree.add(txt)
128
+ elif isinstance(child, IDSStructArray):
129
+ ntree = tree
130
+ if not child.has_value:
131
+ tree.add(f"[magenta]{child._path}[][/]")
132
+ _make_tree(child, hide_empty_nodes, tree=ntree)
133
+
134
+ return tree
135
+
136
+
137
+ def print_metadata_tree_impl(
138
+ structure: Union[IDSMetadata, IDSBase], maxdepth: int
139
+ ) -> None:
140
+ def _make_tree(tree: Tree, metadata: IDSMetadata, depth: int):
141
+ for child in metadata._children.values():
142
+ if child.data_type in (IDSDataType.STRUCTURE, IDSDataType.STRUCT_ARRAY):
143
+ newtree = tree.add(f"[magenta]{child.path_doc}[/]")
144
+ if maxdepth == 0 or depth < maxdepth:
145
+ _make_tree(newtree, child, depth + 1)
146
+ else:
147
+ newtree.add("[bright_black]<hidden>[/]")
148
+ else:
149
+ tree.add(f"[yellow]{child.path_doc}")
150
+
151
+ metadata = structure if isinstance(structure, IDSMetadata) else structure.metadata
152
+ tree = Tree(f"[magenta]{metadata.name}")
153
+ _make_tree(tree, metadata, 1)
154
+ rich.print(tree)
155
+
156
+
157
+ def inspect_impl(ids_node, hide_empty_nodes):
158
+ if not isinstance(ids_node, IDSBase):
159
+ return rich.inspect(ids_node)
160
+ # Title
161
+ if isinstance(ids_node, IDSToplevel):
162
+ title = f"IDS: [green]{ids_node.metadata.name}"
163
+ elif isinstance(ids_node, IDSStructure):
164
+ title = f"IDS structure: [green]{ids_node._path}"
165
+ elif isinstance(ids_node, IDSStructArray):
166
+ title = f"IDS array of structures: [green]{ids_node._path}"
167
+ else:
168
+ title = f"IDS value: [green]{ids_node._path}"
169
+ if ids_node._version:
170
+ title += f" [/](DD version [bold cyan]{ids_node._version}[/])"
171
+
172
+ renderables = []
173
+ # Documentation
174
+ renderables.append(Text(ids_node.metadata.documentation, style="inspect.help"))
175
+
176
+ # Value
177
+ if isinstance(ids_node, (IDSStructArray, IDSPrimitive)):
178
+ val = Pretty(ids_node.value, indent_guides=True, max_length=10, max_string=60)
179
+ value_text = Text.assemble(("value", "inspect.attr"), (" =", "inspect.equals"))
180
+ table = Table.grid(padding=(0, 1), expand=False)
181
+ table.add_column(justify="right")
182
+ table.add_row(value_text, val)
183
+ renderables.append(Panel(table, border_style="inspect.value.border"))
184
+
185
+ attrs = set(name for name in dir(ids_node) if not name.startswith("_"))
186
+ child_nodes = set()
187
+ if isinstance(ids_node, IDSStructure):
188
+ child_nodes = set(ids_node._children)
189
+ attrs -= child_nodes
190
+ attrs -= {"value"}
191
+
192
+ # Properties
193
+ if attrs:
194
+ attrs_table = Table.grid(padding=(0, 1), expand=False)
195
+ attrs_table.add_column(justify="right")
196
+
197
+ for attr in sorted(attrs):
198
+ try:
199
+ value = getattr(ids_node, attr)
200
+ except Exception:
201
+ continue
202
+ if callable(value):
203
+ continue
204
+
205
+ key_text = Text.assemble((attr, "inspect.attr"), (" =", "inspect.equals"))
206
+ attrs_table.add_row(key_text, Pretty(value))
207
+
208
+ renderables.append(Panel(attrs_table, title="Attributes"))
209
+
210
+ if child_nodes:
211
+ child_table = Table.grid(padding=(0, 1), expand=False)
212
+ child_table.add_column(justify="right")
213
+
214
+ for child in sorted(child_nodes):
215
+ value = getattr(ids_node, child)
216
+ if hide_empty_nodes and not value.has_value:
217
+ continue
218
+ key_text = Text.assemble((child, "inspect.attr"), (" =", "inspect.equals"))
219
+ child_table.add_row(key_text, Pretty(value))
220
+
221
+ renderables.append(Panel(child_table, title="Child nodes", style="cyan"))
222
+
223
+ rich.print(Panel.fit(Group(*renderables), title=title, border_style="scope.border"))
224
+
225
+
226
+ def idsdiff_impl(struct1: IDSStructure, struct2: IDSStructure) -> None:
227
+ diff_table = Table("Value in structure 1", "Value in structure 2")
228
+
229
+ for description, child1, child2 in idsdiffgen(struct1, struct2):
230
+ if not isinstance(child1, IDSBase) and not isinstance(child2, IDSBase):
231
+ txt1 = f"{description}: {child1}"
232
+ txt2 = f"{description}: {child2}"
233
+ else:
234
+ txt1 = "-" if child1 is None else repr(child1)
235
+ txt2 = "-" if child2 is None else repr(child2)
236
+
237
+ seqmat = SequenceMatcher()
238
+ seqmat.set_seqs(txt1, txt2)
239
+
240
+ out1 = Text()
241
+ out2 = Text()
242
+ prevmatch = Match(0, 0, 0)
243
+ for match in seqmat.get_matching_blocks():
244
+ if match.a > prevmatch.a + prevmatch.size:
245
+ out1.append(txt1[prevmatch.a + prevmatch.size : match.a], "bold red")
246
+ if match.b > prevmatch.b + prevmatch.size:
247
+ out2.append(txt2[prevmatch.b + prevmatch.size : match.b], "bold green")
248
+ out1.append(txt1[match.a : match.a + match.size])
249
+ out2.append(txt2[match.b : match.b + match.size])
250
+ prevmatch = match
251
+ out1.append(txt1[match.a + match.size :], style="bold red")
252
+ out2.append(txt2[match.b + match.size :], style="bold green")
253
+
254
+ diff_table.add_row(out1, out2)
255
+ diff_table.add_section()
256
+
257
+ if diff_table.row_count:
258
+ rich.print(diff_table)
259
+ else:
260
+ rich.print("Structures", struct1, "and", struct2, "are identical")
imas/_version.py ADDED
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '0.1.dev1618'
16
+ __version_tuple__ = version_tuple = (0, 1, 'dev1618')
@@ -0,0 +1,161 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet xmlns:yaslt="http://www.mod-xslt2.com/ns/1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" extension-element-prefixes="yaslt" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:local="http://www.example.com/functions/local" exclude-result-prefixes="local xs">
3
+ <xsl:param name="DD_GIT_DESCRIBE" as="xs:string" required="yes"/>
4
+ <xsl:param name="AL_GIT_DESCRIBE" as="xs:string" required="yes"/>
5
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
6
+ <!-- This script transforms the IDSDef.xml file into an XML file which will be used to build the MDS+ tree-->
7
+ <!-- It contains the full data structure and describes it in terms of MDS+ terminology (node, member) and types (TEXT,NUMERIC,SIGNAL)-->
8
+ <!-- This XML file has then to be processed by the Java routine CompileTree to create the MDS+ tree (part of the MDS+ libraries) -->
9
+ <!-- Time dependent numeric signals are of the SIGNAL type -->
10
+ <!-- Time independent numeric signals are of the NUMERIC type -->
11
+ <!-- Only Vector of strings (str_1d_type) are of the TEXT type --> <!-- Not sure the vector of strings with time-dependence will work with a TEXT declaration, though -->
12
+ <!-- Written by F. Imbeaux -->
13
+
14
+ <!-- Function for multiplying the number of descendents with timebasepath attribute by the occurrence of the child AoS -->
15
+ <xsl:function name="local:count-dynamic-fields" as="xs:integer">
16
+ <xsl:param name="current" as="node()"/>
17
+ <xsl:param name="level" as="xs:integer"/>
18
+ <xsl:param name="aos" as="xs:boolean"/>
19
+ <xsl:value-of select="$current/@maxoccur*count($current//field[@type='dynamic' and (($aos and @data_type='struct_array') or (not($aos) and not(@data_type='struct_array'))) and count(ancestor::field[@data_type='struct_array'])=$level])+$current/@maxoccur*sum($current//field[@data_type='struct_array' and not(@maxoccur='unbounded') and count(ancestor::field[@data_type='struct_array'])=$level]/local:count-dynamic-fields(.,$level+1,$aos))"/>
20
+ </xsl:function>
21
+
22
+ <!-- Scan for top-level elements -->
23
+ <xsl:template match = "/*">
24
+ <tree>
25
+ <member NAME="REF_INFO" USAGE="NUMERIC"/>
26
+ <node NAME="VERSION">
27
+ <member NAME="DATA_DICT" USAGE="TEXT"><data>"<xsl:value-of select="$DD_GIT_DESCRIBE"/>"</data></member>
28
+ <member NAME="ACC_LAYER" USAGE="TEXT"><data>"<xsl:value-of select="$AL_GIT_DESCRIBE"/>"</data></member>
29
+ <member NAME="BACK_MAJOR" USAGE="NUMERIC"></member>
30
+ <member NAME="BACK_MINOR" USAGE="NUMERIC"></member>
31
+ </node>
32
+
33
+ <xsl:apply-templates select = "IDS"/>
34
+ </tree>
35
+ </xsl:template>
36
+
37
+
38
+
39
+ <!-- First, we scan at the IDS level -->
40
+ <xsl:template match = "IDS">
41
+ <node>
42
+ <xsl:attribute name="NAME"><xsl:value-of select="@name"/></xsl:attribute>
43
+ <xsl:apply-templates select = "field"/>
44
+
45
+ <!-- Create subtrees for IDS occurrence. If parameter maxoccur is not defined, 10 additional occurrences are created-->
46
+ <xsl:call-template name = "addOccurrence" >
47
+ <xsl:with-param name = "iteration" select = "if (@maxoccur) then @maxoccur else 10" />
48
+ </xsl:call-template>
49
+
50
+ </node>
51
+ </xsl:template>
52
+
53
+
54
+
55
+ <!-- Then we scan the fields recursively -->
56
+ <xsl:template match = "field">
57
+ <xsl:choose>
58
+ <xsl:when test="@data_type='structure'">
59
+ <!-- this is a structure : write as node and scan the child elements recursively -->
60
+ <node>
61
+ <xsl:attribute name="NAME"><xsl:value-of select="@name"/></xsl:attribute>
62
+
63
+ <xsl:apply-templates select = "field"/>
64
+ </node>
65
+ </xsl:when>
66
+ <xsl:when test="@data_type='struct_array'">
67
+ <node>
68
+ <xsl:attribute name="NAME"><xsl:value-of select="@name"/></xsl:attribute>
69
+ <member>
70
+ <xsl:attribute name="NAME">static</xsl:attribute>
71
+ <xsl:attribute name="USAGE">NUMERIC</xsl:attribute>
72
+ </member>
73
+ <node>
74
+ <xsl:attribute name="NAME">timed_aos</xsl:attribute>
75
+ <xsl:call-template name = "makeAosSubtrees" >
76
+ <xsl:with-param name = "instances" select = "if (@type='dynamic') then 1 else local:count-dynamic-fields(.,1,true())" />
77
+ </xsl:call-template>
78
+ </node>
79
+ <node>
80
+ <xsl:attribute name="NAME">timed_data</xsl:attribute>
81
+ <xsl:call-template name = "makeDataSubtrees" >
82
+ <xsl:with-param name = "instances" select = "if (@type='dynamic') then 0 else local:count-dynamic-fields(.,1,false())"/>
83
+ </xsl:call-template>
84
+ </node>
85
+ </node>
86
+ </xsl:when>
87
+ <xsl:otherwise>
88
+ <!-- this is a bottom element -->
89
+ <member>
90
+ <xsl:attribute name="NAME"><xsl:value-of select="@name"/></xsl:attribute>
91
+ <!-- There used to be an instruction to use NUMERIC for dynamic str_1d_type fields, not sure if this was on purpose or some mis-use of logical operator precedence -->
92
+ <xsl:attribute name="USAGE"><xsl:value-of select="if(@type='dynamic') then 'SIGNAL' else 'NUMERIC'"/></xsl:attribute>
93
+ </member></xsl:otherwise>
94
+ </xsl:choose>
95
+ </xsl:template>
96
+
97
+
98
+ <!-- Additional IDS occurrence creation -->
99
+ <xsl:template name="addOccurrence">
100
+ <xsl:param name="iteration"/>
101
+ <xsl:variable name="current" select="."/>
102
+ <xsl:for-each select="1 to $iteration">
103
+ <node>
104
+ <xsl:attribute name="NAME">
105
+ <xsl:value-of select="."/>
106
+ </xsl:attribute>
107
+ <xsl:apply-templates select = "$current/field"/>
108
+ </node>
109
+ </xsl:for-each>
110
+ </xsl:template>
111
+
112
+
113
+ <!-- Aos timed node creation: Aos childs-->
114
+ <xsl:template name="makeAosSubtrees">
115
+ <xsl:param name="instances" select="100"/>
116
+ <xsl:for-each select="1 to xs:integer(1+(($instances - 1) div 1000))">
117
+ <xsl:variable name="group" select="."/>
118
+ <node>
119
+ <xsl:attribute name="NAME"><xsl:value-of select="concat('group_',.)"/></xsl:attribute>
120
+ <xsl:for-each select="1 to 1000">
121
+ <xsl:variable name="item" select="($group - 1) * 1000 + ."/>
122
+ <xsl:if test="$item &lt;= $instances">
123
+ <node>
124
+ <xsl:attribute name="NAME"><xsl:value-of select="concat('item_',.)"/></xsl:attribute>
125
+ <member>
126
+ <xsl:attribute name="NAME">aos</xsl:attribute>
127
+ <xsl:attribute name="USAGE">NUMERIC</xsl:attribute>
128
+ </member>
129
+ <member>
130
+ <xsl:attribute name="NAME">time</xsl:attribute>
131
+ <xsl:attribute name="USAGE">NUMERIC</xsl:attribute>
132
+ </member>
133
+ </node>
134
+ </xsl:if>
135
+ </xsl:for-each>
136
+ </node>
137
+ </xsl:for-each>
138
+ </xsl:template>
139
+
140
+
141
+ <!-- Aos timed node creation: Data childs -->
142
+ <xsl:template name="makeDataSubtrees">
143
+ <xsl:param name="instances"/>
144
+ <xsl:for-each select="1 to xs:integer(1+(($instances - 1) div 1000))">
145
+ <xsl:variable name="group" select="."/>
146
+ <node>
147
+ <xsl:attribute name="NAME"><xsl:value-of select="concat('group_',.)"/></xsl:attribute>
148
+ <xsl:for-each select="1 to 1000">
149
+ <xsl:variable name="item" select="($group - 1) * 1000 + ."/>
150
+ <xsl:if test="$item &lt;= $instances">
151
+ <member>
152
+ <xsl:attribute name="NAME"><xsl:value-of select="concat('item_',$item)"/></xsl:attribute>
153
+ <xsl:attribute name="USAGE">NUMERIC</xsl:attribute>
154
+ </member>
155
+ </xsl:if>
156
+ </xsl:for-each>
157
+ </node>
158
+ </xsl:for-each>
159
+ </xsl:template>
160
+
161
+ </xsl:stylesheet>