示例#1
0
class Range2DPluginOp(Range2DOp, PluginOpMixin):
    handler_factory = Callable(Range2DHandler, transient = True)
    xlow = CFloat
    xhigh = CFloat
    ylow = CFloat
    yhigh = CFloat
    
    def default_view(self, **kwargs):
        return Range2DSelectionView(op = self, **kwargs)
    
    def get_notebook_code(self, idx):
        op = Range2DOp()
        op.copy_traits(self, op.copyable_trait_names())

        return dedent("""
        op_{idx} = {repr}
                
        ex_{idx} = op_{idx}.apply(ex_{prev_idx})
        """
        .format(repr = repr(op),
                idx = idx,
                prev_idx = idx - 1))
示例#2
0
class BleedthroughPiecewisePluginView(PluginViewMixin,
                                      BleedthroughPiecewiseDiagnostic):
    handler_factory = Callable(BleedthroughPiecewiseViewHandler)
    subset = DelegatesTo('op', transient=True)

    def plot_wi(self, wi):
        self.plot(wi.previous_wi.result)

    def should_plot(self, changed, payload):
        if changed == Changed.ESTIMATE_RESULT:
            return True

        return False

    def get_notebook_code(self, idx):
        view = BleedthroughPiecewiseDiagnostic()
        view.copy_traits(self, view.copyable_trait_names())
        view.subset = self.subset

        return dedent("""
        op_{idx}.default_view({traits}).plot(ex_{prev_idx})
        """.format(traits=traits_str(view), idx=idx, prev_idx=idx - 1))
示例#3
0
class AutofluorescencePluginOp(PluginOpMixin, AutofluorescenceOp):
    handler_factory = Callable(AutofluorescenceHandler)
    
    channels = List(Str, estimate = True)
    blank_file = File(filter = ["*.fcs"], estimate = True)

    @on_trait_change('channels_items', post_init = True)
    def _channels_changed(self, obj, name, old, new):
        self.changed = "estimate"
    
    def default_view(self, **kwargs):
        return AutofluorescencePluginView(op = self, **kwargs)
    
    def estimate(self, experiment):
        if not self.subset:
            warnings.warn("Are you sure you don't want to specify a subset "
                          "used to estimate the model?",
                          util.CytoflowOpWarning)
            
        AutofluorescenceOp.estimate(self, experiment, subset = self.subset)
        self.changed = "estimate_result"
        
    def clear_estimate(self):
        self._af_median.clear()
        self._af_stdev.clear()
        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
示例#4
0
class PolygonPluginOp(PluginOpMixin, PolygonOp):
    handler_factory = Callable(PolygonHandler)
    
    @on_trait_change('xchannel, ychannel, xscale, yscale', post_init = True)
    def _reset_polygon(self):
        self.vertices = []
    
    def default_view(self, **kwargs):
        return PolygonSelectionView(op = self, **kwargs)
    
    def get_notebook_code(self, idx):
        op = PolygonOp()
        op.copy_traits(self, op.copyable_trait_names())

        return dedent("""
        op_{idx} = {repr}
                
        ex_{idx} = op_{idx}.apply(ex_{prev_idx})
        """
        .format(repr = repr(op),
                idx = idx,
                prev_idx = idx - 1))
示例#5
0
class ThresholdSelectionView(PluginViewMixin, ThresholdSelection):
    handler_factory = Callable(ThresholdViewHandler, transient=True)
    op = Instance(IOperation, fixed=True)
    threshold = DelegatesTo('op', status=True)
    name = Str

    def should_plot(self, changed, payload):
        if changed == Changed.PREV_RESULT or changed == Changed.VIEW:
            return True
        else:
            return False

    def plot_wi(self, wi):
        self.plot(wi.previous_wi.result)

    def get_notebook_code(self, idx):
        view = ThresholdSelection()
        view.copy_traits(self, view.copyable_trait_names())

        return dedent("""
        op_{idx}.default_view({traits}).plot(ex_{prev_idx})
        """.format(idx=idx, traits=traits_str(view), prev_idx=idx - 1))
示例#6
0
class CommandAction(Action):
    """The CommandAction class is an Action class that wraps undo/redo
    commands.  It is only useful for commands that do not take any arguments or
    return any result.
    """

    #### 'CommandAction' interface ############################################

    #: The command to create when the action is performed.
    command = Callable()

    #: The command stack onto which the command will be pushed when the action
    #: is performed.
    command_stack = Instance(ICommandStack)

    #: This is the data on which the command operates.
    data = Any()

    ###########################################################################
    # 'Action' interface.
    ###########################################################################

    def perform(self, event):
        """This is reimplemented to push a new command instance onto the
        command stack.
        """

        self.command_stack.push(self.command(data=self.data))

    def _name_default(self):
        """ This gets the action name from the command. """

        if self.command:
            name = self.command().name
        else:
            name = ""

        return name
示例#7
0
class HistogramPluginView(PluginViewMixin, HistogramView):
    handler_factory = Callable(HistogramHandler, transient=True)
    plotfacet = Str
    plot_params = Instance(HistogramPlotParams, ())

    def enum_plots_wi(self, wi):
        if not self.plotfacet:
            return iter([])

        if self.plotfacet and self.plotfacet not in wi.result.conditions:
            raise util.CytoflowViewError(
                "Plot facet {0} not in the experiment".format(self.huefacet))
        values = np.sort(pd.unique(wi.result[self.plotfacet]))
        return IterWrapper(iter(values), [self.plotfacet])

    def plot(self, experiment, plot_name=None, **kwargs):

        if experiment is None:
            raise util.CytoflowViewError("No experiment specified")

        if self.plotfacet and plot_name is not None:
            experiment = experiment.subset(self.plotfacet, plot_name)

        HistogramView.plot(self, experiment, **kwargs)

    def get_notebook_code(self, idx):
        view = HistogramView()
        view.copy_traits(self, view.copyable_trait_names())
        plot_params_str = traits_str(self.plot_params)

        return dedent("""
        {repr}.plot(ex_{idx}{plot}{plot_params})
        """.format(repr=repr(view),
                   idx=idx,
                   plot=", plot_name = " +
                   repr(self.current_plot) if self.plot_names else "",
                   plot_params=", " +
                   plot_params_str if plot_params_str else ""))
