Пример #1
0
def array_to_vells (x,vellshape=None,expanded_slice=None):
  if expanded_slice is not None:
    a = meq.complex_vells(vellshape);
    a[...] = x[expanded_slice];
  else:
    a = meq.complex_vells(x.shape);
    a[...] = x;
  return a;
Пример #2
0
def array_to_vells (x,vellshape=None,expanded_slice=None):
  if expanded_slice is not None:
    a = meq.complex_vells(vellshape);
    a[...] = x[expanded_slice];
  else:
    a = meq.complex_vells(x.shape);
    a[...] = x;
  return a;
Пример #3
0
 def interpolate_per_source (self,lm_list,dl,dm,grid,vbs,thetaphi=False,rotate=None,masklist=None):
   # Loops over all source coordinates in the lm tensor, interpolates beams for them, and returns the resulting vellsets.
   # lm is a list of [[l0,m0],[l1,m1],...] source coordinates
   # This is the "fail-safe" method, as it interpolates per-source, and therefore allows for the source lm arrays to have different
   # time/frequency dependencies per source.
   vellsets = [];
   for isrc,(l,m) in enumerate(lm_list):
     # apply pointing offsets, if any
     if dl is not None:
       # unite shapes just in case, since l/m and dl/dm may have time/freq axes
       l,dl,m,dm = unite_multiple_shapes(l,dl,m,dm);
     # if mask is set, make sure it has the same shape
     mask = masklist[isrc] if masklist is not None else None;
     if mask is not None:
       l,m,mask = unite_multiple_shapes(l,m,mask);
     grid['l'],grid['m'] = l,m;
     # loop over all 2x2 matrices (we may have several, they all need to be added)
     E = [None]*4;
     for vbmat in vbs:
       for i,vb in enumerate(vbmat):
         beam = vb.interpolate(freqaxis=self._freqaxis,lm=self.interpol_lm,thetaphi=thetaphi,rotate=rotate,mask=mask,**grid);
         if E[i] is None:
           E[i] = meq.complex_vells(beam.shape);
         E[i][...] += beam[...];
     # make vellsets
     for ej in E:
       vellsets.append(meq.vellset(ej));
   return vellsets;
Пример #4
0
 def expand_subshape(self, x, datashape=None, data_subset=None):
     """expands subshape to original data shape"""
     if numpy.isscalar(x):
         return x
     a = numpy.empty(self.tiled_shape, dtype=x.dtype)
     a[...] = self.tile_subshape(x)
     if x.dtype == bool:
         b = numpy.zeros(datashape or self.datashape, bool)
     else:
         b = meq.complex_vells(datashape or self.datashape)
     b[...] = self.untile_data(a)
     return b[data_subset or ()]
Пример #5
0
 def expand_subshape (self,x,datashape=None,data_subset=None):
   """expands subshape to original data shape"""
   if numpy.isscalar(x):
     return x;
   a = numpy.empty(self.tiled_shape,dtype=x.dtype);
   a[...] = self.tile_subshape(x);
   if x.dtype == bool:
     b = numpy.zeros(datashape or self.datashape,bool);
   else:
     b = meq.complex_vells(datashape or self.datashape);
   b[...] = self.untile_data(a);
   return b[data_subset or ()];
Пример #6
0
 def interpolate_per_source(self,
                            lm_list,
                            dl,
                            dm,
                            grid,
                            vbs,
                            thetaphi=False,
                            rotate=None,
                            masklist=None):
     # Loops over all source coordinates in the lm tensor, interpolates beams for them, and returns the resulting vellsets.
     # lm is a list of [[l0,m0],[l1,m1],...] source coordinates
     # This is the "fail-safe" method, as it interpolates per-source, and therefore allows for the source lm arrays to have different
     # time/frequency dependencies per source.
     vellsets = []
     for isrc, (l, m) in enumerate(lm_list):
         # apply pointing offsets, if any
         if dl is not None:
             # unite shapes just in case, since l/m and dl/dm may have time/freq axes
             l, dl, m, dm = unite_multiple_shapes(l, dl, m, dm)
         # if mask is set, make sure it has the same shape
         mask = masklist[isrc] if masklist is not None else None
         if mask is not None:
             l, m, mask = unite_multiple_shapes(l, m, mask)
         grid['l'], grid['m'] = l, m
         # loop over all 2x2 matrices (we may have several, they all need to be added)
         E = [None] * 4
         for vbmat in vbs:
             for i, vb in enumerate(vbmat):
                 beam = vb.interpolate(freqaxis=self._freqaxis,
                                       lm=self.interpol_lm,
                                       thetaphi=thetaphi,
                                       rotate=rotate,
                                       mask=mask,
                                       **grid)
                 if E[i] is None:
                     E[i] = meq.complex_vells(beam.shape)
                 E[i][...] += beam[...]
         # make vellsets
         for ej in E:
             vellsets.append(meq.vellset(ej))
     return vellsets
