PIMA Plug-In Mini API Command Line Interface PIMA COMMAND LINE INTERFACE 19 APRIL 2011 Table of Contents PIMA Command Line Client ....................................................................................................... 3 Prerequisites .............................................................................................................................. 3 Installation.................................................................................................................................. 3 PIMA Command Line Server...................................................................................................... 4 Sample Execution ...................................................................................................................... 6 Client Usage ........................................................................................................................... 6 List Available Algorithms ........................................................................................................ 6 Help for Specific Algorithm ..................................................................................................... 7 Running an Algorithm ............................................................................................................. 8 Algorithm Implementation and Integration .................................................................................. 9 PIMA Command Line Process Flow ......................................................................................10 Implementation – Java jar......................................................................................................10 Implementation – C/C++ dll ...................................................................................................13 Deployment ...........................................................................................................................14 2 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 PIMA Command Line Client The client script allows plug-ins to be invoked through the PIMA command-line interface. The command-line interface is available as long as the PIMA XML Server is running. All output from the script, the PIMA XML Interface, and the specified plug-in is displayed on the standard output where the client script is invoked. The script is located in the scripts directory of the PIMA installation. The options are described in the next section. Prerequisites The most recent version of PIMA (v2.1.4 at the writing of this document) needs to be installed and accessible from the PIMA command line client. Accessibility is through Java Remote Method Invocation (RMI) and, by default, port 1198. Installation All software and support files needed to run the PIMA command line client are contained in the ‘apexclient.zip’ file. To install, simply unzip the file. The directory structure is shown in Figure 1. Figure 1 - Client Directory Structure 3 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 Once installed, modify the apexclient.properties file to reflect the correct entries for log.dir, host, and port (see Figure 2). The log.dir is defaulted to the logs directory created under the apexclient directory when the client was unzipped. It can be changed to any ‘writable’ directory the user chooses. The host is the IP for the PIMA server and the port is defaulted to 1198 which is the default for the CAJO RMI port. Note that input and output directories are also created. These are created for convenience and can be ignored if other input/output directories are to be used. Figure 2 - Sample apexclient.properties File PIMA Command Line Server To run the command line server, open a command window on the server, change directory to %PIMA_HOME%\scripts and run server.bat. By default, the log output of the server to the command window is minimal. To change the logging to a more verbose level, change directory to %PIMA_HOME%\classes\pima and edit the log.properties file. Modify the file by changing two occurrences of ‘INFO’ to ‘DEBUG’ (see Figure 3). Once the changes have been made restart server.bat. Figure 4 has sample output from the start of server.bat with the log level set to ‘DEBUG’. 4 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 For more log output, change to ‘DEBUG’, for less change to ‘INFO’. Figure 3 - PIMA Server log.properties File Figure 4 - PIMA Server Output 5 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 Sample Execution Client Usage On the client, start a command window and change directory to the location of the apexclient installation, e.g. C:\apexclient. Assuming %PATH% contains %JAVA_HOME%\bin, one can query PIMA for basic help with the following command (Figure 5): java -cp apexclient.jar pima.xml.client.apex.ApexClient pima --help Figure 5 - PIMA Client Help Request Output List Available Algorithms Querying for all available algorithms would be accomplished via the following command: 6 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 java -cp apexclient.jar pima.xml.client.apex.ApexClient pima –-request list The output in Figure 6 implies that there are 4 algorithms available 1) Demo:Sample, 2) NRL:Crop, 3) NRL:Mdsap, and 4) shared:Overview. Figure 6 - PIMA Client Request Available Algorithms Output Help for Specific Algorithm As an example, to request help for the shared:Overview algorithm, one would execute the following command: java -cp apexclient.jar pima.xml.client.apex.ApexClient pima –-request help --algorithm shared:Overview 7 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 Figure 7 - Algorithm Usage Output Running an Algorithm To run an algorithm, e.g. shared:Overview, the following command would be used (carriage returns added for clarity): java -cp apexclient.jar pima.xml.client.apex.ApexClient pima –-request execute --algorithm shared:Overview –-wo test_201005131335 -–output_dir C:\apexcleint\output -–image_file C:\apexclient\input\RS2_4539_HH_FQ17_20080406T000952321054Z.nitf PIMA command line client uses the work order flag (--wo test_201005131335) to capture the screen output to a log file in the apexclient\logs directory named test_201005131335.log. 8 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 Figure 8 - Sample Algorithm Output Algorithm Implementation and Integration There are two parts to a PIMA accessible algorithm, a Java component consisting of a jar file and a C/C++ component made up of a dynamically linked library (dll). The Java component’s responsibility is primarily to act as a conduit for passing arguments between the PIMA interface, either graphic or command line, and the actual algorithm which is coded in the dll. This guide describes the implementation of the command line interface. For a discussion on the graphic user interface see “PIMA ELT Quick Start Integration Guide v2_1.doc”. The algorithm developer is allowed a great amount of flexibility with regard to the content of the jar and dll, however each file must contain 1. jar – an algorithm class that extends javax.swing.JPanel and implements pima.algorithm.AlgoParamInterface 2. dll – an implementation of a function called execute Details are in the Implementation – Java jar and Implementation – C/C++ dll sections. In addition, a strict naming convention must be followed. Assume that the algorithm is called ‘overview’. 1. jar – the algorithm class would be named ALGOverview and the jar file containing that class must be named ALGOverview.jar. Note the capitalization of ‘ALG’. 9 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 2. dll – the dll containing the implementation of the execute function must be named libALGOverview.dll. Note that again that ‘ALG’ is upper case and is prefixed by lib which is lower case. PIMA Command Line Process Flow The PIMA command line client interprets the command line and forwards the command and its arguments to the PIMA server. The server then reformats the command to mimic the input that a GUI-based plug-in would accept. This allows graphic and command line interface code to be almost identical. If a developer has already created a PIMA GUI very little additional code has to be written in order for the algorithm to work with a command line interface. The basic command line process flow is: Client pareses command line into XML (this is transparent to the algorithm, XML interface is not public) Client sends XML via Java RMI to server Server parses XML and creates Data Access Object (DAO) based on the XML. It then instantiates the algorithm object and sets the DOA member within the object The server then calls the generateExecArg() method. The algorithm developer has to use the DAO within the generateExecArg() method to create a command line argument string that he/she knows is correct for calling their execute() method in their algorithm dll. generateExecArg() returns the command line argument string Server uses a system call to invoke the algorithm within the dll using the contents of the returned string from generateExecArg() as the input parameter(s) Implementation – Java jar The first component to be considered is the algorithm class’ Java jar. Recall that the algorithm class implements pima.algorithm.AlgoParamInterface. Whether the algorithm developer creates a GUI or command line accessible algorithm, the critical method to be implemented in either case is generateExecArg(). All command line arguments and options are prefixed with a double dash (--). The generateExecArg() method provides the algorithm developer all the command line arguments and options via the DAO. The DAO provides convenient accessor methods for often used command line arguments via the following mapping: image_file base_file output_dir tmp_dir images -> -> -> -> -> String getSelectedImageFilename() String getBaseFilename() String getOutputDirectory() String getTempDirectory() String[] getFilenames() Any additional command line arguments and options can be accessed via the method String[] getNameValuePairs() 10 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 The getNameValuePairs() method returns an array of strings containing all the arguments not available through the above convenience accessor methods, with the format of each string being <name>:<value>. By convention, the command line client expects a “work order” option to be set on the command line with the syntax --wo <work order> with the work order value being unique and usually containing a date/time string, e.g. --wo test_201005191145. Since the work order argument is not available via one of the convenience accessor, it may be accessed by the getNameValuePairs()as one of the elements of the string array with the format wo:test_201005191145. As an example, assume an algorithm needs a region of interest (ROI), which is normally passed through by the PIMA GUI. In the command line interface, the ROI would need to be explicitly passed via name-value pairs. How the ROI is structured is completely up to the algorithm developer. An algorithm requiring an ROI could be called as: java -cp apexclient.jar pima.xml.client.apex.ApexClient pima --request execute --algorithm Demo:AlgNeedingROI --wo PIMA_RSAT2_2009123000000003 --logdir C:\PIMA\log --output_dir C:\PIMA --image_file C:\PIMA\images\image0.ntf --base_file C:\PIMA\images\testimage.ntf --tmp_dir C:\PIMA\tmp --ullon -117.6 --ullat 33.8 --urlon -117.5 --urlat 33.8 --lrlon -117.5 --lrlat 33.7 --lllon -117.6 --lllat 33.7 Another possibility is: java -cp apexclient.jar pima.xml.client.apex.ApexClient pima --request execute --algorithm Demo:AlgNeedingROI --wo PIMA_RSAT2_2009123000000003 --logdir C:\PIMA\log --output_dir C:\PIMA --image_file C:\PIMA\images\image0.ntf --base_file C:\PIMA\images\testimage.ntf --tmp_dir C:\PIMA\tmp --roi -117.6;33.8;117.5;33.8;-117.5;33.7;-117.6;33.7 Using the former execute request, --ullon command line argument would be formatted as: 11 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 ullon:-117.6 In the case of the latter, the –-roi argument as: roi:-117.6;33.8;117.5;33.8;-117.5;33.7;-117.6;33.7 For multi-valued arguments, like roi, use a delimiter other than white space or a colon. Assuming the latter execute request, the generateExecArg() method could look something like this: public String generateExecArg() { String retVal; ... String fullPathStr = dao.getSelectedImageFilename(); String outDir = dao.getOutputDirectory(); ... if (dao.isCommandLine()) { if (dao.getNameValuePairs() != null) { String[] nameValues = dao.getNameValuePairs(); for (int i = 0; i < nameValues.length; i++) { if (nameValues[i].contains("roi")) { // parse the roi knowing that the string // is formatted // roi:<ullat>;<ullon>; . . . ;<lrlon> } } } } ... return retVal; } Figure 9 - Sample generateExecArg() Method Parsing ROI Note the check for isCommandLine() and that the getNameValuePairs() is checked for null. Since the PIMA GUI interface has no notion of name-value pairs, this method returns null when being called from within the PIMA GUI. As noted before, the work order is also available as a name-value pair. Its primary use is in the naming of log files. Command line arguments can also be used as flags or switches by simply omitting the ‘value’ for the argument. For example, assume an algorithm, myAlg, required two inputs, x and y, could be set to run in a “debug” mode. Its command line to run in debug might look like this: java -cp apexclient.jar pima.xml.client.apex.ApexClient pima --request execute 12 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 --algorithm Demo:myAlg --wo debug_201005191315 --logdir C:\PIMA\log --output_dir C:\PIMA --x 457 --y 809 --debug The arguments available via getNameValuePairs() would be: wo:debug_201005191315 x:457 y:809 debug: To check to see if the debug flag was set, one would simply loop through the name:value pairs looking for a string that contained “debug”. A call with debug not set would simply be: java -cp apexclient.jar pima.xml.client.apex.ApexClient pima --request execute --algorithm Demo:myAlg --wo myrun_201005191315 --logdir C:\PIMA\log --output_dir C:\PIMA --x 457 --y 809 getNameValuePairs() would return: wo:myrun_201005191315 x:457 y:809 Finally, although not as essential as the generateExecArg() method, the getHelpURL() should also be implemented. For the command line client, its purpose is to return a ‘usage’ string defining all options for the algorithm user (see Help for Specific Algorithm). Implementation – C/C++ dll The other main component required to integrate algorithms into the PIMA architecture is a dynamically linked library (dll) that implements the interface to the algorithms. Again, the name of the dll that corresponds to the jar file in this example is libALGOverview.dll. PIMA requires that libALGOverview.dll implement a function called execute that is invoked by PIMA to start the algorithm. The signature of the execute function is located in: %PIMA_HOME%\interfaces\PIMA_IF.h This header must be included by the dll. The parameter format is defined by the generateExecArg() declared in pima.algorithm.AlgoParamInterface and 13 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 implemented in ALGOverview.java. A snippet of ALGOverview.cpp is shown below that parses the parameter list from the generateExecArg()method defined in the ALGOverview.java and then eventually completes by exiting with a status integer 0. #include <string> #include <vector> ... #include "PIMA_IF.h" #include “sicdutils.h” ... int execute(execParams* ep) { std::string params(ep->paramList); // // parse param list, assume params are delimited by ";" std::vector<string> token; const string delimiter = ";"; getTokens(params, token, delimiter); std::string inputDir = token.at(0); std::string inputFile = token.at(1); std::string outputDir = token.at(2); ... return 0; } Figure 10 - Sample execute() Function The execute function MUST be implemented by the algorithm developer. A description of the execParams structure is found in PIMA_IF.h. An algorithm dependant status integer is returned where 0 indicates success and non zero otherwise. Building the algorithm as a dll from within MS Studio requires PIAPP_EXPORT defined as a “Preprocessor Definition” in the algorithm’s property page. Deployment Deploying algorithms is simply a matter of copying the jar and dll files to the appropriate directories on the PIMA server under %PIMA_HOME%\algorithms. By convention, each company or organization wishing to deploy their algorithms would have their own directory with bin and class directories under their named directory (see Figure 11). If CompanyA wishes to deploy their version of a “crop” algorithm, they would do so by placing libALGCrop.dll in %PIMA_HOME%\algorithm\CompanyA\bin and ALGCrop.jar in 14 PIMA COMMAND LINE INTERFACE 19 APRIL 2011 %PIMA_HOME%\algorithm\CompanyA\class. A call to execute CompanyA’s crop algorithm from the command line would require the algorithm argument to be set like this: --algorithm CompanyA:Crop A benefit of this directory structure is the avoidance of any naming collisions, thus Organization2 can have their version of “crop” and not worry about possible ambiguous algorithm names. Once the jar and dll are copied to the correct directories, a call to Organization2’s “crop” would set the algorithm argument as: --algorithm Organization2:Crop Figure 11 - Algorithm Directory Structure 15