Possible to get the Parameter from a script (not the value of the parameter)

scijava
imagej2
scripting

#1

For example, say I have:

# @Boolean(label="my label" ) myBoolean

I’d like to get the label name of the parameter corresponding to myBoolean.
Is there a way to get the Parameter, so I can:

thelabel = myBooleanParameter.label()

?

Thanks as always!
John


#2

Good question, I tried a

print dir(myBoolean)

in Jython to get a list of the attribute but there are none that looks like what you are looking for.

['__class__', '__delattr__', '__doc__', '__ensure_finalizer__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__']

Maybe a SciJava package would allow you to retrieve that.
Sorry…


#3

You should be able to read the object annotations via reflections but maybe there is a built-in SciJava way to do it.

The link in your post has an additional y at the end (404).

Update: One thing to note is that it does not work for primtitive types as they are passed by value and the annotation information gets lost.

Update2: This kotlin example works for me:

fun getAnnotationLabel(obj: Any, field: String) : String?
{
	val field = obj::class.java.getDeclaredField(field)
	val annotation = field.getAnnotation(Parameter::class.java)
	val label = annotation?.label
	return label
}

#4

Otherwise you could use the GenericDialog class, in Jython :

from ij.gui import GenericDialog

Win = GenericDialog("Window")
Win.addCheckbox("Hello",True)
Win.showDialog()

Checkbox = Win.getCheckboxes()[0]
print Checkbox.label # -> Hello

#5

@hanslovsky

Have you tried that In an imagej2 script?
I’m not sure if reflection works there, because what is “this” object?

@LThomas, thanks for the suggestion, I can work around if necessary.

Though, the main thing I want to learn from this post is whether this is possible with scijava as it is now. For that I guess I need a scijava expert… @imagejan @ctrueden ?

John


#6

No I have not tried that. Hopefully, the scijava experts can tell what the equivalent of the this object is for that use case.


#7

@bogovicj Why do you want to extract the value of the label, instead of hardcoding it? Just to make your code more DRY?

Also: are you only interested in introspection of parameters? Or are you hoping to mutate some of the parameter attributes as well? Introspection is much more tenable than mutation, especially structural mutation (e.g. adding or removing parameters at execution time).

If all you care about is introspection, you can do it:

#@ String (label = "How should I greet you?", value = "Hello") greeting

println('-- Groovy introspection --')
println()
println('Available variables:')
binding.variables.each {k,v -> println "* $k = $v"}

println()
println('-- ScriptInfo introspection --')
println()
module = binding['org.scijava.script.ScriptModule']
info = module.getInfo()
println('script identifier = ' + info.getIdentifier())
println()
println('Inputs:')
for (input in info.inputs()) {
	println('* ' + input)
}
println()
println('Outputs:')
for (output in info.outputs()) {
	println('* ' + output)
}
println()
greetingInput = info.getInput('greeting')
greetingLabel = greetingInput.getLabel()
println("Label of greeting parameter is: " + greetingLabel)

// The return value of the script is stored into the default "result" output.
greeting + ", your majesty"

And here is the output:

Started Introspection.groovy at Wed Oct 31 10:44:22 CDT 2018
-- Groovy introspection --

Available variables:
* greeting = Hello
* context = javax.script.SimpleScriptContext@6a89e515
* org.scijava.script.ScriptModule = org.scijava.script.ScriptModule@3727b689
* javax.script.filename = /Users/curtis/Desktop/Introspection.groovy
* out = java.io.PrintWriter@2f5a63e7

-- ScriptInfo introspection --

script identifier = script:/Users/curtis/Desktop/Introspection.groovy

Inputs:
* greeting: label='How should I greet you?', required=true, persisted=true, default='Hello'

Outputs:
* result: required=true, persisted=true

Label of greeting parameter is: How should I greet you?

What you cannot do is write callbacks that trigger when things change, nor manipulate the structure of a ScriptModule during execution. The only block of code you can write is the one that runs upon final execution—after the OK button is pressed in the dialog. One thing that @imagejan and I discussed in the past is the ability to define Java classes in scripts and add them to the SciJava context. Then maybe you could code a DynamicCommand plugin in a script, which would be more powerful but also more complex to understand.

Finally, be warned this is a bit low level, undocumented, and potentially subject to change in the future. I do not know how stable the lower-level Module / ModuleInfo / ModuleItem will be in years ahead, as SciJava Common’s module framework is undergoing another design iteration.


#8

Thanks @ctrueden, this is great, much appreciated.

Exactly. I had in mind to reference variables by their label, and without the ability to fetch parameter labels, I’ve had to type/repeat the label in multiple places.

Yes, introspection only.

Good to know, I don’t want / need this for my use case.

Thanks once again.
John