Skip to content

Commit

Permalink
Add methods for CGMES validation (#1042)
Browse files Browse the repository at this point in the history
Add methods for CGMES validation.
CGMES conversion context extension.

Signed-off-by: RALAMBOTIANA MIORA <miora.ralambotiana@rte-france.com>
  • Loading branch information
miovd authored and annetill committed Dec 5, 2019
1 parent 19d03f2 commit 5633368
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,18 @@ public static FakeCgmesModel expectedMicroGridBaseCaseBE() {
.shuntCompensators("_002b0a40-3957-46db-b84a-30420083558f",
"_d771118f-36e9-4115-a128-cc3d9ce3e3da")
.synchronousMachines("_3a3b27be-b18b-4385-b557-6735d733baf0",
"_550ebe0d-f2b2-48c1-991f-cebea43a21aa");
"_550ebe0d-f2b2-48c1-991f-cebea43a21aa")
.modelProfiles("urn:uuid:0eb1540d-5ca3-40ab-9bf7-c91ec4c5d7c3",
"urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd1-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239caf0a-38bf-468b-a4d8-15f619886c58",
"urn:uuid:52b712d1-f3b0-4a59-9191-79f2fb1e4c4e",
"urn:uuid:9e383122-10cf-4da3-9785-f404b3541588",
"urn:uuid:c2960b34-0a04-4cd1-9c4d-f3112d85ec6c",
"urn:uuid:d400c631-75a0-4c30-8aed-832b0d282e73",
"urn:uuid:d400c631-75a0-4c30-8aed-832b0d282e73",
"urn:uuid:f2f43818-09c8-4252-9611-7af80c398d20");
}

private static FakeCgmesModel expectedMiniNodeBreaker() {
Expand Down Expand Up @@ -895,7 +906,17 @@ private static FakeCgmesModel expectedMiniNodeBreaker() {
"_ca67be42-750e-4ebf-bfaa-24d446e59a22")
.asynchronousMachines("_062ece1f-ade5-4d20-9c3a-fd8f12d12ec1",
"_ba62884d-8800-41a8-9c26-698297d7ebaa",
"_f184d87b-5565-45ee-89b4-29e8a42d3ad1");
"_f184d87b-5565-45ee-89b4-29e8a42d3ad1")
.modelProfiles("urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd1-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239ecbd2-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239ecbd2-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239ecbd2-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239scbd7-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239tcbd4-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:239vcbd3-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:6fddfd60-de0d-11e2-8f45-b8f6b1180b6d");
}

public static CgmesModel expectedMicroGridType4BE() {
Expand Down Expand Up @@ -1069,6 +1090,18 @@ public static CgmesModel expectedMicroGridType4BE() {
"_36b83adb-3d45-4693-8967-96627b5f9ec9",
"_63454a73-f439-45bb-951a-e7b193986571");
m.staticVarCompensators("_3c69652c-ff14-4550-9a87-b6fdaccbb5f4");
m.modelProfiles().clear();
m.modelProfiles("urn:uuid:1a64ce59-b28c-4b43-bf21-50b51865d777",
"urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd0-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:2399cbd1-9a39-11e0-aa80-0800200c9a66",
"urn:uuid:75271ec4-af11-4a87-8137-d6d2b43b594d",
"urn:uuid:806f9f1b-ff69-4fb5-80f9-a8f393d31ebb",
"urn:uuid:80f1fec9-412f-4ca5-8706-d0d3382e9a71",
"urn:uuid:8d6b5a63-e64e-4a25-955f-9c5e107382eb",
"urn:uuid:96adadbe-902b-4cd6-9fc8-01a56ecbee79",
"urn:uuid:96adadbe-902b-4cd6-9fc8-01a56ecbee79",
"urn:uuid:af6ed855-b817-447c-b436-51d87f630214");
return m;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2019, 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/.
*/
package com.powsybl.cgmes.conversion;

import com.powsybl.commons.extensions.AbstractExtension;
import com.powsybl.iidm.network.Network;

import java.util.Objects;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public class CgmesConversionContextExtension extends AbstractExtension<Network> {

private final Context context;

public CgmesConversionContextExtension(Context context) {
this.context = Objects.requireNonNull(context);
}

public Context getContext() {
return context;
}

@Override
public String getName() {
return "CgmesConversionContext";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,7 @@ public String getFormat() {
@Override
public Network importData(ReadOnlyDataSource ds, NetworkFactory networkFactory, Properties p) {
CgmesModel cgmes = CgmesModelFactory.create(ds, boundary(p), tripleStore(p));
Network network = new Conversion(cgmes, config(p), activatedPostProcessors(p), networkFactory).convert();
if (storeCgmesModelAsNetworkExtension(p)) {
// Store a reference to the original CGMES model inside the IIDM network
// We could also add listeners to be aware of changes in IIDM data
network.addExtension(CgmesModelExtension.class, new CgmesModelExtension(cgmes));
}
return network;
return new Conversion(cgmes, config(p), activatedPostProcessors(p), networkFactory).convert();
}

@Override
Expand Down Expand Up @@ -187,8 +181,19 @@ private Conversion.Config config(Properties p) {
getFormat(),
p,
PROFILE_USED_FOR_INITIAL_STATE_VALUES_PARAMETER,
defaultValueConfig)
);
defaultValueConfig))
.setStoreCgmesModelAsNetworkExtension(
ConversionParameters.readBooleanParameter(
getFormat(),
p,
STORE_CGMES_MODEL_AS_NETWORK_EXTENSION_PARAMETER,
defaultValueConfig))
.setStoreCgmesConversionContextAsNetworkExtension(
ConversionParameters.readBooleanParameter(
getFormat(),
p,
STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION_PARAMETER,
defaultValueConfig));
}

