Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logs range actions activated #734

Merged
merged 20 commits into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ AutomatonPerimeterResultImpl simulateAutomatonState(State automatonState, State
automatonState);
failedAutomatonPerimeterResultImpl.setComputationStatus(ComputationStatus.FAILURE);
TECHNICAL_LOGS.info("Automaton state {} has failed during sensitivity computation during range automaton simulation.", automatonState.getId());
RaoLogger.logFailedOptimizationSummary(BUSINESS_LOGS, automatonState, failedAutomatonPerimeterResultImpl.getActivatedNetworkActions().size(), failedAutomatonPerimeterResultImpl.getActivatedRangeActions(automatonState).size());
RaoLogger.logFailedOptimizationSummary(BUSINESS_LOGS, automatonState, failedAutomatonPerimeterResultImpl.getActivatedNetworkActions(), getRangeActionsAndTheirTapsAppliedOnState(failedAutomatonPerimeterResultImpl, automatonState));
return failedAutomatonPerimeterResultImpl;
}
// Build and return optimization result
Expand All @@ -131,7 +131,7 @@ AutomatonPerimeterResultImpl simulateAutomatonState(State automatonState, State
rangeAutomatonSimulationResult.getRangeActionsWithSetpoint(),
automatonState);
TECHNICAL_LOGS.info("Automaton state {} has been optimized.", automatonState.getId());
RaoLogger.logOptimizationSummary(BUSINESS_LOGS, automatonState, automatonPerimeterResultImpl.getActivatedNetworkActions().size(), automatonPerimeterResultImpl.getActivatedRangeActions(automatonState).size(), null, null, automatonPerimeterResultImpl);
RaoLogger.logOptimizationSummary(BUSINESS_LOGS, automatonState, automatonPerimeterResultImpl.getActivatedNetworkActions(), getRangeActionsAndTheirTapsAppliedOnState(automatonPerimeterResultImpl, automatonState), null, automatonPerimeterResultImpl);
return automatonPerimeterResultImpl;
}

Expand All @@ -144,6 +144,14 @@ private PrePerimeterSensitivityAnalysis getPreAutoPerimeterSensitivityAnalysis(S
return new PrePerimeterSensitivityAnalysis(flowCnecsInSensi, rangeActionsInSensi, raoParameters, toolProvider);
}

public static Map<RangeAction<?>, Double> getRangeActionsAndTheirTapsAppliedOnState(OptimizationResult optimizationResult, State state) {
Set< RangeAction<?>> setActivatedRangeActions = optimizationResult.getActivatedRangeActions(state);
Map<RangeAction<?>, Double> allRangeActions = new HashMap<>();
MartinBelthle marked this conversation as resolved.
Show resolved Hide resolved
setActivatedRangeActions.stream().filter(PstRangeAction.class::isInstance).map(PstRangeAction.class::cast).forEach(pstRangeAction -> allRangeActions.put(pstRangeAction, (double) optimizationResult.getOptimizedTap(pstRangeAction, state)));
setActivatedRangeActions.stream().filter(ra -> !(ra instanceof PstRangeAction)).forEach(rangeAction -> allRangeActions.put(rangeAction, optimizationResult.getOptimizedSetpoint(rangeAction, state)));
return allRangeActions;
}

