Пример #1
0
 def __init__(self, data, time_axis, freq_axis, start, end,
     t_init=None, t_delt=None, t_label="Time", f_label="Frequency",
     content="", instruments=None):
     if t_delt is None:
         t_delt = min_delt(freq_axis)
     
     super(LinearTimeSpectrogram, self).__init__(
         data, time_axis, freq_axis, start, end, t_init, t_label, f_label,
         content, instruments
     )
     self.t_delt = t_delt
Пример #2
0
    def __init__(self, arr, delt=None):
        self.arr = arr
        if delt is None:
            # Nyquist–Shannon sampling theorem
            delt = min_delt(arr.freq_axis) / 2.

        self.delt = delt

        midpoints = (self.arr.freq_axis[:-1] + self.arr.freq_axis[1:]) / 2
        self.midpoints = np.concatenate([midpoints, arr.freq_axis[-1:]])

        self.max_mp_delt = np.min(delta(self.midpoints))

        self.freq_axis = np.arange(self.arr.freq_axis[0],
                                   self.arr.freq_axis[-1], -self.delt)
        self.time_axis = self.arr.time_axis

        self.shape = (len(self), arr.shape[1])
Пример #3
0
    def __init__(self, arr, delt=None):
        self.arr = arr
        if delt is None:
            # Nyquist–Shannon sampling theorem
            delt = min_delt(arr.freq_axis) / 2.
        
        self.delt = delt
        
        midpoints = (self.arr.freq_axis[:-1] + self.arr.freq_axis[1:]) / 2
        self.midpoints = np.concatenate([midpoints, arr.freq_axis[-1:]])
        
        self.max_mp_delt = np.min(delta(self.midpoints))
        
        self.freq_axis = np.arange(
            self.arr.freq_axis[0], self.arr.freq_axis[-1], -self.delt
        )
        self.time_axis = self.arr.time_axis

        self.shape = (len(self), arr.shape[1])
Пример #4
0
    def __init__(self,
                 data,
                 time_axis,
                 freq_axis,
                 start,
                 end,
                 t_init=None,
                 t_delt=None,
                 t_label="Time",
                 f_label="Frequency",
                 content="",
                 instruments=None):
        if t_delt is None:
            t_delt = min_delt(freq_axis)

        super(LinearTimeSpectrogram,
              self).__init__(data, time_axis, freq_axis, start, end, t_init,
                             t_label, f_label, content, instruments)
        self.t_delt = t_delt
Пример #5
0
    def linearize_freqs(self, delta_freq=None):
        """ Rebin frequencies so that the frequency axis is linear.
        
        Parameters
        ----------
        delta_freq : float
            Difference between consecutive values on the new frequency axis.
            Defaults to half of smallest delta in current frequency axis.
            Compare Nyquist-Shannon sampling theorem.
        """
        if delta_freq is None:
            # Nyquist–Shannon sampling theorem
            delta_freq = min_delt(self.freq_axis) / 2.
        nsize = (self.freq_axis.max() - self.freq_axis.min()) / delta_freq + 1
        new = np.zeros((nsize, self.shape[1]), dtype=self.dtype)

        freqs = self.freq_axis - self.freq_axis.max()
        freqs = freqs / delta_freq

        midpoints = np.round((freqs[:-1] + freqs[1:]) / 2)
        fillto = np.concatenate(
            [midpoints - 1, np.round([freqs[-1]]) - 1]
        )
        fillfrom = np.concatenate(
            [np.round([freqs[0]]), midpoints - 1]
        )
        
        fillto = np.abs(fillto)
        fillfrom = np.abs(fillfrom)

        for row, from_, to_ in izip(self, fillfrom, fillto):
            new[from_: to_] = row

        vrs = self._get_params()
        vrs.update({
            'freq_axis': np.linspace(
                self.freq_axis.max(), self.freq_axis.min(), nsize
            )
        })

        return self.__class__(new, **vrs)
Пример #6
0
    def linearize_freqs(self, delta_freq=None):
        """ Rebin frequencies so that the frequency axis is linear.
        
        Parameters
        ----------
        delta_freq : float
            Difference between consecutive values on the new frequency axis.
            Defaults to half of smallest delta in current frequency axis.
            Compare Nyquist-Shannon sampling theorem.
        """
        if delta_freq is None:
            # Nyquist–Shannon sampling theorem
            delta_freq = min_delt(self.freq_axis) / 2.
        nsize = (self.freq_axis.max() - self.freq_axis.min()) / delta_freq + 1
        new = np.zeros((nsize, self.shape[1]), dtype=self.dtype)

        freqs = self.freq_axis - self.freq_axis.max()
        freqs = freqs / delta_freq

        midpoints = np.round((freqs[:-1] + freqs[1:]) / 2)
        fillto = np.concatenate([midpoints - 1, np.round([freqs[-1]]) - 1])
        fillfrom = np.concatenate([np.round([freqs[0]]), midpoints - 1])

        fillto = np.abs(fillto)
        fillfrom = np.abs(fillfrom)

        for row, from_, to_ in izip(self, fillfrom, fillto):
            new[from_:to_] = row

        vrs = self._get_params()
        vrs.update({
            'freq_axis':
            np.linspace(self.freq_axis.max(), self.freq_axis.min(), nsize)
        })

        return self.__class__(new, **vrs)
