def _find_shift(self, order=3): """ Find the best shift between image1 and image2. Expects _load_data() to have been run first to initialize things. order is the order of the spline used for shifting in the correlation step. """ # Mask pixels around the edges of the image. # We don't have inverse-variances because sdssproc isn't run, so we can't do # smarter masking, like bad pixel smoothing, cosmic rays, etc. # It is important to mask out the ends of the array, because of # spline-induced oddities there. subimg1 = self.bigimg1[self.region].copy() subimg2 = self.bigimg2[self.region].copy() mask = np.ones(subimg1.shape, dtype='f8') mask[:10, :] = 0 mask[-10:, :] = 0 mask[:, :10] = 0 mask[:, -10:] = 0 # Compute linear correlation coefficients # Calculate the maximum product of the two images when shifting by steps of dx. dx = 0.05 nshift = int(np.ceil(2 * self.maxshift / dx)) xshift = -self.maxshift + dx * np.arange(nshift, dtype='f8') self.xshift = xshift # save for plotting def calc_shift(xs, img1, img2, mask): shifted = interpolation.shift(img2, [xs, 0], order=order, prefilter=False) return (img1 * shifted * mask).sum() self.coeff = np.zeros(nshift, dtype='f8') filtered1 = interpolation.spline_filter(subimg1) filtered2 = interpolation.spline_filter(subimg2) for i in range(nshift): # self.coeff[i] = (subimg1 * interpolation.shift(subimg2, # [xshift[i], 0], # order=order) * mask).sum() # self.coeff[i] = (filtered1 * interpolation.shift(filtered2, # [xshift[i], 0], # order=order, # prefilter=False) * mask).sum() self.coeff[i] = calc_shift(xshift[i], filtered1, filtered2, mask) ibest = self.coeff.argmax() self.ibest = ibest # save for plotting self.xoffset = xshift[ibest] # If the sequence is actually R-L, instead of L-R, # then the offset acctually goes the other way. if self.hartpos1 == 'right': self.xoffset = -self.xoffset
def add_filter(pic): ''' add random filter to the picture ''' val = val = random.randint(1, 2) if val == 1: s = random.uniform(0.8, 1.2) pic = gaussian_filter(pic, sigma=s) elif val == 2: pic = spline_filter(pic) return pic
def create_radial_spline(psf, fn, sigma, egy, dtheta, psf_scale_fn): from scipy.ndimage.interpolation import spline_filter z = create_kernel_function_lookup( psf, fn, sigma, egy, dtheta, psf_scale_fn) sp = [] for i in range(z.shape[0]): sp += [spline_filter(z[i], order=2)] return sp
def create_radial_spline(psf, fn, sigma, egy, dtheta, psf_scale_fn): from scipy.ndimage.interpolation import spline_filter z = create_kernel_function_lookup(psf, fn, sigma, egy, dtheta, psf_scale_fn) sp = [] for i in range(z.shape[0]): sp += [spline_filter(z[i], order=2)] return sp
def setBeamCube(self, beam): """Initializes beam cube. Beam is a 2D (or 3D) cube.""" # init cube self._beam = beam.copy() self._beam_ampl = abs(beam) self._beam_real = beam.real self._beam_imag = beam.imag # replace with pre-filtered arrays if needed if beam.ndim > 2 and self._spline_order > 1: if not self._hier_interpol: self._beam_real = interpolation.spline_filter( beam.real, order=self._spline_order) self._beam_imag = interpolation.spline_filter( beam.imag, order=self._spline_order) self._beam_ampl = interpolation.spline_filter( self._beam_ampl, order=self._spline_order) else: # prefilter per frequency plane in per-frequency mode for i in range(beam.shape[2]): self._beam_real[..., i] = interpolation.spline_filter( beam.real[..., i], order=self._spline_order) self._beam_imag[..., i] = interpolation.spline_filter( beam.imag[..., i], order=self._spline_order) self._beam_ampl[..., i] = interpolation.spline_filter( self._beam_ampl[..., i], order=self._spline_order)
def __init__(self, scale_list, values, extrapolate=False, num_extrapolate=2, delta=1e-4): shape = values.shape ndim = len(shape) # error checking if ndim < 3: raise ValueError('Data must have 3 or more dimensions.') elif ndim != len(scale_list): raise ValueError('input and output dimension mismatch.') self._scale_list = scale_list self._max = values.shape self._ext = num_extrapolate # linearly extrapolate given values self._extfun = LinearInterpolator([(0, 1)] * ndim, values, extrapolate=True) self._extrapolate = extrapolate swp_values = [] ext_xi_shape = [] delta_list = [] for (offset, scale), n in zip(scale_list, shape): swp_values.append(np.arange(-num_extrapolate, n + num_extrapolate)) ext_xi_shape.append(n + 2 * num_extrapolate) delta_list.append(scale * delta) ext_xi_shape.append(ndim) xi = np.empty(ext_xi_shape) xmat_list = np.meshgrid(*swp_values, indexing='ij', copy=False) for idx, xmat in enumerate(xmat_list): xi[..., idx] = xmat values_ext = self._extfun(xi) self._filt_values = imag_interp.spline_filter(values_ext) DiffFunction.__init__(self, ndim, delta_list=delta_list)
def __init__(self, scale_list, values, extrapolate=False, num_extrapolate=3, delta=1e-4): shape = values.shape ndim = len(shape) # error checking if ndim < 3: raise ValueError('Data must have 3 or more dimensions.') elif ndim != len(scale_list): raise ValueError('input and output dimension mismatch.') self._scale_list = scale_list self._max = [n - 1 + num_extrapolate for n in shape] self._extrapolate = extrapolate self._ext = num_extrapolate # linearly extrapolate given values ext_points = [ np.arange(num_extrapolate, n + num_extrapolate) for n in shape ] points, delta_list = _scales_to_points(scale_list, values, delta) input_ranges = [(pvec[0], pvec[-1]) for pvec in points] self._extfun = LinearInterpolator(ext_points, values, [delta] * ndim, extrapolate=True) xi_ext = np.stack(np.meshgrid(*(np.arange(0, n + 2 * num_extrapolate) for n in shape), indexing='ij', copy=False), axis=-1) values_ext = self._extfun(xi_ext) self._filt_values = imag_interp.spline_filter(values_ext) DiffFunction.__init__(self, input_ranges, delta_list=delta_list)
def __init__(self, data, pix_ref, shape_out, rebin): self._data = data self._data_spline = [] for i in range(data.shape[0]): self._data_spline += [spline_filter(self._data[i], order=2)] self._axes = [] for i in range(data.ndim): self._axes += [np.arange(0, data.shape[i], dtype=float)] #self._coords = np.meshgrid(*self._axes[1:], indexing='ij') self._rebin = rebin # Shape of global output array self._shape_out = shape_out self._shape = np.array(self.data.shape) for i in range(1, self.data.ndim): self._shape[i] = int(self._shape[i] / self.rebin) self._shape = tuple(self._shape) # Reference pixel coordinates self._pix_ref = pix_ref
def setBeamCube (self,beam): """Initializes beam cube. Beam is a 2D (or 3D) cube."""; # init cube self._beam = beam.copy(); self._beam_ampl = abs(beam); self._beam_real = beam.real; self._beam_imag = beam.imag; # replace with pre-filtered arrays if needed if beam.ndim > 2 and self._spline_order > 1: if not self._hier_interpol: self._beam_real = interpolation.spline_filter(beam.real,order=self._spline_order); self._beam_imag = interpolation.spline_filter(beam.imag,order=self._spline_order); self._beam_ampl = interpolation.spline_filter(self._beam_ampl,order=self._spline_order); else: # prefilter per frequency plane in per-frequency mode for i in range(beam.shape[2]): self._beam_real[...,i] = interpolation.spline_filter(beam.real[...,i],order=self._spline_order); self._beam_imag[...,i] = interpolation.spline_filter(beam.imag[...,i],order=self._spline_order); self._beam_ampl[...,i] = interpolation.spline_filter(self._beam_ampl[...,i],order=self._spline_order);
def spline_filter(grid,order=3): filtered = grid.copy() sciest.spline_filter(grid,order,filtered) return filtered
def draw(self, painter, xmap, ymap, rect): """Implements QwtPlotItem.draw(), to render the image on the given painter.""" xp1, xp2, xdp, xs1, xs2, xds = xinfo = xmap.p1(), xmap.p2( ), xmap.pDist(), xmap.s1(), xmap.s2(), xmap.sDist() yp1, yp2, ydp, ys1, ys2, yds = yinfo = ymap.p1(), ymap.p2( ), ymap.pDist(), ymap.s1(), ymap.s2(), ymap.sDist() dprint(5, "draw:", rect, xinfo, yinfo) self._current_rect = QRectF(QPointF(xs2, ys1), QSizeF(xds, yds)) self._current_rect_pix = QRect( QPoint(*self.lmToPix(xs1, ys1)), QPoint(*self.lmToPix(xs2, ys2))).intersected( self._bounding_rect_pix) dprint(5, "draw:", self._current_rect_pix) # put together tuple describing current mapping mapping = xinfo, yinfo # if mapping has changed w.r.t. cache (i.e. zoom has changed), discard all cached QImages if mapping != self._cache_mapping: dprint(2, "does not match cached mapping, cache is:", self._cache_mapping) dprint(2, "and we have:", mapping) self.clearDisplayCache() self._cache_mapping = mapping t0 = time.time() # check cached QImage for current image key. qimg = self._cache_qimage.get(self._image_key) if qimg: dprint(5, "QImage found in cache, reusing") # else regenerate image else: # check for cached intensity-mapped data if self._cache_imap is not None: dprint(5, "intensity-mapped data found in cache, reusing") else: if self._cache_interp is not None: dprint(5, "interpolated data found in cache, reusing") else: image = self._image.transpose( ) if self._data_fortran_order else self._image spline_order = 2 xsamp = abs(xmap.sDist() / xmap.pDist()) / abs(self._dl) ysamp = abs(ymap.sDist() / ymap.pDist()) / abs(self._dm) if max(xsamp, ysamp) < .33 or min(xsamp, ysamp) > 2: spline_order = 1 dprint(2, "regenerating drawing cache, sampling factors are", xsamp, ysamp, "spline order is", spline_order) self._cache_imap = None if self._prefilter is None and spline_order > 1: self._prefilter = interpolation.spline_filter( image, order=spline_order) dprint(2, "spline prefiltering took", time.time() - t0, "secs") t0 = time.time() # make arrays of plot coordinates # xp[0],yp[0] corresponds to pixel 0,0, where 0,0 is the upper-left corner of the plot # the maps are in a funny order (w.r.t. meaning of p1/p2/s1/s2), so the indices here are determined empirically # We also adjust by half-pixel, to get the world coordinate of the pixel _center_ xp = xmap.s1() - (xmap.sDist() / xmap.pDist()) * ( 0.5 + numpy.arange(int(xmap.pDist()))) yp = ymap.s2() - (ymap.sDist() / ymap.pDist()) * ( 0.5 + numpy.arange(int(ymap.pDist()))) # now convert plot coordinates into fractional image pixel coordinates xi = self._x0 + (xp - self._l0) / self._dl yi = self._y0 + (yp - self._m0) / self._dm # interpolate image data ### # old code for nearest-neighbour interpolation ### # superceded by interpolation below (we simply round pixel coordinates to go to NN when oversampling) ### xi = xi.round().astype(int); ### oob_x = (xi<0)|(xi>=self._nx); ### xi[oob_x] = 0; ### yi = yi.round().astype(int); ### oob_y = (yi<0)|(yi>=self._ny); ### yi[oob_y] = 0; ### idx = (xi[:,numpy.newaxis]*self._ny + yi[numpy.newaxis,:]).ravel(); ### interp_image = self._image.ravel()[idx].reshape((len(xi),len(yi))); ### interp_image[oob_x,:] = 0; ### interp_image[:,oob_y] = 0; ### self._qimage_cache = self.colormap.colorize(interp_image,self._img_range); ### self._qimage_cache_attrs = (rect,xinfo,yinfo); # if either axis is oversampled by a factor of 3 or more, switch to nearest-neighbour interpolation by rounding pixel values if xsamp < .33: xi = xi.round() if ysamp < .33: yi = yi.round() # make [2,nx,ny] array of interpolation coordinates xy = numpy.zeros((2, len(xi), len(yi))) xy[0, :, :] = xi[:, numpy.newaxis] xy[1, :, :] = yi[numpy.newaxis, :] # interpolate. Use NAN for out of range pixels... # for fortran order, tranpose axes for extra speed (flip XY around then) if self._data_fortran_order: xy = xy[-1::-1, ...] if spline_order > 1: interp_image = interpolation.map_coordinates( self._prefilter, xy, order=spline_order, cval=numpy.nan, prefilter=False) else: interp_image = interpolation.map_coordinates( image, xy, order=spline_order, cval=numpy.nan) # ...and put a mask on them (Colormap.colorize() will make these transparent). mask = ~numpy.isfinite(interp_image) self._cache_interp = numpy.ma.masked_array( interp_image, mask) dprint(2, "interpolation took", time.time() - t0, "secs") t0 = time.time() # ok, we have interpolated data in _cache_interp self._cache_imap = self.imap.remap(self._cache_interp) dprint(2, "intensity mapping took", time.time() - t0, "secs") t0 = time.time() # ok, we have intensity-mapped data in _cache_imap qimg = self.colormap.colorize(self._cache_imap) dprint(2, "colorizing took", time.time() - t0, "secs") t0 = time.time() # cache the qimage self._cache_qimage[self._image_key] = qimg.copy() # now draw the image t0 = time.time() painter.drawImage(xp1, yp2, qimg) dprint(2, "drawing took", time.time() - t0, "secs")
def __init__(self, cubefile, convert_cube_content=False, convert_to_rs=False, PBC=True, shift='edge', order=3, verbose=False, precalc_weights=True): self.cubefile = cubefile # read the cube file # convert means density in e / A**3 full_output = read_cube(cubefile, full_output=True, convert=convert_cube_content) # conveniently map dict content to instance variables: # self.atoms # self.cube_data # self.voxdim # self.origin self.__dict__.update(full_output) if verbose: print(get_cube_info(self.cubefile)) self.convert_cube_content = convert_cube_content self.convert_to_rs = convert_to_rs # hard coded conversion factor self.A2au = 1. / Bohr # PBC treatment of the interpolation function self.PBC = PBC if self.PBC: self.mode = 'wrap' else: self.mode = 'constant' self.Q, self.Qinv = self._create_trafo_matrices(self.voxdim) # get the number of voxels self.Nx, self.Ny, self.Nz = self.cube_data.shape # get the cell self.cell = self.atoms.get_cell() # shifting the values shift = shift.lower() if shift == 'edge': self.shift = 0.0 else: self.shift = 0.5 # save spline order self.order = order # pre-calculate the spline weights (one-time process) # instead of doing this with every call to map_coordinates. # Acc. to Joe Kington's mail here: # http://scipy-user.10969.n7.nabble.com/SciPy-User-3D-spline-interpolation-very-very-slow-UPDATE-td19702.html if precalc_weights: self._cube_data = spline_filter(self.cube_data, order=self.order) # flag for map_coordinates self._prefilter = False else: self._cube_data = self.cube_data self._prefilter = True
def read(self, filenames): freqs = [] for ifreq, (filename_real, filename_imag) in enumerate(filenames): """Reads beam patterns from FITS files. If only one file is supplied, assumes a real-only beam. If two files are supplied, uses them for the real and imaginary parts. If 2N files are supplied, treats them as a frequency cube""" ff_re = pyfits.open(filename_real)[0] # form up complex beam beam = numpy.zeros(ff_re.data.shape, complex) beam.real = ff_re.data # add imaginary part if filename_imag: im_data = pyfits.open(filename_imag)[0].data if im_data.shape != ff_re.data.shape: raise TypeError, "shape mismatch between FITS files %s and %s" % ( filename_real, filename_imag) beam.imag = im_data # change order of axis, since FITS has first axis last beam = beam.transpose() # figure out axes axes = FITSAxes(ff_re.header) used_axes = [axes.iaxis(x) for x in "L", "M", "FREQ"] if any([x < 0 for x in used_axes]): raise TypeError, "FITS file %s missing L, M or FREQ axis" laxis, maxis, freqaxis = used_axes # check the other axes other_axes = sorted(set(range(axes.ndim())) - set(used_axes)) if any([axes.naxis(i) > 1 for i in other_axes]): raise TypeError, "FITS file %s has other non-trivial axes besides L/M" % filename_real # setup frequency grid freqgrid = axes.grid(freqaxis) if len(freqgrid) > 1: raise TypeError, "FITS file %s has >1 frequency points" if freqs and freqgrid[0] < freqs[-1]: raise TypeError, "FITS file %s has lower frequency than previous file -- monotonically increasing frequencies are expected" freqs.append(freqgrid[0]) # check if it matches previous image if not ifreq: baseshape = beam.shape self._axes = axes # setup 3D beam cube beamcube = numpy.zeros( (axes.naxis(laxis), axes.naxis(maxis), len(filenames)), complex) # setup conversion functions self._lToPixel = Kittens.utils.curry(axes.toPixel, laxis) self._mToPixel = Kittens.utils.curry(axes.toPixel, maxis) for ax in laxis, maxis: dprint( 1, "%s axis unit is %s" % (self._axes.type(ax), self._axes.unit(ax))) if not self._axes.unit(ax) or self._axes.unit( ax).upper() == "DEG": self._axes.setUnitScale(ax, DEG) else: if baseshape != beam.shape: raise TypeError, "FITS file %s has differing dimensions" % filename_real beam = beam.transpose(used_axes + other_axes) beam = beam.reshape(beam.shape[:len(used_axes)]) beamcube[:, :, ifreq] = beam[:, :, 0] # done reading the beam cube dprint(1, "beam array has shape", beamcube.shape) dprint(2, "l grid is", self._axes.grid(laxis)) dprint(2, "m grid is", self._axes.grid(maxis)) dprint(2, "freq grid is", freqs) self._freqaxis = freqs self._freq_interpolator = interpolate.interp1d(freqs, range(len(freqs)), 'linear') # prefilter beam for interpolator self._beam = beamcube self._beam_ampl = numpy.abs( beamcube) if self.ampl_interpolation else None if self._spline_order > 1: self._beam_real = interpolation.spline_filter( beamcube.real, order=self._spline_order) self._beam_imag = interpolation.spline_filter( beamcube.imag, order=self._spline_order) if self._beam_ampl: self._beam_ampl = interpolation.spline_filter( self._beam_ampl, order=self._spline_order) else: self._beam_real = beamcube.real self._beam_imag = beamcube.imag
def read(self, filename_real, filename_imag=None): """Reads beam patterns from FITS files. If only one file is supplied, assumes a real-only beam. If two files are supplied, uses them for the real and imaginary parts. If 2N files are supplied, treats them as a frequency cube""" ff_re = pyfits.open(filename_real)[0] # form up complex beam beam = numpy.zeros(ff_re.data.shape, complex) beam.real = ff_re.data beam_ampl = None # add imaginary part if filename_imag: im_data = pyfits.open(filename_imag)[0].data if im_data.shape != ff_re.data.shape: raise TypeError, "shape mismatch between FITS files %s and %s" % ( filename_real, filename_imag) beam.imag = im_data if self.ampl_interpolation: beam_ampl = numpy.abs(beam) # change order of axis, since FITS has first axis last beam = beam.transpose() if not beam_ampl is None: beam_ampl = beam_ampl.transpose() # figure out axes self._axes = axes = FITSAxes(ff_re.header) # find L/M axes laxis = axes.iaxis(self._l_axis) maxis = axes.iaxis(self._m_axis) if laxis < 0 or maxis < 0: raise TypeError, "FITS file %s missing %s or %s axis" % ( filename_real, self._l_axis, self._m_axis) # setup conversion functions self._lToPixel = Kittens.utils.curry(axes.toPixel, laxis, sign=self._l_axis_sign) self._mToPixel = Kittens.utils.curry(axes.toPixel, maxis, sign=self._m_axis_sign) # find frequency grid. self._freqToPixel will be None if no frequency axis freqaxis = axes.iaxis('FREQ') if freqaxis >= 0 and axes.naxis(freqaxis) > 1: dprint(1, "FREQ axis has %d points" % axes.naxis(freqaxis)) self._freqgrid = axes.grid(freqaxis) self._freqToPixel = Kittens.utils.curry(axes.toPixel, freqaxis) used_axes = [laxis, maxis, freqaxis] else: self._freqToPixel = None used_axes = [laxis, maxis] # used_axes is either (l,m,freq) or (l,m) # other_axes is all that remains, and they had better be all trivial other_axes = sorted(set(range(axes.ndim())) - set(used_axes)) if any([axes.naxis(i) > 1 for i in other_axes]): raise TypeError, "FITS file %s has other non-trivial axes besides L/M" % filename_real # setup units for ax in laxis, maxis: dprint(1, "%s axis unit is %s" % (axes.type(ax), axes.unit(ax))) if not axes.unit(ax) or axes.unit(ax).upper() == "DEG": axes.setUnitScale(ax, DEG) # transpose array into L,M order and reshape dprint(1, "beam array has shape", beam.shape) beam = beam.transpose(used_axes + other_axes) beam = beam.reshape(beam.shape[:len(used_axes)]) if not beam_ampl is None: beam_ampl = beam_ampl.transpose(used_axes + other_axes) beam_ampl = beam_ampl.reshape(beam_ampl.shape[:len(used_axes)]) dprint(1, "beam array has shape", beam.shape) dprint(2, "l grid is", axes.grid(laxis)) dprint(2, "m grid is", axes.grid(maxis)) if self._freqToPixel: dprint(2, "freq grid is", axes.grid(freqaxis)) # prefilter beam for interpolator self._beam = beam if self._spline_order > 1: self._beam_real = interpolation.spline_filter( beam.real, order=self._spline_order) self._beam_imag = interpolation.spline_filter( beam.imag, order=self._spline_order) if not beam_ampl is None: self._beam_ampl = interpolation.spline_filter( beam_ampl, order=self._spline_order) else: self._beam_ampl = beam_ampl else: self._beam_real = beam.real self._beam_imag = beam.imag self._beam_ampl = beam_ampl
def calc_splinecoeffs(self): self.u_coeffs = spline_filter(self.u) self.v_coeffs = spline_filter(self.v) self.p0 = self.grid[:, 0, 0, 0] self.inv_dp = 1. / (self.grid[:, 1, 1, 1] - self.p0)
def calc_splinecoeffs(self): self.u_coeffs = spline_filter(self.u) self.v_coeffs = spline_filter(self.v) self.p0 = self.grid[:,0,0,0] self.inv_dp = 1. / (self.grid[:,1,1,1] - self.p0)
def smoothPlot(self): if not self.plotted_ticket is None: try: if self.filter==0 or 2<=self.filter<=5: congruence.checkStrictlyPositiveNumber(self.filter_sigma_h, "Sigma/Size H") congruence.checkStrictlyPositiveNumber(self.filter_sigma_v, "Sigma/Size V") if self.filter == 1: congruence.checkStrictlyPositiveNumber(self.filter_spline_order, "Spline Order") ticket = self.plotted_ticket.copy() mask = numpy.where(self.plotted_ticket["histogram"] <= self.plotted_ticket["histogram"].max()*self.masking_level) histogram = ticket["histogram"] h_coord = ticket["bin_h_center"] v_coord = ticket["bin_v_center"] norm = histogram.sum() pixel_area = (h_coord[1]-h_coord[0])*(v_coord[1]-v_coord[0]) filter_mode = self.cb_filter_mode.currentText() if self.filter == 0: histogram = filters.gaussian_filter(histogram, sigma=(self.filter_sigma_h, self.filter_sigma_v), mode=filter_mode, cval=self.filter_cval) elif self.filter == 1: histogram = interpolation.spline_filter(histogram, order=int(self.filter_spline_order)) elif self.filter == 2: histogram = filters.uniform_filter(histogram, size=(int(self.filter_sigma_h), int(self.filter_sigma_v)), mode=filter_mode, cval=self.filter_cval) elif self.filter == 3: histogram = numpy.real(numpy.fft.ifft2(fourier.fourier_gaussian(numpy.fft.fft2(histogram), sigma=(self.filter_sigma_h, self.filter_sigma_v)))) elif self.filter == 4: histogram = numpy.real(numpy.fft.ifft2(fourier.fourier_ellipsoid(numpy.fft.fft2(histogram), size=(self.filter_sigma_h, self.filter_sigma_v)))) elif self.filter == 5: histogram = numpy.real(numpy.fft.ifft2(fourier.fourier_uniform(numpy.fft.fft2(histogram), size=(self.filter_sigma_h, self.filter_sigma_v)))) elif self.filter == 6: histogram = self.apply_fill_holes(histogram) histogram[mask] = 0.0 norm /= histogram.sum() ticket["histogram"] = histogram*norm if self.plot_canvas is None: self.plot_canvas = PowerPlotXYWidget() self.image_box.layout().addWidget(self.plot_canvas) cumulated_power_plot = numpy.sum(histogram)*pixel_area energy_min=0.0 energy_max=0.0 energy_step=0.0 self.plot_canvas.cumulated_power_plot = cumulated_power_plot self.plot_canvas.plot_power_density_ticket(ticket, ticket["h_label"], ticket["v_label"], cumulated_total_power=0.0, energy_min=energy_min, energy_max=energy_max, energy_step=energy_step) self.plotted_ticket = ticket except Exception as e: QMessageBox.critical(self, "Error", str(e), QMessageBox.Ok) if self.IS_DEVELOP: raise e
def zoom(input, zoom, output=None, order=3, mode='constant', cval=0.0, prefilter=True): """ Zoom an array. The array is zoomed using spline interpolation of the requested order. Parameters ---------- input : ndarray The input array. zoom : float or sequence, optional The zoom factor along the axes. If a float, `zoom` is the same for each axis. If a sequence, `zoom` should contain one value for each axis. output : ndarray or dtype, optional The array in which to place the output, or the dtype of the returned array. order : int, optional The order of the spline interpolation, default is 3. The order has to be in the range 0-5. mode : str, optional Points outside the boundaries of the input are filled according to the given mode ('constant', 'nearest', 'reflect' or 'wrap'). Default is 'constant'. cval : scalar, optional Value used for points outside the boundaries of the input if ``mode='constant'``. Default is 0.0 prefilter : bool, optional The parameter prefilter determines if the input is pre-filtered with `spline_filter` before interpolation (necessary for spline interpolation of order > 1). If False, it is assumed that the input is already filtered. Default is True. Returns ------- return_value : ndarray or None The zoomed input. If `output` is given as a parameter, None is returned. """ if order < 0 or order > 5: raise RuntimeError('spline order not supported') input = numpy.asarray(input) if numpy.iscomplexobj(input): raise TypeError('Complex type not supported') if input.ndim < 1: raise RuntimeError('input and output rank must be > 0') mode = _extend_mode_to_code(mode) if prefilter and order > 1: filtered = spline_filter(input, order, output = numpy.float64) else: filtered = input zoom = _ni_support._normalize_sequence(zoom, input.ndim) output_shape = tuple([int(ii * jj) for ii, jj in zip(input.shape, zoom)]) zoom_div = numpy.array(output_shape, float) zoom = (numpy.array(input.shape)) / zoom_div # Zooming to non-finite values in unpredictable, so just choose # zoom factor 1 instead zoom[~numpy.isfinite(zoom)] = 1 output, return_value = _ni_support._get_output(output, input, shape=output_shape) zoom = numpy.asarray(zoom, dtype = numpy.float64) zoom = numpy.ascontiguousarray(zoom) _nd_image.zoom_shift(filtered, zoom, None, output, order, mode, cval) return return_value
def read (self,filenames): freqs = []; for ifreq,(filename_real,filename_imag) in enumerate(filenames): """Reads beam patterns from FITS files. If only one file is supplied, assumes a real-only beam. If two files are supplied, uses them for the real and imaginary parts. If 2N files are supplied, treats them as a frequency cube""" ff_re = pyfits.open(filename_real)[0]; # form up complex beam beam = numpy.zeros(ff_re.data.shape,complex); beam.real = ff_re.data; # add imaginary part if filename_imag: im_data = pyfits.open(filename_imag)[0].data; if im_data.shape != ff_re.data.shape: raise TypeError,"shape mismatch between FITS files %s and %s"%(filename_real,filename_imag); beam.imag = im_data; # change order of axis, since FITS has first axis last beam = beam.transpose(); # figure out axes axes = FITSAxes(ff_re.header); used_axes = [ axes.iaxis(x) for x in "L","M","FREQ" ]; if any([x<0 for x in used_axes]): raise TypeError,"FITS file %s missing L, M or FREQ axis"; laxis,maxis,freqaxis = used_axes; # check the other axes other_axes = sorted(set(range(axes.ndim())) - set(used_axes)); if any([axes.naxis(i)>1 for i in other_axes]): raise TypeError,"FITS file %s has other non-trivial axes besides L/M"%filename_real; # setup frequency grid freqgrid = axes.grid(freqaxis); if len(freqgrid) > 1: raise TypeError,"FITS file %s has >1 frequency points"; if freqs and freqgrid[0] < freqs[-1]: raise TypeError,"FITS file %s has lower frequency than previous file -- monotonically increasing frequencies are expected"; freqs.append(freqgrid[0]); # check if it matches previous image if not ifreq: baseshape = beam.shape; self._axes = axes; # setup 3D beam cube beamcube = numpy.zeros((axes.naxis(laxis),axes.naxis(maxis),len(filenames)),complex); # setup conversion functions self._lToPixel = Kittens.utils.curry(axes.toPixel,laxis); self._mToPixel = Kittens.utils.curry(axes.toPixel,maxis); for ax in laxis,maxis: dprint(1,"%s axis unit is %s"%(self._axes.type(ax),self._axes.unit(ax))); if not self._axes.unit(ax) or self._axes.unit(ax).upper() == "DEG": self._axes.setUnitScale(ax,DEG); else: if baseshape != beam.shape: raise TypeError,"FITS file %s has differing dimensions"%filename_real; beam = beam.transpose(used_axes+other_axes); beam = beam.reshape(beam.shape[:len(used_axes)]); beamcube[:,:,ifreq] = beam[:,:,0]; # done reading the beam cube dprint(1,"beam array has shape",beamcube.shape); dprint(2,"l grid is",self._axes.grid(laxis)); dprint(2,"m grid is",self._axes.grid(maxis)); dprint(2,"freq grid is",freqs); self._freqaxis = freqs; self._freq_interpolator = interpolate.interp1d(freqs,range(len(freqs)),'linear'); # prefilter beam for interpolator self._beam = beamcube; self._beam_ampl = numpy.abs(beamcube) if self.ampl_interpolation else None; if self._spline_order > 1: self._beam_real = interpolation.spline_filter(beamcube.real,order=self._spline_order); self._beam_imag = interpolation.spline_filter(beamcube.imag,order=self._spline_order); if self._beam_ampl: self._beam_ampl = interpolation.spline_filter(self._beam_ampl,order=self._spline_order); else: self._beam_real = beamcube.real; self._beam_imag = beamcube.imag;
def read (self,filename_real,filename_imag=None): """Reads beam patterns from FITS files. If only one file is supplied, assumes a real-only beam. If two files are supplied, uses them for the real and imaginary parts. If 2N files are supplied, treats them as a frequency cube""" ff_re = pyfits.open(filename_real)[0]; # form up complex beam beam = numpy.zeros(ff_re.data.shape,complex); beam.real = ff_re.data; beam_ampl = None # add imaginary part if filename_imag: im_data = pyfits.open(filename_imag)[0].data; if im_data.shape != ff_re.data.shape: raise TypeError,"shape mismatch between FITS files %s and %s"%(filename_real,filename_imag); beam.imag = im_data; if self.ampl_interpolation: beam_ampl = numpy.abs(beam) # change order of axis, since FITS has first axis last beam = beam.transpose(); if not beam_ampl is None: beam_ampl = beam_ampl.transpose() # figure out axes self._axes = axes = FITSAxes(ff_re.header); # find L/M axes laxis = axes.iaxis('L'); maxis = axes.iaxis('M'); if laxis<0 or maxis<0: raise TypeError,"FITS file %s missing L or M axis"%filename_real; # setup conversion functions self._lToPixel = Kittens.utils.curry(axes.toPixel,laxis); self._mToPixel = Kittens.utils.curry(axes.toPixel,maxis); # find frequency grid. self._freqToPixel will be None if no frequency axis freqaxis = axes.iaxis('FREQ'); if freqaxis >= 0 and axes.naxis(freqaxis) > 1: dprint(1,"FREQ axis has %d points"%axes.naxis(freqaxis)); self._freqgrid = axes.grid(freqaxis); self._freqToPixel = Kittens.utils.curry(axes.toPixel,freqaxis); used_axes = [laxis,maxis,freqaxis]; else: self._freqToPixel = None; used_axes = [laxis,maxis]; # used_axes is either (l,m,freq) or (l,m) # other_axes is all that remains, and they had better be all trivial other_axes = sorted(set(range(axes.ndim())) - set(used_axes)); if any([axes.naxis(i)>1 for i in other_axes]): raise TypeError,"FITS file %s has other non-trivial axes besides L/M"%filename_real; # setup units for ax in laxis,maxis: dprint(1,"%s axis unit is %s"%(axes.type(ax),axes.unit(ax))); if not axes.unit(ax) or axes.unit(ax).upper() == "DEG": axes.setUnitScale(ax,DEG); # transpose array into L,M order and reshape dprint(1,"beam array has shape",beam.shape); beam = beam.transpose(used_axes+other_axes); beam = beam.reshape(beam.shape[:len(used_axes)]); if not beam_ampl is None: beam_ampl = beam_ampl.transpose(used_axes+other_axes) beam_ampl = beam_ampl.reshape(beam_ampl.shape[:len(used_axes)]); dprint(1,"beam array has shape",beam.shape); dprint(2,"l grid is",axes.grid(laxis)); dprint(2,"m grid is",axes.grid(maxis)); if self._freqToPixel: dprint(2,"freq grid is",axes.grid(freqaxis)); # prefilter beam for interpolator self._beam = beam; if self._spline_order > 1: self._beam_real = interpolation.spline_filter(beam.real,order=self._spline_order); self._beam_imag = interpolation.spline_filter(beam.imag,order=self._spline_order); if not beam_ampl is None: self._beam_ampl = interpolation.spline_filter(beam_ampl,order=self._spline_order); else: self._beam_ampl = beam_ampl else: self._beam_real = beam.real; self._beam_imag = beam.imag; self._beam_ampl = beam_ampl
def draw (self,painter,xmap,ymap,rect): """Implements QwtPlotItem.draw(), to render the image on the given painter."""; xp1,xp2,xdp,xs1,xs2,xds = xinfo = xmap.p1(),xmap.p2(),xmap.pDist(),xmap.s1(),xmap.s2(),xmap.sDist(); yp1,yp2,ydp,ys1,ys2,yds = yinfo = ymap.p1(),ymap.p2(),ymap.pDist(),ymap.s1(),ymap.s2(),ymap.sDist(); dprint(5,"draw:",rect,xinfo,yinfo); self._current_rect = QRectF(QPointF(xs2,ys1),QSizeF(xds,yds)); self._current_rect_pix = QRect(QPoint(*self.lmToPix(xs1,ys1)),QPoint(*self.lmToPix(xs2,ys2))).intersected(self._bounding_rect_pix); dprint(5,"draw:",self._current_rect_pix); # put together tuple describing current mapping mapping = xinfo,yinfo; # if mapping has changed w.r.t. cache (i.e. zoom has changed), discard all cached QImages if mapping != self._cache_mapping: dprint(2,"does not match cached mapping, cache is:",self._cache_mapping); dprint(2,"and we have:",mapping); self.clearDisplayCache(); self._cache_mapping = mapping; t0 = time.time(); # check cached QImage for current image key. qimg = self._cache_qimage.get(self._image_key); if qimg: dprint(5,"QImage found in cache, reusing"); # else regenerate image else: # check for cached intensity-mapped data if self._cache_imap is not None: dprint(5,"intensity-mapped data found in cache, reusing"); else: if self._cache_interp is not None: dprint(5,"interpolated data found in cache, reusing"); else: image = self._image.transpose() if self._data_fortran_order else self._image; spline_order = 2; xsamp = abs(xmap.sDist()/xmap.pDist())/abs(self._dl); ysamp = abs(ymap.sDist()/ymap.pDist())/abs(self._dm); if max(xsamp,ysamp) < .33 or min(xsamp,ysamp) > 2: spline_order = 1; dprint(2,"regenerating drawing cache, sampling factors are",xsamp,ysamp,"spline order is",spline_order); self._cache_imap = None; if self._prefilter is None and spline_order>1: self._prefilter = interpolation.spline_filter(image,order=spline_order); dprint(2,"spline prefiltering took",time.time()-t0,"secs"); t0 = time.time(); # make arrays of plot coordinates # xp[0],yp[0] corresponds to pixel 0,0, where 0,0 is the upper-left corner of the plot # the maps are in a funny order (w.r.t. meaning of p1/p2/s1/s2), so the indices here are determined empirically # We also adjust by half-pixel, to get the world coordinate of the pixel _center_ xp = xmap.s1() - (xmap.sDist()/xmap.pDist())*(0.5+numpy.arange(int(xmap.pDist()))); yp = ymap.s2() - (ymap.sDist()/ymap.pDist())*(0.5+numpy.arange(int(ymap.pDist()))); # now convert plot coordinates into fractional image pixel coordinates xi = self._x0 + (xp - self._l0)/self._dl; yi = self._y0 + (yp - self._m0)/self._dm; # interpolate image data ### # old code for nearest-neighbour interpolation ### # superceded by interpolation below (we simply round pixel coordinates to go to NN when oversampling) ### xi = xi.round().astype(int); ### oob_x = (xi<0)|(xi>=self._nx); ### xi[oob_x] = 0; ### yi = yi.round().astype(int); ### oob_y = (yi<0)|(yi>=self._ny); ### yi[oob_y] = 0; ### idx = (xi[:,numpy.newaxis]*self._ny + yi[numpy.newaxis,:]).ravel(); ### interp_image = self._image.ravel()[idx].reshape((len(xi),len(yi))); ### interp_image[oob_x,:] = 0; ### interp_image[:,oob_y] = 0; ### self._qimage_cache = self.colormap.colorize(interp_image,self._img_range); ### self._qimage_cache_attrs = (rect,xinfo,yinfo); # if either axis is oversampled by a factor of 3 or more, switch to nearest-neighbour interpolation by rounding pixel values if xsamp < .33: xi = xi.round(); if ysamp < .33: yi = yi.round(); # make [2,nx,ny] array of interpolation coordinates xy = numpy.zeros((2,len(xi),len(yi))); xy[0,:,:] = xi[:,numpy.newaxis]; xy[1,:,:] = yi[numpy.newaxis,:]; # interpolate. Use NAN for out of range pixels... # for fortran order, tranpose axes for extra speed (flip XY around then) if self._data_fortran_order: xy = xy[-1::-1,...]; if spline_order > 1: interp_image = interpolation.map_coordinates(self._prefilter,xy,order=spline_order,cval=numpy.nan,prefilter=False); else: interp_image = interpolation.map_coordinates(image,xy,order=spline_order,cval=numpy.nan); # ...and put a mask on them (Colormap.colorize() will make these transparent). mask = ~numpy.isfinite(interp_image); self._cache_interp = numpy.ma.masked_array(interp_image,mask); dprint(2,"interpolation took",time.time()-t0,"secs"); t0 = time.time(); # ok, we have interpolated data in _cache_interp self._cache_imap = self.imap.remap(self._cache_interp); dprint(2,"intensity mapping took",time.time()-t0,"secs"); t0 = time.time(); # ok, we have intensity-mapped data in _cache_imap qimg = self.colormap.colorize(self._cache_imap); dprint(2,"colorizing took",time.time()-t0,"secs"); t0 = time.time(); # cache the qimage self._cache_qimage[self._image_key] = qimg.copy(); # now draw the image t0 = time.time(); painter.drawImage(xp1,yp2,qimg); dprint(2,"drawing took",time.time()-t0,"secs");