def rangeChange(self, pw, ranges):
        """Adjusts the stimulus signal to keep it at the top of a plot,
        after any ajustment to the axes ranges takes place.

        This is a slot for the undocumented pyqtgraph signal sigRangeChanged.
        From what I can tell the arguments are:

        :param pw: reference to the emitting object (plot widget in my case)
        :type pw: object
        :param ranges: I am only interested when this turns out to be a nested list of axis bounds
        :type ranges: object
        """
        if hasattr(ranges, '__iter__'):
            # adjust the stim signal so that it falls in the correct range
            yrange_size = ranges[1][1] - ranges[1][0]
            stim_x, stim_y = self.stimPlot.getData()
            if stim_y is not None:
                stim_height = yrange_size*STIM_HEIGHT
                # take it to 0
                stim_y = stim_y - np.amin(stim_y)
                # normalize
                if np.amax(stim_y) != 0:
                    stim_y = stim_y/np.amax(stim_y)
                # scale for new size
                stim_y = stim_y*stim_height
                # raise to right place in plot
                stim_y = stim_y + (ranges[1][1] - (stim_height*1.1 + (stim_height*0.2)))
                self.stimPlot.setData(stim_x, stim_y)
            # rmax = self.rasterTop*yrange_size + ranges[1][0]
            # rmin = self.rasterBottom*yrange_size + ranges[1][0]
            self.updateRasterBounds()
Adjusts the stimulus signal to keep it at the top of a plot,
        after any ajustment to the axes ranges takes place.

        This is a slot for the undocumented pyqtgraph signal sigRangeChanged.
        From what I can tell the arguments are:

        :param pw: reference to the emitting object (plot widget in my case)
        :type pw: object
        :param ranges: I am only interested when this turns out to be a nested list of axis bounds
        :type ranges: object