Skip to content

Commit

Permalink
Handling of metadata model is now done in the CgmesExport class
Browse files Browse the repository at this point in the history
Signed-off-by: Romain Courtier <romain.courtier@rte-france.com>
  • Loading branch information
rcourtier committed Mar 28, 2024
1 parent 5c7cdc4 commit 4dae10f
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 296 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
package com.powsybl.cgmes.completion;

import com.google.auto.service.AutoService;
import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.CgmesImportPreProcessor;
import com.powsybl.cgmes.conversion.export.CgmesExportContext;
import com.powsybl.cgmes.conversion.export.CgmesExportUtil;
import com.powsybl.cgmes.conversion.export.elements.*;
import com.powsybl.cgmes.extensions.CgmesTopologyKind;
import com.powsybl.cgmes.extensions.CimCharacteristicsAdder;
import com.powsybl.cgmes.model.CgmesMetadataModel;
import com.powsybl.cgmes.model.CgmesModel;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesSubset;
Expand Down Expand Up @@ -220,7 +222,9 @@ private static void writeHeader(Network network, XMLStreamWriter writer, CgmesEx
String euNamespace = context.getCim().getEuNamespace();
CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), euNamespace, writer);
if (context.getCimVersion() >= 16) {
CgmesExportUtil.writeModelDescription(network, CgmesSubset.EQUIPMENT, writer, context.getExportedEQModel(), context);
CgmesMetadataModel eqModel = CgmesExport.initializeModelForExport(
network, CgmesSubset.EQUIPMENT, null, null, null, context, false);
CgmesExportUtil.writeModelDescription(network, CgmesSubset.EQUIPMENT, writer, eqModel, context);
}
}

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import com.powsybl.cgmes.conversion.naming.NamingStrategy;
import com.powsybl.cgmes.conversion.naming.NamingStrategyFactory;
import com.powsybl.cgmes.extensions.*;
import com.powsybl.cgmes.model.CgmesMetadataModel;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesNamespace;
import com.powsybl.cgmes.model.CgmesSubset;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.Identifiable;
Expand Down Expand Up @@ -59,18 +57,10 @@ public class CgmesExportContext {
private CgmesTopologyKind topologyKind = CgmesTopologyKind.BUS_BRANCH;
private ZonedDateTime scenarioTime = ZonedDateTime.now();
private ReportNode reportNode = ReportNode.NO_OP;
private String boundaryEqId; // may be null
private String boundaryTpId; // may be null
private String businessProcess = DEFAULT_BUSINESS_PROCESS;

private final CgmesMetadataModel exportedEQModel = new CgmesMetadataModel(CgmesSubset.EQUIPMENT, DEFAULT_MODELING_AUTHORITY_SET_VALUE);
private final CgmesMetadataModel exportedTPModel = new CgmesMetadataModel(CgmesSubset.TOPOLOGY, DEFAULT_MODELING_AUTHORITY_SET_VALUE);
private final CgmesMetadataModel exportedSVModel = new CgmesMetadataModel(CgmesSubset.STATE_VARIABLES, DEFAULT_MODELING_AUTHORITY_SET_VALUE);
private final CgmesMetadataModel exportedSSHModel = new CgmesMetadataModel(CgmesSubset.STEADY_STATE_HYPOTHESIS, DEFAULT_MODELING_AUTHORITY_SET_VALUE);

private NamingStrategy namingStrategy = new NamingStrategy.Identity();

public static final boolean EXPORT_AS_CGM_VALUE = false;
public static final boolean CGM_EXPORT_VALUE = false;
public static final boolean MODEL_UPDATE_VALUE = true;
public static final boolean EXPORT_BOUNDARY_POWER_FLOWS_DEFAULT_VALUE = true;
public static final boolean EXPORT_POWER_FLOWS_FOR_SWITCHES_DEFAULT_VALUE = true;
public static final boolean EXPORT_TRANSFORMERS_WITH_HIGHEST_VOLTAGE_AT_END1_DEFAULT_VALUE = false;
Expand Down Expand Up @@ -102,38 +92,6 @@ public class CgmesExportContext {
private final Map<String, Bus> topologicalNodes = new HashMap<>();
private final ReferenceDataProvider referenceDataProvider;

public void updateDependenciesIGM() {
// Update dependencies in a way that:
// [EQ.dependentOn EQ_BD]
// SV.dependentOn TP, SSH[, TP_BD]
// TP.dependentOn EQ
// SSH.dependentOn EQ
String eqModelId = getExportedEQModel().getId();
if (eqModelId == null || eqModelId.isEmpty()) {
return;
}

getExportedTPModel()
.clearDependencies()
.addDependentOn(eqModelId);

getExportedSSHModel()
.clearDependencies()
.addDependentOn(eqModelId);

getExportedSVModel()
.clearDependencies()
.addDependentOn(getExportedTPModel().getId())
.addDependentOn(getExportedSSHModel().getId());

if (boundaryEqId != null) {
getExportedEQModel().addDependentOn(boundaryEqId);
}
if (boundaryTpId != null) {
getExportedSVModel().addDependentOn(boundaryTpId);
}
}

public String getFictitiousContainerFor(Identifiable<?> id) {
return fictitiousContainers.get(id.getId());
}
Expand All @@ -143,7 +101,6 @@ public void setFictitiousContainerFor(Identifiable<?> id, String containerId) {
}

public CgmesExportContext() {
initializeExportedModelProfiles(this.cim);
referenceDataProvider = null;
}

Expand All @@ -164,7 +121,6 @@ public CgmesExportContext(Network network, ReferenceDataProvider referenceDataPr
}

public CgmesExportContext(Network network, ReferenceDataProvider referenceDataProvider, NamingStrategy namingStrategy) {
initializeExportedModelProfiles(this.cim);
this.referenceDataProvider = referenceDataProvider;
this.namingStrategy = namingStrategy;
CimCharacteristics cimCharacteristics = network.getExtension(CimCharacteristics.class);
Expand All @@ -175,43 +131,9 @@ public CgmesExportContext(Network network, ReferenceDataProvider referenceDataPr
topologyKind = networkTopologyKind(network);
}
scenarioTime = network.getCaseDate();
CgmesMetadataModels models = network.getExtension(CgmesMetadataModels.class);
if (models != null) {
models.getModelForSubset(CgmesSubset.EQUIPMENT).ifPresent(eq -> prepareExportedModelFrom(exportedEQModel, eq));
models.getModelForSubset(CgmesSubset.STEADY_STATE_HYPOTHESIS).ifPresent(ssh -> prepareExportedModelFrom(exportedSSHModel, ssh));
models.getModelForSubset(CgmesSubset.TOPOLOGY).ifPresent(tp -> prepareExportedModelFrom(exportedTPModel, tp));
models.getModelForSubset(CgmesSubset.STATE_VARIABLES).ifPresent(sv -> prepareExportedModelFrom(exportedSVModel, sv));
}
addIidmMappings(network);
}

/**
* Set for each exported model the profile relative to the cim version.
* @param cim The cim version from which depends the models profiles uri.
*/
private void initializeExportedModelProfiles(CgmesNamespace.Cim cim) {
if (cim.hasProfiles()) {
exportedEQModel.setProfile(cim.getProfileUri("EQ"));
exportedTPModel.setProfile(cim.getProfileUri("TP"));
exportedSVModel.setProfile(cim.getProfileUri("SV"));
exportedSSHModel.setProfile(cim.getProfileUri("SSH"));
}
}

/**
* Update the model used for the export according to the network model.
* All the metadata information will be duplicated, except for the version that will be incremented.
* @param exportedModel The {@link CgmesMetadataModel} used for the export.
* @param fromModel The {@link CgmesMetadataModel} attached to the network.
*/
private void prepareExportedModelFrom(CgmesMetadataModel exportedModel, CgmesMetadataModel fromModel) {
exportedModel.setDescription(fromModel.getDescription());
exportedModel.setVersion(fromModel.getVersion() + 1);
exportedModel.addSupersedes(fromModel.getId());
exportedModel.addDependentOn(fromModel.getDependentOn());
exportedModel.setModelingAuthoritySet(fromModel.getModelingAuthoritySet());
}

private CgmesTopologyKind networkTopologyKind(Network network) {
for (VoltageLevel vl : network.getVoltageLevels()) {
if (vl.getTopologyKind().equals(TopologyKind.NODE_BREAKER)) {
Expand Down Expand Up @@ -348,16 +270,6 @@ public boolean isExportedEquipment(Identifiable<?> c) {
return !ignored;
}

public CgmesExportContext setBoundaryEqId(String boundaryEqId) {
this.boundaryEqId = boundaryEqId;
return this;
}

public CgmesExportContext setBoundaryTpId(String boundaryTpId) {
this.boundaryTpId = boundaryTpId;
return this;
}

private void addIidmMappingsSwitchTerminals(Network network) {
for (Switch sw : network.getSwitches()) {
String terminal1Id = sw.getAliasFromType(Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TERMINAL + "1").orElse(null);
Expand Down Expand Up @@ -618,7 +530,6 @@ public int getCimVersion() {

public CgmesExportContext setCimVersion(int cimVersion) {
cim = CgmesNamespace.getCim(cimVersion);
initializeExportedModelProfiles(cim);
return this;
}

Expand All @@ -640,22 +551,6 @@ public CgmesExportContext setScenarioTime(ZonedDateTime scenarioTime) {
return this;
}

public CgmesMetadataModel getExportedEQModel() {
return exportedEQModel;
}

public CgmesMetadataModel getExportedTPModel() {
return exportedTPModel;
}

public CgmesMetadataModel getExportedSVModel() {
return exportedSVModel;
}

public CgmesMetadataModel getExportedSSHModel() {
return exportedSSHModel;
}

public boolean exportBoundaryPowerFlows() {
return exportBoundaryPowerFlows;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,24 @@ public static void writeRdfRoot(String cimNamespace, String euPrefix, String euN
writer.writeNamespace("md", MD_NAMESPACE);
}

public static void initializeModelId(Network network, CgmesMetadataModel model, CgmesExportContext context) {
// The ref to build a unique model id must contain:
// the network, the subset (EQ, SSH, SV, ...), the time of the scenario, the version, the business process and the FULL_MODEL part
// If we use name-based UUIDs this ensures that the UUID for the model will be specific enough
CgmesObjectReference[] modelRef = {
refTyped(network),
ref(model.getSubset()),
ref(DATE_TIME_FORMATTER.format(context.getScenarioTime())),
ref(String.valueOf(model.getVersion())),
ref(context.getBusinessProcess()),
Part.FULL_MODEL};
String modelId = "urn:uuid:" + context.getNamingStrategy().getCgmesId(modelRef);
model.setId(modelId);
}

public static void writeModelDescription(Network network, CgmesSubset subset, XMLStreamWriter writer, CgmesMetadataModel modelDescription, CgmesExportContext context) throws XMLStreamException {
if (modelDescription.getId() == null || modelDescription.getId().isEmpty()) {
// The ref to build a unique model id must contain:
// the network, the subset (EQ, SSH, SV, ...), the time of the scenario, the version, the business process and the FULL_MODEL part
// If we use name-based UUIDs this ensures that the UUID for the model will be specific enough
CgmesObjectReference[] modelRef = {
refTyped(network),
ref(subset),
ref(DATE_TIME_FORMATTER.format(context.getScenarioTime())),
ref(String.valueOf(modelDescription.getVersion())),
ref(context.getBusinessProcess()),
Part.FULL_MODEL};
String modelId = "urn:uuid:" + context.getNamingStrategy().getCgmesId(modelRef);
modelDescription.setId(modelId);
initializeModelId(network, modelDescription, context);
}
writer.writeStartElement(MD_NAMESPACE, "FullModel");
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.ABOUT, modelDescription.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
*/
package com.powsybl.cgmes.conversion.export;

import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.conversion.naming.CgmesObjectReference;
import com.powsybl.cgmes.conversion.naming.NamingStrategy;
import com.powsybl.cgmes.conversion.export.elements.*;
import com.powsybl.cgmes.extensions.*;
import com.powsybl.cgmes.model.CgmesMetadataModel;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesSubset;
import com.powsybl.commons.PowsyblException;
Expand Down Expand Up @@ -54,7 +56,12 @@ public static void write(Network network, XMLStreamWriter writer) {
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context) {
context.setExportEquipment(true);
CgmesMetadataModel model = CgmesExport.initializeModelForExport(
network, CgmesSubset.EQUIPMENT, null, null, null, context, false);
write(network, writer, context, model);
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, CgmesMetadataModel model) {
try {
boolean writeConnectivityNodes = context.writeConnectivityNodes();

Expand All @@ -68,7 +75,7 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), euNamespace, writer);

if (context.getCimVersion() >= 16) {
CgmesExportUtil.writeModelDescription(network, CgmesSubset.EQUIPMENT, writer, context.getExportedEQModel(), context);
CgmesExportUtil.writeModelDescription(network, CgmesSubset.EQUIPMENT, writer, model, context);
}

Map<String, String> mapNodeKey2NodeId = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.cgmes.conversion.export;

import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.extensions.CgmesTapChanger;
import com.powsybl.cgmes.extensions.CgmesTapChangers;
Expand Down Expand Up @@ -48,16 +49,18 @@ public static void write(Network network, XMLStreamWriter writer) {
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context) {
write(network, writer, context, Optional.empty());
CgmesMetadataModel model = CgmesExport.initializeModelForExport(
network, CgmesSubset.STATE_VARIABLES, null, null, null, context, false);
write(network, writer, context, model);
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, Optional<CgmesMetadataModel> model) {
public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, CgmesMetadataModel model) {
try {
String cimNamespace = context.getCim().getNamespace();
CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), context.getCim().getEuNamespace(), writer);

if (context.getCimVersion() >= 16) {
CgmesExportUtil.writeModelDescription(network, CgmesSubset.STATE_VARIABLES, writer, model.orElseGet(context::getExportedSVModel), context);
CgmesExportUtil.writeModelDescription(network, CgmesSubset.STATE_VARIABLES, writer, model, context);
writeTopologicalIslands(network, context, writer);
// Note: unmapped topological nodes (node breaker) & boundary topological nodes are not written in topological islands
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.powsybl.cgmes.conversion.export;

import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.extensions.CgmesControlArea;
import com.powsybl.cgmes.extensions.CgmesControlAreas;
Expand Down Expand Up @@ -47,18 +48,20 @@ private SteadyStateHypothesisExport() {
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context) {
write(network, writer, context, Optional.empty());
CgmesMetadataModel model = CgmesExport.initializeModelForExport(
network, CgmesSubset.STEADY_STATE_HYPOTHESIS, null, null, null, context, false);
write(network, writer, context, model);
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, Optional<CgmesMetadataModel> model) {
public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, CgmesMetadataModel model) {
final Map<String, List<RegulatingControlView>> regulatingControlViews = new HashMap<>();
String cimNamespace = context.getCim().getNamespace();

try {
CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), context.getCim().getEuNamespace(), writer);

if (context.getCimVersion() >= 16) {
CgmesExportUtil.writeModelDescription(network, CgmesSubset.STEADY_STATE_HYPOTHESIS, writer, model.orElseGet(context::getExportedSSHModel), context);
CgmesExportUtil.writeModelDescription(network, CgmesSubset.STEADY_STATE_HYPOTHESIS, writer, model, context);
}

writeLoads(network, cimNamespace, writer, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
*/
package com.powsybl.cgmes.conversion.export;

import com.powsybl.cgmes.conversion.CgmesExport;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.model.CgmesMetadataModel;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesSubset;
import com.powsybl.commons.PowsyblException;
Expand Down Expand Up @@ -40,12 +42,18 @@ public static void write(Network network, XMLStreamWriter writer) {
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context) {
CgmesMetadataModel model = CgmesExport.initializeModelForExport(
network, CgmesSubset.TOPOLOGY, null, null, null, context, false);
write(network, writer, context, model);
}

public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, CgmesMetadataModel model) {
try {
String cimNamespace = context.getCim().getNamespace();
CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), context.getCim().getEuNamespace(), writer);

if (context.getCimVersion() >= 16) {
CgmesExportUtil.writeModelDescription(network, CgmesSubset.TOPOLOGY, writer, context.getExportedTPModel(), context);
CgmesExportUtil.writeModelDescription(network, CgmesSubset.TOPOLOGY, writer, model, context);
}

writeTopologicalNodes(network, cimNamespace, writer, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ void microGridBaseCaseAssembledSeparatingByModelingAuthority() {

private void checkExportSvTerminals(Network network) {
CgmesExportContext context = new CgmesExportContext(network);
context.getExportedSVModel().setVersion(2);
context.setExportBoundaryPowerFlows(true);
context.setExportFlowsForSwitches(true);

Expand Down
Loading

0 comments on commit 4dae10f

Please sign in to comment.