FlowCnecResultArrayDeserializer.java
/*
* Copyright (c) 2021, 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.openrao.data.raoresult.io.json.deserializers;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.raoresult.impl.ElementaryFlowCnecResult;
import com.powsybl.openrao.data.raoresult.impl.FlowCnecResult;
import com.powsybl.openrao.data.raoresult.impl.RaoResultImpl;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import java.io.IOException;
import static com.powsybl.openrao.data.raoresult.io.json.RaoResultJsonConstants.*;
/**
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
*/
final class FlowCnecResultArrayDeserializer {
public static final String UNEXPECTED_FIELD = "Cannot deserialize RaoResult: unexpected field in %s (%s)";
private FlowCnecResultArrayDeserializer() {
}
static void deserialize(JsonParser jsonParser, RaoResultImpl raoResult, Crac crac, String jsonFileVersion) throws IOException {
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
if (!jsonParser.nextFieldName().equals(FLOWCNEC_ID)) {
throw new OpenRaoException(String.format("Cannot deserialize RaoResult: each %s must start with an %s field", FLOWCNEC_RESULTS, FLOWCNEC_ID));
}
String flowCnecId = jsonParser.nextTextValue();
FlowCnec flowCnec = crac.getFlowCnec(flowCnecId);
if (flowCnec == null) {
throw new OpenRaoException(String.format("Cannot deserialize RaoResult: flowCnec with id %s does not exist in the Crac", flowCnecId));
}
FlowCnecResult flowCnecResult = raoResult.getAndCreateIfAbsentFlowCnecResult(flowCnec);
deserializeFlowCnecResult(jsonParser, flowCnecResult, jsonFileVersion, crac);
}
}
private static void deserializeFlowCnecResult(JsonParser jsonParser, FlowCnecResult flowCnecResult, String jsonFileVersion, Crac crac) throws IOException {
while (!jsonParser.nextToken().isStructEnd()) {
ElementaryFlowCnecResult eFlowCnecResult;
Instant optimizedInstant = deserializeOptimizedInstant(jsonParser.getCurrentName(), jsonFileVersion, crac);
jsonParser.nextToken();
eFlowCnecResult = flowCnecResult.getAndCreateIfAbsentResultForOptimizationState(optimizedInstant);
deserializeElementaryFlowCnecResult(jsonParser, eFlowCnecResult, jsonFileVersion);
}
}
private static void deserializeElementaryFlowCnecResult(JsonParser jsonParser, ElementaryFlowCnecResult eFlowCnecResult, String jsonFileVersion) throws IOException {
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case MEGAWATT_UNIT:
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnit(jsonParser, eFlowCnecResult, Unit.MEGAWATT, jsonFileVersion);
break;
case AMPERE_UNIT:
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnit(jsonParser, eFlowCnecResult, Unit.AMPERE, jsonFileVersion);
break;
case ZONAL_PTDF_SUM:
checkSideHandlingVersion(jsonFileVersion, ZONAL_PTDF_SUM);
// For older versions, suppose both sides are used
jsonParser.nextToken();
eFlowCnecResult.setPtdfZonalSum(TwoSides.ONE, jsonParser.getDoubleValue());
eFlowCnecResult.setPtdfZonalSum(TwoSides.TWO, jsonParser.getDoubleValue());
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, FLOWCNEC_RESULTS, jsonParser.getCurrentName()));
}
}
}
private static void deserializeElementaryFlowCnecResultForUnit(JsonParser jsonParser, ElementaryFlowCnecResult eFlowCnecResult, Unit unit, String jsonFileVersion) throws IOException {
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case MARGIN:
jsonParser.nextToken();
eFlowCnecResult.setMargin(jsonParser.getDoubleValue(), unit);
break;
case RELATIVE_MARGIN:
jsonParser.nextToken();
eFlowCnecResult.setRelativeMargin(jsonParser.getDoubleValue(), unit);
break;
case SIDE_ONE:
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnitAndSide(jsonParser, eFlowCnecResult, unit, TwoSides.ONE);
break;
case SIDE_TWO:
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnitAndSide(jsonParser, eFlowCnecResult, unit, TwoSides.TWO);
break;
case LEFT_SIDE:
Utils.checkDeprecatedField(LEFT_SIDE, FLOWCNEC_RESULTS, jsonFileVersion, "1.4");
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnitAndSide(jsonParser, eFlowCnecResult, unit, TwoSides.ONE);
break;
case RIGHT_SIDE:
Utils.checkDeprecatedField(RIGHT_SIDE, FLOWCNEC_RESULTS, jsonFileVersion, "1.4");
jsonParser.nextToken();
deserializeElementaryFlowCnecResultForUnitAndSide(jsonParser, eFlowCnecResult, unit, TwoSides.TWO);
break;
case FLOW:
checkSideHandlingVersion(jsonFileVersion, FLOW);
// For older versions, suppose both sides are used
jsonParser.nextToken();
eFlowCnecResult.setFlow(TwoSides.ONE, jsonParser.getDoubleValue(), unit);
eFlowCnecResult.setFlow(TwoSides.TWO, jsonParser.getDoubleValue(), unit);
break;
case COMMERCIAL_FLOW:
checkSideHandlingVersion(jsonFileVersion, COMMERCIAL_FLOW);
// For older versions, suppose both sides are used
jsonParser.nextToken();
eFlowCnecResult.setCommercialFlow(TwoSides.ONE, jsonParser.getDoubleValue(), unit);
eFlowCnecResult.setCommercialFlow(TwoSides.TWO, jsonParser.getDoubleValue(), unit);
break;
case LOOP_FLOW:
checkSideHandlingVersion(jsonFileVersion, LOOP_FLOW);
// For older versions, suppose both sides are used
jsonParser.nextToken();
eFlowCnecResult.setLoopFlow(TwoSides.ONE, jsonParser.getDoubleValue(), unit);
eFlowCnecResult.setLoopFlow(TwoSides.TWO, jsonParser.getDoubleValue(), unit);
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, FLOWCNEC_RESULTS, jsonParser.getCurrentName()));
}
}
}
private static void checkSideHandlingVersion(String jsonFileVersion, String fieldName) {
Utils.checkDeprecatedField(fieldName, FLOWCNEC_RESULTS, jsonFileVersion, "1.1");
}
private static void deserializeElementaryFlowCnecResultForUnitAndSide(JsonParser jsonParser, ElementaryFlowCnecResult eFlowCnecResult, Unit unit, TwoSides side) throws IOException {
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case FLOW:
jsonParser.nextToken();
eFlowCnecResult.setFlow(side, jsonParser.getDoubleValue(), unit);
break;
case COMMERCIAL_FLOW:
jsonParser.nextToken();
eFlowCnecResult.setCommercialFlow(side, jsonParser.getDoubleValue(), unit);
break;
case LOOP_FLOW:
jsonParser.nextToken();
eFlowCnecResult.setLoopFlow(side, jsonParser.getDoubleValue(), unit);
break;
case ZONAL_PTDF_SUM:
jsonParser.nextToken();
if (!unit.equals(Unit.MEGAWATT)) {
throw new OpenRaoException(String.format("%s can only be defined in the MEGAWATT section", ZONAL_PTDF_SUM));
}
eFlowCnecResult.setPtdfZonalSum(side, jsonParser.getDoubleValue());
break;
default:
throw new OpenRaoException(String.format(UNEXPECTED_FIELD, FLOWCNEC_RESULTS, jsonParser.getCurrentName()));
}
}
}
}