JSON RAO Result File
Contents
Introduction
A Remedial Action Optimisation process provides an optimal list of remedial actions to be applied in basecase and after contingencies listed in the CRAC. The decisions are based upon the impact of these remedial actions on the CRAC’s CNECs.
A RaoResult object model has been designed in FARAO in order to hold all the important results of optimisation. In this page, we present:
- where to find the RaoResult instance,
- how to save a RaoResult java object to a JSON file,
- how to import a RaoResult java object from a JSON file,
- how to access information in the RaoResult, using either the RaoResult java object or the JSON file.
Accessing the RAO result
The RaoResult java object is actually an interface that is implemented by many FARAO classes. However, one only needs to use the interface’s functions. A RaoResult object is returned by FARAO’s main optimisation method:
CompletableFuture<RaoResult> RaoProvider::run(RaoInput raoInput, RaoParameters parameters, Instant targetEndInstant)
Where RaoProvider is the chosen implementation of the RAO, such as CASTOR.
Exporting and importing a JSON file
A RaoResult object can be saved into a JSON file (no matter what implementation it is). A RaoResult JSON file can be imported into a RaoResultImpl, and used as a RaoResult java object.
Export
Example:
new RaoResultExporter().export(raoResult, crac, flowUnits, outputStream);
Where:
raoResult
is the RaoResult object you obtained from the RaoProvider;crac
is the CRAC object you used in the RAO;flowUnits
is the set of units in which the flow measurements should be exported (eitherAMPERE
orMEGAWATT
, or both);outputStream
is thejava.io.OutputStream
you want to write the JSON file into.
Import
Example:
RaoResult importedRaoResult = new RaoResultImporter().importRaoResult(inputStream, crac);
Where:
crac
is the CRAC object you used in the RAOinputStream
is thejava.io.InputStream
you read the JSON file into
Contents of the RAO result
The RAO result object generally contains information about post-optimisation results.
However, in some cases, it may be interesting to get some information about the initial state (e.g. power flows before
optimisation), or about the situation after preventive optimisation (e.g. optimal PST tap positions in preventive).
This is why most of the information in the RAO results can have up to 4 values, for these values of OptimizationState:
- INITIAL: values before remedial action optimisation (initial state)
- AFTER_PRA: values after applying optimal Preventive Remedial Actions
- AFTER_ARA: values after applying Automatic Remedial Actions
- AFTER_CRA: values after applying optimal Curative Remedial Actions See also: RAO steps
Computation status
This field contains the status of sensitivity / load-flow computations during the RAO, for a given state,
or for the overall RAO (the status of the overall RAO is computed as the worst status among all states).
It can have one of the following values:
- DEFAULT: the sensitivity / load-flow computations converged normally
- FAILURE: the sensitivity / load-flow computations failed
When the results are returned to the user of your application, they should be sufficiently warned if any state’s sensitivity / load-flow computation has failed.
ComputationStatus getComputationStatus();
ComputationStatus getComputationStatus(State state);
Example:
{
"computationStatus" : "default",
"computationStatusMap": [
{
"computationStatus": "default",
"instant": "preventive"
},
{
"computationStatus": "failure",
"instant": "curative",
"contingency": "contingency1Id"
},
{
"computationStatus": "default",
"instant": "auto",
"contingency": "contingency2Id"
}
],
...
Executed optimisation steps
This field contains macro information about which steps the CASTOR RAO executed.
(See also: Forbidding cost increase, Second preventive RAO parameters)
Value | Did CASTOR run a 1st preventive RAO? | Did CASTOR run a 2nd preventive RAO? | Did the RAO fall back to initial situation? | Did the RAO fall back to 1st preventive RAO result even though a 2nd was run? |
---|---|---|---|---|
FIRST_PREVENTIVE_ONLY | ✔️ | |||
FIRST_PREVENTIVE_FELLBACK_TO_INITIAL_SITUATION | ✔️ | ✔️ | ||
SECOND_PREVENTIVE_IMPROVED_FIRST | ✔️ | ✔️ | ||
SECOND_PREVENTIVE_FELLBACK_TO_INITIAL_SITUATION | ✔️ | ✔️ | ✔️ | |
SECOND_PREVENTIVE_FELLBACK_TO_FIRST_PREVENTIVE_SITUATION | ✔️ | ✔️ | ✔️ |
OptimizationStepsExecuted getOptimizationStepsExecuted();
Example:
{
"optimizationStepsExecuted": "Second preventive improved first preventive results",
...
}
Objective function cost results
Contains information about the reached objective function value, seperated into functional and virtual costs:
- the functional cost reflects the business value of the objective (e.g. the cost associated to the minimum margin and the business penalties on usage of remedial actions)
- the virtual cost reflects the violation of some constraints (e.g. MNEC & loop-flow constraints)
// get the functional cost at a given state
double getFunctionalCost(OptimizationState optimizationState);
// get the total virtual cost at a given state
double getVirtualCost(OptimizationState optimizationState);
// get a specific virtual cost at a given state
double getVirtualCost(OptimizationState optimizationState, String virtualCostName);
// get all the virtual cost names in the RAO
Set<String> getVirtualCostNames();
// get the overall cost (functional + total virtual) at a given state
double getCost(OptimizationState optimizationState);
Example:
"costResults" : {
"initial" : {
"functionalCost" : 100.0,
"virtualCost" : {
"loopFlow" : 0.0,
"MNEC" : 0.0
}
},
"afterPRA" : {
"functionalCost" : 80.0,
"virtualCost" : {
"loopFlow" : 0.0,
"MNEC" : 0.0
}
},
"afterARA" : {
"functionalCost" : -20.0,
"virtualCost" : {
"loopFlow" : 15.0,
"MNEC" : 20.0
}
},
"afterCRA" : {
"functionalCost" : -50.0,
"virtualCost" : {
"loopFlow" : 10.0,
"MNEC" : 2.0
}
}
},
Flow CNECs results
These results contain important RAO information about flow CNECs.
Note that you have to use FlowCnec objects from the CRAC in order to query the RaoResult Java API.
Most results are power flow results (like flows & margins), and can be queried in two units
(AMEPRE & MEGAWATT) and on one or two sides (LEFT & RIGHT).
Flow
The actual power flow on the branch.
// get the flow on a given flow cnec, at a given side, in a given unit, at a given state
double getFlow(OptimizationState optimizationState, FlowCnec flowCnec, Side side, Unit unit);
Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"rightSide" : {
"flow": 1110.0,
...
},
"leftSide" : {
"flow": 1105.0,
...
}
},
"ampere" : {
...
"rightSide" : {
"flow": 2220.0,
...
},
"leftSide" : {
"flow": 2210.0,
...
}
},
...
},
"afterPRA" : {
"megawatt" : {
...
"leftSide" : {
"flow": 1210.0,
...
}
},
"ampere" : {
...
"leftSide" : {
"flow": 505.0,
...
}
},
...
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
...
Margin
The flow margin of the CNEC. If two flow values exist for the CNEC (i.e. if it is monitored on both sides) and / or if it has multiple thresholds, the smallest margin is returned.
// get the margin of a given flow cnec, in a given unit, at a given state
double getMargin(OptimizationState optimizationState, FlowCnec flowCnec, Unit unit);
Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"margin" : 1111.0,
...
},
"ampere" : {
...
"margin" : 1121.0,
...
},
...
},
"afterPRA" : {
"megawatt" : {
...
"margin" : 1211.0,
...
},
"ampere" : {
...
"margin" : 1221.0,
...
},
...
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
...
Relative margin
The relative margin is the smallest flow margin of the CNEC.
- When the margin is negative, the relative margin is equal to the margin
- When the margin is positive, it is equal to the margin divided by the zonal PTDF absolute sum
It is used to artificially increase (in the RAO) the margin on flow cnecs that are less impacted by changes in power exchanges between commercial zones, in order to prioritize other CNECs in the minimum margin optimisation.
(See Modelling the maximum minimum relative margin objective function)
// get the relative margin of a given flow cnec, in a given unit, at a given state
double getRelativeMargin(OptimizationState optimizationState, FlowCnec flowCnec, Unit unit);
Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"relativeMargin" : 1112.0,
...
},
"ampere" : {
...
"relativeMargin" : 1122.0,
...
},
...
},
"afterPRA" : {
"megawatt" : {
...
"relativeMargin" : 1212.0,
...
},
"ampere" : {
...
"relativeMargin" : 1222.0,
...
},
...
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
...
Loop-Flow
The loop-flow value on a CNEC.
Can only be queried for flow CNECs limited by loop-flow thresholds (info in the CRAC).
// get the loop-flow on a given flow cnec, at a given side, in a given unit, at a given state
double getLoopFlow(OptimizationState optimizationState, FlowCnec flowCnec, Side side, Unit unit);
Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"leftSide" : {
...
"loopFlow": 1113.0,
...
}
...
},
"ampere" : {
...
"leftSide" : {
...
"loopFlow": 1123.0,
...
}
...
},
...
},
"afterPRA" : {
"megawatt" : {
...
"rightSide" : {
...
"loopFlow": 1213.0,
...
}
...
},
"ampere" : {
...
"rightSide" : {
...
"loopFlow": 1223.0,
...
}
...
},
...
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
...
Commercial flow
The commercial flow on a CNEC.
Can only be queried for flow CNECs limited by loop-flow thresholds (info in the CRAC).
// get the commercial flow on a given flow cnec, at a given side, in a given unit, at a given state
double getCommercialFlow(OptimizationState optimizationState, FlowCnec flowCnec, Side side, Unit unit);
Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"leftSide" : {
...
"commercialFlow": 1114.0,
...
}
...
},
"ampere" : {
...
"leftSide" : {
...
"commercialFlow": 1124.0,
...
}
...
},
...
},
"afterPRA" : {
"megawatt" : {
...
"rightSide" : {
...
"commercialFlow": 1214.0,
...
}
...
},
"ampere" : {
...
"rightSide" : {
...
"commercialFlow": 1224.0,
...
}
...
},
...
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
...
Zonal PTDF absolute sum
The absolute sum of zonal PTDFs (influence factors) on a given CNEC. Reflects the influence of power exchanges between commercial zones on the CNEC.
Note that this value does not have a unit
// get the absolute sum of zonal PTDFs for a given flow cnec, at a given side, at a given state
double getPtdfZonalSum(OptimizationState optimizationState, FlowCnec flowCnec, Side side);
For compactness, zonal PTDF sums are written in the MEGAWATTS section Example:
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
...
"rightSide" : {
...
"zonalPtdfSum" : 0.1
...
}
...
},
...
},
"afterPRA" : {
...
Complete JSON example
"flowCnecResults" : [ {
"flowCnecId" : "cnec1outageId",
"initial" : {
"megawatt" : {
"margin" : 1111.0,
"relativeMargin" : 1112.0,
"rightSide" : {
"flow" : 1110.5,
"loopFlow" : 1113.5,
"commercialFlow" : 1114.5,
"zonalPtdfSum" : 0.6
}
},
"ampere" : {
"margin" : 1121.0,
"relativeMargin" : 1122.0,
"rightSide" : {
"flow" : 1120.5,
"loopFlow" : 1123.5,
"commercialFlow" : 1124.5
}
}
},
"afterPRA" : {
"megawatt" : {
"margin" : 1211.0,
"relativeMargin" : 1212.0,
"rightSide" : {
"flow" : 1210.5,
"loopFlow" : 1213.5,
"commercialFlow" : 1214.5,
"zonalPtdfSum" : 0.6
}
},
"ampere" : {
"margin" : 1221.0,
"relativeMargin" : 1222.0,
"rightSide" : {
"flow" : 1220.5,
"loopFlow" : 1223.5,
"commercialFlow" : 1224.5
}
}
}
}, {
"flowCnecId" : "cnec1prevId",
"initial" : {
"megawatt" : {
"margin" : 1111.0,
"relativeMargin" : 1112.0,
"rightSide" : {
"flow" : 1110.5,
"loopFlow" : 1113.5,
"commercialFlow" : 1114.5,
"zonalPtdfSum" : 0.6
}
},
"ampere" : {
"margin" : 1121.0,
"relativeMargin" : 1122.0,
"rightSide" : {
"flow" : 1120.5,
"loopFlow" : 1123.5,
"commercialFlow" : 1124.5
}
}
},
"afterPRA" : {
"megawatt" : {
"margin" : 1211.0,
"relativeMargin" : 1212.0,
"rightSide" : {
"flow" : 1210.5,
"loopFlow" : 1213.5,
"commercialFlow" : 1214.5,
"zonalPtdfSum" : 0.6
}
},
"ampere" : {
"margin" : 1221.0,
"relativeMargin" : 1222.0,
"rightSide" : {
"flow" : 1220.5,
"loopFlow" : 1223.5,
"commercialFlow" : 1224.5
}
}
}
}, ...
Angle CNECs results
These results contain important RAO information about angle CNECs.
Note that you have to use AngleCnec objects from the CRAC in order to query the RaoResult Java API.
Angle
Access the angle value of an AngleCnec.
Note that this feature is not implemented in the default RAO result implementation, as angle CNECs are not optimised by the RAO, but monitored by an angle monitoring module.
// get the angle value for a given angle cnec, at a given state, in a given angle unit
double getAngle(OptimizationState optimizationState, AngleCnec angleCnec, Unit unit);
Example:
"angleCnecResults" : [ {
"angleCnecId" : "angleCnecId",
"initial" : {
"degree" : {
"angle" : 3135.0,
...
}
},
"afterPRA" : {
"degree" : {
"angle" : 3235.0,
...
}
},
...
Margin
Access the angle margin value of an AngleCnec.
Note that this feature is not implemented in the default RAO result implementation, as angle CNECs are not optimised by the RAO, but monitored by an angle monitoring module.
// get the margin value for a given angle cnec, at a given state, in a given angle unit
double getMargin(OptimizationState optimizationState, AngleCnec angleCnec, Unit unit);
Example:
"angleCnecResults" : [ {
"angleCnecId" : "angleCnecId",
"initial" : {
"degree" : {
"margin" : 3135.0,
...
}
},
"afterPRA" : {
"degree" : {
"margin" : 3235.0,
...
}
},
...
Complete JSON example
"angleCnecResults" : [ {
"angleCnecId" : "angleCnecId",
"initial" : {
"degree" : {
"angle" : 3135.0,
"margin" : 3131.0
}
},
"afterPRA" : {
"degree" : {
"angle" : 3235.0,
"margin" : 3231.0
}
}, ...
Voltage CNECs results
These results contain important RAO information about voltage CNECs.
Note that you have to use VoltageCnec objects from the CRAC in order to query the RaoResult Java API.
Voltage
Access the voltage value of an VoltageCnec.
Note that this feature is not implemented in the default RAO result implementation, as voltage CNECs are not optimised by the RAO, but monitored by a voltage monitoring module.
// get the voltage value for a given voltage cnec, at a given state, in a given voltage unit
double getVoltage(OptimizationState optimizationState, VoltageCnec voltageCnec, Unit unit);
Example:
"voltageCnecResults" : [ {
"voltageCnecId" : "voltageCnecId",
"initial" : {
"kilovolt" : {
"voltage" : 4146.0,
...
}
},
"afterPRA" : {
"kilovolt" : {
"voltage" : 4246.0,
...
}
}, ...
Margin
Access the voltage margin value of a VoltageCnec.
Note that this feature is not implemented in the default RAO result implementation, as voltage CNECs are not optimised by the RAO, but monitored by a voltage monitoring module.
// get the margin value for a given voltage cnec, at a given state, in a given voltage unit
double getMargin(OptimizationState optimizationState, VoltageCnec voltageCnec, Unit unit);
Example:
"voltageCnecResults" : [ {
"voltageCnecId" : "voltageCnecId",
"initial" : {
"kilovolt" : {
...
"margin" : 4141.0
}
},
"afterPRA" : {
"kilovolt" : {
...
"margin" : 4241.0
}
}, ...
Complete JSON example
"voltageCnecResults" : [ {
"voltageCnecId" : "voltageCnecId",
"initial" : {
"kilovolt" : {
"voltage" : 4146.0,
"margin" : 4141.0
}
},
"afterPRA" : {
"kilovolt" : {
"voltage" : 4246.0,
"margin" : 4241.0
}
}, ...
Network actions results
These results contain information about the selection of network actions by the RAO. Note that you will need to use NetworkAction objects from the CRAC for querying the Java API.
// query if a network action was already activated before a given state was studied
boolean wasActivatedBeforeState(State state, NetworkAction networkAction);
// query if a network action was chosen during the optimization of a given state
boolean isActivatedDuringState(State state, NetworkAction networkAction);
// get the list of all network actions chosen during the optimization of a given state
Set<NetworkAction> getActivatedNetworkActionsDuringState(State state);
// query if a network action was during or before a given state
boolean isActivated(State state, NetworkAction networkAction);
Network actions that are not selected by the RAO do not appear in the JSON file Example:
"networkActionResults" : [ {
"networkActionId" : "complexNetworkActionId",
"activatedStates" : [ {
"instant" : "preventive"
} ]
}, {
"networkActionId" : "injectionSetpointRaId",
"activatedStates" : [ {
"instant" : "auto",
"contingency" : "contingency2Id"
} ]
}
...
Standard range actions results
These results contain information about the selection of standard range actions by the RAO.
Standard range actions are range actions that have a continuous set-point that can be optimised in a given range.
Actually, standard range actions handled by FARAO are: HVDC range actions and Injection range actions.
Note that you will need to use RangeAction objects from the CRAC for querying the Java API.
// get a range action's set-point before the optimization of a given state
double getPreOptimizationSetPointOnState(State state, RangeAction<?> rangeAction);
// query if a range action was activated (ie setpoint changed) during the optimization of a given state
boolean isActivatedDuringState(State state, RangeAction<?> rangeAction);
// get all range actions that were activated by the RAO in a given state
Set<RangeAction<?>> getActivatedRangeActionsDuringState(State state);
// get a range action's optimal setpoint, that was chosen by the RAO in a given state
double getOptimizedSetPointOnState(State state, RangeAction<?> rangeAction);
// get all range actions' optimal setpoints, that were chosen by the RAO in a given state
Map<RangeAction<?>, Double> getOptimizedSetPointsOnState(State state);
Example:
"rangeActionResults" : [ {
"rangeActionId" : "hvdcRange1Id",
"initialSetpoint" : 0.0,
"activatedStates" : [ {
"instant" : "preventive",
"setpoint" : -1000.0
} ]
}, {
"rangeActionId" : "hvdcRange2Id",
"initialSetpoint" : -100.0,
"activatedStates" : [ {
"instant" : "curative",
"contingency" : "contingency1Id",
"setpoint" : 100.0
}, {
"instant" : "curative",
"contingency" : "contingency2Id",
"setpoint" : 400.0
} ]
}, {
"rangeActionId" : "injectionRange1Id",
"initialSetpoint" : 100.0,
"activatedStates" : [ {
"instant" : "curative",
"contingency" : "contingency1Id",
"setpoint" : -300.0
} ]
} ]
PST range actions results
These results contain information about the application of PST range actions by the RAO.
PSTs are not standard range actions, because they have integer tap positions; a few extra methods in the API allow
querying the tap positions. All “set-point” methods of standard range actions also can also be used.
Note that you will need to use PstRangeAction or RangeAction objects from the CRAC for querying the Java API.
/* --- Standard RangeAction methods: --- */
// get a range action's setpoint before the optimization of a given state
double getPreOptimizationSetPointOnState(State state, RangeAction<?> rangeAction);
// query if a range action was activated (ie setpoint changed) during the optimization of a given state
boolean isActivatedDuringState(State state, RangeAction<?> rangeAction);
// get all range actions that were activated by the RAO in a given state
Set<RangeAction<?>> getActivatedRangeActionsDuringState(State state);
// get a range action's optimal setpoint, that was chosen by the RAO in a given state
double getOptimizedSetPointOnState(State state, RangeAction<?> rangeAction);
// get all range actions' optimal setpoints, that were chosen by the RAO in a given state
Map<RangeAction<?>, Double> getOptimizedSetPointsOnState(State state);
/* --- PST-specific methods: --- */
// get a PST range action's tap position before the optimization of a given state
int getPreOptimizationTapOnState(State state, PstRangeAction pstRangeAction);
// get a PST range action's optimal tap position, that was chosen by the RAO in a given state
int getOptimizedTapOnState(State state, PstRangeAction pstRangeAction);
// get all PST range actions' optimal tap positions, that were chosen by the RAO in a given state
Map<PstRangeAction, Integer> getOptimizedTapsOnState(State state);
Example:
"rangeActionResults" : [ {
"rangeActionId" : "pstRange1Id",
"initialSetpoint" : 0.0,
"initialTap" : -3,
"activatedStates" : [ {
"instant" : "preventive",
"tap" : 3,
"setpoint" : 3.0
} ]
}, {
"rangeActionId" : "pstRange2Id",
"initialSetpoint" : 1.5,
"initialTap" : 0,
"activatedStates" : [ ]
}, {
"rangeActionId" : "pstRange3Id",
"initialSetpoint" : 1.0,
"initialTap" : -1,
"activatedStates" : [ ]
} ]
See also
Internal json CRAC format, CASTOR