Skip to content

Commit 7bf237b

Browse files
committed
rationalise cross-ref indexing in charts
1 parent 0fba3a4 commit 7bf237b

File tree

7 files changed

+73
-129
lines changed

7 files changed

+73
-129
lines changed

src/ansys/systemcoupling/core/charts/chart_datatypes.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ class TransferSeriesInfo:
4545
4646
Attributes
4747
----------
48-
data_index : int
49-
This is used by the data source processor to associate this information (likely
50-
obtained from heading or other metadata) with the correct data series.
51-
It indexes into the full list of series associated with a given interface.
5248
series_type : SeriesType
5349
The type of line series.
5450
transfer_display_name : str
@@ -62,22 +58,20 @@ class TransferSeriesInfo:
6258
participant_display_name : str, optional
6359
The display name of the participant. This is required for transfer value series
6460
but not for convergence series.
65-
line_suffixes: list[str]
66-
This should always be empty for convergence series. For transfer value series,
67-
it should contain the suffixes for any component series that exist. That is,
68-
suffixes for complex components, "real" or "imag", and suffixes for vector
69-
components, "x", "y", "z", or a combination of complex and vector component
70-
types. The data indexes for individual components of the transfer are assumed
71-
to be contiguous from ``data_index``.
61+
component_suffix: str, optional
62+
The suffix for this component series, if applicable. This is only needed for
63+
transfer value series that have multiple components, such as complex or vector
64+
values, and is otherwise None. Suffixes for complex components are "real" and
65+
"imag", and suffixes for vector components are "x", "y", and "z". A combination
66+
of complex and vector suffixes is possible, such as "y real" and "x imag".
7267
"""
7368

74-
data_index: int
7569
series_type: SeriesType
7670
transfer_display_name: str
7771
disambiguation_index: int
7872
# Remainder for non-CONVERGENCE series only
7973
participant_display_name: Optional[str] = None
80-
line_suffixes: list[str] = field(default_factory=list)
74+
component_suffix: Optional[str] = None
8175

8276

8377
@dataclass
@@ -115,9 +109,6 @@ class SeriesData:
115109
transfer_index : int
116110
Index of the ``TransferSeriesInfo`` metadata for this series within the
117111
``InterfaceInfo`` for the interface this series is associated with.
118-
component_index : int, optional
119-
The component index if this series is one of a set of complex and/or
120-
vector components of the transfer. Otherwise is ``None``.
121112
start_index : int, optional
122113
The starting iteration of the ``data`` field. This defaults to 0 and
123114
only needs to be set to a different value if incremental data, such
@@ -128,10 +119,7 @@ class SeriesData:
128119
"""
129120

130121
transfer_index: int # Index into transfer_info of associated InterfaceInfo
131-
component_index: Optional[int] = None # Component index if applicable
132-
133122
start_index: int = 0 # Use when providing incremental data
134-
135123
data: list[float] = field(default_factory=list)
136124

137125

src/ansys/systemcoupling/core/charts/csv_chartdata.py

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,8 @@ def read_new_data(self):
157157

158158
def _init_data(self):
159159
series_data_list: list[SeriesData] = []
160-
for i, trans_info in enumerate(self._metadata.transfer_info):
161-
if not trans_info.line_suffixes:
162-
series_data_list.append(SeriesData(transfer_index=i))
163-
else:
164-
for j in range(len(trans_info.line_suffixes)):
165-
series_data_list.append(
166-
SeriesData(transfer_index=i, component_index=j)
167-
)
160+
for i in range(len(self._metadata.transfer_info)):
161+
series_data_list.append(SeriesData(transfer_index=i))
168162
self._data = InterfaceSeriesData(self._metadata, series=series_data_list)
169163

170164
def _process_curr_data(self):
@@ -245,7 +239,6 @@ def parse_csv_metadata(interface_name: str, headers: list[str]) -> InterfaceInfo
245239
data_index = i - start_index
246240
series_type, intf_or_part_disp_name, trans_disp_name = _parse_header(header)
247241
if series_type == SeriesType.CONVERGENCE:
248-
prev_part_name = ""
249242

