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;
Beispiel #2
0
  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
Beispiel #3
0
    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
Beispiel #4
0
 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);
Beispiel #6
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;
  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;
Beispiel #9
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
  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;
Beispiel #11
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
 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;
Beispiel #15
0
    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
Beispiel #16
0
    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
Beispiel #18
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):
        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