Next Previous Up Contents
Next: Activation Actions
Up: Algebraic Expression Syntax
Previous: Examples

### 7.10 Adding User-Defined Functions

The functions provided by default for use with algebraic expressions, while powerful, may not provide all the operations you need. For this reason, it is possible to write your own extensions to the expression language. In this way you can specify arbitrarily complicated functions. Note however that this will only allow you to define new columns or subsets where each cell is a function only of the other cells in the same row - there is no way to define a value in one row as a function of values in other rows.

In order to do this, you have to write and compile a (probably short) program in the Java language. A full discussion of how to go about this is beyond the scope of this document, so if you are new to Java and/or programming you may need to find a friendly local programmer to assist (or mail the author). The following explanation is aimed at Java programmers, but may not be incomprehensible to non-specialists.

The steps you need to follow are:

1. Write and compile a class containing one or more static public methods representing the function(s) required
2. Make this class available on the application's classpath at runtime as described in Section 10.2.1
3. Specify the class's name to the application, either as the value of the `jel.classes` or `jel.classes.activation` system properties (colon-separated if there are several) as described in Section 10.2.3 or during a run using the Available Function Window's Add Class () button

Any public static methods defined in the classes thus specified will be available for use in the Synthetic Column, Algebraic Subset or (in the case of activation functions only) Activation windows. They should be defined to take and return the relevant primitive or Object types for the function required (in the case of activation functions the return value should normally be a short log string).

For example, a class written as follows would define a three-value average:

        public class AuxFuncs {
            public static double average3(double x, double y, double z) {
                return (x + y + z) / 3.0;
            }
        }

and the expression "`average3($1,$2,$3)`" could then be used to define a new synthetic column, giving the average of the first three existing columns. Exactly how you would build this is dependent on your system, but it might involve doing something like the following:

1. Writing a file named "AuxFuncs.java" containing the above code
2. Compiling it using a command like "`javac AuxFuncs.java`"
3. Starting up TOPCAT with the flags: "`topcat -Djel.classes=AuxFuncs -classpath .`"

Note that (in versions later than TOPCAT 4.3-2) variable-length argument lists are supported where the final declared argument is an array, so for instance a method declared like:

           public static double sum(double[] values) {
               double total = 0;
               for (int i = 0; i < values.length; i++) {
                   total += values[i];
               }
               return total;
           }

can be invoked like "`sum(UMAG,GMAG,RMAG,IMAG,ZMAG)`". The alternative form "`double... values`" can be used in the declaration with identical effect.

Next Previous Up Contents
Next: Activation Actions
Up: Algebraic Expression Syntax
Previous: Examples

TOPCAT - Tool for OPerations on Catalogues And Tables
Starlink User Note253
TOPCAT web page: http://www.starlink.ac.uk/topcat/
Author email: m.b.taylor@bristol.ac.uk
Mailing list: topcat-user@jiscmail.ac.uk