250243
# If there are no convergence headings, transfer_disambig will
251244
# remain unpopulated. In this case, assume for now that there
@@ -267,7 +260,6 @@ def parse_csv_metadata(interface_name: str, headers: list[str]) -> InterfaceInfo
267260
assert_(intf_info.display_name == "", "display_name should be empty")
268261
intf_info.display_name = intf_disp_name
269262
series_info = TransferSeriesInfo(
270-
data_index=data_index,
271263
series_type=series_type,
272264
transfer_display_name=trans_disp_name,
273265
# get(..., 0) for case where transfer_disambig empty (see note above)
@@ -276,39 +268,13 @@ def parse_csv_metadata(interface_name: str, headers: list[str]) -> InterfaceInfo
276268
intf_info.transfer_info.append(series_info)
277269
else:
278270
part_disp_name = intf_or_part_disp_name
279-
suffix = _parse_suffix(header, part_disp_name)
280-
if suffix:
281-
if prev_part_name != part_disp_name:
282-
# Start a new series info for a group of components
283-
# Thus if there are 3 components, say, they will
284-
# implicitly have data indexes, data_index, data_index+1,
285-
# data_index+2, and the next TransferSeriesInfo will
286-
# have index data_index+3.
287-
intf_info.transfer_info.append(
288-
TransferSeriesInfo(
289-
data_index=data_index,
290-
series_type=series_type,
291-
transfer_display_name=trans_disp_name,
292-
disambiguation_index=transfer_disambig.get(
293-
trans_disp_name, 0
294-
),
295-
participant_display_name=part_disp_name,
296-
line_suffixes=[suffix],
297-
)
298-
)
299-
prev_part_name = part_disp_name
300-
else:
301-
# Append component info to current series info
302-
intf_info.transfer_info[-1].line_suffixes.append(suffix)
303-
else:
304-
prev_part_name = ""
305-
intf_info.transfer_info.append(
306-
TransferSeriesInfo(
307-
data_index=data_index,
308-
series_type=series_type,
309-
transfer_display_name=trans_disp_name,
310-
disambiguation_index=transfer_disambig.get(trans_disp_name, 0),
311-
participant_display_name=part_disp_name,
312-
)
271+
intf_info.transfer_info.append(
272+
TransferSeriesInfo(
273+
series_type=series_type,
274+
transfer_display_name=trans_disp_name,
275+
disambiguation_index=transfer_disambig.get(trans_disp_name, 0),
276+
participant_display_name=part_disp_name,
277+
component_suffix=_parse_suffix(header, part_disp_name) or None,
313278
)
279+
)
314280
return intf_info

src/ansys/systemcoupling/core/charts/live_csv_datasource.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def read_data(self):
7070

7171
line_series_incr = SeriesData(
7272
line_series.transfer_index,
73-
line_series.component_index,
7473
start_index=start_index,
7574
data=line_series.data[start_index:],
7675
)

src/ansys/systemcoupling/core/charts/plot_functions.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ def cancel(self) -> None: ...
5454
def read_data(self) -> None: ...
5555

5656

57-
def _make_csv_data_reader(interface_name: str) -> ChartDataReader:
58-
return CsvChartDataReader(interface_name)
59-
60-
6157
def _create_and_show_impl(spec: PlotSpec, reader: ChartDataReader) -> Plotter:
6258
if len(spec.interfaces) != 1:
6359
raise ValueError("Plots currently only support one interface")
@@ -88,7 +84,7 @@ def create_and_show_plot_csv(spec: PlotSpec, csv_list: list[str]) -> Plotter:
8884
raise ValueError(
8985
"'csv_list' should have length equal to the number of interfaces"
9086
)
91-
reader = _make_csv_data_reader(spec.interfaces[0].name)
87+
reader = CsvChartDataReader(spec.interfaces[0].name, csv_list[0])
9288
return _create_and_show_impl(spec, reader)
9389

9490

src/ansys/systemcoupling/core/charts/plotdefinition_manager.py

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def set_metadata(self, metadata: InterfaceInfo):
240240
# The integer is the "disambiguation_index" the transfer's TransferSeriesInfo.
241241
transfer_value_line_count: dict[tuple[str, int], int] = {}
242242

243-
for transfer in metadata.transfer_info:
243+
for data_index, transfer in enumerate(metadata.transfer_info):
244244
transfer_key = (
245245
transfer.transfer_display_name,
246246
transfer.disambiguation_index,
@@ -257,7 +257,7 @@ def set_metadata(self, metadata: InterfaceInfo):
257257
] = ""
258258

259259
if conv_subplot := self._conv_subplots.get(interface_name):
260-
data_index_map[transfer.data_index] = (conv_subplot, iconv)
260+
data_index_map[data_index] = (conv_subplot, iconv)
261261
# Add a new series list to y_data, and label to series_labels
262262
# Both will be at position iconv of respective lists
263263
# conv_subplot.y_data.append([])
@@ -277,28 +277,17 @@ def set_metadata(self, metadata: InterfaceInfo):
277277
"<VALUETYPE>", value_type
278278
)
279279
itransval = transfer_value_line_count.get(transfer_key, 0)
280-
if not transfer.line_suffixes:
281-
data_index_map[transfer.data_index] = (
282-
transfer_value_subplot,
283-
itransval,
284-
)
285-
transfer_value_subplot.series_labels.append(
286-
transfer.participant_display_name
287-
)
288-
itransval += 1
289-
transfer_value_line_count[transfer_key] = itransval
290-
else:
291-
for i, suffix in enumerate(transfer.line_suffixes):
292-
data_index_map[transfer.data_index + i] = (
293-
transfer_value_subplot,
294-
itransval + i,
295-
)
296-
transfer_value_subplot.series_labels.append(
297-
transfer.participant_display_name + suffix
298-
)
299-
transfer_value_line_count[transfer_key] = itransval + len(
300-
transfer.line_suffixes
301-
)
280+
label = transfer.participant_display_name
281+
if transfer.component_suffix:
282+
label += transfer.component_suffix
283+
284+
data_index_map[data_index] = (
285+
transfer_value_subplot,
286+
itransval,
287+
)
288+
transfer_value_subplot.series_labels.append(label)
289+
itransval += 1
290+
transfer_value_line_count[transfer_key] = itransval
302291

303292
# This will be what allows us to update subplot data as new data received
304293
self._data_index_map[interface_name] = data_index_map

src/ansys/systemcoupling/core/charts/plotter.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,8 @@ def update_line_series(self, series_data: SeriesData):
204204
"Attempt to add series data to plot before metadata provided."
205205
)
206206

