Ejemplo n.º 1
0
  def compute_jones (self,nodes,sources,stations=None,tags=None,label='',**kw):
    stations = stations or Context.array.stations();
    # set up qualifier labels depending on polarization definition
    if Context.observation.circular():
      x,y,X,Y = 'r','l','R','L';
    else:
      x,y,X,Y = 'x','y','X','Y';
    xx,xy,yx,yy = x+x,x+y,y+x,y+y;
    axx,axy,ayx,ayy = [ q+":a" for q in xx,xy,yx,yy ];
    pxx,pxy,pyx,pyy = [ q+":p" for q in xx,xy,yx,yy ];

    ampl_def = phase_def = None;
    parms_phase = [];
    parms_ampl = [];
    subgroups_phase = [];
    subgroups_ampl = [];
    for src in sources:
      sg = src.name if self.independent_solve else '';
      # (re)create parm definitions.
      if ampl_def is None or self.independent_solve:
        ampl_def  = Meq.Parm(self.init_ampl,tags=tags+"solvable diag ampl",solve_group=sg);
        phase_def = Meq.Parm(self.init_phase,tags=tags+"solvable diag phase",solve_group=sg);
      sga = [];
      sgp = [];
      # now loop to create nodes
      for p in stations:
        jj = nodes(src,p);
        jj << Meq.Matrix22( Meq.Polar(jj(axx) << ampl_def,jj(pxx) << phase_def),0,0,
                            Meq.Polar(jj(ayy) << ampl_def,jj(pyy) << phase_def));
        sga += [jj(axx),jj(ayy)];
        sgp += [jj(pxx),jj(pyy)];
        parms_ampl  += [jj(axx),jj(ayy)];
        parms_phase += [jj(pxx),jj(pyy)];
      # add subgroups for this source
      subgroups_ampl.append(ParmGroup.Subgroup(src.name,sga));
      subgroups_phase.append(ParmGroup.Subgroup(src.name,sgp));

    # make parmgroups for phases and gains
    self.pg_phase = ParmGroup.ParmGroup(label+"_phase",
                    parms_phase,
                    subgroups = subgroups_phase,
                    table_name="%s_phase.fmep"%label,bookmark=4);
    self.pg_ampl  = ParmGroup.ParmGroup(label+"_ampl",
                    parms_ampl,
                    subgroups = subgroups_ampl,
                    table_name="%s_ampl.fmep"%label,bookmark=4);

    ParmGroup.SolveJob("cal_"+label+"_phase","Calibrate %s phases"%label,self.pg_phase);
    ParmGroup.SolveJob("cal_"+label+"_ampl","Calibrate %s amplitudes"%label,self.pg_ampl);

    return nodes;
    def compute_jones(self,
                      jones,
                      sources,
                      stations=None,
                      tags=None,
                      label='',
                      **kw):
        stations = stations or Context.array.stations()
        is_complex = self.matrix_type != "real"
        # set up qualifier labels depending on polarization definition
        if Context.observation.circular():
            x, y, X, Y = 'r', 'l', 'R', 'L'
        else:
            x, y, X, Y = 'x', 'y', 'X', 'Y'
        xx, xy, yx, yy = x + x, x + y, y + x, y + y
        rxx, rxy, ryx, ryy = [q + ":r" for q in (xx, xy, yx, yy)]
        ixx, ixy, iyx, iyy = [q + ":i" for q in (xx, xy, yx, yy)]
        # prepare parm definitions for real and imag parts of diagonal and off-diagonal elements
        tags = NodeTags(tags) + "solvable"
        diag_pdefs = offdiag_pdefs = None
        # loop over sources
        parms_diag = []
        parms_offdiag = []
        subgroups_diag = []
        subgroups_offdiag = []

        # Define a function to put together a matrix element, depending on whether we're in real or complex mode.
        # This is also responsible for appending parms to the appropriate parm and subgroup lists.
        # Note that for the purely-real case we still create parms called 'J:xx:r' (and not 'J:xx' directly),
        # this is to keep MEP tables mutually-compatible naming wise.
        if self.matrix_type == "real":

            def make_element(jj, parmdef, *parmlists):
                parm = jj('r') << parmdef[0]
                for plist in parmlists:
                    plist.append(parm)
                return jj << Meq.Identity(parm)
        else:

            def make_element(jj, parmdef, *parmlists):
                parms = [jj('r') << parmdef[0],
                         jj('i') << parmdef[1]]
                for plist in parmlists:
                    plist += parms
                return jj << Meq.ToComplex(*parms)

        for src in sources:
            sg = src.name if self.independent_solve else ''
            # (re)create parm definitions.
            if diag_pdefs is None or self.independent_solve:
                diag_pdefs = (Meq.Parm(complex(self.init_diag).real,
                                       tags=tags + "diag real",
                                       solve_group=sg),
                              Meq.Parm(complex(self.init_diag).imag,
                                       tags=tags + "diag imag",
                                       solve_group=sg))
                offdiag_pdfefs = (Meq.Parm(complex(self.init_offdiag).imag,
                                           tags=tags + "offdiag real",
                                           solve_group=sg),
                                  Meq.Parm(complex(self.init_offdiag).imag,
                                           tags=tags + "offdiag imag",
                                           solve_group=sg))
            # now loop to create nodes
            sgdiag = []
            sgoff = []
            for p in stations:
                jj = jones(src, p)
                jj << Meq.Matrix22(
                    make_element(jj(xx), diag_pdefs, parms_diag, sgdiag),
                    make_element(jj(xy), offdiag_pdefs, parms_offdiag, sgoff)
                    if self._offdiag else 0,
                    make_element(jj(yx), offdiag_pdefs, parms_offdiag, sgoff)
                    if self._offdiag else 0,
                    make_element(jj(yy), diag_pdefs, parms_diag, sgdiag))
            # add subgroup for this source
            subgroups_diag.append(ParmGroup.Subgroup(src.name, sgdiag))
            subgroups_offdiag.append(ParmGroup.Subgroup(src.name, sgoff))

        # re-sort by name
        from past.builtins import cmp
        from functools import cmp_to_key
        subgroups_diag.sort(key=cmp_to_key(lambda a, b: cmp(a.name, b.name)))
        subgroups_offdiag.sort(
            key=cmp_to_key(lambda a, b: cmp(a.name, b.name)))

        # make parmgroups for diagonal and off-diagonal terms
        self.pg_diag = ParmGroup.ParmGroup(label + "_diag",
                                           parms_diag,
                                           subgroups=subgroups_diag,
                                           table_name="%s_diag.fmep" % label,
                                           bookmark=False)
        if self._offdiag:
            self.pg_offdiag = ParmGroup.ParmGroup(
                label + "_offdiag",
                parms_offdiag,
                subgroups=subgroups_offdiag,
                table_name="%s_offdiag.fmep" % label,
                bookmark=False)

        # make bookmarks
        Bookmarks.make_node_folder("%s diagonal terms" % label, [
            jones(src, p, zz) for src in sources for p in stations
            for zz in ["xx", "yy"]
        ],
                                   sorted=True)
        if self._offdiag:
            Bookmarks.make_node_folder("%s off-diagonal terms" % label, [
                jones(src, p, zz) for src in sources for p in stations
                for zz in ["xy", "yx"]
            ],
                                       sorted=True)

        # make solvejobs
        ParmGroup.SolveJob("cal_" + label + "_diag",
                           "Calibrate %s diagonal terms" % label, self.pg_diag)
        if self._offdiag:
            ParmGroup.SolveJob("cal_" + label + "_offdiag",
                               "Calibrate %s off-diagonal terms" % label,
                               self.pg_offdiag)

        return jones
  def init_parameters (self,ns,sources,stations,inspectors=[]):
    if self.beamshape is not None:
      return;
    # create solvables if enabled
    parms = [];
    parmgroups = [];
    parmdef_scale = Meq.Parm(self.bf*1e-9,tags="beam solvable");
    parmdef_ell = Meq.Parm(self.ellipticity,tags="beam solvable");
    self.per_station = False;

    # solvable beam scale
    if self.solve_scale is PER_STATION:
      self.beamshape = ns.beamshape;
      for p in stations:
        parms.append(beamshape(p) << parmdef_scale);
      inspectors.append(ns.inspector("scale") << 
            StdTrees.define_inspector(ns.beamshape,stations,label=self.label));
      self.per_station = True;
    elif self.solve_scale is PER_ARRAY:
      parms.append(ns.beamshape << parmdef_scale);
      self.beamshape = lambda p:ns.beamshape;
    else:
      ns.beamshape ** (self.bf*1e-9);
      self.beamshape = lambda p:ns.beamshape;
    
    # solvable ellipticities
    if self.solve_ell is PER_STATION:
      self.ell = ns.ell;
      for p in stations:
        ell_xy = ns.ell_xy(p) << parmdef_ell;
        parms.append(ell_xy);
        self.ell(p) << Meq.Composer(ell_xy,-ell_xy);
      inspectors.append(ns.inspector("ellipticity") << 
            StdTrees.define_inspector(ns.ell_xy,stations,label=self.label));
      self.per_station = True;
    elif self.solve_ell is PER_ARRAY:
      ell_xy = ns.ell_xy << parmdef_ell;
      parms.append(ell_xy);
      ns.ell << Meq.Composer(ell_xy,-ell_xy);
      self.ell = lambda p:ns.ell;
    elif self.ellipticity != 0:
      ns.ell ** Meq.Constant([self.ellipticity,-self.ellipticity]);
      self.ell = lambda p:ns.ell;
    else:
      self.ell = lambda p:None;
      
    # make parm group, if any solvables have been created
    if parms:
      parmgroups.append(ParmGroup.Subgroup("beam shape",list(parms)));
      
    # solvable pointings
    if self.solve_pointings:
      self.dlm = ns.dlm;
      parmdef_0 = Meq.Parm(0,tags="beam solvable");
      pparms = [];
      for p in stations:
        dl = ns.dl(p) << parmdef_0;
        dm = ns.dm(p) << parmdef_0;
        ns.dlm(p) << Meq.Composer(dl,dm);
        pparms += [dl,dm];
      parmgroups.append(ParmGroup.Subgroup("pointing offsets",pparms));
      parms += pparms;
      inspectors.append(ns.inspector('dlm') << 
              StdTrees.define_inspector(ns.dlm,stations,label=self.label));
      self.per_station = True;
    else:
      ns.dlm_null ** Meq.Constant([0,0]);
      self.dlm = lambda p:ns.dlm_null;

    # add solve jobs
    self.solvable = bool(parms);
    if self.solvable:
      self.pg_beam = ParmGroup.ParmGroup(self.label,parms,subgroups=parmgroups,table_name="%s.fmep"%self.label,bookmark=True);
      ParmGroup.SolveJob("cal_"+self.label,"Calibrate beam parameters",self.pg_beam);