Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cab8cdc
Extracting mapping source from former time series source
ckittl Feb 9, 2021
9f520fd
Removing mapping function from former source
ckittl Feb 9, 2021
80b36f7
Adapt method name
ckittl Feb 23, 2021
4e94442
Extracting individual information from time series and map them to th…
ckittl Feb 23, 2021
10dd5d7
Reading individual time series as per the model's uuid
ckittl Feb 23, 2021
e24081c
Remove non used API-pieces
ckittl Feb 23, 2021
e56d3f1
Merge remote-tracking branch 'origin/dev' into ck/#274-reworkTimeSeri…
ckittl Feb 23, 2021
a5cc9bd
Adapting and adding tests
ckittl Feb 23, 2021
6ed9498
Reducing code smells
ckittl Feb 23, 2021
c70099e
Merge branch 'dev' into ck/#274-reworkTimeSeriesSource
ckittl Feb 25, 2021
2ab7fdf
Merge branch 'dev' into ck/#274-reworkTimeSeriesSource
ckittl Feb 25, 2021
8136feb
Moving determination of meta information to mapping source
ckittl Mar 1, 2021
a32e7a1
No determination of time series UUID in time series source
ckittl Mar 1, 2021
9518b96
Implement factory pattern for csv time series source
ckittl Mar 1, 2021
3c63f76
Adding utils to trim a time series
ckittl Mar 1, 2021
d5f3501
Query time series with a timely restriction
ckittl Mar 1, 2021
581ba5b
Adding work to CHANGELOG.md
ckittl Mar 1, 2021
08175b7
Fixing javadoc
ckittl Mar 1, 2021
e3ad974
Adapting documentation
ckittl Mar 1, 2021
db0c6f8
Addressing review comments
ckittl Mar 4, 2021
aa952c9
Merge remote-tracking branch 'origin/dev' into ck/#274-reworkTimeSeri…
ckittl Mar 4, 2021
ad5c9ce
Addressing Codacy issues
ckittl Mar 4, 2021
6f63c95
Merge branch 'dev' into ck/#274-reworkTimeSeriesSource
ckittl Mar 4, 2021
f7f8262
Merge branch 'dev' into ck/#274-reworkTimeSeriesSource
ckittl Mar 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- BREAKING: Harmonized field naming for time information
- BREAKING: Properly applying snake case to result file names
- deprecated `TarballUtils`
- Reworking the time series source (one source per time series, distinct mapping source, factory pattern)

### Fixed
- InfluxDbConnector now keeps session instead of creating a new one each call
Expand Down
32 changes: 28 additions & 4 deletions docs/uml/main/DataSourceClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,35 @@ interface WeatherSource {
}
DataSource <|-- WeatherSource

interface WholeSalePriceSource {
{abstract} IndividualTimeSeries<EnergyPriceValue> getWholesalePrice(ClosedInterval<ZonedDateTime>)
{abstract} IndividualTimeSeries<EnergyPriceValue> getWholesalePrice(ZonedDateTime)
interface TimeSeriesMappingSource {
{abstract} Map<UUID, UUID> getMapping()
Optional<UUID> getTimeSeriesUuid(UUID)
{abstract} Optional<IndividualTimeSeriesMetaInformation> getTimeSeriesMetaInformation(UUID)
}
DataSource <|-- WholeSalePriceSource
DataSource <|-- TimeSeriesMappingSource

class CsvTimeSeriesMappingSource {
- TimeSeriesMappingFactory mappingFactory
- Map<UUID, UUID> mapping
}
CsvTimeSeriesMappingSource <|.. TimeSeriesMappingSource
CsvTimeSeriesMappingSource <|-- CsvDataSource

interface TimeSeriesSource<V extends Value> {
{abstract} IndividualTimeSeries<V> getTimeSeries()
{abstract} IndividualTimeSeries<V> getTimeSeries(ClosedInterval<ZonedDateTime>))
{abstract} Optional<V> getValue(ZonedDateTime)
}
TimeSeriesSource <|-- DataSource

class CsvTimeSeriesSource<V extends Value> {
- IndividualTimeSeries<V> timeSeries
+ {static} CsvTimeSeriesSource<? extends Value> getSource(\n\tString,\n\tString,\n\tFileNamingStrategy,\n\tsvFileConnector.CsvIndividualTimeSeriesMetaInformation)
- IndividualTimeSeries<V> buildIndividualTimeSeries(\n\tUUID,\n\tfilePath,\n\tFunction<Map<String, String>,\n\tOptional<TimeBasedValue<V>>>)
- Optional<TimeBasedValue<V>> buildTimeBasedValue(\n\tMap<String, String>,\n\tClass<V>,\n\tTimeBasedSimpleValueFactory<V>)
}
CsvTimeSeriesSource <|.. TimeSeriesSource
CsvTimeSeriesSource <|-- CsvDataSource

interface DataConnector {
{abstract} shutdown()
Expand Down
102 changes: 101 additions & 1 deletion src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class CsvFileConnector implements DataConnector {
private final Map<Class<? extends UniqueEntity>, BufferedCsvWriter> entityWriters =
new HashMap<>();
private final Map<UUID, BufferedCsvWriter> timeSeriesWriters = new HashMap<>();
// ATTENTION: Do not finalize. It's meant for lazy evaluation.
private Map<UUID, CsvIndividualTimeSeriesMetaInformation> individualTimeSeriesMetaInformation;
private final FileNamingStrategy fileNamingStrategy;
private final String baseDirectoryName;

Expand Down Expand Up @@ -175,14 +177,56 @@ public BufferedReader initReader(String filePath) throws FileNotFoundException {
new InputStreamReader(new FileInputStream(fullPath), StandardCharsets.UTF_8), 16384);
}

/**
* Get time series meta information for a given uuid.
*
* <p>This method lazily evaluates the mapping from <i>all</i> time series files to their meta
* information.
*
* @param timeSeriesUuid The time series in question
* @return An option on the queried information
*/
public Optional<IndividualTimeSeriesMetaInformation> getIndividualTimeSeriesMetaInformation(
UUID timeSeriesUuid) {
if (Objects.isNull(individualTimeSeriesMetaInformation))
individualTimeSeriesMetaInformation = buildIndividualTimeSeriesMetaInformation();

return Optional.ofNullable(individualTimeSeriesMetaInformation.get(timeSeriesUuid));
}

/**
* This method creates a map from time series uuid to it's meta information.
*
* @return Mapping from time series uuid to it's meta information.
*/
private Map<UUID, CsvIndividualTimeSeriesMetaInformation>
buildIndividualTimeSeriesMetaInformation() {
return getIndividualTimeSeriesFilePaths()
.parallelStream()
.map(
filePath -> {
/* Extract meta information from file path and enhance it with the file path itself */
String filePathWithoutEnding = removeFileEnding(filePath);
IndividualTimeSeriesMetaInformation metaInformation =
(IndividualTimeSeriesMetaInformation)
fileNamingStrategy.extractTimeSeriesMetaInformation(filePathWithoutEnding);
return new CsvIndividualTimeSeriesMetaInformation(
metaInformation, filePathWithoutEnding);
})
.collect(Collectors.toMap(FileNameMetaInformation::getUuid, v -> v));
}

/**
* Initialises the readers for time series with the specified column schemes. They are given back
* grouped by the column scheme in order to allow for accounting the different content types.
*
* @param columnSchemes the column schemes to initialize readers for. If no scheme is given, all
* possible readers will be initialized.
* @return A mapping from column type to respective readers
* @deprecated Don't use {@link TimeSeriesReadingData}, as it contains a reader, that might not be
* closed
*/
@Deprecated
public Map<ColumnScheme, Set<TimeSeriesReadingData>> initTimeSeriesReader(
ColumnScheme... columnSchemes) {
return getIndividualTimeSeriesFilePaths()
Expand Down Expand Up @@ -245,7 +289,10 @@ private Set<String> getIndividualTimeSeriesFilePaths() {
* @param columnSchemes the allowed column schemes. If no scheme is specified, all schemes are
* allowed.
* @return An {@link Optional} to {@link TimeSeriesReadingData}
* @deprecated Don't use {@link TimeSeriesReadingData}, as it contains a reader, that might not be
* closed
*/
@Deprecated
private Optional<TimeSeriesReadingData> buildReadingData(
String filePathString, ColumnScheme... columnSchemes) {
try {
Expand Down Expand Up @@ -360,7 +407,12 @@ public void shutdown() {
});
}

/** Class to bundle all information, that are necessary to read a single time series */
/**
* Class to bundle all information, that are necessary to read a single time series
*
* @deprecated Use the {@link CsvIndividualTimeSeriesMetaInformation} and build reader on demand
*/
@Deprecated
public static class TimeSeriesReadingData {
private final UUID uuid;
private final ColumnScheme columnScheme;
Expand Down Expand Up @@ -411,4 +463,52 @@ public String toString() {
+ '}';
}
}

/** Enhancing the {@link IndividualTimeSeriesMetaInformation} with the full path to csv file */
public static class CsvIndividualTimeSeriesMetaInformation
extends IndividualTimeSeriesMetaInformation {
private final String fullFilePath;

public CsvIndividualTimeSeriesMetaInformation(
UUID uuid, ColumnScheme columnScheme, String fullFilePath) {
super(uuid, columnScheme);
this.fullFilePath = fullFilePath;
}

public CsvIndividualTimeSeriesMetaInformation(
IndividualTimeSeriesMetaInformation metaInformation, String fullFilePath) {
this(metaInformation.getUuid(), metaInformation.getColumnScheme(), fullFilePath);
}

public String getFullFilePath() {
return fullFilePath;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CsvIndividualTimeSeriesMetaInformation)) return false;
if (!super.equals(o)) return false;
CsvIndividualTimeSeriesMetaInformation that = (CsvIndividualTimeSeriesMetaInformation) o;
return fullFilePath.equals(that.fullFilePath);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), fullFilePath);
}

