|
- Once the deprecation period is over, all the code (source, init) will be removed and info added to the Registry of removed names.
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | | <-- END OF COMMENT BOX CODE -->
| |
> > |
- Task Preferences panel (updated to HIPE 13):
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task Preferences panel" date="1337345737" name="TaskPreferences.png" path="TaskPreferences.png" size="22878" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="a task showing its outline" date="1337345957" name="TaskOutline.png" path="TaskOutline.png" size="27868" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Script for Google Analytics" date="1350658115" name="GoogleAnalytics.txt" path="GoogleAnalytics.txt" size="549" user="Main.DavideRizzo" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 1)" date="1336469922" name="asciiTableReader_basic.png" path="asciiTableReader_basic.png" size="11957" user="Main.JavierDiaz" version="1" |
| |
> > |
META FILEATTACHMENT |
attachment="Screen_Shot_2014-02-18_at_13.48.36.png" attr="" comment="Task Preferences panel (updated to HIPE 13)" date="1392727592" name="Screen_Shot_2014-02-18_at_13.48.36.png" path="Screen Shot 2014-02-18 at 13.48.36.png" size="57185" stream="Screen Shot 2014-02-18 at 13.48.36.png" user="Main.AlvarGarcia" version="1" |
| |
META TOPICMOVED |
by="DavideRizzo" date="1272527701" from="Hcss.DpHipeTools" to="Public.DpHipeTools" |
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
- How you can make HIPE aware of an existing Task.
- How your task can react better to an active data element.
- The default task dialogue window.
| |
< < |
- How you can implement and contribute a specific parameter editor
- How to deprecate tasks and task parameters
| > > |
- How you can implement and contribute a specific parameter editor.
- How to deprecate tasks and task parameters.
| |
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
- Also, if you want to tweak a (registered) modifier (using a specific constructor, for example) or add listeners between them (to update one when another is updated, for example) you will also have to use
Task.getCustomModifiers()
- While you can always write
SomeTask(param = null) on the command line, using a task dialog you will just get SomeTask() : modifiers use null to signify that they have no value and task GUI command generation interprets this as "not using this parameter".
- Modifiers have no notion of the optionality of parameters (or default values): if they have a valid value, they will return it. Task command generation for GUIs will not generate a parameter assignment if the value equals the default. See Task Preferences to change this default behaviour.
| |
< < |
- Modifiers will mark as erroneous any variables incompatible with the type (dynamically) and validator, but will neither reject nor remove any variable dropped
| > > |
- Modifiers will mark as erroneous any variables incompatible with the type (dynamically) and validator, but will neither reject nor remove any variable dropped.
- Only instances of
JDefaultModifier (the default modifier) will listen to VariablesUpdatedEvent (object state been modified) by default. This behaviour can be controlled with the new method setListenUpdates of AbstractModifier . This is useful if you have specific modifiers whose validators check state (for example simpleFitsWriter 's table parameter requires a non-empty table).
| |
- If you want your parameter to support dropping a set of variables (multiple selection in Variables View) your parameter must be of type
java.util.List (or Object ). [Note that list or Pylist will not work: this may be obsolete since Jython 2.5?]
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
The rules for providing JythonConverters are: | |
< < |
- The type that needs the converter should define it (in the same module)
- If the module where the type is defined (for example JDK types) cannot import share_interpreter (where
JythonConverter is defined) then, by default, it should be share_interpreter itself the one that defines the converter.
- A converter cannot be overwritten (but one can be registered for a subclass). This prevents that some client module can break the converters.
| > > |
- The type that needs the converter should define it (in the same module) if possible. Alternatively, the type can implement
__repr__ (importing Jython).
- If the module where the type is defined cannot import share_interpreter (where
JythonConverter is defined) then, by default, it should be share_interpreter (or the "next" module "above" share_interpreter that already imports the type) the one that defines the converter.
- A converter cannot be overwritten (but one can be registered for a subclass). This prevents that some client module can break more "basic" converters.
| |
- Extend
AbstractJythonConverter instead of implementing directly the JythonConverter interface.
- Your converter should call other converters for its elements (rather than doing it itself).
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
- Implement a
JythonConverter
- Register it
| |
> > | The rules for providing JythonConverters are:
- The type that needs the converter should define it (in the same module)
- If the module where the type is defined (for example JDK types) cannot import share_interpreter (where
JythonConverter is defined) then, by default, it should be share_interpreter itself the one that defines the converter.
- A converter cannot be overwritten (but one can be registered for a subclass). This prevents that some client module can break the converters.
- Extend
AbstractJythonConverter instead of implementing directly the JythonConverter interface.
- Your converter should call other converters for its elements (rather than doing it itself).
| |
// Java
JythonConverter<MyType> myConverter = new AbstractJythonConverter<MyType>() {
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | | value = val;
} | |
< < | // this should return a PyString that when executed in Jython creates or gives access to an object like this one
// in this case we construct a new WithRepr (check the use of escape for embedded strings) | > > | // This should return a PyString that when executed in Jython creates or gives access to an object like this one
// in this case we will construct a new WithRepr object
// Check the use of JythonConverters to deal with the constituent types
// in this case a String, so that it is properly escaped, delimited ...
// Note that this method implementation will not work with subclasses of this one, subclasses would have to override it
// solving this here also for subclasses would require that they agree on some common way of creating-accessing instances (constructors, a factory ...) | | public PyString __repr__() { | |
< < | return new PyString("WithRepr(\"" + StringUtil.escape(value, "\"\\") +"\")"); | > > | return new PyString("WithRepr(" + JythonConverters.convert(value) + ")"); | | }
// Typically for human consumption, so this cannot be properly parsed by Jython |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
* To fully support editing modifiers, that is, task parameter GUI elements that allow to generate-edit values (vs just pass variables) full support for generating Jython values must be provided. Most basic and usual types are supported but if this is not the case then you need to provide a Jython converter that supports your type.
* The mechanism for showing defaults does not rely on toString() working for all types, so it generates safe Jython to avoid unwanted errors. | |
< < | * For composite types (arrays, collections ...), the system may fall back to using toString for the elements which may produce a bad default string. In this case, you have to provide a Jython Converter for the element type. | > > |
- For composite types (arrays, collections ...), the system may fall back to using toString for the elements which may produce a bad default string. In this case, you have to provide a proper
__repr__ or a Jython Converter for the element type.
| |
Defining Jython converters
| |
< < | If the type of parameter you use does not have a good way to be written as valid Jython code (it falls back to using toString() on the value from the selection) you may need to register a JythonConverter . | > > | If the type of parameter you use does not have a good way to be written as valid Jython code (it does not implement __repr__ and it falls back to using toString() on the value from the selection) you may need to register a JythonConverter . | | For example, you have a parameter of type X and a modifier for X that has an editor. If you edit the value, when you press Accept the framework will try to generate a Jython string expression that creates that value to be assigned to the parameter in the task call. | |
< < | If there is no JythonConverter for class X or x.toString() does not generate a valid (syntactically or type-wise) Jython expression, the generated command will not execute due to syntax errors or incompatibility with the type the parameter expects.
In many cases, you can define a parameter of a simple type (Object or List) and do the conversion yourself to the proper type in the execute of your method. | > > | If there is no JythonConverter for class X, nor does it define __repr__ and x.toString() does not generate a valid (syntactically or type-wise) Jython expression, the generated command will not execute due to syntax errors or incompatibility with the type the parameter expects.
In many cases, you can define a parameter of a simple type (Object or List) and do the conversion yourself to the proper type in the execute of your method. In others, you can just add a public PyString __repr__() method to the class. For example:
// Java
public class WithRepr {
String value;
public WithRepr(String val) {
value = val;
}
// this should return a PyString that when executed in Jython creates or gives access to an object like this one
// in this case we construct a new WithRepr (check the use of escape for embedded strings)
public PyString __repr__() {
return new PyString("WithRepr(\"" + StringUtil.escape(value, "\"\\") +"\")");
}
// Typically for human consumption, so this cannot be properly parsed by Jython
@Override
public String toString() {
return value;
}
}
| |
So, if your task has a parameter with an editable (that generates values, vs only using already defined variables) modifier the system may not generate the expected values for this type from the modifier. If that is the case, then the module that defines the type (class) of the modifier can:
- Implement a
JythonConverter
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
* To fully support editing modifiers, that is, task parameter GUI elements that allow to generate-edit values (vs just pass variables) full support for generating Jython values must be provided. Most basic and usual types are supported but if this is not the case then you need to provide a Jython converter that supports your type.
* The mechanism for showing defaults does not rely on toString() working for all types, so it generates safe Jython to avoid unwanted errors. | |
> > | * For composite types (arrays, collections ...), the system may fall back to using toString for the elements which may produce a bad default string. In this case, you have to provide a Jython Converter for the element type. | |
Defining Jython converters |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | | If no specific modifier fits your task parameter, the default modifier will be used. The default modifier only has a dot to drop variables. Others modifiers include an editor at the right of the dot to enter values. You can implement a custom Modifier and register it in the system to be used whenever a parameter of the registered type is used. You can also write your specific Modifier for any of the already registered types. In that case, you can create and assign your modifier (and listeners ....) to your parameter in Task.getCustomModifiers() see Registering a modifier.
NOTE: | |
< < |
NOTE: | | The following behaviours and limitations are present in the provided modifiers:
- Not all modifiers are registered: for example if your parameter is of type String but will represent a file (path) the system will choose just a
JStringModifier , so you will have to explicitly associate your parameter (name) to a JFilePathModifier- in Task.getCustomModifiers() .
| |
< < | * Also, if you want to tweak a (registered) modifier (using a specific constructor, for example) you will also have to use Task.getCustomModifiers() | > > |
- Also, if you want to tweak a (registered) modifier (using a specific constructor, for example) or add listeners between them (to update one when another is updated, for example) you will also have to use
Task.getCustomModifiers()
| |
- While you can always write
SomeTask(param = null) on the command line, using a task dialog you will just get SomeTask() : modifiers use null to signify that they have no value and task GUI command generation interprets this as "not using this parameter".
- Modifiers have no notion of the optionality of parameters (or default values): if they have a valid value, they will return it. Task command generation for GUIs will not generate a parameter assignment if the value equals the default. See Task Preferences to change this default behaviour.
- Modifiers will mark as erroneous any variables incompatible with the type (dynamically) and validator, but will neither reject nor remove any variable dropped
| |
Signature components | |
< < | TODO: REVIEW | |
In case the default input area based on modifiers does not fit your needs, you can replace it by your own implementation, and register it so that the system opens the task dialog with your custom TaskSignatureComponent . The following sections show you how this is done. | |
You can create a TaskSignatureComponent by extending JTaskSignatureComponent in the ia.task.gui.dialog package, and providing your own implementation of the makeModifierMap() method. | |
> > | Also if you want to also do your own layout you can extend ==AdbtractTaskSignatureComponent. | |
The JTaskSignatureComponent class implements the TaskSignatureComponent interface, which consists of four explicit contracts:
- Support the
setVariableSelection for initial assignment from the Tool Window
| |
- Deriving from
JComponent
- If registered in the Extension Registry, providing an empty constructor
| |
> > | And, as a signature component acts as a container of modifiers, if you directly implement TaskSignatureComponent , you must also implement Disposable (to clean the modifiers when your task GUI is closed):
- implement
dispose() calling dispose on all your Modifiers that implement Disposable .
| | Conventions for labels for input parameters: to construct the labels of your parameters you can use the static function of class JTaskSignatureComponent public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) it provides a decorated label (including tooltip) that follows the standard style. For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) if present.
For example, if you want to use a custom Signature Component that just wants to use JFilePathModifier for a parameter aimed for a file name, you could do it like this: | | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| |
> > | And, as a Task Panel acts as a container of modifiers (via a TaskSignatureComponent ), if you directly implement , you must also implement Disposable (to clean up the signature when your task GUI is closed and to clean the viewer you are shown in):
@Override
public void dispose() {
if (_component instanceof Disposable) { //_ component is a TaskSignatureComponent
((Disposable) _component).dispose();
}
}
| | |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
 | |
