org.structnetalign.CLI.java Source code

Java tutorial

Introduction

Here is the source code for org.structnetalign.CLI.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 * @author dmyersturnbull
 */
package org.structnetalign;

import java.io.File;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.biojava.bio.structure.align.ce.AbstractUserArgumentProcessor;
import org.structnetalign.weight.AtomCacheFactory;

/**
 * A command-line interface for Struct-NA's main component.
 * @author dmyersturnbull
 * @see PipelineManager
 */
public class CLI {

    public static final String PROGRAM_NAME = "Struct-NA";

    private static final Logger logger = LogManager.getLogger("org.structnetalign");

    private static final String NEWLINE = "\n";

    public static void main(String[] args) {

        Options options = getOptions();
        CommandLineParser parser = new GnuParser();
        CommandLine cmd;
        try {
            cmd = parser.parse(options, args);
        } catch (ParseException e) {
            printUsage(e.getMessage(), options);
            return;
        }

        runPipeline(cmd);

    }

    private static void runPipeline(CommandLine cmd) {
        String pdbDir = cmd.getOptionValue("pdb_dir");
        File input = new File(cmd.getOptionValue("input"));
        File output = new File(cmd.getOptionValue("output"));
        int nCores = cmd.hasOption("cores") ? Integer.parseInt(cmd.getOptionValue("cores"))
                : PipelineManager.N_CORES;
        int xi = cmd.hasOption("xi") ? Integer.parseInt(cmd.getOptionValue("xi")) : PipelineManager.XI;
        double tau = cmd.hasOption("tau") ? Double.parseDouble(cmd.getOptionValue("tau")) : PipelineManager.TAU;
        double zeta = cmd.hasOption("zeta") ? Double.parseDouble(cmd.getOptionValue("zeta")) : PipelineManager.ZETA;
        boolean report = cmd.hasOption("report");
        boolean writeSteps = cmd.hasOption("write_steps");
        boolean noCross = cmd.hasOption("no_cross");
        boolean noMerge = cmd.hasOption("no_merge");
        runPipeline(pdbDir, nCores, input, output, tau, zeta, xi, noCross, noMerge, writeSteps, report);
    }

    private static void runPipeline(String pdbDir, int nCores, File input, File output, double tau, double zeta,
            int xi, boolean noCross, boolean noMerge, boolean writeSteps, boolean report) {
        if (pdbDir != null) {
            System.setProperty(AbstractUserArgumentProcessor.PDB_DIR, pdbDir);
            AtomCacheFactory.setCache(pdbDir);
        }
        PipelineManager man = new PipelineManager();
        man.setXi(xi);
        man.setNCores(nCores);
        man.setTau(tau);
        man.setZeta(zeta);
        man.setReport(report);
        man.setWriteSteps(writeSteps);
        man.setNoCross(noCross);
        man.setNoMerge(noMerge);
        man.run(input, output);
    }

    /**
     * Prints an error message for {@code e} that shows causes and suppressed messages recursively. Just a little more
     * useful than {@code e.printStackTrace()}.
     * 
     * @param e
     */
    public static void printError(Exception e) {
        System.err.println(printError(e, ""));
    }

    private static Options getOptions() {
        Options options = new Options();
        options.addOption(OptionBuilder.hasArg(true)
                .withDescription(
                        "The number of cores to use. Defaults to the number of available processors minus one.")
                .isRequired(false).create("cores"));
        options.addOption(OptionBuilder.hasArg(true).withDescription(
                "The directory containing cached PDB files. Defaults to the AtomCache default, which is probably in your system's temporary directory (e.g. /tmp). It is okay if this is an empty directory, but the directory must exist. You should set up a PDB cache path if you plan to run "
                        + PROGRAM_NAME + " multiple times.")
                .isRequired(false).create("pdb_dir"));
        options.addOption(OptionBuilder.hasArg(true).withDescription(
                "The maximum search depth for traversal during crossing. If a vertex v shares an interaction edge x with vertex s, vertex v shares an interaction edge y with vertex t, and there is no path from u to t and no path from v to s, then x will be updated by y if and only if u and v are seperated by no more than xi homology edges (inclusive), AND s and t are seperated by no more than xi homology edges. Defaults to "
                        + PipelineManager.XI + ". See paper for more details.")
                .isRequired(false).create("xi"));
        options.addOption(OptionBuilder.hasArg(true).withDescription(
                "A threshold probability prior for running the crossing process. Prior to crossing, any homology edge with probability less than tau will be removed. Defaults to "
                        + PipelineManager.TAU + ".")
                .isRequired(false).create("tau"));
        options.addOption(OptionBuilder.hasArg(true).withDescription(
                "A threshold probability prior for running the merging process. Prior to merging, any homology edge with probability less than zeta will be removed. Note that this is performed after a similar process for tau, so zeta should be no greater than tau. Defaults to "
                        + PipelineManager.ZETA + ".")
                .isRequired(false).create("zeta"));
        options.addOption(OptionBuilder.hasArg(false).withDescription(
                "If set, generates an HTML report page with accompanying graph visualizations in the specified directory.")
                .isRequired(false).create("report"));
        options.addOption(
                OptionBuilder.hasArg(false).withDescription("Do not run the vertex degeneracy removal process.")
                        .isRequired(false).create("no_merge"));
        options.addOption(OptionBuilder.hasArg(false).withDescription("Do not run the probability update process.")
                .isRequired(false).create("no_cross"));
        options.addOption(OptionBuilder.hasArg(true).withDescription("Required. The input PSI-MI25 XML file.")
                .isRequired(true).create("input"));
        options.addOption(OptionBuilder.hasArg(true).withDescription("Required. The output PSI-MI25 XML file.")
                .isRequired(true).create("output"));
        //      options.addOption(OptionBuilder.hasArg(true)
        //            .withDescription("The name of the PSI-MI25 confidence short label to use to give the initial weighting (probability) of an interaction as input to " + CLI.PROGRAM_NAME + ". Defaults to " + GraphInteractionAdaptor.INITIAL_CONFIDENCE_LABEL).isRequired(false)
        //            .create("input_conf"));
        //      options.addOption(OptionBuilder.hasArg(true)
        //            .withDescription("The default weighting (probability) of an interaction if the interaction does not have a weight described by input_conf. Defaults to " + GraphInteractionAdaptor.DEFAULT_PROBABILITY).isRequired(false)
        //            .create("default_weight"));
        //      options.addOption(OptionBuilder.hasArg(true)
        //            .withDescription("The name of the PSI-MI25 confidence short label to use to describe the certainty of an interaction as determined by " + CLI.PROGRAM_NAME + ". Defaults to " + GraphInteractionAdaptor.CONFIDENCE_SHORT_LABEL).isRequired(false)
        //            .create("output_conf_label"));
        //      options.addOption(OptionBuilder.hasArg(true)
        //            .withDescription("The name of the PSI-MI25 confidence full name to use to describe certainty of an interaction as determined by " + CLI.PROGRAM_NAME + ". Defaults to " + GraphInteractionAdaptor.CONFIDENCE_FULL_NAME).isRequired(false)
        //            .create("output_conf_name"));
        options.addOption(OptionBuilder.hasArg(false).withDescription("Output a GraphML file for each step.")
                .isRequired(false).create("write_steps"));
        options.addOption(OptionBuilder.hasArg(true).withDescription(
                "Skip the weighting process and use the specified GraphML file to indicate homology instead.")
                .isRequired(false).create("graphml_homology"));
        return options;
    }

    /**
     * @see #printError(Exception)
     */
    private static String printError(Exception e, String tabs) {
        StringBuilder sb = new StringBuilder();
        Throwable prime = e;
        while (prime != null) {
            if (tabs.length() > 0)
                sb.append(tabs + "Cause:" + NEWLINE);
            sb.append(tabs + prime.getClass().getSimpleName() + NEWLINE);
            if (prime.getMessage() != null)
                sb.append(tabs + prime.getMessage() + NEWLINE);
            if (prime instanceof Exception) {
                StackTraceElement[] trace = ((Exception) prime).getStackTrace();
                for (StackTraceElement element : trace) {
                    sb.append(tabs + element.toString() + NEWLINE);
                }
            }
            prime = prime.getCause();
            tabs += "\t";
            sb.append(NEWLINE);
        }
        return sb.toString();
    }

    private static void printUsage(String note, Options options) {
        if (note != null)
            System.out.println(note);
        HelpFormatter hf = new HelpFormatter();
        hf.printHelp("java -jar " + CLI.class.getSimpleName() + ".jar [options]", options);
    }

}