示例#8
0
class PythonFunctionFactory(FactoryBase):

    # The code should contain a single function called "process" which is
    # called with the arguments: relpath, media, dest.  relpath is the key of
    # the media instance in the project dictionary, dest is the destination
    # directory, this can be empty if not specified.
    code = Str

    _func = Callable(transient=True)

    name = 'PythonFunctionFactory'

    def make_jobs(self, media_keys, project):
        self._setup_func()
        jobs = []
        for key in media_keys:
            media = project.get(key)
            relpath = media.relpath
            if not self._done.get(media.path, False):
                info = "Processing %s" % media.path
                job = Job(func=self._run,
                          args=[relpath, media, self.dest],
                          info=info)
                jobs.append(job)
        return jobs

    def _setup_func(self):
        ns = {}
        code_obj = compile(self.code, '<string>', 'exec')
        exec(code_obj, ns)
        self._func = ns['process']

    def _run(self, relpath, media, dest):
        self._func(relpath, media, dest)
        self._done[media.path] = True

    def _code_default(self):
        return "def process(relpath, media, dest): pass"
示例#9
0
class Model(HasTraits):
    text = Unicode()
    # Make sure we notify every time this is set, even if ``120 == 120.0``.
    value = Any(comparison_mode=NO_COMPARE)
    evaluator_func = Callable(int)

    def default_traits_view(self):
        traits_view = View(
            Bound(
                FormLayout(
                    (u'Text:', TextField(id='field')),
                    (u'Kind:',
                     EnumDropDown(id='combo',
                                  values=[
                                      (int, u'Integer'),
                                      (float, u'Float'),
                                  ])),
                    (u'Value:', Label(id='value')),
                    (u'Text:', Label(id='text')),
                ),
                'field.value := object.text',
                'combo.value := object.evaluator_func',
                'field.validator << PythonEvalidator(object.evaluator_func)',
                'value.text << repr(object.value)',
                'text.text << object.text',
                extra_context=dict(PythonEvalidator=PythonEvalidator),
            ),
            resizable=True,
        )
        return traits_view

    @on_trait_change('text,evaluator_func')
    def _update_value(self):
        try:
            value = self.evaluator_func(self.text)
        except (TraitError, TypeError, ValueError):
            value = None
        self.value = value
示例#10
0
class TablePluginView(PluginViewMixin, TableView):
    handler_factory = Callable(TableHandler)
    
    export = Event()
    
    # return the result for export
    result = Instance(pd.Series, status = True)
    
    def plot(self, experiment, plot_name = None, **kwargs):
        TableView.plot(self, experiment, **kwargs)
        self.result = experiment.statistics[self.statistic]
        
    def get_notebook_code(self, idx):
        view = TableView()
        view.copy_traits(self, view.copyable_trait_names())

        return dedent("""
        {repr}.plot(ex_{idx})
        """
        .format(repr = repr(view),
                idx = idx))

    @on_trait_change('export')
    def _on_export(self):
        
        dialog = DefaultFileDialog(parent = None,
                                   action = 'save as', 
                                   default_suffix = "csv",
                                   wildcard = (FileDialog.create_wildcard("CSV", "*.csv") + ';' + #@UndefinedVariable  
                                               FileDialog.create_wildcard("All files", "*")))     #@UndefinedVariable  

        if dialog.open() != OK:
            return
 
        data = pd.DataFrame(index = self.result.index)
        data[self.result.name] = self.result   
        
        self._export_data(data, self.result.name, dialog.path)
示例#11
0
class VersionInfo(HasTraits):
    """ Represents the information about a particular version of an
    application.
    """

    # The version string that this
    version = Str()

    # Customer-facing notes about this version.  Typically this is an
    # HTML document containing the changelog between this version and
    # the previous version
    notes = Str()

    # The location of where to obtain this version.  Typically this will
    # be an HTTP URL, but this can be a URI for a local or LAN item, or
    # it can be a
    location = Str()

    # A function that takes a string (self.version) and returns something
    # that can be used to compare against the version-parsed version of
    # another VersionInfo object.
    version_parser = Callable()

    def __cmp__(self, other):
        """ Allows for comparing two VersionInfo objects so they can
        be presented in version-sorted order.  This is where we parse
        and interpretation of the **version** string attribute.
        """
        # TODO: Do something more intelligent here
        if self.version_parser is not None:
            self_ver = self.version_parser(self.version)
        else:
            self_ver = self.version
        if other.version_parser is not None:
            other_ver = other.version_parser(other.version)
        else:
            other_ver = other.version
        return self_ver < other_ver
示例#12
0
class VolumeSlice(Pipeline):
    """
    Plots an interactive image plane sliced through a 3D volume of data
    supplied as argument.

    **Function signatures**::

        volume_slice(scalars, ...)
        volume_slice(x, y, z, scalars, ...)

    scalars is a 3D numpy arrays giving the data on a grid.

    If 4 arrays, (x, y, z, scalars) are passed, the 3 first arrays give the
    position, and the last the scalar value. The x, y and z arrays are then
    supposed to have been generated by `numpy.mgrid`, in other words, they are
    3D arrays, with positions lying on a 3D orthogonal and regularly spaced
    grid with nearest neighbor in space matching nearest neighbor in the array.
    The function builds a scalar field assuming  the points are regularly
    spaced."""

    _source_function = Callable(scalar_field)

    _pipeline = [ImagePlaneWidgetFactory, ]
