Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deserialization in DynawoModelsSupplier/DynawoEventModelsSupplier #363

Merged
merged 8 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.powsybl.dynawaltz.suppliers;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.powsybl.commons.PowsyblException;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class SupplierJsonDeserializer<T> {

private final StdDeserializer<List<T>> deserializer;

public SupplierJsonDeserializer(StdDeserializer<List<T>> deserializer) {
this.deserializer = deserializer;
}

public List<T> deserialize(Path path) {
try {
Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
return setupObjectMapper().readValue(reader, new TypeReference<>() {
});
} catch (IOException e) {
throw new PowsyblException("JSON input cannot be read", e);
}
}

public List<T> deserialize(InputStream is) {
try {
return setupObjectMapper().readValue(is, new TypeReference<>() {
});
} catch (IOException e) {
throw new PowsyblException("JSON input cannot be read", e);
}
}

private ObjectMapper setupObjectMapper() {
return new ObjectMapper().registerModule(new SimpleModule().addDeserializer(List.class, deserializer));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@
import com.powsybl.commons.report.ReportNode;
import com.powsybl.dynamicsimulation.DynamicModel;
import com.powsybl.dynamicsimulation.DynamicModelsSupplier;
import com.powsybl.dynawaltz.DynaWaltzProvider;
import com.powsybl.dynawaltz.builders.ModelBuilder;
import com.powsybl.dynawaltz.builders.ModelConfigsHandler;
import com.powsybl.dynawaltz.suppliers.Property;
import com.powsybl.dynawaltz.suppliers.SupplierJsonDeserializer;
import com.powsybl.iidm.network.Network;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

/**
* Instantiates an {@link DynamicModelConfig} list from {@link DynamicModelConfig}
* Instantiates an {@link DynamicModelConfig} list from {@link DynamicModelConfig} or JSON input
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class DynawoModelsSupplier implements DynamicModelsSupplier {
Expand All @@ -30,10 +34,23 @@ public class DynawoModelsSupplier implements DynamicModelsSupplier {

private final List<DynamicModelConfig> dynamicModelConfigs;

public static DynawoModelsSupplier load(InputStream is) {
return new DynawoModelsSupplier(new SupplierJsonDeserializer<>(new DynamicModelConfigsJsonDeserializer()).deserialize(is));
}

public static DynawoModelsSupplier load(Path path) {
return new DynawoModelsSupplier(new SupplierJsonDeserializer<>(new DynamicModelConfigsJsonDeserializer()).deserialize(path));
}

public DynawoModelsSupplier(List<DynamicModelConfig> dynamicModelConfigs) {
this.dynamicModelConfigs = dynamicModelConfigs;
}

@Override
public String getName() {
return DynaWaltzProvider.NAME;
}

@Override
public List<DynamicModel> get(Network network, ReportNode reportNode) {
return dynamicModelConfigs.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,44 @@
import com.powsybl.commons.report.ReportNode;
import com.powsybl.dynamicsimulation.EventModel;
import com.powsybl.dynamicsimulation.EventModelsSupplier;
import com.powsybl.dynawaltz.DynaWaltzProvider;
import com.powsybl.dynawaltz.builders.ModelBuilder;
import com.powsybl.dynawaltz.builders.ModelConfigsHandler;
import com.powsybl.dynawaltz.suppliers.Property;
import com.powsybl.dynawaltz.suppliers.SupplierJsonDeserializer;
import com.powsybl.iidm.network.Network;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

/**
* Instantiates an {@link EventModel} list from {@link EventModelConfig}
* Instantiates an {@link EventModel} list from {@link EventModelConfig} or JSON input
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class DynawoEventModelsSupplier implements EventModelsSupplier {

private final List<EventModelConfig> eventModelConfigs;

public static DynawoEventModelsSupplier load(InputStream is) {
return new DynawoEventModelsSupplier(new SupplierJsonDeserializer<>(new EventModelConfigsJsonDeserializer()).deserialize(is));
}

public static DynawoEventModelsSupplier load(Path path) {
return new DynawoEventModelsSupplier(new SupplierJsonDeserializer<>(new EventModelConfigsJsonDeserializer()).deserialize(path));
}

public DynawoEventModelsSupplier(List<EventModelConfig> eventModelConfigs) {
this.eventModelConfigs = eventModelConfigs;
}

@Override
public String getName() {
return DynaWaltzProvider.NAME;
}

@Override
public List<EventModel> get(Network network, ReportNode reportNode) {
return eventModelConfigs.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
*/
package com.powsybl.dynawaltz.suppliers;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.dynamicsimulation.EventModel;
Expand All @@ -23,16 +20,19 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
class DynawoEventModelsSuppliersTest {
class DynawoEventModelsSupplierTest {

@Test
void testEventSupplier() {
Expand Down Expand Up @@ -66,12 +66,19 @@ void testWrongNameBuilder() {
assertTrue(events.isEmpty());
}

@Test
void testSupplierFromPath() throws URISyntaxException {
Network network = EurostagTutorialExample1Factory.create();
Path path = Path.of(Objects.requireNonNull(getClass().getResource("/suppliers/mappingEvent.json")).toURI());
List<EventModel> models = DynawoEventModelsSupplier.load(path).get(network);
assertEquals(1, models.size());
}

@Test
void testEventModelConfigDeserializer() throws IOException {
ObjectMapper objectMapper = setupObjectMapper();
SupplierJsonDeserializer<EventModelConfig> deserializer = new SupplierJsonDeserializer<>(new EventModelConfigsJsonDeserializer());
try (InputStream is = getClass().getResourceAsStream("/suppliers/mappingEvent.json")) {
List<EventModelConfig> configs = objectMapper.readValue(is, new TypeReference<>() {
});
List<EventModelConfig> configs = deserializer.deserialize(is);
assertEquals(1, configs.size());
assertThat(configs.get(0)).usingRecursiveComparison().isEqualTo(getActivePowerVariationConfig());
}
Expand Down Expand Up @@ -133,12 +140,4 @@ private static EventModelConfig getActivePowerVariationConfig() {
.type(PropertyType.DOUBLE)
.build()));
}

private static ObjectMapper setupObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(List.class, new EventModelConfigsJsonDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
*/
package com.powsybl.dynawaltz.suppliers;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.dynamicsimulation.DynamicModel;
Expand All @@ -23,17 +20,20 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
class DynawoModelsSuppliersTest {
class DynawoModelsSupplierTest {

@Test
void testDynamicModelSupplier() {
Expand Down Expand Up @@ -74,12 +74,19 @@ void testWrongNameBuilder() {
assertTrue(models.isEmpty());
}

@Test
void testSupplierFromPath() throws URISyntaxException {
Network network = EurostagTutorialExample1Factory.createWithLFResults();
Path path = Path.of(Objects.requireNonNull(getClass().getResource("/suppliers/mappingDynamicModel.json")).toURI());
List<DynamicModel> models = DynawoModelsSupplier.load(path).get(network);
assertEquals(2, models.size());
}

@Test
void testModelConfigDeserializer() throws IOException {
ObjectMapper objectMapper = setupObjectMapper();
SupplierJsonDeserializer<DynamicModelConfig> deserializer = new SupplierJsonDeserializer<>(new DynamicModelConfigsJsonDeserializer());
try (InputStream is = getClass().getResourceAsStream("/suppliers/mappingDynamicModel.json")) {
List<DynamicModelConfig> configs = objectMapper.readValue(is, new TypeReference<>() {
});
List<DynamicModelConfig> configs = deserializer.deserialize(is);
assertEquals(2, configs.size());
assertThat(configs.get(0)).usingRecursiveComparison().isEqualTo(getLoadConfig());
assertThat(configs.get(1)).usingRecursiveComparison().isEqualTo(getTcbConfig());
Expand Down Expand Up @@ -177,12 +184,4 @@ private static DynamicModelConfig getSimpleTcbConfig() {
.build()
));
}

private static ObjectMapper setupObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(List.class, new DynamicModelConfigsJsonDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2024, 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.dynawaltz.suppliers;

import com.powsybl.commons.PowsyblException;
import com.powsybl.dynawaltz.suppliers.events.EventModelConfig;
import com.powsybl.dynawaltz.suppliers.events.EventModelConfigsJsonDeserializer;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
class SupplierJsonDeserializerTest {

@Test
void testPathException() {
Path path = Path.of("wrongURI");
SupplierJsonDeserializer<EventModelConfig> deserializer = new SupplierJsonDeserializer<>(new EventModelConfigsJsonDeserializer());
Exception e = assertThrows(PowsyblException.class, () -> deserializer.deserialize(path));
assertEquals("JSON input cannot be read", e.getMessage());
}

@Test
void testInputStreamException() throws IOException {
try (InputStream is = InputStream.nullInputStream()) {
SupplierJsonDeserializer<EventModelConfig> deserializer = new SupplierJsonDeserializer<>(new EventModelConfigsJsonDeserializer());
Exception e = assertThrows(PowsyblException.class, () -> deserializer.deserialize(is));
assertEquals("JSON input cannot be read", e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import com.powsybl.dynawaltz.DynaWaltzParameters;
import com.powsybl.dynawaltz.DynaWaltzProvider;
import com.powsybl.dynawaltz.parameters.ParametersSet;
import com.powsybl.dynawaltz.suppliers.dynamicmodels.DynawoModelsSupplier;
import com.powsybl.dynawaltz.suppliers.events.DynawoEventModelsSupplier;
import com.powsybl.dynawaltz.xml.ParametersXml;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VariantManagerConstants;
Expand Down Expand Up @@ -273,6 +275,35 @@ void testSimulationError() {
assertTrue(result.getCurves().isEmpty());
}

@Test
void testIeee14DynawoSuppliers() {
Network network = Network.read(new ResourceDataSource("IEEE14", new ResourceSet("/ieee14", "IEEE14.iidm")));

DynamicModelsSupplier dynamicModelsSupplier = DynawoModelsSupplier.load(getResourceAsStream("/ieee14/disconnectline/dynamicModels.json"));
EventModelsSupplier eventModelsSupplier = DynawoEventModelsSupplier.load(getResourceAsStream("/ieee14/disconnectline/eventModels.json"));

List<ParametersSet> modelsParameters = ParametersXml.load(getResourceAsStream("/ieee14/disconnectline/models.par"));
ParametersSet networkParameters = ParametersXml.load(getResourceAsStream("/ieee14/disconnectline/network.par"), "8");
ParametersSet solverParameters = ParametersXml.load(getResourceAsStream("/ieee14/disconnectline/solvers.par"), "2");
dynaWaltzParameters.setModelsParameters(modelsParameters)
.setNetworkParameters(networkParameters)
.setSolverParameters(solverParameters)
.setSolverType(DynaWaltzParameters.SolverType.IDA)
.setDefaultDumpFileParameters()
.setTimelineExportMode(DynaWaltzParameters.ExportMode.XML);

DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, CurvesSupplier.empty(),
VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP)
.join();

assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus());
assertTrue(result.getStatusText().isEmpty());
assertEquals(0, result.getCurves().size());
List<TimelineEvent> timeLine = result.getTimeLine();
assertEquals(11, timeLine.size());
checkFirstTimeLineEvent(timeLine.get(0), 0, "_GEN____8_SM", "PMIN : activation");
}

private void checkFirstTimeLineEvent(TimelineEvent event, double time, String modelName, String message) {
assertEquals(time, event.time());
assertEquals(modelName, event.modelName());
Expand Down
Loading
Loading