@Override
public String toString() {
return "CsvIndividualTimeSeriesMetaInformation{"
+ "uuid="
+ getUuid()
+ ", columnScheme="
+ getColumnScheme()
+ ", fullFilePath='"
+ fullFilePath
+ '\''
+ '}';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package edu.ie3.datamodel.io.csv;

import edu.ie3.datamodel.exceptions.FileException;
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
import edu.ie3.datamodel.models.UniqueEntity;
import edu.ie3.datamodel.models.input.*;
import edu.ie3.datamodel.models.input.connector.LineInput;
Expand All @@ -30,7 +31,6 @@
import edu.ie3.datamodel.models.result.system.*;
import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult;
import edu.ie3.datamodel.models.timeseries.TimeSeries;
import edu.ie3.datamodel.models.timeseries.mapping.TimeSeriesMapping;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput;
import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -299,7 +299,8 @@ private enum SubDirectories {
TIME_SERIES(
PARTICIPANTS_INPUT.relPath + "time_series" + FILE_SEPARATOR,
false,
Stream.of(TimeSeries.class, TimeSeriesMapping.Entry.class).collect(Collectors.toSet())),
Stream.of(TimeSeries.class, TimeSeriesMappingSource.MappingEntry.class)
.collect(Collectors.toSet())),
THERMAL_INPUT(
Constants.INPUT_SUB_TREE + FILE_SEPARATOR + "thermal" + FILE_SEPARATOR,
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme;
import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.io.csv.timeseries.LoadProfileTimeSeriesMetaInformation;
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
import edu.ie3.datamodel.models.UniqueEntity;
import edu.ie3.datamodel.models.input.AssetInput;
import edu.ie3.datamodel.models.input.AssetTypeInput;
Expand All @@ -19,7 +20,6 @@
import edu.ie3.datamodel.models.timeseries.TimeSeries;
import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry;
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
import edu.ie3.datamodel.models.timeseries.mapping.TimeSeriesMapping;
import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput;
import edu.ie3.datamodel.models.value.*;
import edu.ie3.util.StringUtils;
Expand Down Expand Up @@ -235,7 +235,8 @@ public Optional<String> getFileName(Class<? extends UniqueEntity> cls) {
return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class));
if (OperatorInput.class.isAssignableFrom(cls))
return getOperatorInputFileName(cls.asSubclass(OperatorInput.class));
if (TimeSeriesMapping.Entry.class.isAssignableFrom(cls)) return getTimeSeriesMappingFileName();
if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls))
return getTimeSeriesMappingFileName();
logger.error("There is no naming strategy defined for {}", cls.getSimpleName());
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import edu.ie3.datamodel.io.factory.EntityFactory;
import edu.ie3.datamodel.io.factory.SimpleEntityData;
import edu.ie3.datamodel.models.timeseries.mapping.TimeSeriesMapping;
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
Expand All @@ -16,13 +16,13 @@
import java.util.stream.Stream;