示例#13
0
class ColorTranslationPluginView(PluginViewMixin, ColorTranslationDiagnostic):
    handler_factory = Callable(ColorTranslationViewHandler)
    
    def plot_wi(self, wi):
        self.plot(wi.previous_wi.result)
        
    def should_plot(self, changed, payload):
        if changed == Changed.ESTIMATE_RESULT:
            return True
        
        return False
    
    def get_notebook_code(self, idx):
        view = ColorTranslationDiagnostic()
        view.copy_traits(self, view.copyable_trait_names())
        view.subset = self.subset
        
        return dedent("""
        op_{idx}.default_view({traits}).plot(ex_{prev_idx})
        """
        .format(traits = traits_str(view),
                idx = idx,
                prev_idx = idx - 1))
示例#14
0
class GaussianMixture2DPluginView(PluginViewMixin, GaussianMixture2DView):
    handler_factory = Callable(GaussianMixture2DViewHandler)
    op = Instance(IOperation, fixed=True)
    subset = DelegatesTo('op', transient=True)
    by = DelegatesTo('op', status=True)

    def plot_wi(self, wi):
        if wi.current_view_plot_names:
            self.plot(wi.previous_wi.result, plot_name=wi.current_plot)
        else:
            self.plot(wi.previous_wi.result)

    def enum_plots_wi(self, wi):
        try:
            return self.enum_plots(wi.previous_wi.result)
        except:
            return []

    def should_plot(self, changed):
        if changed == Changed.RESULT:
            return False

        return True
示例#15
0
class CustomEditor(BasicEditorFactory):
    """Editor factory for custom editors."""

    #: Editor class to be instantiated.
    klass = Property()

    #: Factory function used to create the custom control
    factory = Callable()

    #: Arguments to be passed to the user's custom editor factory
    args = Tuple()

    def __init__(self, *args, **traits):
        if len(args) >= 1:
            self.factory = args[0]
            self.args = args[1:]
        super().__init__(**traits)

    # -------------------------------------------------------------------------
    #  Property getters
    # -------------------------------------------------------------------------
    def _get_klass(self):
        """Returns the editor class to be created."""
        return toolkit_object("custom_editor:CustomEditor")
示例#16
0
class Plot3d(Pipeline):
    """
    Draws lines between points.

    **Function signatures**::

        plot3d(x, y, z, ...)
        plot3d(x, y, z, s, ...)

    x, y, z and s are numpy arrays or lists of the same shape. x, y and z
    give the positions of the successive points of the line. s is an
    optional scalar value associated with each point."""

    tube_radius = Trait(0.025, CFloat, None,
                        adapts='filter.radius',
                        help="""radius of the tubes used to represent the
                        lines, If None, simple lines are used.
                        """)

    _source_function = Callable(line_source)

    _pipeline = [StripperFactory, TubeFactory, SurfaceFactory, ]

    def __call_internal__(self, *args, **kwargs):
        """ Override the call to be able to choose whether to apply
        filters.
        """
        self.source = self._source_function(*args, **kwargs)
        kwargs.pop('name', None)
        self.store_kwargs(kwargs)
        # Copy the pipeline so as not to modify it for the next call
        self.pipeline = self._pipeline[:]
        if self.kwargs['tube_radius'] is None:
            self.pipeline.remove(TubeFactory)
            self.pipeline.remove(StripperFactory)
        return self.build_pipeline()
示例#17
0
class ToolBarSchema(Schema):
    """ A schema for a Pyface ToolBarManager.
    """

    #: Assign a default ID for tool bar schemas.
    id = "ToolBar"

    #: The tool bar's user visible name. Note that this name may not be used on
    #: all platforms.
    name = Str("Tool Bar")

    #: The size of tool images (width, height).
    image_size = Tuple((16, 16))

    #: The orientation of the toolbar.
    orientation = Enum("horizontal", "vertical")

    #: Should we display the horizontal divider?
    show_divider = Bool(True)

    #: Should we display the name of each tool bar tool under its image?
    show_tool_names = Bool(True)

    #: A factory for instantiating a pyface ToolBarManager
    tool_bar_manager_factory = Callable(ToolBarManager)

    def create(self, children):
        traits = dict(
            id=self.id,
            name=self.name,
            image_size=self.image_size,
            orientation=self.orientation,
            show_divider=self.show_divider,
            show_tool_names=self.show_tool_names,
        )
        return self.tool_bar_manager_factory(*children, **traits)
示例#18
0
class Contour3d(Pipeline):
    """
    Plots iso-surfaces for a 3D volume of data suplied as arguments.

    **Function signatures**::

        contour3d(scalars, ...)
        contour3d(x, y, z, scalars, ...)

    scalars is a 3D numpy arrays giving the data on a grid.

    If 4 arrays, (x, y, z, scalars) are passed, the 3 first arrays give the
    position, and the last the scalar value. The x, y and z arrays are then
    supposed to have been generated by `numpy.mgrid`, in other words, they are
    3D arrays, with positions lying on a 3D orthogonal and regularly spaced
    grid with nearest neighbor in space matching nearest neighbor in the array.
    The function builds a scalar field assuming  the points are regularly
    spaced."""

    _source_function = Callable(scalar_field)

    _pipeline = [
        IsoSurfaceFactory,
    ]
