For simple operations, subclassing IDLitDataOperation is an easy way to quickly add an operation to the iTools system. See previous post “Creating an iTool data operation” for more information about IDLitDataOperation. If you want to do anything more complicated than a numeric operation on the dependent variable of the currently selected visualization, then you want to subclass IDLitOperation. We will examine a fairly simple subclass of IDLitOperation, MGitOpDerivative, which calculates the derivative of data in a plot visualization.

Here are the files for this demo:

MGitOpDerivative__define.pro (doc

A subclass of IDLitOperation which can calculate a derivative for IDLVECTOR data parameters in IDLitVisPlot visualizations.

MGitOpDerivative_demo.pro (doc)

Program which creates an iTool, loads a sample data set, and registers the above operation for it.

The old standards: init, cleanup, getProperty, setProperty methods

It is very important that the init method calls IDLitOperation::init with the TYPES keyword and pass along it’s own keywords with _EXTRA.

if (~self->IDLitOperation::init(types=['IDLVector'], $
                                name='Derivative', $
                                icon='plot', _extra=e)) then return, 0B

The cleanup, getProperty, and setProperty methods do not need to be overridden from those inherited from IDLitOperation.

The doAction method

The doAction method is called when the operation is performed by the user. The doAction method does the following:

  1. Finds IDLitVisPlot objects in the currently selected items of the iTool.
  2. Saves initial y data of the selected visualizations in an IDLitCommandSet so that the operation can be undone later (done in recordInitialValues)
  3. Do the derivatives (in doDerivative).
  4. Saves the final y data of the visualizations in the same IDLitCommandSet so that the operation can be redone later (done in recordFinalValues)
  5. Return the IDLitCommandSet that the initial and final values are stored in.

The real work is done in mgitopderivative::doDerivative. Here the plot parameter is an IDLitVisPlot object. The X and Y parameters of this object contain the data.

pro mgitopderivative::doDerivative, plot
  compile_opt strictarr

  xdata = plot->getParameter('X')
  ydata = plot->getParameter('Y')

  result = xdata->getData(x)
  result = ydata->getData(y)

  yprime = deriv(x, y)

  result = ydata->setData(yprime)

end

The same kind of code will be used later to change the y values, using IDLitData::setData method instead of IDLitData::getData.

Undo/Redo

Unlike when subclassing IDLitDataOperation, we are responsible for storing information to enable undo/redo. This information is stored in an IDLitCommandSet object. For each visualization acted on, an IDLitCommand is created, data is added to it, and it is added to the command set. Here is a snippet from recordInitialvalues:

ocmd = obj_new('IDLitCommand', $
               target_identifier=targets[i]->getFullIdentifier())

ydata = targets[i]->getParameter('Y')
result = ydata->getData(y)
result = ocmd->addItem('INITIAL_Y', y)

oCmdSet->add, ocmd

recordFinalValues does the same thing, but names the item 'FINAL_Y'. The undoOperation and redoOperation methods simply use this information to set the data of the Y parameter back to the stored value.

Registering the operation

Creating the iTool and registering the operation is straightforward. It is necessary to register the operation so that the tool knows about it. It is possible to globally register the operation, but we will register it with a single iTool in our example. Use itGetCurrent to find the object reference for the iTool and IDLitTool::registerOperation to register the operation. This is done in MGITOPDERIVATIVE_DEMO:

iplot, x, y
id = itGetCurrent(tool=otool)
otool->registerOperation, 'Derivative', 'mgitopderivative', $
                          identifier='Operations/Derivative'