Skip to content

Commit dcc1850

Browse files
Merge pull request #1229 from ie3-institute/ms/#1228-refactor-LoadProfileTimeSeries
Replaced `LoadProfileInput` with `LoadProfileTimeSeries`
2 parents 6f83769 + 8ad0a66 commit dcc1850

37 files changed

+533
-482
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- Removed attribute `dsm` from `LoadInput` [#1195](https://github.com/ie3-institute/PowerSystemDataModel/issues/1195)
2929
- Fix spotless deprecations [#1123](https://github.com/ie3-institute/PowerSystemDataModel/issues/1223)
3030
- Refactored `CongestionResult`, removed `ModelResultEntity` [#1234](https://github.com/ie3-institute/PowerSystemDataModel/issues/1234)
31+
- Replaced `LoadProfileInput` with `LoadProfileTimeSeries` [#1228](https://github.com/ie3-institute/PowerSystemDataModel/issues/1228)
3132

3233
## [5.1.0] - 2024-06-24
3334

src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ public synchronized BufferedCsvWriter getOrInitWriter(
6363
}
6464
}
6565

66-
public synchronized <T extends TimeSeries<E, V>, E extends TimeSeriesEntry<V>, V extends Value>
66+
public synchronized <
67+
T extends TimeSeries<E, V, R>,
68+
E extends TimeSeriesEntry<V>,
69+
V extends Value,
70+
R extends Value>
6771
BufferedCsvWriter getOrInitWriter(T timeSeries, CsvFileDefinition fileDefinition)
6872
throws ConnectorException {
6973
/* Try to the right writer */

src/main/java/edu/ie3/datamodel/io/csv/CsvFileDefinition.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ public CsvFileDefinition(
6868
* @param fileNamingStrategy that should be used
6969
* @throws FileException If the definition cannot be determined
7070
*/
71-
public <T extends TimeSeries<E, V>, E extends TimeSeriesEntry<V>, V extends Value>
71+
public <
72+
T extends TimeSeries<E, V, R>,
73+
E extends TimeSeriesEntry<V>,
74+
V extends Value,
75+
R extends Value>
7276
CsvFileDefinition(
7377
T timeSeries,
7478
String[] headLineElements,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* © 2024. TU Dortmund University,
3+
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
4+
* Research group Distribution grid planning and operation
5+
*/
6+
package edu.ie3.datamodel.io.factory.timeseries;
7+
8+
import edu.ie3.datamodel.io.factory.FactoryData;
9+
import edu.ie3.datamodel.models.value.load.LoadValues;
10+
import java.util.Map;
11+
12+
/**
13+
* Data, that is used to build a {@link
14+
* edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileEntry} within a factory
15+
*
16+
* @param <V> Type of load values class
17+
*/
18+
public class LoadProfileData<V extends LoadValues> extends FactoryData {
19+
public LoadProfileData(Map<String, String> fieldsToAttributes, Class<V> targetClass) {
20+
super(fieldsToAttributes, targetClass);
21+
}
22+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* © 2024. TU Dortmund University,
3+
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
4+
* Research group Distribution grid planning and operation
5+
*/
6+
package edu.ie3.datamodel.io.factory.timeseries;
7+
8+
import edu.ie3.datamodel.io.factory.Factory;
9+
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
10+
import edu.ie3.datamodel.models.profile.LoadProfile;
11+
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileEntry;
12+
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileTimeSeries;
13+
import edu.ie3.datamodel.models.value.load.LoadValues;
14+
import edu.ie3.util.quantities.PowerSystemUnits;
15+
import java.util.Set;
16+
import javax.measure.quantity.Energy;
17+
import javax.measure.quantity.Power;
18+
import tech.units.indriya.ComparableQuantity;
19+
import tech.units.indriya.quantity.Quantities;
20+
21+
/**
22+
* Base factory for all {@link LoadProfileTimeSeries}.
23+
*
24+
* @param <P> type of load profile
25+
* @param <V> type of load values
26+
*/
27+
public abstract class LoadProfileFactory<P extends LoadProfile, V extends LoadValues>
28+
extends Factory<V, LoadProfileData<V>, LoadProfileEntry<V>> {
29+
protected static final String QUARTER_HOUR = "quarterHour";
30+
31+
public LoadProfileFactory(Class<? extends V> valueClass) {
32+
super(valueClass);
33+
}
34+
35+
public abstract LoadProfileTimeSeries<V> build(
36+
LoadProfileMetaInformation metaInformation, Set<LoadProfileEntry<V>> entries);
37+
38+
public abstract P parseProfile(String profile);
39+
40+
/**
41+
* Calculates the maximum average power consumption per quarter-hour for a given calculated over
42+
* all seasons and weekday types of given load profile
43+
*
44+
* @param loadProfile given load profile
45+
* @param entries with power values
46+
* @return the maximal average power
47+
*/
48+
public abstract ComparableQuantity<Power> calculateMaxPower(
49+
P loadProfile, Set<LoadProfileEntry<V>> entries);
50+
51+
/** Returns the quarter-hour field. */
52+
public String getTimeFieldString() {
53+
return QUARTER_HOUR;
54+
}
55+
56+
/** Returns the load profile energy scaling. The default value is 1000 kWh */
57+
public ComparableQuantity<Energy> getLoadProfileEnergyScaling(P loadProfile) {
58+
return Quantities.getQuantity(1000, PowerSystemUnits.KILOWATTHOUR);
59+
}
60+
}

src/main/java/edu/ie3/datamodel/io/factory/timeseries/TimeSeriesMetaInformationFactory.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
import edu.ie3.datamodel.io.factory.EntityData;
99
import edu.ie3.datamodel.io.factory.EntityFactory;
10+
import edu.ie3.datamodel.io.naming.TimeSeriesMetaInformation;
1011
import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
1112
import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
13+
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
1214
import java.util.Collections;
1315
import java.util.List;
1416
import java.util.Set;
@@ -21,12 +23,13 @@
2123
* mappings
2224
*/
2325
public class TimeSeriesMetaInformationFactory
24-
extends EntityFactory<IndividualTimeSeriesMetaInformation, EntityData> {
26+
extends EntityFactory<TimeSeriesMetaInformation, EntityData> {
2527
private static final String TIME_SERIES = "timeSeries";
2628
private static final String COLUMN_SCHEME = "columnScheme";
29+
private static final String LOAD_PROFILE = "loadProfile";
2730

2831
public TimeSeriesMetaInformationFactory() {
29-
super(IndividualTimeSeriesMetaInformation.class);
32+
super(IndividualTimeSeriesMetaInformation.class, LoadProfileMetaInformation.class);
3033
}
3134

3235
@Override
@@ -36,9 +39,15 @@ protected List<Set<String>> getFields(Class<?> entityClass) {
3639
}
3740

3841
@Override
39-
protected IndividualTimeSeriesMetaInformation buildModel(EntityData data) {
40-
UUID timeSeries = data.getUUID(TIME_SERIES);
41-
ColumnScheme columnScheme = ColumnScheme.parse(data.getField(COLUMN_SCHEME)).orElseThrow();
42-
return new IndividualTimeSeriesMetaInformation(timeSeries, columnScheme);
42+
protected TimeSeriesMetaInformation buildModel(EntityData data) {
43+
if (LoadProfileMetaInformation.class.isAssignableFrom(data.getTargetClass())) {
44+
String profile = data.getField(LOAD_PROFILE);
45+
return new LoadProfileMetaInformation(profile);
46+
} else {
47+
UUID timeSeries = data.getUUID(TIME_SERIES);
48+
49+
ColumnScheme columnScheme = ColumnScheme.parse(data.getField(COLUMN_SCHEME)).orElseThrow();
50+
return new IndividualTimeSeriesMetaInformation(timeSeries, columnScheme);
51+
}
4352
}
4453
}

src/main/java/edu/ie3/datamodel/io/naming/DatabaseNamingStrategy.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import edu.ie3.datamodel.models.timeseries.TimeSeries;
1313
import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry;
1414
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
15-
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput;
15+
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileTimeSeries;
1616
import edu.ie3.datamodel.models.value.Value;
1717
import java.util.Optional;
1818

@@ -21,7 +21,7 @@ public class DatabaseNamingStrategy {
2121

2222
private static final String TIME_SERIES_PREFIX = "time_series_";
2323

24-
private static final String LOAD_PROFILE_PREFIX = "load_profile_";
24+
private static final String LOAD_PROFILE = "load_profiles";
2525

2626
private final EntityPersistenceNamingStrategy entityPersistenceNamingStrategy;
2727

@@ -42,6 +42,11 @@ public String getTimeSeriesPrefix() {
4242
return TIME_SERIES_PREFIX;
4343
}
4444

45+
/** Returns the String of the load profile table */
46+
public String getLoadProfileTableName() {
47+
return LOAD_PROFILE;
48+
}
49+
4550
/**
4651
* Provides the name of a time series table given a column scheme
4752
*
@@ -53,13 +58,12 @@ public String getTimeSeriesEntityName(ColumnScheme columnScheme) {
5358
}
5459

5560
/**
56-
* Provides the name of a load profile given by the load profile key
61+
* Provides the name of the load profile table.
5762
*
58-
* @param lpKey Load profile key
5963
* @return the table name
6064
*/
61-
private String getLoadProfileEntityName(String lpKey) {
62-
return LOAD_PROFILE_PREFIX + lpKey;
65+
public String getLoadProfileEntityName() {
66+
return getLoadProfileTableName();
6367
}
6468

6569
/**
@@ -78,7 +82,11 @@ public Optional<String> getEntityName(Class<? extends Entity> cls) {
7882
* @param timeSeries to be named TimeSeries
7983
* @return the table name
8084
*/
81-
public <T extends TimeSeries<E, V>, E extends TimeSeriesEntry<V>, V extends Value>
85+
public <
86+
T extends TimeSeries<E, V, R>,
87+
E extends TimeSeriesEntry<V>,
88+
V extends Value,
89+
R extends Value>
8290
Optional<String> getEntityName(T timeSeries) {
8391
if (timeSeries instanceof IndividualTimeSeries individualTimeSeries) {
8492
Optional<E> maybeFirstElement = individualTimeSeries.getEntries().stream().findFirst();
@@ -89,8 +97,8 @@ Optional<String> getEntityName(T timeSeries) {
8997
logger.error("Unable to determine content of time series {}", timeSeries);
9098
return Optional.empty();
9199
}
92-
} else if (timeSeries instanceof LoadProfileInput loadProfileInput) {
93-
return Optional.of(getLoadProfileEntityName(loadProfileInput.getType().getKey()));
100+
} else if (timeSeries instanceof LoadProfileTimeSeries<?>) {
101+
return Optional.of(getLoadProfileEntityName());
94102
} else {
95103
logger.error("There is no naming strategy defined for {}", timeSeries);
96104
return Optional.empty();

src/main/java/edu/ie3/datamodel/io/naming/DefaultDirectoryHierarchy.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import edu.ie3.datamodel.models.result.system.*;
3131
import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult;
3232
import edu.ie3.datamodel.models.timeseries.TimeSeries;
33-
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput;
3433
import java.io.IOException;
3534
import java.nio.file.Files;
3635
import java.nio.file.Path;
@@ -250,9 +249,7 @@ private enum SubDirectories {
250249
StorageTypeInput.class,
251250
WecTypeInput.class,
252251
OperatorInput.class,
253-
WecCharacteristicInput.class,
254-
RandomLoadParameters.class,
255-
LoadProfileInput.class)
252+
WecCharacteristicInput.class)
256253
.collect(Collectors.toSet())),
257254
PARTICIPANTS_INPUT(
258255
Constants.INPUT_SUB_TREE.resolve("participants"),

src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
99
import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
10-
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileTimeSeriesMetaInformation;
10+
import edu.ie3.datamodel.io.naming.timeseries.LoadProfileMetaInformation;
1111
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
1212
import edu.ie3.datamodel.models.Entity;
1313
import edu.ie3.datamodel.models.input.*;
@@ -17,7 +17,7 @@
1717
import edu.ie3.datamodel.models.timeseries.TimeSeries;
1818
import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry;
1919
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
20-
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput;
20+
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileTimeSeries;
2121
import edu.ie3.datamodel.models.value.*;
2222
import edu.ie3.util.StringUtils;
2323
import java.util.Optional;
@@ -60,7 +60,7 @@ public class EntityPersistenceNamingStrategy {
6060
* profile is accessible via the named capturing group "profile", the uuid by the group "uuid"
6161
*/
6262
private static final String LOAD_PROFILE_TIME_SERIES =
63-
"lpts_(?<profile>[a-zA-Z][0-9])_(?<uuid>" + UUID_STRING + ")";
63+
"lpts_(?<profile>[a-zA-Z]{1,11}[0-9]{0,3})";
6464

6565
/**
6666
* Pattern to identify load profile time series in this instance of the naming strategy (takes
@@ -156,15 +156,13 @@ public IndividualTimeSeriesMetaInformation individualTimesSeriesMetaInformation(
156156
* @param fileName File name to extract information from
157157
* @return Meta information form load profile time series file name
158158
*/
159-
public LoadProfileTimeSeriesMetaInformation loadProfileTimesSeriesMetaInformation(
160-
String fileName) {
159+
public LoadProfileMetaInformation loadProfileTimesSeriesMetaInformation(String fileName) {
161160
Matcher matcher = getLoadProfileTimeSeriesPattern().matcher(fileName);
162161
if (!matcher.matches())
163162
throw new IllegalArgumentException(
164163
"Cannot extract meta information on load profile time series from '" + fileName + "'.");
165164

166-
return new LoadProfileTimeSeriesMetaInformation(
167-
UUID.fromString(matcher.group("uuid")), matcher.group("profile"));
165+
return new LoadProfileMetaInformation(matcher.group("profile"));
168166
}
169167

170168
/**
@@ -215,8 +213,6 @@ public Optional<String> getInputEntityName(Class<? extends InputEntity> cls) {
215213
return getTypeEntityName(cls.asSubclass(AssetTypeInput.class));
216214
if (AssetInput.class.isAssignableFrom(cls))
217215
return getAssetInputEntityName(cls.asSubclass(AssetInput.class));
218-
if (RandomLoadParameters.class.isAssignableFrom(cls))
219-
return getRandomLoadParametersEntityName(cls.asSubclass(RandomLoadParameters.class));
220216
if (GraphicInput.class.isAssignableFrom(cls))
221217
return getGraphicsInputEntityName(cls.asSubclass(GraphicInput.class));
222218
if (OperatorInput.class.isAssignableFrom(cls))
@@ -274,19 +270,6 @@ public Optional<String> getAssetCharacteristicsEntityName(
274270
return Optional.of(addPrefixAndSuffix(assetCharString));
275271
}
276272

277-
/**
278-
* Get the entity name for all {@link RandomLoadParameters}
279-
*
280-
* @param randomLoadParamClass the random load parameters class an entity name string should be
281-
* generated from
282-
* @return the entity name string
283-
*/
284-
public Optional<String> getRandomLoadParametersEntityName(
285-
Class<? extends RandomLoadParameters> randomLoadParamClass) {
286-
String loadParamString = camelCaseToSnakeCase(randomLoadParamClass.getSimpleName());
287-
return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input")));
288-
}
289-
290273
/**
291274
* Converts a given camel case string to its snake case representation
292275
*
@@ -359,7 +342,11 @@ public Optional<String> getTimeSeriesMappingEntityName() {
359342
* @param timeSeries Time series to derive naming information from
360343
* @return A file name for this particular time series
361344
*/
362-
public <T extends TimeSeries<E, V>, E extends TimeSeriesEntry<V>, V extends Value>
345+
public <
346+
T extends TimeSeries<E, V, R>,
347+
E extends TimeSeriesEntry<V>,
348+
V extends Value,
349+
R extends Value>
363350
Optional<String> getEntityName(T timeSeries) {
364351
if (timeSeries instanceof IndividualTimeSeries) {
365352
Optional<E> maybeFirstElement = timeSeries.getEntries().stream().findFirst();
@@ -383,14 +370,12 @@ Optional<String> getEntityName(T timeSeries) {
383370
logger.error("Unable to determine content of time series {}", timeSeries);
384371
return Optional.empty();
385372
}
386-
} else if (timeSeries instanceof LoadProfileInput loadProfileInput) {
373+
} else if (timeSeries instanceof LoadProfileTimeSeries<?> loadProfileTimeSeries) {
387374
return Optional.of(
388375
prefix
389376
.concat("lpts")
390377
.concat("_")
391-
.concat(loadProfileInput.getType().getKey())
392-
.concat("_")
393-
.concat(loadProfileInput.getUuid().toString())
378+
.concat(loadProfileTimeSeries.getLoadProfile().getKey())
394379
.concat(suffix));
395380
} else {
396381
logger.error("There is no naming strategy defined for {}", timeSeries);

0 commit comments

Comments
 (0)