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): global _albus_time global _albus_rm # get time and frequency for the tile cells = request.cells cells_shape = meq.shape(cells); time = cells.grid.time freq = cells.grid.freq # use scipy to interpolate and get rm for MS times f = interp1d(_albus_time, _albus_rm) rotation_measure = f(time) factor = LIGHT_SPEED / freq out_array = meq.vells(cells_shape) metre_sq = factor * factor for j in range(cells_shape[0]): angle = rotation_measure[j] * metre_sq out_array[j,:] = angle vellsets = []; vellsets.append(meq.vellset(out_array)) res = meq.result(cells = request.cells) res.vellsets = vellsets return res
def get_result(self, request): global _albus_time global _albus_rm # get time and frequency for the tile cells = request.cells cells_shape = meq.shape(cells) time = cells.grid.time freq = cells.grid.freq # use scipy to interpolate and get rm for MS times f = interp1d(_albus_time, _albus_rm) rotation_measure = f(time) factor = LIGHT_SPEED / freq out_array = meq.vells(cells_shape) metre_sq = factor * factor for j in range(cells_shape[0]): angle = rotation_measure[j] * metre_sq out_array[j, :] = angle vellsets = [] vellsets.append(meq.vellset(out_array)) res = meq.result(cells=request.cells) res.vellsets = vellsets return res
def get_result (self,request,*children): if len(children): raise TypeError("this is a leaf node, no children expected!"); # make value of same shape as cells cells = request.cells; shape = meq.shape(cells); print("cells shape is",shape); value = meq.vells(shape); # fill in random numbers with the given distribution flat = value.ravel(); # 'flat' reference to array data for i in range(flat.size): flat[i] = self._generator(*self.distribution_args); return meq.result(meq.vellset(value),cells);
def get_result (self,request,*children): if len(children): raise TypeError,"this is a leaf node, no children expected!"; # make value of same shape as cells cells = request.cells; shape = meq.shape(cells); print "cells shape is",shape; value = meq.vells(shape); # fill in random numbers with the given distribution flat = value.ravel(); # 'flat' reference to array data for i in range(flat.size): flat[i] = self._generator(*self.distribution_args); return meq.result(meq.vellset(value),cells);
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 get_result (self,request,*children): try: if len(children) != 1: raise TypeError,"one child expected"; res0 = children[0]; vellsets = []; cells = res0.cells; elevation = res0.vellsets[1].value; shape = elevation.shape # there's probably a numpy function for this for i in range(shape[0]): if elevation[i,0] < 0.0: elevation[i,0] = 0.0 vellsets.append(meq.vellset(elevation)) res = meq.result(cells = cells) res.vellsets = vellsets return res except: traceback.print_exc(); raise;
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): try: if len(children) != 3: raise TypeError,"two children expected"; res0 = children[0]; vellsets = []; cells = res0.cells; result_vector = res0.vellsets[0].value; shape = result_vector.shape res1 = children[1]; min_random = res1.vellsets[0].value res2 = children[2]; max_random = res2.vellsets[0].value noise = random.uniform(min_random, max_random) for i in range(shape[0]): result_vector[i,0] = noise vellsets.append(meq.vellset(result_vector)) res = meq.result(cells = cells) res.vellsets = vellsets return res except: traceback.print_exc(); raise;
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 get_result (self,request,*children): try: if len(children) < 1: raise TypeError,"at least one child is expected"; # now, figure out the lms # 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: 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 = None; # turn freq into an array of the proper shape freq = request.cells.grid.freq; freqshape = [1]*(self._freqaxis+1); freqshape[self._freqaxis] = len(freq); freq = freq.reshape(freqshape); # now compute the beam per source vellsets = []; for isrc in range(nsrc): # get l/m for this sources l,m = lm.vellsets[isrc*nlm].value,lm.vellsets[isrc*nlm+1].value; # apply pointing offset, if given if dl is not None: dl,l,dm,m = unite_multiple_shapes(dl,l,dm,m); l = l - dl m = m - dm l,m,fq = unite_multiple_shapes(l,m,freq); # compute distance (scaled by frequency) dist = fq*self.scale*numpy.sqrt(l*l+m*m); # compute sinc function E = meq.vells(dist.shape); E[...] = numpy.sin(dist)/dist; E[dist==0] = 1; E[(l<0)|(m<0)] = 0; vellsets.append(meq.vellset(E)); # form up result and return result = meq.result(vellsets[0],cells=request.cells); result.vellsets[1:] = vellsets[1:]; # result.dims = (nsrc,) if tensor else (1.); return result; #res0 = children[0]; #res1 = children[1]; #cells = res0.cells #l = res0.vellsets[0].value; #m = res1.vellsets[0].value; #shape = l.shape #for i in range(shape[0]): #if l[i,0] < 0.0 or m[i,0] < 0.0: #l[i,0] = 0.0 #else: #dist = 265.667 * math.sqrt(l[i,0]*l[i,0] + m[i,0]*m[i,0]) ## 265.667 is scaling factor to get 0.707 voltage response at 18 arcmin from pointing position (nominal FWHM=36arcmin at 1.4 GHz) #l[i,0] = math.sin(dist) / dist #vellsets = []; #vellsets.append(meq.vellset(l)) #res = meq.result(cells=cells) #res.vellsets = vellsets #return res except: traceback.print_exc(); raise;
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;
def get_result(self, request, *children): if len(children) < 2: raise TypeError, "this is NOT a leaf node, At least 2 children expected!" cells = request.cells res = meq.result(None, cells) Xp_table = [0, 0, 0] # if necessary loop over time and other axis # First get PiercePoints res1 = children[1] vs1 = res1.vellsets # num_pierce_points each containing vector of length 2 or 3 (x,y(,z)) dims = res1.dims vector_size = dims[1] num_pp = dims[0] x = [] for j in range(num_pp): x.append([]) for i in range(vector_size): x[j].append(0) # x=[[0,]*vector_size,]*num_pp; Xp_table = [0, ] * num_pp for i in range(num_pp): for j in range(vector_size): x[i][j] = vs1[i * vector_size + j].value shape = meq.shape(x[0][0]) grid_size = len(x[0][0]) # print "grid_size",grid_size; # Then the parameters res0 = children[0] vs0 = res0.vellsets # should be one per parameter num_parms = len(vs0) val0 = [0, ] * num_parms par = [0, ] * num_parms solvable = False parmidx = range(num_parms) # initialize result vector 1 field per pp; # ph=[[0,]*grid_size,]*num_parms; ph = [] for j in range(num_pp): ph.append([]) for i in range(grid_size): ph[j].append(0) # if solvable they should have perturbed_values; if vs0[0].has_key('perturbed_value'): solvable = True pert = [0] * num_parms pt = [] perturbations = () spid_index = () # get spidindex for i in range(num_parms): spid_index += vs0[i].spid_index # sort on spidindex for i in range(num_parms): for j in range(i): if spid_index[i] < spid_index[parmidx[j]]: newidx = i for k in range(j, i + 1): old = parmidx[k] parmidx[k] = newidx newidx = old break spid_index = () # 1 perturbed value per pp per paramter # or the other way around??? for i in range(num_parms): pt.append([]) for i2 in range(num_pp): pt[i].append([]) for g in range(grid_size): pt[i][i2].append(0) # fill values sorted for pn in range(num_parms): pnidx = parmidx[pn] val0[pn] = vs0[pnidx].value par[pn] = val0[pn][0] # use first value (in case of constant parms) # assume single perturbation parms for the moment if solvable: pert[pn] = vs0[pnidx].perturbed_value[0] spid_index += vs0[pnidx].spid_index perturbations += vs0[pnidx].perturbations # get U matrix # Only if domain changed!! for i in range(grid_size): for j in range(vector_size): for k in range(num_pp): Xp_table[k] = x[k][j][i] U, S, Ut, B = get_U(Xp_table, order=num_parms) for pn in range(num_parms): if len(val0[pn]) > i: # incorrect check for freq/time dependendies par[pn] = (val0[pn][i]) value = dot(U, par) for v in range(num_pp): ph[v][i] = value[v] for v in range(num_parms): if solvable: old = par[v] if len(pert[v]) > i: par[v] = pert[v][i] else: par[v] = pert[v][0] pval = dot(U, par) par[v] = old for v2 in range(num_pp): pt[v][v2][i] = pval[v2] vellsets = [] for v in range(num_pp): value = meq.vells(shape) ph[v] = array(ph[v]) ph[v].shape = shape value[:] = ph[v] vellsets.append(meq.vellset(value)) if solvable: vellsets[v].perturbed_value = () for v2 in range(num_parms): value = meq.vells(shape) pt[v2][v] = array(pt[v2][v]) pt[v2][v].shape = shape value[:] = pt[v2][v] vellsets[v].perturbed_value += (value,) vellsets[v].spid_index = spid_index vellsets[v].perturbations = perturbations res.vellsets = vellsets # res.dims = [3,1]; # return meq.result(meq.vellset(value),cells); # print "result",res return res
def get_result(self, request, *children): if len(children) < 2: raise TypeError, "this is NOT a leaf node, At least 2 children expected!" cells = request.cells res = meq.result(None, cells) Xp_table = [0, 0, 0] # if necessary loop over time and other axis # First get PiercePoints res1 = children[1] vs1 = res1.vellsets # num_pierce_points each containing vector of length 2 or 3 (x,y(,z)) dims = res1.dims vector_size = dims[1] num_pp = dims[0] x = [] for j in range(num_pp): x.append([]) for i in range(vector_size): x[j].append(0) # x=[[0,]*vector_size,]*num_pp; Xp_table = [ 0, ] * num_pp for i in range(num_pp): for j in range(vector_size): x[i][j] = vs1[i * vector_size + j].value shape = meq.shape(x[0][0]) grid_size = len(x[0][0]) # print "grid_size",grid_size; # Then the parameters res0 = children[0] vs0 = res0.vellsets # should be one per parameter num_parms = len(vs0) val0 = [ 0, ] * num_parms par = [ 0, ] * num_parms solvable = False parmidx = range(num_parms) # initialize result vector 1 field per pp; # ph=[[0,]*grid_size,]*num_parms; ph = [] for j in range(num_pp): ph.append([]) for i in range(grid_size): ph[j].append(0) # if solvable they should have perturbed_values; if vs0[0].has_key('perturbed_value'): solvable = True pert = [0] * num_parms pt = [] perturbations = () spid_index = () # get spidindex for i in range(num_parms): spid_index += vs0[i].spid_index # sort on spidindex for i in range(num_parms): for j in range(i): if spid_index[i] < spid_index[parmidx[j]]: newidx = i for k in range(j, i + 1): old = parmidx[k] parmidx[k] = newidx newidx = old break spid_index = () # 1 perturbed value per pp per paramter # or the other way around??? for i in range(num_parms): pt.append([]) for i2 in range(num_pp): pt[i].append([]) for g in range(grid_size): pt[i][i2].append(0) # fill values sorted for pn in range(num_parms): pnidx = parmidx[pn] val0[pn] = vs0[pnidx].value par[pn] = val0[pn][0] # use first value (in case of constant parms) # assume single perturbation parms for the moment if solvable: pert[pn] = vs0[pnidx].perturbed_value[0] spid_index += vs0[pnidx].spid_index perturbations += vs0[pnidx].perturbations # get U matrix # Only if domain changed!! for i in range(grid_size): for j in range(vector_size): for k in range(num_pp): Xp_table[k] = x[k][j][i] U, S, Ut, B = get_U(Xp_table, order=num_parms) for pn in range(num_parms): if len(val0[pn]) > i: # incorrect check for freq/time dependendies par[pn] = (val0[pn][i]) value = dot(U, par) for v in range(num_pp): ph[v][i] = value[v] for v in range(num_parms): if solvable: old = par[v] if len(pert[v]) > i: par[v] = pert[v][i] else: par[v] = pert[v][0] pval = dot(U, par) par[v] = old for v2 in range(num_pp): pt[v][v2][i] = pval[v2] vellsets = [] for v in range(num_pp): value = meq.vells(shape) ph[v] = array(ph[v]) ph[v].shape = shape value[:] = ph[v] vellsets.append(meq.vellset(value)) if solvable: vellsets[v].perturbed_value = () for v2 in range(num_parms): value = meq.vells(shape) pt[v2][v] = array(pt[v2][v]) pt[v2][v].shape = shape value[:] = pt[v2][v] vellsets[v].perturbed_value += (value, ) vellsets[v].spid_index = spid_index vellsets[v].perturbations = perturbations res.vellsets = vellsets # res.dims = [3,1]; # return meq.result(meq.vellset(value),cells); # print "result",res return res
def get_result(self, request, *children): if len(children) < 1: raise TypeError( "this is NOT a leaf node, At least 1 child with piercepoints expected!" ) res1 = children[0] vs1 = res1.vellsets # pierce_points, vector of length 2 or 3 (x,y(,z)) vector_size = len(vs1) # for now use fist two: if vector_size < 2: raise TypeError( "vector size of child 1 too small, at leat x/y expected") xv = vs1[0].value[0] yv = vs1[1].value[0] if vs1[0].has_field('shape'): shapex = vs1[0].shape else: shapex = (1, ) if vs1[1].has_field('shape'): shapey = vs1[1].shape else: shapey = (1, ) cells = request.cells seg = cells.segments.time # print '************************************************************' # print cells # print '------------------------------------------------------------' # print seg # print '************************************************************' # the startt and endt are the timeslots when tiling is set > 1 if type(seg.start_index) == type(1): startt = seg.start_index endt = seg.end_index else: startt = seg.start_index[0] endt = seg.end_index[-1] # print '************************************************************' # print startt, endt # print '************************************************************' # make time a lot smaller to prevent precision errors for int # the actual value of the constant time = cells.grid.time - self.starttime if startt >= endt: time = [ time, ] val = [] for it in range(startt, endt + 1): if shapex[0] > 1: xv = vs1[0].value[it] if shapey[0] > 1: yv = vs1[1].value[it] xshift = (time[it]) * self.speedx yshift = (time[it]) * self.speedy xn = (xv + xshift) / self.scale yn = (yv + yshift) / self.scale xn = int(xn) % ( self.grid_size ) # zorg dat xn een integer tussen 0 en grid_size is yn = int(yn) % ( self.grid_size ) # zorg dat xn een integer tussen 0 en grid_size is val.append(PhaseScreen.phasescreen[xn][yn] * self.amp_scale + self.tec0) # fill result res = meq.result(None, cells) # print startt,endt,seg,val; val2 = meq.vells(shape=meq.shape(endt + 1, )) val2[:] = val vs = meq.vellset(val2) res.vellsets = [ vs, ] return res
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): if len(children)<1: raise TypeError,"this is NOT a leaf node, At least 1 child with piercepoints expected!"; res1=children[0]; vs1=res1.vellsets; #pierce_points, vector of length 2 or 3 (x,y(,z)) vector_size=len(vs1); #for now use fist two: if vector_size<2: raise TypeError,"vector size of child 1 too small, at leat x/y expected"; xv=vs1[0].value[0]; yv=vs1[1].value[0]; if vs1[0].has_field('shape'): shapex=vs1[0].shape; else: shapex=(1,); if vs1[1].has_field('shape'): shapey=vs1[1].shape; else: shapey=(1,); cells=request.cells; seg=cells.segments.time; # print '************************************************************' # print cells # print '------------------------------------------------------------' # print seg # print '************************************************************' # the startt and endt are the timeslots when tiling is set > 1 if type(seg.start_index) == type(1): startt = seg.start_index; endt = seg.end_index; else: startt = seg.start_index[0]; endt = seg.end_index[-1]; # print '************************************************************' # print startt, endt # print '************************************************************' # make time a lot smaller to prevent precision errors for int # the actual value of the constant time=cells.grid.time - self.starttime; if startt>=endt: time=[time,]; val=[]; for it in range(startt,endt+1): if shapex[0]>1: xv=vs1[0].value[it]; if shapey[0]>1: yv=vs1[1].value[it]; xshift=(time[it])*self.speedx; yshift=(time[it])*self.speedy; xn=(xv+xshift)/self.scale; yn=(yv+yshift)/self.scale; xn=int(xn)%(self.grid_size) # zorg dat xn een integer tussen 0 en grid_size is yn=int(yn)%(self.grid_size) # zorg dat xn een integer tussen 0 en grid_size is val.append(PhaseScreen.phasescreen[xn][yn]*self.amp_scale + self.tec0); #fill result res = meq.result(0,cells); # print startt,endt,seg,val; val2=meq.vells(shape=meq.shape(endt+1,)); val2[:]=val; vs=meq.vellset(val2); res.vellsets=[vs,] return res;
def get_result(self, request, *children): try: if len(children) < 1: raise TypeError, "at least one child is expected" # now, figure out the lms # 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: 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 = None # turn freq into an array of the proper shape freq = request.cells.grid.freq freqshape = [1] * (self._freqaxis + 1) freqshape[self._freqaxis] = len(freq) freq = freq.reshape(freqshape) # now compute the beam per source vellsets = [] for isrc in range(nsrc): # get l/m for this sources l, m = lm.vellsets[isrc * nlm].value, lm.vellsets[isrc * nlm + 1].value # apply pointing offset, if given if dl is not None: dl, l, dm, m = unite_multiple_shapes(dl, l, dm, m) l = l - dl m = m - dm l, m, fq = unite_multiple_shapes(l, m, freq) # compute distance (scaled by frequency) dist = fq * self.scale * numpy.sqrt(l * l + m * m) # compute sinc function E = meq.vells(dist.shape) E[...] = numpy.sin(dist) / dist E[dist == 0] = 1 E[(l < 0) | (m < 0)] = 0 vellsets.append(meq.vellset(E)) # form up result and return result = meq.result(vellsets[0], cells=request.cells) result.vellsets[1:] = vellsets[1:] # result.dims = (nsrc,) if tensor else (1.); return result #res0 = children[0]; #res1 = children[1]; #cells = res0.cells #l = res0.vellsets[0].value; #m = res1.vellsets[0].value; #shape = l.shape #for i in range(shape[0]): #if l[i,0] < 0.0 or m[i,0] < 0.0: #l[i,0] = 0.0 #else: #dist = 265.667 * math.sqrt(l[i,0]*l[i,0] + m[i,0]*m[i,0]) ## 265.667 is scaling factor to get 0.707 voltage response at 18 arcmin from pointing position (nominal FWHM=36arcmin at 1.4 GHz) #l[i,0] = math.sin(dist) / dist #vellsets = []; #vellsets.append(meq.vellset(l)) #res = meq.result(cells=cells) #res.vellsets = vellsets #return res except: traceback.print_exc() raise