示例#19
0
class NotUsedAnyMore:
    # dimension dependent tensor mappings
    #
    map_tns4_to_tns2 = Callable(map3d_tns4_to_tns2, transient=True)
    map_eps_eng_to_mtx = Callable(map3d_eps_eng_to_mtx, transient=True)
    map_sig_eng_to_mtx = Callable(map3d_sig_eng_to_mtx, transient=True)
    compliance_mapping = Callable(compliance_mapping3d, transient=True)
    map_sig_mtx_to_eng = Callable(map3d_sig_mtx_to_eng, transient=True)
    map_eps_mtx_to_eng = Callable(map3d_eps_mtx_to_eng, transient=True)

    def _get_explorer_config(self):
        '''Get the specific configuration of this material model in the explorer
        '''
        c = super(MATS3DEval, self)._get_explorer_config()

        from ibvpy.api import TLine
        from ibvpy.mats.mats3D.mats3D_explorer_bcond import BCDofProportional3D

        # overload the default configuration
        c['bcond_list'] = [
            BCDofProportional3D(max_strain=0.005, phi=0., theta=pi / 2.)
        ]
        c['tline'] = TLine(step=0.05, max=1)
        return c
示例#20
0
from .include import Include

# -------------------------------------------------------------------------
#  Trait definitions:
# -------------------------------------------------------------------------

# Name of the view trait:
AnId = Str(desc="the name of the view")

# Contents of the view trait (i.e., a single Group object):
Content = Instance(Group, desc="the content of the view")

# An optional model/view factory for converting the model into a viewable
# 'model_view' object
AModelView = Callable(
    desc="the factory function for converting a model "
    "into a model/view object"
)

# Reference to a Handler object trait:
AHandler = Any(desc="the handler for the view")

# Dialog window title trait:
ATitle = Str(desc="the window title for the view")

# User interface 'kind' trait. The values have the following meanings:
#
# * 'panel': An embeddable panel. This type of window is intended to be used as
#   part of a larger interface.
# * 'subpanel': An embeddable panel that does not display command buttons,
#   even if the View specifies them.
# * 'modal': A modal dialog box that operates on a clone of the object until
示例#21
0
class TasbeCalibrationView(PluginViewMixin):
    handler_factory = Callable(TasbeViewHandler)
    op = Instance(TasbeCalibrationOp)
    
    id = "edu.mit.synbio.cytoflowgui.op_plugins.tasbe"
    friendly_id = "TASBE Calibration" 
    
    name = Constant("TASBE Calibration")

    fsc_channel = DelegatesTo('op')
    ssc_channel = DelegatesTo('op')

    _polygon_view = Instance(PolygonSelection, transient = True)
    interactive = Property(Bool)
    
    def _get_interactive(self):
        if self._polygon_view:
            return self._polygon_view.interactive
        else:
            return False
        
    def _set_interactive(self, val):
        if self._polygon_view:
            self._polygon_view.interactive = val
    
    def plot_wi(self, wi):
        self.plot(None, plot_name = self.current_plot)
        
    def enum_plots(self, experiment):
        return iter(["Morphology",
                     "Autofluorescence",
                     "Bleedthrough",
                     "Bead Calibration",
                     "Color Translation"])
        
    def enum_plots_wi(self, wi):
        return iter(["Morphology",
                     "Autofluorescence",
                     "Bleedthrough",
                     "Bead Calibration",
                     "Color Translation"])

    def should_plot(self, changed, payload):
        """
        Should the owning WorkflowItem refresh the plot when certain things
        change?  `changed` can be:
        - Changed.VIEW -- the view's parameters changed
        - Changed.RESULT -- this WorkflowItem's result changed
        - Changed.PREV_RESULT -- the previous WorkflowItem's result changed
        - Changed.ESTIMATE_RESULT -- the results of calling "estimate" changed

        """
        if changed == Changed.VIEW:
            _, name, _ = payload
            if self.current_plot == 'Morphology' and (name == 'fsc_channel' or name == 'ssc_channel'):
                return True
            elif name == 'current_plot':
                return True
        elif changed == Changed.PREV_RESULT:
            if self.current_plot == payload:
                return True
        else:
            return False

        
    def plot(self, experiment, plot_name = None, **kwargs):
        
        if plot_name not in ["Morphology", 
                             "Autofluorescence", 
                             "Bleedthrough", 
                             "Bead Calibration", 
                             "Color Translation"]:
            raise util.CytoflowViewError("Which plot do you want?  Must be one "
                                         "of \"Morphology\", \"Autofluorescence\", "
                                         "\"Bleedthrough\", \"Bead Calibration\", "
                                         "or \"Color Translation\"")
                    
        if not self.op._blank_exp:
            raise util.CytoflowViewError("Must set at least the blank control file!")
        
        new_ex = self.op._blank_exp.clone()

        if plot_name == "Morphology":
            if not self._polygon_view:
                self._polygon_view = self.op._polygon_op.default_view()
            
            self._polygon_view.plot(new_ex, **kwargs)
            
            return
        else:
            new_ex = self.op._polygon_op.apply(new_ex)
                    
        if plot_name == "Autofluorescence":
            self.op._af_op.default_view().plot(new_ex, **kwargs)
            return
        else:
            new_ex = self.op._af_op.apply(new_ex)

        if plot_name == "Bleedthrough":
            self.op._bleedthrough_op.default_view().plot(new_ex, **kwargs)
            return
        else:
            new_ex = self.op._bleedthrough_op.apply(new_ex)
            
        if plot_name == "Bead Calibration":
            self.op._bead_calibration_op.default_view().plot(new_ex, **kwargs)
            return
        else:
            new_ex = self.op._bead_calibration_op.apply(new_ex)
            
        if plot_name == "Color Translation":
            self.op._color_translation_op.default_view().plot(new_ex, **kwargs)