207-
trans = self._metadata.transfer_info[series_data.transfer_index]
208-
offset = (
209-
series_data.component_index
210-
if series_data.component_index is not None
211-
else 0
212-
)
213207
subplot_defn, subplot_line_index = self._mgr.subplot_for_data_index(
214-
self._metadata.name, trans.data_index + offset
208+
self._metadata.name, series_data.transfer_index
215209
)
216210
if subplot_defn is None:
217211
# This can happen if the list of plots being show is filtered.

tests/charts/test_csv_chartdata.py

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -105,43 +105,37 @@ def test_parse_header():
105105
assert info0.transfer_display_name == "input"
106106
assert info0.series_type == SeriesType.CONVERGENCE
107107
assert info0.participant_display_name is None
108-
assert info0.data_index == 0
109-
assert info0.line_suffixes == []
108+
assert info0.component_suffix is None
110109

111110
info1 = info.transfer_info[1]
112111
assert info1.transfer_display_name == "input"
113112
assert info1.series_type == SeriesType.WEIGHTED_AVERAGE
114113
assert info1.participant_display_name == "rootFind"
115-
assert info1.data_index == 1
116-
assert info1.line_suffixes == []
114+
assert info1.component_suffix is None
117115

118116
info2 = info.transfer_info[2]
119117
assert info2.transfer_display_name == "input"
120118
assert info2.series_type == SeriesType.WEIGHTED_AVERAGE
121119
assert info2.participant_display_name == "rootFind 2"
122-
assert info2.data_index == 2
123-
assert info2.line_suffixes == []
120+
assert info2.component_suffix is None
124121

125122
info3 = info.transfer_info[3]
126123
assert info3.transfer_display_name == "input2"
127124
assert info3.series_type == SeriesType.CONVERGENCE
128125
assert info3.participant_display_name is None
129-
assert info3.data_index == 3
130-
assert info3.line_suffixes == []
126+
assert info3.component_suffix is None
131127