AutomatonPerimeterResultImpl createFailedAutomatonPerimeterResult(State autoState, PrePerimeterResult result, Set<NetworkAction> activatedNetworkActions, String defineMoment) {
AutomatonPerimeterResultImpl failedAutomatonPerimeterResultImpl = new AutomatonPerimeterResultImpl(
result,
Expand All @@ -153,7 +161,7 @@ AutomatonPerimeterResultImpl createFailedAutomatonPerimeterResult(State autoStat
autoState);
failedAutomatonPerimeterResultImpl.setComputationStatus(ComputationStatus.FAILURE);
TECHNICAL_LOGS.info("Automaton state {} has failed during sensitivity computation {} topological automaton simulation.", autoState.getId(), defineMoment);
RaoLogger.logFailedOptimizationSummary(BUSINESS_LOGS, autoState, failedAutomatonPerimeterResultImpl.getActivatedNetworkActions().size(), failedAutomatonPerimeterResultImpl.getActivatedRangeActions(autoState).size());
RaoLogger.logFailedOptimizationSummary(BUSINESS_LOGS, autoState, failedAutomatonPerimeterResultImpl.getActivatedNetworkActions(), getRangeActionsAndTheirTapsAppliedOnState(failedAutomatonPerimeterResultImpl, autoState));
return failedAutomatonPerimeterResultImpl;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import com.farao_community.farao.commons.Unit;
import com.farao_community.farao.commons.logs.FaraoLogger;
import com.farao_community.farao.data.crac_api.Contingency;
import com.farao_community.farao.data.crac_api.Identifiable;
import com.farao_community.farao.data.crac_api.State;
import com.farao_community.farao.data.crac_api.cnec.FlowCnec;
import com.farao_community.farao.data.crac_api.cnec.Side;
import com.farao_community.farao.data.crac_api.network_action.NetworkAction;
import com.farao_community.farao.data.crac_api.range_action.PstRangeAction;
import com.farao_community.farao.data.crac_api.range_action.RangeAction;
import com.farao_community.farao.data.rao_result_api.OptimizationState;
import com.farao_community.farao.rao_api.parameters.ObjectiveFunctionParameters;
import com.farao_community.farao.rao_api.parameters.RaoParameters;
Expand All @@ -24,8 +27,10 @@
import com.farao_community.farao.search_tree_rao.castor.algorithm.BasecaseScenario;
import com.farao_community.farao.search_tree_rao.castor.algorithm.ContingencyScenario;
import com.farao_community.farao.search_tree_rao.search_tree.algorithms.Leaf;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.farao_community.farao.commons.logs.FaraoLoggerProvider.BUSINESS_LOGS;
Expand Down Expand Up @@ -56,43 +61,35 @@ public static void logSensitivityAnalysisResults(String prefix,
formatDouble(prePerimeterObjectiveFunctionResult.getCost()),
formatDouble(prePerimeterObjectiveFunctionResult.getFunctionalCost()),
formatDouble(prePerimeterObjectiveFunctionResult.getVirtualCost()));
Map<String, Double> virtualCosts = getVirtualCostDetailed(prePerimeterObjectiveFunctionResult);

RaoLogger.logMostLimitingElementsResults(BUSINESS_LOGS,
sensitivityAnalysisResult,
raoParameters.getObjectiveFunctionParameters().getType(),
numberOfLoggedLimitingElements);
}

public static void logRangeActions(FaraoLogger logger,
Leaf leaf,
OptimizationPerimeter optimizationContext) {
logRangeActions(logger, leaf, optimizationContext, null);
}

public static void logRangeActions(FaraoLogger logger,
Leaf leaf,
OptimizationPerimeter
optimizationContext, String prefix) {

boolean globalPstOptimization = optimizationContext instanceof GlobalOptimizationPerimeter;

String rangeActionSetpoints = optimizationContext.getRangeActionsPerState().entrySet().stream()
.flatMap(eState -> eState.getValue().stream().map(rangeAction -> {
double rangeActionValue;
if (rangeAction instanceof PstRangeAction) {
rangeActionValue = leaf.getOptimizedTap((PstRangeAction) rangeAction, eState.getKey());
} else {
rangeActionValue = leaf.getOptimizedSetpoint(rangeAction, eState.getKey());
}
if (globalPstOptimization) {
return format("%s@%s: %.0f", rangeAction.getName(), eState.getKey().getId(), rangeActionValue);
} else {
return format("%s: %.0f", rangeAction.getName(), rangeActionValue);
}
}))
.collect(Collectors.joining(", "));

logger.info("{}range action(s): {}", prefix == null ? "" : prefix, rangeActionSetpoints);
List<String> rangeActionSetpoints = optimizationContext.getRangeActionOptimizationStates().stream().flatMap(state ->
leaf.getActivatedRangeActions(state).stream().map(rangeAction -> {
double rangeActionValue = rangeAction instanceof PstRangeAction ? leaf.getOptimizedTap((PstRangeAction) rangeAction, state) :
leaf.getOptimizedSetpoint(rangeAction, state);
return globalPstOptimization ? format("%s@%s: %.0f", rangeAction.getName(), state.getId(), rangeActionValue) :
format("%s: %.0f", rangeAction.getName(), rangeActionValue);
})).collect(Collectors.toList());

boolean isRangeActionSetPointEmpty = rangeActionSetpoints.isEmpty();
if (isRangeActionSetPointEmpty) {
logger.info("{}No range actions activated", prefix == null ? "" : prefix);
} else {
logger.info("{}range action(s): {}", prefix == null ? "" : prefix, String.join(", ", rangeActionSetpoints));
}
}

public static void logMostLimitingElementsResults(FaraoLogger logger, OptimizationResult optimizationResult, ObjectiveFunctionParameters.ObjectiveFunctionType objectiveFunction, int numberOfLoggedElements) {
Expand Down Expand Up @@ -249,40 +246,55 @@ private static Map<FlowCnec, Double> getMostLimitingElementsAndMargins(Optimizat
return mostLimitingElementsAndMargins;
}

public static void logOptimizationSummary(FaraoLogger logger, State optimizedState, long activatedNetworkActions, long activatedRangeActions, Double initialFunctionalCost, Double initialVirtualCost, ObjectiveFunctionResult finalObjective) {
Optional<Contingency> optionalContingency = optimizedState.getContingency();
String scenarioName = optionalContingency.isEmpty() ? "preventive" : optionalContingency.get().getName();
String raResult = "";
if (activatedNetworkActions + activatedRangeActions == 0) {
raResult = "no remedial actions activated";
} else if (activatedNetworkActions > 0 && activatedRangeActions == 0) {
raResult = String.format("%s network action(s) activated", activatedNetworkActions);
} else if (activatedRangeActions > 0 && activatedNetworkActions == 0) {
raResult = String.format("%s range action(s) activated", activatedRangeActions);
public static void logFailedOptimizationSummary(FaraoLogger logger, State optimizedState, Set<NetworkAction> networkActions, Map<RangeAction<?>, java.lang.Double> rangeActions) {
String scenarioName = getScenarioName(optimizedState);
String raResult = getRaResult(networkActions, rangeActions);
logger.info("Scenario \"{}\": {}", scenarioName, raResult);
}

public static void logOptimizationSummary(FaraoLogger logger, State optimizedState, Set<NetworkAction> networkActions, Map<RangeAction<?>, java.lang.Double> rangeActions, ObjectiveFunctionResult preOptimObjectiveFunctionResult, ObjectiveFunctionResult finalObjective) {
String scenarioName = getScenarioName(optimizedState);
String raResult = getRaResult(networkActions, rangeActions);
Map<String, Double> finalVirtualCostDetailed = getVirtualCostDetailed(finalObjective);
String initialCostString;
if (preOptimObjectiveFunctionResult == null) {
initialCostString = "";
} else {
raResult = String.format("%s network action(s) and %s range action(s) activated", activatedNetworkActions, activatedRangeActions);
Map<String, Double> initialVirtualCostDetailed = getVirtualCostDetailed(preOptimObjectiveFunctionResult);
if (initialVirtualCostDetailed.isEmpty()) {
initialCostString = String.format("initial cost = %s (functional: %s, virtual: %s), ", formatDouble(preOptimObjectiveFunctionResult.getFunctionalCost() + preOptimObjectiveFunctionResult.getVirtualCost()), formatDouble(preOptimObjectiveFunctionResult.getFunctionalCost()), formatDouble(preOptimObjectiveFunctionResult.getVirtualCost()));
} else {
initialCostString = String.format("initial cost = %s (functional: %s, virtual: %s %s), ", formatDouble(preOptimObjectiveFunctionResult.getFunctionalCost() + preOptimObjectiveFunctionResult.getVirtualCost()), formatDouble(preOptimObjectiveFunctionResult.getFunctionalCost()), formatDouble(preOptimObjectiveFunctionResult.getVirtualCost()), initialVirtualCostDetailed);
}
}
String initialCostString = initialFunctionalCost == null || initialVirtualCost == null ? "" :
String.format("initial cost = %s (functional: %s, virtual: %s), ", formatDouble(initialFunctionalCost + initialVirtualCost), formatDouble(initialFunctionalCost), formatDouble(initialVirtualCost));

logger.info("Scenario \"{}\": {}{}, cost {} = {} (functional: {}, virtual: {})", scenarioName, initialCostString, raResult, OptimizationState.afterOptimizing(optimizedState),
formatDouble(finalObjective.getCost()), formatDouble(finalObjective.getFunctionalCost()), formatDouble(finalObjective.getVirtualCost()));
logger.info("Scenario \"{}\": {}{}, cost {} = {} (functional: {}, virtual: {}{})", scenarioName, initialCostString, raResult, OptimizationState.afterOptimizing(optimizedState),
formatDouble(finalObjective.getCost()), formatDouble(finalObjective.getFunctionalCost()), formatDouble(finalObjective.getVirtualCost()), finalVirtualCostDetailed.isEmpty() ? "" : " " + finalVirtualCostDetailed);
}

public static void logFailedOptimizationSummary(FaraoLogger logger, State optimizedState, long activatedNetworkActions, long activatedRangeActions) {
Optional<Contingency> optionalContingency = optimizedState.getContingency();
String scenarioName = optionalContingency.isEmpty() ? "preventive" : optionalContingency.get().getName();
String raResult = "";
public static String getRaResult(Set<NetworkAction> networkActions, Map<RangeAction<?>, java.lang.Double> rangeActions) {
long activatedNetworkActions = networkActions.size();
long activatedRangeActions = rangeActions.size();
String networkActionsNames = StringUtils.join(networkActions.stream().map(Identifiable::getName).collect(Collectors.toSet()), ", ");

Set<String> rangeActionsSet = new HashSet<>();
rangeActions.forEach((key, value) -> rangeActionsSet.add(format("%s: %.0f", key.getName(), value)));
String rangeActionsNames = StringUtils.join(rangeActionsSet, ", ");

if (activatedNetworkActions + activatedRangeActions == 0) {
raResult = "no remedial actions activated";
return "no remedial actions activated";
} else if (activatedNetworkActions > 0 && activatedRangeActions == 0) {
raResult = String.format("%s network action(s) activated", activatedNetworkActions);
return String.format("%s network action(s) activated : %s", activatedNetworkActions, networkActionsNames);
} else if (activatedRangeActions > 0 && activatedNetworkActions == 0) {
raResult = String.format("%s range action(s) activated", activatedRangeActions);
return String.format("%s range action(s) activated : %s", activatedRangeActions, rangeActionsNames);
} else {
raResult = String.format("%s network action(s) and %s range action(s) activated", activatedNetworkActions, activatedRangeActions);
return String.format("%s network action(s) and %s range action(s) activated : %s and %s",
activatedNetworkActions, activatedRangeActions, networkActionsNames, rangeActionsNames);
}
logger.info("Scenario \"{}\": {}", scenarioName, raResult);
}

public static String getScenarioName(State state) {
Optional<Contingency> optionalContingency = state.getContingency();
return optionalContingency.isEmpty() ? "preventive" : optionalContingency.get().getName();
}

public static String formatDouble(double value) {
Expand All @@ -294,4 +306,15 @@ public static String formatDouble(double value) {
return String.format(Locale.ENGLISH, "%.2f", value);
}
}

/**
* For a given virtual-cost-name, if its associated virtual cost is positive, this method will return a map containing
* these information to be used in the Rao logs
*/
public static Map<String, Double> getVirtualCostDetailed(ObjectiveFunctionResult objectiveFunctionResult) {
return objectiveFunctionResult.getVirtualCostNames().stream()
.filter(virtualCostName -> objectiveFunctionResult.getVirtualCost(virtualCostName) > 1e-6)
.collect(Collectors.toMap(Function.identity(),
name -> Math.round(objectiveFunctionResult.getVirtualCost(name) * 100.0) / 100.0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ public Pair<Double, List<FlowCnec>> getVirtualCostAndCostlyElements(FlowResult
return getVirtualCostAndCostlyElements(flowResult, rangeActionActivationResult, sensitivityResult, sensitivityStatus, virtualCostName, new HashSet<>());
}

public Pair<Double, List<FlowCnec>> getVirtualCostAndCostlyElements(FlowResult flowResult, RangeActionActivationResult rangeActionActivationResult, SensitivityResult sensitivityResult, ComputationStatus sensitivityStatus, String virtualCostName, Set<String> contingenciesToExlude) {
public Pair<Double, List<FlowCnec>> getVirtualCostAndCostlyElements(FlowResult flowResult, RangeActionActivationResult rangeActionActivationResult, SensitivityResult sensitivityResult, ComputationStatus sensitivityStatus, String virtualCostName, Set<String> contingenciesToExclude) {
return virtualCostEvaluators.stream()
.filter(costEvaluator -> costEvaluator.getName().equals(virtualCostName))
.findAny()
.map(costEvaluator -> costEvaluator.computeCostAndLimitingElements(flowResult, rangeActionActivationResult, sensitivityResult, sensitivityStatus, contingenciesToExlude))
.map(costEvaluator -> costEvaluator.computeCostAndLimitingElements(flowResult, rangeActionActivationResult, sensitivityResult, sensitivityStatus, contingenciesToExclude))
.orElse(Pair.of(Double.NaN, new ArrayList<>()));
}

Expand Down
Loading