Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -113,7 +113,7 @@ public CompletableFuture<SensitivityAnalysisResult> runAsync(Network network,
SensitivityResultModelWriter resultWriter = new SensitivityResultModelWriter(runParameters.getContingencies());

return provider.run(network, workingVariantId, factorReader, resultWriter, runParameters)
.thenApply(unused -> new SensitivityAnalysisResult(factors, resultWriter.getContingencyStatuses(), resultWriter.getValues()));
.thenApply(unused -> new SensitivityAnalysisResult(factors, resultWriter.getContingencyStatuses(), resultWriter.getPreContingencyStatuses(), resultWriter.getValues()));
}

public CompletableFuture<SensitivityAnalysisResult> runAsync(Network network,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import com.powsybl.contingency.json.ContingencyJsonModule;
import com.powsybl.iidm.network.ImportConfig;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.tools.ConversionToolUtils;
import com.powsybl.sensitivity.json.JsonSensitivityAnalysisParameters;
import com.powsybl.sensitivity.json.SensitivityJsonModule;
import com.powsybl.tools.Command;
Expand Down Expand Up @@ -59,6 +58,8 @@ public class SensitivityAnalysisTool implements Tool {
private static final String VARIABLE_SETS_FILE_OPTION = "variable-sets-file";
private static final String PARAMETERS_FILE = "parameters-file";
private static final String OUTPUT_CONTINGENCY_STATUS_FILE_OPTION = "output-contingency-file";
private static final String OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION = "output-pre-contingency-file";

private static final String SINGLE_OUTPUT = "single-output";

@Override
Expand Down Expand Up @@ -115,6 +116,11 @@ public Options getOptions() {
.hasArg()
.argName("FILE")
.build());
options.addOption(Option.builder().longOpt(OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION)
.desc("pre contingency status output path (csv only)")
.hasArg()
.argName("FILE")
.build());
options.addOption(Option.builder().longOpt(SINGLE_OUTPUT)
.desc("Output sensitivity analysis results in a single json file using output file option (values, factors and contingency status).")
.build());
Expand Down Expand Up @@ -150,33 +156,50 @@ private static String buildContingencyStatusPath(String outputFile) {
return outputFile.replace(".csv", "_contingency_status.csv");
}

private static String buildPreContingencyStatusPath(String outputFile) {
return outputFile.replace(".csv", "_pre_contingency_status.csv");
}

@Override
public void run(CommandLine line, ToolRunningContext context) throws Exception {
Path caseFile = context.getFileSystem().getPath(line.getOptionValue(CASE_FILE_OPTION));
Path outputFile = context.getFileSystem().getPath(line.getOptionValue(OUTPUT_FILE_OPTION));
boolean csv = isCsv(outputFile);
Path outputFileStatus = null;

Path outputFilePreContingencyStatus = null;
if (csv) {
if (line.hasOption(OUTPUT_CONTINGENCY_STATUS_FILE_OPTION)) {
outputFileStatus = context.getFileSystem().getPath(line.getOptionValue(OUTPUT_CONTINGENCY_STATUS_FILE_OPTION));
} else {
outputFileStatus = context.getFileSystem().getPath(buildContingencyStatusPath(line.getOptionValue(OUTPUT_FILE_OPTION)));
}
if (line.hasOption(OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION)) {
outputFilePreContingencyStatus = context.getFileSystem().getPath(line.getOptionValue(OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION));
} else {
outputFilePreContingencyStatus = context.getFileSystem().getPath(buildPreContingencyStatusPath(line.getOptionValue(OUTPUT_FILE_OPTION)));
}
boolean contingencyCsv = isCsv(outputFileStatus);
if (!contingencyCsv) {
throw new PowsyblException(OUTPUT_FILE_OPTION + " and " + OUTPUT_CONTINGENCY_STATUS_FILE_OPTION + " files must have the same format (csv).");
throw new PowsyblException(OUTPUT_FILE_OPTION + " and " + OUTPUT_CONTINGENCY_STATUS_FILE_OPTION + " and " + OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION + " files must have the same format (csv).");
}

if (line.hasOption(SINGLE_OUTPUT)) {
throw new PowsyblException("Unsupported " + SINGLE_OUTPUT + " option does not support csv file as argument of " + OUTPUT_FILE_OPTION + ". Must be json.");
}
} else {
// json format
if (line.hasOption(OUTPUT_CONTINGENCY_STATUS_FILE_OPTION)) {
throw new PowsyblException(OUTPUT_CONTINGENCY_STATUS_FILE_OPTION + " file is not supported in json");
}
if (line.hasOption(OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION)) {
throw new PowsyblException(OUTPUT_PRE_CONTINGENCY_STATUS_FILE_OPTION + " file is not supported in json");
}
}

Path factorsFile = context.getFileSystem().getPath(line.getOptionValue(FACTORS_FILE_OPTION));

context.getOutputStream().println("Loading network '" + caseFile + "'");
Properties inputParams = readProperties(line, ConversionToolUtils.OptionType.IMPORT, context);
Properties inputParams = readProperties(line, OptionType.IMPORT, context);
Network network = Network.read(caseFile, context.getShortTimeExecutionComputationManager(), ImportConfig.load(), inputParams);
if (network == null) {
throw new PowsyblException("Case '" + caseFile + "' not found");
Expand Down Expand Up @@ -210,7 +233,7 @@ public void run(CommandLine line, ToolRunningContext context) throws Exception {
Stopwatch stopwatch = Stopwatch.createStarted();
try (ComputationManager computationManager = DefaultComputationManagerConfig.load().createLongTimeExecutionComputationManager()) {
SensitivityAnalysisParametersRecord parametersRecord = new SensitivityAnalysisParametersRecord(factorsReader, params, network, contingencies,
variableSets, computationManager, outputFile, outputFileStatus, csv);
variableSets, computationManager, outputFile, outputFileStatus, outputFilePreContingencyStatus, csv);
run(line, parametersRecord);
}
context.getOutputStream().println("Analysis done in " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
Expand All @@ -224,6 +247,7 @@ private record SensitivityAnalysisParametersRecord(SensitivityFactorJsonReader f
ComputationManager computationManager,
Path outputFile,
Path outputFileStatus,
Path outputFilePreContingencyStatus,
boolean csv) {
}

Expand All @@ -243,10 +267,15 @@ private void run(CommandLine line, SensitivityAnalysisParametersRecord parameter
} else {
if (parametersRecord.csv) {
try (Writer writer = Files.newBufferedWriter(parametersRecord.outputFile, StandardCharsets.UTF_8);
Writer writerStatuses = Files.newBufferedWriter(parametersRecord.outputFileStatus, StandardCharsets.UTF_8);
Writer writerComponentsStatuses = Files.newBufferedWriter(parametersRecord.outputFileStatus, StandardCharsets.UTF_8);
Writer writerPreContingencyStatuses = Files.newBufferedWriter(parametersRecord.outputFilePreContingencyStatus, StandardCharsets.UTF_8);
TableFormatter formatter = SensitivityResultCsvWriter.createTableFormatter(writer);
TableFormatter formatterStatus = SensitivityResultCsvWriter.createContingencyStatusTableFormatter(writerStatuses)) {
SensitivityResultWriter valuesWriter = new SensitivityResultCsvWriter(formatter, formatterStatus, parametersRecord.contingencies);
TableFormatter formatterComponentsStatus = SensitivityResultCsvWriter.createContingencyStatusComponentsTableFormatter(writerComponentsStatuses);
TableFormatter formatterPreContingency = SensitivityResultCsvWriter.createPreContingencyStatusTableFormatter(writerPreContingencyStatuses)
) {

SensitivityResultWriter valuesWriter = new SensitivityResultCsvWriter(formatter, formatterComponentsStatus,
formatterPreContingency, parametersRecord.contingencies);
SensitivityAnalysis.run(parametersRecord.network, parametersRecord.network.getVariantManager().getWorkingVariantId(),
parametersRecord.factorsReader, valuesWriter, parametersRecord.contingencies, parametersRecord.variableSets, parametersRecord.params,
parametersRecord.computationManager, ReportNode.NO_OP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ public class SensitivityResultCsvWriter implements SensitivityResultWriter {

private final TableFormatter formatter;

private final TableFormatter formatterContingencyStatus;
private final TableFormatter formatterContingencyComponentsStatuses;

private final TableFormatter formatterPreContingency;

private final List<Contingency> contingencies;

public SensitivityResultCsvWriter(TableFormatter formatter, TableFormatter formatterContingencyStatus,
List<Contingency> contingencies) {
public SensitivityResultCsvWriter(TableFormatter formatter, TableFormatter formatterContingencyComponentsStatuses,
TableFormatter formatterPreContingency, List<Contingency> contingencies) {
this.formatter = Objects.requireNonNull(formatter);
this.formatterContingencyStatus = Objects.requireNonNull(formatterContingencyStatus);
this.formatterContingencyComponentsStatuses = Objects.requireNonNull(formatterContingencyComponentsStatuses);
this.formatterPreContingency = Objects.requireNonNull(formatterPreContingency);
this.contingencies = Objects.requireNonNull(contingencies);
}

Expand All @@ -45,13 +48,29 @@ public static TableFormatter createTableFormatter(Writer writer) {
new Column("Sensitivity value"));
}

public static TableFormatter createContingencyStatusTableFormatter(Writer writer) {
public static TableFormatter createContingencyStatusComponentsTableFormatter(Writer writer) {
Objects.requireNonNull(writer);
TableFormatterFactory factory = new CsvTableFormatterFactory();
var tfc = TableFormatterConfig.load();
return factory.create(writer, "Sensitivity analysis contingency status result", tfc,
new Column("Contingency ID"),
new Column("Contingency Status"));
new Column("Contingency Status"),
new Column("Loadflow Status"),
new Column("Loadflow Status Description"),
new Column("Connected component"),
new Column("Synchronous component"));
}

public static TableFormatter createPreContingencyStatusTableFormatter(Writer writer) {
Objects.requireNonNull(writer);
TableFormatterFactory factory = new CsvTableFormatterFactory();
var tfc = TableFormatterConfig.load();
return factory.create(writer, "Sensitivity analysis pre contingency status result", tfc,
new Column("Connected component"),
new Column("Synchronous component"),
new Column("Loadflow Status"),
new Column("Loadflow Status Description")
);
}

@Override
Expand All @@ -68,12 +87,33 @@ public void writeSensitivityValue(int factorIndex, int contingencyIndex, double
}

@Override
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status) {
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status, SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus, int numCC, int numCS) {
try {
formatterContingencyComponentsStatuses.writeCell(contingencies.get(contingencyIndex).getId());
formatterContingencyComponentsStatuses.writeCell(status.toString());
formatterContingencyComponentsStatuses.writeCell(loadFlowStatus.status().toString());
formatterContingencyComponentsStatuses.writeCell(loadFlowStatus.statusText());
formatterContingencyComponentsStatuses.writeCell(numCC);
formatterContingencyComponentsStatuses.writeCell(numCS);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

@Override
public void writeSynchronousComponentStatus(int numCC, int numCS, SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus) {
try {
formatterContingencyStatus.writeCell(contingencies.get(contingencyIndex).getId());
formatterContingencyStatus.writeCell(status.name());
formatterPreContingency.writeCell(numCC);
formatterPreContingency.writeCell(numCS);
formatterPreContingency.writeCell(loadFlowStatus.status().toString());
formatterPreContingency.writeCell(loadFlowStatus.statusText());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

@Override
public void computationComplete() {
// WHAT TO DO HERE ??
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set to computationComplete to true like for the json writer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Alice.

The goal of the writer is to write the information on several csv files (unlike the json one that can handle all information in one single file). I'm a little bit reluctant to create a computation.csv with just a computationComplete column with a true value in one line hence my question. Maybe adding some other global statistics on the computation for the future in the computationComplete( Map<String,Double> computationStats) would have sense in a future PR ?

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.*;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand All @@ -28,10 +25,15 @@ public class SensitivityResultJsonWriter implements SensitivityResultWriter, Aut

private final List<SensitivityAnalysisResult.SensitivityContingencyStatus> contingencyStatusBuffer;

private final List<SensitivityAnalysisResult.SensitivityPreContingencyStatus> precontingencyStatusBuffer;

private boolean computationComplete = false;

public SensitivityResultJsonWriter(JsonGenerator jsonGenerator, List<Contingency> contingencies) {
this.jsonGenerator = Objects.requireNonNull(jsonGenerator);
this.contingencies = Objects.requireNonNull(contingencies);
this.contingencyStatusBuffer = new ArrayList<>(Collections.nCopies(contingencies.size(), null));
this.precontingencyStatusBuffer = new ArrayList<>();
try {
jsonGenerator.writeStartArray();
jsonGenerator.writeStartArray();
Expand All @@ -46,8 +48,21 @@ public void writeSensitivityValue(int factorIndex, int contingencyIndex, double
}

@Override
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status) {
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status, SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus, int numCC, int numCs) {
contingencyStatusBuffer.set(contingencyIndex, new SensitivityAnalysisResult.SensitivityContingencyStatus(contingencies.get(contingencyIndex).getId(), status));
contingencyStatusBuffer.get(contingencyIndex).addComponentLoadFlowStatus(loadFlowStatus, numCC, numCs);
}

@Override
public void writeSynchronousComponentStatus(int numCC, int numCS, SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus) {
SensitivityAnalysisResult.SensitivityPreContingencyStatus e = new SensitivityAnalysisResult.SensitivityPreContingencyStatus(loadFlowStatus, numCC, numCS);
precontingencyStatusBuffer.add(e);

}

@Override
public void computationComplete() {
computationComplete = true;
}

@Override
Expand All @@ -60,6 +75,17 @@ public void close() {
SensitivityAnalysisResult.SensitivityContingencyStatus.writeJson(jsonGenerator, status);
}
jsonGenerator.writeEndArray();
jsonGenerator.writeStartArray();
for (SensitivityAnalysisResult.SensitivityPreContingencyStatus status : precontingencyStatusBuffer) {
SensitivityAnalysisResult.SensitivityPreContingencyStatus.writeJson(jsonGenerator, status);
}
jsonGenerator.writeEndArray();
// Write computation completion information
jsonGenerator.writeStartArray();
jsonGenerator.writeStartObject();
jsonGenerator.writeBooleanField("completion", computationComplete);
jsonGenerator.writeEndObject();
jsonGenerator.writeEndArray();
jsonGenerator.writeEndArray();
} catch (IOException e) {
throw new UncheckedIOException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ public class SensitivityResultModelWriter implements SensitivityResultWriter {

private final List<SensitivityAnalysisResult.SensitivityContingencyStatus> contingencyStatuses;

private final List<SensitivityAnalysisResult.SensitivityPreContingencyStatus> preContingencyStatuses;

private boolean computationComplete;

public SensitivityResultModelWriter(List<Contingency> contingencies) {
this.contingencies = Objects.requireNonNull(contingencies);
contingencyStatuses = new ArrayList<>(Collections.nCopies(contingencies.size(), null));
preContingencyStatuses = new ArrayList<>();
}

public List<SensitivityValue> getValues() {
Expand All @@ -38,13 +43,36 @@ public List<SensitivityAnalysisResult.SensitivityContingencyStatus> getContingen
return contingencyStatuses;
}

public List<SensitivityAnalysisResult.SensitivityPreContingencyStatus> getPreContingencyStatuses() {
return preContingencyStatuses;
}

public boolean isComputationComplete() {
return computationComplete;
}

@Override
public void writeSensitivityValue(int factorIndex, int contingencyIndex, double value, double functionReference) {
values.add(new SensitivityValue(factorIndex, contingencyIndex, value, functionReference));
}

@Override
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status) {
contingencyStatuses.set(contingencyIndex, new SensitivityAnalysisResult.SensitivityContingencyStatus(contingencies.get(contingencyIndex).getId(), status));
public void writeContingencyStatus(int contingencyIndex, SensitivityAnalysisResult.Status status,
SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus, int numCC, int numCs) {
if (contingencyStatuses.get(contingencyIndex) == null) {
contingencyStatuses.set(contingencyIndex, new SensitivityAnalysisResult.SensitivityContingencyStatus(
contingencies.get(contingencyIndex).getId(), status));
}
contingencyStatuses.get(contingencyIndex).addComponentLoadFlowStatus(loadFlowStatus, numCC, numCs);
}

@Override
public void writeSynchronousComponentStatus(int numCC, int numCS, SensitivityAnalysisResult.LoadFlowStatus loadFlowStatus) {
preContingencyStatuses.add(new SensitivityAnalysisResult.SensitivityPreContingencyStatus(loadFlowStatus, numCS, numCS));
}

@Override
public void computationComplete() {
computationComplete = true;
}
}
Loading