Example #1
0
    def _annotation_plot(self, axes, annotation, annotation_facet,
                         annotation_value, annotation_color, **kwargs):

        km = annotation[0]
        peaks = annotation[1]
        cluster_peak = annotation[2]
        density = annotation[3]

        xbins = axes.fp_xbins
        ybins = axes.fp_ybins
        kwargs = axes.fp_keywords

        # get rid of some kwargs that confuse pcolormesh
        kwargs.pop('annotations', None)
        kwargs.pop('annotation_facet', None)
        kwargs.pop('plot_name', None)

        xscale = kwargs['scale'][self.xchannel]
        yscale = kwargs['scale'][self.ychannel]

        kwargs.pop('scale')
        kwargs.pop('lim')

        smoothed = kwargs.pop('smoothed', False)
        smoothed_sigma = kwargs.pop('smoothed_sigma', 1)

        h = density(util.cartesian([xscale(xbins), yscale(ybins)]))
        h = np.reshape(h, (len(xbins), len(ybins)))
        if smoothed:
            h = scipy.ndimage.filters.gaussian_filter(h, sigma=smoothed_sigma)
        axes.pcolormesh(xbins, ybins, h.T, **kwargs)

        ix = self.op.channels.index(self.xchannel)
        iy = self.op.channels.index(self.ychannel)

        for k in range(len(km.cluster_centers_)):

            x = self.op._scale[self.xchannel].inverse(
                km.cluster_centers_[k][ix])
            y = self.op._scale[self.ychannel].inverse(
                km.cluster_centers_[k][iy])

            plt.plot(x, y, '*', color='blue')

            peak_idx = cluster_peak[k]
            peak = peaks[peak_idx]
            peak_x = xscale.inverse(peak[0])
            peak_y = yscale.inverse(peak[1])

            plt.plot([x, peak_x], [y, peak_y])

        for peak in peaks:
            x = self.op._scale[self.ychannel].inverse(peak[0])
            y = self.op._scale[self.xchannel].inverse(peak[1])
            plt.plot(x, y, 'o', color="magenta")
Example #2
0
    def _annotation_plot(self, axes, xlim, ylim, xscale, yscale, annotation,
                         annotation_facet, annotation_value, annotation_color):

        km = annotation[0]
        peaks = annotation[1]
        cluster_peak = annotation[2]
        density = annotation[3]

        xbins = axes.fp_xbins
        ybins = axes.fp_ybins
        kwargs = axes.fp_keywords

        # get rid of some kwargs that confuse pcolormesh
        kwargs.pop('annotations')
        kwargs.pop('annotation_facet')

        h = density(util.cartesian([xscale(xbins), yscale(ybins)]))
        h = np.reshape(h, (len(xbins), len(ybins)))
        axes.pcolormesh(xbins, ybins, h.T, **kwargs)

        ix = self.op.channels.index(self.xchannel)
        iy = self.op.channels.index(self.ychannel)

        for k in range(len(km.cluster_centers_)):

            x = self.op._scale[self.xchannel].inverse(
                km.cluster_centers_[k][ix])
            y = self.op._scale[self.ychannel].inverse(
                km.cluster_centers_[k][iy])

            plt.plot(x, y, '*', color='blue')

            peak_idx = cluster_peak[k]
            peak = peaks[peak_idx]
            peak_x = xscale.inverse(peak[0])
            peak_y = yscale.inverse(peak[1])

            plt.plot([x, peak_x], [y, peak_y])

            for peak in peaks:
                x = self.op._scale[self.ychannel].inverse(peak[0])
                y = self.op._scale[self.xchannel].inverse(peak[1])
                plt.plot(x, y, 'o', color="magenta")