Пример #7
0
    def plot(self, figure=None, overlays=[], colorbar=True, min_=None, max_=None,
             linear=True, showz=True, yres=DEFAULT_YRES,
             max_dist=None, **matplotlib_args):
        """
        Plot spectrogram onto figure.
        
        Parameters
        ----------
        figure : matplotlib.figure.Figure
            Figure to plot the spectrogram on. If None, new Figure is created.
        overlays : list
            List of overlays (functions that receive figure and axes and return
            new ones) to be applied after drawing.
        colorbar : bool
            Flag that determines whether or not to draw a colorbar. If existing
            figure is passed, it is attempted to overdraw old colorbar.
        min_ : float
            Clip intensities lower than min_ before drawing.
        max_ : float
            Clip intensities higher than max_ before drawing.
        linear :  bool
            If set to True, "stretch" image to make frequency axis linear.
        showz : bool
            If set to True, the value of the pixel that is hovered with the
            mouse is shown in the bottom right corner.
        yres : int or None
            To be used in combination with linear=True. If None, sample the
            image with half the minimum frequency delta. Else, sample the
            image to be at most yres pixels in vertical dimension. Defaults
            to 1080 because that's a common screen size.
        max_dist : float or None
            If not None, mask elements that are further than max_dist away
            from actual data points (ie, frequencies that actually have data 
            from the receiver and are not just nearest-neighbour interpolated).
        """
        # [] as default argument is okay here because it is only read.
        # pylint: disable=W0102,R0914
        if linear:
            delt = yres
            if delt is not None:
                delt = max(
                    (self.freq_axis[0] - self.freq_axis[-1]) / (yres - 1),
                    min_delt(self.freq_axis) / 2.
                )
                delt = float(delt)
            
            data = _LinearView(self.clip_values(min_, max_), delt)
            freqs = np.arange(
                self.freq_axis[0], self.freq_axis[-1], -data.delt
            )
        else:
            data = np.array(self.clip_values(min_, max_))
            freqs = self.freq_axis
        newfigure = figure is None
        if figure is None:
            figure = plt.figure(frameon=True, FigureClass=SpectroFigure)
            axes = figure.add_subplot(111)
        else:
            if figure.axes:
                axes = figure.axes[0]
            else:
                axes = figure.add_subplot(111)
        
        params = {
            'origin': 'lower',
            'aspect': 'auto',
        }
        params.update(matplotlib_args)
        if linear and max_dist is not None:
            toplot = ma.masked_array(data, mask=data.make_mask(max_dist))
        else:
            toplot = data
        im = axes.imshow(toplot, **params)
        
        xa = axes.get_xaxis()
        ya = axes.get_yaxis()

        xa.set_major_formatter(
            FuncFormatter(self.time_formatter)
        )
        
        if linear:
            # Start with a number that is divisible by 5.
            init = (self.freq_axis[0] % 5) / data.delt
            nticks = 15.
            # Calculate MHz difference between major ticks.
            dist = (self.freq_axis[0] - self.freq_axis[-1]) / nticks
            # Round to next multiple of 10, at least ten.
            dist = max(round(dist, -1), 10)
            # One pixel in image space is data.delt MHz, thus we can convert
            # our distance between the major ticks into image space by dividing
            # it by data.delt.
            
            ya.set_major_locator(
                IndexLocator(
                    dist / data.delt, init
                )
            )
            ya.set_minor_locator(
                IndexLocator(
                    dist / data.delt / 10, init
                )
            )
            def freq_fmt(x, pos):
                # This is necessary because matplotlib somehow tries to get
                # the mid-point of the row, which we do not need here.
                x = x + 0.5
                return self.format_freq(self.freq_axis[0] - x * data.delt)
        else:
            freq_fmt = _list_formatter(freqs, self.format_freq)
            ya.set_major_locator(MaxNLocator(integer=True, steps=[1, 5, 10]))
        
        ya.set_major_formatter(
            FuncFormatter(freq_fmt)
        )
        
        axes.set_xlabel(self.t_label)
        axes.set_ylabel(self.f_label)
        # figure.suptitle(self.content)
        
        figure.suptitle(
            ' '.join([
                get_day(self.start).strftime("%d %b %Y"),
                'Radio flux density',
                '(' + ', '.join(self.instruments) + ')',
            ])
        )
        
        for tl in xa.get_ticklabels():
            tl.set_fontsize(10)
            tl.set_rotation(30)
        figure.add_axes(axes)
        figure.subplots_adjust(bottom=0.2)
        figure.subplots_adjust(left=0.2)
        
        if showz:
            figure.gca().format_coord = self._mk_format_coord(
                data, figure.gca().format_coord)
        
        if colorbar:
            if newfigure:
                figure.colorbar(im).set_label("Intensity")
            else:
                if len(figure.axes) > 1:
                    Colorbar(figure.axes[1], im).set_label("Intensity")

        for overlay in overlays:
            figure, axes = overlay(figure, axes)
            
        for ax in figure.axes:
            ax.autoscale()
        figure._init(self, freqs)
        return figure
