Skip to content

Commit 92faac1

Browse files
committed
Protected time series
1 parent be68fe7 commit 92faac1

File tree

3 files changed

+45
-37
lines changed

3 files changed

+45
-37
lines changed

pypsdm/io/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def df_to_csv(
125125
mkdirs=False,
126126
delimiter: str = ",",
127127
index_label="uuid",
128-
datetime_pattern=DateTimePattern.UTC_TIME_PATTERN,
128+
datetime_pattern=DateTimePattern.UTC_TIME_PATTERN_EXTENDED,
129129
):
130130
df = df.copy(deep=True)
131131
if isinstance(path, Path):

pypsdm/models/primary_data.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ def __hash__(self):
3434

3535
@dataclass
3636
class PrimaryData:
37-
# ts_uuid -> ts
38-
time_series: ComplexPowerDict[TimeSeriesKey]
37+
# ts_key -> ts
38+
_time_series: ComplexPowerDict[TimeSeriesKey]
3939
# participant_uuid -> ts_uuid
40-
participant_mapping: dict[str, str]
40+
_participant_mapping: dict[str, str]
4141

4242
def __init__(
4343
self, time_series: "ComplexPowerDict", participant_mapping: dict[str, str]
4444
):
45-
self.time_series = time_series
46-
self.participant_mapping = participant_mapping
45+
self._time_series = time_series
46+
self._participant_mapping = participant_mapping
4747

4848
def __eq__(self, other):
4949
try:
@@ -53,46 +53,52 @@ def __eq__(self, other):
5353
return False
5454

5555
def __len__(self):
56-
return len(self.time_series)
56+
return len(self._time_series)
5757

5858
def __contains__(self, uuid):
59-
return uuid in self.time_series or uuid in self.participant_mapping
59+
return uuid in self._time_series or uuid in self._participant_mapping
6060

6161
def __getitem__(self, get: str | TimeSeriesKey) -> ComplexPower:
6262
match get:
6363
case str():
6464
get_key = TimeSeriesKey(get, None)
65-
if get in self.participant_mapping:
66-
ts_uuid = self.participant_mapping[get]
65+
if get in self._participant_mapping:
66+
ts_uuid = self._participant_mapping[get]
6767
key = TimeSeriesKey(ts_uuid, None)
68-
return self.time_series[key]
69-
elif get_key in self.time_series:
70-
return self.time_series[get_key]
68+
return self._time_series[key]
69+
elif get_key in self._time_series:
70+
return self._time_series[get_key]
7171
else:
7272
raise KeyError(
7373
f"{get} neither a valid time series nor a participant uuid."
7474
)
7575
case TimeSeriesKey():
76-
return self.time_series[get]
76+
return self._time_series[get]
7777
case _:
7878
raise ValueError(
7979
"Only str uuid of either time series or participant or TimeSeriesKey of time series are allowed as key for PrimaryData."
8080
)
8181

8282
def p(self, ffill=True):
83-
return self.time_series.p(ffill)
83+
return self._time_series.p(ffill)
8484

8585
def q(self, ffill=True):
86-
return self.time_series.q(ffill)
86+
return self._time_series.q(ffill)
8787

8888
def p_sum(self) -> Series:
89-
return self.time_series.p_sum()
89+
return self._time_series.p_sum()
9090

9191
def q_sum(self):
92-
return self.time_series.q_sum()
92+
return self._time_series.q_sum()
9393

9494
def sum(self) -> ComplexPower:
95-
return self.time_series.sum()
95+
return self._time_series.sum()
96+
97+
def add_time_series(
98+
self, ts_key: TimeSeriesKey, ts: ComplexPower, participant: str
99+
):
100+
self._time_series[ts_key] = ts
101+
self._participant_mapping[participant] = ts_key.ts_uuid
96102

97103
def get_for_participants(self, participants) -> list[ComplexPower]:
98104
time_series = []
@@ -106,9 +112,9 @@ def filter_by_participants(
106112
self, participants: list[str], skip_missing: bool = False
107113
):
108114
if skip_missing:
109-
participants = [p for p in participants if p in self.participant_mapping]
115+
participants = [p for p in participants if p in self._participant_mapping]
110116
try:
111-
pm = {p: self.participant_mapping[p] for p in participants}
117+
pm = {p: self._participant_mapping[p] for p in participants}
112118
ts = ComplexPowerDict({ts_uuid: self[ts_uuid] for ts_uuid in pm.values()}) # type: ignore
113119
return PrimaryData(ts, pm)
114120
except KeyError as e:
@@ -118,27 +124,27 @@ def filter_by_participants(
118124
) from e
119125