132128
info4 = info.transfer_info[4]
133129
assert info4.transfer_display_name == "input2"
134130
assert info4.series_type == SeriesType.WEIGHTED_AVERAGE
135131
assert info4.participant_display_name == "rootFind 2"
136-
assert info4.data_index == 4
137-
assert info4.line_suffixes == []
132+
assert info4.component_suffix is None
138133

139134
info5 = info.transfer_info[5]
140135
assert info5.transfer_display_name == "input2"
141136
assert info5.series_type == SeriesType.WEIGHTED_AVERAGE
142137
assert info5.participant_display_name == "rootFind"
143-
assert info5.data_index == 5
144-
assert info5.line_suffixes == []
138+
assert info5.component_suffix is None
145139

146140

147141
def test_parse_header_components():
@@ -165,49 +159,67 @@ def test_parse_header_components():
165159

166160
assert info.display_name == "Intf-1"
167161
assert info.is_transient
168-
assert len(info.transfer_info) == 6
162+
assert len(info.transfer_info) == 10
169163

170164
info0 = info.transfer_info[0]
171165
assert info0.transfer_display_name == "input"
172166
assert info0.series_type == SeriesType.CONVERGENCE
173167
assert info0.participant_display_name is None
174-
assert info0.data_index == 0
175-
assert info0.line_suffixes == []
168+
assert info0.component_suffix is None
176169

177170
info1 = info.transfer_info[1]
178171
assert info1.transfer_display_name == "input"
179172
assert info1.series_type == SeriesType.SUM
180173
assert info1.participant_display_name == "part1"
181-
assert info1.data_index == 1
182-
assert info1.line_suffixes == ["x", "y", "z"]
174+
assert info1.component_suffix == "x"
183175

184-
info2 = info.transfer_info[2]
176+
info1 = info.transfer_info[2]
177+
assert info1.transfer_display_name == "input"
178+
assert info1.series_type == SeriesType.SUM
179+
assert info1.participant_display_name == "part1"
180+
assert info1.component_suffix == "y"
181+
182+
info1 = info.transfer_info[3]
183+
assert info1.transfer_display_name == "input"
184+
assert info1.series_type == SeriesType.SUM
185+
assert info1.participant_display_name == "part1"
186+
assert info1.component_suffix == "z"
187+
188+
info2 = info.transfer_info[4]
185189
assert info2.transfer_display_name == "input"
186190
assert info2.series_type == SeriesType.SUM
187191
assert info2.participant_display_name == "part2"
188-
assert info2.data_index == 4
189-
assert info2.line_suffixes == ["x", "y", "z"]
192+
assert info2.component_suffix == "x"
190193

191-
info3 = info.transfer_info[3]
194+
info2 = info.transfer_info[5]
195+
assert info2.transfer_display_name == "input"
196+
assert info2.series_type == SeriesType.SUM
197+
assert info2.participant_display_name == "part2"
198+
assert info2.component_suffix == "y"
199+
200+
info2 = info.transfer_info[6]
201+
assert info2.transfer_display_name == "input"
202+
assert info2.series_type == SeriesType.SUM
203+
assert info2.participant_display_name == "part2"
204+
assert info2.component_suffix == "z"
205+
206+
info3 = info.transfer_info[7]
192207
assert info3.transfer_display_name == "input2"
193208
assert info3.series_type == SeriesType.CONVERGENCE
194209
assert info3.participant_display_name is None
195-
assert info3.data_index == 7
196-
assert info3.line_suffixes == []
210+
assert info3.component_suffix is None
197211

198-
info4 = info.transfer_info[4]
212+
info4 = info.transfer_info[8]
199213
assert info4.transfer_display_name == "input2"
200214
assert info4.series_type == SeriesType.SUM
201215
assert info4.participant_display_name == "part2"
202-
assert info4.data_index == 8
203-
assert info4.line_suffixes == []
216+
assert info4.component_suffix is None
204217

205-
info5 = info.transfer_info[5]
218+
info5 = info.transfer_info[9]
206219
assert info5.transfer_display_name == "input2"
207220
assert info5.series_type == SeriesType.SUM
208221
assert info5.participant_display_name == "part1"
209-
assert info5.data_index == 9
210-
assert info5.line_suffixes == []
222+
assert info5.component_suffix is None
211223

212224

213225
def test_timestep(data1):

0 commit comments

Comments
 (0)