示例#1
0
    def __init__(self,
                 requires=None,
                 provides=None,
                 parent=None,
                 project=None,
                 enabled=True,
                 pref_manager=None):
        ## The package which contains the collection node.
        self.parentPackage = parent

        # The preferences manager of the node.
        if pref_manager is None:
            self.pref_manager = PreferencesManager()
        else:
            self.pref_manager = pref_manager

        ## The node's enabled state.
        #
        # Mark the collection node as enabled or disabled.
        self.enabled = enabled

        ## The collection node's output.
        #
        # The output dictionary can be used to pass parameters to the next
        # node in the collection.
        self.output = {}

        # The variables required by the node.
        self.requires = requires

        # The variables provided by the node.
        self.provides = provides

        ## The current pSysmon project.
        #
        self.project = project

        ## The parent collection holding the node instance.
        #
        self.parentCollection = None

        # If the node is executed in a collection thread a thread ID is
        # assigned.
        self.procName = None
示例#2
0
    def __init__(self,
                 name,
                 mode,
                 category,
                 tags,
                 enabled=True,
                 docEntryPoint=None,
                 parentStack=None):
        ''' The constructor

        '''
        # The name of the stack node.
        self.name = name

        # The mode of the stack node (editable, uneditable).
        self.mode = mode

        # The category of the stack node.
        self.category = category

        # The tags assigned to the stack node.
        self.tags = tags

        # The result of the processing node.
        self.results = {}

        # The preferences of the stack node.
        self.pref_manager = PreferencesManager()

        # The entry point of the documentation of the node.
        self.docEntryPoint = docEntryPoint

        # The parent stack holding the stack node.
        self.parentStack = parentStack

        # The enabled state of the node.
        self.enabled = enabled
