eu.itesla_project.security.RunSecurityAnalysisTool.java Source code

Java tutorial

Introduction

Here is the source code for eu.itesla_project.security.RunSecurityAnalysisTool.java

Source

/**
 * Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
 * 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 eu.itesla_project.security;

import com.google.auto.service.AutoService;
import eu.itesla_project.commons.io.ComponentDefaultConfig;
import eu.itesla_project.commons.tools.Command;
import eu.itesla_project.commons.tools.Tool;
import eu.itesla_project.computation.ComputationManager;
import eu.itesla_project.computation.local.LocalComputationManager;
import eu.itesla_project.contingency.ContingenciesProvider;
import eu.itesla_project.contingency.ContingenciesProviderFactory;
import eu.itesla_project.iidm.datasource.GenericReadOnlyDataSource;
import eu.itesla_project.iidm.import_.Importer;
import eu.itesla_project.iidm.import_.Importers;
import eu.itesla_project.iidm.network.Network;
import eu.itesla_project.loadflow.api.LoadFlowFactory;
import eu.itesla_project.contingency.Contingency;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
 * @author Mathieu Bague <mathieu.bague at rte-france.com>
 */
@AutoService(Tool.class)
public class RunSecurityAnalysisTool implements Tool {

    private static final Logger LOGGER = LoggerFactory.getLogger(RunSecurityAnalysisTool.class);

    private static final char CSV_SEPARATOR = ';';

    @Override
    public Command getCommand() {
        return new Command() {

            @Override
            public String getName() {
                return "run-security-analysis";
            }

            @Override
            public String getTheme() {
                return "Computation";
            }

            @Override
            public String getDescription() {
                return "run security analysis using load flow";
            }

            @Override
            @SuppressWarnings("static-access")
            public Options getOptions() {
                Options options = new Options();
                options.addOption(Option.builder().longOpt("case-format").desc("the case format").hasArg()
                        .argName("FORMAT").required().build());
                options.addOption(Option.builder().longOpt("case-dir").desc("the directory where the case is")
                        .hasArg().argName("DIR").required().build());
                options.addOption(Option.builder().longOpt("case-basename").desc("the case base name").hasArg()
                        .argName("NAME").build());
                options.addOption(Option.builder().longOpt("output-csv-file").desc("output CSV file path").hasArg()
                        .argName("FILE").required().build());
                options.addOption(
                        Option.builder().longOpt("detailed").desc("detailed results of constraints").build());
                return options;
            }

            @Override
            public String getUsageFooter() {
                return "Where FORMAT is one of " + Importers.getFormats();
            }

        };
    }

    private static String toString(List<LimitViolation> violations, boolean detailed) {
        if (detailed) {
            StringBuilder builder = new StringBuilder();
            if (violations != null) {
                for (LimitViolation violation : violations) {
                    builder.append(violation.getSubject().getId()).append(" (")
                            .append(violation.getValue() / violation.getLimit() * 100).append(") ");
                }
            }
            return builder.toString();
        } else {
            return violations != null ? (violations.isEmpty() ? "OK" : "NOK") : "NOK";
        }
    }

    @Override
    public void run(CommandLine line) throws Exception {
        ComponentDefaultConfig config = new ComponentDefaultConfig();
        String caseFormat = line.getOptionValue("case-format");
        Path caseDir = Paths.get(line.getOptionValue("case-dir"));
        String caseBaseName = line.getOptionValue("case-basename");
        Path outputCsvFile = Paths.get(line.getOptionValue("output-csv-file"));
        boolean detailed = line.hasOption("detailed");

        ContingenciesProvider contingencyProvider = config.findFactoryImplClass(ContingenciesProviderFactory.class)
                .newInstance().create();
        LoadFlowFactory loadFlowFactory = config.findFactoryImplClass(LoadFlowFactory.class).newInstance();

        try (ComputationManager computationManager = new LocalComputationManager()) {

            Importer importer = Importers.getImporter(caseFormat, computationManager);
            if (importer == null) {
                throw new RuntimeException("Format " + caseFormat + " not supported");
            }

            Map<String, Map<String, List<LimitViolation>>> statusPerContingencyPerCase = Collections
                    .synchronizedMap(new TreeMap<>());

            Set<String> contingencyIds = Collections.synchronizedSet(new LinkedHashSet<>());

            if (caseBaseName != null) {
                System.out.println("loading case " + caseBaseName + " ...");

                // load the network
                Network network = importer.import_(new GenericReadOnlyDataSource(caseDir, caseBaseName),
                        new Properties());

                List<Contingency> contingencies = contingencyProvider.getContingencies(network);
                contingencyIds.addAll(contingencies.stream().map(Contingency::getId).collect(Collectors.toList()));

                StaticSecurityAnalysis securityAnalysis = new StaticSecurityAnalysis(network, loadFlowFactory,
                        computationManager);

                statusPerContingencyPerCase.put(caseBaseName, securityAnalysis.run(contingencies));
            } else {
                Importers.importAll(caseDir, importer, true, network -> {
                    try {
                        List<Contingency> contingencies = contingencyProvider.getContingencies(network);
                        contingencyIds.addAll(
                                contingencies.stream().map(Contingency::getId).collect(Collectors.toList()));

                        StaticSecurityAnalysis securityAnalysis = new StaticSecurityAnalysis(network,
                                loadFlowFactory, computationManager);

                        statusPerContingencyPerCase.put(network.getId(), securityAnalysis.run(contingencies));
                    } catch (Exception e) {
                        LOGGER.error(e.toString(), e);
                    }
                }, dataSource -> System.out.println("loading case " + dataSource.getBaseName() + " ..."));
            }

            try (BufferedWriter writer = Files.newBufferedWriter(outputCsvFile, StandardCharsets.UTF_8)) {
                writer.write("base case");
                for (String contingencyId : contingencyIds) {
                    writer.write(CSV_SEPARATOR);
                    writer.write(contingencyId);
                }
                writer.newLine();

                for (Map.Entry<String, Map<String, List<LimitViolation>>> e : statusPerContingencyPerCase
                        .entrySet()) {
                    String baseCaseName = e.getKey();
                    Map<String, List<LimitViolation>> statusPerContingency = e.getValue();
                    writer.write(baseCaseName);
                    for (String contingencyId : contingencyIds) {
                        List<LimitViolation> violations = statusPerContingency.get(contingencyId);
                        writer.write(CSV_SEPARATOR);
                        writer.write(toString(violations, detailed));
                    }
                    writer.newLine();
                }
            }
        }
    }

}