public class TimeSeriesMappingFactory
extends EntityFactory<TimeSeriesMapping.Entry, SimpleEntityData> {
extends EntityFactory<TimeSeriesMappingSource.MappingEntry, SimpleEntityData> {
private static final String UUID = "uuid";
private static final String PARTICIPANT = "participant";
private static final String TIME_SERIES = "timeSeries";

public TimeSeriesMappingFactory() {
super(TimeSeriesMapping.Entry.class);
super(TimeSeriesMappingSource.MappingEntry.class);
}

@Override
Expand All @@ -32,10 +32,10 @@ protected List<Set<String>> getFields(SimpleEntityData data) {
}

@Override
protected TimeSeriesMapping.Entry buildModel(SimpleEntityData data) {
protected TimeSeriesMappingSource.MappingEntry buildModel(SimpleEntityData data) {
UUID uuid = data.getUUID(UUID);
UUID participant = data.getUUID(PARTICIPANT);
UUID timeSeries = data.getUUID(TIME_SERIES);
return new TimeSeriesMapping.Entry(uuid, participant, timeSeries);
return new TimeSeriesMappingSource.MappingEntry(uuid, participant, timeSeries);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package edu.ie3.datamodel.io.processor.input;

import edu.ie3.datamodel.io.processor.EntityProcessor;
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
import edu.ie3.datamodel.models.input.*;
import edu.ie3.datamodel.models.input.connector.*;
import edu.ie3.datamodel.models.input.connector.type.LineTypeInput;
Expand All @@ -18,7 +19,6 @@
import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput;
import edu.ie3.datamodel.models.input.thermal.ThermalBusInput;
import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput;
import edu.ie3.datamodel.models.timeseries.mapping.TimeSeriesMapping;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand All @@ -39,7 +39,7 @@ public class InputEntityProcessor extends EntityProcessor<InputEntity> {
/* InputEntity */
OperatorInput.class,
RandomLoadParameters.class,
TimeSeriesMapping.Entry.class,
TimeSeriesMappingSource.MappingEntry.class,
/* - AssetInput */
NodeInput.class,
LineInput.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.source;

import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.models.input.InputEntity;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

/**
* This interface describes basic function to handle mapping between models and their respective
* time series
*/
public interface TimeSeriesMappingSource extends DataSource {
/**
* Get a mapping from model {@link UUID} to the time series {@link UUID}
*
* @return That mapping
*/
Map<UUID, UUID> getMapping();

/**
* Get a time series identifier to a given model identifier
*
* @param modelIdentifier Identifier of the model
* @return An {@link Optional} to the time series identifier
*/
default Optional<UUID> getTimeSeriesUuid(UUID modelIdentifier) {
return Optional.ofNullable(getMapping().get(modelIdentifier));
}

/**
* Get an option on the given time series meta information
*
* @param timeSeriesUuid Unique identifier of the time series in question
* @return An Option onto the meta information
*/
Optional<IndividualTimeSeriesMetaInformation> getTimeSeriesMetaInformation(UUID timeSeriesUuid);

/** Class to represent one entry within the participant to time series mapping */
class MappingEntry extends InputEntity {
private final UUID participant;
private final UUID timeSeries;

public MappingEntry(UUID uuid, UUID participant, UUID timeSeries) {
super(uuid);
this.participant = participant;
this.timeSeries = timeSeries;
}

public UUID getParticipant() {
return participant;
}

public UUID getTimeSeries() {
return timeSeries;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MappingEntry)) return false;
if (!super.equals(o)) return false;
MappingEntry that = (MappingEntry) o;
return participant.equals(that.participant) && timeSeries.equals(that.timeSeries);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), participant, timeSeries);
}

@Override
public String toString() {
return "MappingEntry{"
+ "uuid="
+ getUuid()
+ ", participant="
+ participant
+ ", timeSeries="
+ timeSeries
+ '}';
}
}
}
Loading