示例#22
0
class TasbeCalibrationOp(PluginOpMixin):
    handler_factory = Callable(TasbeHandler)
    
    id = Constant('edu.mit.synbio.cytoflowgui.op_plugins.bleedthrough_piecewise')
    friendly_id = Constant("Quantitative Pipeline")
    name = Constant("TASBE")
    
    fsc_channel = DelegatesTo('_polygon_op', 'xchannel', estimate = True)
    ssc_channel = DelegatesTo('_polygon_op', 'ychannel', estimate = True)
    vertices = DelegatesTo('_polygon_op', 'vertices', estimate = True)
    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)
    units_list = List(_Unit, estimate = True)
    
    bead_peak_quantile = Int(80, estimate = True)
    bead_brightness_threshold = Float(100, estimate = True)
    bead_brightness_cutoff = util.FloatOrNone("", estimate = True)
    
    do_color_translation = Bool(estimate = True)
    to_channel = Str(estimate = True)
    translation_list = List(_TranslationControl, estimate = True)
    mixture_model = Bool(False, estimate = True)
    
    do_estimate = Event
    valid_model = Bool(False, status = True)
    do_exit = Event
    input_files = List(File)
    output_directory = Directory
        
    _blank_exp = Instance(Experiment, transient = True)
    _blank_exp_file = File(transient = True)
    _blank_exp_channels = List(Str, status = True)
    _polygon_op = Instance(PolygonOp, 
                           kw = {'name' : 'polygon',
                                 'xscale' : 'log', 
                                 'yscale' : 'log'}, 
                           transient = 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)
    
    status = Str(status = True)
    
    @on_trait_change('channels[], to_channel, do_color_translation', 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))
                
            if channel not in [unit.channel for unit in self.units_list]:
                self.units_list.append(_Unit(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)
            
        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)
                
        if self.do_color_translation:
            to_remove = []
            for unit in self.units_list:
                if unit.channel != self.to_channel:
                    to_remove.append(unit)
            
            for unit in to_remove:
                self.units_list.remove(unit)
                 
            self.translation_list = []
            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))
            
        self.changed = (Changed.ESTIMATE, ('bleedthrough_list', self.bleedthrough_list))            
        self.changed = (Changed.ESTIMATE, ('units_list', self.units_list))


    @on_trait_change('_polygon_op:vertices', post_init = True)
    def _polygon_changed(self, obj, name, old, new):
        self.changed = (Changed.ESTIMATE, (None, None))

    @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))
        
    @on_trait_change('units_list_items,units_list.+', post_init = True)
    def _units_changed(self, obj, name, old, new):
        self.changed = (Changed.ESTIMATE, ('units_list', self.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")
        
#         experiment = experiment.clone()

        if not self.fsc_channel:
            raise util.CytoflowOpError('fsc_channel',
                                       "Must set FSC channel")
            
        if not self.ssc_channel:
            raise util.CytoflowOpError('ssc_channel',
                                       "Must set SSC channel")
        
        if not self._polygon_op.vertices:
            raise util.CytoflowOpError(None, "Please draw a polygon around the "
                                             "single-cell population in the "
                                             "Morphology tab")            

        experiment = self._blank_exp.clone()
        experiment = self._polygon_op.apply(experiment)
        
        self._af_op.channels = self.channels
        self._af_op.blank_file = self.blank_file
        
        self._af_op.estimate(experiment, subset = "polygon == True")
        self.changed = (Changed.ESTIMATE_RESULT, "Autofluorescence")
        experiment = self._af_op.apply(experiment)
        
        self.status = "Estimating 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 = "polygon == True") 
        self.changed = (Changed.ESTIMATE_RESULT, "Bleedthrough")
        experiment = self._bleedthrough_op.apply(experiment)
        
        self.status = "Estimating 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        
        
        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)
        self.changed = (Changed.ESTIMATE_RESULT, "Bead Calibration")
        
        if self.do_color_translation:
            self.status = "Estimating color translation"

            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 = 'polygon == True')                                         
            
            self.changed = (Changed.ESTIMATE_RESULT, "Color Translation")
            
        self.status = "Done estimating"
        self.valid_model = True
        
        
    def should_clear_estimate(self, changed, payload):
        """
        Should the owning WorkflowItem clear the estimated model by calling
        op.clear_estimate()?  `changed` can be:
        - Changed.ESTIMATE -- the parameters required to call 'estimate()' (ie
          traits with estimate = True metadata) have changed
        - Changed.PREV_RESULT -- the previous WorkflowItem's result changed

         """
        if changed == Changed.ESTIMATE:
            name, _ = payload
            if name == 'fsc_channel' or name == 'ssc_channel':
                return False
                    
        return True
        
        
    def clear_estimate(self):
        self._af_op = AutofluorescenceOp()
        self._bleedthrough_op = BleedthroughLinearOp()
        self._bead_calibration_op = BeadCalibrationOp()
        self._color_translation_op = ColorTranslationOp()
        self.valid_model = False
        
        self.changed = (Changed.ESTIMATE_RESULT, self)
                        
    def should_apply(self, changed, payload):
        """
        Should the owning WorkflowItem apply this operation when certain things
        change?  `changed` can be:
        - Changed.OPERATION -- the operation's parameters changed
        - Changed.PREV_RESULT -- the previous WorkflowItem's result changed
        - Changed.ESTIMATE_RESULT -- the results of calling "estimate" changed

        """
        if changed == Changed.ESTIMATE_RESULT and \
            self.blank_file != self._blank_exp_file:
            return True
        
        elif changed == Changed.OPERATION:
            name, _ = payload
            if name == "output_directory":
                return False

            return True
        
        return False

        
        
    def apply(self, experiment):

        # this "apply" function is a little odd -- it does not return an Experiment because
        # it always the only WI/operation in the workflow.
        
        if self.blank_file != self._blank_exp_file:
            self._blank_exp = ImportOp(tubes = [Tube(file = self.blank_file)] ).apply()
            self._blank_exp_file = self.blank_file
            self._blank_exp_channels = self._blank_exp.channels
            self.changed = (Changed.PREV_RESULT, None)
            return
        
            
        out_dir = Path(self.output_directory)
        for path in self.input_files:
            in_file_path = Path(path)
            out_file_path = out_dir / in_file_path.name
            if out_file_path.exists():
                raise util.CytoflowOpError(None,
                                           "File {} already exists"
                                           .format(out_file_path))
                
        tubes = [Tube(file = path, conditions = {'filename' : Path(path).stem})
                 for path in self.input_files]
        
        for tube in tubes:
            self.status = "Converting " + Path(tube.file).stem
            experiment = ImportOp(tubes = [tube], conditions = {'filename' : 'category'}).apply()
            
            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)                                                
                    
            ExportFCS(path = self.output_directory,
                      by = ['filename'],
                      _include_by = False).export(experiment)
                      
        self.input_files = []
        self.status = "Done converting!"
    
    
    def default_view(self, **kwargs):
        return TasbeCalibrationView(op = self, **kwargs)
    
    def get_help(self):
        current_dir = os.path.abspath(__file__)
        help_dir = os.path.split(current_dir)[0]
        help_dir = os.path.join(help_dir, "help")
        
        help_file = None
        for klass in self.__class__.__mro__:
            mod = klass.__module__
            mod_html = mod + ".html"
            
            h = os.path.join(help_dir, mod_html)
            if os.path.exists(h):
                help_file = h
                break
                
        with open(help_file, encoding = 'utf-8') as f:
            help_html = f.read()
            
        return help_html
示例#23
0
class KMeansPluginView(PluginViewMixin):
    handler_factory = Callable(KMeansViewHandler)
    op = Instance(IOperation, fixed=True)
    subset = DelegatesTo('op', transient=True)
    by = DelegatesTo('op', status=True)
    xchannel = DelegatesTo('op', 'xchannel', transient=True)
    xscale = DelegatesTo('op', 'xscale', transient=True)
    ychannel = DelegatesTo('op', 'ychannel', transient=True)
    yscale = DelegatesTo('op', 'yscale', transient=True)
    plot_params = Instance(ScatterplotPlotParams, ())

    id = "edu.mit.synbio.cytoflowgui.op_plugins.kmeans"
    friendly_id = "KMeans"

    name = Constant("KMeans")

    def plot(self, experiment, **kwargs):
        KMeans2DView(op=self.op,
                     xchannel=self.xchannel,
                     ychannel=self.ychannel,
                     xscale=self.xscale,
                     yscale=self.yscale).plot(experiment, **kwargs)

    def plot_wi(self, wi):
        if wi.result:
            if self.plot_names:
                self.plot(
                    wi.result,
                    plot_name=self.current_plot**self.plot_params.trait_get())
            else:
                self.plot(wi.result, **self.plot_params.trait_get())
        else:
            if self.plot_names:
                self.plot(wi.previous_wi.result,
                          plot_name=self.current_plot,
                          **self.plot_params.trait_get())
            else:
                self.plot(wi.previous_wi.result,
                          **self.plot_params.trait_get())

    def enum_plots_wi(self, wi):
        if wi.result:
            try:
                return self.enum_plots(wi.result)
            except:
                return []
        else:
            try:
                return self.enum_plots(wi.previous_wi.result)
            except:
                return []

    def get_notebook_code(self, idx):
        view = KMeans2DView()
        view.copy_traits(self, view.copyable_trait_names())
        view.subset = self.subset
        plot_params_str = traits_str(self.plot_params)

        return dedent("""
        op_{idx}.default_view({traits}).plot(ex_{idx}{plot_params})
        """.format(traits=traits_str(view),
                   idx=idx,
                   plot_params=", " +
                   plot_params_str if plot_params_str else ""))
示例#24
0
class KMeansPluginOp(PluginOpMixin, KMeansOp):
    handler_factory = Callable(FlowPeaksHandler)

    # add "estimate" metadata
    xchannel = Str(estimate=True)
    ychannel = Str(estimate=True)
    xscale = util.ScaleEnum(estimate=True)
    yscale = util.ScaleEnum(estimate=True)
    num_clusters = util.PositiveCInt(2, allow_zero=False, estimate=True)

    by = List(Str, estimate=True)

    # bits to support the subset editor

    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('xchannel, ychannel')
    def _channel_changed(self, obj, name, old, new):
        self.channels = []
        self.scale = {}
        if self.xchannel:
            self.channels.append(self.xchannel)

            if self.xchannel in self.scale:
                del self.scale[self.xchannel]

            self.scale[self.xchannel] = self.xscale

        if self.ychannel:
            self.channels.append(self.ychannel)

            if self.ychannel in self.scale:
                del self.scale[self.ychannel]

            self.scale[self.ychannel] = self.yscale

    @on_trait_change('xscale, yscale')
    def _scale_changed(self, obj, name, old, new):
        self.scale = {}

        if self.xchannel:
            self.scale[self.xchannel] = self.xscale

        if self.ychannel:
            self.scale[self.ychannel] = self.yscale

    def default_view(self, **kwargs):
        return KMeansPluginView(op=self, **kwargs)

    def estimate(self, experiment):
        if not self.xchannel:
            raise util.CytoflowOpError('xchannel', "Must set X channel")

        if not self.ychannel:
            raise util.CytoflowOpError('ychannel', "Must set Y channel")

        try:
            super().estimate(experiment, subset=self.subset)
        except:
            raise
        finally:
            self.changed = (Changed.ESTIMATE_RESULT, self)

    def clear_estimate(self):
        self._kmeans.clear()
        self.changed = (Changed.ESTIMATE_RESULT, self)

    def get_notebook_code(self, idx):
        op = KMeansOp()
        op.copy_traits(self, op.copyable_trait_names())

        return dedent("""
        op_{idx} = {repr}
        
        op_{idx}.estimate(ex_{prev_idx}{subset})
        ex_{idx} = op_{idx}.apply(ex_{prev_idx})
        """.format(repr=repr(op),
                   idx=idx,
                   prev_idx=idx - 1,
                   subset=", subset = " +
                   repr(self.subset) if self.subset else ""))