Пример #8
0
    def plot(self,
             figure=None,
             overlays=[],
             colorbar=True,
             min_=None,
             max_=None,
             linear=True,
             showz=True,
             yres=DEFAULT_YRES,
             max_dist=None,
             **matplotlib_args):
        """
        Plot spectrogram onto figure.
        
        Parameters
        ----------
        figure : matplotlib.figure.Figure
            Figure to plot the spectrogram on. If None, new Figure is created.
        overlays : list
            List of overlays (functions that receive figure and axes and return
            new ones) to be applied after drawing.
        colorbar : bool
            Flag that determines whether or not to draw a colorbar. If existing
            figure is passed, it is attempted to overdraw old colorbar.
        min_ : float
            Clip intensities lower than min_ before drawing.
        max_ : float
            Clip intensities higher than max_ before drawing.
        linear :  bool
            If set to True, "stretch" image to make frequency axis linear.
        showz : bool
            If set to True, the value of the pixel that is hovered with the
            mouse is shown in the bottom right corner.
        yres : int or None
            To be used in combination with linear=True. If None, sample the
            image with half the minimum frequency delta. Else, sample the
            image to be at most yres pixels in vertical dimension. Defaults
            to 1080 because that's a common screen size.
        max_dist : float or None
            If not None, mask elements that are further than max_dist away
            from actual data points (ie, frequencies that actually have data 
            from the receiver and are not just nearest-neighbour interpolated).
        """
        # [] as default argument is okay here because it is only read.
        # pylint: disable=W0102,R0914
        if linear:
            delt = yres
            if delt is not None:
                delt = max(
                    (self.freq_axis[0] - self.freq_axis[-1]) / (yres - 1),
                    min_delt(self.freq_axis) / 2.)
                delt = float(delt)

            data = _LinearView(self.clip_values(min_, max_), delt)
            freqs = np.arange(self.freq_axis[0], self.freq_axis[-1],
                              -data.delt)
        else:
            data = np.array(self.clip_values(min_, max_))
            freqs = self.freq_axis
        newfigure = figure is None
        if figure is None:
            figure = plt.figure(frameon=True, FigureClass=SpectroFigure)
            axes = figure.add_subplot(111)
        else:
            if figure.axes:
                axes = figure.axes[0]
            else:
                axes = figure.add_subplot(111)

        params = {
            'origin': 'lower',
            'aspect': 'auto',
        }
        params.update(matplotlib_args)
        if linear and max_dist is not None:
            toplot = ma.masked_array(data, mask=data.make_mask(max_dist))
        else:
            toplot = data
        im = axes.imshow(toplot, **params)

        xa = axes.get_xaxis()
        ya = axes.get_yaxis()

        xa.set_major_formatter(FuncFormatter(self.time_formatter))

        if linear:
            # Start with a number that is divisible by 5.
            init = (self.freq_axis[0] % 5) / data.delt
            nticks = 15.
            # Calculate MHz difference between major ticks.
            dist = (self.freq_axis[0] - self.freq_axis[-1]) / nticks
            # Round to next multiple of 10, at least ten.
            dist = max(round(dist, -1), 10)
            # One pixel in image space is data.delt MHz, thus we can convert
            # our distance between the major ticks into image space by dividing
            # it by data.delt.

            ya.set_major_locator(IndexLocator(dist / data.delt, init))
            ya.set_minor_locator(IndexLocator(dist / data.delt / 10, init))

            def freq_fmt(x, pos):
                # This is necessary because matplotlib somehow tries to get
                # the mid-point of the row, which we do not need here.
                x = x + 0.5
                return self.format_freq(self.freq_axis[0] - x * data.delt)
        else:
            freq_fmt = _list_formatter(freqs, self.format_freq)
            ya.set_major_locator(MaxNLocator(integer=True, steps=[1, 5, 10]))

        ya.set_major_formatter(FuncFormatter(freq_fmt))

        axes.set_xlabel(self.t_label)
        axes.set_ylabel(self.f_label)
        # figure.suptitle(self.content)

        figure.suptitle(' '.join([
            get_day(self.start).strftime("%d %b %Y"),
            'Radio flux density',
            '(' + ', '.join(self.instruments) + ')',
        ]))

        for tl in xa.get_ticklabels():
            tl.set_fontsize(10)
            tl.set_rotation(30)
        figure.add_axes(axes)
        figure.subplots_adjust(bottom=0.2)
        figure.subplots_adjust(left=0.2)

        if showz:
            figure.gca().format_coord = self._mk_format_coord(
                data,
                figure.gca().format_coord)

        if colorbar:
            if newfigure:
                figure.colorbar(im).set_label("Intensity")
            else:
                if len(figure.axes) > 1:
                    Colorbar(figure.axes[1], im).set_label("Intensity")

        for overlay in overlays:
            figure, axes = overlay(figure, axes)

        for ax in figure.axes:
            ax.autoscale()
        figure._init(self, freqs)
        return figure