DMelt:General/5 Using Scripts
Running Scripts
DataMelt is designed to work with several programming languages that are integrated (or written) in Java. DataMelt IDE allows to use interactive shells (in case of scripting languages) or the DataMelt editor.
DataMelt Java numerical libraries are designed for programming using several languages:
- Jython - Probably, this is the most simple and the most powerful approach as it combines the strength of the Python language with most complete and most popular Java. Read the tutorial online or the books
- JRuby - Similar to Jython is a scripting language, but with different syntax. Read tutorial online
- BeanShell - another scripting language which have the full access to Java API, but it is mainly designed to call Java classes without its own API. Read about it here
- Java - as above to build compiled Java bitecode libraries without interactivity. No need to introduce - this is the backbone of the scripting languages above, but you can still program using it. Read Java tutorial online
- Matlab or Octave - for analytic calculations (interactive). Octave is a high-level language intended for numerical or analytical computations. It is a Matlab-like numerical programming language. You can find about the syntax of Octave-type macros here.
If you have a source file loaded to the editor, one can execute it by pressing the "Run" button on the toolbar of DataMelt. One can also use the [F8] key. Also check out the "Run" toolbar menu for more options. The result depends on the file type:
- if you are editing a Java file (the extension ".java"), the program will be compiled and executed. One can also compile Java source files using the "Run" toolbar menu.
- if you are working with a BeanShell file (the extension ".bsh"), the program will be executed by pressing [[[:Template:Run.png]]] or [F8]. Text output will go to "BeanShell" (a window below the main editor)
- if you are working with Jython or Python files (the extension ".py"), the program will be executed as before, with the text output in the JythonShell (below the editor).
- if you are working with JRuby or Ruby files (the extension ".rb"), the program will be executed as before, with the text output in the JRubyShell (below the editor).
- if you are working with Matlab or Octave macros (the extension ".m") and using the analytic calculations capabilities of the program, the program will be executed as before, with the text output in the JasymcaShell.
Using JythonShell
For interactive coding and prototyping use the JythonShell (a window below the main editor). Use the standard Jython/Python language Jython.ORG. One advantage using the DataMelt JythonShell is that it has the code assist. To learn about the JythonShell, enter Python commands line by line. Use the help system as "obj." + [Ctrl]+[Space], where "obj" is any object.
Here is an example of a simple calculator:
from math import * print sin(20)*10*tan(0.5) 2.2293624664292436
you can see the available functions as by executing the command "dir()". The next example shows all the methods of the Python string object:
a="python" a. # press [Ctrl]+[Space] to find all methods
Executing scripts in a GUI mode
To run a Jython script in DataMelt IDE, use the Run button on the toolbar of DataMelt. One can also use the [F8] key for fast execution of a script. In case of an error, the DataMelt main editor will move the cursor to the appropriate line with error. Press any key to remove the line highlighting (red color).
As exercise, try to run this script: load to the DataMelt IDE and execute the script pressing the key [F8].
from jhplot import * f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", 1.0, 10.0) c1 = HPlot("Example of function") c1.visible() c1.setAutoRange() c1.draw(f1)
The script creates an EPS image "example.eps" with the 2D function as shown in this figure
Print streams in JythonShell
As usual, use the Python "print" method to print strings and numbers. The output will be directed to the JythonShell itself. You can also direct output steam and error stream to "System console". Use Java "System.out" and "System.err" for this. Here is an example:
print "Hello, Jython" print 233 # this is a number
You can also redirect the outputs from Jython macros to the Java system console:
from java.lang import * System.out.println("OK message") System.err.println("Error message") # will be shown in RED
Using File Menu
Let us show how to run Jython scripts using File Manu. Simple open a script using File-Open. When you will see Jython file in the editor, click on "run" button.
Running Jython scripts using URL
You can open or execute a Jython script from URL. Go to "File->Open from URL". You will see a dialogue window. Copy and paster URL. For example, in the Firefox, navigate to some link and right-click on the mouse button. Select "Copy and Link location", and then copy it to the DataMelt URL window. Make sure that you copy a complete address which starts from "http". Then click "run". This will execute the script from URL.
Be careful! Only run scripts from trusted sites! You can access the script later from the directory "macros/downloads".
Running a script in a batch mode
On Linux/Unix and Mac platforms, one can run scripts without DataMelt GUI. You can use a bash script included in the installation directory: dmelt_bat>ch.sh. If you have a Jython script "example.py", simply run DataMelt as:
./dmelt_batch.sh example.py
It is assumed that this command is executed inside the DataMelt install directory (where "dmelt.jar" is located). If the Jython code takes an argument, run the above example as:
./dmelt_batch.sh example.py argument
You can always redefine the installation directory by changing SCAVIS_HOME inside dmelt_batch.sh file.
#!/bin/bash YDIR=`pwd` args=$# if [ $args == 0 ] then echo "did not specify jython file!" echo "run DataMelt file in batch mode without the editor" echo "TYPE: a_run.sh <file>.py" exit 1; fi # set here home directory where the jehep.jar file is located JEHEP_HOME="/user/home/dmelt" FILE=$1 ################## do not edit ############################### JAVA_HEAP_SIZE=256 CLASSPATH="." for i in ${JEHEP_HOME}/lib/*/*.jar do CLASSPATH=$CLASSPATH:"$i" done JYTHON_HOME=${JEHEP_HOME}"/lib/jython" CP=${JYTHON_HOME}"/jython.jar" if [ ! -z "$CLASSPATH" ] then CP=$CP:$CLASSPATH fi # run file java -mx${JAVA_HEAP_SIZE}m -classpath "$CP" -Dpython.home=${JYTHON_HOME} \ org.python.util.jython $FILE
The only thing you need to do is to set the variable "JHPLOT_HOME" to the installation location where "dmelt.sh" is located. It is assumed that Java is installed (type "java" to check"). Make this script executable, i.e. type "chmod 755 run.sh".
Now, in order to run the above script, just execute:
bash> run.sh example.py
This will brings up a canvas and generate a vector-format image "example.eps".
Generating images in a background
Images can be generated without pop-up GUI window if the method "visible(0)" is called for the created canvases (HPlot, HPlotJa etc.). "0" indicates Java "false". Then, the last statement should be "export(file)" applied to canvases.
Jython and JavaBean properties
As I have not seen any topic of the Jython access properties to JavaBean here, I'd like to give a few example of how they are very efficient with the jhplot libraries to make a code very compact and easy to write and read. Maybe what I will describe is obvious, but I guess that not all are aware of those properties.
First, I don't want to describe in details what is a JavaBean (you can find tens of websites that will explain it better than me), but just explain basically that they are Java class that respect some writing conventions. One of this convention, in particular, has a very important interest in Jython: The fields of a Java Class are declared private (possibly protected or friendly) and are accessed via “assessor” methods (getters/setters methods) as following. For instance a field:
private double dou1=1;
will be accessed with two public methods:
public double getDou1();
and
public void setDou1(double d);
used for reading and writing this double value.
The things is that most of the jHPlot code is written respecting this convention. Let's see now how it could be used to simplify the code. Thus a small piece of Jython code used in the standard "Java way" would be written:
from java.awt import Color from java.util import Random from jhplot import HPlotJa, H1D from jhplot.jadraw import JaText rand = Random() val = [] for i in range(500): val.append(rand.nextGaussian()) h1 = H1D("H1D-1",20, -2.0, 2.0) h1.setColor(Color.green) h1.setErrX(False) h1.setErrY(True) h1.setPenWidthErr(2) h1.fill(val) c1 = HPlotJa("Canvas-1", 600, 600, 1, 1, True) c1.visible() c1.setAntiAlias(False) c1.setGTitle("Title-1") c1.setNameX("Xaxis") c1.setNameY("Yaxis") c1.setName("Canvas Title") c1.draw(h1) t1 = JaText("Text-1", 0.3, 0.3, "NDC") t1.setColor(h1.getColor()) c1.draw(t1) c1.update()
Of course, this works very well but as the Jython interpreter is smart with these accessor methods, it is possible to get a direct access to the private field and the interpreter will by itself use the getter/setter methods. Now if I write the same example as above with the properties, one would have:
from java.awt import Color from java.util import Random from jhplot import HPlotJa, H1D from jhplot.jadraw import JaText rand = Random() val = [] for i in range(500): val.append(rand.nextGaussian()) h2 = H1D("H1D-2",20, -2.0, 2.0) h2.color = Color.blue h2.errX = False h2.errY = True h2.penWidthErr = 2 h2.fill(val) c2 = HPlotJa("Canvas-2", 600, 600, 1, 1, True) c2.visible() c2.antiAlias = False c2.GTitle = "Title-2" c2.nameX = "Xaxis" c2.nameY = "Yaxis" c2.name = "Canvas Title" c2.draw(h2) t2 = JaText("Text-2", 0.3, 0.3, "NDC") t2.color = h2.color c2.draw(t2) c2.update()
One can see that we don't really save typing code , however it is (in my opinion) more clear to read, thanks to the “=” symbols.
Finally there another way to use those JavaBean properties, with once again, the smart Jython interpreter who can read or write the class fields directly in the object instance. Thus the same code can now be written:
from java.awt import Color from java.util import Random from jhplot import HPlotJa, H1D from jhplot.jadraw import JaText rand = Random() val = [] for i in range(500): val.append(rand.nextGaussian()) h3 = H1D("H1D-3", 20, -2.0, 2.0, color=Color.red, errX=False, errY=True, penWidthErr=2) h3.fill(val) c3 = HPlotJa("Canvas-3",600,600,1,1,True,antiAlias=False, GTitle="Title-3", nameX="Xaxis", nameY="Yaxis", name="Canvas Title") c3.visible() c3.draw(h3) t3 = JaText("Text-3", 0.3, 0.3, "NDC", color=h3.color) c3.draw(t3) c3.update()
One can see now that the code is more compact and each object is easy to identify. Of course these three methods produce exactly the same result.
Although this feature allows to save a lot a time while coding one must, however, be careful with some methods which are sometime named get/setSomething() but which are actually not providing any access to a private field of the class but a random methods doing some stuff. Of course this will not work in that case.
More information can be found here
(contributed by Marc-Antoine)