示例#25
0
class TableFilter(HasPrivateTraits):
    """ Filter for items displayed in a table.
    """

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    # UI name of this filter (so the user can identify it in the UI)
    name = Str('Default filter')

    # Default name that can be automatically overridden
    _name = Str('Default filter')

    # A user-readable description of what kind of object satisfies the filter
    desc = Str('All items')

    # A callable function that returns whether the passed object is allowed
    # by the filter
    allowed = Callable(lambda object: True, transient=True)

    # Is the filter a template (i.e., non-deletable, non-editable)?
    template = Bool(False)

    #-------------------------------------------------------------------------
    #  Class constants:
    #-------------------------------------------------------------------------

    # Traits that are ignored by the _anytrait_changed() handler
    ignored_traits = ['_name', 'template', 'desc']

    #-------------------------------------------------------------------------
    #  Traits view definitions:
    #-------------------------------------------------------------------------

    traits_view = View(
        'name{Filter name}',
        '_',
        Include('filter_view'),
        title='Edit Filter',
        width=0.2,
        buttons=[
            'OK', 'Cancel',
            Action(name='Help',
                   action='show_help',
                   defined_when="ui.view_elements.content['filter_view']"
                   ".help_id != ''")
        ])

    searchable_view = View(
        [[Include('search_view'), '|[]'], ['handler.status~', '|[]<>'],
         [
             'handler.find_next`Find the next matching item`',
             'handler.find_previous`Find the previous matching item`',
             'handler.select`Select all matching items`',
             'handler.OK`Exit search`', '-<>'
         ], '|<>'],
        title='Search for',
        kind='livemodal',
        width=0.25)

    search_view = Group(Include('filter_view'))

    filter_view = Group()

    #-------------------------------------------------------------------------
    #  Returns whether a specified object meets the filter/search criteria:
    #  (Should normally be overridden)
    #-------------------------------------------------------------------------

    def filter(self, object):
        """ Returns whether a specified object meets the filter or search
        criteria.
        """
        return self.allowed(object)

    #-------------------------------------------------------------------------
    #  Returns a user readable description of what kind of object will
    #  satisfy the filter:
    #  (Should normally be overridden):
    #-------------------------------------------------------------------------

    def description(self):
        """ Returns a user-readable description of what kind of object
        satisfies the filter.
        """
        return self.desc

    #-------------------------------------------------------------------------
    #  Edits the contents of the filter:
    #-------------------------------------------------------------------------

    def edit(self, object):
        """ Edits the contents of the filter.
        """
        return self.edit_traits(view=self.edit_view(object), kind='livemodal')

    def edit_view(self, object):
        """ Return a view to use for editing the filter.

        The ''object'' parameter is a sample object for the table that the
        filter will be applied to. It is supplied in case the filter needs to
        extract data or metadata from the object. If the table is empty, the
        ''object'' argument is None.
        """
        return None

    #-------------------------------------------------------------------------
    #  'object' interface:
    #-------------------------------------------------------------------------

    def __str__(self):
        return self.name

    #-------------------------------------------------------------------------
    #  Event handlers:
    #-------------------------------------------------------------------------

    def _anytrait_changed(self, name, old, new):
        if ((name not in self.ignored_traits)
                and ((self.name == self._name) or (self.name == ''))):
            self.name = self._name = self.description()
