Exemplo n.º 1
0
 def __init__(self, data=None):
     super(Data, self).__init__(data)
     #: dictionary of data sources added to the Data layer
     self.data_sources = {}
     #: data source objects
     self.data_obj = {}
     #: data
     self.data = DataRegistry()
Exemplo n.º 2
0
 def __init__(self, data=None):
     super(Data, self).__init__(data)
     #: dictionary of data sources added to the Data layer
     self.data_sources = {}
     #: data source objects
     self.data_obj = {}
     #: data
     self.data = DataRegistry()
Exemplo n.º 3
0
class Data(Layer):
    """
    The Data layer of the model.

    :param data: Dictionary of model data specific to the data layer.
    :type data: dict

    The :attr:`~Layer.layer` attribute is a dictionary of data sources names
    as keys of dictionaries for each data source with the module and optionally
    the package containing the module, the filename, which can be ``None``,
    containing specific data for the data source and an optional path to the
    data file. If the path is ``None``, then the default path for data internal
    to Circus is used. External data files should specify the path.
    """
    def __init__(self, data=None):
        super(Data, self).__init__(data)
        #: dictionary of data sources added to the Data layer
        self.data_sources = {}
        #: data source objects
        self.data_obj = {}
        #: data
        self.data = DataRegistry()
        # layers are initialized by the model

    def add(self, data_source, module, package=None):
        """
        Add data_source to model. Tries to import module, then looks for data
        source class definition.

        :param data_source: Name of data source to add.
        :type data_source: str
        :param module: Module in which data source resides. Can be absolute or
            relative. See :func:`importlib.import_module`
        :type module: str
        :param package: Optional, but must be used if module is relative.
        :type package: str

        .. seealso::
            :func:`importlib.import_module`
        """
        # TODO: 3 ways to add a data source
        # (1) this way
        # (2) using class factory, inputs in JSON file
        # (3) use DataSource or one of its subclasses
        # import module
        mod = importlib.import_module(module, package)
        # get data source class definition from the module
        if data_source.startswith('_'):
            err_msg = 'No "%s" attribute in "%s".' % (data_source, mod)
            raise AttributeError(err_msg)
        self.data_sources[data_source] = getattr(mod, data_source)
        # only update layer info if it is missing!
        if data_source not in self.layer:
            # copy data source parameters to :attr:`Layer.layer`
            self.layer[data_source] = {'module': module, 'package': package}
        # add a place holder for the data source object when it's constructed
        self.data_obj[data_source] = None

    def open(self, data_source, filename, path=None):
        """
        Open filename to get data for data_source.

        :param data_source: Data source for which the file contains data.
        :type data_source: str
        :param filename: Name of the file which contains data for the data
            source.
        :type filename: str
        :param path: Path of file containting data. [../data]
        :type path: str
        """
        # only update layer info if it is missing!
        if data_source not in self.layer:
            # update path and filename to this layer of the model
            self.layer[data_source] = {'path': path, 'filename': filename}
        # filename can be a list or a string, concatenate list with os.pathsep
        # and append the full path to strings.
        if isinstance(filename, basestring):
            filename = os.path.join(path, filename)
        else:
            file_list = [os.path.join(path, f) for f in filename]
            filename = os.path.pathsep.join(file_list)
        # call constructor of data source with filename argument
        self.data_obj[data_source] = self.data_sources[data_source](filename)
        # register data and uncertainty in registry
        data_src_obj = self.data_obj[data_source]
        self.data.register(data_src_obj.data, data_src_obj.uncertainty,
                           data_src_obj.isconstant, data_src_obj.timeseries,
                           data_src_obj.data_source)

    def load(self):
        """
        Add data_sources to layer and open files with data for the data_source.
        """
        for k, v in self.layer.iteritems():
            self.add(k, v['module'], v.get('package'))
            if v.get('filename'):
                self.open(k, v['filename'], v.get('path'))

    def edit(self, data_src, value):
        """
        Edit data layer.

        :param data_src: Name of :class:`DataSource` to edit.
        :type data_scr: str
        :param value: Values to edit.
        :type value: dict
        """
        # check if opening file
        if 'filename' in value:
            items = [
                k for k, v in self.data.data_source.iteritems()
                if v == data_src
            ]
            self.data.unregister(items)  # remove items from Registry
            # open file and register new data
            self.open(data_src, value['filename'], value.get('path'))
            self.layer[data_src].update(value)  # update layer with new items

    def delete(self, data_src):
        """
        Delete data sources.
        """
        items = self.data_obj[data_src].data.keys()  # items to edit
        self.data.unregister(items)  # remove items from Registry
        self.layer.pop(data_src)  # remove data source from layer
        self.data_obj.pop(data_src)  # remove data_source object
        self.data_sources.pop(data_src)  # remove data_source object