> > | Sample code in Java and Jython :
// Jython
from herschel.ia.task import ParameterGroups, Group
def getGroups(self):
return ParameterGroups(self, [
Group("Pool", "Export a pool", ["input"]),
Group("Observations", "Export Observations to HSA Directory format", ["input2"])])
// Java
@Override
public ParameterGroups getGroups() {
Group g1 = new Group("Basic", "Basic interface for simple table data", FILE, TABLE_TYPE,
PARSER_SKIP);
Group g2 = new Group("Advanced", "Comprehensive interface for complex table data",
ADVANCED_NAMES);
return new ParameterGroups(this, g1, g2);
}
| |
This automatic layout may not suit your task for several reasons:
- A parameter may need several input fields (see for instance the
angle parameter of the rotate task, in the figure below).
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | | class ComputeTask extends Task {
ComputeTask() {
super("compute"); | |
< < | prime = new TaskParameter("spectrum", SpecificProduct.class)
:
getSignature().setPrimeInput(prime) | > > | prime = new TaskParameter("spectrum", SpecificProduct.class);
addTaskParameter(prime);
getSignature().setPrimeInput(prime); | | }
}
|
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
| |
> > | Laying out your task with one parameter per row (narrow GUI)
We provide a Task Signature Component that uses one parameter per row (for narrow panels). You just need to register that your task uses this signature component instead of the default one:
#1-column layout
REGISTRY.register(COMPONENT,Extension(
"OpenVariableTask Signature",
"herschel.ia.task.gui.dialog.JTaskSignatureComponentNarrow",
"factory.editor.tool.task.signature",
"herschel.ia.toolbox.util.OpenVariableTask"))
| |
Custom Task Dialogs
Eventually, if the above options still do not accommodate your needs you can replace the the default Task Panel with your own implementation |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
For your task to appear in the Applicable category whenever the user selects a suitable variable, you still need to define a Validator. See Validating prime input below. | |
< < | Tasks without at least an input cannot be registered and should not be used (create a parameterless function instead). | > > | Tasks without any input cannot be registered and should not be used (create a parameterless function instead). | |
Tasks Naming Conventions | | If no specific modifier fits your task parameter, the default modifier will be used. The default modifier only has a dot to drop variables. Others modifiers include an editor at the right of the dot to enter values. You can implement a custom Modifier and register it in the system to be used whenever a parameter of the registered type is used. You can also write your specific Modifier for any of the already registered types. In that case, you can create and assign your modifier (and listeners ....) to your parameter in Task.getCustomModifiers() see Registering a modifier.
NOTE: | |
> > |
NOTE: | | The following behaviours and limitations are present in the provided modifiers:
- Not all modifiers are registered: for example if your parameter is of type String but will represent a file (path) the system will choose just a
JStringModifier , so you will have to explicitly associate your parameter (name) to a JFilePathModifier- in Task.getCustomModifiers() . * Also, if you want to tweak a (registered) modifier (using a specific constructor, for example) you will also have to use Task.getCustomModifiers()
| |
< < |
- While you can always write
SomeTask(param = null) on the command line, using a task dialog you will just get SomeTask() : modifiers use null to signify that they have no value and task command generation interprets this as "not using this parameter".
- Modifiers have no notion of the optionality of parameters: if they have a valid value, they will return it. Task command generation for GUIs will not generate a parameter assignment if the value equals the default. See Task Preferences to change this default behaviour.
- Modifiers will mark as erroneous any variables incompatible with the type (dynamically), but will accept not reject dropping it in the dot.
- If you want your parameter to support dropping a set of variables (multiple selection in Variables View) your parameter must be of type
java.util.List (or Object ). [Note that list or Pylist will not work]
- Modifiers have no notion of default values. This implies that there is no way to know what command will be generated seeing a GUI unleSee the next section
| > > |
- While you can always write
SomeTask(param = null) on the command line, using a task dialog you will just get SomeTask() : modifiers use null to signify that they have no value and task GUI command generation interprets this as "not using this parameter".
- Modifiers have no notion of the optionality of parameters (or default values): if they have a valid value, they will return it. Task command generation for GUIs will not generate a parameter assignment if the value equals the default. See Task Preferences to change this default behaviour.
- Modifiers will mark as erroneous any variables incompatible with the type (dynamically) and validator, but will neither reject nor remove any variable dropped
- If you want your parameter to support dropping a set of variables (multiple selection in Variables View) your parameter must be of type
java.util.List (or Object ). [Note that list or Pylist will not work: this may be obsolete since Jython 2.5?]
| |
Showing default values |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | | A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, use TaskParameter.TRUE_VALIDATOR . There are also support classes for writing common validators: AnyOfValidator , InstanceOfValidator , PredicateValidator , RangeValidator , RegexValidator in package ia.gui.apps.validator .
Please, do not implement ParameterValidator interface directly as it will block extension of it: use ParameterValidatorAdapter (that also detects some validation problems). Note that your validators must be fast, self-contained (with no visible side effects) and not use I/O : they are called frequently and from multiple threads, including the EDT in the case of GUI validation. | |
> > | Avoiding Applicability
You can veto appearing in Applicable in Tasks View by overriding Task.canBeApplicable() to return false. This applies, for example, to tasks whose primary input is a number or a String (and they have/need validators). | |
Task dialogue windows |
|
META TOPICPARENT |
name="WritingTasks" |
<-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END --> | |
In most cases, the type of the prime input is not enough to determine whether a task is applicable to a variable. Your task may only run on a SpecificProduct if it has certain contents: a typical example is a SPIRE task operating on an ObservationContext: clearly, such task should not be listed when a HIFI observation is selected. | |
< < | This is why you must write a ParameterValidator to restrict a task to certain product contents: | > > | This is why you must write a ParameterValidator (extend ParameterValidatorAdapter ) to restrict a task to certain product contents: | |
// Java
prime = new TaskParameter("spectrum", SpecificProduct.class)
| |
Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm. | |
< < | A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, write a dummy validator that always accepts input values (or use TaskParameter.TRUE_VALIDATOR ). | > > | A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, use TaskParameter.TRUE_VALIDATOR . There are also support classes for writing common validators: AnyOfValidator , InstanceOfValidator , PredicateValidator , RangeValidator , RegexValidator in package ia.gui.apps.validator .
Please, do not implement ParameterValidator interface directly as it will block extension of it: use ParameterValidatorAdapter (that also detects some validation problems). Note that your validators must be fast, self-contained (with no visible side effects) and not use I/O : they are called frequently and from multiple threads, including the EDT in the case of GUI validation. | |
Task dialogue windows | | <-- END OF COMMENT BOX CODE -->
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1254239744" name="crop.png" path="crop.png" size="14045" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Script for Google Analytics" date="1350658115" name="GoogleAnalytics.txt" path="GoogleAnalytics.txt" size="549" user="Main.DavideRizzo" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 1)" date="1336469922" name="asciiTableReader_basic.png" path="asciiTableReader_basic.png" size="11957" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop input updated to the new look of tasks" date="1275479674" name="crop_input_new.png" path="crop_input_new.png" size="14159" user="Main.JavierDiaz" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task Preferences panel" date="1337345737" name="TaskPreferences.png" path="TaskPreferences.png" size="22878" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop input updated to the new look of tasks" date="1275479674" name="crop_input_new.png" path="crop_input_new.png" size="14159" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 2)" date="1336469944" name="asciiTableReader_Advanced.png" path="asciiTableReader_Advanced.png" size="21471" user="Main.JavierDiaz" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="a task showing its outline" date="1337345957" name="TaskOutline.png" path="TaskOutline.png" size="27868" user="Main.JavierDiaz" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1254239744" name="crop.png" path="crop.png" size="14045" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop modifier updated to the new look of tasks" date="1275479639" name="crop_modifier_new.png" path="crop_modifier_new.png" size="14021" user="Main.JavierDiaz" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop updated to the new look of tasks" date="1275479736" name="crop_new.png" path="crop_new.png" size="14211" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop with closed sections updated to the new look of tasks" date="1275479716" name="crop_closed.png" path="crop_closed.png" size="8289" user="Main.JavierDiaz" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task Preferences panel" date="1337345737" name="TaskPreferences.png" path="TaskPreferences.png" size="22878" user="Main.JavierDiaz" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop updated to the new look of tasks" date="1275479736" name="crop_new.png" path="crop_new.png" size="14211" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="a task showing its outline" date="1337345957" name="TaskOutline.png" path="TaskOutline.png" size="27868" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Script for Google Analytics" date="1350658115" name="GoogleAnalytics.txt" path="GoogleAnalytics.txt" size="549" user="Main.DavideRizzo" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 1)" date="1336469922" name="asciiTableReader_basic.png" path="asciiTableReader_basic.png" size="11957" user="Main.JavierDiaz" version="1" |
| |
META TOPICMOVED |
by="DavideRizzo" date="1272527701" from="Hcss.DpHipeTools" to="Public.DpHipeTools" |
|
|
META TOPICPARENT |
name="WritingTasks" |
| |
> > | <-- ANALYTICS CODE - DO NOT EDIT -->
<-- Google Analytics script BEGIN -->
<-- Google Analytics script END -->
<-- END OF ANALYTICS CODE --> | | <--
- Set TOPICTITLE = Adding tools to HIPE
--> | | <-- END OF COMMENT BOX CODE -->
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop with closed sections updated to the new look of tasks" date="1275479716" name="crop_closed.png" path="crop_closed.png" size="8289" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="a task showing its outline" date="1337345957" name="TaskOutline.png" path="TaskOutline.png" size="27868" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop updated to the new look of tasks" date="1275479736" name="crop_new.png" path="crop_new.png" size="14211" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task Preferences panel" date="1337345737" name="TaskPreferences.png" path="TaskPreferences.png" size="22878" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1254239744" name="crop.png" path="crop.png" size="14045" user="Main.JaimeSaiz" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Script for Google Analytics" date="1350658115" name="GoogleAnalytics.txt" path="GoogleAnalytics.txt" size="549" user="Main.DavideRizzo" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop modifier updated to the new look of tasks" date="1275479639" name="crop_modifier_new.png" path="crop_modifier_new.png" size="14021" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop input updated to the new look of tasks" date="1275479674" name="crop_input_new.png" path="crop_input_new.png" size="14159" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 2)" date="1336469944" name="asciiTableReader_Advanced.png" path="asciiTableReader_Advanced.png" size="21471" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 1)" date="1336469922" name="asciiTableReader_basic.png" path="asciiTableReader_basic.png" size="11957" user="Main.JavierDiaz" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop input updated to the new look of tasks" date="1275479674" name="crop_input_new.png" path="crop_input_new.png" size="14159" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task dialogs with groups (group 2)" date="1336469944" name="asciiTableReader_Advanced.png" path="asciiTableReader_Advanced.png" size="21471" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="a task showing its outline" date="1337345957" name="TaskOutline.png" path="TaskOutline.png" size="27868" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop modifier updated to the new look of tasks" date="1275479639" name="crop_modifier_new.png" path="crop_modifier_new.png" size="14021" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop updated to the new look of tasks" date="1275479736" name="crop_new.png" path="crop_new.png" size="14211" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop with closed sections updated to the new look of tasks" date="1275479716" name="crop_closed.png" path="crop_closed.png" size="8289" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Task Preferences panel" date="1337345737" name="TaskPreferences.png" path="TaskPreferences.png" size="22878" user="Main.JavierDiaz" version="1" |
| |
META TOPICMOVED |
by="DavideRizzo" date="1272527701" from="Hcss.DpHipeTools" to="Public.DpHipeTools" |
|
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
|
META TOPICPARENT |
name="WritingTasks" |
| |
< < | Adding Tools to HIPE | > > | <--
- Set TOPICTITLE = Adding tools to HIPE
-->
Did you spot something wrong or missing on this page? If you have an account on this TWiki, you can fix it yourself by editing the page. If you don't have an account, you can send a message to the Editorial Board to tell us about it. Thank you in advance!
Adding tools to HIPE | |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | |
| |
< < | Simple sample | > > | Example | | This simple reproducible example wraps up the just explained steps altogether.
It is just a button whose label is changed by the tool when the user clicks on it: | |
public class SimpleButtonTool extends AbstractTool {
| |
< < | private ArrayData _data; | > > | private ArrayData _data = null; | | private boolean _flag = true;
public SimpleButtonTool() { | | }
void updateLabel(JButton button) { | |
> > | boolean hasData = _data = null;
button.setEnabled(hasData);
if (hasData) { | | int size = _data.getSize();
int rank = _data.getRank();
button.setText("Data has " + (_flag? "size " + size : "rank " + rank));
_flag = _flag; | |
> > | } else {
button.setText("No data selected");
} | | }
}
| | private static int _counter = 1;
private SimpleButtonTool _tool; | |
< < | public SimpleButtonToolComponent() {
super(new BorderLayout());
}
protected Class getSelectionType() { | > > | protected Class<ToolSelection> getSelectionType() { | | return ToolSelection.class;
}
protected boolean makeEditorContent() {
final JButton button = new JButton();
setName("Button Tool " + _counter++); | |
< < | _tool = (SimpleButtonTool)getSelection().getTool();
_tool.setData((ArrayData)getSelection().getSelection().getValue()); | > > | ToolSelection toolSelection = getSelection();
_tool = (SimpleButtonTool)toolSelection.getTool();
Selection selection = toolSelection.getSelection();
if (selection = null) {
_tool.setData((ArrayData)selection.getValue());
} | | _tool.updateLabel(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | |
Conventions for labels for input parameters: to construct the labels of your parameters you can use the static function of class JTaskSignatureComponent public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) it provides a decorated label (including tooltip) that follows the standard style. For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) if present. | |
< < | For example, if you want to use a custom Signature Component that just wants to use ia.gui.apps.modifier.JFilePathModifier for a parameter aimed for a file name, you could do it like this: | > > | For example, if you want to use a custom Signature Component that just wants to use JFilePathModifier for a parameter aimed for a file name, you could do it like this: | |
public class MySignatureComponent extends JTaskSignatureComponent {
| |
- Assign the Task to display ( the setTask)
- Notify request of executions to the framework by
- Allow for setting the Site Event handler for notifying request of execution (the setSiteEventHandler method)
| |
< < |
-
- Notify the execution requests calling the trigger method of ia.gui.kernel.SiteEventHandler passing a ia.gui.kernel.event.CommandExecutionRequestEvent.
You can create this event through the ia.task.gui.dialog.TaskCommandExecutionEventFactory.
| > > |
-
- Notify the execution requests calling the trigger method of
herschel.ia.gui.kernel.SiteEventHandler passing a herschel.ia.gui.kernel.event.CommandExecutionRequestEvent . You can create this event through the herschel.ia.task.gui.dialog.TaskCommandExecutionEventFactory .
| |
- Return the
javax.swing.Actions for running the task and resetting (clear) the signature (the actions that are invoked when pressing "Accept" and "Clear" buttons, if present), to allow to execute them from the toolbar of HIPE. The simplest implementation would be to create and assign those actions to your buttons in your setTask(TaskApi) method and then to return them from the buttons when asked:
public Action getRunAction() {
| | If you have an existing task and want to make it available in HIPE, you just need to follow the steps described in the above section.
Now, a task has its limitations. It is somewhat an atomic operation for which you provide some inputs and expect some result. | |
< < | Therefore, it is not expected for acting interactively with a user, and it is not meant for holding internal status either, that a user can modify during its execution. | > > | Therefore, it is not expected for acting interactively with a user, and it is not meant for holding internal state either, that a user can modify during its execution. | |
If you need more flexibility, you can write your own implementation of the Tool interface.
Besides, you would most probably need a viewer associated to your tool, for letting the user interact with it. | | List<? extends Parameter> inputs,
Category... categories)
| |
< < | You provide the variable types you are interested in within the prime input: just return a ia.gui.kernel.ToolParameter initiated with the proper class of data you want to handle: | > > | You provide the variable types you are interested in within the prime input: just return a herschel.ia.gui.kernel.ToolParameter initiated with the proper class of data you want to handle: | |
new ToolParameter("data", MyTargetDataType.class)
| | More conditions for checking whether the tool can react on a particular variable can be added by providing a ParameterValidator to the prime input.
The actual job to be done can be delegated to a third object (the "tool object"), or just be executed by the tool class itself. | |
< < | This latter case is the default, otherwise, you need to call setToolObject(Object toolObject) in your constructor. | > > | This latter case is the default; otherwise, you need to call setToolObject(Object toolObject) in your constructor. | |
Moreover, you may return the categories you think the tool is meaningful for, by providing the proper ones in the super call. | |
Tool Viewer | |
< < | Every tool has an associated viewer, which must implement ia.gui.kernel.parts.EditorComponent (by extending ia.gui.kernel.parts.AbstractEditorComponent or one of its subclasses). | > > | Every tool has an associated viewer, which must implement EditorComponent (by extending AbstractEditorComponent or one of its subclasses). | |
Tool Registry
Once you have your tool and the corresponding viewer, you need to register them like this: |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | |
Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm. | |
< < | A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, write a dummy validator that always accepts input values. | > > | A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, write a dummy validator that always accepts input values (or use TaskParameter.TRUE_VALIDATOR ). | |
Task dialogue windows |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | p.parameterValidator = MyVal()
| |
> > | Also, a prebuilt confirming (always returns true) Validator is available in TaskParameter :
parameter.setParameterValidator(TaskParameter.TRUE_VALIDATOR);
| | Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm.
A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, write a dummy validator that always accepts input values. |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | }
});
| |
> > | In Jython, your can define your own ParameterValidatorAdapter classes, although we suggest that you use Java validator classes:
from herschel.ia.gui.kernel import ParameterValidatorAdapter, ParameterValidationException
class MyVal(ParameterValidatorAdapter):
def validate(self, val):
if (val < 0 or val > 10):
raise ParameterValidationException("Bad value " + str(val) + ", must be between 0 and 10")
And you can assign instances to your parameters
p.parameterValidator = MyVal()
| |
Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm. |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | For naming tasks follow the Java conventions, that is, use camelCase and avoid underscores: reduceLight is valid, reduce_light is not. HIPE displays info log messages for invalid task names. Note that task names are used as variable names (of type Task ) automatically created when starting HIPE.
| |
> > | | | Validating prime input
In most cases, the type of the prime input is not enough to determine whether a task is applicable to a variable. Your task may only run on a SpecificProduct if it contains certain contents: a typical example is a SPIRE task operating on an ObservationContext: clearly, such task should not be listed when a HIFI observation is selected. |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | toolRegistry.register(compute, [Category.IMAGE, Category.PACS]))
| |
< < | Your task is now enabled whenever the users selects a session variable of the same type as the first input parameter of your task. | | To define the prime parameter, modify your task constructor as follows:
class ComputeTask extends Task {
| | }
| |
> > | For your task to appear in the Applicable category whenever the user selects a suitable variable, you still need to define a Validator. See Validating prime input below. | | Tasks Naming Conventions
Tasks registered in HIPE should follow the naming conventions shown in this example: | |
Validating prime input
| |
< < | If you followed the instructions in the previous section, your task now appears in the Applicable category of the Tasks view whenever a variable of the same type as the prime input is selected. | > > | In most cases, the type of the prime input is not enough to determine whether a task is applicable to a variable. Your task may only run on a SpecificProduct if it contains certain contents: a typical example is a SPIRE task operating on an ObservationContext: clearly, such task should not be listed when a HIFI observation is selected. | | | |
< < | Sometimes this may not be enough. Your task may only run on a SpecificProduct if it contains certain contents: a typical example is a SPIRE task operating on an ObservationContext: clearly, such task should not be listed when a HIFI observation is selected.
To restrict a task to certain product contents, write a ParameterValidator : | > > | This is why you must write a ParameterValidator to restrict a task to certain product contents: | |
prime = new TaskParameter("spectrum", SpecificProduct.class)
prime.setParameterValidator(new ParameterValidatorAdapter() {
| |
Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm. | |
> > |
A validator is mandatory for the task to appear in the Applicable category of the Tasks view. If your task really is very general and applies to a given variable type with no exceptions, write a dummy validator that always accepts input values. | |
Task dialogue windows |
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | }
| |
> > | Tasks Naming Conventions | | Tasks registered in HIPE should follow the naming conventions shown in this example:
- Name of the class:
ReduceTask
- Name of the task (given by
getName() ): reduce
|
|
META TOPICPARENT |
name="WritingTasks" |
Adding Tools to HIPE | | <-- summary -->
Tools are processing units that operate on specific data elements.
From the Java point of view, a tool is an implementation of the Tool interface. | |
< < | Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hood. | > > | Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hood. See the topic on WritingTasks for details. | |
If a data element is selected, a list of tools that can operate on that element should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialogue window for settings parameters (for task tools). |
|
< < |
META TOPICPARENT |
name="DpHipe" |
| > > |
META TOPICPARENT |
name="WritingTasks" |
| | Adding Tools to HIPE
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- Register your task properly
- Prefer strings to enums (harder to write without autocomplete) for textual invocation
- Use validators to restrict applicability
| |
< < |
-
| > > |
- (Addition for usability) Progress indicators
| |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- Check the generated information in the URM
- Provide reproductible (even if not complete) examples
- Try to provide alternative documentation to jtags in Javadoc
| |
> > |
- Register your task in the proper categories
| |
-
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
< < | | |
 | | <-- summary -->
Tools are processing units that operate on specific data elements.
From the Java point of view, a tool is an implementation of the Tool interface. | |
< < | The well-known Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hood. | > > | Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hood. | | | |
< < | If a data element is selected, a list of tools that can operate on that data should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialog for settings parameters (for task tools). | > > | If a data element is selected, a list of tools that can operate on that element should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialogue window for settings parameters (for task tools). | | | |
< < | This section explains:
- how you can create a Tool and register it for being available for dedicated data
- how you can make HIPE aware of an existing Task,
- how your task can react better on an active data element,
- the default task dialog and how you implement and contribute a dedicated input dialog for your task,
- how you can implement and contribute a specific parameter editor
| > > | This section explains the following:
- How you can create a tool and register it, so that it becomes available for specific data.
- How you can make HIPE aware of an existing Task.
- How your task can react better to an active data element.
- The default task dialogue window.
- How you can implement and contribute a specific parameter editor
| | | |
< < | | |
| |
< < |
Adding a Tool as a Task | > > | Adding a task as a HIPE tool | | | |
< < | Task Registry | > > | Registering tasks | | | |
< < | Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.: | > > | You can made you task globally available to the system by specifying an instance of that task within a Jython file (usually called __init__.py for HIPE internal modules) that is read by HIPE at startup (see My first Java HIPE task). For example: | |
# __init__.py file
compute = ComputeTask()
| |
< < | To make your task appear in the "Tasks" view, you need to add the following lines: | > > | To make your task appear in the Tasks view, you need to add the following lines to the Jython file: | |
from herschel.ia.task.views import TaskToolRegistry
toolRegistry = TaskToolRegistry.getInstance()
toolRegistry.register(compute)
| |
< < | For PACS users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | | You can also specify that your task belongs to one or more Category :
from herschel.ia.gui.kernel.Tool import Category
toolRegistry.register(compute, [Category.IMAGE, Category.PACS]))
| |
< < | Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task! | | | |
< < | Within your task, you can control which parameter signs-up to be the prime parameter (the one which reacts on a selected data variable) by the Task API: | > > | Your task is now enabled whenever the users selects a session variable of the same type as the first input parameter of your task.
To define the prime parameter, modify your task constructor as follows: | |
class ComputeTask extends Task {
ComputeTask() {
| | }
| |
< < | Naming conventions for task when to be registered in HIPE should follow this example assuming that the task will perform the functionality named "reduce" :
Name of the Class : ReduceTask
Name of the Task (getName()) : reduce
Name of the variable in Jython : reduce
| > > | Tasks registered in HIPE should follow the naming conventions shown in this example:
- Name of the class:
ReduceTask
- Name of the task (given by
getName() ): reduce
- Name of the task variable in Jython:
reduce
| | | |
< < | For naming tasks we follow the Java conventions, we use camel-case , not underscores : "reduceLight" is valid, "reduce_light" is not. Info log messages are produced for invalid task names. Note that the task names are used as variable names (of type task) automatically created when starting HIPE. | > > | For naming tasks follow the Java conventions, that is, use camelCase and avoid underscores: reduceLight is valid, reduce_light is not. HIPE displays info log messages for invalid task names. Note that task names are used as variable names (of type Task ) automatically created when starting HIPE. | | | |
< < | Prime input validation | > > | Validating prime input | | | |
< < | The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | > > | If you followed the instructions in the previous section, your task now appears in the Applicable category of the Tasks view whenever a variable of the same type as the prime input is selected. | | | |
< < | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on an ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | > > | Sometimes this may not be enough. Your task may only run on a SpecificProduct if it contains certain contents: a typical example is a SPIRE task operating on an ObservationContext: clearly, such task should not be listed when a HIFI observation is selected. | | | |
< < | You can write a ParameterValidator to do just that: | > > | To restrict a task to certain product contents, write a ParameterValidator : | |
prime = new TaskParameter("spectrum", SpecificProduct.class)
prime.setParameterValidator(new ParameterValidatorAdapter() {
public void validate(Object value) throws ParameterValidationException {
SpecificProduct s = (SpecificProduct)value;
| |
< < | if (! (logic that would validate the contents of the value...)) {
throw new ParameterValidationException(reason); | > > | if (! ( [logic that would validate the contents of the value] )) {
throw new ParameterValidationException( [reason] ); | | }
}
});
| |
< < | In other words, rather than writing this logic within the pre-amble or execution block of your task, we recommend you to move that logic into the parameter validation. This way we achieve two things:
- make the logic appear where it should be and therefore keeping the execution block of your task concentrated to the algorithm, and
- make your task appear as a tool within HIPE that can be ran against specific data.
| > > | Note how the validation logic is now within the parameter validation block, rather than in the preamble or execution block of your task. One advantage is that the execution block of your task can concentrate on the core algorithm. | | | |
< < | Task Dialogs
Default Task Dialog | > > | Task dialogue windows | |
| |
< < | The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | > > | HIPE generates a default input dialog for all registered tasks. The dialog has three sections: Input, Output and Info, each of which can be collapsed. The following two figures show the interface of the crop task, with extended and collapsed sections: | | | |
< < | The default dialog for the crop task:
| |  | |
< < | As for instance you may want to have more control over how the input parameters are presented to the user:
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
- you may want to organize your parameters by grouping them in tabs, or putting a border around a group of parameters
- you may want to have more informative tooltips, labels or even input fields that are more suitable for your task.
A new default dialog layout has been implemented following the request of the DPUG:
It puts two parameters per line: lines are filled left to right, and then top to bottom. If you only have 1 input (or output) it will fill the whole line.
Modifiers implementors should take care that the preferred size of their modifier is smaller (about 20 chars max).
Provided modifiers have been updated but some modifiers are too wide for this layout (for instance, AngleModifier can have three texts and one combo in a line, see rotate later).
The default dialog for the crop task, with all sections opened:
| |  | |
< < | To adapt to these scenarios and more, the system provides three ways for customizing you Task dialogs:
- Parameter Modifiers
- Signature Components
- Task Panels.
| > > | Parameters are listed in two columns. HIPE lists the parameters from left to right and top to bottom. If a single input or output parameter is present, this fills a whole line. | | | |
< < | | > > | This automatic layout may not suit your task for several reasons:
- A parameter may need several input fields (see for instance the
angle parameter of the rotate task, in the figure below).
- You may only want to provide a sub-set of parameters (and leave the full set to expert users on the command line).
- You may want to organise your parameters by grouping them in tabs, or putting a border around a group of parameters.
- You may want to have more informative tooltips, labels or even input fields that are more suitable to your task.
| | | |
< < | Parameter Modifiers
The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifier objects. | > > |  | | | |
< < | The input area for the crop task:
 | > > | The following sections explore three ways to customise your task dialogue windows:
- Parameter modifiers
- Signature components
- Custom task panels
| | | |
< < | The composition of Modifier objects is created based on the types of the values of the Task Parameters of the Task Signature. | > > | | | | |
< < | The Modifier for the row1 Parameter of the crop task:
 | > > | Parameter modifiers
Each parameter field in the input area of a task dialogue window corresponds to a Modifier object. HIPE adds Modifier objects according to the types of input parameters in the task signature. | | | |
< < | Currently the system contains basic implementation for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there's still a lot of space for improvements and contribution. You can find the general available modifiers in package herschel.ia.gui.apps.modifier ; please consult the Javadoc of your HIPE installation. | > > | For instance, the crop task displays five input parameters: image , row1 , column1 , row2 , column2 : | | | |
< < | If the default parameter doesn't fit for your Task Parameter, you can:
- Implement a Modifier,
- Register it to the system.
| > > |
HIPE provides modifiers for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there is still a lot of room for improvements and contributions. You can find the general available modifiers in the herschel.ia.gui.apps.modifier package; please consult the Javadoc of your HIPE installation. | | | |
< < | Alternatively, you could want to write your specific Modifier for one of the already available types. In that case, you could create your modifier in a custom Signature Component. | > > | If no default modifier fits your task parameter, you can implement a custom Modifier and register it to the system. You can also write your specific Modifier for one of the already available types. In that case, you can create your modifier in a custom Signature Component. | |
NOTE:
The following behaviours and limitations are present in the provided modifiers: | |
< < |
- While you can always write
SomeTask(param = null) in Console, using a task dialog you will get SomeTask() : for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
| > > |
- While you can always write
SomeTask(param = null) on the command line, using a task dialog you will get SomeTask() : the task will interpret null as if the parameter has been ignored by the user.
| |
- Modifiers have no notion of the optionality of parameters: if they have a valid value, they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
| |
< < |
- Specialized modifiers:
- Will mark as errorenous variables incompatible with the type (dynamically), but will accept any variable.
| > > |
- Specialized modifiers will mark as erroneous any variables incompatible with the type (dynamically), but will accept any variable.
| | | |
< < | Implement a Modifier | > > | Implementing a modifier | | | |
< < | The ia.gui.apps.Modifier interface consists of two explicit contracts:
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
and two implicit contracts: | > > | Your modifier should extend AbstractModifier , which in turn implements the Modifier interface. Both reside in the ia.gui.apps.modifier package. The Modifier interface consists of two explicit contracts:
- Support of drag and drop features (by indirectly extending
setVariableSelection and getVariableSelection in the ia.gui.kernel package)
- Support object inspection (via the
setObject and getObject methods)
Modifiers must also honour two implicit contracts:
- Deriving from
JComponent
- If registered in the Extension Registry, providing an empty constructor
| | | |
< < | Register a Modifier | > > | Registering a modifier | | | |
< < | The registration of the Modifier is done again in the __init__.py via the Extension Registry with the usual syntax (please note the name of the factory: factory.modifier).
Be aware that the registration is system wise so the registration overrides any other registered modifier for that type. | > > | You can register your modifier via the Extension Registry with the following syntax (please note the name of the factory: factory.modifier ): | |
REGISTRY.register(COMPONENT,Extension(
| | "herschel.ia.MyClass")
| |
< < | In case the Modifier you have created is only applicable to a specific task or even to a specific parameter of a specific task, you can simply assign it to the applicable Task Parameter: | > > | Be aware that the registration is system-wise, so it overrides any other registered modifier for that type.
In case the modifier you have created is only applicable to a specific task or even to a specific parameter of a specific task, you can simply assign it to the applicable task parameter: | |
// YourTask constructor
| | ...
} | |
< < | // Customize your modifiers | > > | // Customise your modifiers | | @Override
public Map<String, Modifier> getCustomModifiers() {
Map<String, Modifier> map = new LinkedHashMap<String, Modifier>(); | | }
| |
< < | | | | |
< < | Signature Components | > > | Signature components | |
| |
< < | In case the default input area based on Modifiers doesn't fit your needs you can just replace it by your own implementation.
Rotate Alternative Signature (old):
Rotate Alternative Signature (new):
 | > > | In case the default input area based on modifiers does not fit your needs, you can replace it by your own implementation, and register it to the system. The following sections show you how this is done. | | | |
< < | If this is the case you need to:
- Implement a Task Signature Component
- Register it to the system.
Implement a Task Signature Component | > > | Implementing a task signature component | |
| |
< < | The ia.task.gui.dialog.TaskSignatureComponent interface consists of four explicit contracts: | > > | You can create a task signature component by extending JTaskSignatureComponent in the ia.task.gui.dialog package, and providing your own implementation of the makeModifierMap() method.
The JTaskSignatureComponent class implements the TaskSignatureComponent interface, which consists of four explicit contracts: | |
- Support the
setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display (
setSignature )
- Return a map of parameters and assigned values (in
Map<TaskParameter, VariableSelection> getParameters )
- Clear and check user inputs implementations (used by the default buttons)
| |
< < | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| | | |
< < | Conventions for labels for input parameters: to construct the labels of your parameters you can use the static function of class JTaskSignatureComponent public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) it provides a decorated label (including tooltip) that follows the standard style. For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) if present. | > > | Task signature components must also honour two implicit contracts:
- Deriving from
JComponent
- If registered in the Extension Registry, providing an empty constructor
| | | |
< < | An easy way of implementing TaskSignatureComponent is by extending ia.task.gui.dialog.JTaskSignatureComponent and providing your own implementation for the makeModifierMap() method. | > > | Conventions for labels for input parameters: to construct the labels of your parameters you can use the static function of class JTaskSignatureComponent public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) it provides a decorated label (including tooltip) that follows the standard style. For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) if present. | |
For example, if you want to use a custom Signature Component that just wants to use ia.gui.apps.modifier.JFilePathModifier for a parameter aimed for a file name, you could do it like this: | | }
| |
< < |
| | <-- Author: JorgoBakker - 21 Dec 2007 -->
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Task Compliance Checklist | |
< < | Developing a task that looks "native" takes time and a quite a few steps. To help you comply with all requirements, we offer a (high level) list of common deficiencies and mistakes to be taken into account. This is not a MUST comply list (yet). | > > | Developing a task that looks "native" takes time and involves quite a few steps. To help you comply with all requirements, we offer a (high level) list of common deficiencies and mistakes to be taken into account. This is not a MUST comply list (yet). | |
- Use a two column layout for the Inputs
| |
- Prefer no scrolling, then vertical to horizontal.
-
| |
< < | Points 1 to 4 are given for free if you just use the default implementation | > > | Points 1 to 4 are given for free if you just use the default implementation. So if the default implementation suits you, you will benefit from all the upgrades that the task framework gets. | |
| |
| |
< < | Above, Usage point 6 (we minimize string literals and follwo naming conventions) | > > | Above, Usage point 6 (we minimize string literals and follow naming conventions) | |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Name of the variable in Jython : reduce
| |
< < | For naming tasks we follow the Java conventions, we use camel-case , not underscores : "reduceLight" is valid, "reduce_light" is not. Info log messages are produced for invalid task names. | > > | For naming tasks we follow the Java conventions, we use camel-case , not underscores : "reduceLight" is valid, "reduce_light" is not. Info log messages are produced for invalid task names. Note that the task names are used as variable names (of type task) automatically created when starting HIPE. | |
Prime input validation | | Triggering Events
For a full detailed section about triggering events have a look at DpHipeCommonUtilities. | |
> > |
Task Compliance Checklist
Developing a task that looks "native" takes time and a quite a few steps. To help you comply with all requirements, we offer a (high level) list of common deficiencies and mistakes to be taken into account. This is not a MUST comply list (yet).
- Use a two column layout for the Inputs
- Use foldable sections for the task
- Use decorated labels (bold, asterisk ...)
- Use tooltips on the labels describing the parameters
- Use specialized modifiers
- Prefer enumerations (Combo boxes of String lists) to open ended texts
- Prefer no scrolling, then vertical to horizontal.
-
Points 1 to 4 are given for free if you just use the default implementation
- Update the progress while the task is executing (if it takes more than a second)
- Allow the task to be started and cleaned from the toolbar of HIPE
- Allow your task to be interrupted
- Provide informative error messages (in the constructor of your exceptions)
- Log important information for users to check
- Follow the naming conventions
- Register your task properly
- Prefer strings to enums (harder to write without autocomplete) for textual invocation
- Use validators to restrict applicability
-
- Put descriptions in your task parameters
- Use _ doc _ to show the signature of your task
- Check the generated information in the URM
- Provide reproductible (even if not complete) examples
- Try to provide alternative documentation to jtags in Javadoc
-
All of the tasks in ia_toolbox_util try to follow this recomendations.
A sample task illustrating some of the previous points:
/**
* The Decompress task.
* <p>Decompresses a (relative path) archive file in a user-chosen directory.
* Supports arbitrary nesting (but not per entry) of the following algorithms: TAR, ZIP, GZIP.
* So tar,gz or zip.gz will be completely expanded but zip entries in tar archive
* will only be expanded up to the zip entries.
*
*<p>Parameters:
*<ul>
*<li><b>archive</b> (INPUT, mandatory) = String with the archive file path
*<li><b>dirout</b> (INPUT, mandatory) = String with the output directory path (may not exist).
*<li><b>compression</b> (INPUT) = String with the type of compression in the file.
* <p>Valid options:
* <ul>
* <li> <b>"Guess"<b>: (default) automatically detect the type of compression used </li>
* <li> <b> "ZIP" </b>: use unzip (or equivalent) to decompress</li>
* <li> <b>"TAR"</b>: use untar (or equivalent) to decompress</li>
* <li> <b> "GZ"</b>: use gunzip (or equivalent) to decompress</li>
* <li> <b> "TGZ"</b>: use gunzip then untar (or equivalent) to decompress</li>
* </ul>
*<ul>
*<p>
*usage:
*<pre>
* #Decompress a tar archive in a temporal directory
* decompress("./mytar.tar", "/tmp")
* </pre>
Above, Documentation point 5 (Parts: title, description, parameters (with options), sample usage. Check HTML usage)
*
* @author jadiaz
*
* @jhelp Decompresses a (relative path) compressed file in a user-chosen directory
* Two first arguments are mandatory. Supports arbitrary nesting (but not per entry) of the following algorithms: TAR, ZIP, GZIP.
* So tar,gz or zip.gz will be completely expanded but zip entries in tar archive will only be expanded up to the zip entries.
*
* @jalias decompress
*
* @jcategory task
*
* @jsynopsis
* decompress(<archive>, <dirout> [, <compression>])
*
* @jexample-preamble
* from java.io import File, FileOutputStream
* from com.ice.tar import TarOutputStream, TarEntry
* file = File("./mytar.tar");
* testFile = File("deleteMe");
* if testFile.exists(): testFile.createNewFile()
* stream = TarOutputStream(FileOutputStream(file))
* entry = TarEntry(testFile)
* stream.putNextEntry(entry)
* @jexample Untarring in temp
* decompress("./mytar.tar", "/tmp")
* @jexample-postamble
* file.delete()
* testFile.delete()
* del(file, testFile, stream, entry)
* del(File, FileOutputStream, TarOutputStream, TarEntry)
*
* @jparameter tar, INPUT, String, MANDATORY, null
* Path of the file to be untared
*
* @jparameter dirout, INPUT, String, MANDATORY, null
* Directory (that may not exist yet) where we want to untar the tar file
*
* @jparameter compression, INPUT, String, OPTIONAL, "Guess"
* Type of compression of the input file, values: GUESS, ZIP, TAR, GZ, TGZ
*
* @jlimitation
* Gzipped files will expand to the filename minus the ".gz" or ".gzip" if present, else they will add ".new" to
* avoid overwritting the original (if you are expanding in the same directory where the archive is).
*
* @jhistory
* 2010-05-25 JDS first release
* 2010-06-09 JDS expanded, renamed to decompress
*
*/
Above, Documentation point 3 and 4 (Check jtags definitions)
public class DecompressTask extends Task {
private static final long serialVersionUID = 1L;
//@SuppressWarnings("unused")
private static final Logger _Log = Logger.getLogger(DecompressTask.class.getName());
Above, Usage point 5 (provide a logger)
private static final String TASKNAME = "decompress",
ARCHIVE = "archive", DIROUT = "dirout", COMPRESS= "compression";
Above, Usage point 6 (we minimize string literals and follwo naming conventions)
public static PyString __doc__ = new PyString(
"decompress(<archive>, <dirout> [, <compression>])\n" +
"\nWhere all parameters are strings, archive is the source file and dirout a (possibly not existing) directory"
);
Above, Documentation point 2 (Line 1: syntax (@jsynopsis ) , rest of lines: description (@jhelp ))
public enum CompressType {
UNKNOWN("Guess"),
ZIP("ZIP"),
TAR("TAR"),
GZIP("GZ"),
TGZ ("TGZ");
@Override
public String toString() {
return _text;
}
public static CompressType get(String text) {
for (CompressType e: CompressType.values()) { //vs valueOf(arg0) -> CONSTANT name
if (text.equals(e._text)) return e;
}
return null;
}
public static String [] toStringArray() {
CompressType [] data = CompressType.values();
String [] out = new String [data.length];
for (int i = 0; i < data.length; i++) {
out[i] = data[i].toString();
}
return out;
}
private CompressType(String text) {
_text = text;
}
private String _text;
};
public DecompressTask() {
super(TASKNAME);
TaskUtil.addParameter(this,
ARCHIVE, String.class, INPUT, MANDATORY, null, NULL_NOT_ALLOWED,
"The tar file to expand");
Above, Documentation point 1 (each task parameter has a string describing it , note syntax similar to @jparameter )
TaskUtil.addParameter(this,
DIROUT, String.class, INPUT, MANDATORY, null, NULL_NOT_ALLOWED,
"The directory where the tar will be expanded");
Above, Usage point 8 (this is an enum , but we define it as a string, and we show it like a Combobox)
TaskUtil.addParameter(this,
COMPRESS, String.class, INPUT, OPTIONAL, CompressType.UNKNOWN.toString(), NULL_NOT_ALLOWED,
"The directory where the tar will be expanded");
}
@Override
public Map<String, Modifier> getCustomModifiers() {
Map<String, Modifier> m = new LinkedHashMap<String, Modifier>();
//TODO: also for gzipped files
m.put(ARCHIVE, new JFilePathModifier(FileSelectionMode.OPEN,
new FileNameExtensionFilter("tar files", "tar"),
new FileNameExtensionFilter("gzip files", "gz", "tgz", "gzip"),
new FileNameExtensionFilter("zip files", "zip")
));
m.put(DIROUT, new JFilePathModifier(FileSelectionMode.DIRECTORY));
m.put(COMPRESS, new JOptionModifier((Object []) CompressType.toStringArray()));
Above, GUI point 6 (we use a JCombobox), GUI point 5 (we provide FIlePaths instead of just text fields)
return m;
}
@Override
public void execute() throws InterruptedException {
String tarpath = (String) getValue(ARCHIVE);
String dirpath = (String) getValue(DIROUT);
String compress = (String) getValue(COMPRESS);
File tarfile = new File(tarpath);
File dirfile = new File(dirpath);
advance(5,"Validating parameters ...");
if (isEmpty(tarpath) || ! tarfile.exists() || tarfile.isDirectory()) {
throw new IllegalArgumentException(ARCHIVE + " must point to an archive file.");
}
if (isEmpty(dirpath) || (dirfile.exists() && ! dirfile.isDirectory())) {
throw new IllegalArgumentException(DIROUT + " must point to a directory.");
}
CompressType type = null;
if (isEmpty(compress)) {
compress = null;
} else {
type = CompressType.get(compress);
if (type == null) { //not found
throw new IllegalArgumentException(COMPRESS + " invalid value, allowed values are " + Arrays.toString(CompressType.values()));
}
}
Above, Usage point 4 (we check validity of inputs, with taylored error messages)
advance(10,"Prepare environment ...");
if (! dirfile.exists() && ! dirfile.mkdirs()) {
throw new RuntimeException(getExceptionMessage("Could not create " + DIROUT + "."));
}
advance(20,"Analyzing archive ...");
InputStream i = null;
try {
if (type == null || CompressType.UNKNOWN.equals(type)) {
i = getStream(tarfile);
} else {
i = new BufferedInputStream(new FileInputStream(tarpath));
switch (type) {
case TAR : i = new TarInputStream(i); break;
case GZIP : i = new GZIPInputStream(i); break;
case ZIP : i = new ZipInputStream(i); break;
case TGZ : i = new TarInputStream(new GZIPInputStream(i)); break;
//default :
}
}
advance(30,"Decompressing archive ...");
Above, Usage point 1 (every time we do something significant to the user (or time consuming), we update the progress)
//fugly
if (i instanceof TarInputStream) {
process((TarInputStream) i, dirfile);
} else if (i instanceof GZIPInputStream) { //need a file name
process((GZIPInputStream) i, new File(dirfile, getGZIPName(tarfile.getName())));
} else if (i instanceof ZipInputStream) {
process((ZipInputStream)i, dirfile);
} else { //unknown compression
throw new IllegalArgumentException("Unknown compression algorithm in file " + tarpath);
}
} catch (IOException e) {
throw new RuntimeException(getExceptionMessage("Could not expand " + ARCHIVE, e),e);
Above, Usage point 4 (even if we do not check each error, we provide a default "personalized" error message : while expanding something went wrong)
} finally {
if (i != null) {
try {
i.close();
} catch (IOException e) { }
}
}
}
| |
<-- Author: JorgoBakker - 21 Dec 2007 --> |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | }
| |
< < | NOTE:
Using TaskParameter.setModifier() for customizing modifiers is deprecated.
This mechanism is unsafe, even dangerous, because it implies executing GUI code at task creation, which is done in a non-GUI thread.
In consequence, this method is planned to be removed. | |
| |
- Support the
setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display (
setSignature )
- Return a map of parameters and assigned values (in
Map<TaskParameter, VariableSelection> getParameters )
| |
< < |
- Clear and check user inputs (used by the default buttons)
| > > |
- Clear and check user inputs implementations (used by the default buttons)
| | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| |
> > | Conventions for labels for input parameters: to construct the labels of your parameters you can use the static function of class JTaskSignatureComponent public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) it provides a decorated label (including tooltip) that follows the standard style. For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) if present. | | An easy way of implementing TaskSignatureComponent is by extending ia.task.gui.dialog.JTaskSignatureComponent and providing your own implementation for the makeModifierMap() method.
For example, if you want to use a custom Signature Component that just wants to use ia.gui.apps.modifier.JFilePathModifier for a parameter aimed for a file name, you could do it like this: | |
NOTE:
You no longer need a signature component to choose your own modifiers for your task (and link them with events ...): Task has a new function public Map<String, Modifier> getCustomModifiers() where you can do just that, see above "Register a Modifier".
| |
< < | Conventions for labels for input parameters: (see DM).
The static function public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) provides a decorated label (including tooltip) that follows the standard style.
For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label) | | | |
< < | If some other function needs to be made public so that tasks can follow the default style, they will be added above. | |
Register a Task Signature Component | |
- Notify request of executions to the framework by
- Allow for setting the Site Event handler for notifying request of execution (the setSiteEventHandler method)
- Notify the execution requests calling the trigger method of ia.gui.kernel.SiteEventHandler passing a ia.gui.kernel.event.CommandExecutionRequestEvent.
You can create this event through the ia.task.gui.dialog.TaskCommandExecutionEventFactory.
| |
> > |
- Return the
javax.swing.Actions for running the task and resetting (clear) the signature (the actions that are invoked when pressing "Accept" and "Clear" buttons, if present), to allow to execute them from the toolbar of HIPE. The simplest implementation would be to create and assign those actions to your buttons in your setTask(TaskApi) method and then to return them from the buttons when asked:
public Action getRunAction() {
return runbutton.getAction();
}
public Action getResetAction() {
return resetButton.getAction();
}
| | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| |
< < | NOTE:
A Task panel will need in the future to provide the actions that invoke "Accept" and "Clear", so that they can be invoked from some other part of the interface (or somebody may remove the Buttons from his panel). Currently we try to invoke the actions via the Toolbar. | |
The Rotate Panel example (herschel.ia.task.example.RotatePanel):
 | | Task compliance