Пример #7
0
 def get_result(self, request, *children):
     # get list of VoltageBeams
     vbs, beam_max = self.init_voltage_beams()
     # now, figure out the lm and time/freq grid
     lm = children[0]
     l = lm.vellsets[0].value
     m = lm.vellsets[1].value
     # setup grid dict that will be passed to VoltageBeam.interpolate
     grid = dict(l=l, m=m)
     for axis in 'time', 'freq':
         values = _cells_grid(lm, axis)
         if values is None:
             values = _cells_grid(request, axis)
         if values is not None:
             grid[axis] = values
     # interpolate
     vellsets = []
     for vb in vbs:
         if vb is None:
             vellsets.append(meq.vellset(meq.sca_vells(0.)))
         else:
             beam = vb.interpolate(freqaxis=self._freqaxis, **grid)
             if self.normalize and beam_max != 0:
                 beam /= beam_max
             vells = meq.complex_vells(beam.shape)
             vells[...] = beam[...]
             # make vells and return result
             vellsets.append(meq.vellset(vells))
     # create result object
     cells = request.cells if vb.hasFrequencyAxis() else getattr(
         lm, 'cells', None)
     result = meq.result(vellsets[0], cells=cells)
     # if more than one vellset, then we have 2x2
     if len(vellsets) > 1:
         result.vellsets[1:] = vellsets[1:]
         result.dims = (2, 2)
     return result
 def get_result (self,request,*children):
   # get list of VoltageBeams
   vbs,beam_max = self.init_voltage_beams();
   # now, figure out the lm and time/freq grid
   lm = children[0];
   l = lm.vellsets[0].value;
   m = lm.vellsets[1].value;
   # setup grid dict that will be passed to VoltageBeam.interpolate
   grid = dict(l=l,m=m);
   for axis in 'time','freq':
     values = _cells_grid(lm,axis);
     if values is None:
       values = _cells_grid(request,axis);
     if values is not None:
       grid[axis] = values;
   # interpolate
   vellsets = [];
   hasfreq = False;
   for vb in vbs:
     if vb is None:
       vellsets.append(meq.vellset(meq.sca_vells(0.)));
     else:
       beam = vb.interpolate(freqaxis=self._freqaxis,**grid);
       hasfreq = hasfreq or vb.hasFrequencyAxis();
       if self.normalize and beam_max != 0:
         beam /= beam_max;
       vells = meq.complex_vells(beam.shape);
       vells[...] = beam[...];
       # make vells and return result
       vellsets.append(meq.vellset(vells));
   # create result object
   cells = request.cells if hasfreq else getattr(lm,'cells',None);
   result = meq.result(vellsets[0],cells=cells);
   result.vellsets[1:] = vellsets[1:];
   result.dims = (2,len(vellsets)/2);
   return result;
Пример #9
0
 def _expand_trivial_subshape(self, x, datashape=None, data_subset=None):
     a = meq.complex_vells(x.shape)
     a[...] = x
     return a[data_subset]
Пример #10
0
 def get_result(self, request, *children):
     # get list of VoltageBeams
     vbs, beam_max = self.init_voltage_beams()
     # now, figure out the lm and time/freq grid
     # lm may be a 2/3-vector or an Nx2/3 tensor
     lm = children[0]
     dims = getattr(lm, 'dims', [len(lm.vellsets)])
     if len(dims) == 2 and dims[1] in (2, 3):
         nsrc, nlm = dims
         tensor = True
     elif len(dims) == 1 and dims[0] in (2, 3):
         nsrc, nlm = 1, dims[0]
         tensor = False
     else:
         print "child 0: %d vellsets, shape %s" % (len(
             lm.vellsets), getattr(lm, 'dims', []))
         raise TypeError, "expecting a 2/3-vector or an Nx2/3 matrix for child 0 (lm)"
     # pointing offsets (child 1) are optional
     if len(children) > 1:
         dlm = children[1]
         if len(dlm.vellsets) != 2:
             raise TypeError, "expecting a 2-vector for child 1 (dlm)"
         dl, dm = dlm.vellsets[0].value, dlm.vellsets[1].value
     else:
         dl = dm = 0
     # setup grid dict that will be passed to VoltageBeam.interpolate
     grid = dict()
     for axis in 'time', 'freq':
         values = _cells_grid(lm, axis)
         if values is None:
             values = _cells_grid(request, axis)
         if values is not None:
             grid[axis] = values
     vellsets = []
     # now loop over sources and interpolte
     for isrc in range(nsrc):
         # put l,m into grid
         l, m = lm.vellsets[isrc * nlm].value, lm.vellsets[isrc * nlm +
                                                           1].value
         l, dl = unite_shapes(l, dl)
         m, dm = unite_shapes(m, dm)
         grid['l'] = l - dl
         grid['m'] = m - dm
         # interpolate
         for vb in vbs:
             if vb is None:
                 vellsets.append(meq.vellset(meq.sca_vells(0.)))
             else:
                 beam = vb.interpolate(freqaxis=self._freqaxis, **grid)
                 if self.normalize and beam_max != 0:
                     beam /= beam_max
                 vells = meq.complex_vells(beam.shape)
                 vells[...] = beam[...]
                 # make vells and return result
                 vellsets.append(meq.vellset(vells))
     # create result object
     cells = request.cells if vb.hasFrequencyAxis() else getattr(
         lm, 'cells', None)
     result = meq.result(vellsets[0], cells=cells)
     if len(vellsets) > 1:
         result.vellsets[1:] = vellsets[1:]
     # vbs is either length 4 or length 1. If length 4, then result needs to have its dimensions
     if len(vbs) > 1:
         result.dims = (nsrc, 2, 2) if tensor else (2, 2)
     return result
Пример #11
0
 def _expand_trivial_subshape (self,x,datashape=None,data_subset=None):
   a = meq.complex_vells(x.shape);
   a[...] = x;
   return a[data_subset];
     
Пример #12
0
    def interpolate_batch(self,
                          lm_list,
                          dl,
                          dm,
                          grid,
                          vbs,
                          thetaphi=False,
                          rotate=None,
                          masklist=None):
        # A faster version of interpolate_per_source(), which assumes that all lm's (as well as the masks, if given)
        # have the same shape, and stacks them into a single array for a single interpolation call.
        # If there's a shape mismatch, it'll fall back to interpolate_per_source
        # 'maskarr', if given, should be an list of per-source mask arrays
        nsrc = len(lm_list)
        maskcube = None
        for isrc, (l, m) in enumerate(lm_list):
            mask = masklist[isrc] if masklist is not None else None
            # apply pointing offsets, if any
            if dl is not None:
                # unite shapes just in case, since l/m and dl/dm may have time/freq axes
                l, dl, m, dm = unite_multiple_shapes(l, dl, m, dm)
                l, m = l - dl, m - dm
            # unite l,m shapes just in case, and transform
            l, m, mask = unite_multiple_shapes(l, m, mask)
            if not isrc:
                lm_shape = l.shape
                cubeshape = [nsrc] + list(lm_shape)
                lcube = numpy.zeros(cubeshape, float)
                mcube = numpy.zeros(cubeshape, float)
                if masklist is not None:
                    maskcube = numpy.zeros(cubeshape, bool)
            else:
                if l.shape != lm_shape:
                    dprint(
                        1,
                        "l/m shapes unequal at source %d, falling back to per-source interpolation"
                        % isrc)
                    return self.interpolate_per_source(lm_list,
                                                       dl,
                                                       dm,
                                                       grid,
                                                       vbs,
                                                       thetaphi=thetaphi,
                                                       rotate=rotate,
                                                       masklist=masklist)
            lcube[isrc, ...] = l
            mcube[isrc, ...] = m
            if mask is not None:
                maskcube[isrc, ...] = mask


