RaoLoggerTest.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.searchtreerao.commons;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import com.powsybl.contingency.Contingency;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.logs.OpenRaoLogger;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.openrao.commons.logs.RaoBusinessLogs;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.openrao.data.crac.api.NetworkElement;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.raoapi.parameters.ObjectiveFunctionParameters;
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
import com.powsybl.openrao.searchtreerao.result.api.ObjectiveFunctionResult;
import com.powsybl.openrao.searchtreerao.result.api.OptimizationResult;
import com.powsybl.openrao.searchtreerao.castor.algorithm.Perimeter;
import com.powsybl.openrao.searchtreerao.castor.algorithm.ContingencyScenario;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.slf4j.LoggerFactory;
import java.util.*;
import static java.lang.String.format;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static com.powsybl.openrao.commons.Unit.MEGAWATT;
import static com.powsybl.openrao.commons.Unit.AMPERE;
/**
* @author Peter Mitri {@literal <peter.mitri at rte-france.com>}
*/
class RaoLoggerTest {
private ObjectiveFunctionResult objectiveFunctionResult;
private FlowResult flowResult;
private FlowCnec cnec1;
private FlowCnec cnec2;
private FlowCnec cnec3;
private FlowCnec cnec4;
private FlowCnec cnec5;
private FlowCnec cnec6;
private State statePreventive;
private State stateCo1Auto;
private State stateCo1Curative;
private State stateCo2Curative;
private OptimizationResult basecaseOptimResult;
@BeforeEach
public void setUp() {
objectiveFunctionResult = mock(ObjectiveFunctionResult.class);
flowResult = mock(FlowResult.class);
basecaseOptimResult = mock(OptimizationResult.class);
Instant preventiveInstant = mock(Instant.class);
when(preventiveInstant.isPreventive()).thenReturn(true);
when(preventiveInstant.getKind()).thenReturn(InstantKind.PREVENTIVE);
Instant autoInstant = mock(Instant.class);
when(autoInstant.getKind()).thenReturn(InstantKind.AUTO);
Instant curativeInstant = mock(Instant.class);
when(curativeInstant.getKind()).thenReturn(InstantKind.CURATIVE);
when(curativeInstant.getOrder()).thenReturn(3);
statePreventive = mockState("preventive", preventiveInstant);
stateCo1Auto = mockState("co1 - auto", autoInstant);
stateCo1Curative = mockState("co1 - curative", curativeInstant);
stateCo2Curative = mockState("co2 - curative", curativeInstant);
when(preventiveInstant.comesBefore(curativeInstant)).thenReturn(true);
cnec1 = mockCnec("ne1", stateCo1Curative, -10, -10, 30, 300, 0.1);
cnec2 = mockCnec("ne2", statePreventive, 0, 0, -10, -10, 0.2);
cnec3 = mockCnec("ne3", stateCo2Curative, 10, 100, 10, 200, 0.3);
cnec4 = mockCnec("ne4", stateCo1Auto, 20, 200, 0, 0, 0.4);
cnec5 = mockCnec("ne5", stateCo1Curative, 30, 300, 20, 100, 0.5);
cnec6 = mockCnec("ne6", stateCo1Curative, -0.0003, -0.0003, -0.002, -0.002, 0.5);
}
private State mockState(String stateId, Instant instant) {
State state = mock(State.class);
when(state.getId()).thenReturn(stateId);
when(state.getInstant()).thenReturn(instant);
return state;
}
private FlowCnec mockCnec(String neName, State state, double marginMw, double relMarginMw, double marginA, double relMarginA, double ptdf) {
NetworkElement ne = mock(NetworkElement.class);
when(ne.getName()).thenReturn(neName);
FlowCnec cnec = mock(FlowCnec.class);
when(cnec.getNetworkElement()).thenReturn(ne);
when(cnec.getState()).thenReturn(state);
String cnecId = neName + " @ " + state.getId();
when(cnec.getId()).thenReturn(cnecId);
mockCnecFlowResult(flowResult, cnec, marginMw, relMarginMw, marginA, relMarginA, ptdf);
mockCnecFlowResult(basecaseOptimResult, cnec, marginMw, relMarginMw, marginA, relMarginA, ptdf);
when(cnec.getMonitoredSides()).thenReturn(Set.of(TwoSides.ONE));
return cnec;
}
private void mockCnecFlowResult(FlowResult flowResult, FlowCnec cnec, double marginMw, double relMarginMw, double marginA, double relMarginA, double ptdf) {
when(flowResult.getMargin(cnec, Unit.MEGAWATT)).thenReturn(marginMw);
when(flowResult.getRelativeMargin(cnec, Unit.MEGAWATT)).thenReturn(relMarginMw);
when(flowResult.getMargin(cnec, Unit.AMPERE)).thenReturn(marginA);
when(flowResult.getRelativeMargin(cnec, Unit.AMPERE)).thenReturn(relMarginA);
when(flowResult.getPtdfZonalSum(cnec, TwoSides.ONE)).thenReturn(ptdf);
}
private String absoluteMarginLog(int order, double margin, Unit unit, FlowCnec cnec) {
return marginLog(order, margin, false, null, unit, cnec);
}
private String relativeMarginLog(int order, double margin, Double ptdf, Unit unit, FlowCnec cnec) {
return marginLog(order, margin, true, ptdf, unit, cnec);
}
private String marginLog(int order, double margin, boolean relative, Double ptdf, Unit unit, FlowCnec cnec) {
String relativeMargin = relative ? " relative" : "";
String ptdfString = (ptdf != null) ? format(" (PTDF %f)", ptdf) : "";
String descriptor = format("%s at state %s", cnec.getNetworkElement().getName(), cnec.getState().getId());
return format(Locale.ENGLISH, "Limiting element #%02d:%s margin = %s %s%s, element %s, CNEC ID = \"%s\"", order, relativeMargin, margin, unit, ptdfString, descriptor, cnec.getId());
}
@Test
void testGetSummaryFromObjFunctionResultOnAllStates() {
// Absolute MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec2, cnec3, cnec4, cnec5));
List<String> summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.MEGAWATT, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -10, MEGAWATT, cnec1), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, MEGAWATT, cnec2), summary.get(1));
assertEquals(absoluteMarginLog(3, 10, MEGAWATT, cnec3), summary.get(2));
assertEquals(absoluteMarginLog(4, 20, MEGAWATT, cnec4), summary.get(3));
assertEquals(absoluteMarginLog(5, 30, MEGAWATT, cnec5), summary.get(4));
// Relative MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec2, cnec3, cnec4, cnec5));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.MEGAWATT, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -10, MEGAWATT, cnec1), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, MEGAWATT, cnec2), summary.get(1));
assertEquals(relativeMarginLog(3, 100, .3, MEGAWATT, cnec3), summary.get(2));
assertEquals(relativeMarginLog(4, 200, .4, MEGAWATT, cnec4), summary.get(3));
assertEquals(relativeMarginLog(5, 300, .5, MEGAWATT, cnec5), summary.get(4));
// Absolute A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec2, cnec4, cnec3, cnec5, cnec1));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.AMPERE, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -10, AMPERE, cnec2), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, AMPERE, cnec4), summary.get(1));
assertEquals(absoluteMarginLog(3, 10, AMPERE, cnec3), summary.get(2));
assertEquals(absoluteMarginLog(4, 20, AMPERE, cnec5), summary.get(3));
assertEquals(absoluteMarginLog(5, 30, AMPERE, cnec1), summary.get(4));
// Relative A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec2, cnec4, cnec5, cnec3, cnec1));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(statePreventive, stateCo1Auto, stateCo1Curative, stateCo2Curative), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.AMPERE, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -10, AMPERE, cnec2), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, AMPERE, cnec4), summary.get(1));
assertEquals(relativeMarginLog(3, 100, .5, AMPERE, cnec5), summary.get(2));
assertEquals(relativeMarginLog(4, 200, .3, AMPERE, cnec3), summary.get(3));
assertEquals(relativeMarginLog(5, 300, .1, AMPERE, cnec1), summary.get(4));
}
@Test
void testGetMostLimitingElementsForNarrowMargin() {
// Absolute MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec6));
List<String> summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.MEGAWATT, 1);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, -0.0003, MEGAWATT, cnec6), summary.get(0));
// Relative MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec6));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.MEGAWATT, 5);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, -0.0003, MEGAWATT, cnec6), summary.get(0));
// Absolute A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec6));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, null, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.AMPERE, 5);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, -0.002, AMPERE, cnec6), summary.get(0));
// Relative A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec6));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(statePreventive, stateCo1Auto, stateCo1Curative, stateCo2Curative), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.AMPERE, 5);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, -0.002, AMPERE, cnec6), summary.get(0));
}
@Test
void testGetSummaryFromObjFunctionResultOnSomeStates() {
// Absolute MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec2, cnec3, cnec4, cnec5));
List<String> summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.MEGAWATT, 5);
assertEquals(0, summary.size());
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(statePreventive), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.MEGAWATT, 5);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, 0, MEGAWATT, cnec2), summary.get(0));
// Relative MW
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec2, cnec3, cnec4, cnec5));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(statePreventive, stateCo1Curative), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.MEGAWATT, 5);
assertEquals(3, summary.size());
assertEquals(absoluteMarginLog(1, -10, MEGAWATT, cnec1), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, MEGAWATT, cnec2), summary.get(1));
assertEquals(relativeMarginLog(3, 300, .5, MEGAWATT, cnec5), summary.get(2));
// Absolute A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec2, cnec4, cnec3, cnec5, cnec1));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(stateCo2Curative), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.AMPERE, 5);
assertEquals(1, summary.size());
assertEquals(absoluteMarginLog(1, 10, AMPERE, cnec3), summary.get(0));
// Relative A
when(objectiveFunctionResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec2, cnec4, cnec5, cnec3, cnec1));
summary = RaoLogger.getMostLimitingElementsResults(objectiveFunctionResult, flowResult, Set.of(stateCo2Curative, stateCo1Auto), ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.AMPERE, 5);
assertEquals(2, summary.size());
assertEquals(absoluteMarginLog(1, 0, AMPERE, cnec4), summary.get(0));
assertEquals(relativeMarginLog(2, 200, .3, AMPERE, cnec3), summary.get(1));
}
@Test
void testGetSummaryFromScenarios() {
Contingency contingency2 = mock(Contingency.class);
when(stateCo2Curative.getContingency()).thenReturn(Optional.of(contingency2));
Contingency contingency1 = mock(Contingency.class);
when(stateCo1Auto.getContingency()).thenReturn(Optional.of(contingency1));
when(stateCo1Curative.getContingency()).thenReturn(Optional.of(contingency1));
Perimeter preventivePerimeter = new Perimeter(statePreventive, Set.of(stateCo2Curative));
Perimeter curativePerimeter = new Perimeter(stateCo1Curative, null);
Set<ContingencyScenario> contingencyScenarios = Set.of(
ContingencyScenario.create()
.withContingency(stateCo1Auto.getContingency().get())
.withAutomatonState(stateCo1Auto)
.withCurativePerimeter(curativePerimeter)
.build());
OptimizationResult co1AutoOptimResult = mock(OptimizationResult.class);
OptimizationResult co1CurativeOptimResult = mock(OptimizationResult.class);
Map<State, OptimizationResult> contingencyOptimizationResults = Map.of(stateCo1Auto, co1AutoOptimResult, stateCo1Curative, co1CurativeOptimResult);
mockCnecFlowResult(co1AutoOptimResult, cnec1, 25, 40, 15, 11, .1);
mockCnecFlowResult(co1AutoOptimResult, cnec4, 35, 50, -21, -21, .4);
mockCnecFlowResult(co1AutoOptimResult, cnec5, -45, -45, 10, 12, .5);
mockCnecFlowResult(co1CurativeOptimResult, cnec1, 2, 1, -8, -8, .1);
mockCnecFlowResult(co1CurativeOptimResult, cnec5, -8, -8, 12, 100, .5);
// Absolute MW
when(basecaseOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec2, cnec3, cnec4, cnec5));
when(co1AutoOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec5, cnec1, cnec4));
when(co1CurativeOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec5, cnec1));
List<String> summary = RaoLogger.getMostLimitingElementsResults(preventivePerimeter, basecaseOptimResult, contingencyScenarios, contingencyOptimizationResults, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.MEGAWATT, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -8, MEGAWATT, cnec5), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, MEGAWATT, cnec2), summary.get(1));
assertEquals(absoluteMarginLog(3, 2, MEGAWATT, cnec1), summary.get(2));
assertEquals(absoluteMarginLog(4, 10, MEGAWATT, cnec3), summary.get(3));
assertEquals(absoluteMarginLog(5, 35, MEGAWATT, cnec4), summary.get(4));
// Relative MW
when(basecaseOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec5, cnec4, cnec3, cnec2, cnec1));
when(co1AutoOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec5, cnec1, cnec4));
when(co1CurativeOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec5, cnec1));
summary = RaoLogger.getMostLimitingElementsResults(preventivePerimeter, basecaseOptimResult, contingencyScenarios, contingencyOptimizationResults, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.MEGAWATT, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -8, MEGAWATT, cnec5), summary.get(0));
assertEquals(absoluteMarginLog(2, 0, MEGAWATT, cnec2), summary.get(1));
assertEquals(relativeMarginLog(3, 1, null, MEGAWATT, cnec1), summary.get(2));
assertEquals(relativeMarginLog(4, 50, null, MEGAWATT, cnec4), summary.get(3));
assertEquals(relativeMarginLog(5, 100, null, MEGAWATT, cnec3), summary.get(4));
// Absolute A
when(basecaseOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec2, cnec5, cnec1, cnec3, cnec4));
when(co1AutoOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec4, cnec5, cnec1));
when(co1CurativeOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec5));
summary = RaoLogger.getMostLimitingElementsResults(preventivePerimeter, basecaseOptimResult, contingencyScenarios, contingencyOptimizationResults, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_MARGIN, Unit.AMPERE, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -21, AMPERE, cnec4), summary.get(0));
assertEquals(absoluteMarginLog(2, -10, AMPERE, cnec2), summary.get(1));
assertEquals(absoluteMarginLog(3, -8, AMPERE, cnec1), summary.get(2));
assertEquals(absoluteMarginLog(4, 10, AMPERE, cnec3), summary.get(3));
assertEquals(absoluteMarginLog(5, 12, AMPERE, cnec5), summary.get(4));
// Relative A
when(basecaseOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec4, cnec3, cnec5, cnec1, cnec2));
when(co1AutoOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec4, cnec1, cnec5));
when(co1CurativeOptimResult.getMostLimitingElements(anyInt())).thenReturn(List.of(cnec1, cnec5));
summary = RaoLogger.getMostLimitingElementsResults(preventivePerimeter, basecaseOptimResult, contingencyScenarios, contingencyOptimizationResults, ObjectiveFunctionParameters.ObjectiveFunctionType.MAX_MIN_RELATIVE_MARGIN, Unit.AMPERE, 5);
assertEquals(5, summary.size());
assertEquals(absoluteMarginLog(1, -21, AMPERE, cnec4), summary.get(0));
assertEquals(absoluteMarginLog(2, -10, AMPERE, cnec2), summary.get(1));
assertEquals(absoluteMarginLog(3, -8, AMPERE, cnec1), summary.get(2));
assertEquals(relativeMarginLog(4, 100, null, AMPERE, cnec5), summary.get(3));
assertEquals(relativeMarginLog(5, 200, null, AMPERE, cnec3), summary.get(4));
}
@Test
void testFormatDoubleBasedOnMarginWithPositiveMargin() {
double margin = 1.2; // margin > 0, formatDoubleBasedOnMargin to default number of decimals = 2;
assertEquals("10.0", RaoLogger.formatDoubleBasedOnMargin(10., margin));
assertEquals("-53.63", RaoLogger.formatDoubleBasedOnMargin(-53.634, margin));
assertEquals("-53.64", RaoLogger.formatDoubleBasedOnMargin(-53.635, margin));
assertEquals("-infinity", RaoLogger.formatDoubleBasedOnMargin(-Double.MAX_VALUE, margin));
assertEquals("+infinity", RaoLogger.formatDoubleBasedOnMargin(Double.MAX_VALUE, margin));
assertEquals("-infinity", RaoLogger.formatDoubleBasedOnMargin(-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00, margin));
assertEquals("+infinity", RaoLogger.formatDoubleBasedOnMargin(179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00, margin));
}
@Test
void testFormatDoubleBasedOnMarginWithNegativeMargin() {
double margin = -0.0004; // -1 < margin < 0, formatDoubleBasedOnMargin depending on margin
assertEquals("10.0", RaoLogger.formatDoubleBasedOnMargin(10., margin));
assertEquals("-53.634", RaoLogger.formatDoubleBasedOnMargin(-53.634, margin));
assertEquals("-53.6354", RaoLogger.formatDoubleBasedOnMargin(-53.63535, margin));
assertEquals("-infinity", RaoLogger.formatDoubleBasedOnMargin(-Double.MAX_VALUE, margin));
assertEquals("+infinity", RaoLogger.formatDoubleBasedOnMargin(Double.MAX_VALUE, margin));
assertEquals("-infinity", RaoLogger.formatDoubleBasedOnMargin(-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00, margin));
assertEquals("+infinity", RaoLogger.formatDoubleBasedOnMargin(179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00, margin));
}
private ListAppender<ILoggingEvent> registerLogs(Class clazz) {
Logger logger = (Logger) LoggerFactory.getLogger(clazz);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.start();
logger.addAppender(listAppender);
return listAppender;
}
@Test
void testLogOptimizationSummary() {
State preventive = Mockito.mock(State.class);
Instant preventiveInstant = Mockito.mock(Instant.class);
when(preventiveInstant.toString()).thenReturn("preventive");
when(preventive.getInstant()).thenReturn(preventiveInstant);
State curative = Mockito.mock(State.class);
Instant curativeInstant = Mockito.mock(Instant.class);
when(curativeInstant.toString()).thenReturn("curative");
when(curative.getInstant()).thenReturn(curativeInstant);
Contingency contingency = Mockito.mock(Contingency.class);
when(contingency.getName()).thenReturn(Optional.of("contingency"));
when(curative.getContingency()).thenReturn(Optional.of(contingency));
OpenRaoLogger logger = OpenRaoLoggerProvider.BUSINESS_LOGS;
List<ILoggingEvent> logsList = registerLogs(RaoBusinessLogs.class).list;
// initial objective
ObjectiveFunctionResult initialObjectiveFunctionResult = Mockito.mock(ObjectiveFunctionResult.class);
when(initialObjectiveFunctionResult.getCost()).thenReturn(-200.);
when(initialObjectiveFunctionResult.getFunctionalCost()).thenReturn(-210.3);
when(initialObjectiveFunctionResult.getVirtualCost()).thenReturn(10.3);
when(initialObjectiveFunctionResult.getVirtualCostNames()).thenReturn(Set.of("sensi-fallback-cost"));
when(initialObjectiveFunctionResult.getVirtualCost("sensi-fallback-cost")).thenReturn(10.3);
// final objective
when(objectiveFunctionResult.getCost()).thenReturn(-100.);
when(objectiveFunctionResult.getFunctionalCost()).thenReturn(-150.);
when(objectiveFunctionResult.getVirtualCost()).thenReturn(50.);
when(objectiveFunctionResult.getVirtualCostNames()).thenReturn(Set.of("mnec-violation-cost", "loopflow-violation-cost"));
when(objectiveFunctionResult.getVirtualCost("mnec-violation-cost")).thenReturn(42.2);
when(objectiveFunctionResult.getVirtualCost("loopflow-violation-cost")).thenReturn(7.8);
// Create Remedial actions
NetworkAction fakeRA = Mockito.mock(NetworkAction.class);
when(fakeRA.getName()).thenReturn("Open_fake_RA");
Set<NetworkAction> networkActions = Set.of(fakeRA);
Map<RangeAction<?>, Double> rangeActions = new HashMap<>();
RangeAction<?> fakePST1 = Mockito.mock(RangeAction.class);
RangeAction<?> fakePST2 = Mockito.mock(RangeAction.class);
when(fakePST1.getName()).thenReturn("PST_1");
when(fakePST2.getName()).thenReturn("PST_2");
rangeActions.put(fakePST1, -2.);
rangeActions.put(fakePST2, 4.);
RaoLogger.logOptimizationSummary(logger, preventive, networkActions, rangeActions, initialObjectiveFunctionResult, objectiveFunctionResult);
assertEquals("[INFO] Scenario \"preventive\": initial cost = -200.0 (functional: -210.3, virtual: 10.3 {sensi-fallback-cost=10.3})," +
" 1 network action(s) and 2 range action(s) activated : Open_fake_RA and PST_2: 4, PST_1: -2," +
" cost after preventive optimization = -100.0 (functional: -150.0, virtual: 50.0 {mnec-violation-cost=42.2, loopflow-violation-cost=7.8})", logsList.get(logsList.size() - 1).toString());
// Remove virtual cost for visibility
when(initialObjectiveFunctionResult.getCost()).thenReturn(-200.);
when(initialObjectiveFunctionResult.getFunctionalCost()).thenReturn(-200.);
when(initialObjectiveFunctionResult.getVirtualCost()).thenReturn(0.);
when(initialObjectiveFunctionResult.getVirtualCost("sensi-fallback-cost")).thenReturn(0.);
when(objectiveFunctionResult.getCost()).thenReturn(-100.);
when(objectiveFunctionResult.getFunctionalCost()).thenReturn(-100.);
when(objectiveFunctionResult.getVirtualCost()).thenReturn(0.);
when(objectiveFunctionResult.getVirtualCostNames()).thenReturn(Set.of("mnec-violation-cost", "loopflow-violation-cost"));
when(objectiveFunctionResult.getVirtualCost("mnec-violation-cost")).thenReturn(0.);
when(objectiveFunctionResult.getVirtualCost("loopflow-violation-cost")).thenReturn(0.);
RaoLogger.logOptimizationSummary(logger, curative, Collections.emptySet(), rangeActions, initialObjectiveFunctionResult, objectiveFunctionResult);
assertEquals("[INFO] Scenario \"contingency\": initial cost = -200.0 (functional: -200.0, virtual: 0.0)," +
" 2 range action(s) activated : PST_2: 4, PST_1: -2, cost after curative optimization = -100.0 (functional: -100.0, virtual: 0.0)", logsList.get(logsList.size() - 1).toString());
RaoLogger.logOptimizationSummary(logger, preventive, Collections.emptySet(), Collections.emptyMap(), initialObjectiveFunctionResult, objectiveFunctionResult);
assertEquals("[INFO] Scenario \"preventive\": initial cost = -200.0 (functional: -200.0, virtual: 0.0)," +
" no remedial actions activated, cost after preventive optimization = -100.0 (functional: -100.0, virtual: 0.0)", logsList.get(logsList.size() - 1).toString());
RaoLogger.logOptimizationSummary(logger, preventive, networkActions, Collections.emptyMap(), initialObjectiveFunctionResult, objectiveFunctionResult);
assertEquals("[INFO] Scenario \"preventive\": initial cost = -200.0 (functional: -200.0, virtual: 0.0)," +
" 1 network action(s) activated : Open_fake_RA, cost after preventive optimization = -100.0 (functional: -100.0, virtual: 0.0)", logsList.get(logsList.size() - 1).toString());
RaoLogger.logOptimizationSummary(logger, preventive, Collections.emptySet(), Collections.emptyMap(), null, objectiveFunctionResult);
assertEquals("[INFO] Scenario \"preventive\":" +
" no remedial actions activated, cost after preventive optimization = -100.0 (functional: -100.0, virtual: 0.0)", logsList.get(logsList.size() - 1).toString());
assertThrows(java.lang.NullPointerException.class, () -> RaoLogger.logOptimizationSummary(logger, preventive, Collections.emptySet(), Collections.emptyMap(), initialObjectiveFunctionResult, null));
}
@Test
void testLogFailedOptimizationSummary() {
State preventive = Mockito.mock(State.class);
State curative = Mockito.mock(State.class);
Contingency contingency = Mockito.mock(Contingency.class);
when(contingency.getName()).thenReturn(Optional.of("contingency"));
when(curative.getContingency()).thenReturn(Optional.of(contingency));
OpenRaoLogger logger = OpenRaoLoggerProvider.BUSINESS_LOGS;
List<ILoggingEvent> logsList = registerLogs(RaoBusinessLogs.class).list;
// Create Remedial actions
NetworkAction fakeRA = Mockito.mock(NetworkAction.class);
when(fakeRA.getName()).thenReturn("Open_fake_RA");
Set<NetworkAction> networkActions = Set.of(fakeRA);
Map<RangeAction<?>, Double> rangeActions = new HashMap<>();
RangeAction<?> fakePST1 = Mockito.mock(RangeAction.class);
RangeAction<?> fakePST2 = Mockito.mock(RangeAction.class);
when(fakePST1.getName()).thenReturn("PST_1");
when(fakePST2.getName()).thenReturn("PST_2");
rangeActions.put(fakePST1, -2.);
rangeActions.put(fakePST2, 4.);
RaoLogger.logFailedOptimizationSummary(logger, preventive, Collections.emptySet(), Collections.emptyMap());
assertEquals("[INFO] Scenario \"preventive\": no remedial actions activated", logsList.get(logsList.size() - 1).toString());
RaoLogger.logFailedOptimizationSummary(logger, curative, networkActions, Collections.emptyMap());
assertEquals("[INFO] Scenario \"contingency\": 1 network action(s) activated : Open_fake_RA", logsList.get(logsList.size() - 1).toString());
RaoLogger.logFailedOptimizationSummary(logger, curative, Collections.emptySet(), rangeActions);
assertEquals("[INFO] Scenario \"contingency\": 2 range action(s) activated : PST_2: 4, PST_1: -2", logsList.get(logsList.size() - 1).toString());
RaoLogger.logFailedOptimizationSummary(logger, curative, networkActions, rangeActions);
assertEquals("[INFO] Scenario \"contingency\": 1 network action(s) and 2 range action(s) activated : Open_fake_RA and PST_2: 4, PST_1: -2", logsList.get(logsList.size() - 1).toString());
}
}