- Write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
| |
< < |
- The name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
| > > |
- The name of the task should be a legal variable name in the global name-space. For example your instance of
DoXTask should report itself as e.g.: "doX" and not as "This is my task" or "DoXTask".
| |
- If your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
| |
> > |
- Your main output parameter will be the first (input)output parameter in your task, this will be the parameter value that is returned automatically upon execution of your task (ret value comes from first output in
ret = t(x,y,z) ).
| |
- Write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
Recommendations for simple tasks and limitations |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
 | | <-- summary -->
Tools are processing units that operate on specific data elements.
From the Java point of view, a tool is an implementation of the Tool interface. | |
< < | The well-known Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hoods. | > > | The well-known Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hood. | |
If a data element is selected, a list of tools that can operate on that data should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialog for settings parameters (for task tools). | |
This section explains:
- how you can create a Tool and register it for being available for dedicated data
| |
< < |
- how you can make HIPE aware of an existing Task,
| > > |
- how you can make HIPE aware of an existing Task,
| |
- how your task can react better on an active data element,
- the default task dialog and how you implement and contribute a dedicated input dialog for your task,
- how you can implement and contribute a specific parameter editor
| | }
| |
< < | Naming conventions for task when to be registered in Hipe should follow this example assuming that the task will perform the functionality named "reduce" : | > > | Naming conventions for task when to be registered in HIPE should follow this example assuming that the task will perform the functionality named "reduce" : | |
Name of the Class : ReduceTask
Name of the Task (getName()) : reduce
| |
The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | |
< < | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | > > | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on an ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | |
You can write a ParameterValidator to do just that:
| |
In other words, rather than writing this logic within the pre-amble or execution block of your task, we recommend you to move that logic into the parameter validation. This way we achieve two things:
- make the logic appear where it should be and therefore keeping the execution block of your task concentrated to the algorithm, and
| |
< < |
- make your task appear as a tool within HIPE that can be ran against specific data.
| > > |
- make your task appear as a tool within HIPE that can be ran against specific data.
| |
Task Dialogs | | A new default dialog layout has been implemented following the request of the DPUG:
It puts two parameters per line: lines are filled left to right, and then top to bottom. If you only have 1 input (or output) it will fill the whole line.
Modifiers implementors should take care that the preferred size of their modifier is smaller (about 20 chars max). | |
< < | Provided modifiers have been updated but some modifiers are too wide for this layout (ex. AngleModifier, can have 3 texts and 1 combo in a line, see rotate later).
| > > | Provided modifiers have been updated but some modifiers are too wide for this layout (for instance, AngleModifier can have three texts and one combo in a line, see rotate later).
| | The default dialog for the crop task, with all sections opened:
 | |
