Ejemplo n.º 1
0
    def __init__(self, title, masterWindow=None, weight=True, minsize=(900, 500),
                 icon=Icon.SCIPION_ICON, **kwargs):
        Window.__init__(self, title, masterWindow, weight=weight, 
                        icon=icon, minsize=minsize, enableQueue=True, **kwargs)
        
        content = tk.Frame(self.root)
        content.columnconfigure(0, weight=1)
        content.rowconfigure(1, weight=1)
        content.grid(row=0, column=0, sticky='news')
        self.content = content

        if getattr(self, 'menuCfg', None):
            Window.createMainMenu(self, self.menuCfg)
        
        self.header = self.createHeaderFrame(content)
        self.header.grid(row=0, column=0, sticky='new')
        
        self.footer = tk.Frame(content, bg='white')
        self.footer.grid(row=1, column=0, sticky='news') 
        
        self.view, self.viewWidget = None, None
        
        self.viewFuncs = {VIEW_PROJECTS: ProjectsView,
                          VIEW_PROTOCOLS: ProtocolsView,
                          VIEW_DATA: ProjectDataView,
                          }
Ejemplo n.º 2
0
 def __init__(self, title, masterWindow=None, weight=True, minsize=(900, 500),
              icon="scipion_bn.xbm", **args):
     Window.__init__(self, title, masterWindow, weight=weight, 
                     icon=icon, minsize=minsize, enableQueue=True)
     
     content = tk.Frame(self.root)
     content.columnconfigure(0, weight=1)
     content.rowconfigure(1, weight=1)
     content.grid(row=0, column=0, sticky='news')
     self.content = content
     
     Window.createMainMenu(self, self.menuCfg)
     
     self.header = self.createHeaderFrame(content)
     self.header.grid(row=0, column=0, sticky='new')
     
     self.footer = tk.Frame(content, bg='white')
     self.footer.grid(row=1, column=0, sticky='news') 
     
     self.view, self.viewWidget = None, None
     
     self.viewFuncs = {VIEW_PROJECTS: ProjectsView,
                       VIEW_PROTOCOLS: ProtocolsView,
                       VIEW_DATA: ProjectDataView,
                       }
Ejemplo n.º 3
0
    def __init__(self, title, parent=None, weight=True, minsize=(400, 150),
                 icon="scipion_bn.xbm", **args):
        """
         We assume the parent should be of ProjectsView
        """
        Window.__init__(self, title, parent.windows, weight=weight,
                        icon=icon, minsize=minsize, enableQueue=True)

        self.parent = parent
        self.projectsPath = self.parent.manager.PROJECTS
        self.projName = tk.StringVar()
        self.projName.set('')
        self.projLocation = tk.StringVar()
        self.projLocation.set(self.projectsPath)

        content = tk.Frame(self.root)
        content.columnconfigure(0, weight=1)
        content.columnconfigure(1, weight=1)
        content.config(bg='white')
        content.grid(row=0, column=0, sticky='news',
                       padx=5, pady=5)
        labelName = tk.Label(content, text=Message.LABEL_PROJECT, bg='white', bd=0)
        labelName.grid(row=0, column=0, sticky='nw', padx=5, pady=5)
        entryName = tk.Entry(content, bg=cfgEntryBgColor, width=20, textvariable=self.projName)
        entryName.grid(row=0, column=1, sticky='nw', padx=5, pady=5)

        labelCheck = tk.Label(content, text="Use default location", bg='white', bd=0)
        labelCheck.grid(row=1, column=0, sticky='nw', padx=5, pady=5)
        self.tkCheckVar = tk.IntVar()
        btnCheck = tk.Checkbutton(content, variable=self.tkCheckVar, bg='white', bd=0)
        btnCheck.grid(row=1, column=1, sticky='nw', padx=5, pady=5)

        self.browseFrame = tk.Frame(content, bg='white')
        #self.browseFrame.columnconfigure(1, weight=1)
        self.browseFrame.grid(row=2, column=0, padx=0, pady=0, columnspan=2, sticky='nw')
        self.entryBrowse = tk.Entry(self.browseFrame, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation)
        self.entryBrowse.grid(row=0, column=0, sticky='nw', padx=5, pady=5)
        self.btnBrowse = IconButton(self.browseFrame, 'Browse', Icon.ACTION_BROWSE, command=self._browsePath)
        self.btnBrowse.grid(row=0, column=1, sticky='e', padx=5, pady=5)

        self.initial_focus = entryName
        self.tkCheckVar.trace('w', self._onVarChanged)
        btnCheck.select()

        btnFrame = tk.Frame(content)
        btnFrame.columnconfigure(0, weight=1)
        btnFrame.grid(row=3, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2)
        btnFrame.config(bg='white')

        # Create buttons
        btnSelect = HotButton(btnFrame, 'Create', Icon.BUTTON_SELECT, command=self._select)
        btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5)
        btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close)
        btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