private List<CgmesImportPostProcessor> activatedPostProcessors(Properties p) {
Expand All @@ -206,14 +211,6 @@ private List<CgmesImportPostProcessor> activatedPostProcessors(Properties p) {
.collect(Collectors.toList());
}

private boolean storeCgmesModelAsNetworkExtension(Properties p) {
return ConversionParameters.readBooleanParameter(
getFormat(),
p,
STORE_CGMES_MODEL_AS_NETWORK_EXTENSION_PARAMETER,
defaultValueConfig);
}

private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName, String toName) throws IOException {
if (from.exists(fromName)) {
try (InputStream is = from.newInputStream(fromName);
Expand All @@ -235,6 +232,7 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
public static final String POWSYBL_TRIPLESTORE = "iidm.import.cgmes.powsybl-triplestore";
public static final String PROFILE_USED_FOR_INITIAL_STATE_VALUES = "iidm.import.cgmes.profile-used-for-initial-state-values";
public static final String STORE_CGMES_MODEL_AS_NETWORK_EXTENSION = "iidm.import.cgmes.store-cgmes-model-as-network-extension";
public static final String STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION = "iidm.import.cgmes.store-cgmes-conversion-context-as-network-extension";

private static final Parameter ALLOW_UNSUPPORTED_TAP_CHANGERS_PARAMETER = new Parameter(
ALLOW_UNSUPPORTED_TAP_CHANGERS,
Expand Down Expand Up @@ -281,6 +279,11 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
"Profile used for initial state values",
"SSH"
);
private static final Parameter STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION_PARAMETER = new Parameter(
STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION,
ParameterType.BOOLEAN,
"Store the CGMES-IIDM terminal mapping as a network extension",
Boolean.FALSE);
private static final Parameter STORE_CGMES_MODEL_AS_NETWORK_EXTENSION_PARAMETER = new Parameter(
STORE_CGMES_MODEL_AS_NETWORK_EXTENSION,
ParameterType.BOOLEAN,
Expand All @@ -292,10 +295,12 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
ALLOW_UNSUPPORTED_TAP_CHANGERS_PARAMETER,
CHANGE_SIGN_FOR_SHUNT_REACTIVE_POWER_FLOW_INITIAL_STATE_PARAMETER,
CONVERT_BOUNDARY_PARAMETER,
CONVERT_SV_INJECTIONS_PARAMETER,
CREATE_BUSBAR_SECTION_FOR_EVERY_CONNECTIVITY_NODE_PARAMETER,
POST_PROCESSORS_PARAMETER,
POWSYBL_TRIPLESTORE_PARAMETER,
STORE_CGMES_MODEL_AS_NETWORK_EXTENSION_PARAMETER,
POST_PROCESSORS_PARAMETER);
STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION_PARAMETER,
STORE_CGMES_MODEL_AS_NETWORK_EXTENSION_PARAMETER);

private final Parameter boundaryLocationParameter;
private final Map<String, CgmesImportPostProcessor> postProcessors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ public Network convert() {
postProcessor.process(network, cgmes.tripleStore(), profiling);
}

if (config.storeCgmesModelAsNetworkExtension()) {
// Store a reference to the original CGMES model inside the IIDM network
// We could also add listeners to be aware of changes in IIDM data
network.addExtension(CgmesModelExtension.class, new CgmesModelExtension(cgmes));
}
if (config.storeCgmesConversionContextAsNetworkExtension()) {
// Store the terminal mapping in an extension for external validation
network.addExtension(CgmesConversionContextExtension.class, new CgmesConversionContextExtension(context));
}

profiling.report();
return network;
}
Expand Down Expand Up @@ -422,6 +432,24 @@ public Config setProfileUsedForInitialStateValues(String profileUsedForInitialFl
return this;
}

public boolean storeCgmesModelAsNetworkExtension() {
return storeCgmesModelAsNetworkExtension;
}

public Config setStoreCgmesModelAsNetworkExtension(boolean storeCgmesModelAsNetworkExtension) {
this.storeCgmesModelAsNetworkExtension = storeCgmesModelAsNetworkExtension;
return this;
}

public boolean storeCgmesConversionContextAsNetworkExtension() {
return storeCgmesConversionContextAsNetworkExtension;
}

public Config setStoreCgmesConversionContextAsNetworkExtension(boolean storeCgmesTerminalMappingAsNetworkExtension) {
this.storeCgmesConversionContextAsNetworkExtension = storeCgmesTerminalMappingAsNetworkExtension;
return this;
}

private boolean allowUnsupportedTapChangers = true;
private boolean convertBoundary = false;
private boolean changeSignForShuntReactivePowerFlowInitialState = false;
Expand All @@ -431,6 +459,8 @@ public Config setProfileUsedForInitialStateValues(String profileUsedForInitialFl
private boolean createBusbarSectionForEveryConnectivityNode = false;
private boolean convertSvInjections = true;
private StateProfile profileUsedForInitialStateValues = SSH;
private boolean storeCgmesModelAsNetworkExtension = true;
private boolean storeCgmesConversionContextAsNetworkExtension = false;

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2019, 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/.
*/
package com.powsybl.cgmes.conversion;

import com.powsybl.cgmes.conformity.test.CgmesConformity1Catalog;
import com.powsybl.iidm.network.Network;
import org.junit.Test;

import java.util.Properties;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public class CgmesConversionContextExtensionTest {

@Test
public void test() {
Properties properties = new Properties();
properties.put(CgmesImport.STORE_CGMES_CONVERSION_CONTEXT_AS_NETWORK_EXTENSION, "true");
Network network = new CgmesImport().importData(CgmesConformity1Catalog.microGridBaseCaseBE().dataSource(), properties);
CgmesConversionContextExtension extension = network.getExtension(CgmesConversionContextExtension.class);
assertNotNull(extension);
assertTrue(extension.getContext().config().storeCgmesConversionContextAsNetworkExtension());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,8 @@ static String baseName(ReadOnlyDataSource ds) {
CgmesContainer container(String containerId);

double nominalVoltage(String baseVoltageId);

default PropertyBags modelProfiles() {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public boolean hasEquipmentCore() {
if (p != null && p.contains("/EquipmentCore/")) {
if (LOG.isInfoEnabled()) {
LOG.info("Model contains Equipment Core data profile in model {}",
m.get(CgmesNames.FULL_MODEL));
m.get(CgmesNames.FULL_MODEL));
}
return true;
}
Expand Down Expand Up @@ -162,10 +162,10 @@ public boolean isNodeBreaker() {
boolean isNodeBreaker = eqModelHasEquipmentOperationProfile.values().stream().allMatch(Boolean::valueOf);
if (isNodeBreaker) {
LOG.info(
"All FullModel objects have EquipmentOperation profile, so conversion will be considered node-breaker");
"All FullModel objects have EquipmentOperation profile, so conversion will be considered node-breaker");
} else {
LOG.info(
"Following FullModel objects do not have EquipmentOperation profile, so conversion will not be considered node-breaker:");
"Following FullModel objects do not have EquipmentOperation profile, so conversion will not be considered node-breaker:");
eqModelHasEquipmentOperationProfile.entrySet().forEach(meqop -> {
if (!meqop.getValue()) {
LOG.info(" {}", meqop.getKey());
Expand Down Expand Up @@ -435,6 +435,11 @@ public PropertyBags dcTerminalsTP() {
return namedQuery("dcTerminalsTP");
}

@Override
public PropertyBags modelProfiles() {
return namedQuery(MODEL_PROFILES);
}

public PropertyBags namedQuery(String name, String... params) {
String queryText = queryCatalog.get(name);
if (queryText == null) {
Expand Down Expand Up @@ -493,8 +498,8 @@ public void add(CgmesSubset subset, String type, PropertyBags objects) {
private String contextNameFor(CgmesSubset subset) {
String contextNameEQ = contextNameForEquipmentSubset();
return contextNameEQ != null
? buildContextNameForSubsetFrom(contextNameEQ, subset)
: modelId() + "_" + subset + ".xml";
? buildContextNameForSubsetFrom(contextNameEQ, subset)
: modelId() + "_" + subset + ".xml";
}

private String contextNameForEquipmentSubset() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

import static org.junit.Assert.*;
Expand All @@ -30,7 +29,7 @@ public CgmesModelTester(TestGridModel gm) {
this.gridModel = gm;
}

public void test() throws IOException {
public void test() {
ReadOnlyDataSource ds = gridModel.dataSource();

// Check that the case exists
Expand Down Expand Up @@ -91,6 +90,7 @@ private void testCompare(CgmesModel expected, CgmesModel actual) {
testPropertyBags(expected.staticVarCompensators(), actual.staticVarCompensators());
testPropertyBags(expected.synchronousMachines(), actual.synchronousMachines());
testPropertyBags(expected.asynchronousMachines(), actual.asynchronousMachines());
testPropertyBags(expected.modelProfiles(), actual.modelProfiles());
}

private void testPropertyBags(PropertyBags expecteds, PropertyBags actuals) {
Expand Down
Loading

0 comments on commit 5633368

Please sign in to comment.