Parameter Modifiers
| |
< < | The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifiers . | > > | The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifier objects. | |
The input area for the crop task:
 | |
< < | The composition of Modifiers is created based on the types of the values of the Task Parameters of the Task Signature. | > > | The composition of Modifier objects is created based on the types of the values of the Task Parameters of the Task Signature. | |
The Modifier for the row1 Parameter of the crop task:
 | |
Implement a Modifier
| |
< < | The Modifier interface consists of two explicit contracts: | > > | The ia.gui.apps.Modifier interface consists of two explicit contracts: | |
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
and two implicit contracts: | | Implement a Task Signature Component
| |
< < | The TaskSignatureComponent interface consists of four explicit contracts | > > | The ia.task.gui.dialog.TaskSignatureComponent interface consists of four explicit contracts: | |
- Support the
setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display (
setSignature )
- Return a map of parameters and assigned values (in
Map<TaskParameter, VariableSelection> getParameters )
| |
- Be JComponent
- Have an empty constructor
| |
< < | An easy way of implementing TaskSignatureComponent is by extending JTaskSignatureComponent and providing your own implementation for the makeModifierMap() method. | > > | An easy way of implementing TaskSignatureComponent is by extending ia.task.gui.dialog.JTaskSignatureComponent and providing your own implementation for the makeModifierMap() method. | | | |
< < | For example, if you want to use a custom Signature Component that just wants to use JFilePathModifier for a parameter aimed for a file name, you could do it like this: | > > | For example, if you want to use a custom Signature Component that just wants to use ia.gui.apps.modifier.JFilePathModifier for a parameter aimed for a file name, you could do it like this: | |
public class MySignatureComponent extends JTaskSignatureComponent {
| | Implement a Task Panel
| |
< < | The TaskPanel interface consists of three explicit contracts | > > | The ia.task.gui.dialog.TaskPanel interface consists of three explicit contracts: | |
- Support the setVariableSelection for initial assignment from the Tool Window
- Assign the Task to display ( the setTask)
- Notify request of executions to the framework by
- Allow for setting the Site Event handler for notifying request of execution (the setSiteEventHandler method )
| |
< < | | > > |
-
- Notify the execution requests calling the trigger method of ia.gui.kernel.SiteEventHandler passing a ia.gui.kernel.event.CommandExecutionRequestEvent.
You can create this event through the ia.task.gui.dialog.TaskCommandExecutionEventFactory.
| | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| | List<? extends Parameter> inputs,
Category... categories)
| |
< < | You provide the variable types you are interested in within the prime input: just return a ToolParameter initiated with the proper class of data you want to handle: | > > | You provide the variable types you are interested in within the prime input: just return a ia.gui.kernel.ToolParameter initiated with the proper class of data you want to handle: | |
new ToolParameter("data", MyTargetDataType.class)
| |
Tool Viewer | |
< < | Every tool has an associated viewer, which must implement EditorComponent (by extending AbstractEditorComponent or one of its subclasses). | > > | Every tool has an associated viewer, which must implement ia.gui.kernel.parts.EditorComponent (by extending ia.gui.kernel.parts.AbstractEditorComponent or one of its subclasses). | |
Tool Registry
Once you have your tool and the corresponding viewer, you need to register them like this: |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes.
The default dialog for the crop task:
| |
< < |  | > > |  | |
As for instance you may want to have more control over how the input parameters are presented to the user:
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
| | A new default dialog layout has been implemented following the request of the DPUG:
It puts two parameters per line: lines are filled left to right, and then top to bottom. If you only have 1 input (or output) it will fill the whole line.
Modifiers implementors should take care that the preferred size of their modifier is smaller (about 20 chars max). | |
< < | Provided modifiers have been updated but some modifiers are too wide for this layout (ex. AngleModifier, can have 3 texts and 1 combo in a line). | > > | Provided modifiers have been updated but some modifiers are too wide for this layout (ex. AngleModifier, can have 3 texts and 1 combo in a line, see rotate later).
The default dialog for the crop task, with all sections opened:
 | |
To adapt to these scenarios and more, the system provides three ways for customizing you Task dialogs: | | The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifiers .
The input area for the crop task:
| |
< < |  | > > |  | |
The composition of Modifiers is created based on the types of the values of the Task Parameters of the Task Signature.
The Modifier for the row1 Parameter of the crop task:
| |
< < |  | > > |  | |
Currently the system contains basic implementation for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there's still a lot of space for improvements and contribution. You can find the general available modifiers in package herschel.ia.gui.apps.modifier ; please consult the Javadoc of your HIPE installation. | |
In case the default input area based on Modifiers doesn't fit your needs you can just replace it by your own implementation. | |
< < | Rotate Alternative Signature:
| > > | Rotate Alternative Signature (old):
| |  | |
> > | Rotate Alternative Signature (new):
 | | If this is the case you need to:
- Implement a Task Signature Component
- Register it to the system.
| |
| |
> > | NOTE:
You no longer need a signature component to choose your own modifiers for your task (and link them with events ...): Task has a new function public Map<String, Modifier> getCustomModifiers() where you can do just that, see above "Register a Modifier".
Conventions for labels for input parameters: (see DM).
The static function public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) provides a decorated label (including tooltip) that follows the standard style.
For the function to work properly your task parameters should be fully configured (for example, the parameter description will be the tooltip of the label)
If some other function needs to be made public so that tasks can follow the default style, they will be added above. | | Register a Task Signature Component
| |
See also the Extension Registry documentation for more details. | |
< < | NOTE:
Conventions for labels for input parameters: (see DM).
The static function public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) provides a decorated label (including tooltip) that follows the standard style.
If some other function needs to be made public so that tasks can follow the default style, they will be added above. | | | |
--> | |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="rotate panel updated to the new look of tasks" date="1275479566" name="rotate_new.png" path="rotate_new.png" size="10857" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop input updated to the new look of tasks" date="1275479674" name="crop_input_new.png" path="crop_input_new.png" size="14159" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1254239744" name="crop.png" path="crop.png" size="14045" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop modifier updated to the new look of tasks" date="1275479639" name="crop_modifier_new.png" path="crop_modifier_new.png" size="14021" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop with closed sections updated to the new look of tasks" date="1275479716" name="crop_closed.png" path="crop_closed.png" size="8289" user="Main.JavierDiaz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop updated to the new look of tasks" date="1275479736" name="crop_new.png" path="crop_new.png" size="14211" user="Main.JavierDiaz" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
META TOPICMOVED |
by="DavideRizzo" date="1272527701" from="Hcss.DpHipeTools" to="Public.DpHipeTools" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
<-- Author: JorgoBakker - 21 Dec 2007 --> | |
> > | <--
--> | |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | |
< < | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | > > | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | |
You can write a ParameterValidator to do just that:
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
| |
> > |
META TOPICMOVED |
by="DavideRizzo" date="1272527701" from="Hcss.DpHipeTools" to="Public.DpHipeTools" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- Have an empty constructor
| |
> > | NOTE:
A Task panel will need in the future to provide the actions that invoke "Accept" and "Clear", so that they can be invoked from some other part of the interface (or somebody may remove the Buttons from his panel). Currently we try to invoke the actions via the Toolbar. | | The Rotate Panel example (herschel.ia.task.example.RotatePanel):
 |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- you may want to organize your parameters by grouping them in tabs, or putting a border around a group of parameters
