So I've been working on my Bisque module -- specifically, I'm trying to make the output of the pollen-tube-tracker module immediately useful, at least a bit. (The module generates comprehensive output in CSV or XML form, but no one can read all that at a glance.) Specifically, what our pollen expert requested was a plot of pollen tube velocities, versus time. That sounds like a very reasonable request, no? He sketched out for me a simple cartoon, with one trace per tube, with tube velocity as the ordinate against time as the abscissa:
It turns out, that's not so easy.
How Bisque Works
One reason it isn't easy is because a Bisque module is doesn't get to speak directly to the users. I want to explain what I mean, so here's a little sketch of how the architecture looks from my perspective:
You, the biologist user, are running a browser and working through the interface Bisque provides. In this diagram, I'm "mod.py," a Python script that gets invoked every time the user picks my module to perform an analysis. My job is to mediate between Bisque and the binary executables (represented by engine.bin) that do the hard work. In the pollen-tube case, there are three binary executables, and they expect to run in a Unix environment, with their input in the form of named files (named just so) in a local filesystem. The engines need command-line arguments, and if anything goes wrong they send a message in English to standard output. Whereas Bisque, instead, gives me the URL of the input files. It gives me user parameters in a slightly different format (e.g., sizes could be in microns rather than pixels). It doesn't understand English error messages.
My job (as mod.py) is to be the bridge: download the images from the URLs and save them locally. Adapt the parameters. Run the engines and interpret their outputs. Detect errors. Translate engine output into a Bisque-acceptable response. Like any translator, this means mod.py has to understand both parties' "languages" and sometimes do a bit of extra explaining, but it's not that complicated. The Bisque developers have provided code to help out with the hardest parts, like that of downloading images and uploading XML output. Thus mod.py is roughly 700 lines of python -- not very long.
The high-level interface to the module is defined by a module-definition file, which is mdef.xml in the above diagram. It defines a module's inputs and outputs. This is how, for example, you the user can give me, the script, a bunch of numeric parameters to control the tracker. Inside mdef.xml there is a list of input parameters; when you choose my module, Bisque reads mdef.xml and lets you tweak the parameters before clicking the "run" button. When "run" fires, Bisque shunts those parameters over to mod.py.
So Where's My Chart?
It's not enough to say that mdef.xml spells out the input parameters for mod.py; more accurately, it acts as a contract between Bisque and mod.py. The output from mod.py, which is exclusively XML, must conform to the structure delineated in mdef.xml. So it defines the output interface (from mod.py and to Bisque), too. Bisque by default supports a few kinds of output. The output XML can define an overlay of aggregate graphical primitives (called GObjects) on the input image. You can produce some text-based summary output. And Bisque will always let you have the raw XML, if you ask for it.
If you want a chart, it gets a bit tricky. You can make simple charts by specifying a single xpath, which will extract a single vector of variables from the output. You can plot them, or draw a histogram, or a few other things, but mdef.xml is essentially an interface. An interface should answer the question "what is the output?" rather than "how do we make the output?"
Furthermore, mod.py cannot really generate a plot easily. Its job is to bridge between Bisque and the engine, not to offer reinterpretations of the engine output. (In fact I violate my own advice here a bit, because my module does augment the engine output with a reinterpretation that lacks the time dimension. I call the outputs "time-indexed" and "time-collapsed," because it's easier to visualize the time-collapsed output in Bisque, although the time-indexed one is more complete. It's kind of a hack. If possible I'd like to eliminate that behavior.)
Not quite there