private static final Logger LOGGER =
Logger.getLogger(FanmodTool.class.getName());
public static void main(String[] args) {
ArgOptions opts = new ArgOptions();
opts.addOption('h', "help", "Generates a help message and exits",
false, null, "Program Options");
opts.addOption('v', "verbose", "Turns on verbose output",
false, null, "Program Options");
opts.addOption('V', "verbVerbose", "Turns on very verbose output",
false, null, "Program Options");
opts.addOption('r', "randomGraphs", "The number of random graphs" +
" to use for the null model (default: 1000)",
true, "INT", "Algorithm Options");
opts.addOption('z', "motifSize", "The number of vertices in the" +
" identified motifs (default: 3)",
true, "INT", "Algorithm Options");
opts.addOption('s', "useSimpleMotifs", "If searching for motifs in a " +
"multigraph, counts only simple graphs as motifs",
false, null, "Algorithm Options");
opts.addOption('Z', "minZScore", "The minimum Z-Score for any motif" +
" in the original network to be used for computing " +
"modularity (default: 1)",
true, "DOUBLE", "Algorithm Options");
opts.addOption('O', "minOccurrences", "The minimum number of occurrences"
+ " for any motif" +
" in the original network to be used for computing " +
"modularity (default: 1)",
true, "INT", "Algorithm Options");
// opts.addOption('w', "weighted", "Uses a weighted edge simiarity",
// false, null, "Input Options");
opts.addOption('d', "loadAsDirectedGraph", "Loads the input graph as " +
"a directed graph",
false, null, "Input Options");
opts.addOption('m', "loadAsMultigraph", "Loads the input graph as " +
"a multigraph",
false, null, "Input Options");
opts.addOption('o', "outputFormat", "The type of format to use " +
"when writing the graphs (default: serialized)",
true, "FORMAT", "Output Options");
opts.addOption('H', "makeHtml", "Generates an HTML rendering" +
"of the significant motifs",
true, "DIR", "Output Options");
opts.parseOptions(args);
if (opts.numPositionalArgs() < 2 || opts.hasOption("help")) {
usage(opts);
return;
}
// If verbose output is enabled, update all the loggers in the S-Space
// package logging tree to output at Level.FINE (normally, it is
// Level.INFO). This provides a more detailed view of how the execution
// flow is proceeding.
if (opts.hasOption('v'))
LoggerUtil.setLevel(Level.FINE);
if (opts.hasOption('V'))
LoggerUtil.setLevel(Level.FINER);
LOGGER.info("Loading graph file");
Indexer<String> vertexLabels = new ObjectIndexer<String>();
File f = new File(opts.getPositionalArg(0));
int motifSize = (opts.hasOption('z')) ? opts.getIntOption('z') : 3;
int numRandomGraphs = (opts.hasOption('r'))
? opts.getIntOption('r') : 1000;
double minZScore = opts.hasOption('Z')
? opts.getDoubleOption('Z')
: 1d;
int minOccurrences = opts.hasOption('O')
? opts.getIntOption('O')
: 1;
Fanmod.MotifFilter filter =
new Fanmod.FrequencyAndZScoreFilter(minOccurrences, minZScore);
info(LOGGER, "retaining motifs occurring at least %d times with a " +
"z-score at or above %f", minOccurrences, minZScore);
boolean isMultigraph = opts.hasOption('m');
boolean isDirected = opts.hasOption('d');
Fanmod fanmod = new Fanmod();
try {
if (isMultigraph && isDirected) {
DirectedMultigraph<String> dm =
GraphIO.readDirectedMultigraph(f, vertexLabels);
boolean findSimpleMotifs = opts.hasOption('s');
Map<Multigraph<String,DirectedTypedEdge<String>>,Fanmod.Result>
motifToZScore = fanmod.findMotifs(
dm, findSimpleMotifs, motifSize, numRandomGraphs, filter);
info(LOGGER, "found %d motifs with z-score above %f%n",
motifToZScore.size(), minZScore);
if (opts.hasOption('H')) {
File baseDir = new File(opts.getStringOption('H'));
// Check that we can create output in that directory
if (!baseDir.exists())
baseDir.mkdir();
DotIO dio = new DotIO();
// Generate a consistent set of edge colors to user across
// all the motif visualizations
Map<String,Color> edgeColors = new HashMap<String,Color>();
ColorGenerator cg = new ColorGenerator();
for (String type : dm.edgeTypes())
edgeColors.put(type, cg.next());
PrintWriter pw = new PrintWriter(new File(baseDir, "index.html"));
PrintWriter imgScript = new PrintWriter(new File(baseDir, "img-script.sh"));
imgScript.println("#!/bin/bash");
pw.println("<html>");
pw.println("<head><script src=\"http://www.kryogenix.org/code/browser/sorttable/sorttable.js\"></script></head>");
// pw.println("<head><script src=\"sorttable.js\"></script></head>");
pw.println("<body><table border=\"2\" class=\"sortable\">");
pw.println(" <tr>" +
"<td><h1><u>Motif</u></h1></td>" +
"<td><h1><u>Count</u></h1></td>" +
"<td><h1><u>Z-Score</u></h1></td>" +
"<td><h1><u>Mean Count in Random Graphs</u></h1></td>" +
"<td><h1><u>StdDev in Random Graphs</u></h1></td>" +
"</tr>");
int graphNum = 0;
for (Map.Entry<Multigraph<String,DirectedTypedEdge<String>>,Fanmod.Result> e :
motifToZScore.entrySet()) {
File dotFile = new File(baseDir, "graph-" + (graphNum++) + ".dot");
dio.writeDirectedMultigraph(e.getKey(), dotFile, edgeColors);
String imgFile = dotFile.getName();
imgFile = imgFile.substring(0, imgFile.length() - 3) + "gif";
imgScript.printf("dot -Tgif %s -o %s%n", dotFile.getName(), imgFile);
int count = e.getValue().count;
double zScore = e.getValue().statistic;
double mean = e.getValue().meanCountInNullModel;
double stddev = e.getValue().stddevInNullModel;
pw.printf(" <tr><td><img src=\"%s\"></td><td>%d</td><td>%f</td><td>%f</td><td>%f</td></tr>%n",
imgFile, count, zScore, mean, stddev);
}
pw.println("</table></body></html>");
imgScript.close();
pw.close();
}
info(LOGGER, "writing final motifs to %s",
opts.getPositionalArg(1));
// Write the results to file
File output = new File(opts.getPositionalArg(1));
// Copy the motifs to a new HashSet to avoid writing the result
// as a KeySet, which includes the fanmod result values.
SerializableUtil.save(
new HashSet<Multigraph<String,
DirectedTypedEdge<String>>>(motifToZScore.keySet()), output);
}
else if (isMultigraph) {
boolean findSimpleMotifs = opts.hasOption('s');
UndirectedMultigraph<String> um =
GraphIO.readUndirectedMultigraph(f, vertexLabels);
Map<Multigraph<String,TypedEdge<String>>,Fanmod.Result>
motifToZScore = fanmod.findMotifs(
um, findSimpleMotifs, motifSize, numRandomGraphs, filter);
info(LOGGER, "found %d motifs with z-score above %f%n",
motifToZScore.size(), minZScore);
if (opts.hasOption('H')) {
File baseDir = new File(opts.getStringOption('H'));
// Check that we can create output in that directory
if (!baseDir.exists())
baseDir.mkdir();
DotIO dio = new DotIO();
// Generate a consistent set of edge colors to user across
// all the motif visualizations
Map<String,Color> edgeColors = new HashMap<String,Color>();
ColorGenerator cg = new ColorGenerator();
for (String type : um.edgeTypes())
edgeColors.put(type, cg.next());
PrintWriter pw = new PrintWriter(new File(baseDir, "index.html"));
PrintWriter imgScript = new PrintWriter(new File(baseDir, "img-script.sh"));
imgScript.println("#!/bin/bash");
pw.println("<html>");
pw.println("<head><script src=\"http://www.kryogenix.org/code/browser/sorttable/sorttable.js\"></script></head>");
// pw.println("<head><script src=\"sorttable.js\"></script></head>");
pw.println("<body><table border=\"2\" class=\"sortable\">");
pw.println(" <tr>" +
"<td><h1><u>Motif</u></h1></td>" +
"<td><h1><u>Count</u></h1></td>" +
"<td><h1><u>Z-Score</u></h1></td>" +
"<td><h1><u>Mean Count in Random Graphs</u></h1></td>" +
"<td><h1><u>StdDev in Random Graphs</u></h1></td>" +
"</tr>");
int graphNum = 0;
for (Map.Entry<Multigraph<String,TypedEdge<String>>,Fanmod.Result> e :
motifToZScore.entrySet()) {
File dotFile = new File(baseDir, "graph-" + (graphNum++) + ".dot");
dio.writeUndirectedMultigraph(e.getKey(), dotFile, edgeColors);
String imgFile = dotFile.getName();
imgFile = imgFile.substring(0, imgFile.length() - 3) + "gif";
imgScript.printf("dot -Tgif %s -o %s%n", dotFile.getName(), imgFile);
int count = e.getValue().count;
double zScore = e.getValue().statistic;
double mean = e.getValue().meanCountInNullModel;
double stddev = e.getValue().stddevInNullModel;
pw.printf(" <tr><td><img src=\"%s\"></td><td>%d</td><td>%f</td><td>%f</td><td>%f</td></tr>%n",
imgFile, count, zScore, mean, stddev);
}
pw.println("</table></body></html>");
imgScript.close();
pw.close();
info(LOGGER, "writing final motifs to %s",
opts.getPositionalArg(1));
// Write the results to file
File output = new File(opts.getPositionalArg(1));
// Copy the motifs to a new HashSet to avoid writing the result
// as a KeySet, which includes the fanmod result values.
SerializableUtil.save(
new HashSet<Multigraph<String,TypedEdge<String>>>(
motifToZScore.keySet()), output);