- you may want to have more informative tooltips, labels or even input fields that are more suitable for your task.
| |
> > | A new default dialog layout has been implemented following the request of the DPUG:
It puts two parameters per line: lines are filled left to right, and then top to bottom. If you only have 1 input (or output) it will fill the whole line.
Modifiers implementors should take care that the preferred size of their modifier is smaller (about 20 chars max).
Provided modifiers have been updated but some modifiers are too wide for this layout (ex. AngleModifier, can have 3 texts and 1 combo in a line). | | To adapt to these scenarios and more, the system provides three ways for customizing you Task dialogs:
- Parameter Modifiers
- Signature Components
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Name of the Task (getName()) : reduce
Name of the variable in Jython : reduce
| |
> > |
For naming tasks we follow the Java conventions, we use camel-case , not underscores : "reduceLight" is valid, "reduce_light" is not. Info log messages are produced for invalid task names. | |
Prime input validation | |
- While you can always write
SomeTask(param = null) in Console, using a task dialog you will get SomeTask() : for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
- Modifiers have no notion of the optionality of parameters: if they have a valid value, they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
- Specialized modifiers:
| |
< < |
-
- Will only store variables compatible with the type.
- They do not to accept variables set to None.
| > > |
-
- Will mark as errorenous variables incompatible with the type (dynamically), but will accept any variable.
| |
Implement a Modifier | |
See also the Extension Registry documentation for more details. | |
> > | NOTE:
Conventions for labels for input parameters: (see DM).
The static function public static JLabel getDecoratedLabel(TaskParameter tp, boolean isPrimeInput, String altName) provides a decorated label (including tooltip) that follows the standard style.
If some other function needs to be made public so that tasks can follow the default style, they will be added above.
| | |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | "Rotate Signature",
"herschel.ia.task.example.RotateSignatureComponent",
"factory.editor.tool.task.signature", | |
< < | "herschel.ia.image.Rotate")) | > > | "herschel.ia.image.RotateTask")) | | | | "Rotate Task Panel",
"herschel.ia.task.example.RotatePanel",
"factory.editor.tool.task", | |
< < | "herschel.ia.image.Rotate")); | > > | "herschel.ia.image.RotateTask")); | | |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | | |
< < | Adding a Task as a Tool | > > | Adding a Tool as a Task | |
Task Registry
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
> > | | |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
--> | |
< < |  | > > |  | |
<-- summary -->
Tools are processing units that operate on specific data elements. | | The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes.
The default dialog for the crop task:
| |
< < |  | > > |  | |
As for instance you may want to have more control over how the input parameters are presented to the user:
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
| |
Parameter Modifiers
| |
< < | The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifiers | > > | The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifiers . | |
The input area for the crop task:
| |
< < |  | > > |  | |
The composition of Modifiers is created based on the types of the values of the Task Parameters of the Task Signature. | |
< < | The Modifier for the first Parameter of the crop task:
 | > > | The Modifier for the row1 Parameter of the crop task:
 | | | |
