class SingleSlicer (AxisSlicer): ''' Represents an (N-1)-dim slice of an N-dimensional wave. ''' # need to reimplement some methods, but we wish to retain # their functionality: def __init__(self, parent=None, axis=0, master=None, tparent=None, viewer=None): AxisSlicer.__init__(self, parent, axis, master, tparent, viewer) # initialize GUI self.val_from = ValueWidget (None, "From: ", QtGui.QSpinBox(), 0, 99, 1, 0, self.triggerSlicing) self.val_delta = ValueWidget (None, "Delta: ", QtGui.QSpinBox(), 1, 99, 1, 1, self.triggerSlicing) self.slice_label = QtGui.QLabel ("<info>") # attach toolbar to parent, by default (or to us, if no parent) for w in [ self.val_from, self.val_delta, self.slice_label ]: self.tools.addWidget(w) def _prepareMaster(self, wave): self.Axis_prepareMaster (wave) if self.master_wave is None: return self.val_from.spin.setRange (0, self.master_wave.shape[self.slice_axis]) self.val_delta.spin.setRange (1, self.master_wave.shape[self.slice_axis]) @QtCore.pyqtSlot() def slice (self, wave=None): # everything we do depends strongly on the selected slice_axis, # so if that one changes, we can aswell trigger a _prepareMaster() # session. if wave is not None: self._prepareMaster(wave) if self.master_wave is None: return xfrom = self.val_from.value() delta = self.val_delta.value() xto = xfrom + delta log.debug ("Slicing axis %d, from %d to %d" % (self.slice_axis, xfrom, xto)) # we want to slice along an arbitrary axis, here's the strategy: # . swap the axis 0 with slice_axis # . slice along axis 0 # . swap back (slice_axis with 0) # . sum along slice_axis (we want to integrate out the # dimension we slice along...) self.slice_wave = self.master_wave.swapaxes(0,self.slice_axis)[xfrom:xto].swapaxes(self.slice_axis,0).sum(self.slice_axis) log.debug ("%d axes: %s" % (self.slice_wave.ndim, [str(a) for a in self.slice_wave.dim])) self.slice_label.setText(" ax%d: %5.2f : %5.2f" % (self.slice_axis, self.master_wave.dim[self.slice_axis].i2x (xfrom), self.master_wave.dim[self.slice_axis].i2x (xto))) self.sliced.emit ([self.slice_wave])
class AxisSlicer(BaseSlicer): ''' Base class for an axis-based slicer. This one typically slices perpendicular to a specified wave axis. (Opposed to a free slicer, where the the slicing takes place not perpendicular to a particular axis, but along a freely specified line.) ''' def __init__ (self, parent, axis=0, master=None, tparent=None, viewer=None): ''' Parameters are those of BaseSlicer and the following: axis: Axis perpendicular to which to slice ''' BaseSlicer.__init__(self, parent, master, tparent, viewer) self.slice_axis = axis # axis perpendicular to which we will slice self.val_axis = ValueWidget (None, "Axis: ", QtGui.QSpinBox(), 0, 99, 1, axis, self._prepareAxis) self.tools.addWidget(self.val_axis) @QtCore.pyqtSlot (int) def _prepareAxis (self, axis): ''' Make sure val_axis and slice_axis are in sync. ''' self.slice_axis = self.val_axis.value() self._prepareMaster(self.master_wave) # adjust spinbox limits self.slice(self.master_wave) Axis_prepareAxis = _prepareAxis def _prepareMaster(self, wave): self.Base_prepareMaster(wave) if self.master_wave is None: return self.val_axis.spin.setRange (0, self.master_wave.ndim-1) Axis_prepareMaster = _prepareMaster
class CompressingSlicer (AxisSlicer): ''' This class generates a compressed version of the specified wave. It is useful for creating waterfall diagrams along specified axes. axis: The slice axis step: Distance between display slices norm: Normalize: if specified, the wave will be normalized to the maximum intensity point prior to intensity manipulation. intg: Specifies whether slices between step N and N+step should be added up. ''' def __init__ (self, parent=None, axis=0, master=None, tparent=None, viewer=None): AxisSlicer.__init__(self, parent, axis, master, tparent, viewer) self.old_intg = 1 # need these to link intg/step self.old_step = 1 self.xoffset = 0 # property that will be needed at plot time self.yoffset = 0 # Initialize GUI. self.val_step = ValueWidget (None, "Step: ", QtGui.QSpinBox(), 1, 99, 1, 1, self.triggerSlicing) self.chk_norm = QtGui.QCheckBox ("Norm") self.chk_intg = QtGui.QCheckBox ("Intg") self.chk_norm.stateChanged.connect (self.triggerSlicing) self.chk_intg.stateChanged.connect (self.triggerSlicing) # attach toolbar to parent, by default (or to us, if no parent) for w in [ self.val_step, self.chk_norm, self.chk_intg ]: self.tools.addWidget(w) def _prepareMaster(self, wave): self.Axis_prepareMaster (wave) if self.master_wave is None: return self.val_step.spin.setRange (1, self.master_wave.shape[self.slice_axis]) @QtCore.pyqtSlot() def slice (self, wave=None): ''' Creates a slice-wise compressed version of the input wave. (I.e. one with a reduced size in the specified dimension, that has beend periodically sliced and integrated.) ''' if wave is not None: self._prepareMaster(wave) if self.master_wave is None: return ax = self.slice_axis self.old_step = step = self.val_step.value() if self.chk_intg.isChecked(): intg = step else: intg = 1 self.slice_wave = ncomp(self.master_wave, ax, step, intg, self.chk_norm.isChecked()) self.sliced.emit ([self.slice_wave])