Ejemplo n.º 4
0
    def __init__(self, title, parent=None, weight=True, minsize=(400, 110),
                 icon="scipion_bn.xbm", **args):
        """
         We assume the parent should be of ProjectsView
        """
        Window.__init__(self, title, parent.windows, weight=weight,
                        icon=icon, minsize=minsize, enableQueue=True)
        self.root['background'] = 'white'

        self.parent = parent
        self.projectsPath = self.parent.manager.PROJECTS
        self.projName = tk.StringVar()
        self.projName.set('')
        self.projLocation = tk.StringVar()
        self.projLocation.set(self.projectsPath)

        content = tk.Frame(self.root)
        content.columnconfigure(0, weight=1)
        content.columnconfigure(1, weight=3)
        content.config(bg='white')
        content.grid(row=0, column=0, sticky='news', padx=5, pady=5)

        #  Project name line
        labelName = tk.Label(content, text=Message.LABEL_PROJECT + ' name', bg='white', bd=0)
        labelName.grid(row=0, sticky=tk.W, padx=5, pady=5)
        entryName = tk.Entry(content, bg=cfgEntryBgColor, width=20, textvariable=self.projName)
        entryName.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=5, pady=5)

        # Project location line
        labelLocation = tk.Label(content, text=Message.LABEL_PROJECT + ' location', bg='white', bd=0)
        labelLocation.grid(row=1, column=0, sticky='nw', padx=5, pady=5)

        self.entryBrowse = tk.Entry(content, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation)
        self.entryBrowse.grid(row=1, column=1, sticky='nw', padx=5, pady=5)
        self.btnBrowse = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0, command=self._browsePath)
        self.btnBrowse.grid(row=1, column=2, sticky='e', padx=5, pady=5)

        self.initial_focus = entryName

        btnFrame = tk.Frame(content)
        btnFrame.columnconfigure(0, weight=1)
        btnFrame.grid(row=2, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2)
        btnFrame.config(bg='white')

        # Create buttons
        btnSelect = HotButton(btnFrame, 'Create', Icon.BUTTON_SELECT, command=self._select)
        btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5)
        btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close)
        btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
Ejemplo n.º 5
0
 def visualizeClasses(self, e=None):
     classTemplate = "class_%03d"
     averages = '%03d@' + self.protocol._getFileName('averages')
     
     def getInfo2(level, classNo):
         return classTemplate % classNo, averages % classNo
     
     node = self.protocol.buildDendrogram()
     
     g = Graph(root=node)
     self.graph = g
            
     self.win = Window("Select classes", self.formWindow, minsize=(1000, 600))
     root = self.win.root
     canvas = Canvas(root)
     canvas.grid(row=0, column=0, sticky='nsew')
     root.grid_columnconfigure(0, weight=1)
     root.grid_rowconfigure(0, weight=1) 
     
     self.buttonframe = tk.Frame(root)
     self.buttonframe.grid(row=2, column=0, columnspan=2)  
     self.win.createCloseButton(self.buttonframe).grid(row=0, column=0, sticky='n', padx=5, pady=5) 
     saveparticlesbtn = HotButton(self.buttonframe, "Particles", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Particles', self.getSelectedNodesCount(2)))
     saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5)  
     btn = HotButton(self.buttonframe, "Classes", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Classes', self.getSelectedNodesCount(1)))
     btn.grid(row=0, column=2, sticky='n', padx=5, pady=5)
         
     lt = LevelTree(g)
     lt.DY = 135 # TODO: change in percent of the image size
     lt.setCanvas(canvas)
     lt.paint(self._createNode, maxLevel=self.maxLevel.get()-1)
     canvas.updateScrollRegion()
     
     return [self.win]
Ejemplo n.º 6
0
    def visualizeClasses(self, e=None):
        classTemplate = "class_%03d"
        averages = '%03d@' + self.protocol._getFileName('averages')

        def getInfo2(level, classNo):
            return classTemplate % classNo, averages % classNo

        node = self.protocol.buildDendrogram(writeAverages=False)

        g = Graph(root=node)
        self.graph = g

        self.win = Window("Select classes",
                          self.formWindow,
                          minsize=(1000, 600))
        root = self.win.root
        canvas = Canvas(root)
        canvas.grid(row=0, column=0, sticky='nsew')
        root.grid_columnconfigure(0, weight=1)
        root.grid_rowconfigure(0, weight=1)

        self.buttonframe = tk.Frame(root)
        self.buttonframe.grid(row=2, column=0, columnspan=2)
        self.win.createCloseButton(self.buttonframe).grid(row=0,
                                                          column=0,
                                                          sticky='n',
                                                          padx=5,
                                                          pady=5)
        saveparticlesbtn = HotButton(self.buttonframe,
                                     "Particles",
                                     Icon.PLUS_CIRCLE,
                                     command=self._askCreateParticles)
        saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5)
        btn = HotButton(self.buttonframe,
                        "Classes",
                        Icon.PLUS_CIRCLE,
                        command=self._askCreateClasses)
        btn.grid(row=0, column=2, sticky='n', padx=5, pady=5)

        lt = LevelTree(g)
        lt.DY = 135  # TODO: change in percent of the image size
        lt.setCanvas(canvas)
        lt.paint(self._createNode, maxLevel=self.maxLevel.get() - 1)
        canvas.updateScrollRegion()

        return [self.win]
Ejemplo n.º 7
0
    def __init__(self,
                 title,
                 parent=None,
                 weight=True,
                 minsize=(400, 150),
                 icon="scipion_bn.xbm",
                 **args):
        """
         We assume the parent should be of ProjectsView
        """
        Window.__init__(self,
                        title,
                        parent.windows,
                        weight=weight,
                        icon=icon,
                        minsize=minsize,
                        enableQueue=True)

        self.parent = parent
        self.projectsPath = self.parent.manager.PROJECTS
        self.projName = tk.StringVar()
        self.projName.set('')
        self.projLocation = tk.StringVar()
        self.projLocation.set(self.projectsPath)

        content = tk.Frame(self.root)
        content.columnconfigure(0, weight=1)
        content.columnconfigure(1, weight=1)
        content.config(bg='white')
        content.grid(row=0, column=0, sticky='news', padx=5, pady=5)
        labelName = tk.Label(content,
                             text=Message.LABEL_PROJECT,
                             bg='white',
                             bd=0)
        labelName.grid(row=0, column=0, sticky='nw', padx=5, pady=5)
        entryName = tk.Entry(content,
                             bg=cfgEntryBgColor,
                             width=20,
                             textvariable=self.projName)
        entryName.grid(row=0, column=1, sticky='nw', padx=5, pady=5)

        labelCheck = tk.Label(content,
                              text="Use default location",
                              bg='white',
                              bd=0)
        labelCheck.grid(row=1, column=0, sticky='nw', padx=5, pady=5)
        self.tkCheckVar = tk.IntVar()
        btnCheck = tk.Checkbutton(content,
                                  variable=self.tkCheckVar,
                                  bg='white',
                                  bd=0)
        btnCheck.grid(row=1, column=1, sticky='nw', padx=5, pady=5)

        self.browseFrame = tk.Frame(content, bg='white')
        #self.browseFrame.columnconfigure(1, weight=1)
        self.browseFrame.grid(row=2,
                              column=0,
                              padx=0,
                              pady=0,
                              columnspan=2,
                              sticky='nw')
        self.entryBrowse = tk.Entry(self.browseFrame,
                                    bg=cfgEntryBgColor,
                                    width=40,
                                    textvariable=self.projLocation)
        self.entryBrowse.grid(row=0, column=0, sticky='nw', padx=5, pady=5)
        self.btnBrowse = IconButton(self.browseFrame,
                                    'Browse',
                                    Icon.ACTION_BROWSE,
                                    command=self._browsePath)
        self.btnBrowse.grid(row=0, column=1, sticky='e', padx=5, pady=5)

        self.initial_focus = entryName
        self.tkCheckVar.trace('w', self._onVarChanged)
        btnCheck.select()

        btnFrame = tk.Frame(content)
        btnFrame.columnconfigure(0, weight=1)
        btnFrame.grid(row=3,
                      column=0,
                      sticky='sew',
                      padx=5,
                      pady=(0, 5),
                      columnspan=2)
        btnFrame.config(bg='white')

        # Create buttons
        btnSelect = HotButton(btnFrame,
                              'Create',
                              Icon.BUTTON_SELECT,
                              command=self._select)
        btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5)
        btnCancel = Button(btnFrame,
                           'Cancel',
                           Icon.BUTTON_CANCEL,
                           command=self.close)
        btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
Ejemplo n.º 8
0
    def __init__(self, title, parent=None, weight=True, minsize=(400, 150),
                 icon="scipion_bn.xbm", **args):
        """
         We assume the parent should be ProjectsView
        """
        Window.__init__(self, title, parent.windows, weight=weight,
                        icon=icon, minsize=minsize, enableQueue=True)
        self.root['background'] = 'white'
        self.parent = parent
        # Dirty hack, need to add a slash for the explorer to pick up the right default path.
        self.projectsPath = getHomePath()+"/"
        self.projLocation = tk.StringVar()
        self.projLocation.set(self.projectsPath)

        self.projName = tk.StringVar()
        self.projName.set('')

        self.searchLocation = tk.StringVar()
        self.searchLocation.set('')

        content = tk.Frame(self.root)
        content.columnconfigure(0, weight=1)
        content.columnconfigure(1, weight=1)
        content.config(bg='white')
        content.grid(row=0, column=0, sticky='news',
                       padx=5, pady=5)

        # Path explorer
        labelProjectLocation = tk.Label(content, text="Project location", bg='white', bd=0)
        labelProjectLocation.grid(row=0, column=0, sticky='nw', padx=5, pady=5)

        self.entryBrowse = tk.Entry(content, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation)
        self.entryBrowse.grid(row=0, column=1, sticky='nw', padx=5, pady=5)
        self.btnBrowse = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0,
                                    command=self._browseProjectLocation)
        self.btnBrowse.grid(row=0, column=2, sticky='e', padx=5, pady=5)

        # Copy files check
        labelCheck = tk.Label(content, text="Copy project", bg='white', borderwidth=0)
        labelCheck.grid(row=1, column=0, sticky='nw', padx=5, pady=5)

        self.tkCheckVar = tk.IntVar()
        btnCheck = tk.Checkbutton(content, variable=self.tkCheckVar, highlightthickness=0, activebackground='white',
                                  bg='white', bd=0)
        btnCheck.grid(row=1, column=1, sticky='nw', padx=0, pady=5)

        btnCopyHelp = IconButton(content, Message.LABEL_BUTTON_HELP, Icon.ACTION_HELP, highlightthickness=0,
             command=lambda: self.showInfo('If checked, \"Project location\" will be copied. Otherwise a soft link to it will be created.'))
        btnCopyHelp.grid(row=1, column=3, sticky='e', padx=2, pady=2)

        # Project name
        labelName = tk.Label(content, text='Project name (Optional)', bg='white', bd=0)
        labelName.grid(row=2, column=0, sticky='nw', padx=5, pady=5)
        entryName = tk.Entry(content, bg='white', width=20, textvariable=self.projName)
        entryName.grid(row=2, column=1, sticky='nw', padx=5, pady=5)

        # Path to search for raw data and restore broken links.
        labelSearchLocation = tk.Label(content, text="Raw files location (Optional)", bg='white', bd=0)
        labelSearchLocation.grid(row=3, column=0, sticky='nw', padx=5, pady=5)

        self.entrySearchLocation = tk.Entry(content, bg='white', width=40, textvariable=self.searchLocation)
        self.entrySearchLocation.grid(row=3, column=1, sticky='nw', padx=5, pady=5)
        self.btnSearch = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0, command=self._browseSearchLocation)
        self.btnSearch.grid(row=3, column=2, sticky='e', padx=5, pady=5)
        btnSearchHelp = IconButton(content, Message.LABEL_BUTTON_HELP, Icon.ACTION_HELP, highlightthickness=0,
             command=lambda: self.showInfo('Optional: Folder where raw files, binaries (movies, migcrographs,..) can be found. Used to repair broken links.'))
        btnSearchHelp.grid(row=3, column=3, sticky='e', padx=2, pady=2)

        self.initial_focus = entryName
        btnCheck.select()

        btnFrame = tk.Frame(content)
        btnFrame.columnconfigure(0, weight=1)
        btnFrame.grid(row=4, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2)
        btnFrame.config(bg='white')

        # Create buttons
        btnSelect = HotButton(btnFrame, 'Import', Icon.BUTTON_SELECT, command=self._select)
        btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5)
        btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close)
        btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
