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;
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;
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 ()]
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 ()];
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
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;
def _expand_trivial_subshape(self, x, datashape=None, data_subset=None): a = meq.complex_vells(x.shape) a[...] = x return a[data_subset]
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
def _expand_trivial_subshape (self,x,datashape=None,data_subset=None): a = meq.complex_vells(x.shape); a[...] = x; return a[data_subset];
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;
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;