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")
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")
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)
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)