domainiac 1.0.0__py3-none-any.whl → 2.0.0__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.
- domainiac/__init__.py +8 -1
- domainiac/managers/__init__.py +1 -0
- domainiac/managers/masterdata_manager.py +4 -1
- domainiac/managers/nwp_manager.py +298 -0
- domainiac/managers/plant_manager.py +46 -7
- domainiac/managers/unit_manager.py +10 -9
- domainiac/modeling/__init__.py +2 -0
- domainiac/modeling/nwp.py +27 -0
- domainiac/modeling/plant.py +58 -0
- {domainiac-1.0.0.dist-info → domainiac-2.0.0.dist-info}/METADATA +3 -2
- domainiac-2.0.0.dist-info/RECORD +16 -0
- {domainiac-1.0.0.dist-info → domainiac-2.0.0.dist-info}/WHEEL +1 -1
- domainiac-1.0.0.dist-info/RECORD +0 -12
domainiac/__init__.py
CHANGED
@@ -1 +1,8 @@
|
|
1
|
-
from .managers import
|
1
|
+
from .managers import (
|
2
|
+
MeteringManager,
|
3
|
+
NWPManager,
|
4
|
+
PlantManager,
|
5
|
+
ResourceManager,
|
6
|
+
UnitManager,
|
7
|
+
)
|
8
|
+
from .modeling import Coordinate, Group, Neighborhood, NWPParameter, NWPProvider, Plant
|
domainiac/managers/__init__.py
CHANGED
@@ -59,7 +59,10 @@ class MasterdataManager:
|
|
59
59
|
|
60
60
|
# Apply the filters
|
61
61
|
for column, value in filters.items():
|
62
|
-
|
62
|
+
if isinstance(value, list):
|
63
|
+
df = df[df[column].isin(value)].reset_index()
|
64
|
+
else:
|
65
|
+
df = df[df[column] == value].reset_index()
|
63
66
|
|
64
67
|
for column in columns:
|
65
68
|
if column not in df.columns:
|
@@ -0,0 +1,298 @@
|
|
1
|
+
import datamazing.pandas as pdz
|
2
|
+
import numpy as np
|
3
|
+
import pandas as pd
|
4
|
+
from sklearn.neighbors import KDTree
|
5
|
+
|
6
|
+
from ..modeling.nwp import Coordinate, Neighborhood, NWPParameter, NWPProvider
|
7
|
+
|
8
|
+
|
9
|
+
class NWPManager:
|
10
|
+
"""
|
11
|
+
Contains all logic concerning NWP data.
|
12
|
+
This includes:
|
13
|
+
- Getting NWP data
|
14
|
+
- Getting average NWP data
|
15
|
+
- Finding closest NWP coordinates
|
16
|
+
"""
|
17
|
+
|
18
|
+
NWP_INTERPOLATION_METHODS = {
|
19
|
+
# Wind and temperature are estimates
|
20
|
+
# of the instantaneous value at time t.
|
21
|
+
# We use linear interpolation.
|
22
|
+
NWPParameter.WIND: ("linear", "instantanous"),
|
23
|
+
NWPParameter.TEMPERATURE: ("linear", "instantanous"),
|
24
|
+
# solar is an estimate of the average value
|
25
|
+
# in the interval [t-1, t].
|
26
|
+
# We use PCHIP interpolation to ensure
|
27
|
+
# a smooth shape and non-negative values
|
28
|
+
# (https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.PchipInterpolator.html)
|
29
|
+
NWPParameter.SOLAR: ("pchip", "interval_average"),
|
30
|
+
}
|
31
|
+
|
32
|
+
NWP_RESOLUTIONS = {
|
33
|
+
(NWPProvider.ECMWF, NWPParameter.WIND): pd.Timedelta("PT3H"),
|
34
|
+
(NWPProvider.ECMWF, NWPParameter.TEMPERATURE): pd.Timedelta("PT3H"),
|
35
|
+
(NWPProvider.ECMWF, NWPParameter.SOLAR): pd.Timedelta("PT1H"),
|
36
|
+
(NWPProvider.DMI, NWPParameter.WIND): pd.Timedelta("PT1H"),
|
37
|
+
(NWPProvider.DMI, NWPParameter.TEMPERATURE): pd.Timedelta("PT1H"),
|
38
|
+
(NWPProvider.DMI, NWPParameter.SOLAR): pd.Timedelta("PT1H"),
|
39
|
+
(NWPProvider.CONWX, NWPParameter.WIND): pd.Timedelta("PT1H"),
|
40
|
+
(NWPProvider.CONWX, NWPParameter.TEMPERATURE): pd.Timedelta("PT1H"),
|
41
|
+
(NWPProvider.CONWX, NWPParameter.SOLAR): pd.Timedelta("PT1H"),
|
42
|
+
}
|
43
|
+
|
44
|
+
def __init__(
|
45
|
+
self,
|
46
|
+
db: pdz.Database,
|
47
|
+
time_interval: pdz.TimeInterval,
|
48
|
+
resolution: pd.Timedelta,
|
49
|
+
):
|
50
|
+
self.db = db
|
51
|
+
self.time_interval = time_interval
|
52
|
+
self.resolution = resolution
|
53
|
+
|
54
|
+
self._nwp_coordinates_kd_tree = dict()
|
55
|
+
self._nwp_table_name_prefix = "forecastNwp"
|
56
|
+
|
57
|
+
@classmethod
|
58
|
+
def get_nwp_resolution(
|
59
|
+
cls, provider: NWPProvider, parameter: NWPParameter
|
60
|
+
) -> pd.Timedelta:
|
61
|
+
"""
|
62
|
+
Get the resolution of the NWP parameter.
|
63
|
+
"""
|
64
|
+
return cls.NWP_RESOLUTIONS[(provider, parameter)]
|
65
|
+
|
66
|
+
@classmethod
|
67
|
+
def get_nwp_interpolation_method(cls, parameter: NWPParameter) -> tuple[str, str]:
|
68
|
+
"""
|
69
|
+
Get the interpolation method and temporal aggregation for the NWP parameter.
|
70
|
+
"""
|
71
|
+
return cls.NWP_INTERPOLATION_METHODS[parameter]
|
72
|
+
|
73
|
+
@staticmethod
|
74
|
+
def calculate_wind_speed_from_vectors(u: pd.Series, v: pd.Series) -> pd.Series:
|
75
|
+
return np.sqrt(u**2 + v**2)
|
76
|
+
|
77
|
+
def _get_table_name(
|
78
|
+
self,
|
79
|
+
provider: NWPProvider,
|
80
|
+
parameter: NWPParameter,
|
81
|
+
) -> str:
|
82
|
+
"""
|
83
|
+
Get the table name for a given NWP parameter.
|
84
|
+
"""
|
85
|
+
return self._nwp_table_name_prefix + provider.value + parameter.value
|
86
|
+
|
87
|
+
def _get_kd_tree(self, provider: NWPProvider, parameter: NWPParameter) -> KDTree:
|
88
|
+
"""
|
89
|
+
Create a KDTree from the coordinates from the nwp parameter table.
|
90
|
+
This is done lazily, so that the KDTree is only created once.
|
91
|
+
"""
|
92
|
+
key = (provider, parameter)
|
93
|
+
if key not in self._nwp_coordinates_kd_tree:
|
94
|
+
# Base KDTree on one hour of data
|
95
|
+
query_time_interval = pdz.TimeInterval(
|
96
|
+
self.time_interval.left, self.time_interval.left + pd.Timedelta("PT1H")
|
97
|
+
)
|
98
|
+
|
99
|
+
df = self.db.query(
|
100
|
+
table_name=self._get_table_name(provider, parameter),
|
101
|
+
time_interval=query_time_interval,
|
102
|
+
)
|
103
|
+
|
104
|
+
self._nwp_coordinates_kd_tree[key] = dict()
|
105
|
+
|
106
|
+
# Make KDTree for altitude
|
107
|
+
self._nwp_coordinates_kd_tree[key]["altitude"] = KDTree(
|
108
|
+
df[["altitude_m"]].drop_duplicates()
|
109
|
+
)
|
110
|
+
|
111
|
+
# Make KDTree for latitude and longitude
|
112
|
+
self._nwp_coordinates_kd_tree[key]["plane"] = KDTree(
|
113
|
+
df[["latitude", "longitude"]].drop_duplicates()
|
114
|
+
)
|
115
|
+
|
116
|
+
return self._nwp_coordinates_kd_tree[key]
|
117
|
+
|
118
|
+
def get_nwp_neighbors(
|
119
|
+
self,
|
120
|
+
provider: NWPProvider,
|
121
|
+
parameter: NWPParameter,
|
122
|
+
neighborhood: Neighborhood,
|
123
|
+
) -> list[Coordinate]:
|
124
|
+
"""
|
125
|
+
Find n closest coordinates based on the NWP parameter table.
|
126
|
+
|
127
|
+
Note: This assumes that coordinates does not change over time.
|
128
|
+
"""
|
129
|
+
kd_tree = self._get_kd_tree(provider, parameter)
|
130
|
+
|
131
|
+
altitude_indices = kd_tree["altitude"].query(
|
132
|
+
np.c_[neighborhood.coordinate.altitude],
|
133
|
+
k=1,
|
134
|
+
return_distance=False,
|
135
|
+
)
|
136
|
+
# TODO: Allow this to handle multiple altitudes
|
137
|
+
nearest_altitude = kd_tree["altitude"].data.base[altitude_indices][0][0][0]
|
138
|
+
|
139
|
+
plane_indices = kd_tree["plane"].query(
|
140
|
+
np.c_[neighborhood.coordinate.latitude, neighborhood.coordinate.longitude],
|
141
|
+
k=neighborhood.num_neighbors,
|
142
|
+
return_distance=False,
|
143
|
+
)
|
144
|
+
nearest_planes = kd_tree["plane"].data.base[plane_indices][0]
|
145
|
+
|
146
|
+
coordinates = [
|
147
|
+
Coordinate(latitude=plane[0], longitude=plane[1], altitude=nearest_altitude)
|
148
|
+
for plane in nearest_planes
|
149
|
+
]
|
150
|
+
|
151
|
+
return coordinates
|
152
|
+
|
153
|
+
def _get_nwp_parameter(
|
154
|
+
self,
|
155
|
+
provider: NWPProvider,
|
156
|
+
parameter: NWPParameter,
|
157
|
+
coordinate: Coordinate,
|
158
|
+
) -> pd.DataFrame:
|
159
|
+
"""
|
160
|
+
Get NWP data for a given parameter, coordinate and altitude.
|
161
|
+
"""
|
162
|
+
table = self._get_table_name(provider, parameter)
|
163
|
+
|
164
|
+
filters = {
|
165
|
+
"latitude": coordinate.latitude,
|
166
|
+
"longitude": coordinate.longitude,
|
167
|
+
"altitude_m": coordinate.altitude,
|
168
|
+
}
|
169
|
+
|
170
|
+
# Pad time interval with one resolution
|
171
|
+
# This is needed for the interpolation to work as we shift back in time
|
172
|
+
nwp_resolution = self.get_nwp_resolution(provider, parameter)
|
173
|
+
|
174
|
+
# Pad time interval to make sure interpolation is possible
|
175
|
+
padded_time_interval = pdz.TimeInterval(
|
176
|
+
self.time_interval.left - (nwp_resolution / 2),
|
177
|
+
self.time_interval.right + (nwp_resolution * 1.5),
|
178
|
+
)
|
179
|
+
|
180
|
+
df = self.db.query(table, padded_time_interval, filters=filters)
|
181
|
+
|
182
|
+
df = df.drop(
|
183
|
+
columns=[
|
184
|
+
"created_time_utc",
|
185
|
+
"altitude_m",
|
186
|
+
"longitude",
|
187
|
+
"latitude",
|
188
|
+
]
|
189
|
+
)
|
190
|
+
|
191
|
+
return df
|
192
|
+
|
193
|
+
def _get_interpolated_nwp_parameter(
|
194
|
+
self,
|
195
|
+
provider: NWPProvider,
|
196
|
+
parameter: NWPParameter,
|
197
|
+
coordinate: Coordinate,
|
198
|
+
):
|
199
|
+
"""
|
200
|
+
Get NWP data for a given parameter, coordinate and altitude,
|
201
|
+
using the proper interpolation technique.
|
202
|
+
"""
|
203
|
+
df = self._get_nwp_parameter(provider, parameter, coordinate)
|
204
|
+
|
205
|
+
nwp_resolution = self.get_nwp_resolution(provider, parameter)
|
206
|
+
interpolation_method, temporal_aggregation = self.get_nwp_interpolation_method(
|
207
|
+
parameter
|
208
|
+
)
|
209
|
+
|
210
|
+
match temporal_aggregation:
|
211
|
+
# if the parameter is an interval average,
|
212
|
+
# it makes best sense to interpolate from
|
213
|
+
# midpoint to midpoint. Otherwise, we just
|
214
|
+
# interpolate regularly.
|
215
|
+
case "interval_average":
|
216
|
+
shift = -1 / 2
|
217
|
+
case "instantanous":
|
218
|
+
shift = 0
|
219
|
+
|
220
|
+
df_shifted = pdz.shift_time(df, on="time_utc", period=shift * nwp_resolution)
|
221
|
+
|
222
|
+
# Interpolate
|
223
|
+
df_resampled = pdz.resample(
|
224
|
+
df_shifted, on="time_utc", resolution=self.resolution / 2
|
225
|
+
).interpolate(interpolation_method)
|
226
|
+
|
227
|
+
# Shift back time, so that the output time series again represents
|
228
|
+
# the value by the endpoint.
|
229
|
+
df_re_shifted = pdz.shift_time(
|
230
|
+
df_resampled, on="time_utc", period=-shift * self.resolution
|
231
|
+
)
|
232
|
+
|
233
|
+
# Make sure times is divisible by the resolution
|
234
|
+
df_resolution = df_re_shifted[
|
235
|
+
df_re_shifted["time_utc"].dt.round(self.resolution)
|
236
|
+
== df_re_shifted["time_utc"]
|
237
|
+
]
|
238
|
+
|
239
|
+
return df_resolution
|
240
|
+
|
241
|
+
def get_nwp_parameter(
|
242
|
+
self,
|
243
|
+
provider: NWPProvider,
|
244
|
+
parameter: NWPParameter,
|
245
|
+
coordinate: Coordinate,
|
246
|
+
):
|
247
|
+
df_nwp = self._get_interpolated_nwp_parameter(provider, parameter, coordinate)
|
248
|
+
|
249
|
+
# Ensure data is within time_interval defined by user
|
250
|
+
df_nwp = df_nwp.query(
|
251
|
+
f"time_utc >= '{self.time_interval.left}' "
|
252
|
+
f"and time_utc <= '{self.time_interval.right}'",
|
253
|
+
)
|
254
|
+
|
255
|
+
return df_nwp
|
256
|
+
|
257
|
+
def get_nwp_parameter_in_neighborhood(
|
258
|
+
self,
|
259
|
+
provider: NWPProvider,
|
260
|
+
parameter: NWPParameter,
|
261
|
+
neighborhood: Neighborhood,
|
262
|
+
) -> pd.DataFrame:
|
263
|
+
"""
|
264
|
+
Get average NWP data for a given parameter, coordinates and altitude.
|
265
|
+
"""
|
266
|
+
dfs = []
|
267
|
+
|
268
|
+
neighbors = self.get_nwp_neighbors(provider, parameter, neighborhood)
|
269
|
+
for coordinate in neighbors:
|
270
|
+
df_coordinate = self.get_nwp_parameter(provider, parameter, coordinate)
|
271
|
+
dfs.append(df_coordinate)
|
272
|
+
|
273
|
+
df = pd.concat(dfs)
|
274
|
+
df = pdz.group(df, "time_utc").agg("mean")
|
275
|
+
|
276
|
+
return df
|
277
|
+
|
278
|
+
def get_nwp(
|
279
|
+
self,
|
280
|
+
provider: NWPProvider,
|
281
|
+
parameters: list[NWPParameter],
|
282
|
+
neighborhood: Neighborhood,
|
283
|
+
) -> pd.DataFrame:
|
284
|
+
"""
|
285
|
+
Get weather features for a given coordinate.
|
286
|
+
"""
|
287
|
+
dfs = []
|
288
|
+
for parameter in parameters:
|
289
|
+
df_param = self.get_nwp_parameter_in_neighborhood(
|
290
|
+
provider,
|
291
|
+
parameter,
|
292
|
+
neighborhood,
|
293
|
+
)
|
294
|
+
dfs.append(df_param)
|
295
|
+
|
296
|
+
df = pdz.merge_many(dfs=dfs, on=["time_utc"])
|
297
|
+
|
298
|
+
return df
|
@@ -24,7 +24,13 @@ class PlantManager(MasterdataManager):
|
|
24
24
|
def get_plants(
|
25
25
|
self,
|
26
26
|
filters: dict = {},
|
27
|
-
columns: list =
|
27
|
+
columns: list | None = None,
|
28
|
+
) -> pd.DataFrame:
|
29
|
+
"""Gets the plants for a given plant type.
|
30
|
+
Filters for plants valid at the end of time interval.
|
31
|
+
Filters by default for plants in operation.
|
32
|
+
"""
|
33
|
+
default_columns = [
|
28
34
|
"plant_id",
|
29
35
|
"masterdata_gsrn",
|
30
36
|
"datahub_gsrn_e18",
|
@@ -33,12 +39,11 @@ class PlantManager(MasterdataManager):
|
|
33
39
|
"is_tso_connected",
|
34
40
|
"valid_from_date_utc",
|
35
41
|
"valid_to_date_utc",
|
36
|
-
]
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
"""
|
42
|
+
]
|
43
|
+
if not columns:
|
44
|
+
columns = default_columns
|
45
|
+
else:
|
46
|
+
columns = list(set(default_columns + columns))
|
42
47
|
return self.get_data("masterdataPlant", filters=filters, columns=columns)
|
43
48
|
|
44
49
|
def get_installed_power_timeseries(self, gsrn: str) -> pd.DataFrame:
|
@@ -62,3 +67,37 @@ class PlantManager(MasterdataManager):
|
|
62
67
|
return df_plant.filter(["time_utc", "installed_power_MW"]).reset_index(
|
63
68
|
drop=True
|
64
69
|
)
|
70
|
+
|
71
|
+
def _get_corrected_installed_power(
|
72
|
+
self, gsrn: str, df_invalid_periods: pd.DataFrame
|
73
|
+
):
|
74
|
+
df_times = self.time_interval.to_range(self.resolution).to_frame(
|
75
|
+
index=False, name="time_utc"
|
76
|
+
)
|
77
|
+
df = self.get_installed_power_timeseries(gsrn=gsrn)
|
78
|
+
|
79
|
+
# explode invalid periods to time series
|
80
|
+
df_invalid_periods = df_invalid_periods.query(f"masterdata_gsrn == '{gsrn}'")
|
81
|
+
df_invalid_periods = pdz.merge(
|
82
|
+
df_times,
|
83
|
+
df_invalid_periods,
|
84
|
+
left_time="time_utc",
|
85
|
+
right_period=("start_date_utc", "end_date_utc"),
|
86
|
+
)
|
87
|
+
|
88
|
+
df = pdz.merge(
|
89
|
+
df,
|
90
|
+
df_invalid_periods,
|
91
|
+
on="time_utc",
|
92
|
+
how="left",
|
93
|
+
)
|
94
|
+
|
95
|
+
# correct installed power for invalid periods
|
96
|
+
df["installed_power_MW"] = df["installed_power_MW"].where(
|
97
|
+
df["corrected_installed_power_MW"].isnull(),
|
98
|
+
df["corrected_installed_power_MW"],
|
99
|
+
)
|
100
|
+
|
101
|
+
df = df[["time_utc", "installed_power_MW"]]
|
102
|
+
|
103
|
+
return df
|
@@ -24,18 +24,19 @@ class UnitManager(MasterdataManager):
|
|
24
24
|
def get_units(
|
25
25
|
self,
|
26
26
|
filters: dict = {},
|
27
|
-
columns: list =
|
28
|
-
"masterdata_gsrn",
|
29
|
-
"installed_power_MW",
|
30
|
-
"plant_id",
|
31
|
-
"price_area",
|
32
|
-
"valid_from_date_utc",
|
33
|
-
"valid_to_date_utc",
|
34
|
-
"power_system_resource_type",
|
35
|
-
],
|
27
|
+
columns: list | None = None,
|
36
28
|
) -> pd.DataFrame:
|
37
29
|
"""Gets the units for a given unit type.
|
38
30
|
Filters for units valid at the end of time interval.
|
39
31
|
Filters by default for units in operation.
|
40
32
|
"""
|
33
|
+
default_columns = [
|
34
|
+
"masterdata_gsrn",
|
35
|
+
"plant_id",
|
36
|
+
"power_system_resource_type",
|
37
|
+
]
|
38
|
+
if not columns:
|
39
|
+
columns = default_columns
|
40
|
+
else:
|
41
|
+
columns = list(set(default_columns + columns))
|
41
42
|
return self.get_data("masterdataUnit", filters=filters, columns=columns)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from enum import Enum
|
3
|
+
|
4
|
+
|
5
|
+
class NWPParameter(Enum):
|
6
|
+
SOLAR = "Solar"
|
7
|
+
WIND = "Wind"
|
8
|
+
TEMPERATURE = "Temperature"
|
9
|
+
|
10
|
+
|
11
|
+
class NWPProvider(Enum):
|
12
|
+
ECMWF = "Ecmwf"
|
13
|
+
CONWX = "Conwx"
|
14
|
+
DMI = "Dmi"
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass(frozen=True)
|
18
|
+
class Coordinate:
|
19
|
+
latitude: float
|
20
|
+
longitude: float
|
21
|
+
altitude: float
|
22
|
+
|
23
|
+
|
24
|
+
@dataclass(frozen=True)
|
25
|
+
class Neighborhood:
|
26
|
+
coordinate: Coordinate
|
27
|
+
num_neighbors: int
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
|
3
|
+
import pandas as pd
|
4
|
+
|
5
|
+
from .nwp import Coordinate
|
6
|
+
|
7
|
+
|
8
|
+
@dataclass(frozen=True)
|
9
|
+
class Plant:
|
10
|
+
plant_gsrn: str
|
11
|
+
plant_name: str
|
12
|
+
datahub_gsrn_e18: str
|
13
|
+
price_area: str
|
14
|
+
coordinate: Coordinate
|
15
|
+
installed_power_MW: float
|
16
|
+
|
17
|
+
@classmethod
|
18
|
+
def plants_from_df(cls, df: pd.DataFrame) -> list["Plant"]:
|
19
|
+
plants = []
|
20
|
+
for _, row in df.iterrows():
|
21
|
+
plant = cls(
|
22
|
+
plant_gsrn=row["plant_gsrn"],
|
23
|
+
plant_name=row["plant_name"],
|
24
|
+
datahub_gsrn_e18=row["datahub_gsrn_e18"],
|
25
|
+
price_area=row["price_area"],
|
26
|
+
coordinate=Coordinate(
|
27
|
+
latitude=row["latitude"],
|
28
|
+
longitude=row["longitude"],
|
29
|
+
altitude=0,
|
30
|
+
),
|
31
|
+
installed_power_MW=row["installed_power_MW"],
|
32
|
+
)
|
33
|
+
plants.append(plant)
|
34
|
+
return plants
|
35
|
+
|
36
|
+
|
37
|
+
@dataclass(frozen=True)
|
38
|
+
class Group:
|
39
|
+
coordinate: Coordinate
|
40
|
+
installed_power_MW: float
|
41
|
+
identifiers: dict[str, str]
|
42
|
+
|
43
|
+
@classmethod
|
44
|
+
def groups_from_df(cls, df: pd.DataFrame, identifiers: list[str]) -> list["Group"]:
|
45
|
+
groups = []
|
46
|
+
for _, row in df.iterrows():
|
47
|
+
identifiers = {identifier: row[identifier] for identifier in identifiers}
|
48
|
+
group = cls(
|
49
|
+
identifiers=identifiers,
|
50
|
+
installed_power_MW=row["installed_power_MW"],
|
51
|
+
coordinate=Coordinate(
|
52
|
+
latitude=row["latitude"],
|
53
|
+
longitude=row["longitude"],
|
54
|
+
altitude=0,
|
55
|
+
),
|
56
|
+
)
|
57
|
+
groups.append(group)
|
58
|
+
return groups
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: domainiac
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: Package for working with Energinet data, but with specialized functions used for Enigma.
|
5
5
|
Author: Team Enigma
|
6
6
|
Author-email: gridop-enigma@energinet.dk
|
@@ -9,4 +9,5 @@ Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.10
|
10
10
|
Requires-Dist: datamazing (>=5.0.2,<6.0.0)
|
11
11
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
12
|
+
Requires-Dist: scikit-learn (>=1.3.0,<2.0.0)
|
12
13
|
Requires-Dist: typeguard (>=4.2.1,<5.0.0)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
domainiac/__init__.py,sha256=Wuix4jscZD4sy7YB0RAedAo_eiRW5AcPlef58lKvg6s,207
|
2
|
+
domainiac/managers/__init__.py,sha256=x7NZxFAuJig2TZGJ71niwMyPyDvxjaiE647BJQU0qD8,256
|
3
|
+
domainiac/managers/masterdata_manager.py,sha256=H-Dk-dvZZ3bqgV66Xf1V4GQnQWprzLqSKdfD1MPLQgo,2223
|
4
|
+
domainiac/managers/metering_manager.py,sha256=NXGHuNjWiAUE08fGIPAfvwbzlKESbKaO5uyxLNyZKC0,995
|
5
|
+
domainiac/managers/nwp_manager.py,sha256=qGr4c1ZbUnVRmhX_LmjaobBKN6BBXUn5bbYVKa_5lo4,9921
|
6
|
+
domainiac/managers/plant_manager.py,sha256=o0HkOs1nf1uri7OMMH-VgPTAONWjuEE80SyD9RDf0n8,3186
|
7
|
+
domainiac/managers/resource_manager.py,sha256=QMkNcrgyXLLlkCR9kg4-nFjTaYHtlsldex-b_8lAmO0,3730
|
8
|
+
domainiac/managers/unit_manager.py,sha256=DYF-AiBHzUGZJE5XlTLcszvgIQkSzZs_s9o35l4bkVk,1219
|
9
|
+
domainiac/modeling/__init__.py,sha256=Ac5feYZ9gVLayU1Cb1ACqOyDrmvcxoOvZuUkOeXVKf8,101
|
10
|
+
domainiac/modeling/nwp.py,sha256=PolrBdQn8W-e1M0_pefvmLn2mr4HT0NqlYlkyCV0dds,438
|
11
|
+
domainiac/modeling/plant.py,sha256=48KEcfiMk90fOAzOeI5qtf1FcGvpyBNIRmN2zvx9CLc,1699
|
12
|
+
domainiac/wrappers/__init__.py,sha256=vZOw9maXgVoAvudZqioD-GTPkgPI6fm7_CUELQcR_-g,43
|
13
|
+
domainiac/wrappers/cache_wrapper.py,sha256=jDg-Lt_y-YzItyP-74tGULOxb07s_CcutmOHP1Ie00Q,355
|
14
|
+
domainiac-2.0.0.dist-info/METADATA,sha256=O0KM7oPIYCtDKihwlHr8leFJ7XErIsjb8WMobGibAic,510
|
15
|
+
domainiac-2.0.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
16
|
+
domainiac-2.0.0.dist-info/RECORD,,
|
domainiac-1.0.0.dist-info/RECORD
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
domainiac/__init__.py,sha256=7-KoUot9OZgzMoOLhuHInlvyt9EfL5QjuZagTbAJksU,82
|
2
|
-
domainiac/managers/__init__.py,sha256=QzkZNv8_3G0TPcfQia45RWBnASYR6WIuY6jlFBeley0,220
|
3
|
-
domainiac/managers/masterdata_manager.py,sha256=tl37saXdH1aeek3Oo58nTxl-eL2txKnmpwVHkyij7n0,2099
|
4
|
-
domainiac/managers/metering_manager.py,sha256=NXGHuNjWiAUE08fGIPAfvwbzlKESbKaO5uyxLNyZKC0,995
|
5
|
-
domainiac/managers/plant_manager.py,sha256=sEVc3_RaJaG-beT7kv3rgvCtaWLCuXuhxy21mk360Og,1944
|
6
|
-
domainiac/managers/resource_manager.py,sha256=QMkNcrgyXLLlkCR9kg4-nFjTaYHtlsldex-b_8lAmO0,3730
|
7
|
-
domainiac/managers/unit_manager.py,sha256=8B0hRu_tlZfaZYKDnM0NAQoJ6a1s_8DicBM9v6GEkYE,1174
|
8
|
-
domainiac/wrappers/__init__.py,sha256=vZOw9maXgVoAvudZqioD-GTPkgPI6fm7_CUELQcR_-g,43
|
9
|
-
domainiac/wrappers/cache_wrapper.py,sha256=jDg-Lt_y-YzItyP-74tGULOxb07s_CcutmOHP1Ie00Q,355
|
10
|
-
domainiac-1.0.0.dist-info/METADATA,sha256=LWQrY1F34IUdCbZbsXqQ8Di6DOMVidN7bq1deCbzUFU,465
|
11
|
-
domainiac-1.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
-
domainiac-1.0.0.dist-info/RECORD,,
|