|
|
Line 1: |
Line 1: |
| Here we introduce Alida's operator concept with some code snippets of <code>ALDOperator</code>s | | Here we introduce Alida's operator concept with some code snippets to give you a first impression of how to deal with Alida on the programming level. |
| and focus on Alida's capabilities to automatically generate user interfaces.
| |
|
| |
|
| = First operator =
| | * for Java snippets and more follow [[Java_quick|this]] link |
| | * C++ snippets and interesting information on the implementation in C++ can be found [[C++_quick|here]] |
|
| |
|
| As a first example of an Alida operator we implement the row or column wise
| | Notes on the installation of Alida can be found [[Installation|here]] and in the user manual accessible from [http://www2.informatik.uni-halle.de/agprbio/alida/downloads/manual/AlidaManual.pdf here]. |
| sum for a 2D array of Doubles.
| |
| The class <code>MatrixSum</code> extending <code>ALDOperator</code> features three member variables
| |
| holding the input 2D array, an enum to indicate the mode of summation (<code>ROW</code> or <code>COLUMN</code>), and
| |
| an 1D array of the sums to be computed and returned by the operator.
| |
| Alida requires only to annotate these members with the @Parameter annotation
| |
| which declares
| |
| | |
| * the direction (<code>IN</code>, <code>OUT</code>, <code>INOUT</code>),
| |
| * whether the parameter is required,
| |
| * an optional textual description,
| |
| * and a label used, e.g. in the graphical user interface automatically generated
| |
| to execute the operator.
| |
| | |
| It is important to add a public standard constructor (without arguments)
| |
| to be able to use Java's reflection mechanism.
| |
| Finally, the abstract method <code>operate()</code> of <code>ALDOperator</code> has to be overridden
| |
| implementing the functionality of the operator.
| |
| | |
| | |
| | |
| <pre>
| |
| @ALDAOperator(genericExecutionMode=ALDAOperator.ExecutionMode.ALL,
| |
| level=ALDAOperator.Level.APPLICATION)
| |
| public class MatrixSum extends ALDOperator {
| |
| | |
| /** Choose row or colum wise sum
| |
| */
| |
| public static enum SummarizeMode {
| |
| /** row wise */
| |
| ROW,
| |
| | |
| /** column wise */
| |
| COLUMN
| |
| }
| |
| | |
| /**
| |
| * Input matrix
| |
| */
| |
| @Parameter( label= "Input matrix", required = true,
| |
| direction = Parameter.Direction.IN, description = "Input matrix.")
| |
| private Double[][] matrix;
| |
| | |
| /**
| |
| * Mode of summarizing
| |
| */
| |
| @Parameter( label= "Summarize mode", required = true,
| |
| direction = Parameter.Direction.IN, description = "Sum over columns or rows?")
| |
| private SummarizeMode summarizeMode = SummarizeMode.ROW;
| |
| | |
| /**
| |
| * 1D Array of sums.
| |
| */
| |
| @Parameter( label= "sums",
| |
| direction = Parameter.Direction.OUT, description = "Row or column wise sums.")
| |
| private Double[] sums = null;
| |
| | |
| /**
| |
| * Default constructor.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public MatrixSum() throws ALDOperatorException {
| |
| }
| |
| | |
| /**
| |
| * Constructor.
| |
| *
| |
| * @param matrix Input matrix.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public MatrixSum(Double[] [] matrix) throws ALDOperatorException {
| |
| this.matrix = matrix;
| |
| }
| |
| | |
| @Override
| |
| protected void operate() {
| |
| if ( matrix == null )
| |
| sums = null;
| |
| | |
| // calculate sums
| |
| if ( summarizeMode == SummarizeMode.ROW ) {
| |
| sums = new Double[matrix.length];
| |
| for ( int row = 0 ; row < matrix.length ; row++ ) {
| |
| sums[row] = 0.0;
| |
| for ( int col = 0 ; col < matrix[0].length ; col++ )
| |
| sums[row] += matrix[row][col];
| |
| }
| |
| } else {
| |
| sums = new Double[matrix[0].length];
| |
| for ( int col = 0 ; col < matrix[0].length ; col++ ) {
| |
| sums[col] = 0.0;
| |
| for ( int row = 0 ; row < matrix.length ; row++ )
| |
| sums[col] += matrix[row][col];
| |
| }
| |
| }
| |
| }
| |
| </pre>
| |
| | |
| | |
| | |
| These are the basic requirements for the operator to be used on the programming level.
| |
| An example of this use is included in the example in the next section.
| |
| | |
| If we further annotate the class with
| |
| <pre>
| |
| @ALDAOperator(genericExecutionMode=ALDAOperator.ExecutionMode.ALL)
| |
| </pre>
| |
| this is all needed to also facilitate
| |
| execution of this operator via a graphical and a command line user interface
| |
| automatically generated by Alida.
| |
| (Setting <code>level=ALDAOperator.Level.APPLICATION</code> declares this operator an application
| |
| which is used in the GUI to control display of available operators.)
| |
| | |
| | |
| == Invocation via a graphical user interface ==
| |
| | |
| Alida comes with one single application to execute Alida operators
| |
| with a automatically generated graphical user interface which may be
| |
| started from command line by
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunnerGUI
| |
| </pre>
| |
| | |
| This will pop up a window to choose an operator to execute.
| |
| Arranged according to the package structure all operators allows to be executed
| |
| via the graphical user interface according to their <code>genericExecutionMode</code>
| |
| are displayed.
| |
| Initially packages are unfolded up to a predefined depth.
| |
| Unfold the demo package, select <code>MatrixSum</code>, and choose the "Configure Operator" button.
| |
| This will pop up another window which allows you to configure the input parameters
| |
| of the operator.
| |
| Important note: After finishing to input the data matrix entering the final matrix elements
| |
| you have to select a previous matrix element due to subtle AWT details.
| |
| For the enumeration to select the mode Alida has automatically generated
| |
| a combo box to allow convenient selections.
| |
| If you are finished with the parameter configuration you want to invoke the operator
| |
| using the run button.
| |
| On completion of <code>MatrixSum</code> the interface will pop up the result window which allows you
| |
| to inspect the outcome of the operation.
| |
| | |
| == Invocation via command line ==
| |
| | |
| The command line user interface of Alida allows to invoke all Alida operator
| |
| properly annotated to allows generic execution.
| |
| | |
| You may invoke the matrix summation operator by
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner MatrixSum matrix='[[1,2,3],[4,5,6]]' sums=-
| |
| </pre>
| |
| which returns as result on standard output
| |
| <pre>
| |
| sums = [6.0,15.0]
| |
| </pre>
| |
| | |
| Parameter values are specified as name=value pairs.
| |
| Alida's syntax for 2D array should be self-explanatory from this example.
| |
| As the mode of summation is not supplied as a parameter its default is used
| |
| | |
| Note, the command
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner MatrixSum matrix='[[1,2,3],[4,5,6]]'
| |
| </pre>
| |
| will return no output as the command line user interface returns only output parameters requested.
| |
| | |
| The enumeration defined in <code>MatrixSum</code> is supported by the
| |
| user interface without further action required as shown in the next example.
| |
| This also demonstrates redirection of output
| |
| to a file, sums.out in this case.
| |
| | |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner MatrixSum matrix='[[1,2,3],[4,5,6]]'
| |
| summarizeMode=COLUMN sums=@sums.out+
| |
| </pre>
| |
| Input can be read from file as well:
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner MatrixSum matrix=@data sums=-+
| |
| </pre>
| |
| | |
| where the file data contains the string defining the matrix, e.g., <code>[[1,2,3],[4,5,6]]</code>
| |
| | |
| = Adding more features to an operator =
| |
| | |
| We now generalize this example to realize not only summation over rows or
| |
| columns, but arbitrary summarizing operations.
| |
| This shows Alida's feature to allow an operator as parameter of another operator.
| |
| | |
| == Implementation ==
| |
| | |
| First we generalize <code>ALDArraySum</code> to the operator <code>ApplyToMatrix</code>
| |
| which also takes a 2D array and an enum indicating the mode of marginalization (<code>ROW</code> or <code>COLUMN</code>).
| |
| It takes an additional input parameter which specifies the operation to be applied on each
| |
| row or column.
| |
| | |
| This parameter is itself an Alida operator and of type <code>ALDSummarizeArrayOp</code>
| |
| which is implemented as an abstract class.
| |
| This abstract operator defines a summarizing operator
| |
| which takes a 1D array as input and returns a summarizing scalar.
| |
| As this is an abstract class there is no need to override the <code>operate()</code>
| |
| method, however some getter and setter methods are provided.
| |
| | |
| | |
| | |
| <pre>
| |
| @Parameter( label= "Input 1D array", required = true,
| |
| direction = Parameter.Direction.IN, description = "Input array (1D).")
| |
| protected Double[] data;
| |
| | |
| /**
| |
| * Summarizing scalar
| |
| */
| |
| @Parameter( label= "Summarizing scalar",
| |
| direction = Parameter.Direction.OUT, description = "Summarizing scalar of the 1D arra")
| |
| protected Double summary = null;
| |
| | |
| /**
| |
| * Default constructor.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public ALDSummarizeArrayOp() throws ALDOperatorException {
| |
| }
| |
| | |
| /**
| |
| * Returns the 1D array
| |
| * @return data array
| |
| */
| |
| public Double[] getData() {
| |
| return this.data;
| |
| }
| |
| | |
| /**
| |
| * Sets the 1D array
| |
| * @param data
| |
| */
| |
| public void setData( Double[] data) {
| |
| this.data = data;
| |
| }
| |
| | |
| </pre>
| |
| | |
| | |
| Now we add concrete examples of such a summarizing operation, in this case
| |
| summation (<code>ALDArraySum</code>), to return the mean (<code>ALDArrayMean</code>), and the minimum (<code>ALDArrayMin</code>).
| |
| Each implements the <code>operate()</code> method and has to supply a standard constructor.
| |
| In this example we add another constructor for convenience.
| |
| This operators are declared as operators on the standard in contrast to
| |
| application level, as they are not expected to be invoked as an application.
| |
| However, setting the level to standard in the menu of the graphical user interface
| |
| stills allows their execution.
| |
| When extending the abstract super class it is necessary to annotate the
| |
| class with <code>@ALDDerivedClass</code> in order to allow Alida's dataIO mechanism to find the derived class
| |
| in the automatically generated user interface.
| |
| This holds for other parameter types as well.
| |
| More specifically, if an instance of a class is to be supplied in an automatically
| |
| generated user interface as a value for a parameter of one of its super classes,
| |
| Alida requires the annotation <code>@ALDDerivedClass</code>.
| |
| | |
| | |
| | |
| <pre>
| |
| @ALDDerivedClass
| |
| @ALDAOperator(genericExecutionMode=ALDAOperator.ExecutionMode.ALL,
| |
| level=ALDAOperator.Level.STANDARD)
| |
| public class ALDArraySum extends ALDSummarizeArrayOp {
| |
| | |
| @Override
| |
| protected void operate() {
| |
| summary = 0.0;
| |
| for ( int i = 0 ; i < data.length ; i++ )
| |
| summary += data[i];
| |
| }
| |
| | |
| /**
| |
| * Default constructor.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public ALDArraySum() throws ALDOperatorException {
| |
| }
| |
| | |
| </pre>
| |
| | |
| | |
| Now we are ready to implement
| |
| the <code>ApplyToMatrix</code> operator, which also demonstrates supplemental parameters.
| |
| This supplementals, e.g., control debugging output or returning of intermediate results.
| |
| For demo purposes we declare a supplemental input parameter <code>returnElapsedTime</code>.
| |
| If it is set to true the operator will return the elapsed time in a second
| |
| supplemental parameter with direction output.
| |
| | |
| Again, the operation is implemented in the <code>operate()</code> method and the remainder of the
| |
| class supplies getter and setter methods for convenience.
| |
| The <code>operate()</code> method give also an example of the invocation of an operator on the
| |
| programming level.
| |
| In this case, an instance of the operator is already passed as a parameter.
| |
| Its parameters are set, in this case each 1D array to be summarized in turn.
| |
| Upon return from the method <code>runOp()</code> the results may be retrieved from the operator object,
| |
| in this example with the <code>getSummary()</code> method.
| |
| Besides getter and setter methods as implemented in each operator
| |
| Alida provides also a generic get and set methods applicable to
| |
| all parameters of an operator.
| |
| Note, that the operator is not invoked by its <code>operate()</code> method, but via
| |
| the <code>runOp()</code> method implemented the base class <code>ALDOperator</code>.
| |
| This methods validates the parameters before invocation of <code>operate()</code>.
| |
| Furthermore, it take all necessary measures for Alida's processing
| |
| history which automatically logs
| |
| all manipulative actions on the data and corresponding parameter settings.
| |
| | |
| | |
| | |
| <pre>
| |
| @ALDAOperator(genericExecutionMode=ALDAOperator.ExecutionMode.ALL,
| |
| level=ALDAOperator.Level.APPLICATION)
| |
| public class ApplyToMatrix extends ALDOperator {
| |
| | |
| /** Choose row or colum wise sum
| |
| */
| |
| public static enum SummarizeMode {
| |
| /** row wise */
| |
| ROW,
| |
| /** column wise */
| |
| COLUMN
| |
| }
| |
| | |
| /**
| |
| * Input matrix
| |
| */
| |
| @Parameter( label= "Input matrix", required = true,
| |
| direction = Parameter.Direction.IN, description = "Input matrix.")
| |
| private Double[][] matrix;
| |
| | |
| /**
| |
| * Mode of summarizing
| |
| */
| |
| @Parameter( label= "Summarize mode", required = true,
| |
| direction = Parameter.Direction.IN, description = "Sum over columns or rows.")
| |
| private SummarizeMode summarizeMode = SummarizeMode.ROW;
| |
| | |
| /**
| |
| * Summarizing opererator
| |
| */
| |
| @Parameter( label= "Summarizing operator", required = true,
| |
| direction = Parameter.Direction.IN, description = "Specifies the summarizing operation to apply")
| |
| private ALDSummarizeArrayOp summarizeOp;
| |
| | |
| /**
| |
| * 1D Array of summaries.
| |
| */
| |
| @Parameter( label= "summaries",
| |
| direction = Parameter.Direction.OUT, description = "Row or column wise summaries")
| |
| private Double[] summaries = null;
| |
| | |
| /**
| |
| * Supplemental to request elapsed time to be returned
| |
| */
| |
| @Parameter( label= "Return elapsed time",
| |
| direction = Parameter.Direction.IN, description = "Request elapsed time consumed to be returned",
| |
| supplemental=true)
| |
| private boolean returnElapsedTime = false;
| |
| | |
| /**
| |
| * Elpased time
| |
| */
| |
| @Parameter( label= "Elapsed time",
| |
| direction = Parameter.Direction.OUT, description = "Elapsed time of operation in milliseconds",
| |
| supplemental=true)
| |
| private long elapsedTime;
| |
| | |
| /**
| |
| * Default constructor.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public ApplyToMatrix() throws ALDOperatorException {
| |
| }
| |
| | |
| /**
| |
| * Constructor.
| |
| *
| |
| * @param matrix Input matrix.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public ApplyToMatrix(Double[] [] matrix) throws ALDOperatorException {
| |
| this.matrix = matrix;
| |
| }
| |
| | |
| @Override
| |
| protected void operate() throws ALDOperatorException,ALDProcessingDAGException {
| |
| if ( returnElapsedTime )
| |
| elapsedTime = System.currentTimeMillis();
| |
| | |
| if ( matrix == null )
| |
| summaries = null;
| |
| | |
| // calculate summaries
| |
| if ( summarizeMode == SummarizeMode.ROW ) {
| |
| summaries = new Double[matrix.length];
| |
| for ( int row = 0 ; row < matrix.length ; row++ ) {
| |
| summarizeOp.setData(matrix[row]);
| |
| summarizeOp.runOp();
| |
| summaries[row] = summarizeOp.getSummary();
| |
| }
| |
| } else {
| |
| summaries = new Double[matrix[0].length];
| |
| Double[] tmp = new Double[matrix.length];
| |
| for ( int col = 0 ; col < matrix[0].length ; col++ ) {
| |
| for ( int row = 0 ; row < matrix.length ; row++ )
| |
| tmp[row] = matrix[row][col];
| |
| | |
| summarizeOp.setData(tmp);
| |
| summarizeOp.runOp();
| |
| summaries[col] = summarizeOp.getSummary();
| |
| }
| |
| }
| |
| | |
| if ( returnElapsedTime )
| |
| elapsedTime = System.currentTimeMillis() - elapsedTime;
| |
| }
| |
|
| |
| // ==============================================================
| |
| // Getter and setter methods
| |
| /** Get value of returnElapsedTime.
| |
| * Explanation: Request elapsed time consumed to be returned.
| |
| * @return value of returnElapsedTime
| |
| */
| |
| public boolean getReturnElapsedTime(){
| |
| return returnElapsedTime;
| |
| }
| |
| | |
| /** Set value of returnElapsedTime.
| |
| * Explanation: Request elapsed time consumed to be returned.
| |
| * @param value New value of returnElapsedTime
| |
| */
| |
| public void setReturnElapsedTime( boolean value){
| |
| this.returnElapsedTime = value;
| |
| }
| |
| </pre>
| |
| | |
| | |
| | |
| == Invocation via a graphical user interface ==
| |
| | |
| If the graphical interface is still running just select our new operator
| |
| and begin to configure it.
| |
| For the parameter summarizing operator you have a choice of all operators extending
| |
| the abstract operator <code>ALDSummarizeArrayOp</code>.
| |
| All which is necessary on the implementation side is proper annotation of the extending
| |
| classes with <code>@ALDDerivedClass</code>.
| |
| As the selected operator may have its own parameters you may want to configure it.
| |
| In our example this is not necessary as the input array is, of course, supplied
| |
| by the <code>ApplyToMatrix</code> operator.
| |
| Do not forget to input your data before hitting the run button.
| |
| After return, again a result window give you the results of the operation.
| |
| Note, if you did not tick Return elapsed time" this window will show zero
| |
| for the time elapsed as the operator has not been request to stop the time.
| |
| | |
| | |
| == Invocation via command line ==
| |
| | |
| When invoking the <code>ApplyToMatrix</code> operator from command line
| |
| we have to handle derived classes as value for parameters.
| |
| In the graphical user interface Alida features a combo box where
| |
| we may choose from.
| |
| In the command line interface Alida allows to prefix the value of a parameter
| |
| with a derived class to be passed to the operator.
| |
| This is necessary as Alida as, of course, no way to itself
| |
| decide if and which derived class is to be used.
| |
| Alida's syntax is to enclose the class name in a dollar sign and a colon.
| |
| As evident in the following example, abbreviations are of the fully
| |
| qualified class name are accepted as long as they are unambiguous.
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner Apply \
| |
| matrix='[[1,2,3],[4,5,6]]' \
| |
| summarizeMode=ROW \
| |
| summarizeOp='<math>ALDArrayMean:{}' \
| |
| summaries=-
| |
| </pre>
| |
| results in
| |
| <pre>
| |
| summaries = [2.0,5.0]
| |
| </pre>
| |
| | |
| | |
| <code>ALDOpRunner</code> may be persuaded to show all operators derived from <code>ALDSummarizeArrayOp</code>
| |
| and known within the user interface if we enter an invalid class name:
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner \
| |
| Apply matrix='[[1,2,3],[4,5,6]]' \
| |
| summarizeMode=ROW summarizeOp='</math>dd:{}' \
| |
| summaries=-
| |
| </pre>
| |
| yields
| |
| <pre>
| |
| ALDStandardizedDataIOCmdline::readData found 0 derived classes matching <dd>
| |
| derived classes available:
| |
| de.unihalle.informatik.Alida.demo.ALDArrayMean
| |
| de.unihalle.informatik.Alida.demo.ALDArrayMin
| |
| de.unihalle.informatik.Alida.demo.ALDArraySum
| |
| ERROR: reading parameter <summarizeOp> returns null
| |
| </pre>
| |
| | |
| | |
| Supplemental parameters are handled like other parameters
| |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner Apply \
| |
| matrix='[[1,2,3],[4,5,6]]' \
| |
| summarizeMode=COLUMN \
| |
| summarizeOp='<math>ALDArrayMin:{}' \
| |
| summaries=- \
| |
| returnElapsedTime=true \
| |
| elapsedTime=-
| |
| </pre>
| |
| gives
| |
| <pre>
| |
| summaries = [1.0,2.0,3.0]
| |
| elapsedTime = 4
| |
| </pre>
| |
| | |
| | |
| | |
| = Adding more data types as parameters =
| |
| | |
| Alida provides automatic IO of primitive data types, enumerations, arrays, collections,
| |
| and operators.
| |
| In addition so called parameterized classes are supported.
| |
| Any Java class may be declared to be a parameterized class in Alida
| |
| by annotating the class <code>@ALDParametrizedClass</code> as shown in the
| |
| class <code>ExperimentalData</code>.
| |
| All member variables to be known to and handled by Alida's user interface
| |
| simply need to be annotated with <code>@ALDClassParameter</code>.
| |
| | |
| Here we implement a toy version of experimental data <code>ExperimentalData</code>.
| |
| A complete experiment consists of a number of independent repetitions of
| |
| sub experiments.
| |
| In each of these the same features (measurements) are recorded.
| |
| The measurements a represented in
| |
| a 2D array of Doubles, where each column represents
| |
| one sub experiment and the rows the distinct features.
| |
| The measurements may be normalized which is indicated by the
| |
| normalized member variable.
| |
| | |
| The class is annotated by <code>@ALDParametrizedClass</code>, and
| |
| and all members to be handle in Alida'a user interfaces are
| |
| to be annotated with <code>@ALDParametrizedClass</code>.
| |
| The label field has the same semantics as for parameters of operators.
| |
| These annotations are the only implementational overhead
| |
| to allow Alida to automatically generate user interfaces
| |
| where the parameterized class acts a a parameter.
| |
| | |
| | |
| | |
| <pre>
| |
| @ALDParametrizedClass
| |
| @ALDMetaInfo(export=ALDMetaInfo.ExportPolicy.MANDATORY)
| |
| public class ExperimentalData {
| |
| @ALDClassParameter(label="description")
| |
| private String description = null;
| |
| | |
| @ALDClassParameter(label="data")
| |
| private Double[][] data = null;
| |
| | |
| /** are the data normalized
| |
| */
| |
| @ALDClassParameter(label="Is normalized")
| |
| private boolean normalized = false;
| |
| | |
| /** Standard constructor is needed
| |
| */
| |
| public ExperimentalData() {
| |
| }
| |
| | |
| /** Constructor for an experiment.
| |
| * Normalized is assumed to be false.
| |
| *
| |
| * @param description a textual desciption of the experiment
| |
| * @param data measurements
| |
| */
| |
| public ExperimentalData( String description, Double[][] data) {
| |
| this( description, data, false);
| |
| }
| |
| | |
| /** Constructor for an experiment.
| |
| *
| |
| * @param description a textual desciption of the experiment
| |
| * @param data measurements
| |
| * @param normalized are the data normalized
| |
| */
| |
| public ExperimentalData( String description, Double[][] data, boolean normalized) {
| |
| this.normalized = normalized;
| |
| this.description = description;
| |
| this.setData( data, normalized);
| |
| }
| |
| </pre>
| |
| | |
| | |
| This is shown below for a simple normalizing operator <code>NormalizeExperimentalDataOp</code>
| |
| which takes experimental data as input an returns a new instance
| |
| of <code>ExperimentalData</code> which contains normalized data.
| |
| | |
| | |
| | |
| <pre>
| |
| @ALDAOperator(genericExecutionMode=ALDAOperator.ExecutionMode.ALL,
| |
| level=ALDAOperator.Level.APPLICATION)
| |
| public class NormalizeExperimentalDataOp extends ALDOperator {
| |
| | |
| /**
| |
| * Input data
| |
| */
| |
| @Parameter( label= "Experimental data", required = true,
| |
| direction = Parameter.Direction.IN, description = "Experimental data to be normalized")
| |
| private ExperimentalData experiment = null;
| |
| | |
| /**
| |
| * Normalized experiment to be returned
| |
| */
| |
| @Parameter( label= "Normalized experiment",
| |
| direction = Parameter.Direction.OUT, description = "Normalized experiment")
| |
| private ExperimentalData result = null;
| |
| | |
| /**
| |
| * Default constructor.
| |
| * @throws ALDOperatorException
| |
| */
| |
| public NormalizeExperimentalDataOp() throws ALDOperatorException {
| |
| }
| |
| | |
| /**
| |
| * Constructor.
| |
| *
| |
| * @param experiment Experimental data
| |
| * @throws ALDOperatorException
| |
| */
| |
| public NormalizeExperimentalDataOp(ExperimentalData experiment) throws ALDOperatorException {
| |
| this.experiment = experiment;
| |
| }
| |
| | |
| @Override
| |
| protected void operate() throws ALDOperatorException,ALDProcessingDAGException {
| |
|
| |
| ApplyToMatrix normalizeOp = new ApplyToMatrix( experiment.getData());
| |
| normalizeOp.setSummarizeMode( ApplyToMatrix.SummarizeMode.ROW);
| |
| normalizeOp.setSummarizeOp( new ALDArrayMean());
| |
| normalizeOp.runOp();
| |
| | |
| Double[][] normalizedData = (Double[][])(experiment.getData().clone());
| |
| for ( int e = 0; e < experiment.getNumExperiments(); e++ ) {
| |
| for ( int f = 0 ; f < experiment.getNumFeatures() ; f++ ) {
| |
| normalizedData[f][e] -= normalizeOp.getSummaries()[f];
| |
| }
| |
| }
| |
| | |
| result = new ExperimentalData( experiment.getDescription() + " (Normalized)", normalizedData, true);
| |
| }
| |
| </pre>
| |
| | |
| | |
| | |
| This mechanism applies in a recursive fashion, i.e. a parameterized class may
| |
| (recursively) contain a member variable which itself is a parametrized class.
| |
| Likewise, an operator acting as a parameter of another operator
| |
| may in turn have a parameter of type <code>ALDOperator</code>.
| |
| | |
| == Invocation via a graphical user interface ==
| |
| | |
| Invoking and configuring <code>NormalizeExperimentalDataOp</code> from the graphical user interface
| |
| shows as the only required parameter the experimental data.
| |
| This parameterized class can be configured in a separate window
| |
| very similar to to configuration of operators.
| |
| Likewise the resulting normalized experimental data
| |
| may be inspected in their own window.
| |
| | |
| Obviously this is a toy example, as we would not expect the measurements to
| |
| be entered manually, but rather stored and read from file in a specialized format.
| |
| This is one of the rare cases where
| |
| custom data IO provider need to be implemented, in this
| |
| case for <code>ExperimentalData</code>.
| |
| | |
| | |
| == Invocation via command line ==
| |
| | |
| Again, invocation from command line is provided by Alida in an automatic
| |
| way with no further implementational overhead.
| |
| The syntax for parameterized classes es a comma separated list of name=value pairs
| |
| enclosed in curly brackets where name refers to annotated member variables of
| |
| the parameterized class.
| |
| | |
| <pre>
| |
| java de.unihalle.informatik.Alida.tools.ALDOpRunner NormalizeExperimentalDataOp \
| |
| experiment='{data=[[1,2,3],[2,2,2],[100,103,110]],description="Demo experiment"}' \
| |
| result=-
| |
| </pre>
| |
| yields
| |
| <pre>
| |
| result = { normalized = true ,
| |
| description = "Demo experiment" (Normalized) ,
| |
| data = [[-1.0,0.0,1.0],[0.0,0.0,0.0],
| |
| [-4.333333333333329,-1.3333333333333286,5.666666666666671]] }
| |
| </pre>
| |
| | |
| If a class derived from <code>ExperimentalData</code> was to be supplied to the operator,
| |
| the curly brackets can be prefixed by a derive class definition starting with a dollar sign
| |
| and ending with a colon as shown for the summarizing operators above.
| |