Skip to content

InitialWorkingExample

Gijs Molenaar edited this page Feb 13, 2014 · 4 revisions
  # stations list  STATIONS = range(1,15);  # 3 sources  SOURCES = ('a','b','c');    #--- these are generated automatically from the station list  # list of ifrs as station pairs: each entry is two indices, (s1,s2)  IFRS   = [ (s1,s2) for s1 in STATIONS for s2 in STATIONS if s1<s2 ];  # list of ifr strings of the form "s1-s2"  QIFRS  = [ '-'.join(map(str,ifr)) for ifr in IFRS ];  # combined list: each entry is ("s1-s2",s1,s2)  QQIFRS = [ ('-'.join(map(str,ifr)),) + ifr for ifr in IFRS ];    # namespace of all node classes  Meq = Namespace('Meq');     # global node scope & repository  nsglob = NodeScope();       # init some node groups  ROOT = NodeGroup('root');  SOLVERS = NodeGroup('solvers');    #------- create nodes for instrumental model  # some handy aliases  ZERO = nsglob.zero() << Meq.Constant(value=0);  UNITY = nsglob.unity() << Meq.Constant(value=1);    PHASE_CENTER_RA  = nsglob.ra0() << Meq.Parm();  PHASE_CENTER_DEC = nsglob.dec0() << Meq.Parm();    STATION_UWV = {};  STATION_POS = {};    ARRAY_POS = nsglob.xyz0() << Meq.Composer(    nsglob.x0() << Meq.Parm(),    nsglob.y0() << Meq.Parm(),    nsglob.z0() << Meq.Parm() );      # create station-related nodes and branches  for s in STATIONS:    STATION_POS[s] = nsglob.xyz(s) << Meq.Composer(      nsglob.x(s) << Meq.Parm(),      nsglob.y(s) << Meq.Parm(),      nsglob.z(s) << Meq.Parm() );    STATION_UWV[s] = nsglob.stuwv(s) << Meq.UWV(children={      'xyz': STATION_POS[s],      'xyz0': ARRAY_POS,      'ra': PHASE_CENTER_RA,      'dec': PHASE_CENTER_DEC    });    # create per-source station gains    for (q,src) in enumerate(SOURCES):      nsglob.G(s,q=q) << Meq.Composer(        nsglob.Gxx(s,q=q) << Meq.Polar(Meq.Parm(),Meq.Parm()), ZERO,        ZERO, nsglob.Gyy(s,q=q) << Meq.Polar(Meq.Parm(),Meq.Parm()),      dims=[2,2]);    # alternative: single gain with no direction dependence    # nsglob.G(s) << Meq.Composer(    #    nsglob.Gxx(s) << Meq.Polar(Meq.Parm(),Meq.Parm()), ZERO,    #    ZERO, nsglob.Gyy(s) << Meq.Polar(Meq.Parm(),Meq.Parm()),    #  dims=[2,2]);    # this function returns a per-station gain node, given a set of qualifiers  def STATION_GAIN (s=s,q=q,**qual):      # **qual swallows any remaining qualifiers    return nsglob.G(s,q=q);    # note alternative for no direction dependence:    # def STATION_GAIN (s=s,**qual):      #   return nsglob.G(s);      #------- end of instrumental model        #------- create model for unpolarized point source  # References instrumental model: STATION_GAIN(s,**qual), STATION_UWV[s].  # Returns unqualified predict node, should be qualified with ifr string.  def makeUnpolarizedPointSource (ns,**qual):    ns.lmn() << Meq.LMN(children={        'ra':   ns.ra() << Meq.Parm(),        'dec':  ns.dec() << Meq.Parm(),        'ra0':  PHASE_CENTER_RA,        'dec0': PHASE_CENTER_DEC    });    ns.stokes_i() << Meq.Parm();    # create per-station term subtrees    for s in STATIONS:      ns.sdft(s) << Meq.MatrixMultiply(        STATION_GAIN(s,**qual),        Meq.StatPSDFT(ns.lmn(),STATION_UWV[s])      );    # create per-baseline predicters    for (q,s1,s2) in QQIFRS:      ns.predict(q) << Meq.Multiply(          ns.stokes_i(),          ns.dft(q) << Meq.DFT(ns.sdft(s1),ns.sdft(s2)),      );    return ns.predict;      #------- create peeling unit  # inputs: an unqualified input node, will be qualified with ifr string.  # predicters: list of unqualified predict nodes, will be qualified with ifr string.  # Returns unqualified output node, should be qualified with ifr string.  def peelUnit (inputs,predicters,ns):    for q in QIFRS:      # create condeq branch      ns.condeq(q) << Meq.Condeq(        ns.measured(q) << Meq.PhaseShift(children=inputs(q)),        ns.predicted(q) << Meq.Add(*[prd(q) for prd in predicters])      );      # create subtract branch      ns.subtract(q) << Meq.Subtract(ns.measured(q),ns.predicted(q));    # creates solver and sequencers    ns.solver() << Meq.Solver(*[ns.condeq(q) for q in QIFRS]);    for q in QIFRS:      ns.reqseq(q) << Meq.ReqSeq(ns.solver(),ns.subtract(q));    # returns root nodes of unit    return ns.reqseq;    # create source predictors, each in its own subscope  predicter = {};  for (q,src) in enumerate(SOURCES):    predicter[q] = makeUnpolarizedPointSource(nsglob.subscope('predict',src),q=q);    # create spigots  for q in QIFRS:    nsglob.spigot(q) << Meq.Spigot();      # chain peel units, by connecting outputs to inputs. First input  # is spigot.  inputs = nsglob.spigot;  for (q,src) in enumerate(SOURCES):    ns_pu = nsglob.subscope('peelunit',q);    inputs = peelUnit(inputs,predicter.values(),ns=ns_pu);    SOLVERS << ns_pu.solver();      # create sinks, connect them to output of last peel unit  for q in QIFRS:    ROOT << nsglob.sink(q) << Meq.Sink(inputs(q));      # create data collectors (this simply shows off the use of arbitrary node  # groupings)  ROOT << nsglob.solver_collect() << Meq.DataCollect(*SOLVERS.values());      # deliberately create an orphan branch. This checkes orphan collection.  # this whole branch should go away, and so should the UNITY node, which  # is not used anywhere  nsglob.orphan() << Meq.Add(Meq.Const(value=0),UNITY,Meq.Add(UNITY,ZERO));  # resolve all nodes  nsglob.resolve(ROOT);```
Clone this wiki locally