com.powsybl.metrix.mapping.timeseries.CalculatedTimeSeriesStore Maven / Gradle / Ivy
/*
* Copyright (c) 2020, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.metrix.mapping.timeseries;
import com.powsybl.timeseries.*;
import com.powsybl.timeseries.ast.NodeCalc;
import com.powsybl.timeseries.ast.TimeSeriesNames;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Paul Bui-Quang {@literal }
*/
public class CalculatedTimeSeriesStore implements ReadOnlyTimeSeriesStore {
private final Map nodes;
private final Map> tags;
private final Set indexSet = new HashSet<>();
private final Set dependentTsNamesVerified = new HashSet<>();
private final ReadOnlyTimeSeriesStore store;
public CalculatedTimeSeriesStore(Map nodes, Map> tags, ReadOnlyTimeSeriesStore store) {
this.nodes = Objects.requireNonNull(nodes);
this.tags = Objects.requireNonNull(tags);
this.store = Objects.requireNonNull(store);
}
public CalculatedTimeSeriesStore(Map nodes, ReadOnlyTimeSeriesStore store) {
this(nodes, Map.of(), store);
}
public NodeCalc getTimeSeriesNodeCalc(String timeSeriesName) {
Objects.requireNonNull(timeSeriesName);
return nodes.get(timeSeriesName);
}
@Override
public Set getTimeSeriesNames(TimeSeriesFilter filter) {
return nodes.keySet();
}
@Override
public boolean timeSeriesExists(String timeSeriesName) {
Objects.requireNonNull(timeSeriesName);
return nodes.containsKey(timeSeriesName);
}
@Override
public Set getTimeSeriesDataVersions(String timeSeriesName) {
NodeCalc node = nodes.get(timeSeriesName);
if (node == null) {
return Collections.emptySet();
}
return CalculatedTimeSeries.computeVersions(node, new FromStoreTimeSeriesNameResolver(store, -1));
}
@Override
public Set getTimeSeriesDataVersions() {
return store.getTimeSeriesDataVersions();
}
@Override
public Optional getTimeSeriesMetadata(String timeSeriesName) {
Objects.requireNonNull(timeSeriesName);
NodeCalc node = nodes.get(timeSeriesName);
if (node == null) {
return Optional.empty();
}
Optional optFstOrderNodeCalc = findFirstOrderNodeCalc(node, store.getTimeSeriesNames(null));
TimeSeriesIndex index = optFstOrderNodeCalc
.map(this::computeIndex)
.orElse(InfiniteTimeSeriesIndex.INSTANCE);
Map timeSeriesTags = tags.containsKey(timeSeriesName) ? tags.get(timeSeriesName) : Map.of();
return Optional.of(new TimeSeriesMetadata(timeSeriesName, TimeSeriesDataType.DOUBLE, timeSeriesTags, index));
}
private Optional findFirstOrderNodeCalc(NodeCalc node, Set storedTimeSeriesNames) {
Set dependentTsNames = TimeSeriesNames.list(node);
if (dependentTsNames.stream().anyMatch(storedTimeSeriesNames::contains)) {
return Optional.of(node);
}
if (dependentTsNames.isEmpty()) {
return Optional.empty();
}
return nodes.entrySet()
.stream()
.filter(tsNode -> dependentTsNames.contains(tsNode.getKey()))
.map(tsNode -> findFirstOrderNodeCalc(tsNode.getValue(), storedTimeSeriesNames))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
}
private TimeSeriesIndex computeIndex(NodeCalc node) {
Set dependentTsNames = TimeSeriesNames.list(node);
Set dependentTsNamesToVerify = new HashSet<>(dependentTsNames);
dependentTsNamesToVerify.removeAll(dependentTsNamesVerified);
if (!dependentTsNamesToVerify.isEmpty()) {
indexSet.add(CalculatedTimeSeries.computeIndex(node, new FromStoreTimeSeriesNameResolver(store, -1)));
dependentTsNamesVerified.addAll(dependentTsNames);
}
return indexSet.iterator().next();
}
@Override
public List getTimeSeriesMetadata(Set timeSeriesNames) {
Objects.requireNonNull(timeSeriesNames);
return timeSeriesNames.stream().filter(this::timeSeriesExists).map(this::getTimeSeriesMetadata)
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
}
private CalculatedTimeSeries createCalculatedTimeSeries(String timeSeriesName, NodeCalc nodeCalc, int version) {
CalculatedTimeSeries calculatedTimeSeries = new CalculatedTimeSeries(timeSeriesName, nodeCalc);
calculatedTimeSeries.setTimeSeriesNameResolver(new FromStoreTimeSeriesNameResolver(store, version));
return calculatedTimeSeries;
}
@Override
public Optional getDoubleTimeSeries(String timeSeriesName, int version) {
Objects.requireNonNull(timeSeriesName);
NodeCalc node = nodes.get(timeSeriesName);
if (node == null) {
return Optional.empty();
}
return Optional.of(createCalculatedTimeSeries(timeSeriesName, node, version));
}
@Override
public List getDoubleTimeSeries(Set timeSeriesNames, int version) {
return timeSeriesNames.stream().map(timeSeriesName -> getDoubleTimeSeries(timeSeriesName, version))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
@Override
public List getDoubleTimeSeries(int version) {
return nodes.entrySet().stream()
.map(e -> createCalculatedTimeSeries(e.getKey(), e.getValue(), version))
.collect(Collectors.toList());
}
@Override
public List getStringTimeSeries(Set timeSeriesNames, int version) {
return Collections.emptyList();
}
@Override
public Optional getStringTimeSeries(String timeSeriesName, int version) {
return Optional.empty();
}
@Override
public void addListener(TimeSeriesStoreListener listener) {
// nothing to do
}
@Override
public void removeListener(TimeSeriesStoreListener listener) {
// nothing to do
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy