/*************************************************************************
* *
* This file is part of the 20n/act project. *
* 20n/act enables DNA prediction for synthetic biology/bioengineering. *
* Copyright (C) 2017 20n Labs, Inc. *
* *
* Please direct all queries to act@20n.com. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
*************************************************************************/
package com.act.biointerpretation.l2expansion;
import com.act.biointerpretation.mechanisminspection.ReactionRenderer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
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 java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Used to render an already-genderated prediction corpus for manual curation.
*/
public class L2RenderingDriver {
private static final Logger LOGGER = LogManager.getFormatterLogger(L2RenderingDriver.class);
private static final String OPTION_CORPUS_PATH = "c";
private static final String OPTION_OUTPUT_DIRECTORY = "r";
private static final String OPTION_IMAGE_FORMAT = "f";
private static final String OPTION_IMAGE_WIDTH = "w";
private static final String OPTION_IMAGE_HEIGHT = "h";
private static final String OPTION_HELP = "h";
private static final String DEFAULT_IMAGE_FORMAT = "png";
private static final String DEFAULT_IMAGE_WIDTH = "1000";
private static final String DEFAULT_IMAGE_HEIGHT = "1000";
public static final String HELP_MESSAGE =
"This class is used to render an already-generated prediction corpus. The corpus is read in from " +
"file, and basic statistics about it are generated. Without -r, nothing more is done. With " +
"-r, the corpus is also rendered into a specified directory. This entails printing one image of " +
"each prediction, and one image of each ro that occurs in any prediction. The corpus itself is " +
"also printed to the same directory, as well as a file containing the product inchis from the corpus, " +
"which contains one inchi per line, and can be used as input to the BingSearchRanker.";
public static final List<Option.Builder> OPTION_BUILDERS = new ArrayList<Option.Builder>() {{
add(Option.builder(OPTION_CORPUS_PATH)
.argName("corpus file path")
.desc("The path to the prediction corpus file.")
.hasArg()
.longOpt("corpus-path")
.required()
);
add(Option.builder(OPTION_OUTPUT_DIRECTORY)
.argName("output directory")
.desc("The path to the directory in which to render the corpus.")
.hasArg()
.longOpt("output-directory")
.required()
);
add(Option.builder(OPTION_IMAGE_FORMAT)
.argName("image format")
.desc("The format in which to print the images, i.e 'png'")
.hasArg()
.longOpt("image-format")
);
add(Option.builder(OPTION_IMAGE_WIDTH)
.argName("image width")
.desc("The width of the images to print")
.hasArg()
.longOpt("image-width")
);
add(Option.builder(OPTION_IMAGE_HEIGHT)
.argName("image height")
.desc("The height of the images to print")
.hasArg()
.longOpt("image-height")
);
add(Option.builder(OPTION_HELP)
.argName("help")
.desc("Prints this help message.")
.longOpt("help")
);
}};
public static final HelpFormatter HELP_FORMATTER = new HelpFormatter();
static {
HELP_FORMATTER.setWidth(100);
}
public static void main(String[] args) throws Exception {
// Build command line parser.
Options opts = new Options();
for (Option.Builder b : OPTION_BUILDERS) {
opts.addOption(b.build());
}
CommandLine cl = null;
try {
CommandLineParser parser = new DefaultParser();
cl = parser.parse(opts, args);
} catch (ParseException e) {
LOGGER.error("Argument parsing failed: %s", e.getMessage());
HELP_FORMATTER.printHelp(L2RenderingDriver.class.getCanonicalName(), HELP_MESSAGE, opts, null, true);
System.exit(1);
}
// Print help.
if (cl.hasOption(OPTION_HELP)) {
HELP_FORMATTER.printHelp(L2RenderingDriver.class.getCanonicalName(), HELP_MESSAGE, opts, null, true);
return;
}
// Set up input corpus file.
File corpusFile = new File(cl.getOptionValue(OPTION_CORPUS_PATH));
if (!corpusFile.exists()) {
LOGGER.error("Input corpus file does not exist");
return;
}
//Set up output directory.
File outputDirectory = new File(cl.getOptionValue(OPTION_OUTPUT_DIRECTORY));
if (outputDirectory.exists() && !outputDirectory.isDirectory()) {
LOGGER.error("Can't render corpus: supplied image directory is an existing non-directory file.");
return;
}
outputDirectory.mkdir();
LOGGER.info("Reading in corpus from file.");
L2PredictionCorpus predictionCorpus = L2PredictionCorpus.readPredictionsFromJsonFile(corpusFile);
LOGGER.info("Finished reading in corpus with %d predictions", predictionCorpus.getCorpus().size());
// Set image format options
String format = cl.getOptionValue(OPTION_IMAGE_FORMAT, DEFAULT_IMAGE_FORMAT);
Integer width = Integer.parseInt(cl.getOptionValue(OPTION_IMAGE_WIDTH, DEFAULT_IMAGE_WIDTH));
Integer height = Integer.parseInt(cl.getOptionValue(OPTION_IMAGE_HEIGHT, DEFAULT_IMAGE_HEIGHT));
// Render the corpus.
LOGGER.info("Drawing images for each prediction in corpus.");
ReactionRenderer reactionRenderer = new ReactionRenderer(format, width, height);
PredictionCorpusRenderer renderer = new PredictionCorpusRenderer(reactionRenderer);
renderer.renderCorpus(predictionCorpus, outputDirectory);
LOGGER.info("L2RenderingDriver complete!");
}
}