< < | Currently the system contains basic implementation for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there's still a lot of space for improvements and contribution. You can find the general available modifiers in package herschel.ia.gui.apps.modifier . | > > | Currently the system contains basic implementation for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there's still a lot of space for improvements and contribution. You can find the general available modifiers in package herschel.ia.gui.apps.modifier ; please consult the Javadoc of your HIPE installation. | | | |
< < | If your Task Parameter isn't one of the aforementioned types, you could: | > > | If the default parameter doesn't fit for your Task Parameter, you can: | |
- Register it to the system.
| |
< < | Alternatively, you could want to write your specific Modifier for one of the already available types. In that case, you could skip the registration, and just create your modifier in your Java code within a custom Signature Component. | > > | Alternatively, you could want to write your specific Modifier for one of the already available types. In that case, you could create your modifier in a custom Signature Component. | |
NOTE:
The following behaviours and limitations are present in the provided modifiers: | | "herschel.ia.MyClass")
| |
< < | In case the Modifier you have created is only applicable to a specific task or even to a specific parameter of a specific task you can simply assign it to the Task Parameter itself: | > > | In case the Modifier you have created is only applicable to a specific task or even to a specific parameter of a specific task, you can simply assign it to the applicable Task Parameter: | |
| |
< < | // In your task constructor
TaskParameter parameter = new TaskParameter("input", String.class);
parameter.setModifier(new MyModifer()); | > > | // YourTask constructor
public YourTask() {
addTaskParameter(new TaskParameter("someInput", MyClass.class));
...
}
// Customize your modifiers
@Override
public Map<String, Modifier> getCustomModifiers() {
Map<String, Modifier> map = new LinkedHashMap<String, Modifier>();
map.put("someInput", new MyModifier());
return map;
} | | | |
> > | NOTE:
Using TaskParameter.setModifier() for customizing modifiers is deprecated.
This mechanism is unsafe, even dangerous, because it implies executing GUI code at task creation, which is done in a non-GUI thread.
In consequence, this method is planned to be removed. | |
Signature Components | |
<-- Author: JorgoBakker - 21 Dec 2007 --> | |
< < | | |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1203070875" name="crop_input.jpg" path="crop_input.jpg" size="17033" user="Main.NicolaDeCandussio" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with input highlighted" date="1254240567" name="crop_input.png" path="crop_input.png" size="14865" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="Tasks and variables" date="1254240686" name="tasks.png" path="tasks.png" size="13304" user="Main.JaimeSaiz" version="1" |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1254239744" name="crop.png" path="crop.png" size="14045" user="Main.JaimeSaiz" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
| |
< < |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="modifier" date="1203071348" name="crop_modifier.jpg" path="crop_modifier.jpg" size="16408" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="" date="1203007458" name="crop.jpg" path="crop.jpg" size="20487" user="Main.NicolaDeCandussio" version="1" |
| > > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="crop task with modifier highlighted" date="1254240597" name="crop_modifier.png" path="crop_modifier.png" size="14728" user="Main.JaimeSaiz" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | REGISTRY = ExtensionRegistry.getInstance()
REGISTRY.register(COMPONENT,Extension( | |
< < | "Tool",
"herschel.ia.task.views.TaskToolComponent",
"factory.editor.new",
"herschel.ia.gui.kernel.ToolSelection"));
REGISTRY.register(COMPONENT,Extension( | | "Button Tool", | |
< < | "herschel.ia.task.views.SimpleButtonToolComponent", | > > | "herschel.path.to.SimpleButtonToolComponent", | | "factory.editor.tool", | |
< < | "herschel.ia.task.views.SimpleButtonTool")) | > > | "herschel.path.to.SimpleButtonTool")) | |
from herschel.ia.gui.kernel import ToolRegistry | |
< < | from herschel.ia.task.views import SimpleButtonTool | > > | from herschel.path.to import SimpleButtonTool | | simpleButton = SimpleButtonTool()
ToolRegistry.getInstance().register(simpleButton) |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Some short-cuts | |
> > | | |
--> | | This follows in some way the MVC pattern: your target data is the Model, your associated viewer is the View, and your tool is the Controller.
Tool Implementation | |
< < | The Tool interface is simple:
public interface Tool {
// Known categories to which a tool may belong to
public enum Category { SPIRE, PACS, HIFI, GENERAL, IMAGE }
// Whether the tool can cope with the given values; that is, if they can be associated to the input parameters
boolean canHandle(List<?> values);
// Whether the tool can cope with the given value; that is, if it can be associated to the prime input
boolean canHandle(Object value);
| > > | In order to write a tool, Tool interface needs to be implemented. Instead of doing it directly, it is encouraged to extend AbstractTool . | | | |
< < | // Get an array of categories to which this tool belongs to
Category[] getCategories(); | > > | The information to be provided is passed to one of its constructors in a super call from the derived class: | | | |
< < | // Return the set of input parameters
List<Parameter> getInputs();
// Get the tool name
String getName();
// Return the prime input parameter
Parameter getPrimeInput();
// Return the source code of this tool
SourceCode getSourceCoe(); | > > |
/** Constructor for a tool with a single parameter and general category. */
protected AbstractTool(String name, Parameter primeInput)
| | | |
< < | // Get the actual object that does the work
Object getToolObject(); | > > | /** Constructor for a tool with a single input parameter. */
protected AbstractTool(String name, Parameter primeInput, Category... categories) | | | |
< < | // Set the actual object that does the work
void setToolObject(Object o); | > > | /** Constructor for a tool with multiple input parameters and general category. */
protected AbstractTool(String name, Parameter primeInput, List<? extends Parameter> inputs) | | | |
< < | // Returns whether this tool is able to be executed
boolean isApplicable();
} | > > | /** Constructor with all arguments. */
protected AbstractTool(String name,
Parameter primeInput,
List<? extends Parameter> inputs,
Category... categories) | | | |
< < | You provide the variable types you are interested in within the prime input: just return a ToolParameter initiated with the proper class of data you want to handle. | > > | You provide the variable types you are interested in within the prime input: just return a ToolParameter initiated with the proper class of data you want to handle: | |
| |
< < | private ToolParameter _prime = new ToolParameter("data", MyTargetDataType.class);
public Parameter getPrimeInput() { return _prime; } | > > | new ToolParameter("data", MyTargetDataType.class) | |
| |
> > | More conditions for checking whether the tool can react on a particular variable can be added by providing a ParameterValidator to the prime input. | | The actual job to be done can be delegated to a third object (the "tool object"), or just be executed by the tool class itself. | |
< < | In this latter case, the method Object getToolObject() should return this . | > > | This latter case is the default, otherwise, you need to call setToolObject(Object toolObject) in your constructor.
Moreover, you may return the categories you think the tool is meaningful for, by providing the proper ones in the super call.
Naming conventions | | | |
< < | Moreover, you may return the categories you think the tool is meaningful for, through the proper implementation of Category[] getCategories() . | > > | Conventions for names of a tool class and its variable in the Tasks view are similar than those for tasks. For example, a tool for spectrum filtering could be called:
Name of the Class : SpectrumFilterTool
Name of the Tool (getName()) : spectrumFilter
Name of the variable in Jython : spectrumFilter
| |
Tool Viewer
Every tool has an associated viewer, which must implement EditorComponent (by extending AbstractEditorComponent or one of its subclasses). | |
# Associate the tool with the viewer
REGISTRY.register(COMPONENT,Extension(
| |
< < | "My Tool",
"herschel.path.to.MyToolComponent", | > > | "Spectrum Filter Tool",
"herschel.path.to.SpectrumFilterToolComponent", | | "factory.editor.tool", | |
< < | "herschel.path.to.MyTool")) | > > | "herschel.path.to.SpectrumFilterTool")) | |
# Register the tool so it is automatically available for the proper variables in HIPE
from herschel.ia.gui.kernel import ToolRegistry | |
< < | from herschel.path.to import MyTool
ToolRegistry.getInstance().register(MyTool()) | > > | from herschel.path.to import SpectrumFilterTool
spectrumFilter = SpectrumFilterTool()
ToolRegistry.getInstance().register(spectrumFilter)
all = [ "spectrumFilter", "SpectrumFilterTool", ... ] | |
| | 1. The tool class
| |
< < | public class ButtonTool implements Tool { | > > | public class SimpleButtonTool extends AbstractTool { | | | |
< < | private Category[] _categories = { Category.GENERAL };
private ToolParameter _prime = new ToolParameter("data", ArrayData.class); | | private ArrayData _data;
private boolean _flag = true; | |
< < | public Category[] getCategories() {
return _categories;
}
public String getName() {
return "Button Tool";
}
public Parameter getPrimeInput() {
return _prime;
}
public Object getToolObject() {
return this; | > > | public SimpleButtonTool() {
super("simpleButton", new ToolParameter("data", ArrayData.class)); | | } | |
< < | public void setToolObject(Object o) {
// do nothing
}
public void setData(ArrayData data) { | > > | void setData(ArrayData data) { | | _data = data;
} | | 2. The viewer class
| |
< < | public class ButtonToolComponent extends AbstractEditorComponent<ToolSelection> { | > > | public class SimpleButtonToolComponent extends AbstractEditorComponent<ToolSelection> { | |
private static final long serialVersionUID = 1L;
private static int _counter = 1; | |
< < | private ButtonTool _tool; | > > | private SimpleButtonTool _tool; | | | |
< < | public ButtonToolComponent() { | > > | public SimpleButtonToolComponent() { | | super(new BorderLayout());
} | |
< < | protected Class<ToolSelection> getSelectionType() { | > > | protected Class getSelectionType() { | | return ToolSelection.class;
}
protected boolean makeEditorContent() {
final JButton button = new JButton();
setName("Button Tool " + _counter++); | |
< < | _tool = (ButtonTool)getSelection().getTool(); | > > | _tool = (SimpleButtonTool)getSelection().getTool(); | | _tool.setData((ArrayData)getSelection().getSelection().getValue());
_tool.updateLabel(button);
button.addActionListener(new ActionListener() { | | 3. The registration
| |
> > | COMPONENT = ExtensionRegistry.COMPONENT
REGISTRY = ExtensionRegistry.getInstance()
REGISTRY.register(COMPONENT,Extension(
"Tool",
"herschel.ia.task.views.TaskToolComponent",
"factory.editor.new",
"herschel.ia.gui.kernel.ToolSelection")); | | REGISTRY.register(COMPONENT,Extension(
"Button Tool", | |
< < | "herschel.your.package.ButtonToolComponent", | > > | "herschel.ia.task.views.SimpleButtonToolComponent", | | "factory.editor.tool", | |
< < | "herschel.your.package.ButtonTool")) | > > | "herschel.ia.task.views.SimpleButtonTool")) | |
from herschel.ia.gui.kernel import ToolRegistry | |
< < | from herschel.your.package import ButtonTool
ToolRegistry().getInstance().register(ButtonTool()) | > > | from herschel.ia.task.views import SimpleButtonTool
simpleButton = SimpleButtonTool()
ToolRegistry.getInstance().register(simpleButton)
# cleanup
del(ExtensionRegistry, Extension, REGISTRY, COMPONENT)
all = [ "simpleButton", "SimpleButtonTool" ] | |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | // Known categories to which a tool may belong to
public enum Category { SPIRE, PACS, HIFI, GENERAL, IMAGE }
| |
> > | // Whether the tool can cope with the given values; that is, if they can be associated to the input parameters
boolean canHandle(List<?> values);
// Whether the tool can cope with the given value; that is, if it can be associated to the prime input
boolean canHandle(Object value);
// Get an array of categories to which this tool belongs to
Category[] getCategories();
// Return the set of input parameters
List<Parameter> getInputs(); | | // Get the tool name
String getName(); | |
> > | // Return the prime input parameter
Parameter getPrimeInput();
// Return the source code of this tool
SourceCode getSourceCoe(); | | // Get the actual object that does the work
Object getToolObject();
// Set the actual object that does the work
void setToolObject(Object o); | |
< < | // Get an array of categories to which this tool belongs to
Category[] getCategories();
// Return the prime input parameter
Parameter getPrimeInput(); | > > | // Returns whether this tool is able to be executed
boolean isApplicable(); | | }
You provide the variable types you are interested in within the prime input: just return a ToolParameter initiated with the proper class of data you want to handle. |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | The Modifier for the first Parameter of the crop task:
 | |
< < | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double and few more, so there's still a lot of space for improvements and contribution. | > > | Currently the system contains basic implementation for the simple types Boolean , Integer , Float , Long , Double , String and few more, so there's still a lot of space for improvements and contribution. You can find the general available modifiers in package herschel.ia.gui.apps.modifier . | | | |
< < | The following behaviours and limitations are present in the provided modifiers:
- If the value is unfilled or invalid (red) the parameter will not used (but see D'n'D). This has been retrofitted in a consistent manner after 1.0
- While you can always in Console write "SomeTask(param = null)", with a Panel you will get "Task()": for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
- Modifiers have no notion of the optionality of parameters: if they have a valid value they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
- All Modifiers accept D'n'D of variables and if a variable is D'n'Ded and stored it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state.
- Speciallized modifiers:
- Will only store variables compatible with the type.
- They do not seem to accept variables set to None (to check)
- Once a variable has been accepted the value the user edits will forever be ignored
- Cannot forget the variable (default can't either but has no editor).
- JDefaultModifier: (D'n'D can block some Drops, but basically accepts any type)
- Initially they have no type
- They accept the type of the first variable D'n'Ded and remember it (of any type!)
- Now they only accept variables of the same type (or compatible)
- You can erase the type D'n'Ding a None
- Current floating point modifiers are incapable of parsing some special values like NaN, +-Infinite and -0, as parsing/checking is done via pure numeric patterns.
If your Task Parameter isn't one of the mentioned types, you could: | > > | If your Task Parameter isn't one of the aforementioned types, you could: | |
- Implement a Modifier
- Register it to the system.
Alternatively, you could want to write your specific Modifier for one of the already available types. In that case, you could skip the registration, and just create your modifier in your Java code within a custom Signature Component. | |
< < | In package herschel.ia.gui.apps.modifier you can find the general available modifiers. | > > | NOTE:
The following behaviours and limitations are present in the provided modifiers:
- While you can always write
SomeTask(param = null) in Console, using a task dialog you will get SomeTask() : for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
- Modifiers have no notion of the optionality of parameters: if they have a valid value, they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
- Specialized modifiers:
- Will only store variables compatible with the type.
- They do not to accept variables set to None.
| |
Implement a Modifier |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Currently the system contains basic implementation for the simple types Integer, Float, Long, Double and few more, so there's still a lot of space for improvements and contribution. | |
< < | The following behaviours and limitations are present in the provided modifiers: | > > | The following behaviours and limitations are present in the provided modifiers: | |
- If the value is unfilled or invalid (red) the parameter will not used (but see D'n'D). This has been retrofitted in a consistent manner after 1.0
- While you can always in Console write "SomeTask(param = null)", with a Panel you will get "Task()": for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
- Modifiers have no notion of the optionality of parameters: if they have a valid value they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
| | parameter.setModifier(new MyModifer());
| |
< < | If a modifier is associated to a task parameter in the task constructor, like in the example above, it is instantiated during initialization, when the task is created. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write a custom Signature Component instead, which would be instantiated after the theme is set. Not only the theme is wrong but, as is the case with JComboBoxes (JOptionModifier), the component may not behave properly when actioned. | |
Signature Components |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | |
< < | Sometimes this may not be enough, e.g. is certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | > > | Sometimes this may not be enough, e.g. in certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | |
You can write a ParameterValidator to do just that:
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | parameter.setModifier(new MyModifer());
| |
< < | If a modifier is associated to a task parameter in the task constructor, like in the example above, it is instantiated during initialization, when the task is created. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write a custom Signature Component instead, which would be instantiated after the theme is set. | > > | If a modifier is associated to a task parameter in the task constructor, like in the example above, it is instantiated during initialization, when the task is created. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write a custom Signature Component instead, which would be instantiated after the theme is set. Not only the theme is wrong but, as is the case with JComboBoxes (JOptionModifier), the component may not behave properly when actioned. | |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The following behaviours and limitations are present in the provided modifiers:
- If the value is unfilled or invalid (red) the parameter will not used (but see D'n'D). This has been retrofitted in a consistent manner after 1.0
| |
< < |
- While you can always in Console write "SomeTask(param = null)", with a Panel you will get "Task()": for GUIs "null is not allowed"
- Modifiers have no notion of the optionality of parameters: if they have a valid value they will return it. So parameters with valid default values will be committed even if optional(if not modified/invalidated)
- All Modifiers accept D'n'D of variables and if a variable is D'n'Ded and stored it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state.
| > > |
- While you can always in Console write "SomeTask(param = null)", with a Panel you will get "Task()": for GUIs "null is not allowed". The task machinery will take nulls as if the parameter has been ignored by the user.
- Modifiers have no notion of the optionality of parameters: if they have a valid value they will return it. The task machinery will not generate a parameter assignment if the value equals the default.
- All Modifiers accept D'n'D of variables and if a variable is D'n'Ded and stored it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state.
| |
- Speciallized modifiers:
- Will only store variables compatible with the type.
| |
< < |
-
- They do not seem to accept null (to check)
| > > |
-
- They do not seem to accept variables set to None (to check)
| |
-
- Once a variable has been accepted the value the user edits will forever be ignored
- Cannot forget the variable (default can't either but has no editor).
- JDefaultModifier: (D'n'D can block some Drops, but basically accepts any type)
- Initially they have no type
- They accept the type of the first variable D'n'Ded and remember it (of any type!)
- Now they only accept variables of the same type (or compatible)
| |
< < |
-
- You can erase the type D'n'Ding a null (None)
| > > |
-
- You can erase the type D'n'Ding a None
| |
- Current floating point modifiers are incapable of parsing some special values like NaN, +-Infinite and -0, as parsing/checking is done via pure numeric patterns.
If your Task Parameter isn't one of the mentioned types, you could: |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double and few more, so there's still a lot of space for improvements and contribution.
The following behaviours and limitations are present in the provided modifiers: | |
< < |
- If the value is unfilled or invalid (red) the parameter will not be commited to the task : the getObject method returns null : This has been retrofitted in a consistent manner after 1.0
- The point above means null is not a value a parameter will ever show from a modifier in a task invocation, While you can always in a TUI write T(a = null), with a GUI you will get T()
- Modifiers so, have no notion of the optionality of parameters: if they have a valid value they will return it. So parameters with valid default values will be committed (if not modified/invalidated)
- Modifiers accept D'n'D of variables and if a variable is D'n'Ded it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state, we are planning on making explicit captured variables in all our implementations (when we can!)
- D'n'D is not really typechecked (and it can't easily be!)
| > > |
- If the value is unfilled or invalid (red) the parameter will not used (but see D'n'D). This has been retrofitted in a consistent manner after 1.0
- While you can always in Console write "SomeTask(param = null)", with a Panel you will get "Task()": for GUIs "null is not allowed"
- Modifiers have no notion of the optionality of parameters: if they have a valid value they will return it. So parameters with valid default values will be committed even if optional(if not modified/invalidated)
- All Modifiers accept D'n'D of variables and if a variable is D'n'Ded and stored it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state.
- Speciallized modifiers:
- Will only store variables compatible with the type.
- They do not seem to accept null (to check)
- Once a variable has been accepted the value the user edits will forever be ignored
- Cannot forget the variable (default can't either but has no editor).
- JDefaultModifier: (D'n'D can block some Drops, but basically accepts any type)
| |
-
- Initially they have no type
- They accept the type of the first variable D'n'Ded and remember it (of any type!)
| |
< < |
-
- Now they only accept variables of the same type
- You go back to the first step D'n'Ding a null (None): type capture erased
- Even if it were typechecked, you can change the object (and type) of a Jython variable AFTER you have D'n'D somewhere: the modifier should be listening to those events to remove the capture when the variable changes type. In Jython one does not declare types, and one can change the type of a variable when one wishes.
- So, D'n'D should start prefilled with a (target) type that is final and also it could listen to all variables changes or the type capture should be removed.
- Current floating point modifiers are incapable of parsing special values like NaN, +-Infinite and -0, as parsing/checking is done via pure numeric patterns.
| > > |
-
- Now they only accept variables of the same type (or compatible)
- You can erase the type D'n'Ding a null (None)
- Current floating point modifiers are incapable of parsing some special values like NaN, +-Infinite and -0, as parsing/checking is done via pure numeric patterns.
| |
If your Task Parameter isn't one of the mentioned types, you could: |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Currently the system contains basic implementation for the simple types Integer, Float, Long, Double and few more, so there's still a lot of space for improvements and contribution. | |
> > | The following behaviours and limitations are present in the provided modifiers:
- If the value is unfilled or invalid (red) the parameter will not be commited to the task : the getObject method returns null : This has been retrofitted in a consistent manner after 1.0
- The point above means null is not a value a parameter will ever show from a modifier in a task invocation, While you can always in a TUI write T(a = null), with a GUI you will get T()
- Modifiers so, have no notion of the optionality of parameters: if they have a valid value they will return it. So parameters with valid default values will be committed (if not modified/invalidated)
- Modifiers accept D'n'D of variables and if a variable is D'n'Ded it takes precedence over the filled value: currently only the default modifier has visual feedback about it's D'n'D state, we are planning on making explicit captured variables in all our implementations (when we can!)
- D'n'D is not really typechecked (and it can't easily be!)
- Initially they have no type
- They accept the type of the first variable D'n'Ded and remember it (of any type!)
- Now they only accept variables of the same type
- You go back to the first step D'n'Ding a null (None): type capture erased
- Even if it were typechecked, you can change the object (and type) of a Jython variable AFTER you have D'n'D somewhere: the modifier should be listening to those events to remove the capture when the variable changes type. In Jython one does not declare types, and one can change the type of a variable when one wishes.
- So, D'n'D should start prefilled with a (target) type that is final and also it could listen to all variables changes or the type capture should be removed.
- Current floating point modifiers are incapable of parsing special values like NaN, +-Infinite and -0, as parsing/checking is done via pure numeric patterns.
| | If your Task Parameter isn't one of the mentioned types, you could:
- Implement a Modifier
- Register it to the system.
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | compute=ComputeTask()
| |
< < | To make your task appear in the "Run Tools" view, you need to add the following lines: | > > | To make your task appear in the "Tasks" view, you need to add the following lines: | |
| |
< < | from herschel.ia.task.views import TaskToolFactory
TaskToolFactory.register(compute) | > > | from herschel.ia.task.views import TaskToolRegistry
toolRegistry = TaskToolRegistry.getInstance()
toolRegistry.register(compute) | | | |
< < | For PCSS (PACS' builds) users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | > > | For PACS users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | |
You can also specify that your task belongs to one or more Category :
from herschel.ia.gui.kernel.Tool import Category
| |
< < | TaskToolFactory.register(compute, [Category.IMAGE, Category.PACS])) | > > | toolRegistry.register(compute, [Category.IMAGE, Category.PACS])) | |
Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task! | |
Task compliance | |
< < |
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- the name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| > > |
- Write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- The name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
- If your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- Write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| | | |
< < | Some Recommendations of use of simple tasks and its limitations | > > | Recommendations for simple tasks and limitations | | | |
< < |
- Use a function that fully initializes TaskParameters: you avoid working with partially initialized data or data with non obvious defaults.
| > > |
- Use a function that fully initializes TaskParameters: you avoid working with partially initialized data or data with non obvious defaults.
| |
- Please take care to register your task properly: otherwise it may half-work, which is much worse than not working at all!
| |
< < |
- Capture exceptions and check your params before trying to properly execute if you want to provide better error reporting than the one provided by default
| > > |
- Capture exceptions and check your params before trying to properly execute, if you want to provide better error reporting than the one provided by default.
| |
- You should not do user interaction after you have started execute() (not on EDT).
| |
< < |
- Validators: you cannot compare multiple parameters, order of execution is not specified, will be executed several times. SO if you need to validate dependent parameters it should be done later.
- Once you are in execute() console has already been updated with the command : Although you can change the value of TaskParameters, this will not be properly reflected on the UI, so don't do it. So once you are on execute() you can check , possibly abort, and properly execute (nothing else).
| > > |
- Validators: you cannot compare multiple parameters, order of execution is not specified, will be executed several times. So, if you need to validate dependent parameters, it should be done later.
- Once you are in execute() console has already been updated with the command : Although you can change the value of TaskParameters, this will not be properly reflected on the UI, so don't do it. So once you are on execute() you can check , possibly abort, and properly execute (nothing else).
| |
Adding a Tool that is not a Task | | "herschel.path.to.MyTool"))
# Register the tool so it is automatically available for the proper variables in HIPE | |
< < | from herschel.ia.gui.kernel import ToolFactory | > > | from herschel.ia.gui.kernel import ToolRegistry | | from herschel.path.to import MyTool | |
< < | ToolFactory.register(MyTool()) | > > | ToolRegistry.getInstance().register(MyTool()) | |
| | "factory.editor.tool",
"herschel.your.package.ButtonTool")) | |
< < | from herschel.ia.gui.kernel import ToolFactory | > > | from herschel.ia.gui.kernel import ToolRegistry | | from herschel.your.package import ButtonTool | |
< < | ToolFactory.register(ButtonTool()) | > > | ToolRegistry().getInstance().register(ButtonTool()) | |
| |
Triggering Events | |
< < | For a full detailed section about triggering events have a look at DpHipeCommonUtilities | > > | For a full detailed section about triggering events have a look at DpHipeCommonUtilities. | |
<-- Author: JorgoBakker - 21 Dec 2007 --> |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Task compliance | |
< < | | > > | | |
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- the name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| |
< < |
- If your task uses file paths as arguments to avoid problems with windows paths you should add a Mapper to your TaskParameter:
parameter.setMapper(new FilenameMapper()); //Java
| > > |
Some Recommendations of use of simple tasks and its limitations
- Use a function that fully initializes TaskParameters: you avoid working with partially initialized data or data with non obvious defaults.
- Please take care to register your task properly: otherwise it may half-work, which is much worse than not working at all!
- Capture exceptions and check your params before trying to properly execute if you want to provide better error reporting than the one provided by default
- You should not do user interaction after you have started execute() (not on EDT).
- Validators: you cannot compare multiple parameters, order of execution is not specified, will be executed several times. SO if you need to validate dependent parameters it should be done later.
- Once you are in execute() console has already been updated with the command : Although you can change the value of TaskParameters, this will not be properly reflected on the UI, so don't do it. So once you are on execute() you can check , possibly abort, and properly execute (nothing else).
| |
Adding a Tool that is not a Task |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- the name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| |
> > |
- If your task uses file paths as arguments to avoid problems with windows paths you should add a Mapper to your TaskParameter:
parameter.setMapper(new FilenameMapper()); //Java
| |
Adding a Tool that is not a Task |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | parameter.setModifier(new MyModifer());
| |
< < | If your Modifier is registered as the default one for a type, it may be instantiated during the initialization. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write your custom Signature Component, which would be instantiated after the theme is set. | > > | If a modifier is associated to a task parameter in the task constructor, like in the example above, it is instantiated during initialization, when the task is created. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write a custom Signature Component instead, which would be instantiated after the theme is set. | |
| | protected Map<TaskParameter, Modifier> makeModifierMap() {
SignatureApi signature = getSignature(); | |
< < | Map<TaskParameter, Modifier> map =
new LinkedHashMap<TaskParameter, Modifier>(); | > > | Map<TaskParameter, Modifier> m = new LinkedHashMap<TaskParameter, Modifier>(); | | | |
< < | map.put(signature.getTaskParameter("file"), new JFilePathModifier(SAVE));
map.put(signature.getTaskParameter("number"), new JIntegerModifier()); | > > | m.put(signature.getTaskParameter("file"), new JFilePathModifier(SAVE));
m.put(signature.getTaskParameter("number"), new JIntegerModifier()); | | | |
< < | return map; | > > | return m; | | }
}
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | The Modifier for the first Parameter of the crop task:
 | |
< < | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double so there's still a lot of space for improvements and contribution. | > > | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double and few more, so there's still a lot of space for improvements and contribution. | | | |
< < | If your Task Parameter isn't one of the mentioned types you need to: | > > | If your Task Parameter isn't one of the mentioned types, you could: | |
- Implement a Modifier
- Register it to the system.
| |
> > |
Alternatively, you could want to write your specific Modifier for one of the already available types. In that case, you could skip the registration, and just create your modifier in your Java code within a custom Signature Component.
In package herschel.ia.gui.apps.modifier you can find the general available modifiers. | |
Implement a Modifier
| |
< < | The Modifier interface consists of two explicit contracts | > > | The Modifier interface consists of two explicit contracts: | |
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
| |
< < | and two implicit contracts inherited by the %EXTENSION_REGISTRY% | > > | and two implicit contracts: | | | |
< < |
- Have an empty constructor
| > > | | |
Register a Modifier
| |
< < | The registration of the Modifier is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.modifier). | > > | The registration of the Modifier is done again in the __init__.py via the Extension Registry with the usual syntax (please note the name of the factory: factory.modifier). | |
Be aware that the registration is system wise so the registration overrides any other registered modifier for that type. | | parameter.setModifier(new MyModifer());
| |
> > | If your Modifier is registered as the default one for a type, it may be instantiated during the initialization. This means that the JComponents used for your Modifier may not have the same GUI theme than the application, because the GUI theme is set just after the initialization of the registry. In that case, you may consider to write your custom Signature Component, which would be instantiated after the theme is set. | |
| | Map<TaskParameter, Modifier> map =
new LinkedHashMap<TaskParameter, Modifier>(); | |
< < | map.put(signature.getTaskParameter("file"), new JFilePathModifier()); | > > | map.put(signature.getTaskParameter("file"), new JFilePathModifier(SAVE)); | | map.put(signature.getTaskParameter("number"), new JIntegerModifier());
return map; | | }
| |
< < | In package herschel.ia.gui.apps.modifier you can find more general available modifiers. | |
Register a Task Signature Component |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The TaskSignatureComponent interface consists of four explicit contracts | |
< < |
- Support the setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display ( the setSignature)
- Return a map of parameters and assigned values ( the getParameters note return value ca be simplified to Map<TaskParameter, VariableSelection> )
| > > |
- Support the
setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display (
setSignature )
- Return a map of parameters and assigned values (in
Map<TaskParameter, VariableSelection> getParameters )
| |
- Clear and check user inputs (used by the default buttons)
and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
| |
> > |
An easy way of implementing TaskSignatureComponent is by extending JTaskSignatureComponent and providing your own implementation for the makeModifierMap() method.
For example, if you want to use a custom Signature Component that just wants to use JFilePathModifier for a parameter aimed for a file name, you could do it like this:
public class MySignatureComponent extends JTaskSignatureComponent {
private static final long serialVersionUID = 1L;
protected Map<TaskParameter, Modifier> makeModifierMap() {
SignatureApi signature = getSignature();
Map<TaskParameter, Modifier> map =
new LinkedHashMap<TaskParameter, Modifier>();
map.put(signature.getTaskParameter("file"), new JFilePathModifier());
map.put(signature.getTaskParameter("number"), new JIntegerModifier());
return map;
}
}
In package herschel.ia.gui.apps.modifier you can find more general available modifiers. | |
Register a Task Signature Component |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
 | |
< < | | | <-- summary -->
Tools are processing units that operate on specific data elements.
From the Java point of view, a tool is an implementation of the Tool interface. | | If a data element is selected, a list of tools that can operate on that data should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialog for settings parameters (for task tools). | |
> > | | | This section explains:
- how you can create a Tool and register it for being available for dedicated data
- how you can make HIPE aware of an existing Task,
| |
Triggering Events | |
< < | For a full detailed section about triggering events have a look at DpHipeEventExecution | > > | For a full detailed section about triggering events have a look at DpHipeCommonUtilities | |
<-- Author: JorgoBakker - 21 Dec 2007 --> |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- Assign the Task to display ( the setTask)
- Notify request of executions to the framework by
- Allow for setting the Site Event handler for notifying request of execution (the setSiteEventHandler method )
| |
< < | | > > | | | and the two implicit contracts inherited by the Extension Registry
- Be JComponent
- Have an empty constructor
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
> > | <--
Some short-cuts
--> | |
<-- summary --> | |
< < | Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. If a data element is selected, a list of tools that can operate on that data should appear. Double clicking on the tool will open a dialog for settings parameters. | > > | Tools are processing units that operate on specific data elements.
From the Java point of view, a tool is an implementation of the Tool interface.
The well-known Tasks are examples of tools within HIPE. In this case, TaskTool is used under the hoods.
If a data element is selected, a list of tools that can operate on that data should appear.
Double clicking on the tool will open an associated view (for non-task tools) or a dialog for settings parameters (for task tools). | |
This section explains: | |
> > |
- how you can create a Tool and register it for being available for dedicated data
| |
- how you can make HIPE aware of an existing Task,
- how your task can react better on an active data element,
| |
< < |
- the default task dialog and how you implement and contribute a dedicated the input dialog for your task,
| > > |
- the default task dialog and how you implement and contribute a dedicated input dialog for your task,
| |
- how you can implement and contribute a specific parameter editor
| |
| |
< < | | |
| |
< < | <--
Some short-cuts
--> | > > | Adding a Task as a Tool | | | |
< < | Task Registry | > > | Task Registry | |
Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.:
| |
| |
< < | Prime input validation | > > | Prime input validation | |
The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | |
- make your task appear as a tool within HIPE that can be ran against specific data.
| |
< < | Tools dialog | > > | Task Dialogs
Default Task Dialog | |
The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | |
| |
< < | Parameter Modifiers | > > | Parameter Modifiers | |
The system provides a default dialog displaying an input area for setting the values of the parameter based on a composition of Modifiers | |
- Register it to the system.
| |
< < | Implement a Modifier | > > | Implement a Modifier | |
The Modifier interface consists of two explicit contracts
- Support the drag and drop features (the set/getVariableSelection)
| |
- Have an empty constructor
| |
< < | Register a Modifier | > > | Register a Modifier | |
The registration of the Modifier is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.modifier). | |
| |
< < | Signature Components | > > | Signature Components | |
In case the default input area based on Modifiers doesn't fit your needs you can just replace it by your own implementation. | |
- Implement a Task Signature Component
- Register it to the system.
| |
< < | Implement a Task Signature Component | > > | Implement a Task Signature Component | |
The TaskSignatureComponent interface consists of four explicit contracts | |
- Have an empty constructor
| |
< < | Register a Task Signature Component | > > | Register a Task Signature Component | |
| | | |
< < | Task Dialogs | > > | Custom Task Dialogs | | Eventually, if the above options still do not accommodate you needs you can replace the the default Task Panel with your own implementation
If this is the case you need to:
- Implement a Task Panel
- Register it to the system.
| |
< < | Implement a Task Panel | > > | Implement a Task Panel | |
The TaskPanel interface consists of three explicit contracts | |  | |
< < | Register a Task Panel | > > | Register a Task Panel | |
| |
| |
< < | Triggering Events
For a full detailed section about triggering events have alook at DpHipeEventExecution
Task compliance | > > | Task compliance | |
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- the name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
| |
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| |
< < | <-- Author: JorgoBakker - 21 Dec 2007 --> | > > | Adding a Tool that is not a Task
If you have an existing task and want to make it available in HIPE, you just need to follow the steps described in the above section.
Now, a task has its limitations. It is somewhat an atomic operation for which you provide some inputs and expect some result.
Therefore, it is not expected for acting interactively with a user, and it is not meant for holding internal status either, that a user can modify during its execution.
If you need more flexibility, you can write your own implementation of the Tool interface.
Besides, you would most probably need a viewer associated to your tool, for letting the user interact with it.
This follows in some way the MVC pattern: your target data is the Model, your associated viewer is the View, and your tool is the Controller.
Tool Implementation
The Tool interface is simple:
public interface Tool {
// Known categories to which a tool may belong to
public enum Category { SPIRE, PACS, HIFI, GENERAL, IMAGE }
// Get the tool name
String getName();
// Get the actual object that does the work
Object getToolObject();
// Set the actual object that does the work
void setToolObject(Object o);
// Get an array of categories to which this tool belongs to
Category[] getCategories();
// Return the prime input parameter
Parameter getPrimeInput();
}
You provide the variable types you are interested in within the prime input: just return a ToolParameter initiated with the proper class of data you want to handle.
private ToolParameter _prime = new ToolParameter("data", MyTargetDataType.class);
public Parameter getPrimeInput() { return _prime; }
The actual job to be done can be delegated to a third object (the "tool object"), or just be executed by the tool class itself.
In this latter case, the method Object getToolObject() should return this .
Moreover, you may return the categories you think the tool is meaningful for, through the proper implementation of Category[] getCategories() .
Tool Viewer
Every tool has an associated viewer, which must implement EditorComponent (by extending AbstractEditorComponent or one of its subclasses).
Tool Registry
Once you have your tool and the corresponding viewer, you need to register them like this:
# Associate the tool with the viewer
REGISTRY.register(COMPONENT,Extension(
"My Tool",
"herschel.path.to.MyToolComponent",
"factory.editor.tool",
"herschel.path.to.MyTool"))
# Register the tool so it is automatically available for the proper variables in HIPE
from herschel.ia.gui.kernel import ToolFactory
from herschel.path.to import MyTool
ToolFactory.register(MyTool())
Communicating Tool & Viewer
In the viewer, you can access the tool and the selected data within the makeEditorContent method provided by AbstractEditorComponent .
At this point, you can let the tool know about the viewer as well, if you want:
protected boolean makeEditorContent() {
// Get the tool and the selected data
ToolSelection selection = getSelection();
Tool tool = selection.getTool();
Object data = selection.getSelection().getValue();
// Optional - you would need to provide a setViewer method
((MyTool)tool).setViewer(this);
// Build the editor contents ...
}
| | | |
> > | Simple sample
This simple reproducible example wraps up the just explained steps altogether.
It is just a button whose label is changed by the tool when the user clicks on it:
1. The tool class
public class ButtonTool implements Tool {
private Category[] _categories = { Category.GENERAL };
private ToolParameter _prime = new ToolParameter("data", ArrayData.class);
private ArrayData _data;
private boolean _flag = true;
public Category[] getCategories() {
return _categories;
}
public String getName() {
return "Button Tool";
}
public Parameter getPrimeInput() {
return _prime;
}
public Object getToolObject() {
return this;
}
public void setToolObject(Object o) {
// do nothing
}
public void setData(ArrayData data) {
_data = data;
}
void updateLabel(JButton button) {
int size = _data.getSize();
int rank = _data.getRank();
button.setText("Data has " + (_flag? "size " + size : "rank " + rank));
_flag = !_flag;
}
}
2. The viewer class
public class ButtonToolComponent extends AbstractEditorComponent<ToolSelection> {
private static final long serialVersionUID = 1L;
private static int _counter = 1;
private ButtonTool _tool;
public ButtonToolComponent() {
super(new BorderLayout());
}
protected Class<ToolSelection> getSelectionType() {
return ToolSelection.class;
}
protected boolean makeEditorContent() {
final JButton button = new JButton();
setName("Button Tool " + _counter++);
_tool = (ButtonTool)getSelection().getTool();
_tool.setData((ArrayData)getSelection().getSelection().getValue());
_tool.updateLabel(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_tool.updateLabel(button);
}
});
add(button);
return true;
}
public Icon getComponentIcon() {
return IconLibrary.VARIABLE;
}
}
3. The registration
REGISTRY.register(COMPONENT,Extension(
"Button Tool",
"herschel.your.package.ButtonToolComponent",
"factory.editor.tool",
"herschel.your.package.ButtonTool"))
from herschel.ia.gui.kernel import ToolFactory
from herschel.your.package import ButtonTool
ToolFactory.register(ButtonTool())
4. Executing the example
For executing this simple tool, just include it in a package owned by you, open the workbench in HIPE, and execute the following in the console:
x = Int1d.range(12)
y = Double2d([[1,2,3],[4,5,6]])
Then open the x and y variables with the Button Tool and click the button: its label is updated by the tool.
Triggering Events
For a full detailed section about triggering events have a look at DpHipeEventExecution
<-- Author: JorgoBakker - 21 Dec 2007 --> | |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
class ComputeTask extends Task {
ComputeTask() {
| |
< < | super(compute); | > > | super("compute"); | | prime=new TaskParameter("spectrum",SpecificProduct.class)
:
getSignature().setPrimeInput(prime) |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Task Registry | |
For PCSS (PACS' builds) users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | |
< < | You can also specify that your task belongs to one or more categories ###http://www.rssd.esa.int/SD-general/Projects/Herschel/hscdt/releases/doc/api/herschel/ia/gui/kernel/Tool.Category.html: | > > | You can also specify that your task belongs to one or more Category : | |
from herschel.ia.gui.kernel.Tool import Category
TaskToolFactory.register(compute, [Category.IMAGE, Category.PACS]))
| |
Within your task, you can control which parameter signs-up to be the prime parameter (the one which reacts on a selected data variable) by the Task API:
| |
< < | class MyTask extends Task {
MyTask() { | > > | class ComputeTask extends Task {
ComputeTask() {
super(compute); | | prime=new TaskParameter("spectrum",SpecificProduct.class)
:
getSignature().setPrimeInput(prime) | | }
| |
< < | One more thing. If you call super("My Task") within the constructor of class "MyTask", do not have any spaces between the string because this string is the name of the task in HIPE. Thus you should use super("MyTask") instead. | > > | Naming conventions for task when to be registered in Hipe should follow this example assuming that the task will perform the functionality named "reduce" :
Name of the Class : ReduceTask
Name of the Task (getName()) : reduce
Name of the variablein Jython : reduce
| |
Prime input validation |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.:
# __init__.py file
| |
< < | myTask=MyTask() | > > | compute=ComputeTask() | |
To make your task appear in the "Run Tools" view, you need to add the following lines:
from herschel.ia.task.views import TaskToolFactory
| |
< < | TaskToolFactory.register(MyTask()) | > > | TaskToolFactory.register(compute) | |
For PCSS (PACS' builds) users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | |
< < | You can also specify that your task belongs to one or more categories: | > > | You can also specify that your task belongs to one or more categories ###http://www.rssd.esa.int/SD-general/Projects/Herschel/hscdt/releases/doc/api/herschel/ia/gui/kernel/Tool.Category.html: | |
from herschel.ia.gui.kernel.Tool import Category
| |
< < | TaskToolFactory.register(MyTask(), [Category.IMAGE, Category.PACS])) | > > | TaskToolFactory.register(compute, [Category.IMAGE, Category.PACS])) | |
Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task! |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
| |
< < | import Category | > > | Triggering Events
For a full detailed section about triggering events have alook at DpHipeEventExecution | | Task compliance
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
You can also specify that your task belongs to one or more categories:
| |
< < | from herschel.ia.kernel.Tool import Category | > > | from herschel.ia.gui.kernel.Tool import Category | | TaskToolFactory.register(MyTask(), [Category.IMAGE, Category.PACS]))
Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task! | |
| |
< < | | > > | import Category | | Task compliance
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | }
}
| |
> > |
One more thing. If you call super("My Task") within the constructor of class "MyTask", do not have any spaces between the string because this string is the name of the task in HIPE. Thus you should use super("MyTask") instead. | |
Prime input validation |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | myTask=MyTask()
| |
< < | To make your task appear in the "Run Tools" view, you have to change the above by: | > > | To make your task appear in the "Run Tools" view, you need to add the following lines: | |
from herschel.ia.task.views import TaskToolFactory
TaskToolFactory.register(MyTask())
| |
> > | For PCSS (PACS' builds) users, this __init__.py file is located at $install_dir/data/toolbox/your_sub_system. | | You can also specify that your task belongs to one or more categories:
from herschel.ia.kernel.Tool import Category
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- Have an empty constructor
| |
> > | The Rotate Panel example (herschel.ia.task.example.RotatePanel):
 | | Register a Task Panel
| | | |
> > |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Task Panel" date="1203583605" name="rotate_panel.jpg" path="rotate_panel.jpg" size="6678" user="Main.NicolaDeCandussio" version="1" |
| |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1203070875" name="crop_input.jpg" path="crop_input.jpg" size="17033" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
| |
> > | <--
Some short-cuts
--> | | Task Registry
Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.: | | The Modifier interface consists of two explicit contracts
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
| |
< < | and two implicit contracts inherited by the ExtensionRegistry | > > | and two implicit contracts inherited by the %EXTENSION_REGISTRY% | |
- Be JComponent
- Have an empty constructor
| |
- Assign the Signature to display ( the setSignature)
- Return a map of parameters and assigned values ( the getParameters note return value ca be simplified to Map<TaskParameter, VariableSelection> )
- Clear and check user inputs (used by the default buttons)
| |
< < | and the two implicit contracts inherited by the ExtensionRegistry | > > | and the two implicit contracts inherited by the Extension Registry | |
- Be JComponent
- Have an empty constructor
| |
| |
< < | The registration of the Task Signature Component is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | > > | The registration of the Task Signature Component is done again in the __init__.py via the Extension Registry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | |
REGISTRY.register(COMPONENT,Extension(
"Rotate Signature",
| | "factory.editor.tool.task.signature",
"herschel.ia.image.Rotate"))
| |
< < | , where:
- id is a unique identifier
- implSignatureComponent - implementation of
SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
| | | |
< < | See also the Extension Registry documentation for more details. | > > |
See also the Extension Registry documentation for more details. | |
| | The TaskPanel interface consists of three explicit contracts
- Support the setVariableSelection for initial assignment from the Tool Window
- Assign the Task to display ( the setTask)
| |
< < |
- Set the SiteEvent handler for notifying request of execution (the setSiteEventHandler)
and the two implicit contracts inherited by the ExtensionRegistry | > > |
- Notify request of executions to the framework by
- Allow for setting the Site Event handler for notifying request of execution (the setSiteEventHandler method )
- Notify the execution requests calling the trigger method of SiteEventHandler
passing ExecutionRequestEvent (a viable implementation called TaskExecutionEvent is available.
and the two implicit contracts inherited by the Extension Registry | |
- Be JComponent
- Have an empty constructor
| |
| |
< < | The registration of the Task Panel Component is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | > > | The registration of the Task Panel Component is done again in the __init__.py via the Extension Registry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | |
REGISTRY.register(COMPONENT,Extension(
| |
< < | "Default Task Panel",
"herschel.ia.task.gui.dialog.JTaskPanel", | > > | "Rotate Task Panel",
"herschel.ia.task.example.RotatePanel", | | "factory.editor.tool.task", | |
< < | "herschel.ia.task.Task")); | > > | "herschel.ia.image.Rotate")); | | | |
< < | , where:
- id is a unique identifier
- implSignatureComponent - implementation of
SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
| | | |
< < | See also the Extension Registry documentation for more details. | > > |
See also the Extension Registry documentation for more details. | |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | Modifier . | |
< < | One of the Modifier in the input area for the crop task:
| > > | The first Modifier of the input area for the crop task:
| |
Currently the system contains basic implementation for the simple types Integer, Float, Long, Double so there's still a lot of space for improvements and contribution. | |
< < | If your Task Parameter doesn't follow into the mentioned types you need to: | > > | If your Task Parameter isn't one of the mentioned types you need to: | |
- Implement a Modifier
- Register it to the system.
Implement a Modifier
| |
< < | The modifier interface consists of two explicit contracts | > > | The Modifier interface consists of two explicit contracts | |
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
and two implicit contracts inherited by the ExtensionRegistry | |
Signature Components | |
< < | | | | |
< < | | > > | In case the default input area based on Modifiers doesn't fit your needs you can just replace it by your own implementation. | |
Rotate Alternative Signature:
 | |
< < | For that you can implement a herschel.ia.task.gui.dialog.SignatureComponent and register it as follows (again in the __init__.py ): | > > | If this is the case you need to:
- Implement a Task Signature Component
- Register it to the system.
Implement a Task Signature Component
The TaskSignatureComponent interface consists of four explicit contracts
- Support the setVariableSelection for initial assignment from the Tool Window
- Assign the Signature to display ( the setSignature)
- Return a map of parameters and assigned values ( the getParameters note return value ca be simplified to Map<TaskParameter, VariableSelection> )
- Clear and check user inputs (used by the default buttons)
and the two implicit contracts inherited by the ExtensionRegistry
- Be JComponent
- Have an empty constructor
Register a Task Signature Component
The registration of the Task Signature Component is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | |
REGISTRY.register(COMPONENT,Extension(
| |
< < | id, # string
implSignatureComponent, # string
"factory.editor.tool.task",
implTask)); # string | > > | "Rotate Signature",
"herschel.ia.task.example.RotateSignatureComponent",
"factory.editor.tool.task.signature",
"herschel.ia.image.Rotate")) | |
, where:
- id is a unique identifier
- implSignatureComponent - implementation of
SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
| |
< < | An example (which you can find in the prototype): | > > | See also the Extension Registry documentation for more details.
Task Dialogs
Eventually, if the above options still do not accomodate you needs you can replace the the default Task Panel with your own implemetation
If this is the case you need to:
- Implement a Task Panel
- Register it to the system.
Implement a Task Panel
The TaskPanel interface consists of three explicit contracts
- Support the setVariableSelection for initial assignment from the Tool Window
- Assign the Task to display ( the setTask)
- Set the SiteEvent handler for notifying request of execution (the setSiteEventHandler)
and the two implicit contracts inherited by the ExtensionRegistry
- Be JComponent
- Have an empty constructor
Register a Task Panel
The registration of the Task Panel Component is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.editor.tool.task.signature). | |
REGISTRY.register(COMPONENT,Extension(
| |
< < | "herschel.ia.gui.components.editor.tasks.RotateSignatureComponent",
"herschel.ia.gui.components.editor.tasks.RotateSignatureComponent", | > > | "Default Task Panel",
"herschel.ia.task.gui.dialog.JTaskPanel", | | "factory.editor.tool.task", | |
< < | "herschel.ia.image.Rotate")); | > > | "herschel.ia.task.Task")); | | | |
> > | , where:
- id is a unique identifier
- implSignatureComponent - implementation of
SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
| | See also the Extension Registry documentation for more details. | |
< < | Note that your GUI component must have a default constructor! | | | |
< < | Task Dialogs
The default dialog provided by the system is result of the composition of a main input area (TaskSignatureComponent) and a panel containing the buttons (JTaskButtonsPanel). The main panel is based | | Task compliance
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | |
< < | * The default dialog:
| > > | The default dialog for the crop task:
| |
As for instance you may want to have more control over how the input parameters are presented to the user: | |
Parameter Modifiers
| |
< < | The system provides a default dialog displaying an input area for setting the values of the parameter. Based on the type of the value of the Task Parameter the input area dinamically loads the most appropriated (and registered) component satisfying the contract of the | > > | The system provides a default dialog displaying an input area for setting the values of the parameter.
The input area for the crop task:
Based on the type of the value of the Task Parameter the input area dinamically loads the most appropriated (and registered) component satisfying the contract of the | | Modifier . | |
> > |
One of the Modifier in the input area for the crop task:
 | | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double so there's still a lot of space for improvements and contribution.
If your Task Parameter doesn't follow into the mentioned types you need to: | |
Register a Modifier
| |
< < | The registration of the Modifier is done again in the __init__.py via the ModifierFactory with the same syntax (please note the name of the factory: factory.modifier). | > > | The registration of the Modifier is done again in the __init__.py via theExtensionRegistry with the usual syntax (please note the name of the factory: factory.modifier).
Be aware that the registration is system wise so the registration overrides any other registered modifier. | |
REGISTRY.register(COMPONENT,Extension(
| | "factory.modifier",
"herschel.ia.MyClass")
| |
> > |
In case the Modifier you have created is only applicable to a specific task or even to a specific parameter of a specific task you can simply assign it to the Task Parameter itself:
// In your task constructor
TaskParameter parameter = new TaskParameter("input", String.class);
parameter.setModifier(new MyModifer());
| |
Signature Components | |
| |
> > |
Rotate Alternative Signature:
 | | For that you can implement a herschel.ia.task.gui.dialog.SignatureComponent and register it as follows (again in the __init__.py ):
REGISTRY.register(COMPONENT,Extension(
| | | |
> > |
META FILEATTACHMENT |
attr="" autoattached="1" comment="" date="1203070875" name="crop_input.jpg" path="crop_input.jpg" size="17033" user="Main.NicolaDeCandussio" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Rotate Alternative Signature" date="1203074625" name="rotate.jpg" path="rotate.jpg" size="19901" user="Main.NicolaDeCandussio" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
| |
> > |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="modifier" date="1203071348" name="crop_modifier.jpg" path="crop_modifier.jpg" size="16408" user="Main.NicolaDeCandussio" version="1" |
| |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="" date="1203007458" name="crop.jpg" path="crop.jpg" size="20487" user="Main.NicolaDeCandussio" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | |
> > | * The default dialog:
 | | As for instance you may want to have more control over how the input parameters are presented to the user:
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
- you may want to organize your parameters by grouping them in tabs, or putting a border around a group of parameters
| |
Parameter Modifiers
| |
< < | The system provides a default dialog displaying an input area for setting the values of the parameter. Based on the type of the value of the Task Parameter the input area dinamically load the most appropriated (and registered) component satisfying the contract of the | > > | The system provides a default dialog displaying an input area for setting the values of the parameter. Based on the type of the value of the Task Parameter the input area dinamically loads the most appropriated (and registered) component satisfying the contract of the | | Modifier . | |
< < | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double. | > > | Currently the system contains basic implementation for the simple types Integer, Float, Long, Double so there's still a lot of space for improvements and contribution. | | | |
> > | If your Task Parameter doesn't follow into the mentioned types you need to:
- Implement a Modifier
- Register it to the system.
Implement a Modifier
The modifier interface consists of two explicit contracts
- Support the drag and drop features (the set/getVariableSelection)
- Support the inspection for Object (the set/getObject)
and two implicit contracts inherited by the ExtensionRegistry
- Be JComponent
- Have an empty constructor
Register a Modifier
The registration of the Modifier is done again in the __init__.py via the ModifierFactory with the same syntax (please note the name of the factory: factory.modifier).
REGISTRY.register(COMPONENT,Extension(
"MyModifier",
"herschel.ia.mymodifier.MyModifier",
"factory.modifier",
"herschel.ia.MyClass")
| |
Signature Components | |
> > |
| | For that you can implement a herschel.ia.task.gui.dialog.SignatureComponent and register it as follows (again in the __init__.py ):
REGISTRY.register(COMPONENT,Extension(
| | See also the Extension Registry documentation for more details.
Note that your GUI component must have a default constructor! | |
> > | | |
Task Dialogs
The default dialog provided by the system is result of the composition of a main input area (TaskSignatureComponent) and a panel containing the buttons (JTaskButtonsPanel). The main panel is based | |
<-- Author: JorgoBakker - 21 Dec 2007 --> | |
< < |
META FILEATTACHMENT |
attachment="hipe-tools.jpg" attr="h" comment="Task, tools and variables" date="1198422542" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" stream="hipe-tools.jpg" user="Main.JorgoBakker" version="1" |
| > > |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="Task, tools and variables" date="1198422543" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" user="Main.JorgoBakker" version="1" |
META FILEATTACHMENT |
attr="h" autoattached="1" comment="" date="1203007458" name="crop.jpg" path="crop.jpg" size="20487" user="Main.NicolaDeCandussio" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- make your task appear as a tool within HIPE that can be ran against specific data.
| |
< < | Task Input Dialog | > > | Tools dialog | | | |
< < | Default dialog, drag-and-drop features, dedicated dialogs
The application is generating a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only
provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | | | |
< < | However, you may want to have more control over how the input parameters are presented to the user: | > > | The system generates a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes.
As for instance you may want to have more control over how the input parameters are presented to the user: | |
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
- you may want to organize your parameters by grouping them in tabs, or putting a border around a group of parameters
- you may want to have more informative tooltips, labels or even input fields that are more suitable for your task.
| |
> > | To adapt to these scenarios and more, the system provides three ways for customizing you Task dialogs:
- Parameter Modifiers
- Signature Components
- Task Dialogs.
Parameter Modifiers
The system provides a default dialog displaying an input area for setting the values of the parameter. Based on the type of the value of the Task Parameter the input area dinamically load the most appropriated (and registered) component satisfying the contract of the
Modifier .
Currently the system contains basic implementation for the simple types Integer, Float, Long, Double.
Signature Components | | For that you can implement a herschel.ia.task.gui.dialog.SignatureComponent and register it as follows (again in the __init__.py ):
REGISTRY.register(COMPONENT,Extension(
| | See also the Extension Registry documentation for more details.
Note that your GUI component must have a default constructor! | |
< < | | | | |
< < | Parameter Modifiers
TODO: Default modifiers, specialized modifiers
| > > | Task Dialogs
The default dialog provided by the system is result of the composition of a main input area (TaskSignatureComponent) and a panel containing the buttons (JTaskButtonsPanel). The main panel is based | |
Task compliance
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Prime input validation
| |
< < | The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct is selected. | > > | The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct (i.e. the type of the value of the Parameter) is selected. | |
Sometimes this may not be enough, e.g. is certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
<-- summary --> | |
< < | Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. If a data element is selected, a list of tools that can operate on that data should appear. | > > | Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. If a data element is selected, a list of tools that can operate on that data should appear. Double clicking on the tool will open a dialog for settings parameters. | |
This section explains:
- how you can make HIPE aware of an existing Task,
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
You can also specify that your task belongs to one or more categories:
| |
< < | from herschel.ia.core.Tool import Category | > > | from herschel.ia.kernel.Tool import Category | | TaskToolFactory.register(MyTask(), [Category.IMAGE, Category.PACS]))
Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task! | |
, where:
- id is a unique identifier
| |
< < | | > > |
- implSignatureComponent - implementation of
SignatureComponent interface
| |
- implTask - implementation of your task for which this input dialog applies
An example (which you can find in the prototype): | | Task compliance
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
| |
< < |
- the name of the task should be a legal variable name in the global name-space. For example your instance of MyTask should report itself as e.g.: "myTask" and not "This is my task".
| > > |
- the name of the task should be a legal variable name in the global name-space. For example your instance of
MyTask should report itself as e.g.: "myTask" and not "This is my task".
| |
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
- id is a unique identifier
- implSignatureComponent - implementation of SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
| |
< < | and the registry elements are defined as:
from herschel.ia.core import ExtensionRegistry, Extension
FACTORY=ExtensionRegistry.FACTORY
COMPONENT=ExtensionRegistry.COMPONENT
REGISTRY=ExtensionRegistry.getInstance()
| |
An example (which you can find in the prototype):
| | "factory.editor.tool.task",
"herschel.ia.image.Rotate"));
| |
> > | See also the Extension Registry documentation for more details. | |
Note that your GUI component must have a default constructor!
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
Task Registry | |
< < | | > > | | | Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.:
# __init__.py file
| | }
}
| |
> > | | |
Prime input validation | |
> > | | | The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct is selected.
Sometimes this may not be enough, e.g. is certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected... | | In other words, rather than writing this logic within the pre-amble or execution block of your task, we recommend you to move that logic into the parameter validation. This way we achieve two things:
- make the logic appear where it should be and therefore keeping the execution block of your task concentrated to the algorithm, and
- make your task appear as a tool within HIPE that can be ran against specific data.
| |
> > | | |
Task Input Dialog | |
> > | | | Default dialog, drag-and-drop features, dedicated dialogs
The application is generating a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only
provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes. | |
Note that your GUI component must have a default constructor! | |
> > | | |
Parameter Modifiers | |
> > | | | TODO: Default modifiers, specialized modifiers | |
> > | | |
Task compliance | |
> > | | |
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- the name of the task should be a legal variable name in the global name-space. For example your instance of MyTask should report itself as e.g.: "myTask" and not "This is my task".
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| |
> > | | | | |
< < | -- JorgoBakker - 21 Dec 2007 | > > | <-- Author: JorgoBakker - 21 Dec 2007 --> | |
META FILEATTACHMENT |
attachment="hipe-tools.jpg" attr="h" comment="Task, tools and variables" date="1198422542" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" stream="hipe-tools.jpg" user="Main.JorgoBakker" version="1" |
|
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | | getSignature().setPrimeInput(prime)
}
} | |
< < | public void setParameterValidator(ParameterValidator validator) {
_validator = validator;
} | |
Prime input validation | | You can write a ParameterValidator to do just that:
prime=new TaskParameter("spectrum",SpecificProduct.class)
| |
< < | validator=new ParameterValidator() {
public boolean isValid(Object value) {
SpecificProduct s=(SpecificProduct)value;
...logic that would validate the contents of the value...
} | > > | prime.setValidator(new ParameterValidatorAdapter() { | | public void validate(Object value) throws ParameterValidationException { | |
< < | if (isValid(value)) throw new ParameterValidationException(reason); | > > | SpecificProduct s=(SpecificProduct)value;
if (! (logic that would validate the contents of the value...)) {
throw new ParameterValidationException(reason); | | }
} | |
> > | }); | |
In other words, rather than writing this logic within the pre-amble or execution block of your task, we recommend you to move that logic into the parameter validation. This way we achieve two things: |
|
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE | |
> > |  | |
<-- summary --> | |
< < | Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. This section explains: | > > | Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. If a data element is selected, a list of tools that can operate on that data should appear.
This section explains: | |
- how you can make HIPE aware of an existing Task,
- how your task can react better on an active data element,
- the default task dialog and how you implement and contribute a dedicated the input dialog for your task,
| |
| |
> > |
| | Task Registry | |
< < | Task factory, __init_ .py, categories,..._ | > > |
Up to now you have made you task globally available to the system by specifying an instance of that task within the __init__.py file of your sub-system, e.g.:
# __init__.py file
myTask=MyTask()
To make your task appear in the "Run Tools" view, you have to change the above by:
from herschel.ia.task.views import TaskToolFactory
TaskToolFactory.register(MyTask())
You can also specify that your task belongs to one or more categories:
from herschel.ia.core.Tool import Category
TaskToolFactory.register(MyTask(), [Category.IMAGE, Category.PACS]))
Your task will now be enabled whenever a session variable is selected which matches the type of the first input parameter within your task!
Within your task, you can control which parameter signs-up to be the prime parameter (the one which reacts on a selected data variable) by the Task API:
class MyTask extends Task {
MyTask() {
prime=new TaskParameter("spectrum",SpecificProduct.class)
:
getSignature().setPrimeInput(prime)
}
}
public void setParameterValidator(ParameterValidator validator) {
_validator = validator;
}
| |
Prime input validation | |
< < | Writing a validator for the contents of your prime data input | > > | The mechanism above makes you task to become a tool within the system and it appears whenever a variable of type SpecificProduct is selected.
Sometimes this may not be enough, e.g. is certain situations your task will only run on a SpecificProduct if it contains certain contents. A typical situation would be when a SPIRE reduction operates on a ObservationContext: such a task should not be listed whenever a HIFI observation is selected...
You can write a ParameterValidator to do just that:
prime=new TaskParameter("spectrum",SpecificProduct.class)
validator=new ParameterValidator() {
public boolean isValid(Object value) {
SpecificProduct s=(SpecificProduct)value;
...logic that would validate the contents of the value...
}
public void validate(Object value) throws ParameterValidationException {
if (!isValid(value)) throw new ParameterValidationException(reason);
}
}
In other words, rather than writing this logic within the pre-amble or execution block of your task, we recommend you to move that logic into the parameter validation. This way we achieve two things:
- make the logic appear where it should be and therefore keeping the execution block of your task concentrated to the algorithm, and
- make your task appear as a tool within HIPE that can be ran against specific data.
| |
Task Input Dialog
Default dialog, drag-and-drop features, dedicated dialogs | |
> > | The application is generating a default input dialog for all registered tasks within the software. As the system does not know the intent of your task, it can only
provide a dry-listing of all requested parameters; such a dialog may not be suitable for your purposes.
However, you may want to have more control over how the input parameters are presented to the user:
- you may only want to provide a sub-set of parameters (and leave the full-set to expert users on the command-line)
- you may want to organize your parameters by grouping them in tabs, or putting a border around a group of parameters
- you may want to have more informative tooltips, labels or even input fields that are more suitable for your task.
For that you can implement a herschel.ia.task.gui.dialog.SignatureComponent and register it as follows (again in the __init__.py ):
REGISTRY.register(COMPONENT,Extension(
id, # string
implSignatureComponent, # string
"factory.editor.tool.task",
implTask)); # string
, where:
- id is a unique identifier
- implSignatureComponent - implementation of SignatureComponent interface
- implTask - implementation of your task for which this input dialog applies
and the registry elements are defined as:
from herschel.ia.core import ExtensionRegistry, Extension
FACTORY=ExtensionRegistry.FACTORY
COMPONENT=ExtensionRegistry.COMPONENT
REGISTRY=ExtensionRegistry.getInstance()
An example (which you can find in the prototype):
REGISTRY.register(COMPONENT,Extension(
"herschel.ia.gui.components.editor.tasks.RotateSignatureComponent",
"herschel.ia.gui.components.editor.tasks.RotateSignatureComponent",
"factory.editor.tool.task",
"herschel.ia.image.Rotate"));
Note that your GUI component must have a default constructor! | |
Parameter Modifiers | |
< < | Default modifiers, specialized modifiers | > > | TODO: Default modifiers, specialized modifiers | |
Task compliance | |
< < | Name of the task, validator, user documentation | > > |
- write user documentation (jtags)! That will be automatically picked up whenever a user asks the system for help on your task.
- the name of the task should be a legal variable name in the global name-space. For example your instance of MyTask should report itself as e.g.: "myTask" and not "This is my task".
- if your prime parameter is not the first parameter in your task, specify the prime parameter using the
setPrimeInput method in the signature
- write a parameter validator for your prime parameter if your task should be listed not only on prime data type but on prime data contents as well.
| |
-- JorgoBakker - 21 Dec 2007
\ No newline at end of file | |
> > |
META FILEATTACHMENT |
attachment="hipe-tools.jpg" attr="h" comment="Task, tools and variables" date="1198422542" name="hipe-tools.jpg" path="hipe-tools.jpg" size="13675" stream="hipe-tools.jpg" user="Main.JorgoBakker" version="1" |
|
|
> > |
META TOPICPARENT |
name="DpHipe" |
Adding Tools to HIPE
<-- summary -->
Tools are processing units that operate on specific data elements. The well-known Tasks are examples of tools within HIPE. This section explains:
- how you can make HIPE aware of an existing Task,
- how your task can react better on an active data element,
- the default task dialog and how you implement and contribute a dedicated the input dialog for your task,
- how you can implement and contribute a specific parameter editor
Task Registry
Task factory, __init_ .py, categories,..._
Prime input validation
Writing a validator for the contents of your prime data input
Task Input Dialog
Default dialog, drag-and-drop features, dedicated dialogs
Parameter Modifiers
Default modifiers, specialized modifiers
Task compliance
Name of the task, validator, user documentation
-- JorgoBakker - 21 Dec 2007 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|