Exemplo n.º 4
0
class Data(Layer):
    """
    The Data layer of the model.

    :param data: Dictionary of model data specific to the data layer.
    :type data: dict

    The :attr:`~Layer.layer` attribute is a dictionary of data sources names
    as keys of dictionaries for each data source with the module and optionally
    the package containing the module, the filename, which can be ``None``,
    containing specific data for the data source and an optional path to the
    data file. If the path is ``None``, then the default path for data internal
    to Circus is used. External data files should specify the path.
    """
    def __init__(self, data=None):
        super(Data, self).__init__(data)
        #: dictionary of data sources added to the Data layer
        self.data_sources = {}
        #: data source objects
        self.data_obj = {}
        #: data
        self.data = DataRegistry()
        # layers are initialized by the model

    def add(self, data_source, module, package=None):
        """
        Add data_source to model. Tries to import module, then looks for data
        source class definition.

        :param data_source: Name of data source to add.
        :type data_source: str
        :param module: Module in which data source resides. Can be absolute or
            relative. See :func:`importlib.import_module`
        :type module: str
        :param package: Optional, but must be used if module is relative.
        :type package: str

        .. seealso::
            :func:`importlib.import_module`
        """
        # TODO: 3 ways to add a data source
        # (1) this way
        # (2) using class factory, inputs in JSON file
        # (3) use DataSource or one of its subclasses
        # import module
        mod = importlib.import_module(module, package)
        # get data source class definition from the module
        if data_source.startswith('_'):
                err_msg = 'No "%s" attribute in "%s".' % (data_source, mod)
                raise AttributeError(err_msg)
        self.data_sources[data_source] = getattr(mod, data_source)
        # only update layer info if it is missing!
        if data_source not in self.layer:
            # copy data source parameters to :attr:`Layer.layer`
            self.layer[data_source] = {'module': module, 'package': package}
        # add a place holder for the data source object when it's constructed
        self.data_obj[data_source] = None

    def open(self, data_source, filename, path=None):
        """
        Open filename to get data for data_source.

        :param data_source: Data source for which the file contains data.
        :type data_source: str
        :param filename: Name of the file which contains data for the data
            source.
        :type filename: str
        :param path: Path of file containting data. [../data]
        :type path: str
        """
        # default path for data is in ../data
        if not path:
            path = os.path.join(_DATA, data_source)
        # only update layer info if it is missing!
        if data_source not in self.layer:
            # update path and filename to this layer of the model
            self.layer[data_source] = {'path': path, 'filename': filename}
        # filename can be a list or a string, concatenate list with os.pathsep
        # and append the full path to strings.
        if isinstance(filename, basestring):
            filename = os.path.join(path, filename)
        else:
            file_list = [os.path.join(path, f) for f in filename]
            filename = os.path.pathsep.join(file_list)
        # call constructor of data source with filename argument
        self.data_obj[data_source] = self.data_sources[data_source](filename)
        # register data and uncertainty in registry
        data_src_obj = self.data_obj[data_source]
        self.data.register(data_src_obj.data, data_src_obj.uncertainty,
                           data_src_obj.isconstant, data_src_obj.timeseries,
                           data_src_obj.data_source)

    def load(self):
        """
        Add data_sources to layer and open files with data for the data_source.
        """
        for k, v in self.layer.iteritems():
            self.add(k, v['module'], v.get('package'))
            if v.get('filename'):
                self.open(k, v['filename'], v.get('path'))

    def edit(self, data_src, value):
        """
        Edit data layer.

        :param data_src: Name of :class:`DataSource` to edit.
        :type data_scr: str
        :param value: Values to edit.
        :type value: dict
        """
        # check if opening file
        if 'filename' in value:
#             items = self.data_obj[data_src].data.keys()  # items to edit
            items = [k for k, v in self.data.data_source.iteritems() if
                     v == data_src]
            self.data.unregister(items)  # remove items from Registry
            # open file and register new data
            self.open(data_src, value['filename'], value.get('path'))
            self.layer[data_src].update(value)  # update layer with new items

    def delete(self, data_src):
        """
        Delete data sources.
        """
        items = self.data_obj[data_src].data.keys()  # items to edit
        self.data.unregister(items)  # remove items from Registry
        self.layer.pop(data_src)  # remove data source from layer
        self.data_obj.pop(data_src)  # remove data_source object
        self.data_sources.pop(data_src)  # remove data_source object