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"](http://michaelgalloy.com/2006/05/01/creating-an-itool-data-operation.html) 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`](http://michaelgalloy.com/demos/itools/mgitopderivative__define.pro) ([doc](http://michaelgalloy.com/demos/itools/mgitopderivative__define.html)

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

[`MGitOpDerivative_demo.pro`](http://michaelgalloy.com/demos/itools/mgitopderivative_demo.pro) ([doc](http://michaelgalloy.com/demos/itools/mgitopderivative_demo.html))

: 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'