120126
def get_for_participant(self, participant: str) -> ComplexPower | None:
121-
ts_uuid = self.participant_mapping.get(participant)
127+
ts_uuid = self._participant_mapping.get(participant)
122128
if ts_uuid:
123129
return self[ts_uuid] # type: ignore
124130
else:
125131
return None
126132

127133
def filter_by_date_time(self, time: Union[datetime, list[datetime]]):
128-
ts = self.time_series.filter_by_date_time(time)
129-
return PrimaryData(ts, self.participant_mapping)
134+
ts = self._time_series.filter_by_date_time(time)
135+
return PrimaryData(ts, self._participant_mapping)
130136

131137
def interval(self, start: datetime, end: datetime):
132-
ts = self.time_series.interval(start, end)
133-
return PrimaryData(ts, self.participant_mapping)
138+
ts = self._time_series.interval(start, end)
139+
return PrimaryData(ts, self._participant_mapping)
134140

135141
def to_csv(self, path: str, mkdirs=False, delimiter=","):
136142
write_ts = partial(PrimaryData._write_ts_df, path, mkdirs, delimiter)
137143

138144
with concurrent.futures.ProcessPoolExecutor() as executor:
139145
futures = [
140146
executor.submit(write_ts, ts, key)
141-
for key, ts in list(self.time_series.items())
147+
for key, ts in list(self._time_series.items())
142148
]
143149

144150
for future in concurrent.futures.as_completed(futures):
@@ -147,11 +153,11 @@ def to_csv(self, path: str, mkdirs=False, delimiter=","):
147153
raise maybe_exception
148154

149155
# write mapping data
150-
index = [str(uuid.uuid4()) for _ in range(len(self.participant_mapping))]
156+
index = [str(uuid.uuid4()) for _ in range(len(self._participant_mapping))]
151157
mapping_data = pd.DataFrame(
152158
{
153-
"participant": self.participant_mapping.keys(),
154-
"time_series": self.participant_mapping.values(),
159+
"participant": self._participant_mapping.keys(),
160+
"time_series": self._participant_mapping.values(),
155161
},
156162
index=index,
157163
)
@@ -200,9 +206,11 @@ def compare(self, other):
200206
errors = []
201207

202208
# Compare participant mapping
203-
participant_ts_self = set([(p, t) for p, t in self.participant_mapping.items()])
209+
participant_ts_self = set(
210+
[(p, t) for p, t in self._participant_mapping.items()]
211+
)
204212
participant_ts_other = set(
205-
[(p, t) for p, t in other.participant_mapping.items()]
213+
[(p, t) for p, t in other._participant_mapping.items()]
206214
)
207215
mapping_differences = participant_ts_self.symmetric_difference(
208216
participant_ts_other
@@ -217,7 +225,7 @@ def compare(self, other):
217225

218226
# Compare time series
219227
try:
220-
self.time_series.compare(other.time_series)
228+
self._time_series.compare(other._time_series)
221229
except ComparisonError as e:
222230
errors.extend(e.differences)
223231

tests/models/test_primary_data.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ def test_compare():
7676
pd = get_primary_data()
7777
pd2 = get_primary_data()
7878
pd.compare(pd2)
79-
pd2.time_series[TimeSeriesKey("a", TimeSeriesEnum.P_TIME_SERIES)] = get_sample_data(
80-
q=False
79+
pd2._time_series[TimeSeriesKey("a", TimeSeriesEnum.P_TIME_SERIES)] = (
80+
get_sample_data(q=False)
8181
)
8282
try:
8383
pd.compare(pd2)
@@ -89,11 +89,11 @@ def test_compare():
8989
def test_to_csv(tmp_path):
9090
pd = get_primary_data()
9191
uuid_ts = {}
92-
for key, ts in pd.time_series.items():
92+
for key, ts in pd._time_series.items():
9393
ts_uuid = uuid.uuid4()
9494
key = TimeSeriesKey(str(ts_uuid), key.ts_type)
9595
uuid_ts[key] = ts
96-
pd.time_series = ComplexPowerDict(uuid_ts)
96+
pd._time_series = ComplexPowerDict(uuid_ts)
9797
pd.to_csv(tmp_path)
9898
pd2 = PrimaryData.from_csv(tmp_path)
9999
assert pd == pd2

0 commit comments

Comments
 (0)