Skip to content

Commit

Permalink
Add deserialization in DynawoModelsSupplier/DynawoEventModelsSupplier (
Browse files Browse the repository at this point in the history
…#363)

* Add deserialization in DynawoModelsSupplier and DynawoEventModelsSupplier through a load static method
* Add integration test
* Add unit test

Signed-off-by: lisrte <[email protected]>
  • Loading branch information
Lisrte authored Jul 2, 2024
1 parent 93ea4ad commit fde10f2
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 32 deletions.
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,34 @@ 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)
.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

0 comments on commit fde10f2

Please sign in to comment.