#        if mask.any():
#          dprint(2,"source %d has %d slots masked"%(isrc,mask.sum()));
# if 'rotate' is specified, it needs to be promoted to the same cube shape, and ravelled
        if rotate is not None:
            lcube, mcube, maskcube, rotate = unite_multiple_shapes(
                lcube, mcube, maskcube,
                rotate.reshape([1] + list(rotate.shape)))
            cubeshape = list(lcube.shape)
            rotate = rotate.ravel()
        # ok, we've stacked things into lm cubes, interpolate
        grid['l'], grid['m'] = lcube.ravel(), mcube.ravel()
        # loop over all 2x2 matrices (we may have several, they all need to be added)
        E = [None] * 4
        for vbmat in vbs:
            for i, vb in enumerate(vbmat):
                beam = vb.interpolate(freqaxis=self._freqaxis,
                                      extra_axes=1,
                                      thetaphi=thetaphi,
                                      rotate=rotate,
                                      **grid)
                if E[i] is None:
                    E[i] = beam
                else:
                    E[i] += beam
        # The l/m cubes have a shape of [nsrcs,lm_shape].
        # These are raveled for interpolation, so the resulting Es have a shape of [nsrcs*num_lm_points,num_freq]
        # Reshape them properly. Note that there's an extra "source" axis at the front, so the frequency axis
        # is off by 1.
        if len(cubeshape) <= self._freqaxis + 1:
            cubeshape = list(cubeshape) + [1] * (self._freqaxis -
                                                 len(cubeshape) + 2)
        cubeshape[self._freqaxis + 1] = len(grid['freq'])
        E = [ej.reshape(cubeshape) for ej in E]
        # apply mask cube, if we had one
        if maskcube is not None:
            # the E planes now have the same shape as the maskcube, but with an extra frequency axis. Promote the maskcube
            # accordingly
            me = unite_multiple_shapes(maskcube, *E)
            maskcube = me[0]
            E = me[1:]
            dprint(2, "maskcube sum", maskcube.sum())
            for ej in E:
                ej[maskcube] = 0
        # now tease the E's apart plane by plane
        # make vellsets
        vellsets = []
        for isrc in range(nsrc):
            for ej in E:
                dprint(
                    2, "source %d has %d null gains" %
                    (isrc, (ej[isrc, ...] == 0).sum()))
                ejplane = ej[isrc, ...]
                value = meq.complex_vells(ejplane.shape, ejplane)
                vellsets.append(meq.vellset(value))
        return vellsets
 def get_result (self,request,*children):
   # get list of VoltageBeams
   vbs,beam_max = self.init_voltage_beams();
   # now, figure out the lm and time/freq grid
   # lm may be a 2/3-vector or an Nx2/3 tensor
   lm = children[0];
   dims = getattr(lm,'dims',[len(lm.vellsets)]);
   if len(dims) == 2 and dims[1] in (2,3):
     nsrc,nlm = dims;
     tensor = True;
   elif len(dims) == 1 and dims[0] in (2,3):
     nsrc,nlm = 1,dims[0];
     tensor = False;
   else:
     print "child 0: %d vellsets, shape %s"%(len(lm.vellsets),getattr(lm,'dims',[]));
     raise TypeError,"expecting a 2/3-vector or an Nx2/3 matrix for child 0 (lm)";
   # pointing offsets (child 1) are optional
   if len(children) > 1:
     dlm = children[1];
     if len(dlm.vellsets) != 2:
       raise TypeError,"expecting a 2-vector for child 1 (dlm)";
     dl,dm = dlm.vellsets[0].value,dlm.vellsets[1].value;
   else:
     dl = dm = 0;
   # setup grid dict that will be passed to VoltageBeam.interpolate
   grid = dict();
   for axis in 'time','freq':
     values = _cells_grid(lm,axis);
     if values is None:
       values = _cells_grid(request,axis);
     if values is not None:
       grid[axis] = values;
   vellsets = [];
   # now loop over sources and interpolte
   for isrc in range(nsrc):
     # put l,m into grid
     l,m = lm.vellsets[isrc*nlm].value,lm.vellsets[isrc*nlm+1].value;
     l,dl = unite_shapes(l,dl);
     m,dm = unite_shapes(m,dm);
     grid['l'] = l - dl;
     grid['m'] = m - dm;
     # interpolate
     for vb in vbs:
       if vb is None:
         vellsets.append(meq.vellset(meq.sca_vells(0.)));
       else:
         beam = vb.interpolate(freqaxis=self._freqaxis,**grid);
         if self.normalize and beam_max != 0:
           beam /= beam_max;
         vells = meq.complex_vells(beam.shape);
         vells[...] = beam[...];
         # make vells and return result
         vellsets.append(meq.vellset(vells));
   # create result object
   cells = request.cells if vb.hasFrequencyAxis() else getattr(lm,'cells',None);
   result = meq.result(vellsets[0],cells=cells);
   if len(vellsets) > 1:
     result.vellsets[1:] = vellsets[1:];
   # vbs is either length 4 or length 1. If length 4, then result needs to have its dimensions
   if len(vbs) > 1:
     result.dims = (nsrc,2,2) if tensor else (2,2);
   return result;