Ejemplo n.º 9
0
class SpiderViewerWard(SpiderViewerClassify):
    _targets = [SpiderProtClassifyWard]
    _label = "viewer ward"
    
    def _defineParams(self, form):
        SpiderViewerClassify._defineParams(self, form)

        self.groupClass.addParam('maxLevel', IntParam, default=4,
                      label='Maximum level',
                      help='Maximum level of classes to show')


    def visualizeClasses(self, e=None):
        classTemplate = "class_%03d"
        averages = '%03d@' + self.protocol._getFileName('averages')
        
        def getInfo2(level, classNo):
            return classTemplate % classNo, averages % classNo
        
        node = self.protocol.buildDendrogram()
        
        g = Graph(root=node)
        self.graph = g
               
        self.win = Window("Select classes", self.formWindow, minsize=(1000, 600))
        root = self.win.root
        canvas = Canvas(root)
        canvas.grid(row=0, column=0, sticky='nsew')
        root.grid_columnconfigure(0, weight=1)
        root.grid_rowconfigure(0, weight=1) 
        
        self.buttonframe = tk.Frame(root)
        self.buttonframe.grid(row=2, column=0, columnspan=2)  
        self.win.createCloseButton(self.buttonframe).grid(row=0, column=0, sticky='n', padx=5, pady=5) 
        saveparticlesbtn = HotButton(self.buttonframe, "Particles", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Particles', self.getSelectedNodesCount(2)))
        saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5)  
        btn = HotButton(self.buttonframe, "Classes", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Classes', self.getSelectedNodesCount(1)))
        btn.grid(row=0, column=2, sticky='n', padx=5, pady=5)
            
        lt = LevelTree(g)
        lt.DY = 135 # TODO: change in percent of the image size
        lt.setCanvas(canvas)
        lt.paint(self._createNode, maxLevel=self.maxLevel.get()-1)
        canvas.updateScrollRegion()
        
        return [self.win]
    
    def askCreateSubset(self, output, size):
        
        headerLabel = 'Are you sure you want to create a new set of %s with %s %s?'%(output, size, 'element' if size == 1 else 'elements')
        runname =  askString('Question','Run name:', self.win.getRoot(), 30, defaultValue='ProtUserSubSet', headerLabel=headerLabel)
        if runname:
            createFunc = getattr(self, 'save' + output)
            createFunc(runname)
        
        
    def _createSubsetProtocol(self, createOutputFunc, label=None):
        """ Create a subset of classes or particles. """
        try:
            project = self.getProject()
            prot = project.newProtocol(ProtUserSubSet)
            prot.setObjLabel(label)
            prot.inputObject.set(self.protocol)
            project._setupProtocol(prot)
            prot.makePathsAndClean()
            createOutputFunc(prot)
            prot.setStatus(STATUS_FINISHED)
            project._storeProtocol(prot)
            #self.project.launchProtocol(prot, wait=True)

        except Exception, ex:
            import traceback
            traceback.print_exc()    
            self.win.showError(str(ex))
Ejemplo n.º 10
0
class SpiderViewerWard(SpiderViewerClassify):
    """ Visualization of Spider - classify Ward protocol results. """

    _targets = [SpiderProtClassifyWard]
    _label = "viewer ward"

    def _defineParams(self, form):
        SpiderViewerClassify._defineParams(self, form)

        self.groupClass.addParam('maxLevel',
                                 IntParam,
                                 default=4,
                                 label='Maximum level',
                                 help='Maximum level of classes to show')

    def visualizeClasses(self, e=None):
        classTemplate = "class_%03d"
        averages = '%03d@' + self.protocol._getFileName('averages')

        def getInfo2(level, classNo):
            return classTemplate % classNo, averages % classNo

        node = self.protocol.buildDendrogram(writeAverages=False)

        g = Graph(root=node)
        self.graph = g

        self.win = Window("Select classes",
                          self.formWindow,
                          minsize=(1000, 600))
        root = self.win.root
        canvas = Canvas(root)
        canvas.grid(row=0, column=0, sticky='nsew')
        root.grid_columnconfigure(0, weight=1)
        root.grid_rowconfigure(0, weight=1)

        self.buttonframe = tk.Frame(root)
        self.buttonframe.grid(row=2, column=0, columnspan=2)
        self.win.createCloseButton(self.buttonframe).grid(row=0,
                                                          column=0,
                                                          sticky='n',
                                                          padx=5,
                                                          pady=5)
        saveparticlesbtn = HotButton(self.buttonframe,
                                     "Particles",
                                     Icon.PLUS_CIRCLE,
                                     command=self._askCreateParticles)
        saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5)
        btn = HotButton(self.buttonframe,
                        "Classes",
                        Icon.PLUS_CIRCLE,
                        command=self._askCreateClasses)
        btn.grid(row=0, column=2, sticky='n', padx=5, pady=5)

        lt = LevelTree(g)
        lt.DY = 135  # TODO: change in percent of the image size
        lt.setCanvas(canvas)
        lt.paint(self._createNode, maxLevel=self.maxLevel.get() - 1)
        canvas.updateScrollRegion()

        return [self.win]

    def _askCreateParticles(self):
        self._askCreateSubset('Particles', self.getSelectedNodesCount(2))

    def _askCreateClasses(self):
        self._askCreateSubset('Classes', self.getSelectedNodesCount(1))

    def _askCreateSubset(self, output, size):

        if self._selectionOverlap():
            self.win.showError("Classes could not overlap in the tree.")
            return

        s = '' if size == 1 else 's'
        headerLabel = 'Are you sure you want to create a new set of ' \
                      ' %s with %s element%s?' % (output, size, s)
        runname = askString('Question',
                            'Run name:',
                            self.win.getRoot(),
                            30,
                            defaultValue='ProtUserSubSet',
                            headerLabel=headerLabel)
        if runname:
            createFunc = getattr(self, 'save' + output)
            createFunc(runname)

    def _createSubsetProtocol(self, createOutputFunc, label=None):
        """ Create a subset of classes or particles. """
        try:
            project = self.getProject()
            prot = project.newProtocol(ProtUserSubSet)
            prot.setObjLabel(label)
            prot.inputObject.set(self.protocol)
            project._setupProtocol(prot)
            prot.makePathsAndClean()
            createOutputFunc(prot)
            prot.setStatus(STATUS_FINISHED)
            project._storeProtocol(prot)
            #self.project.launchProtocol(prot, wait=True)

        except Exception, ex:
            import traceback
            traceback.print_exc()
            self.win.showError(str(ex))