Example #3
0
    def estimate(self, experiment, subset=None):
        """
        Estimate the bleedthrough from the single-channel controls in `controls`
        """
        if not experiment:
            raise util.CytoflowOpError("No experiment specified")

        if self.num_knots < 3:
            raise util.CytoflowOpError(
                "Need to allow at least 3 knots in the spline")

        self._channels = self.controls.keys()

        if len(self._channels) < 2:
            raise util.CytoflowOpError(
                "Need at least two channels to correct bleedthrough.")

        self._splines = {}
        mesh_axes = []

        for channel in self._channels:
            self._splines[channel] = {}

            # make a little Experiment
            check_tube(self.controls[channel], experiment)
            tube_exp = ImportOp(tubes=[Tube(
                file=self.controls[channel])]).apply()

            # apply previous operations
            for op in experiment.history:
                tube_exp = op.apply(tube_exp)

            # subset it
            if subset:
                try:
                    tube_data = tube_exp.query(subset).copy()
                except:
                    raise util.CytoflowOpError(
                        "Subset string '{0}' isn't valid".format(self.subset))

                if len(tube_data.index) == 0:
                    raise util.CytoflowOpError(
                        "Subset string '{0}' returned no events".format(
                            self.subset))
            else:
                tube_data = tube_exp.data.copy()

            # polyfit requires sorted data
            tube_data.sort_values(by=channel, inplace=True)

            channel_min = tube_data[channel].min()
            channel_max = tube_data[channel].max()

            # we're going to set the knots and splines evenly across the hlog-
            # transformed data, so as to capture both the "linear" aspect
            # of near-0 and negative values, and the "log" aspect of large
            # values

            # parameterize the hlog transform
            r = experiment.metadata[channel]['range']  # instrument range
            d = np.log10(r)  # maximum display scale, in decades

            # the transition point from linear --> log scale
            # use half of the log-transformed scale as "linear".
            b = 2**(np.log2(r) / 2)

            # the splines' knots
            knot_min = channel_min
            knot_max = channel_max

            hlog_knot_min, hlog_knot_max = \
                hlog((knot_min, knot_max), b = b, r = r, d = d)
            hlog_knots = np.linspace(hlog_knot_min, hlog_knot_max,
                                     self.num_knots)
            knots = hlog_inv(hlog_knots, b=b, r=r, d=d)

            # only keep the interior knots
            knots = knots[1:-1]

            # the interpolators' mesh
            if 'af_median' in experiment.metadata[channel] and \
               'af_stdev' in experiment.metadata[channel]:
                mesh_min = experiment.metadata[channel]['af_median'] - \
                           3 * experiment.metadata[channel]['af_stdev']
            else:
                mesh_min = -0.01 * r  # TODO - does this even work?

            mesh_max = r

            hlog_mesh_min, hlog_mesh_max = \
                hlog((mesh_min, mesh_max), b = b, r = r, d = d)
            hlog_mesh_axis = \
                np.linspace(hlog_mesh_min, hlog_mesh_max, self.mesh_size)

            mesh_axis = hlog_inv(hlog_mesh_axis, b=b, r=r, d=d)
            mesh_axes.append(mesh_axis)

            for to_channel in self._channels:
                from_channel = channel
                if from_channel == to_channel:
                    continue

                self._splines[from_channel][to_channel] = \
                    scipy.interpolate.LSQUnivariateSpline(tube_data[from_channel].values,
                                                          tube_data[to_channel].values,
                                                          t = knots,
                                                          k = 1)

        mesh = pandas.DataFrame(util.cartesian(mesh_axes),
                                columns=[x for x in self._channels])

        mesh_corrected = mesh.apply(_correct_bleedthrough,
                                    axis=1,
                                    args=([[x for x in self._channels],
                                           self._splines]))

        for channel in self._channels:
            chan_values = np.reshape(mesh_corrected[channel],
                                     [len(x) for x in mesh_axes])
            self._interpolators[channel] = \
                scipy.interpolate.RegularGridInterpolator(points = mesh_axes,
                                                          values = chan_values,
                                                          bounds_error = False,
                                                          fill_value = 0.0)
    def estimate(self, experiment, subset = None): 
        """
        Estimate the bleedthrough from the single-channel controls in `controls`
        """
        if not experiment:
            raise util.CytoflowOpError("No experiment specified")
        
        if self.num_knots < 3:
            raise util.CytoflowOpError("Need to allow at least 3 knots in the spline")
        
        self._channels = self.controls.keys()

        if len(self._channels) < 2:
            raise util.CytoflowOpError("Need at least two channels to correct bleedthrough.")

        self._splines = {}
        mesh_axes = []

        for channel in self._channels:
            self._splines[channel] = {}
            
            # make a little Experiment
            check_tube(self.controls[channel], experiment)
            tube_exp = ImportOp(tubes = [Tube(file = self.controls[channel])],
                                name_metadata = experiment.metadata['name_metadata']).apply()
            
            # apply previous operations
            for op in experiment.history:
                tube_exp = op.apply(tube_exp)
                
            # subset it
            if subset:
                try:
                    tube_exp = tube_exp.query(subset)
                except:
                    raise util.CytoflowOpError("Subset string '{0}' isn't valid"
                                          .format(self.subset))
                                
                if len(tube_exp.data) == 0:
                    raise util.CytoflowOpError("Subset string '{0}' returned no events"
                                          .format(self.subset))
            
            tube_data = tube_exp.data
                
            # polyfit requires sorted data
            tube_data.sort_values(by = channel, inplace = True)
            
            channel_min = tube_data[channel].min()
            channel_max = tube_data[channel].max()
            
            # we're going to set the knots and splines evenly across the hlog-
            # transformed data, so as to capture both the "linear" aspect
            # of near-0 and negative values, and the "log" aspect of large
            # values

            # parameterize the hlog transform
            r = experiment.metadata[channel]['range']  # instrument range
            d = np.log10(r)  # maximum display scale, in decades
            
            # the transition point from linear --> log scale
            # use half of the log-transformed scale as "linear".
            b = 2 ** (np.log2(r) / 2)
            
            # the splines' knots
            knot_min = channel_min
            knot_max = channel_max
            
            hlog_knot_min, hlog_knot_max = \
                hlog((knot_min, knot_max), b = b, r = r, d = d)
            hlog_knots = np.linspace(hlog_knot_min, hlog_knot_max, self.num_knots)
            knots = hlog_inv(hlog_knots, b = b, r = r, d = d)
            
            # only keep the interior knots
            knots = knots[1:-1] 
            
            # the interpolators' mesh       
            if 'af_median' in experiment.metadata[channel] and \
               'af_stdev' in experiment.metadata[channel]:     
                mesh_min = experiment.metadata[channel]['af_median'] - \
                           3 * experiment.metadata[channel]['af_stdev']
            else:
                mesh_min = -0.01 * r  # TODO - does this even work?
                
            mesh_max = r
                
            hlog_mesh_min, hlog_mesh_max = \
                hlog((mesh_min, mesh_max), b = b, r = r, d = d)
            hlog_mesh_axis = \
                np.linspace(hlog_mesh_min, hlog_mesh_max, self.mesh_size)
            
            mesh_axis = hlog_inv(hlog_mesh_axis, b = b, r = r, d = d)
            mesh_axes.append(mesh_axis)
            
            for to_channel in self._channels:
                from_channel = channel
                if from_channel == to_channel:
                    continue
                
                self._splines[from_channel][to_channel] = \
                    scipy.interpolate.LSQUnivariateSpline(tube_data[from_channel].values,
                                                          tube_data[to_channel].values,
                                                          t = knots,
                                                          k = 1)
         
        
        mesh = pd.DataFrame(util.cartesian(mesh_axes), 
                            columns = [x for x in self._channels])
         
        mesh_corrected = mesh.apply(_correct_bleedthrough,
                                    axis = 1,
                                    args = ([[x for x in self._channels], 
                                             self._splines]))
        
        for channel in self._channels:
            chan_values = np.reshape(mesh_corrected[channel], [len(x) for x in mesh_axes])
            self._interpolators[channel] = \
                scipy.interpolate.RegularGridInterpolator(points = mesh_axes, 
                                                          values = chan_values, 
                                                          bounds_error = False, 
                                                          fill_value = 0.0)