Пример #14
0
  def interpolate_batch (self,lm_list,dl,dm,grid,vbs,thetaphi=False,rotate=None,masklist=None):
    # A faster version of interpolate_per_source(), which assumes that all lm's (as well as the masks, if given) 
    # have the same shape, and stacks them into a single array for a single interpolation call.
    # If there's a shape mismatch, it'll fall back to interpolate_per_source
    # 'maskarr', if given, should be an list of per-source mask arrays 
    nsrc = len(lm_list);
    maskcube = None;
    for isrc,(l,m) in enumerate(lm_list):
      mask = masklist[isrc] if masklist is not None else None;
      # apply pointing offsets, if any
      if dl is not None:
        # unite shapes just in case, since l/m and dl/dm may have time/freq axes
        l,dl,m,dm = unite_multiple_shapes(l,dl,m,dm);
        l,m = l-dl,m-dm;
      # unite l,m shapes just in case, and transform
      l,m,mask = unite_multiple_shapes(l,m,mask);
      if not isrc:
        lm_shape = l.shape;
        cubeshape = [nsrc]+list(lm_shape);
        lcube = numpy.zeros(cubeshape,float);
        mcube = numpy.zeros(cubeshape,float);
        if masklist is not None:
          maskcube = numpy.zeros(cubeshape,bool);
      else:
        if l.shape != lm_shape:
          dprint(1,"l/m shapes unequal at source %d, falling back to per-source interpolation"%isrc);
          return self.interpolate_per_source(lm_list,dl,dm,grid,vbs,thetaphi=thetaphi,rotate=rotate,masklist=masklist);
      lcube[isrc,...] = l;
      mcube[isrc,...] = m;
      if mask is not None:
        maskcube[isrc,...] = mask;
#        if mask.any():
#          dprint(2,"source %d has %d slots masked"%(isrc,mask.sum()));
    # if 'rotate' is specified, it needs to be promoted to the same cube shape, and ravelled
    if rotate is not None:
      lcube,mcube,maskcube,rotate = unite_multiple_shapes(lcube,mcube,maskcube,rotate.reshape([1]+list(rotate.shape)));
      cubeshape = list(lcube.shape);
      rotate = rotate.ravel();
    # ok, we've stacked things into lm cubes, interpolate
    grid['l'],grid['m'] = lcube.ravel(),mcube.ravel();
    # loop over all 2x2 matrices (we may have several, they all need to be added)
    E = [None]*4;
    for vbmat in vbs:
      for i,vb in enumerate(vbmat):
        beam = vb.interpolate(freqaxis=self._freqaxis,extra_axes=1,thetaphi=thetaphi,rotate=rotate,**grid);
        if E[i] is None:
          E[i] = beam;
        else:
          E[i] += beam;
    # The l/m cubes have a shape of [nsrcs,lm_shape].
    # These are raveled for interpolation, so the resulting Es have a shape of [nsrcs*num_lm_points,num_freq]
    # Reshape them properly. Note that there's an extra "source" axis at the front, so the frequency axis
    # is off by 1.
    if len(cubeshape) <= self._freqaxis+1:
      cubeshape = list(cubeshape) + [1]*(self._freqaxis - len(cubeshape) + 2);
    cubeshape[self._freqaxis+1] = len(grid['freq']);
    E = [ ej.reshape(cubeshape) for ej in E ];
    # apply mask cube, if we had one
    if maskcube is not None:
      # the E planes now have the same shape as the maskcube, but with an extra frequency axis. Promote the maskcube
      # accordingly
      me = unite_multiple_shapes(maskcube,*E);
      maskcube = me[0];
      E = me[1:];
      dprint(2,"maskcube sum",maskcube.sum());
      for ej in E:
        ej[maskcube] = 0;
    # now tease the E's apart plane by plane
    # make vellsets
    vellsets = [];
    for isrc in range(nsrc):
      for ej in E:
        dprint(2,"source %d has %d null gains"%(isrc,(ej[isrc,...]==0).sum()));
        ejplane = ej[isrc,...];
        value = meq.complex_vells(ejplane.shape,ejplane);
        vellsets.append(meq.vellset(value));
    return vellsets;