Scripting in scuba is similar to tkmedit, except that it is less atrocious. For starters, there's a nice shell available with tab completion and other niceties. Try it out. Also try PrintAllCommands in the shell to get a list of C-bound tcl commands. And of course, check out the scuba.tcl script for other useful functions.
Here is a sample script that loads up different surface files and saves screen captures.
set err [catch { # Get filenames together. set sSubjectName [GetSubjectName] set sSubjectDir [GetSubjectDir] set sSurfDir ${sSubjectDir}/surf set sSuffix hires set sSurface pial # Load the first surface, creating a layer for it. Save the layer ID # and get the collection ID. set fnSurface \ [file join $sSurfDir rh.${sSurface}.${sSuffix}[format "%04d" 0]] set bCreateLayer true set nFrameIDToAdd [GetMainFrameID] set layerID [LoadSurface $fnSurface $bCreateLayer $nFrameIDToAdd] set colID [Get2DMRISLayerSurfaceCollection $layerID] set min 0 set max 10 for { set nSurf $min } { $nSurf <= $max } { incr nSurf 1 } { # Make a new file name. set fnSurface \ [file join $sSurfDir rh.${sSurface}.${sSuffix}[format "%04d" $nSurf]] # Point the surface layer data to this new file and load it. Force a redraw. SetSurfaceCollectionFileName $colID $fnSurface LoadSurfaceFromFileName $colID UpdateFrame [GetMainFrameID] # Take a screen shot. set fnCapture ${sSubjectName}_${sSuffix}[format "%04d" $nSurf].tiff CaptureFrameToFile [GetMainFrameID] $fnCapture echo "Saved $fnCapture" } # end of catch } sResult] if { 0 != $err } { echo "Script failed: $sResult" } else { echo "Script complete." }
Let's go through it line by line.
set err [catch {
It's good to use try blocks in tcl to handle error messages nicely. Luckily it's pretty easy to do this. scuba tries to give helpful error messages, so this is somewhat fruitful. At the very least, it lets us nicely abort the script if something goes wrong; for example, if a file fails to load, the script will stop instead of continuing along and trying to draw an non-existent file.
# Get filenames together. set sSubjectName [GetSubjectName] set sSubjectDir [GetSubjectDir] set sSurfDir ${sSubjectDir}/surf set sSuffix hires set sSurface pial
Note the GetSubjectName and GetSubjectDir commands. These are defined in scuba.tcl. They only return anything useful if the -s option is used with scuba.
# Load the first surface, creating a layer for it. Save the layer ID # and get the collection ID. set fnSurface \ [file join $sSurfDir rh.${sSurface}.${sSuffix}[format "%04d" 0]] set bCreateLayer true set nFrameIDToAdd [GetMainFrameID] set layerID [LoadSurface $fnSurface $bCreateLayer $nFrameIDToAdd] set colID [Get2DMRISLayerSurfaceCollection $layerID]
Construct a file name and load a surface with the LoadSurface function in scuba.tcl. We tell it to create a corresponding layer for us; remember that we need a layer to draw a data collection. We add the layer to the main frame as well. We then get the collection ID because we'll need it later on. Inside LoadSurface, we created a MRIS data collection and gave it the fnSurface file name. We also created a layer and added it to the frame, and assigned the data collection to that layer.
set min 0 set max 10 for { set nSurf $min } { $nSurf <= $max } { incr nSurf 1 } { # Make a new file name. set fnSurface \ [file join $sSurfDir rh.${sSurface}.${sSuffix}[format "%04d" $nSurf]]
Note that for the first pass through, this file name will be the same one as we just loaded.
# Point the surface layer data to this new file. Force a redraw. SetSurfaceCollectionFileName $colID $fnSurface LoadSurfaceFromFileName $colID UpdateFrame [GetMainFrameID]
This part is important. We can reassign a file name for a data collection and reload it, effectively loading a new data set into the existing data collection object. This is preferable to deleting the layer and collection and creating a new one, as it is more efficient. The layer and layer settings survive, as do the association of data collection, layer, and view/frame. All that changes is the source data.
We use the UpdateFrame in function in scuba.tcl to tell the frame to redraw, and then wait until all events (i.e. draw events) are handled before continuing on. This lets the script 'pause' until we redraw the screen.
# Take a screen shot. set fnCapture ${sSubjectName}_${sSuffix}[format "%04d" $nSurf].tiff CaptureFrameToFile [GetMainFrameID] $fnCapture echo "Saved $fnCapture" }
This simply builds a capture file name and make a screen capture. Notice the .tiff extension, appropriate because the CaptureFrameToFile function makes tiff files.
# end of catch } sResult] if { 0 != $err } { echo "Script failed: $sResult" } else { echo "Script complete." }
And here we simply handle our catch result. Notice at the very top we assign the value of the catch command to the variable err. Now we check it. catching in tcl looks like this:
set err [catch { script... } sResult]
If the script throws an error, sResult will get the result string, and err will be set to non-zero. Otherwise err will be 0.