Example #5
0
    def estimate(self, experiment, subset = None): 
        """
        Estimate the bleedthrough from the single-channel controls in 
        :attr:`controls`
        """
        
        if not self.ignore_deprecated:
            raise util.CytoflowOpError(None,
                                       "BleedthroughPiecewiseOp is DEPRECATED. "
                                       "To use it anyway, set ignore_deprected "
                                       "to True.")
        
        if experiment is None:
            raise util.CytoflowOpError('experiment', 
                                       "No experiment specified")
        
        if self.num_knots < 3:
            raise util.CytoflowOpError('num_knots',
                                       "Need to allow at least 3 knots in the spline")
        
        self._channels = list(self.controls.keys())

        if len(self._channels) < 2:
            raise util.CytoflowOpError('controls',
                                       "Need at least two channels to correct bleedthrough.")
        
        for channel in list(self.controls.keys()):
            if 'range' not in experiment.metadata[channel]:
                raise util.CytoflowOpError(None,
                                           "Can't find range for channel {}"
                                           .format(channel))

        self._splines = {}
        mesh_axes = []

        for channel in self._channels:
            self._splines[channel] = {}
            
            # make a little Experiment
            check_tube(self.controls[channel], experiment)
            tube_exp = ImportOp(tubes = [Tube(file = self.controls[channel])],
                                channels = {experiment.metadata[c]["fcs_name"] : c for c in experiment.channels},
                                name_metadata = experiment.metadata['name_metadata']).apply()
            
            # apply previous operations
            for op in experiment.history:
                if hasattr(op, 'by'):
                    for by in op.by:
                        if 'experiment' in experiment.metadata[by]:
                            raise util.CytoflowOpError('experiment',
                                                       "Prior to applying this operation, "
                                                       "you must not apply any operation with 'by' "
                                                       "set to an experimental condition.")
                tube_exp = op.apply(tube_exp)
                
            # subset it
            if subset:
                try:
                    tube_exp = tube_exp.query(subset)
                except Exception as e:
                    raise util.CytoflowOpError('subset',
                                               "Subset string '{0}' isn't valid"
                                          .format(self.subset)) from e
                                
                if len(tube_exp.data) == 0:
                    raise util.CytoflowOpError('subset',
                                               "Subset string '{0}' returned no events"
                                          .format(self.subset))
            
            tube_data = tube_exp.data
                
            # polyfit requires sorted data
            tube_data.sort_values(by = channel, inplace = True)
            
            channel_min = tube_data[channel].min()
            channel_max = tube_data[channel].max()
            
            # we're going to set the knots and splines evenly across the 
            # logicle-transformed data, so as to captur both the "linear"
            # aspect of the near-0 and negative values, and the "log"
            # aspect of large values.
            
            scale = util.scale_factory("logicle", experiment, channel = channel)
            
            # the splines' knots
            knot_min = channel_min
            knot_max = channel_max            
            
            lg_knot_min = scale(knot_min)
            lg_knot_max = scale(knot_max)
            lg_knots = np.linspace(lg_knot_min, lg_knot_max, self.num_knots)
            knots = scale.inverse(lg_knots)
            
            # only keep the interior knots
            knots = knots[1:-1] 
            
            # the interpolators' mesh       
            if 'af_median' in experiment.metadata[channel] and \
               'af_stdev' in experiment.metadata[channel]:     
                mesh_min = experiment.metadata[channel]['af_median'] - \
                           3 * experiment.metadata[channel]['af_stdev']
            elif 'range' in experiment.metadata[channel]:
                mesh_min = -0.01 * experiment.metadata[channel]['range'] # TODO - does this even work?
                warn("This works best if you apply AutofluorescenceOp before "
                     "computing bleedthrough", util.CytoflowOpWarning)
                
            mesh_max = experiment.metadata[channel]['range']

            lg_mesh_min = scale(mesh_min)
            lg_mesh_max = scale(mesh_max)
            lg_mesh_axis = \
                np.linspace(lg_mesh_min, lg_mesh_max, self.mesh_size)
            
            mesh_axis = scale.inverse(lg_mesh_axis)
            mesh_axes.append(mesh_axis)
            
            for to_channel in self._channels:
                from_channel = channel
                if from_channel == to_channel:
                    continue
                
                self._splines[from_channel][to_channel] = \
                    scipy.interpolate.LSQUnivariateSpline(tube_data[from_channel].values,
                                                          tube_data[to_channel].values,
                                                          t = knots,
                                                          k = 1)
         
        
        mesh = pd.DataFrame(util.cartesian(mesh_axes), 
                            columns = [x for x in self._channels])
         
        mesh_corrected = mesh.apply(_correct_bleedthrough,
                                    axis = 1,
                                    args = ([[x for x in self._channels], 
                                             self._splines]))
        
        for channel in self._channels:
            chan_values = mesh_corrected[channel].values.reshape([len(x) for x in mesh_axes])
            self._interpolators[channel] = \
                scipy.interpolate.RegularGridInterpolator(points = mesh_axes, 
                                                          values = chan_values, 
                                                          bounds_error = False, 
                                                          fill_value = 0.0)
    def estimate(self, experiment, subset = None): 
        """
        Estimate the bleedthrough from the single-channel controls in `controls`
        """
        if not experiment:
            raise CytoflowOpError("No experiment specified")
        
        if self.num_knots < 3:
            raise CytoflowOpError("Need to allow at least 3 knots in the spline")
        
        self._channels = self.controls.keys()
    
        for channel in self._channels:
            try:
                tube_meta = fcsparser.parse(self.controls[channel], 
                                            meta_data_only = True, 
                                            reformat_meta = True)
                tube_channels = tube_meta["_channels_"].set_index("$PnN")
            except Exception as e:
                raise CytoflowOpError("FCS reader threw an error on tube {0}: {1}"\
                                   .format(self.controls[channel], e.value))

            for channel in self._channels:
                exp_v = experiment.metadata[channel]['voltage']
            
                if not "$PnV" in tube_channels.ix[channel]:
                    raise CytoflowOpError("Didn't find a voltage for channel {0}" 
                                          "in tube {1}".format(channel, self.controls[channel]))
                
                control_v = tube_channels.ix[channel]["$PnV"]
                
                if control_v != exp_v:
                    raise CytoflowOpError("Voltage differs for channel {0} in tube {1}"
                                          .format(channel, self.controls[channel]))

        self._splines = {}
        mesh_axes = []

        for channel in self._channels:
            self._splines[channel] = {}

            try:
                tube_meta, tube_data = fcsparser.parse(self.controls[channel], 
                                                       reformat_meta = True)
                tube_channels = tube_meta["_channels_"].set_index("$PnN")
            except Exception as e:
                raise CytoflowOpError("FCS reader threw an error on tube {0}: {1}"\
                                   .format(self.controls[channel], e.value))
            
            data = tube_data.sort(channel)

            for af_channel in self._channels:
                if 'af_median' in experiment.metadata[af_channel]:
                    data[af_channel] = data[af_channel] - \
                                    experiment.metadata[af_channel]['af_median']

            channel_min = data[channel].min()
            channel_max = data[channel].max()
            
            # we're going to set the knots and splines evenly across the hlog-
            # transformed data, so as to capture both the "linear" aspect
            # of near-0 and negative values, and the "log" aspect of large
            # values

            # parameterize the hlog transform
            r = experiment.metadata[channel]['range']  # instrument range
            d = np.log10(r)  # maximum display scale, in decades
            
            # the transition point from linear --> log scale
            # use half of the log-transformed scale as "linear".
            b = 2 ** (np.log2(r) / 2)
            
            # the splines' knots
            knot_min = channel_min
            knot_max = channel_max
            
            hlog_knot_min, hlog_knot_max = \
                hlog((knot_min, knot_max), b = b, r = r, d = d)
            hlog_knots = np.linspace(hlog_knot_min, hlog_knot_max, self.num_knots)
            knots = hlog_inv(hlog_knots, b = b, r = r, d = d)
            
            # only keep the interior knots
            knots = knots[1:-1] 
            
            # the interpolators' mesh            
            mesh_min = -3 * experiment.metadata[channel]['af_stdev']
            mesh_max = r
                
            hlog_mesh_min, hlog_mesh_max = \
                hlog((mesh_min, mesh_max), b = b, r = r, d = d)
            hlog_mesh_axis = \
                np.linspace(hlog_mesh_min, hlog_mesh_max, self.mesh_size)
            
            mesh_axis = hlog_inv(hlog_mesh_axis, b = b, r = r, d = d)
            mesh_axes.append(mesh_axis)
            
            for to_channel in self._channels:
                from_channel = channel
                if from_channel == to_channel:
                    continue
                
                self._splines[from_channel][to_channel] = \
                    scipy.interpolate.LSQUnivariateSpline(data[from_channel].values,
                                                          data[to_channel].values,
                                                          t = knots,
                                                          k = 1)
         
        
        mesh = pandas.DataFrame(cartesian(mesh_axes), 
                                columns = [x for x in self._channels])
         
        mesh_corrected = mesh.apply(_correct_bleedthrough,
                                    axis = 1,
                                    args = ([[x for x in self._channels], 
                                             self._splines]))
        
        for channel in self._channels:
            chan_values = np.reshape(mesh_corrected[channel], [len(x) for x in mesh_axes])
            self._interpolators[channel] = \
                scipy.interpolate.RegularGridInterpolator(mesh_axes, chan_values)