示例#3
0
class ProcessingNode(object):
    ''' The ProcessingNode class.

    The processing node gets data from the processing stack, does some computation with 
    this data and returns the processed data to the processing stack.
    The type of data needed has to be defined by the ProcessingNode. Currently the processing 
    of obspy Stream objects is supported.
    The return value has to be of the same type as the data passed to the processing node.
    '''
    # The class to which the processing node is assigned to.
    # User *common* for nodes which can be used by every class.
    # Nodes with a specified nodeClass usually depend on some special
    # variables which have to be passed to them using the variable kwargs
    # argument.
    nodeClass = 'common'

    def __init__(self,
                 name,
                 mode,
                 category,
                 tags,
                 enabled=True,
                 docEntryPoint=None,
                 parentStack=None):
        ''' The constructor

        '''
        # The name of the stack node.
        self.name = name

        # The mode of the stack node (editable, uneditable).
        self.mode = mode

        # The category of the stack node.
        self.category = category

        # The tags assigned to the stack node.
        self.tags = tags

        # The result of the processing node.
        self.results = {}

        # The preferences of the stack node.
        self.pref_manager = PreferencesManager()

        # The entry point of the documentation of the node.
        self.docEntryPoint = docEntryPoint

        # The parent stack holding the stack node.
        self.parentStack = parentStack

        # The enabled state of the node.
        self.enabled = enabled

    @property
    def settings(self):
        ''' The configuration settings of the node.
        '''
        settings = {}
        settings[self.name] = self.pref_manager.settings
        settings[self.name]['enabled'] = self.enabled
        return settings

    def __getstate__(self):
        ''' Remove instances that can't be pickled.
        '''
        result = self.__dict__.copy()

        # The following attributes can't be pickled and therefore have
        # to be removed.
        # These values have to be reset when loading the project.
        if 'logger' in iter(result.keys()):
            del result['logger']
        return result

    def __setstate__(self, d):
        ''' Fill missing attributes after unpickling.

        '''
        self.__dict__.update(d)  # I *think* this is a safe way to do it
        #print dir(self)

        # Track some instance attribute changes.
        if not "logger" in dir(self):
            logger_prefix = psysmon.logConfig['package_prefix']
            loggerName = logger_prefix + "." + __name__ + "." + self.__class__.__name__
            self.logger = logging.getLogger(loggerName)

    def isEnabled(self):
        ''' Check the enabled state of the node.

        '''
        return self.enabled

    def toggleEnabled(self):
        ''' Toggle the enabled state of the node.

        '''
        self.enabled = not self.enabled

    def getEditPanel(self, parent):
        ''' The method to build and return the edit panel for the processing 
        stack GUI.

        '''
        return PrefEditPanel(pref=self.pref_manager, parent=parent)

    def execute(self, stream, process_limits=None, origin_resource=None):
        ''' Execute the stack node.

        Parameters
        ----------
        stream : :class:`obspy.core.Stream`
            The data to process.
        '''
        assert False, 'execute must be defined'

    def update_pref_manager(self, pref_manager):
        ''' Update the existing preferences manager with the one passed as an argument.

        This is used when loading a psysmon project. The preference items are created
        during the instance initialization of the processing nodes.
        The values saved in the project file are not updated. The update is done
        using this method.
        '''
        self.pref_manager.update(pref_manager)

    def add_result(self,
                   name,
                   res_type='value',
                   metadata=None,
                   origin_resource=None,
                   custom_class=None,
                   **kwargs):
        ''' Add a result.

        Parameters
        ----------
        result : object
            The result to add to the processing node results.

        res_type : String
            The type of the result to add. ('value', 'custom')

        custom_class : class inhereted from :class:`ProcessingResult`
            The custom class of a result of kind 'custom'.
        '''
        if name not in iter(self.results.keys()):
            if res_type == 'value':
                self.results[name] = ValueResult(
                    name=name,
                    origin_name=self.name,
                    origin_pos=self.parentStack.nodes.index(self),
                    res_type=res_type,
                    metadata=metadata,
                    origin_resource=origin_resource)
            elif res_type == 'grid_2d':
                self.results[name] = Grid2dResult(
                    name=name,
                    origin_name=self.name,
                    origin_pos=self.parentStack.nodes.index(self),
                    metadata=metadata,
                    origin_resource=origin_resource)
            else:
                raise ValueError('The result of type %s is not supported.' %
                                 res_type)

        if self.results[name].type != res_type:
            raise ValueError(
                "The type %s of the existing results doesn't match the type %s of the result to add."
                % (self.results[name].type, res_type))

        if res_type == 'value':
            self.results[name].add_value(**kwargs)
        elif res_type == 'grid_2d':
            self.results[name].add_grid(**kwargs)

    def clear_results(self):
        ''' Remove the results.
        '''
        self.results = {}

    def get_result_names(self):
        ''' Get the available result names.

        '''
        return list(set([x.name for x in self.results]))
    def setUp(self):
        self.app = PSysmonApp()
        self.app.Init()                 # The widget inspection tool can be called using CTRL+ALT+i

        self.pref = PreferencesManager()

        # Add the logging page.
        self.pref.add_page('Logging')
        self.pref.add_page('List editor')

        # Add a single_choice field.
        item = SingleChoicePrefItem(name = 'single_choice',
                              group = 'test group 1',
                              limit = ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'),
                              value = 'ERROR',
                              tool_tip = 'tooltip of the single choice control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a multi_choice field.
        item = MultiChoicePrefItem(name = 'multi_choice',
                              group = 'test group 1',
                              limit = ('value 1', 'value 2', 'value 3', 'value 4', 'value 5'),
                              value = ['value 2', 'value 4'],
                              tool_tip = 'tooltip of the multi choice control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a textedit field.
        item = TextEditPrefItem(name = 'textedit',
                              group = 'test group 1',
                              value = 'this is a textedit field',
                              tool_tip = 'tooltip of the textedit control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a integer_control field.
        item = IntegerControlPrefItem(name = 'integer_control',
                              group = 'test group 1',
                              value = 10,
                              tool_tip = 'tooltip of the integer control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an integer_range field.
        item = IntegerSpinPrefItem(name = 'integer_range',
                              group = 'test group 1',
                              value = 10,
                              limit = (0, 100),
                              tool_tip = 'tooltip of the integer spin control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an float_spin field.
        item = FloatSpinPrefItem(name = 'float_spin',
                              group = 'test group 1',
                              value = 10.3,
                              limit = (0, 100),
                              tool_tip = 'tooltip of the float spin control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a datetime_edit field.
        item = DateTimeEditPrefItem(name = 'datetime',
                                    group = 'test group 1',
                                    value = udt.UTCDateTime('2014-01-01T01:02:03.123456'),
                                    tool_tip = 'tooltip of the datetime edit control element'
                                    )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an filebrowse field.
        item = FileBrowsePrefItem(name = 'filebrowse',
                              group = 'test group 2',
                              value = '',
                              filemask = 'comma separated version (*.csv)|*.csv|' \
                                        'all files (*)|*',
                              tool_tip = 'tooltip of the file browse control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an dirbrowse field.
        item = DirBrowsePrefItem(name = 'dirbrowse',
                              group = 'test group 2',
                              value = '',
                              tool_tip = 'tooltip of the dir browse control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a list grid edit field.
        item = ListCtrlEditPrefItem(name = 'list ctrl',
                                    group = 'list editor',
                                    value = [[21, 22, 23, 24]],
                                    limit = [[11, 12, 13, 14],[21, 22, 23, 24], [31, 32, 33, 34]],
                                    column_labels = ['eins', 'zwei', 'drei', 'vier'],
                                    tool_tip = 'tooltip of the list ctrl edit control element'
                                   )
        self.pref.add_item(pagename = 'List editor', item = item)

        # Add a list grid edit field.
        item = ListGridEditPrefItem(name = 'list grid',
                                    group = 'list editor',
                                    value = [],
                                    column_labels = ['eins', 'zwei', 'drei', 'vier'],
                                    tool_tip = 'tooltip of the list grid edit control element'
                                   )
        self.pref.add_item(pagename = 'List editor', item = item)
class ListbookPrefDialogTestCase(unittest.TestCase):
    """
    Test suite for psysmon.packages.geometry.editGeometry.EditGeometryDlg
    """

    @classmethod
    def setUpClass(cls):
        print "In setUpClass...\n"



    @classmethod
    def tearDownClass(cls):
        print "....in tearDownClass.\n"


    def setUp(self):
        self.app = PSysmonApp()
        self.app.Init()                 # The widget inspection tool can be called using CTRL+ALT+i

        self.pref = PreferencesManager()

        # Add the logging page.
        self.pref.add_page('Logging')
        self.pref.add_page('List editor')

        # Add a single_choice field.
        item = SingleChoicePrefItem(name = 'single_choice',
                              group = 'test group 1',
                              limit = ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'),
                              value = 'ERROR',
                              tool_tip = 'tooltip of the single choice control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a multi_choice field.
        item = MultiChoicePrefItem(name = 'multi_choice',
                              group = 'test group 1',
                              limit = ('value 1', 'value 2', 'value 3', 'value 4', 'value 5'),
                              value = ['value 2', 'value 4'],
                              tool_tip = 'tooltip of the multi choice control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a textedit field.
        item = TextEditPrefItem(name = 'textedit',
                              group = 'test group 1',
                              value = 'this is a textedit field',
                              tool_tip = 'tooltip of the textedit control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a integer_control field.
        item = IntegerControlPrefItem(name = 'integer_control',
                              group = 'test group 1',
                              value = 10,
                              tool_tip = 'tooltip of the integer control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an integer_range field.
        item = IntegerSpinPrefItem(name = 'integer_range',
                              group = 'test group 1',
                              value = 10,
                              limit = (0, 100),
                              tool_tip = 'tooltip of the integer spin control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an float_spin field.
        item = FloatSpinPrefItem(name = 'float_spin',
                              group = 'test group 1',
                              value = 10.3,
                              limit = (0, 100),
                              tool_tip = 'tooltip of the float spin control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a datetime_edit field.
        item = DateTimeEditPrefItem(name = 'datetime',
                                    group = 'test group 1',
                                    value = udt.UTCDateTime('2014-01-01T01:02:03.123456'),
                                    tool_tip = 'tooltip of the datetime edit control element'
                                    )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an filebrowse field.
        item = FileBrowsePrefItem(name = 'filebrowse',
                              group = 'test group 2',
                              value = '',
                              filemask = 'comma separated version (*.csv)|*.csv|' \
                                        'all files (*)|*',
                              tool_tip = 'tooltip of the file browse control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add an dirbrowse field.
        item = DirBrowsePrefItem(name = 'dirbrowse',
                              group = 'test group 2',
                              value = '',
                              tool_tip = 'tooltip of the dir browse control element'
                             )
        self.pref.add_item(pagename = 'Logging', item = item)

        # Add a list grid edit field.
        item = ListCtrlEditPrefItem(name = 'list ctrl',
                                    group = 'list editor',
                                    value = [[21, 22, 23, 24]],
                                    limit = [[11, 12, 13, 14],[21, 22, 23, 24], [31, 32, 33, 34]],
                                    column_labels = ['eins', 'zwei', 'drei', 'vier'],
                                    tool_tip = 'tooltip of the list ctrl edit control element'
                                   )
        self.pref.add_item(pagename = 'List editor', item = item)

        # Add a list grid edit field.
        item = ListGridEditPrefItem(name = 'list grid',
                                    group = 'list editor',
                                    value = [],
                                    column_labels = ['eins', 'zwei', 'drei', 'vier'],
                                    tool_tip = 'tooltip of the list grid edit control element'
                                   )
        self.pref.add_item(pagename = 'List editor', item = item)


    def tearDown(self):
        pass



    def test_dialog_creation(self):
        ''' Test the creation of the dialog window.
        '''
        dlg = ListbookPrefDialog(preferences = self.pref)
        dlg.ShowModal()
        dlg.Destroy()
        print self.pref
        self.app.MainLoop()
示例#6
0
 def setUp(self):
     self.pref = PreferencesManager()
示例#7
0
class PreferencesManagerTestCase(unittest.TestCase):
    """
    Test suite for psysmon.core.preferences_manager.PreferencesManager class.
    """

    @classmethod
    def setUpClass(cls):
        print "In setUpClass...\n"



    @classmethod
    def tearDownClass(cls):
        print "....in tearDownClass.\n"


    def setUp(self):
        self.pref = PreferencesManager()


    def tearDown(self):
        pass


    def test_add_item(self):
        ''' Test the add_item method.
        '''
        # The logging verbose level.
        item = PreferenceItem(name = 'verbose', 
                              value = 'DEBUG',
                              mode = 'single_choice',
                              limit = ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG')
                             )
        self.pref.add_item(item)     
        self.assertEqual(len(self.pref.pages['preferences']), 1)  
        self.assertTrue(self.pref.pages['preferences'][0].guiclass, SingleChoiceField)                           
        self.assertEqual(self.pref.pages['preferences'][0].name, 'verbose')


        item = PreferenceItem(name = 'pref2', 
                              value = 'value2',
                              mode = 'custom'
                             )
        self.pref.add_item(item)     
        self.assertEqual(len(self.pref.pages['preferences']), 2)                             
        self.assertEqual(self.pref.pages['preferences'][0].name, 'verbose')
        self.assertTrue(self.pref.pages['preferences'][0].guiclass, None)                           
        self.assertEqual(self.pref.pages['preferences'][1].name, 'pref2')

        self.pref.add_page('Testpage')
        item = PreferenceItem(name = 'pref3',
                              value = 'value3',
                              mode = 'custom'
                             )
        self.pref.add_item(item, pagename = 'Testpage')
        self.assertEqual(len(self.pref.pages['Testpage']), 1)
        self.assertEqual(self.pref.pages['Testpage'][0].name, 'pref3')



    def test_get_item(self):
        ''' The the get_item method.
        '''
        item = PreferenceItem(name = 'pref1', 
                              value = 'value1',
                              mode = 'custom'
                             )
        self.pref.add_item(item)     
        item = PreferenceItem(name = 'pref2', 
                              value = 'value2',
                              mode = 'custom'
                             )
        self.pref.add_item(item)     

        cur_item = self.pref.get_item(name = 'pref2')
        self.assertEqual(len(cur_item), 1)
        self.assertEqual(cur_item[0].name, 'pref2')
        self.assertEqual(cur_item[0].value, 'value2')
        self.assertEqual(cur_item[0].mode, 'custom')
示例#8
0
    def __init__(self,
                 name,
                 user,
                 psybase=None,
                 base_dir='',
                 dbDialect='mysql',
                 dbDriver=None,
                 dbHost='localhost',
                 pkg_version=None,
                 db_version={},
                 dbName="",
                 createTime=None,
                 dbTables={}):
        '''The constructor.

        Create an instance of the Project class.

        Parameters
        ----------
        psybase : :class:`~psysmon.core.base.Base`
            The related pSysmon base instance.

        name : String
            The name of the project.

        base_dir : String
            The base directory of the project.

        user : :class:`~User` instance
            The admin user of the project.

        dbDialect : String, optional
            The database dialect to be used by sqlalchemy (default: mysql).

        dbDriver : String, optional
            The database driver to be used by sqlalchemy (default: None).

        dbHost : String, optional
            The database host (default: localhost).

        dbName : String, optional
            The name of the database associated with the project (default: "").

        createTime : :class:`~psysmon.core.UTCDateTime`, optional
            The time when the project has been created (default: UTCDateTime())

        dbTables : Dictionary of Strings, optional
            The database tablenames used by the project. The name of the table 
            (without prefix) is the key of the dictionary (default: {}).
    
        pkg_version : Dictionary of Strings
            The package version strings of the packages which were present 
            when the project was created. The name of the package is the 
            key of the dictionary.

        db_version : Dictionary of Strings
            The package version strings of the packages for which a database 
            table was created. The name of the package is the key of the 
            dictionary.
        '''

        # The logger.
        loggerName = __name__ + "." + self.__class__.__name__
        self.logger = logging.getLogger(loggerName)

        # The parent psysmon base.
        if psybase is not None:
            self._psybase = weakref.ref(psybase)
        else:
            self._psybase = None

        # The project name.
        self.name = name

        # The slug of the project name.
        self.slug = self.name.lower().replace(' ', '_')

        # The time when the project has been created.
        if createTime is None:
            self.createTime = utcdatetime.UTCDateTime()
        else:
            self.createTime = createTime

        # The project's base directory.
        self.base_dir = base_dir

        # The database engine to be used.
        self.dbDialect = dbDialect

        # The database driver to be used.
        self.dbDriver = dbDriver

        # The host on which the mySQL database server is running.
        self.dbHost = dbHost

        # The mySQL database name.
        if not dbName:
            self.dbName = "psysmon_" + user.name
        else:
            self.dbName = dbName

        # A dictionary of the project databaser table names.
        self.dbTables = dbTables

        # The sqlAlchemy database base instance.
        self.dbBase = None

        # The sqlAlchemy database session.
        self.dbSessionClass = None

        # The project file.
        self.projectFile = self.slug + ".ppr"

        # The version dictionary of the package versions.
        self.pkg_version = {}
        if pkg_version is None:
            for cur_pkg in self.psybase.packageMgr.packages.itervalues():
                self.pkg_version[cur_pkg.name] = cur_pkg.version
        else:
            self.pkg_version = pkg_version

        # The version dictionary of the packages which created at least
        # one database table.
        self.db_version = db_version

        # Is the project saved?
        self.saved = False

        # The thread lock object.
        self.threadMutex = None

        # A list of users associated with this project.
        self.user = []

        # The currently active user.
        self.activeUser = None

        # Add the user(s) to the project user list.
        if isinstance(user, list):
            self.user.extend(user)
        else:
            self.user.append(user)

        self.setActiveUser(self.user[0].name)

        # The project's waveclients.
        self.waveclient = {}

        # The default waveclient.
        self.defaultWaveclient = None

        # The association of the SCNLs to the data sources (the waveclients).
        self.scnlDataSources = {}

        # The project preferences.
        self.pref_manager = PreferencesManager()

        # The geometry inventory.
        self.geometry_inventory = None
示例#9
0
    def __init__(self,
                 name,
                 mode,
                 category,
                 tags,
                 group='general',
                 icons=None,
                 parent=None,
                 docEntryPoint=None,
                 position_pref=0,
                 *kwargs):
        ''' The constructor.

        Create an instance of the PluginNode.

        Parameters
        ----------
        name : String
            The name of the plugin-node.
        mode : String
            The mode of the plugin-node (option, command, interactive, view).
        category : String
            The category of the plugin-node.
        tags : list of String
            A list of strings containing the tags of the collection node.
            These values are not limited but they should contain one of 
            the three development state tags:
             - stable
             - experimental
             - damaged
        group : String
            The group of the plugin-node. A group contains the categories (default = 'general').
        icons : List of Strings
            The icons used in the ribbonbar.
        nodeClass : String
            The name of the class for which the plugin-node has been written.
        parent : :class:`~psysmon.core.packageNodes.CollectionNode`
            The parent collectionNode which has loaded the plugin.
        docEntryPoint : String
            The path to where the documentation's index.html file can be found.
        position_pref : Integer
            The preferred position of the tool in the category section of the ribbon bar.
        '''
        # The name of the plugin.
        self.name = name

        # The mode of the plugin.
        self.mode = mode

        # The group of the plugin.
        self.group = group

        # The category of the plugin.
        self.category = category

        # The tags of the plugin.
        self.tags = tags

        # The parent collection node which contains the plugin.
        self.parent = parent

        # The preferences of the plugin.
        self.pref_manager = PreferencesManager()

        # The path to the html index file containing the documentation of the
        # plugin.
        self.docEntryPoint = docEntryPoint

        # The icons of the plugin.
        # The dictionary has to be filled in the constructor of the
        # plugin node. The icons icons['active'] and icons['inactive']
        # should be set.
        self.icons = {}

        # The activation state of the tool. This is used by view- and
        # interactive tools. For other tool modes, the active state is
        # always False.
        self.active = False

        # The preferred position within a category.
        self.position_pref = position_pref
示例#10
0
class PluginNode(object):
    ''' The base class of all plugin nodes.

    This class is the base class on which all plugins are built.

    Attributes
    ----------
    nodeClass : String
        The name of the class which can use the plugin. Use 'common' for 
        a plugin that can be used by every class. Default is 'common'.
    '''
    # The class to which the plugin is assigned to.
    # Use *common* for plugins which can be used by every class.
    # Nodes with a specified nodeClass usually depend on some special
    # variables which have to be passed to them using the variable kwargs
    # argument.
    nodeClass = 'common'

    def __init__(self,
                 name,
                 mode,
                 category,
                 tags,
                 group='general',
                 icons=None,
                 parent=None,
                 docEntryPoint=None,
                 position_pref=0,
                 *kwargs):
        ''' The constructor.

        Create an instance of the PluginNode.

        Parameters
        ----------
        name : String
            The name of the plugin-node.
        mode : String
            The mode of the plugin-node (option, command, interactive, view).
        category : String
            The category of the plugin-node.
        tags : list of String
            A list of strings containing the tags of the collection node.
            These values are not limited but they should contain one of 
            the three development state tags:
             - stable
             - experimental
             - damaged
        group : String
            The group of the plugin-node. A group contains the categories (default = 'general').
        icons : List of Strings
            The icons used in the ribbonbar.
        nodeClass : String
            The name of the class for which the plugin-node has been written.
        parent : :class:`~psysmon.core.packageNodes.CollectionNode`
            The parent collectionNode which has loaded the plugin.
        docEntryPoint : String
            The path to where the documentation's index.html file can be found.
        position_pref : Integer
            The preferred position of the tool in the category section of the ribbon bar.
        '''
        # The name of the plugin.
        self.name = name

        # The mode of the plugin.
        self.mode = mode

        # The group of the plugin.
        self.group = group

        # The category of the plugin.
        self.category = category

        # The tags of the plugin.
        self.tags = tags

        # The parent collection node which contains the plugin.
        self.parent = parent

        # The preferences of the plugin.
        self.pref_manager = PreferencesManager()

        # The path to the html index file containing the documentation of the
        # plugin.
        self.docEntryPoint = docEntryPoint

        # The icons of the plugin.
        # The dictionary has to be filled in the constructor of the
        # plugin node. The icons icons['active'] and icons['inactive']
        # should be set.
        self.icons = {}

        # The activation state of the tool. This is used by view- and
        # interactive tools. For other tool modes, the active state is
        # always False.
        self.active = False

        # The preferred position within a category.
        self.position_pref = position_pref

    @property
    def rid(self):
        ''' The resource ID of the plugin.
        '''
        name_slug = self.name.replace(' ', '_')
        if self.parent:
            return self.parent.collection_node.rid + '/plugin/' + name_slug
        else:
            return '/plugin/' + name_slug

    def __getattr__(self, attrname):
        ''' Handle call of attributes which are derived from the parent recorder.
        '''
        if attrname in self.pref_manager.get_name():
            return self.pref_manager.get_value(attrname)
        else:
            raise AttributeError(attrname)

    def register(self, parent):
        ''' Register the plugin within a collection node.

        Parameters
        ----------
        parent : :class:`~psysmon.core.packageNodes.CollectionNode`

        '''
        self.parent = parent

    def register_keyboard_shortcuts(self):
        ''' Register the keyboard shortcuts.
        '''
        return None

    def activate(self):
        ''' Activate the plugin.
        '''
        self.active = True

    def deactivate(self):
        ''' Deactivate the plugin.
        '''
        self.active = False

    def buildMenu(self):
        ''' Build the menu which is added to the parent's menu bar.
        '''
        return None

    def buildFoldPanel(self, panelBar):
        ''' Create the foldpanel GUI.

        '''
        return PrefEditPanel(pref=self.pref_manager, parent=panelBar)

    def getHooks(self):
        ''' Register the callback methods for certain key events.

        The hooks are Matplotlib events (e.g. button_press_event, 
        button_release_event, motions_notify_event.
        Other types of hooks can be provided by the collection nodes.
        '''
        return None

    def initialize_preferences(self):
        ''' Initialize runtime dependent preference items.
        '''
        pass

    def get_virtual_stations(self):
        ''' Return the required virtual stations in a display group.

        Returns
        -------
        stations : list of strings
            The names of the required stations.
        '''
        return []
示例#11
0
class CollectionNode:
    ''' The base class of all psysmon collection nodes.

    All collection nodes contained in psysmon packages have to inherit from 
    the :class:`CollectionNode` class.

    Attributes
    ----------
    mode : Sting
        Specify the behavior in the collection. Allowed values are:
        
            - editable
                The user can edit the node parameters.
            - uneditable
                There are no parameters to edit.
            - standalone
                The node is not included in the execution of the collection.
                Each node can be executed individually using the context 
                menu of the collection listbox.

    name : String
        The name of the collection node.


    '''

    ## The CollectionNode constructor.
    #
    # @param self The Object pointer.
    # @param name The name of the collection node.
    # @param type The type of the collection node.
    # Allowed values are:
    # - editable
    # - uneditable
    # - standalone
    # @param category The category to which the collection node is assigned to.
    # @param tags A list of strings containing the tags of the collection node. These values are
    # not limited but they should contain one of the three development state tags:
    # - stable
    # - experimental
    # - damaged
    # @param property A dictionary containing the default properties of the
    # collection node. This dictionary is used to initialize a new collection node
    # and to save the user input for this collection node during the sessions.
    # @param parent The parent package of the collection node.

    name = None

    ## The type of the collection node.
    #
    # Each collection node can specify it's type. Currently there are three
    # allowed values:
    # - editable The user can edit the node paramters.
    # - uneditable There are no node parameters to edit.
    # - standalone The node is not included in the collection execution. Each
    # node can be executed individually using the collection listbox context menu.
    mode = None

    # The category of the collection node.
    category = None

    ## The tags assigned to the collection node.
    #
    # The tags attribute is a list of Strings.@n
    # Additionally to the category, one or more tags can be assigned to the
    # collection node. These tags can be used when creating sub-selections of
    # all available collection nodes.@n
    # For example, a set of nodes has been created for the processing tasks
    # at a certain institution or for a special project, one could tag these
    # nodes with the institution name or the project name to make it easy for
    # users to select these nodes or also to hide these nodes from their
    # collection node inventory.@n
    # The tag values are not limited but they should contain one of the three
    # development state tags:
    # - stable
    # - experimental
    # - damaged
    tags = []

    # The entry point of the documentation of the collection node.
    docEntryPoint = None

    def __init__(self,
                 requires=None,
                 provides=None,
                 parent=None,
                 project=None,
                 enabled=True,
                 pref_manager=None):
        ## The package which contains the collection node.
        self.parentPackage = parent

        # The preferences manager of the node.
        if pref_manager is None:
            self.pref_manager = PreferencesManager()
        else:
            self.pref_manager = pref_manager

        ## The node's enabled state.
        #
        # Mark the collection node as enabled or disabled.
        self.enabled = enabled

        ## The collection node's output.
        #
        # The output dictionary can be used to pass parameters to the next
        # node in the collection.
        self.output = {}

        # The variables required by the node.
        self.requires = requires

        # The variables provided by the node.
        self.provides = provides

        ## The current pSysmon project.
        #
        self.project = project

        ## The parent collection holding the node instance.
        #
        self.parentCollection = None

        # If the node is executed in a collection thread a thread ID is
        # assigned.
        self.procName = None

    @property
    def rid(self):
        ''' The resource ID of the collection node.
        '''
        name_slug = self.name.replace(' ', '_')
        if self.parentCollection is not None:
            rid = self.parentCollection.rid + '/' + name_slug
        else:
            rid = name_slug

        return rid

    ## The __getstate__ method.
    #
    # Remove the project instance before pickling the instance.
    def __getstate__(self):
        result = self.__dict__.copy()
        del result['project']
        return result

    ## The __setstate__ method.
    #
    # Fill the attributes after unpickling.
    def __setstate__(self, d):
        self.__dict__.update(d)  # I *think* this is a safe way to do it
        self.project = None

        # Track some instance attribute changes.
        #if not "mode" in dir(self):
        #    self.mode = self.type

        #if not "options" in dir(self):
        #    self.options = self.property

    ## Set the name of the collection node package.
    #
    #
    def setNodePkg(self, nodePkg):
        ## The name of the python package containing the nodeClass.
        #
        # This attribute holds the name of the @b python package holding the
        # nodeClass. This package is not to be mixed up with the pSysmon package.
        self.nodePkg = nodePkg

    ## The collection node edit method.
    #
    # The CollecitonNode class requires from it's subclasses to define this method.@n
    # The @e edit method is called to edit the collection node parameters. In
    # the pSysmon GUI this is done using the collection listbox context menu.
    # Within the edit method it's up to the programmer of the collection node
    # how to get the user input to change the collection node properties.
    #
    # @param self The object pointer.
    # @param project The current pSysmon project.
    def edit(self):
        assert False, 'edit must be defined'

    ## The collection node execute method.
    #
    # The CollecitonNode class requires from it's subclasses to define this method.@n
    # The @e execute method is called to execute the collection node. In
    # the pSysmon GUI this is done using the @e execute @e collection button.
    # Within the execute method it's up to the programmer of the collection node
    # what algorithm actually is executed.
    #
    # @param self The object pointer.
    # @param project The current pSysmon project.
    # @param prevNodeOutput The output of the previous node in the collection
    def execute(self, prevNodeOutput={}):
        assert False, 'execute must be defined'

    ## Run the collection node from within a thread.
    #
    # A Collection object is designed to be executed as a thread. The Collection.execute()
    # method calls the run method of each collection node. In the run method several
    # thread dependent attributes can be set before executing the collection node.
    # Currently the procId is saved as an attribute of the collection node
    # so that the node knows to which thread it belongs to.
    def run(self, procName, prevNodeOutput={}):
        self.procName = procName
        self.execute(prevNodeOutput)

    def update_pref_manager(self, pref_manager):
        ''' Update the existing preferences manager with the one passed as an argument.
        '''
        self.pref_manager.update(pref_manager)

    ## Log messages.
    #
    # The collection node is executed by a CollectionNode object. This object handles
    # the logging of various messages (error, warning, status, ...) to a log file.
    #
    # @see CollectionNode.log
    def log(self, mode, msg):

        # If the node is running in a thread, log to the collection (the
        # log file).
        # If the thread is not running, log to the pSysmon log area.
        if self.procName:
            self.parentCollection.log(self.name, mode, msg)
        else:
            self.project.log(mode, msg)

    def provideData(self, name, data, description):
        ''' Provide the data to the other collection nodes.

        Parameters
        ----------
        name : String
            The name of the data provided.

        data : Object
            The data provided to the next collection nodes.

        description : String
            A short description of the data.
        '''
        self.parentCollection.pickleData(name=name,
                                         data=data,
                                         description=description,
                                         origin=self.name)

    def requireData(self, name=None, origin=None):
        ''' Require data from the collection's shelf.

        Parameters
        ----------
        names : List of Strings
            The names of the variables to restore from the collection's 
            shelf.
        '''
        print "Requiring data with name: %s and origin: %s" % (name, origin)
        return self.parentCollection.unpickleData(name=name, origin=origin)
示例#12
0
class ProcessingNode:
    ''' The ProcessingNode class.

    The processing node gets data from the processing stack, does some computation with 
    this data and returns the processed data to the processing stack.
    The type of data needed has to be defined by the ProcessingNode. Currently the processing 
    of obspy Stream objects is supported.
    The return value has to be of the same type as the data passed to the processing node.
    '''
    # The class to which the processing node is assigned to.
    # User *common* for nodes which can be used by every class.
    # Nodes with a specified nodeClass usually depend on some special
    # variables which have to be passed to them using the variable kwargs
    # argument.
    nodeClass = 'common'

    def __init__(self,
                 name,
                 mode,
                 category,
                 tags,
                 enabled=True,
                 docEntryPoint=None,
                 parentStack=None):
        ''' The constructor

        '''
        # The name of the stack node.
        self.name = name

        # The mode of the stack node (editable, uneditable).
        self.mode = mode

        # The category of the stack node.
        self.category = category

        # The tags assigned to the stack node.
        self.tags = tags

        # The result of the processing node.
        self.results = {}

        # The preferences of the stack node.
        self.pref_manager = PreferencesManager()

        # The entry point of the documentation of the node.
        self.docEntryPoint = docEntryPoint

        # The parent stack holding the stack node.
        self.parentStack = parentStack

        # The enabled state of the node.
        self.enabled = enabled

    def isEnabled(self):
        ''' Check the enabled state of the node.

        '''
        return self.enabled

    def toggleEnabled(self):
        ''' Toggle the enabled state of the node.

        '''
        self.enabled = not self.enabled

    def getEditPanel(self, parent):
        ''' The method to build and return the edit panel for the processing 
        stack GUI.

        '''
        return PrefEditPanel(pref=self.pref_manager, parent=parent)

    def execute(self, stream, process_limits=None):
        ''' Execute the stack node.

        Parameters
        ----------
        stream : :class:`obspy.core.Stream`
            The data to process.
        '''
        assert False, 'execute must be defined'

    def update_pref_manager(self, pref_manager):
        ''' Update the existing preferences manager with the one passed as an argument.

        This is used when loading a psysmon project. The preference items are created
        during the instance initialization of the processing nodes.
        The values saved in the project file are not updated. The update is done
        using this method.
        '''
        self.pref_manager.update(pref_manager)

    def add_result(self,
                   name,
                   scnl,
                   value,
                   res_type='value',
                   custom_class=None):
        ''' Add a result.

        Parameters
        ----------
        result : object
            The result to add to the processing node results.

        res_type : String
            The type of the result to add. ('value', 'custom')

        custom_class : class inhereted from :class:`ProcessingResult`
            The custom class of a result of kind 'custom'.
        '''
        if name not in self.results.keys():
            if res_type == 'value':
                self.results[name] = ValueResult(
                    name=name,
                    origin_name=self.name,
                    origin_pos=self.parentStack.nodes.index(self),
                    res_type=res_type)
            else:
                raise ValueError('The result of type %s is not supported.' %
                                 res_type)

        if self.results[name].type != res_type:
            raise ValueError(
                "The type %s of the existing results doesn't match the type %s of the result to add."
                % (self.results[name].type, res_type))

        self.results[name].add_value(scnl=scnl, value=value)

    def clear_results(self):
        ''' Remove the results.
        '''
        self.results = {}

    def get_result_names(self):
        ''' Get the available result names.

        '''
        return list(set([x.name for x in self.results]))