Skip to content

How_can_I_explicitly_change_the_state_of_a_node?

Gijs Molenaar edited this page Feb 13, 2014 · 2 revisions
> I'm attempting to update node state ...
>
> In my _define_forest I have
>
>
>   BEAM_LM = [(0.0,0.0)]
>   l_beam,m_beam = BEAM_LM[0]
>   ns.l_beam_c << Meq.Parm(l_beam,node_groups='Parm')
>
>
> In my _test_forest I have
>
>  ...
> #define request
>   for i in range(3):
>     request = make_request(counter=i, dom_range =
> [[f0,f1],[t0,t1],lm_range,lm_range], nr_cells = [1,1,lm_num,lm_num])
> # execute request
>     mqs.meq('Node.Execute',record(name='E',request=request),wait=True);
> # now attempt to update 'l_beam_c' state before next request is issued
>     node_name = 'l_beam_c'
>     cache_rec = mqs.getnodestate(node_name).cache
>     print 'iteration field', i, ' ',cache_rec.result
>     l = l + 0.008
>     cache_rec.result.vellsets[0].value[0]= l
>     print 'iteration changed field ', i, ' ',cache_rec.result
>     change_rec = record(cache=cache_rec)
> # attempting to use Meow Utils
>     Utils.set_node_state(mqs,node_name,change_rec)
>
> which results in some printout like
>
> rqid ev.0.0.0.0.0
> iteration field 0   { vellsets: (MeqVellSet({'value':MeqVells([ 0.])}),) }
> iteration changed field  0   { vellsets: (MeqVellSet({'value':MeqVells([
> 0.008])}),) }
> rqid ev.0.0.0.1.0
> ...
>
>
> but when I look at the L_beam_c node in the record browser
> nothing seems to get changed which influences down-stream stuff.
>
> however if I do something like
>
>     change_rec = record(demo_value = 0.005)
>     Utils.set_node_state(mqs,node_name,change_rec)
>
>
> then indeed a new top-level field 'demo_value' is inserted into the node.
>
> So I'm close but no cigar!!

You're just changing the wrong field, cache.result is recalculated for you, so there's no use changing it. Try this instead:

     * change_rec = record(value = 0.005) 
  * Utils.set_node_state(mqs,node_name,change_rec) 

..assuming it's a Meq.Constant node, that is. If it's a Meq.Parm, you have to form up a polc and assign it to init_funklet instead, there's examples of this in Meow.Utils.reset_parameters.

> But I would have thought that since the Compounder realizes it
> has an updated request, it should propagate a new request
> to all children. I'll also copy this note to Sarod.
>

Ahhh but of course, I'd forgotten about that. It doesn't quite work the way you think though -- the parent node may have been told by its child node that its value does not depend on, e.g., domain (as is the case for a MeqConstant), and after that it is entirely justified in ignoring further requests that differ only in domain/cells.

One could argue that a Meq.Constant should automatically clear its cache.result when it value has changed; however, that doesn't solve the problem of parents further upstream still retaining a cache.

Actually, once you start playing God -- i.e. manipulating node state directly -- there's no foolproof way for nodes to know whether their caches are still valid. So the really robust solution is for you to do:

mqs.clearcache('nodename',recursive=True);

before issuing a new request ('nodename' should be the root node). This should solve all mis-caching problems.

Cheers

Oleg

(Here's an example of a _test_forest routine where two nodes (L,M) have their state updated for each request and the root node is told to 'clearcache' before every request is executed ... and have a look at the ASTRON/JIVE daily image for 16-01-2007 for the final result!)

def _test_forest(mqs,parent):
# any large time range will do   
  t0 = 0.0;  
  t1 = 1.5e70  

  f0 = 0.5  
  f1 = 1.5  

  lm_range = [-0.04,0.04];  
  lm_num = 50;  
  l = -0.024  
  counter = 0

# define request  
  for i in range(5):    
    m = -0.024    
    l = l + 0.008    
    node_name = 'l_beam_c'    ]
    change_rec = record(value = l)    
    Utils.set_node_state(mqs,node_name,change_rec)    
    for j in range(5):      
      m = m + 0.008      
      node_name = 'm_beam_c'      
      change_rec = record(value = m)      
# Feb 2009 - the following line is now obsolete 
#     Utils.set_node_state(mqs,node_name,change_rec)  
# Use this next line instead
      mqs.setnodestate(node_name,change_rec,sync=True)    
      mqs.clearcache('E',recursive=True)      
      request = make_request(counter=counter, dom_range = [[f0,f1],[t0,t1],lm_range,lm_range], \
          nr_cells =[1,1,lm_num,lm_num])      
      counter = counter + 1
# execute request - Feb 2009: note wait is now set to False in this example     
      mqs.meq('Node.Execute',record(name='E',request=request),wait=False);
Clone this wiki locally