From 46f49187aa686ed9871d464fb74475096721c858 Mon Sep 17 00:00:00 2001 From: lisrte Date: Fri, 8 Nov 2024 17:38:05 +0100 Subject: [PATCH 1/6] Parse aggregatedResults.xml and use it for post contingency results Signed-off-by: lisrte --- .../dynawo/commons/AbstractXmlParser.java | 74 ++++++++++++++++++ .../dynawo/commons/DynawoConstants.java | 2 + .../commons/timeline/XmlTimeLineParser.java | 56 ++------------ .../timeline/XmlTimeLineParserTest.java | 4 +- .../DynaFlowSecurityAnalysisHandler.java | 4 +- .../ContingencyResultsUtils.java | 29 +++++-- .../dynaflow/results/FailedCriterion.java | 17 ++++ .../dynaflow/results/LoadIncreaseResult.java | 22 ++++++ .../powsybl/dynaflow/results/ResultsUtil.java | 77 +++++++++++++++++++ .../dynaflow/results/ScenarioResult.java | 25 ++++++ .../com/powsybl/dynaflow/results/Status.java | 18 +++++ .../results/XmlScenarioResultParser.java | 61 +++++++++++++++ .../DynaFlowSecurityAnalysisTest.java | 14 +++- .../XmlAggregatedResultParserTest.java | 54 +++++++++++++ .../SecurityAnalysis/aggregatedResults.xml | 5 ++ .../src/test/resources/aggregated_results.xml | 9 +++ .../resources/aggregated_results_faulty.xml | 10 +++ .../com/powsybl/dynawo/it/DynaFlowTest.java | 2 +- .../dynawo/it/DynawoSecurityAnalysisTest.java | 2 +- .../dynamic-security-analysis/results.json | 2 +- .../security-analysis/sa_nb_results.json | 4 +- .../DynawoSecurityAnalysisHandler.java | 5 +- 22 files changed, 422 insertions(+), 74 deletions(-) create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/AbstractXmlParser.java rename dynaflow/src/main/java/com/powsybl/dynaflow/{ => results}/ContingencyResultsUtils.java (73%) create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/ScenarioResult.java create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/Status.java create mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java create mode 100644 dynaflow/src/test/java/com/powsybl/dynaflow/results/XmlAggregatedResultParserTest.java create mode 100644 dynaflow/src/test/resources/SecurityAnalysis/aggregatedResults.xml create mode 100644 dynaflow/src/test/resources/aggregated_results.xml create mode 100644 dynaflow/src/test/resources/aggregated_results_faulty.xml diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractXmlParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractXmlParser.java new file mode 100644 index 000000000..93db965cf --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractXmlParser.java @@ -0,0 +1,74 @@ +/** + * 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.dynawo.commons; + +import com.powsybl.commons.exceptions.UncheckedXmlStreamException; + +import javax.xml.XMLConstants; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.io.IOException; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * @author Laurent Issertial {@literal } + */ +public abstract class AbstractXmlParser { + + public List parse(Path path) { + List series = new ArrayList<>(); + parse(path, series::add); + return series; + } + + public void parse(Path path, Consumer consumer) { + Objects.requireNonNull(path); + if (!Files.exists(path)) { + return; + } + try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + parse(reader, consumer); + } catch (IOException e) { + throw new UncheckedIOException(e); + } catch (XMLStreamException e) { + throw new UncheckedXmlStreamException(e); + } + } + + public List parse(Reader reader) throws XMLStreamException { + List series = new ArrayList<>(); + parse(reader, series::add); + return series; + } + + public void parse(Reader reader, Consumer consumer) throws XMLStreamException { + XMLInputFactory factory = XMLInputFactory.newInstance(); + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + XMLStreamReader xmlReader = null; + try { + xmlReader = factory.createXMLStreamReader(reader); + read(xmlReader, consumer); + } finally { + if (xmlReader != null) { + xmlReader.close(); + } + } + } + + protected abstract void read(XMLStreamReader reader, Consumer consumer) throws XMLStreamException; +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java index a8061a831..a2358c369 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java @@ -37,4 +37,6 @@ private DynawoConstants() { "standbyAutomaton"); public static final String OUTPUT_IIDM_FILENAME = "outputIIDM.xml"; + + public static final String AGGREGATED_RESULTS = "aggregatedResults.xml"; } diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParser.java index 33d344983..8a1ecc194 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParser.java @@ -9,68 +9,25 @@ import com.powsybl.commons.exceptions.UncheckedXmlStreamException; import com.powsybl.commons.xml.XmlUtil; +import com.powsybl.dynawo.commons.AbstractXmlParser; -import javax.xml.XMLConstants; -import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import java.io.IOException; -import java.io.Reader; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.function.Consumer; /** * @author Laurent Issertial {@literal } * @author Marcos de Miguel {@literal } */ -public final class XmlTimeLineParser implements TimeLineParser { +public final class XmlTimeLineParser extends AbstractXmlParser implements TimeLineParser { private static final String TIME = "time"; private static final String MODEL_NAME = "modelName"; private static final String MESSAGE = "message"; - public List parse(Path timeLineFile) { - Objects.requireNonNull(timeLineFile); - if (!Files.exists(timeLineFile)) { - return Collections.emptyList(); - } - - try (Reader reader = Files.newBufferedReader(timeLineFile, StandardCharsets.UTF_8)) { - return parse(reader); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (XMLStreamException e) { - throw new UncheckedXmlStreamException(e); - } - } - - public static List parse(Reader reader) throws XMLStreamException { - - List timeLineSeries; - XMLInputFactory factory = XMLInputFactory.newInstance(); - factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - XMLStreamReader xmlReader = null; - try { - xmlReader = factory.createXMLStreamReader(reader); - timeLineSeries = read(xmlReader); - } finally { - if (xmlReader != null) { - xmlReader.close(); - } - } - return timeLineSeries; - } - - private static List read(XMLStreamReader xmlReader) throws XMLStreamException { - List timeline = new ArrayList<>(); + @Override + protected void read(XMLStreamReader xmlReader, Consumer consumer) throws XMLStreamException { int state = xmlReader.next(); while (state == XMLStreamConstants.COMMENT) { state = xmlReader.next(); @@ -83,12 +40,11 @@ private static List read(XMLStreamReader xmlReader) throws XMLStr String message = xmlReader.getAttributeValue(null, MESSAGE); XmlUtil.readEndElementOrThrow(xmlReader); TimeLineUtil.createEvent(time, modelName, message) - .ifPresent(timeline::add); + .ifPresent(consumer); } } catch (XMLStreamException e) { throw new UncheckedXmlStreamException(e); } }); - return timeline; } } diff --git a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParserTest.java b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParserTest.java index 1f2fd7385..5d8d61a3f 100644 --- a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParserTest.java +++ b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/XmlTimeLineParserTest.java @@ -27,7 +27,7 @@ class XmlTimeLineParserTest { void test() throws XMLStreamException { InputStreamReader xml = new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream("/timeline.xml"))); - List timeline = XmlTimeLineParser.parse(xml); + List timeline = new XmlTimeLineParser().parse(xml); assertEquals(5, timeline.size()); assertEquals("PMIN : activation", timeline.get(0).message()); @@ -54,7 +54,7 @@ void parseFromPath() throws URISyntaxException { @Test void testInconsistentFile() throws XMLStreamException { InputStreamReader xml = new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream("/wrongTimeline.xml"))); - List timeline = XmlTimeLineParser.parse(xml); + List timeline = new XmlTimeLineParser().parse(xml); assertEquals(4, timeline.size()); } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java index 314c2ed94..213cbea4a 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisHandler.java @@ -19,6 +19,7 @@ import com.powsybl.contingency.contingency.list.ContingencyList; import com.powsybl.contingency.json.ContingencyJsonModule; import com.powsybl.dynaflow.json.DynaFlowConfigSerializer; +import com.powsybl.dynaflow.results.ContingencyResultsUtils; import com.powsybl.dynawo.commons.DynawoUtil; import com.powsybl.iidm.network.Network; import com.powsybl.loadflow.LoadFlowParameters; @@ -38,7 +39,6 @@ import static com.powsybl.dynaflow.DynaFlowConstants.CONFIG_FILENAME; import static com.powsybl.dynaflow.DynaFlowConstants.IIDM_FILENAME; import static com.powsybl.dynaflow.SecurityAnalysisConstants.CONTINGENCIES_FILENAME; -import static com.powsybl.dynaflow.SecurityAnalysisConstants.DYNAWO_CONSTRAINTS_FOLDER; import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; import static com.powsybl.dynawo.commons.DynawoUtil.getCommandExecutions; @@ -88,7 +88,7 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr return new SecurityAnalysisReport( new SecurityAnalysisResult( ContingencyResultsUtils.getPreContingencyResult(network, violationFilter), - ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir.resolve(DYNAWO_CONSTRAINTS_FOLDER), contingencies), + ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir, contingencies), Collections.emptyList()) ); } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/ContingencyResultsUtils.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java similarity index 73% rename from dynaflow/src/main/java/com/powsybl/dynaflow/ContingencyResultsUtils.java rename to dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java index 776366d0a..afd8e987b 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/ContingencyResultsUtils.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java @@ -5,10 +5,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * SPDX-License-Identifier: MPL-2.0 */ -package com.powsybl.dynaflow; +package com.powsybl.dynaflow.results; import com.powsybl.commons.report.ReportNode; import com.powsybl.contingency.Contingency; +import com.powsybl.dynaflow.DynaflowReports; import com.powsybl.dynaflow.xml.ConstraintsReader; import com.powsybl.dynawo.commons.CommonReports; import com.powsybl.dynawo.commons.timeline.TimelineEntry; @@ -23,9 +24,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import static com.powsybl.dynaflow.SecurityAnalysisConstants.DYNAWO_CONSTRAINTS_FOLDER; +import static com.powsybl.dynawo.commons.DynawoConstants.AGGREGATED_RESULTS; + /** * @author Laurent Issertial */ @@ -48,22 +54,29 @@ public static PreContingencyResult getPreContingencyResult(Network network, Limi * Build the post-contingency results from the constraints files written by dynawo */ public static List getPostContingencyResults(Network network, LimitViolationFilter violationFilter, - Path constraintsDir, List contingencies) { + Path workingDir, List contingencies) { + Path constraintsDir = workingDir.resolve(DYNAWO_CONSTRAINTS_FOLDER); + Path results = workingDir.resolve(AGGREGATED_RESULTS); + Map scenarioResults = new HashMap<>(); + if (Files.exists(results)) { + new XmlScenarioResultParser().parse(results, s -> scenarioResults.put(s.id(), s.status())); + } return contingencies.stream() - .map(c -> getPostContingencyResult(network, violationFilter, constraintsDir, c)) + .map(c -> new PostContingencyResult(c, + ResultsUtil.convertStatus(scenarioResults.getOrDefault(c.getId(), Status.EXECUTION_PROBLEM)), + getLimitViolationsResult(network, violationFilter, constraintsDir, c))) .collect(Collectors.toList()); } - private static PostContingencyResult getPostContingencyResult(Network network, LimitViolationFilter violationFilter, - Path constraintsDir, Contingency contingency) { + private static LimitViolationsResult getLimitViolationsResult(Network network, LimitViolationFilter violationFilter, + Path constraintsDir, Contingency contingency) { Path constraintsFile = constraintsDir.resolve("constraints_" + contingency.getId() + ".xml"); if (Files.exists(constraintsFile)) { List limitViolationsRead = ConstraintsReader.read(network, constraintsFile); List limitViolationsFiltered = violationFilter.apply(limitViolationsRead, network); - return new PostContingencyResult(contingency, PostContingencyComputationStatus.CONVERGED, new LimitViolationsResult(limitViolationsFiltered)); - } else { - return new PostContingencyResult(contingency, PostContingencyComputationStatus.FAILED, Collections.emptyList()); + return new LimitViolationsResult(limitViolationsFiltered); } + return LimitViolationsResult.empty(); } // Report the timeline events from the timeline files written by dynawo diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java new file mode 100644 index 000000000..12027f1cb --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java @@ -0,0 +1,17 @@ +/** + * 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.dynaflow.results; + +/** + * scenarioResults or loadIncreaseResults failed criterion + * @param message Failed criterion message + * @param time Failure time (in seconds) + * @author Laurent Issertial {@literal } + */ +public record FailedCriterion(String message, double time) { +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java new file mode 100644 index 000000000..38605ead5 --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java @@ -0,0 +1,22 @@ +/** + * 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.dynaflow.results; + +import java.util.Collections; +import java.util.List; + +/** + * @author Laurent Issertial {@literal } + */ +public record LoadIncreaseResult(double loadLevel, Status status, + List scenarioResults, List failedCriteria) { + + public LoadIncreaseResult(double loadLevel, Status status) { + this(loadLevel, status, Collections.emptyList(), Collections.emptyList()); + } +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java new file mode 100644 index 000000000..cfac54c62 --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java @@ -0,0 +1,77 @@ +/** + * 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.dynaflow.results; + +import com.powsybl.security.PostContingencyComputationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Optional; + +import static com.powsybl.dynaflow.results.Status.CRITERIA_NON_RESPECTED; +import static com.powsybl.security.PostContingencyComputationStatus.*; + +/** + * @author Laurent Issertial {@literal } + */ +public final class ResultsUtil { + + private ResultsUtil() { + } + + private static final Logger LOGGER = LoggerFactory.getLogger(ResultsUtil.class); + + public static PostContingencyComputationStatus convertStatus(Status status) { + return switch (status) { + case CONVERGENCE -> CONVERGED; + case DIVERGENCE -> SOLVER_FAILED; + case EXECUTION_PROBLEM, CRITERIA_NON_RESPECTED -> FAILED; + }; + } + + static Optional createScenarioResult(String id, String status, List failedCriteria) { + if (id == null || status == null || failedCriteria == null) { + LOGGER.warn("Inconsistent scenario result entry (id: '{}', status: '{}', failedCriteria: '{}')", id, status, failedCriteria); + } else { + try { + Status statusE = Status.valueOf(status); + boolean isCriterionError = CRITERIA_NON_RESPECTED == statusE; + if (isCriterionError && failedCriteria.isEmpty()) { + LOGGER.warn("ScenarioResult with {} status should have failed criteria", status); + return Optional.empty(); + } else if (!isCriterionError && !failedCriteria.isEmpty()) { + LOGGER.warn("ScenarioResult with {} status should not have failed criteria", status); + return Optional.empty(); + } + return Optional.of(new ScenarioResult(id, statusE, failedCriteria)); + } catch (IllegalArgumentException e) { + logInconsistentEntry("status", status); + } + } + return Optional.empty(); + } + + static Optional createFailedCriterion(String message, String time) { + if (message == null || time == null) { + LOGGER.warn("Inconsistent failed criterion entry (message: '{}', time: '{}')", message, time); + } else { + try { + double timeD = Double.parseDouble(time); + return Optional.of(new FailedCriterion(message, timeD)); + } catch (NumberFormatException e) { + logInconsistentEntry("time", time); + } + } + return Optional.empty(); + } + + private static void logInconsistentEntry(String fieldName, String message) { + LOGGER.warn("Inconsistent {} entry '{}'", fieldName, message); + } +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ScenarioResult.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ScenarioResult.java new file mode 100644 index 000000000..4328dd59f --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ScenarioResult.java @@ -0,0 +1,25 @@ +/** + * 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.dynaflow.results; + +import java.util.Collections; +import java.util.List; + +/** + * Contingency scenario result + * @param id Contingency id + * @param status Result status + * @param failedCriteria List of failed criterion + * @author Laurent Issertial {@literal } + */ +public record ScenarioResult(String id, Status status, List failedCriteria) { + + public ScenarioResult(String id, Status status) { + this(id, status, Collections.emptyList()); + } +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/Status.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/Status.java new file mode 100644 index 000000000..2ea56fb06 --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/Status.java @@ -0,0 +1,18 @@ +/** + * 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.dynaflow.results; + +/** + * @author Laurent Issertial {@literal } + */ +public enum Status { + CONVERGENCE, + DIVERGENCE, + EXECUTION_PROBLEM, + CRITERIA_NON_RESPECTED +} diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java new file mode 100644 index 000000000..2f9428938 --- /dev/null +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java @@ -0,0 +1,61 @@ +/** + * 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.dynaflow.results; + +import com.powsybl.commons.exceptions.UncheckedXmlStreamException; +import com.powsybl.commons.xml.XmlUtil; +import com.powsybl.dynawo.commons.AbstractXmlParser; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * @author Laurent Issertial {@literal } + */ +public final class XmlScenarioResultParser extends AbstractXmlParser { + + private static final String STATUS = "status"; + private static final String ID = "id"; + private static final String TIME = "time"; + + @Override + protected void read(XMLStreamReader xmlReader, Consumer consumer) throws XMLStreamException { + int state = xmlReader.next(); + while (state == XMLStreamConstants.COMMENT) { + state = xmlReader.next(); + } + XmlUtil.readSubElements(xmlReader, elementName -> readScenarioResult(elementName, xmlReader, consumer)); + } + + public static void readScenarioResult(String elementName, XMLStreamReader xmlReader, Consumer scenarioConsumer) { + if (elementName.equals("scenarioResults")) { + String id = xmlReader.getAttributeValue(null, ID); + String status = xmlReader.getAttributeValue(null, STATUS); + List failedCriteria = new ArrayList<>(); + XmlUtil.readSubElements(xmlReader, subElementName -> readFailedCriterion(subElementName, xmlReader, failedCriteria::add)); + ResultsUtil.createScenarioResult(id, status, failedCriteria).ifPresent(scenarioConsumer); + } + } + + public static void readFailedCriterion(String elementName, XMLStreamReader xmlReader, Consumer resultConsumer) { + try { + if (elementName.equals("criterionNonRespected")) { + String message = xmlReader.getAttributeValue(null, ID); + String time = xmlReader.getAttributeValue(null, TIME); + XmlUtil.readEndElementOrThrow(xmlReader); + ResultsUtil.createFailedCriterion(message, time).ifPresent(resultConsumer); + } + } catch (XMLStreamException e) { + throw new UncheckedXmlStreamException(e); + } + } +} diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java index 75c9b4ced..e4eeb3ced 100644 --- a/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysisTest.java @@ -35,6 +35,8 @@ import static com.powsybl.commons.test.ComparisonUtils.assertXmlEquals; import static com.powsybl.dynaflow.DynaFlowConstants.DYNAFLOW_NAME; import static com.powsybl.dynaflow.DynaFlowConstants.IIDM_FILENAME; +import static com.powsybl.dynaflow.SecurityAnalysisConstants.DYNAWO_CONSTRAINTS_FOLDER; +import static com.powsybl.dynawo.commons.DynawoConstants.AGGREGATED_RESULTS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -50,17 +52,19 @@ private static class LocalCommandExecutorMock extends AbstractLocalCommandExecut private final String contingencyFile; private final List contingencyIds; private final List constraints; + private final String aggregatedResult; public LocalCommandExecutorMock(String stdoutFileRef, String inputFile) { - this(stdoutFileRef, inputFile, null, List.of(), List.of()); + this(stdoutFileRef, inputFile, null, List.of(), List.of(), null); } - public LocalCommandExecutorMock(String stdoutFileRef, String inputFile, String contingencyFile, List contingencyIds, List outputConstraints) { + public LocalCommandExecutorMock(String stdoutFileRef, String inputFile, String contingencyFile, List contingencyIds, List outputConstraints, String aggregatedResult) { this.stdOutFileRef = Objects.requireNonNull(stdoutFileRef); this.inputFile = inputFile; this.contingencyFile = contingencyFile; this.contingencyIds = contingencyIds; this.constraints = outputConstraints; + this.aggregatedResult = aggregatedResult; } @Override @@ -90,7 +94,8 @@ private void validateInputs(Path workingDir) throws IOException { } private void copyOutputs(Path workingDir) throws IOException { - Path constraintsFolder = Files.createDirectories(workingDir.resolve("constraints")); + copyFile(aggregatedResult, Files.createFile(workingDir.resolve(AGGREGATED_RESULTS))); + Path constraintsFolder = Files.createDirectories(workingDir.resolve(DYNAWO_CONSTRAINTS_FOLDER)); for (int i = 0; i < contingencyIds.size(); i++) { copyFile(constraints.get(i), constraintsFolder.resolve("constraints_" + contingencyIds.get(i) + ".xml")); } @@ -114,7 +119,8 @@ void test() throws IOException { LocalCommandExecutor commandExecutor = new LocalCommandExecutorMock("/dynawo_version.out", "/SecurityAnalysis/input.xiidm", "/SecurityAnalysis/contingencies.json", - contingencyIds, List.of("/SecurityAnalysis/constraints1.xml", "/SecurityAnalysis/constraints2.xml")); + contingencyIds, List.of("/SecurityAnalysis/constraints1.xml", "/SecurityAnalysis/constraints2.xml"), + "/SecurityAnalysis/aggregatedResults.xml"); SecurityAnalysisRunParameters runParameters = new SecurityAnalysisRunParameters() .setComputationManager(new LocalComputationManager(new LocalComputationConfig(fileSystem.getPath("/working-dir"), 1), commandExecutor, ForkJoinPool.commonPool())); SecurityAnalysisReport report = SecurityAnalysis.run(network, contingencies, runParameters); diff --git a/dynaflow/src/test/java/com/powsybl/dynaflow/results/XmlAggregatedResultParserTest.java b/dynaflow/src/test/java/com/powsybl/dynaflow/results/XmlAggregatedResultParserTest.java new file mode 100644 index 000000000..f207ba9b9 --- /dev/null +++ b/dynaflow/src/test/java/com/powsybl/dynaflow/results/XmlAggregatedResultParserTest.java @@ -0,0 +1,54 @@ +/** + * 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.dynaflow.results; + +import org.junit.jupiter.api.Test; + +import javax.xml.stream.XMLStreamException; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +import static com.powsybl.dynaflow.results.Status.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Laurent Issertial {@literal } + */ +class XmlAggregatedResultParserTest { + + @Test + void test() throws XMLStreamException { + InputStreamReader xml = new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream("/aggregated_results.xml"))); + List result = new XmlScenarioResultParser().parse(xml); + + assertThat(result).containsExactly( + new ScenarioResult("DisconnectLine", CONVERGENCE), + new ScenarioResult("DisconnectGenerator", DIVERGENCE), + new ScenarioResult("DisconnectGroup", CRITERIA_NON_RESPECTED, + List.of(new FailedCriterion("total load power = 276.374MW", 185.0))), + new ScenarioResult("DisconnectGenerator2", EXECUTION_PROBLEM)); + } + + @Test + void parseFromPath() throws URISyntaxException { + Path path = Path.of(Objects.requireNonNull(getClass().getResource("/aggregated_results.xml")).toURI()); + List result = new XmlScenarioResultParser().parse(path); + assertEquals(4, result.size()); + } + + @Test + void testInconsistentFile() throws XMLStreamException { + InputStreamReader xml = new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream("/aggregated_results_faulty.xml"))); + List result = new XmlScenarioResultParser().parse(xml); + assertEquals(0, result.size()); + } +} diff --git a/dynaflow/src/test/resources/SecurityAnalysis/aggregatedResults.xml b/dynaflow/src/test/resources/SecurityAnalysis/aggregatedResults.xml new file mode 100644 index 000000000..7483f14ac --- /dev/null +++ b/dynaflow/src/test/resources/SecurityAnalysis/aggregatedResults.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/dynaflow/src/test/resources/aggregated_results.xml b/dynaflow/src/test/resources/aggregated_results.xml new file mode 100644 index 000000000..221b3612b --- /dev/null +++ b/dynaflow/src/test/resources/aggregated_results.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dynaflow/src/test/resources/aggregated_results_faulty.xml b/dynaflow/src/test/resources/aggregated_results_faulty.xml new file mode 100644 index 000000000..3db0fc37e --- /dev/null +++ b/dynaflow/src/test/resources/aggregated_results_faulty.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java index 70f8cc6eb..41f181b36 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaFlowTest.java @@ -58,7 +58,7 @@ class DynaFlowTest extends AbstractDynawoTest { @BeforeEach void setUp() throws Exception { super.setUp(); - DynaFlowConfig config = new DynaFlowConfig(Path.of("/dynaflow-launcher"), false); + DynaFlowConfig config = new DynaFlowConfig(Path.of("/dynaflow-launcher"), true); loadFlowProvider = new DynaFlowProvider(() -> config); loadFlowParameters = new LoadFlowParameters(); securityAnalysisProvider = new DynaFlowSecurityAnalysisProvider(() -> config); diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSecurityAnalysisTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSecurityAnalysisTest.java index 1d136dbb2..02b7adfa6 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSecurityAnalysisTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynawoSecurityAnalysisTest.java @@ -59,7 +59,7 @@ class DynawoSecurityAnalysisTest extends AbstractDynawoTest { @BeforeEach void setUp() throws Exception { super.setUp(); - provider = new DynawoSecurityAnalysisProvider(new DynawoAlgorithmsConfig(Path.of("/dynaflow-launcher"), false)); + provider = new DynawoSecurityAnalysisProvider(new DynawoAlgorithmsConfig(Path.of("/dynaflow-launcher"), true)); parameters = new DynamicSecurityAnalysisParameters() .setDynamicSimulationParameters(new DynamicSimulationParameters(0, 100)) .setDynamicContingenciesParameters(new DynamicSecurityAnalysisParameters.ContingenciesParameters(50)); diff --git a/dynawo-integration-tests/src/test/resources/ieee14/dynamic-security-analysis/results.json b/dynawo-integration-tests/src/test/resources/ieee14/dynamic-security-analysis/results.json index 459e59842..bd63cea33 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/dynamic-security-analysis/results.json +++ b/dynawo-integration-tests/src/test/resources/ieee14/dynamic-security-analysis/results.json @@ -29,7 +29,7 @@ "type" : "LOAD" } ] }, - "status" : "FAILED", + "status" : "CONVERGED", "limitViolationsResult" : { "limitViolations" : [ ], "actionsTaken" : [ ] diff --git a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json index 9ae2c0898..40a10f27b 100644 --- a/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json +++ b/dynawo-integration-tests/src/test/resources/ieee14/security-analysis/sa_nb_results.json @@ -83,7 +83,7 @@ "type" : "GENERATOR" } ] }, - "status" : "CONVERGED", + "status" : "SOLVER_FAILED", "limitViolationsResult" : { "limitViolations" : [ ], "actionsTaken" : [ ] @@ -108,7 +108,7 @@ "type" : "GENERATOR" } ] }, - "status" : "CONVERGED", + "status" : "SOLVER_FAILED", "limitViolationsResult" : { "limitViolations" : [ { "subjectId" : "S1VL1_BBS", diff --git a/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java b/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java index aedb25440..5759452bc 100644 --- a/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java +++ b/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java @@ -13,7 +13,7 @@ import com.powsybl.computation.Command; import com.powsybl.computation.CommandExecution; import com.powsybl.computation.ExecutionReport; -import com.powsybl.dynaflow.ContingencyResultsUtils; +import com.powsybl.dynaflow.results.ContingencyResultsUtils; import com.powsybl.dynawo.xml.DydXml; import com.powsybl.dynawo.xml.DynawoSimulationConstants; import com.powsybl.dynawo.xml.JobsXml; @@ -39,7 +39,6 @@ import java.util.Collections; import java.util.List; -import static com.powsybl.dynaflow.SecurityAnalysisConstants.DYNAWO_CONSTRAINTS_FOLDER; import static com.powsybl.dynawo.DynawoSimulationConstants.FINAL_STATE_FOLDER; import static com.powsybl.dynawo.DynawoSimulationConstants.OUTPUTS_FOLDER; import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; @@ -92,7 +91,7 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr return new SecurityAnalysisReport( new SecurityAnalysisResult( ContingencyResultsUtils.getPreContingencyResult(network, violationFilter), - ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir.resolve(DYNAWO_CONSTRAINTS_FOLDER), context.getContingencies()), + ContingencyResultsUtils.getPostContingencyResults(network, violationFilter, workingDir, context.getContingencies()), Collections.emptyList()) ); } From d6876cd05c2dd2010b951c7df5d0ed6b00434205 Mon Sep 17 00:00:00 2001 From: lisrte Date: Wed, 13 Nov 2024 10:34:24 +0100 Subject: [PATCH 2/6] Fix merge main Signed-off-by: lisrte --- .../main/java/com/powsybl/dynawo/commons/DynawoConstants.java | 2 +- .../com/powsybl/dynaflow/results/ContingencyResultsUtils.java | 4 ++-- .../dynawo/security/DynawoSecurityAnalysisHandler.java | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java index a09c25b04..264d72bab 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java @@ -42,7 +42,7 @@ private DynawoConstants() { public static final String OUTPUT_IIDM_FILENAME = "outputIIDM.xml"; public static final String AGGREGATED_RESULTS = "aggregatedResults.xml"; - + public static final String FINAL_STATE_FOLDER = "finalState"; public static final String TIMELINE_FOLDER = "timeLine"; diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java index afd8e987b..cb436088f 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.stream.Collectors; -import static com.powsybl.dynaflow.SecurityAnalysisConstants.DYNAWO_CONSTRAINTS_FOLDER; +import static com.powsybl.dynaflow.SecurityAnalysisConstants.CONSTRAINTS_FOLDER; import static com.powsybl.dynawo.commons.DynawoConstants.AGGREGATED_RESULTS; /** @@ -55,7 +55,7 @@ public static PreContingencyResult getPreContingencyResult(Network network, Limi */ public static List getPostContingencyResults(Network network, LimitViolationFilter violationFilter, Path workingDir, List contingencies) { - Path constraintsDir = workingDir.resolve(DYNAWO_CONSTRAINTS_FOLDER); + Path constraintsDir = workingDir.resolve(CONSTRAINTS_FOLDER); Path results = workingDir.resolve(AGGREGATED_RESULTS); Map scenarioResults = new HashMap<>(); if (Files.exists(results)) { diff --git a/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java b/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java index 043fde1eb..4a65d8876 100644 --- a/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java +++ b/dynawo-security-analysis/src/main/java/com/powsybl/dynawo/security/DynawoSecurityAnalysisHandler.java @@ -37,8 +37,7 @@ import java.util.Collections; import java.util.List; -import static com.powsybl.dynawo.commons.DynawoConstants.OUTPUT_IIDM_FILENAME_PATH; -import static com.powsybl.dynawo.commons.DynawoConstants.TIMELINE_FOLDER; +import static com.powsybl.dynawo.commons.DynawoConstants.*; import static com.powsybl.dynawo.commons.DynawoUtil.getCommandExecutions; /** From 8d514f8a6686e67bc5bace3060f62861b2cdbd42 Mon Sep 17 00:00:00 2001 From: lisrte Date: Wed, 11 Dec 2024 10:59:52 +0100 Subject: [PATCH 3/6] Remove unused LoadIncreaseResult class Signed-off-by: lisrte --- .../dynaflow/results/LoadIncreaseResult.java | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java deleted file mode 100644 index 38605ead5..000000000 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/LoadIncreaseResult.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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.dynaflow.results; - -import java.util.Collections; -import java.util.List; - -/** - * @author Laurent Issertial {@literal } - */ -public record LoadIncreaseResult(double loadLevel, Status status, - List scenarioResults, List failedCriteria) { - - public LoadIncreaseResult(double loadLevel, Status status) { - this(loadLevel, status, Collections.emptyList(), Collections.emptyList()); - } -} From 1e48fa8fc977bcb88fd36cbdcb1883789301fa74 Mon Sep 17 00:00:00 2001 From: Florian Dupuy <66690739+flo-dup@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:10:10 +0100 Subject: [PATCH 4/6] Fix Signed-off-by: Florian Dupuy <66690739+flo-dup@users.noreply.github.com> --- .../com/powsybl/dynaflow/results/ContingencyResultsUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java index cb436088f..648e3962b 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java @@ -65,7 +65,7 @@ public static List getPostContingencyResults(Network netw .map(c -> new PostContingencyResult(c, ResultsUtil.convertStatus(scenarioResults.getOrDefault(c.getId(), Status.EXECUTION_PROBLEM)), getLimitViolationsResult(network, violationFilter, constraintsDir, c))) - .collect(Collectors.toList()); + .toList(); } private static LimitViolationsResult getLimitViolationsResult(Network network, LimitViolationFilter violationFilter, From 799fb9fcaf2d347495ea7b343fdf3933df2a7d02 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Thu, 12 Dec 2024 16:08:42 +0100 Subject: [PATCH 5/6] Fix checkstyle Signed-off-by: Florian Dupuy --- .../powsybl/dynaflow/results/ContingencyResultsUtils.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java index 648e3962b..1de95b7eb 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ContingencyResultsUtils.java @@ -16,7 +16,10 @@ import com.powsybl.dynawo.commons.timeline.XmlTimeLineParser; import com.powsybl.iidm.network.Network; import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.security.*; +import com.powsybl.security.LimitViolation; +import com.powsybl.security.LimitViolationFilter; +import com.powsybl.security.LimitViolationsResult; +import com.powsybl.security.Security; import com.powsybl.security.results.NetworkResult; import com.powsybl.security.results.PostContingencyResult; import com.powsybl.security.results.PreContingencyResult; @@ -27,7 +30,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static com.powsybl.dynaflow.SecurityAnalysisConstants.CONSTRAINTS_FOLDER; import static com.powsybl.dynawo.commons.DynawoConstants.AGGREGATED_RESULTS; From 6546929d72e75104af8e53d723402f6ec2fc68a1 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 12 Dec 2024 11:29:09 +0100 Subject: [PATCH 6/6] Rename FailedCriterion message field to description Signed-off-by: lisrte --- .../com/powsybl/dynaflow/results/FailedCriterion.java | 4 ++-- .../java/com/powsybl/dynaflow/results/ResultsUtil.java | 8 ++++---- .../powsybl/dynaflow/results/XmlScenarioResultParser.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java index 12027f1cb..8e2ddd47d 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/FailedCriterion.java @@ -9,9 +9,9 @@ /** * scenarioResults or loadIncreaseResults failed criterion - * @param message Failed criterion message + * @param description Failed criterion description * @param time Failure time (in seconds) * @author Laurent Issertial {@literal } */ -public record FailedCriterion(String message, double time) { +public record FailedCriterion(String description, double time) { } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java index cfac54c62..8840f8e8d 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/ResultsUtil.java @@ -57,13 +57,13 @@ static Optional createScenarioResult(String id, String status, L return Optional.empty(); } - static Optional createFailedCriterion(String message, String time) { - if (message == null || time == null) { - LOGGER.warn("Inconsistent failed criterion entry (message: '{}', time: '{}')", message, time); + static Optional createFailedCriterion(String description, String time) { + if (description == null || time == null) { + LOGGER.warn("Inconsistent failed criterion entry (description: '{}', time: '{}')", description, time); } else { try { double timeD = Double.parseDouble(time); - return Optional.of(new FailedCriterion(message, timeD)); + return Optional.of(new FailedCriterion(description, timeD)); } catch (NumberFormatException e) { logInconsistentEntry("time", time); } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java b/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java index 2f9428938..5d21cddd0 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/results/XmlScenarioResultParser.java @@ -49,10 +49,10 @@ public static void readScenarioResult(String elementName, XMLStreamReader xmlRea public static void readFailedCriterion(String elementName, XMLStreamReader xmlReader, Consumer resultConsumer) { try { if (elementName.equals("criterionNonRespected")) { - String message = xmlReader.getAttributeValue(null, ID); + String description = xmlReader.getAttributeValue(null, ID); String time = xmlReader.getAttributeValue(null, TIME); XmlUtil.readEndElementOrThrow(xmlReader); - ResultsUtil.createFailedCriterion(message, time).ifPresent(resultConsumer); + ResultsUtil.createFailedCriterion(description, time).ifPresent(resultConsumer); } } catch (XMLStreamException e) { throw new UncheckedXmlStreamException(e);