This tutorial will guide you through adding a new example command to PhyloNet that can be executed from within the PhyloNet PHYLONET
block of a NEXUS file.
Step 1. Prepare Existing Source
...
Code Block |
---|
package com.example; import edu.rice.cs.bioinfo.programs.phylonet.commands.*; import edu.rice.cs.bioinfo.library.language.pyson._1_0.ir.blockcontents.*; import edu.rice.cs.bioinfo.library.language.richnewick._1_0.ast.*; import edu.rice.cs.bioinfo.library.programming.*; import java.io.*; import java.util.*; public class CountNodes extends CommandBase { public CountNodes(SyntaxCommand motivatingCommand, ArrayList<Parameter> params, Map<String,NetworkNonEmpty> sourceIdentToNetwork, Proc3<String, Integer, Integer> errorDetected) { super(motivatingCommand, params, sourceIdentToNetwork, errorDetected); } ... } |
Your first step should be to provide the illustrated public four argument constructor with corresponding call to super
. When your command is encountered in a PhyloNet
block, it is this constructor that will be called to create your command.
...
Code Block |
---|
protected boolean checkParamsForCommand() { int expectedNetworkNameParameterIndex = 0; // network ident should be first parameter in command. // automatically checks for network existance and reports any errors to this.errorDetected. NetworkNonEmpty network = this.assertAndGetNetwork(expectedNetworkNameParameterIndex); if(network == null) // user specified network name is invalid { return false; } _networkToScan = network; // added field to class to retain network to scan. return true; } |
Note that we have added a field to our class _networkToScan
to point to the user specified network to scan. This will be useful in our next step.
...
Code Block |
---|
protected void executeCommandHelp(Proc<String> displayResult) throws IOException { String eNewickNetwork = NetworkTransformer.toENewick(_networkToScan); // convert NEXUS network to extended newick string /* * convert extended network string to Network */ edu.rice.cs.bioinfo.programs.phylonet.structs.network.io.ExNewickReader<String> enr = new edu.rice.cs.bioinfo.programs.phylonet.structs.network.io.ExNewickReader<String>( newStringReader(eNewickNetwork)); edu.rice.cs.bioinfo.programs.phylonet.structs.network.Network<String> net; try { net = enr.readNetwork(); } catch(Exception e) { throw new RuntimeException(e); } /* * count and display number of nodes in network */ Iterable<edu.rice.cs.bioinfo.programs.phylonet.structs.network.NetNode<String>> allNodes = net.dfs(); int nodeCount = 0; for(Object node : net.dfs()) { nodeCount++; } displayResult.execute("\nNetwork contains " + nodeCount + " nodes."); } |
...
The next step is to update edu.rice.cs.bioinfo.programs.phylonet.commands.CommandFactory
to construct instances of the CountNodes
command. When examining the existing structure of the CommandFactory
you will discover an if
/else if
chain within the make
method:
Code Block |
---|
public class CommandFactory { public static Command make(SyntaxCommand directive, Map<String,NetworkNonEmpty> sourceIdentToNetwork, Proc3<String, Integer, Integer> errorDetected, Random rand) { ... if(lowerCommandName.equals("symmetricdifference") || lowerCommandName.equals("rf")) { return new SymmetricDifference(directive, params, sourceIdentToNetwork, errorDetected); } else if(lowerCommandName.equals("lca")) { return new LCA(directive, params, sourceIdentToNetwork, errorDetected); } ... } |
...
Code Block |
---|
public class CommandFactory {
public static Command make(SyntaxCommand directive, Map<String,NetworkNonEmpty> sourceIdentToNetwork,
Proc3<String, Integer, Integer> errorDetected, Random rand)
{
...
else if(lowerCommandName.equals("nexus_out"))
{
return new NexusOut(directive, params, sourceIdentToNetwork, errorDetected);
}
else if(lowerCommandName.equals("countnodes"))
{
return new CountNodes(directive, params, sourceIdentToNetwork, errorDetected);
}
...
|
...
At this point inclusion of a new command is complete. After recompiling PhyloNet the new command should be available. For example, the following NEXUS file will now be processed by PhyloNet:
Code Block | ||
---|---|---|
| ||
#NEXUS
BEGIN NETWORKS;
Network net = ((a,(b,(c)x#1)M)N,((x#1,d)J,e)Z)R;
END;
BEGIN PHYLONET;
CountNodes net;
END;
|