def apply(self, experiment): if not self.beads_name: raise util.CytoflowOpError("Specify which beads to calibrate with.") for i, unit_i in enumerate(self.units_list): for j, unit_j in enumerate(self.units_list): if unit_i.channel == unit_j.channel and i != j: raise util.CytoflowOpError("Channel {0} is included more than once" .format(unit_i.channel)) self.units = {} for unit in self.units_list: self.units[unit.channel] = unit.unit self.beads = self.BEADS[self.beads_name] BeadCalibrationOp.apply(self, experiment)
class TasbePluginOp(PluginOpMixin): handler_factory = Callable(TasbeHandler) id = Constant( 'edu.mit.synbio.cytoflowgui.op_plugins.bleedthrough_piecewise') friendly_id = Constant("Quantitative Pipeline") name = Constant("TASBE") channels = List(Str, estimate=True) blank_file = File(filter=["*.fcs"], estimate=True) bleedthrough_list = List(_BleedthroughControl, estimate=True) beads_name = Str(estimate=True) beads_file = File(filter=["*.fcs"], estimate=True) beads_unit = Str(estimate=True) bead_peak_quantile = Int(80, estimate=True) bead_brightness_threshold = Float(100, estimate=True) bead_brightness_cutoff = Float(Undefined, estimate=True) to_channel = Str(estimate=True) translation_list = List(_TranslationControl, estimate=True) mixture_model = Bool(False, estimate=True) _af_op = Instance(AutofluorescenceOp, (), transient=True) _bleedthrough_op = Instance(BleedthroughLinearOp, (), transient=True) _bead_calibration_op = Instance(BeadCalibrationOp, (), transient=True) _color_translation_op = Instance(ColorTranslationOp, (), transient=True) subset_list = List(ISubset, estimate=True) subset = Property(Str, depends_on="subset_list.str") # MAGIC - returns the value of the "subset" Property, above def _get_subset(self): return " and ".join( [subset.str for subset in self.subset_list if subset.str]) @on_trait_change("subset_list.str", post_init=True) def _subset_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('subset_list', self.subset_list)) @on_trait_change('channels[]', post_init=True) def _channels_changed(self, obj, name, old, new): self.bleedthrough_list = [] for c in self.channels: self.bleedthrough_list.append(_BleedthroughControl(channel=c)) self.changed = (Changed.ESTIMATE, ('bleedthrough_list', self.bleedthrough_list)) self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append( _TranslationControl(from_channel=c, to_channel=self.to_channel)) self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) @on_trait_change('to_channel', post_init=True) def _to_channel_changed(self, obj, name, old, new): self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append( _TranslationControl(from_channel=c, to_channel=self.to_channel)) self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) @on_trait_change("bleedthrough_list_items, bleedthrough_list.+", post_init=True) def _bleedthrough_controls_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('bleedthrough_list', self.bleedthrough_list)) @on_trait_change("translation_list_items, translation_list.+", post_init=True) def _translation_controls_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) def estimate(self, experiment, subset=None): if not self.subset: warnings.warn( "Are you sure you don't want to specify a subset " "used to estimate the model?", util.CytoflowOpWarning) if experiment is None: raise util.CytoflowOpError("No valid result to estimate with") experiment = experiment.clone() self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file self._af_op.estimate(experiment, subset=self.subset) self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._af_op.apply(experiment) self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file self._bleedthrough_op.estimate(experiment, subset=self.subset) self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._bleedthrough_op.apply(experiment) self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[ self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff self._bead_calibration_op.units.clear() # this is the old way # for channel in self.channels: # self._bead_calibration_op.units[channel] = self.beads_unit # this way matches TASBE better self._bead_calibration_op.units[self.to_channel] = self.beads_unit self._bead_calibration_op.estimate(experiment) self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._bead_calibration_op.apply(experiment) self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[( control.from_channel, control.to_channel)] = control.file self._color_translation_op.estimate(experiment, subset=self.subset) self.changed = (Changed.ESTIMATE_RESULT, self) def should_clear_estimate(self, changed): if changed == Changed.ESTIMATE: return True return False def clear_estimate(self): self._af_op = AutofluorescenceOp() self._bleedthrough_op = BleedthroughLinearOp() self._bead_calibration_op = BeadCalibrationOp() self._color_translation_op = ColorTranslationOp() self.changed = (Changed.ESTIMATE_RESULT, self) def apply(self, experiment): if experiment is None: raise util.CytoflowOpError("No experiment was specified") experiment = self._af_op.apply(experiment) experiment = self._bleedthrough_op.apply(experiment) experiment = self._bead_calibration_op.apply(experiment) experiment = self._color_translation_op.apply(experiment) return experiment def default_view(self, **kwargs): return TasbePluginView(op=self, **kwargs)
class TasbePluginOp(PluginOpMixin): handler_factory = Callable(TasbeHandler) id = Constant('edu.mit.synbio.cytoflowgui.op_plugins.bleedthrough_piecewise') friendly_id = Constant("Quantitative Pipeline") name = Constant("TASBE") channels = List(Str, estimate = True) blank_file = File(filter = ["*.fcs"], estimate = True) bleedthrough_list = List(_BleedthroughControl, estimate = True) beads_name = Str(estimate = True) beads_file = File(filter = ["*.fcs"], estimate = True) beads_unit = Str(estimate = True) bead_peak_quantile = CInt(80, estimate = True) bead_brightness_threshold = CFloat(100.0, estimate = True) bead_brightness_cutoff = util.CFloatOrNone(None, estimate = True) to_channel = Str(estimate = True) translation_list = List(_TranslationControl, estimate = True) mixture_model = Bool(False, estimate = True) _af_op = Instance(AutofluorescenceOp, (), transient = True) _bleedthrough_op = Instance(BleedthroughLinearOp, (), transient = True) _bead_calibration_op = Instance(BeadCalibrationOp, (), transient = True) _color_translation_op = Instance(ColorTranslationOp, (), transient = True) subset_list = List(ISubset, estimate = True) subset = Property(Str, depends_on = "subset_list.str") # MAGIC - returns the value of the "subset" Property, above def _get_subset(self): return " and ".join([subset.str for subset in self.subset_list if subset.str]) @on_trait_change("subset_list.str") def _subset_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('subset_list', self.subset_list)) @on_trait_change('channels[]', post_init = True) def _channels_changed(self, obj, name, old, new): for channel in self.channels: if channel not in [control.channel for control in self.bleedthrough_list]: self.bleedthrough_list.append(_BleedthroughControl(channel = channel)) to_remove = [] for control in self.bleedthrough_list: if control.channel not in self.channels: to_remove.append(control) for control in to_remove: self.bleedthrough_list.remove(control) for c in self.channels: if c == self.to_channel: continue if channel not in [control.from_channel for control in self.translation_list]: self.translation_list.append(_TranslationControl(from_channel = c, to_channel = self.to_channel)) to_remove = [] for control in self.translation_list: if control.from_channel not in self.channels: to_remove.append(control) for control in to_remove: self.translation_list.remove(control) self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) self.changed = (Changed.ESTIMATE, ('bleedthrough_list', self.bleedthrough_list)) @on_trait_change('to_channel', post_init = True) def _to_channel_changed(self, obj, name, old, new): self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append(_TranslationControl(from_channel = c, to_channel = self.to_channel)) self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) @on_trait_change("bleedthrough_list_items, bleedthrough_list.+", post_init = True) def _bleedthrough_controls_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('bleedthrough_list', self.bleedthrough_list)) @on_trait_change("translation_list_items, translation_list.+", post_init = True) def _translation_controls_changed(self, obj, name, old, new): self.changed = (Changed.ESTIMATE, ('translation_list', self.translation_list)) def estimate(self, experiment, subset = None): if not self.subset: warnings.warn("Are you sure you don't want to specify a subset " "used to estimate the model?", util.CytoflowOpWarning) if experiment is None: raise util.CytoflowOpError("No valid result to estimate with") # TODO - don't actually need to apply these operations to data in estimate experiment = experiment.clone() self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file try: self._af_op.estimate(experiment, subset = self.subset) except: raise finally: self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._af_op.apply(experiment) self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file try: self._bleedthrough_op.estimate(experiment, subset = self.subset) except: raise finally: self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._bleedthrough_op.apply(experiment) self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff self._bead_calibration_op.units.clear() # this is the old way # for channel in self.channels: # self._bead_calibration_op.units[channel] = self.beads_unit # this way matches TASBE better self._bead_calibration_op.units[self.to_channel] = self.beads_unit try: self._bead_calibration_op.estimate(experiment) except: raise finally: self.changed = (Changed.ESTIMATE_RESULT, self) experiment = self._bead_calibration_op.apply(experiment) self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[(control.from_channel, control.to_channel)] = control.file try: self._color_translation_op.estimate(experiment, subset = self.subset) except: raise finally: self.changed = (Changed.ESTIMATE_RESULT, self) def should_clear_estimate(self, changed, payload): if changed == Changed.ESTIMATE: return True return False def clear_estimate(self): self._af_op = AutofluorescenceOp() self._bleedthrough_op = BleedthroughLinearOp() self._bead_calibration_op = BeadCalibrationOp() self._color_translation_op = ColorTranslationOp() self.changed = (Changed.ESTIMATE_RESULT, self) def apply(self, experiment): if experiment is None: raise util.CytoflowOpError("No experiment was specified") experiment = self._af_op.apply(experiment) experiment = self._bleedthrough_op.apply(experiment) experiment = self._bead_calibration_op.apply(experiment) experiment = self._color_translation_op.apply(experiment) return experiment def default_view(self, **kwargs): return TasbePluginView(op = self, **kwargs) def get_notebook_code(self, idx): self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff self._bead_calibration_op.units.clear() self._bead_calibration_op.units[self.to_channel] = self.beads_unit self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[(control.from_channel, control.to_channel)] = control.file return dedent(""" # the TASBE-style calibration is not a single Cytoflow module. Instead, it # is a specific sequence of four calibrations: autofluorescence correction, # bleedthrough, bead calibration and color translation. # autofluorescence op_{idx}_af = {af_repr} op_{idx}_af.estimate(ex_{prev_idx}{subset}) ex_{idx}_af = op_{idx}_af.apply(ex_{prev_idx}) # bleedthrough op_{idx}_bleedthrough = {bleedthrough_repr} op_{idx}_bleedthrough.estimate(ex_{idx}_af{subset}) ex_{idx}_bleedthrough = op_{idx}_bleedthrough.apply(ex_{idx}_af) # bead calibration # beads: {beads} op_{idx}_beads = {beads_repr} op_{idx}_beads.estimate(ex_{idx}_bleedthrough) ex_{idx}_beads = op_{idx}_beads.apply(ex_{idx}_bleedthrough) # color translation op_{idx}_color = {color_repr} op_{idx}_color.estimate(ex_{idx}_beads{subset}) ex_{idx} = op_{idx}_color.apply(ex_{idx}_beads) """ .format(idx = idx, prev_idx = idx - 1, af_repr = repr(self._af_op), bleedthrough_repr = repr(self._bleedthrough_op), color_repr = repr(self._color_translation_op), beads = self.beads_name, beads_repr = repr(self._bead_calibration_op), subset = ", subset = " + repr(self.subset) if self.subset else ""))
class TasbePluginOp(PluginOpMixin): handler_factory = Callable(TasbeHandler) id = Constant('edu.mit.synbio.cytoflowgui.op_plugins.bleedthrough_piecewise') friendly_id = Constant("Quantitative Pipeline") name = Constant("TASBE") channels = List(Str, estimate = True) blank_file = File(filter = ["*.fcs"], estimate = True) bleedthrough_list = List(_BleedthroughControl, estimate = True) beads_name = Str(estimate = True) beads_file = File(filter = ["*.fcs"], estimate = True) beads_unit = Str(estimate = True) bead_peak_quantile = Int(80, estimate = True) bead_brightness_threshold = Float(100, estimate = True) bead_brightness_cutoff = Float(Undefined, estimate = True) to_channel = Str(estimate = True) translation_list = List(_TranslationControl, estimate = True) mixture_model = Bool(False, estimate = True) _af_op = Instance(AutofluorescenceOp, (), transient = True) _bleedthrough_op = Instance(BleedthroughPiecewiseOp, (), transient = True) _bead_calibration_op = Instance(BeadCalibrationOp, (), transient = True) _color_translation_op = Instance(ColorTranslationOp, (), transient = True) @on_trait_change('channels[]', post_init = True) def _channels_changed(self, obj, name, old, new): self.bleedthrough_list = [] for c in self.channels: self.bleedthrough_list.append(_BleedthroughControl(channel = c)) self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append(_TranslationControl(from_channel = c, to_channel = self.to_channel)) self.changed = "estimate" @on_trait_change('to_channel', post_init = True) def _to_channel_changed(self, obj, name, old, new): self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append(_TranslationControl(from_channel = c, to_channel = self.to_channel)) def estimate(self, experiment, subset = None): if not self.subset: warnings.warn("Are you sure you don't want to specify a subset " "used to estimate the model?", util.CytoflowOpWarning) experiment = experiment.clone() self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file self._af_op.estimate(experiment, subset = self.subset) self.changed = "estimate_result" experiment = self._af_op.apply(experiment) self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file self._bleedthrough_op.estimate(experiment, subset = self.subset) self.changed = "estimate_result" experiment = self._bleedthrough_op.apply(experiment) self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff self._bead_calibration_op.units.clear() for channel in self.channels: self._bead_calibration_op.units[channel] = self.beads_unit self._bead_calibration_op.estimate(experiment) self.changed = "estimate_result" experiment = self._bead_calibration_op.apply(experiment) self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[(control.from_channel, control.to_channel)] = control.file self._color_translation_op.estimate(experiment, subset = self.subset) self.changed = "estimate_result" def should_clear_estimate(self, changed): """ Should the owning WorkflowItem clear the estimated model by calling op.clear_estimate()? `changed` can be: - "estimate" -- the parameters required to call 'estimate()' (ie traits with estimate = True metadata) have changed - "prev_result" -- the previous WorkflowItem's result changed """ if changed == "prev_result": return False return True def clear_estimate(self): self._af_op = AutofluorescenceOp() self._bleedthrough_op = BleedthroughPiecewiseOp() self._bead_calibration_op = BeadCalibrationOp() self._color_translation_op = ColorTranslationOp() self.changed = "estimate_result" def apply(self, experiment): experiment = self._af_op.apply(experiment) experiment = self._bleedthrough_op.apply(experiment) experiment = self._bead_calibration_op.apply(experiment) experiment = self._color_translation_op.apply(experiment) return experiment def default_view(self, **kwargs): return TasbePluginView(op = self, **kwargs)
class TasbeWorkflowOp(WorkflowOperation): id = Constant('edu.mit.synbio.cytoflowgui.workflow.operations.tasbe') friendly_id = Constant("Quantitative Pipeline") name = Constant("TASBE") channels = List(Str, estimate=True) blank_file = File(filter=["*.fcs"], estimate=True) bleedthrough_list = List(BleedthroughControl, estimate=True) beads_name = Str(estimate=True) beads_file = File(filter=["*.fcs"], estimate=True) beads_unit = Str(estimate=True) # used if do_color_translation is True units_list = List(BeadUnit, estimate=True) # used if do_color_translation is False bead_peak_quantile = Int(80, estimate=True) bead_brightness_threshold = Float(100.0, estimate=True) bead_brightness_cutoff = util.FloatOrNone(None, estimate=True) do_color_translation = Bool(False, estimate=True) to_channel = Str(estimate=True) translation_list = List(TranslationControl, estimate=True) mixture_model = Bool(False, estimate=True) _af_op = Instance(AutofluorescenceOp, (), transient=True) _bleedthrough_op = Instance(BleedthroughLinearOp, (), transient=True) _bead_calibration_op = Instance(BeadCalibrationOp, (), transient=True) _color_translation_op = Instance(ColorTranslationOp, (), transient=True) estimate_progress = Str(Progress.NO_MODEL, transient=True, estimate_result=True, status=True) # override the base class's "subset" with one that is dynamically generated / # updated from subset_list subset = Property(Str, observe="subset_list.items.str") subset_list = List(ISubset, estimate=True) # bits to support the subset editor @observe('subset_list:items.str') def _on_subset_changed(self, _): self.changed = 'subset_list' # MAGIC - returns the value of the "subset" Property, above def _get_subset(self): return " and ".join( [subset.str for subset in self.subset_list if subset.str]) @observe('channels.items,to_channel,do_color_translation', post_init=True) def _on_channels_changed(self, _): # bleedthrough for channel in self.channels: if channel not in [ control.channel for control in self.bleedthrough_list ]: self.bleedthrough_list.append( BleedthroughControl(channel=channel)) to_remove = [] for control in self.bleedthrough_list: if control.channel not in self.channels: to_remove.append(control) for control in to_remove: self.bleedthrough_list.remove(control) # bead calibration for channel in self.channels: if channel not in [unit.channel for unit in self.units_list]: self.units_list.append(BeadUnit(channel=channel)) to_remove = [] for unit in self.units_list: if unit.channel not in self.channels: to_remove.append(unit) for unit in to_remove: self.units_list.remove(unit) # color translation if self.to_channel not in self.channels: self.translation_list = [] self.to_channel = '' return for channel in self.channels: if channel != self.to_channel: if channel not in [ control.from_channel for control in self.translation_list ]: self.translation_list.append( TranslationControl(from_channel=channel, to_channel=self.to_channel)) to_remove = [] for control in self.translation_list: if control.from_channel not in self.channels or \ control.to_channel not in self.channels: to_remove.append(control) for control in to_remove: self.translation_list.remove(control) @observe('to_channel', post_init=True) def _on_to_channel_changed(self, _): self.translation_list = [] if self.to_channel: for c in self.channels: if c == self.to_channel: continue self.translation_list.append( TranslationControl(from_channel=c, to_channel=self.to_channel)) @observe("bleedthrough_list:items:file", post_init=True) def _bleedthrough_controls_changed(self, _): self.changed = 'bleedthrough_list' @observe("translation_list:items:file", post_init=True) def _translation_controls_changed(self, _): self.changed = 'translation_list' @observe('units_list:items:unit', post_init=True) def _on_units_changed(self, _): self.changed = 'units_list' def estimate(self, experiment, subset=None): if not self.subset: warnings.warn( "Are you sure you don't want to specify a subset " "used to estimate the model?", util.CytoflowOpWarning) if experiment is None: raise util.CytoflowOpError("No valid result to estimate with") # TODO - don't actually need to apply these operations to data in estimate experiment = experiment.clone() self.estimate_progress = Progress.AUTOFLUORESCENCE self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file self._af_op.estimate(experiment, subset=self.subset) experiment = self._af_op.apply(experiment) self.estimate_progress = Progress.BLEEDTHROUGH self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file self._bleedthrough_op.estimate(experiment, subset=self.subset) experiment = self._bleedthrough_op.apply(experiment) self.estimate_progress = Progress.BEAD_CALIBRATION self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[ self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff if self.do_color_translation: # this way matches TASBE better self._bead_calibration_op.units.clear() self._bead_calibration_op.units[self.to_channel] = self.beads_unit self._bead_calibration_op.estimate(experiment) experiment = self._bead_calibration_op.apply(experiment) self.estimate_progress = Progress.COLOR_TRANSLATION self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[( control.from_channel, control.to_channel)] = control.file self._color_translation_op.estimate(experiment, subset=self.subset) else: self._bead_calibration_op.units.clear() for unit in self.units_list: self._bead_calibration_op.units[unit.channel] = unit.unit self._bead_calibration_op.estimate(experiment) experiment = self._bead_calibration_op.apply(experiment) self.estimate_progress = Progress.VALID def should_clear_estimate(self, changed, payload): if changed == Changed.ESTIMATE: return True return False def clear_estimate(self): self._af_op = AutofluorescenceOp() self._bleedthrough_op = BleedthroughLinearOp() self._bead_calibration_op = BeadCalibrationOp() self._color_translation_op = ColorTranslationOp() self.estimate_progress = Progress.NO_MODEL def apply(self, experiment): if self.estimate_progress == Progress.NO_MODEL: raise util.CytoflowOpError(None, 'Click "Estimate"!') elif self.estimate_progress != Progress.VALID: raise util.CytoflowOpError(None, 'No valid model') experiment = self._af_op.apply(experiment) experiment = self._bleedthrough_op.apply(experiment) experiment = self._bead_calibration_op.apply(experiment) if self.do_color_translation: experiment = self._color_translation_op.apply(experiment) return experiment def default_view(self, **kwargs): return TasbeWorkflowView(op=self, **kwargs) def get_notebook_code(self, idx): self._af_op.channels = self.channels self._af_op.blank_file = self.blank_file self._bleedthrough_op.controls.clear() for control in self.bleedthrough_list: self._bleedthrough_op.controls[control.channel] = control.file self._bead_calibration_op.beads = BeadCalibrationOp.BEADS[ self.beads_name] self._bead_calibration_op.beads_file = self.beads_file self._bead_calibration_op.bead_peak_quantile = self.bead_peak_quantile self._bead_calibration_op.bead_brightness_threshold = self.bead_brightness_threshold self._bead_calibration_op.bead_brightness_cutoff = self.bead_brightness_cutoff self._bead_calibration_op.units.clear() self._bead_calibration_op.units[self.to_channel] = self.beads_unit self._color_translation_op.mixture_model = self.mixture_model self._color_translation_op.controls.clear() for control in self.translation_list: self._color_translation_op.controls[( control.from_channel, control.to_channel)] = control.file return dedent(""" # the TASBE-style calibration is not a single Cytoflow module. Instead, it # is a specific sequence of four calibrations: autofluorescence correction, # bleedthrough, bead calibration and color translation. # autofluorescence op_{idx}_af = {af_repr} op_{idx}_af.estimate(ex_{prev_idx}{subset}) ex_{idx}_af = op_{idx}_af.apply(ex_{prev_idx}) # bleedthrough op_{idx}_bleedthrough = {bleedthrough_repr} op_{idx}_bleedthrough.estimate(ex_{idx}_af{subset}) ex_{idx}_bleedthrough = op_{idx}_bleedthrough.apply(ex_{idx}_af) # bead calibration # beads: {beads} op_{idx}_beads = {beads_repr} op_{idx}_beads.estimate(ex_{idx}_bleedthrough) ex_{idx}_beads = op_{idx}_beads.apply(ex_{idx}_bleedthrough) # color translation op_{idx}_color = {color_repr} op_{idx}_color.estimate(ex_{idx}_beads{subset}) ex_{idx} = op_{idx}_color.apply(ex_{idx}_beads) """.format(idx=idx, prev_idx=idx - 1, af_repr=repr(self._af_op), bleedthrough_repr=repr(self._bleedthrough_op), color_repr=repr(self._color_translation_op), beads=self.beads_name, beads_repr=repr(self._bead_calibration_op), subset=", subset = " + repr(self.subset) if self.subset else ""))