Was this page helpful?

What are hooks and how can I customize radR with them?

From $1

    You can have radR run your own code from several places in the processing loop.  These places are called hooks, and you can "hang" your own functions from them for radR to execute (morbid terminology acknowledged).   These hook functions  are also called hooks, when it isn't confusing.

    Example:

    Goal: have radR print the data timestamp to the console each time meta-data for a scan are read.

    Solution:

    rss.add.hook("SCAN_INFO", function(si) gui.print.cons(si$timestamp))

    This is formatted as a single line to ease copy/pasting it into the radR window (don't forget to hit Enter).
    Here is a detailed explanation:

     

    rss.add.hook(   ## call the function responsible for adding user hook functions to radR

    "SCAN_INFO", ## the first parameter is the name of the hook; i.e. the location of the predefined
                 ## point in radR processing from where your function will be called.  This one
                 ## corresponds to the point where radR has just finished reading the scan meta-data
                 ## from its current data source, but before the scan data themselves have been read.
                 ## (meta-data are things like timestamp, number of pulses, pulse length, and so on)         

     

    function(si) ## the next parameter is your function.  In this case, the hook will call your function with a single
                 ## parameter, namely the list with scan meta-data.  Each hook calls its hook functions with
                 ## a fixed, pre-determined list of parameters, but your function is free to ignore them by
                 ## using "..." as its parameter list:  function(...) instead of function(si)

    gui.print.cons( ## this is the first (and only) statement of your function.  If it is to have more than one
                    ## statement, these must be surrounded in braces:  function(...) { statements }
    ## Many built-in radR functions begin with gui. which means they are related to the user interface.
                    ## gui.print.cons  is a function whose job is to print an R object to the radR gui console.
                    ## unix users can avoid this and simply use print to send the object to the terminal window.

    si$timestamp    ## this extracts the timestamp element from the meta-data item passed to your function.
                    ## si is a list with named elements, and this element contains the date/time for the
                    ## first pulse in the scan.  This is stored internally as the number of seconds elapsed since
                    ## the midnight between Dec. 31 1969 and Jan. 1, 1970 in the Greenwich timezone.

    ))              ## remember to close any parentheses opened earlier.


    List of radR Hooks

    The complete list of radR hooks is found in the file radR/main/radRshared.h   Here is the list as of Nov., 2008:

        ANTENNA_CONFIG    
        BEGIN_SCAN        
        BLIP              
        CLASSIFY          
        DONE_SCAN         
        END_SINK          
        END_SOURCE        
        FIND_PATCHES      
        FULL_SCAN         
        GET_SCAN_DATA     
        GET_SCAN_DATA_NAMES
        GET_SCAN_INFO     
        ONEXIT            
        ONPAUSE           
        ONPLAY            
        ONSTOP            
        PAINT_BACKGROUND  
        PATCH             
        PATCH_STATS       
        PLOT_CURSOR_MOVED 
        POST_SCAN_CONVERT 
        PRE_SCAN_CONVERT  
        PUT_SCAN_DATA     
        RAW_BLIPS         
        SCAN_INFO         
        SCAN_ROW          
        SCORES            
        START_SINK        
        START_SOURCE      
        STATS             
        TK_PLOT_MODE      
        TRACK             
        UPDATE_PARMS      

    You can learn where these are called by examining the radR source code for lines like

    rss.call.hook(RSS$PRE_SCAN_CONVERT_HOOK, ...)

    TODO: document the location and calling conventions of each hook!!! 

    Useful Functions for Hooks

    These are presented in the form of examples: 

    rss.disable.hook("SCAN_INFO")   ## radR will stop calling the hook function you defined above
    rss.enable.hook("SCAN_INFO")    ## radR will resume calling the hook function you defined above
    rss.drop.hook("SCAN_INFO")      ## radR will delete (and no longer call, of course) the hook function you defined above

    You can add multiple hook functions to a single hook.  The different functions are distinguished by a name, which follows the name of the hook in most hook functions. By default, the name is "user".  The order in which they are executed is random.
    TODO: not exactly true, but we should move to a well-defined, user-specified order.

    ## add a hook function called myhook1 to the PRE_SCAN_CONVERT hook.  It will assign the current
    ## time to the variable time.hook.last.called in the global environment (since we use <<- instead of <-).
       rss.add.hook("PRE_SCAN_CONVERT", "myhook1", function(...) time.hook.last.called <<- Sys.time())

    ## disable the hook function myhook1 which is installed on the PRE_SCAN_CONVERT hook
       rss.disable.hook("PRE_SCAN_CONVERT", "myhook1")

    ## completely remove
    the hook function myhook1 which is installed on the PRE_SCAN_CONVERT hook
       rss.drop.hook("PRE_SCAN_CONVERT", "myhook1")

    Where radR keeps hooks

    The object RSS$hooks holds all hook functions (i.e. those which have been defined with rss.add.hook and not deleted with rss.drop.hook).  Each element of RSS$hooks is a list of hook functions, stored by hook name.

    e.g.

    names(RSS$hooks)                       ## the list of all hook names

    names(RSS$hooks$DONE_SCAN)             ## the names of all hook functions installed on the DONE_SCAN hook

    RSS$hooks$DONE_SCAN$saveblips$f        ## the hook function installed on the DONE_SCAN hook by the saveblips plugin

    RSS$hooks$DONE_SCAN$saveblips$enabled  ## flag: is the saveblips plugin's DONE_SCAN hook function enabled?

    Debugging hook functions

    Unfortunately, this is currently dangerous in Linux and impossible in Windows.

    In linux, you must call debug() with the installed version of the hook function:

    debug(RSS$hooks$DONE_SCAN$saveblips$f)

    If you try to do this:

    f <- function(...) { gui.print.cons(Sys.time()); gui.print.cons("Hello from my hook")}
    rss.add.hook("DONE_SCAN", f)
    debug(f)

    you will find that the debugger is never entered.  This is because rss.add.hook installs a copy of your hook function, and the debugging flag must be set directly on that copy. 

    TODO:  is there any way to have R disable the Tcl/Tk event loop upon entering a debug()ed function?

    Was this page helpful?
    Tags: (Edit tags)
    • No tags
     
    Comments (0)

     
    Powered by MindTouch Core