示例#26
0
class ObjectColumn(TableColumn):
    """ A column for editing objects.
    """

    # -------------------------------------------------------------------------
    #  Trait definitions:
    # -------------------------------------------------------------------------

    #: Name of the object trait associated with this column:
    name = Str()

    #: Column label to use for this column:
    label = Property()

    #: Trait editor used to edit the contents of this column:
    editor = Instance(EditorFactory)

    #: The editor style to use to edit the contents of this column:
    style = EditorStyle

    #: Format string to apply to column values:
    format = Str("%s")

    #: Format function to apply to column values:
    format_func = Callable()

    # -------------------------------------------------------------------------
    #  Trait view definitions:
    # -------------------------------------------------------------------------

    traits_view = View(
        [
            ["name", "label", "type", "|[Column Information]"],
            [
                "horizontal_alignment{Horizontal}@",
                "vertical_alignment{Vertical}@",
                "|[Alignment]",
            ],
            ["editable", "9", "droppable", "9", "visible", "-[Options]>"],
            "|{Column}",
        ],
        [
            [
                "text_color@",
                "cell_color@",
                "read_only_cell_color@",
                "|[UI Colors]",
            ],
            "|{Colors}",
        ],
        [["text_font@", "|[Font]<>"], "|{Font}"],
        ["menu@", "|{Menu}"],
        ["editor@", "|{Editor}"],
    )

    def _get_label(self):
        """ Gets the label of the column.
        """
        if self._label is not None:
            return self._label
        return user_name_for(self.name)

    def _set_label(self, label):
        old, self._label = self._label, label
        if old != label:
            self.trait_property_changed("label", old, label)

    def get_raw_value(self, object):
        """ Gets the unformatted value of the column for a specified object.
        """
        try:
            return xgetattr(self.get_object(object), self.name)
        except Exception as e:
            from traitsui.api import raise_to_debug

            raise_to_debug()
            return None

    def get_value(self, object):
        """ Gets the formatted value of the column for a specified object.
        """
        try:
            if self.format_func is not None:
                return self.format_func(self.get_raw_value(object))

            return self.format % (self.get_raw_value(object),)
        except:
            logger.exception(
                "Error occurred trying to format a %s value"
                % self.__class__.__name__
            )
            return "Format!"

    def get_drag_value(self, object):
        """Returns the drag value for the column.
        """
        return self.get_raw_value(object)

    def set_value(self, object, value):
        """ Sets the value of the column for a specified object.
        """
        target, name = self.target_name(object)
        setattr(target, name, value)

    def get_editor(self, object):
        """ Gets the editor for the column of a specified object.
        """
        if self.editor is not None:
            return self.editor

        target, name = self.target_name(object)

        return target.base_trait(name).get_editor()

    def get_style(self, object):
        """ Gets the editor style for the column of a specified object.
        """
        return self.style

    def key(self, object):
        """ Returns the value to use for sorting.
        """
        return self.get_raw_value(object)

    def is_droppable(self, object, value):
        """ Returns whether a specified value is valid for dropping on the
            column for a specified object.
        """
        if self.droppable:
            try:
                target, name = self.target_name(object)
                target.base_trait(name).validate(target, name, value)
                return True
            except:
                pass

        return False

    def target_name(self, object):
        """ Returns the target object and name for the column.
        """
        object = self.get_object(object)
        name = self.name
        col = name.rfind(".")
        if col < 0:
            return (object, name)

        return (xgetattr(object, name[:col]), name[col + 1 :])
示例#27
0
class PolygonPluginOp(PolygonOp, PluginOpMixin):
    handler_factory = Callable(PolygonHandler)
    
    def default_view(self, **kwargs):
        return PolygonSelectionView(op = self, **kwargs)
示例#28
0
class LC(HasTraits):
    '''Loading case class
    '''

    reader = WeakRef

    lcc_table = WeakRef

    # name of the file containing the stress resultants
    #
    file_name = Str(input=True)

    # data filter (used to hide unwanted values, e.g. high sigularities etc.)
    #
    data_filter = Callable(input=True)

    # name of the loading case
    #
    name = Str(input=True)

    # category of the loading case
    #
    category = Enum('dead-load',
                    'additional dead-load',
                    'imposed-load',
                    input=True)

    # list of keys specifying the names of the loading cases
    # that can not exist at the same time, i.e. which are exclusive to each other
    #
    exclusive_to = List(Str, input=True)

    def _exclusive_to_default(self):
        return []

    # combination factors (need to be defined in case of imposed loads)
    #
    psi_0 = Float(input=True)
    psi_1 = Float(input=True)
    psi_2 = Float(input=True)

    # security factors ULS
    #
    gamma_fav = Float(input=True)

    def _gamma_fav_default(self):
        if self.category == 'dead-load':
            return 1.00
        if self.category == 'additional dead-load':
            return 0.00
        if self.category == 'imposed-load':
            return 0.00

    gamma_unf = Float(input=True)

    def _gamma_unf_default(self):
        if self.category == 'dead-load':
            return 1.35
        if self.category == 'additional dead-load':
            return 1.35
        if self.category == 'imposed-load':
            return 1.50

    # security factors SLS:
    # (used to distinguish combinations where imposed-loads
    # or additional-dead-loads are favorable or unfavorable.)
    #
    gamma_fav_SLS = Float(input=True)

    def _gamma_fav_SLS_default(self):
        if self.category == 'dead-load':
            return 1.00
        elif self.category == 'additional dead-load' or \
             self.category == 'imposed-load':
            return 0.00

    gamma_unf_SLS = Float(input=True)

    def _gamma_unf_SLS_default(self):
        return 1.00

    # original state data (before filtering)
    #
    state_data_orig = Property(Dict,
                               depends_on='file_name, lcc_table.data_dir')

    @cached_property
    def _get_state_data_orig(self):
        return self.reader.read_state_data(self.file_name)

    # state data (after filtering)
    #
    state_data_dict = Property(
        Dict, depends_on='file_name, data_filter, lcc_table.data_dir')

    @cached_property
    def _get_state_data_dict(self):
        d = {}
        for k, arr in self.state_data_orig.items():
            d[k] = self.data_filter(self.lcc_table, arr)
        return d

    # if reader == 'RFEM':
    #sr_columns = List(['mx', 'my', 'mxy', 'nx', 'ny', 'nxy'])
    # if reader == 'InfoCAD':
    #sr_columns = List(['mx', 'my', 'mxy', 'nx', 'ny', 'nxy', 'ux_elem', 'uy_elem', 'uz_elem'])
    # if reader == 'InfoCADRxyz':
    sr_columns = List(['Rx', 'Ry', 'Rz', 'Mx', 'My', 'Mz'])

    sr_arr = Property(Array)

    def _get_sr_arr(self):
        '''return the stress resultants of the loading case
        as stack of all sr-column arrays.
        '''
        sd_dict = self.state_data_dict
        return hstack([sd_dict[sr_key] for sr_key in self.sr_columns])
示例#29
0
 class MyNewCallable2(HasTraits):
     value = Callable(pow, allow_none=True)
     empty_callable = Callable()
     a_non_none_union = Union(Callable(allow_none=False), Int)
     a_allow_none_union = Union(Callable(allow_none=True), Int)
示例#30
0
 class MyNewCallable(HasTraits):
     value = Callable(default_value=pow, allow_none=False)