1 # demo_parm.py:
   2 
   3 # Demonstrates the following MeqTree features:
   4 # Simple Tree with a solver and several  parameters, demonstartes paramter options 
   5 
   6 # Tips:
   7 
   8 # The parameters are stored in the meptable. you can browse this to view the solutions
   9 
  10 
  11 
  12 #********************************************************************************
  13 # Initialisation:
  14 #********************************************************************************
  15 
  16 from Timba.TDL import *
  17 from Timba.Meq import meq
  18 # from qt import *
  19 # from numarray import *
  20 
  21 # from Timba.Contrib.JEN.util import JEN_bookmarks
  22 
  23 # Make sure that all nodes retain their results in their caches,
  24 # for your viewing pleasure.
  25 Settings.forest_state.cache_policy = 100
  26 Settings.forest_state.bookmarks = []
  27 
  28 
  29 
  30 #********************************************************************************
  31 # The function under the 'blue button':
  32 #********************************************************************************
  33 
  34 def _define_forest (ns, **kwargs):
  35    """Definition of a 'forest' of one or more trees"""
  36    #You can attach a meptable to a Parm by setting the field table_name,
  37    # the funklet will then be initialized (if available) from 
  38    # and (after solving) stored in the table.
  39    meptable ="test.mep"
  40    #set this as the table for all our parms
  41 
  42 
  43    # Make a Parm  node, initialize it with constant 1.
  44    # The node_groups='Parm' options is needed to be recognized by the solver
  45    #tiling means that you have independent solutions for different time/freq slots.
  46    #We make our simple_parm less simple, by tiling it in freq and time:
  47 
  48 
  49    simple_parm = ns['simple_parm'] << Meq.Parm(1.,node_groups='Parm',table_name=meptable,
  50                                                tiling= record(freq=1,time=2)
  51                                                #Gives an independent solution per freq. cell
  52                                                # and per 2 time cells
  53                                                )
  54 
  55    # a parm is initialized with a 'funklet' the most common funklet is the 'polc' a
  56    # 2-dim polynomial in freq. and time, you can define the polc by giving a 2d array of its coefficients
  57    # The shape of the array determinse the polynomial
  58    polc = meq.polc([[1.,.02,.03],[.04,.005,.00001]]); #1.+0.02*f +0.03*f^2 +0.04*t +0.005*t*f +0.00001*t*f^2
  59    polc_parm = ns['polc_parm'] <<Meq.Parm(init_funklet = polc,node_groups='Parm',table_name=meptable);
  60 
  61 
  62    # Alternatively, you can fix the shape of the Polc by setting the shape field of the connected Parm.
  63    # All missing coeffs will be initialized wiht zero's.
  64    shape_parm = ns['shape_parm']<<Meq.Parm(1.,shape=[2,3],node_groups = 'Parm',table_name=meptable); #results in a [[1,0.0],[0.0.0]] polc.
  65 
  66    # A more general, but sometimes slow, option is to make use of the Aips++ functional interpreter
  67    # to create any real function. This is done by setting the "function" field of the polc.
  68    functional = meq.polc([1.,2.,1.5]); # The number of coeffs should match the number of p# in function 
  69    functional.function = "p0+p1*exp(-0.01*x0^2)*sin(x1*p2)";
  70    functional_parm =  ns['functional_parm'] <<Meq.Parm(init_funklet = functional ,node_groups='Parm',table_name=meptable);
  71 
  72 
  73 
  74 
  75 
  76 
  77    # Now a nonsense fit. lets fit simple_parm to the functional_parm, and shape_parm to polc_parm
  78    # The final difference between the shape_parm and the polc_parm can be explained by the fact that for
  79    # solvable polcs per default the lower right triangle of coefficients is kept to 0.
  80    # i.e. all c_nm with (n+m) > max(n,m)
  81    #
  82    # The Condeq has exactly 2 children: the 'model' (in this case the parm)
  83    # and the 'data' on which you want to fit the 'model'.
  84    # solvable parm can be on both sides, so there is no real distinction between 'model' and 'data' here.
  85    condeq_polc_shape = ns['condeq_polc_shape'] << Meq.Condeq(children=(polc_parm,shape_parm))
  86    condeq_simple_functional = ns['condeq_simple_functional'] << Meq.Condeq(children=(simple_parm,functional_parm))
  87 
  88    # Now create a solver node. A solver can have several children, but they all must be condeqs.
  89    solver = ns['solver'] << Meq.Solver(children=(condeq_polc_shape,
  90                                                  condeq_simple_functional),
  91                                        solvable = ['simple_parm','shape_parm'], #list of solvable parameters 
  92                                        num_iter = 10,       #stop after 10 iterations or after convergence
  93                                        epsilon = 1e-4,       #convergence limit, good default
  94                                        last_update=True,    #sends last update to parms after convergence
  95                                        save_funklets=True  #needed to save funklets in parmtable
  96                                        )
  97    # Make a bookmark of the result node, for easy viewing:
  98    bm = record(name='result',page=
  99                [record(viewer='Result Plotter',udi='/node/simple_parm', publish=True, pos=(0,0)),
 100                 record(viewer='Result Plotter',udi='/node/polc_parm', publish=True, pos=(1,0)),
 101                 record(viewer='Result Plotter',udi='/node/functional_parm', publish=True, pos=(0,1)),
 102                 record(viewer='Result Plotter',udi='/node/shape_parm', publish=True, pos=(1,1)),
 103                 record(viewer='Result Plotter',udi='/node/condeq_polc_shape', publish=True, pos=(1,2)),
 104                 record(viewer='Result Plotter',udi='/node/condeq_simple_functional', publish=True, pos=(0,2)),
 105                 record(viewer='Result Plotter',udi='/node/solver', publish=True, pos=(2,0))
 106                 ])
 107    Settings.forest_state.bookmarks.append(bm)
 108 
 109    # Finished:
 110    return True
 111 
 112 
 113 
 114 #********************************************************************************
 115 # The function under the TDL Exec button:
 116 #********************************************************************************
 117 
 118 def _tdl_job_execute (mqs, parent):
 119     """Execute the forest, starting at the named node"""
 120     domain = meq.domain(1,10,1,10)                            # (f1,f2,t1,t2)
 121     cells = meq.cells(domain, num_freq=10, num_time=11)
 122     request = meq.request(cells, rqtype='ev')
 123     result = mqs.meq('Node.Execute',record(name='solver', request=request))
 124     return result
 125 
 126 #********************************************************************************
 127 #********************************************************************************

MeqParm.py (last edited 2007-02-07 15:30:15 by OlegSmirnov)