Esempio n. 1
0
def save(system,
         path=None,
         filetype=None,
         workspace=None,
         base='user',
         **kwds):
    """Export system to file.

    Args:
        system (object): rian system instance
        path (str, optional): path of export file
        filetype (str, optional): filetype of export file
        workspace (str, optional): workspace to use for file export

    Returns:
        Boolean value which is True if file export was successful

    """

    from hup.base import otree

    if not otree.has_base(system, 'System'):
        raise ValueError("system is not valid")

    from hup.base import env

    # get directory, filename and fileextension
    if isinstance(workspace, str) and not workspace == 'None':
        directory = rian.path('systems', workspace=workspace, base=base)
    elif isinstance(path, str):
        directory = env.get_dirname(path)
    else:
        directory = env.get_dirname(system.path)
    if isinstance(path, str):
        name = env.basename(path)
    else:
        name = system.fullname
    if isinstance(filetype, str):
        fileext = filetype
    elif isinstance(path, str):
        fileext = env.fileext(path) or env.fileext(system.path)
    else:
        fileext = env.fileext(system.path)
    path = str(env.join_path(directory, name + '.' + fileext))

    # get filetype from file extension if not given
    # and test if filetype is supported
    if not filetype:
        filetype = fileext.lower()
    if filetype not in filetypes():
        raise ValueError(f"filetype '{filetype}' is not supported.")

    # export to file
    module_name = filetypes(filetype)[0]
    if module_name == 'archive':
        return rian.system.exports.archive.save(system, path, filetype, **kwds)

    return False
Esempio n. 2
0
    def load(self, path):
        """Return system configuration as dictionary.

        Args:
            path: configuration file used to generate system
                configuration dictionary.

        """
        from hup.base import env
        from hup.io import ini

        # import ini file to dictionary, using ini file structure
        # described with regular expressions
        system = ini.load(path,
                          scheme={
                              'system': {
                                  'name': str,
                                  'type': str
                              },
                              'schedule [.0-9a-zA-Z]*': {
                                  'system [.0-9a-zA-Z]*': dict
                              }
                          })

        if not system \
            or not 'system' in system \
            or not 'type' in system['system']:
            raise ValueError("""could not import system:
                configuration file '%s' is not valid.""" % (path))

        config = system['system'].copy()

        # update / set name
        if 'name' not in config: config['name'] = env.basename(path)

        # update / set optimization schedules
        schedules = {}
        for key in system:
            if key[:8].lower() != 'schedule': continue
            name = key[9:]
            schedules[name] = {'name': name}
            for syskey in system[key]:
                if syskey[:6].lower() != 'system': continue
                systype = syskey[7:]
                schedules[name][systype] = system[key][syskey].copy()

        config['schedules'] = schedules

        return {'config': config}
Esempio n. 3
0
def save(dataset,
         path=None,
         filetype=None,
         workspace=None,
         base='user',
         **kwds):
    """Export dataset to file.

    Args:
        dataset (object): rian dataset instance
        path (str, optional): path of export file
        filetype (str, optional): filetype of export file
        workspace (str, optional): workspace to use for file export

    Returns:
        Boolean value which is True if file export was successful

    """

    if not otree.has_base(dataset, 'Dataset'):
        raise TypeError("dataset is not valid")

    from hup.base import env
    import rian

    # get directory, filename and fileextension
    if isinstance(workspace, str) and not workspace == 'None':
        dname = rian.path('datasets', workspace=workspace, base=base)
    elif isinstance(path, str):
        dname = env.get_dirname(path)
    else:
        dname = env.get_dirname(dataset.path)
    if isinstance(path, str):
        fbase = env.basename(path)
    else:
        fbase = dataset.fullname
    if isinstance(filetype, str):
        fext = filetype
    elif isinstance(path, str):
        fext = env.fileext(path) or env.fileext(dataset.path)
    else:
        fext = env.fileext(dataset.path)
    path = str(env.join_path(dname, fbase + '.' + fext))

    # get filetype from file extension if not given
    # and test if filetype is supported
    if not filetype:
        filetype = fext.lower()
    if filetype not in filetypes():
        raise ValueError(f"filetype '{filetype}' is not supported.")

    # export to file
    mname = filetypes(filetype)[0]
    if mname == 'text':
        return text.save(dataset, path, filetype, **kwds)
    if mname == 'archive':
        return archive.save(dataset, path, filetype, **kwds)
    if mname == 'image':
        return image.save(dataset, path, filetype, **kwds)

    return False
Esempio n. 4
0
 def test_basename(self) -> None:
     path = (('a', ('b', 'c')), 'd', 'base.ext')
     val = env.basename(*path)
     self.assertEqual(val, 'base')
Esempio n. 5
0
    def _set_workspace_scandir(self, *args, **kwds):
        """Scan workspace for files."""

        # change current base and workspace (if necessary)
        cur_ws = self._get_workspace()
        cur_base = self._get_base()

        if args:
            ws = args[0]
        else:
            ws = cur_ws
        if 'base' in kwds:
            base = kwds.pop('base')
        else:
            base = cur_base

        if (base, ws) != (cur_base, cur_ws):
            current = self._config.get('workspace', None)
            chdir = self._set_workspace(ws, base=base)
        else:
            chdir = False

        # scan workspace for objects
        for objtype in list(self._config['register'].keys()):
            dirmask = self._config['current']['path'][objtype + 's']
            filemask = self._get_path_expand(dirmask, '*.*')
            if objtype == 'dataset':
                from rian.dataset import imports
                filetypes = imports.filetypes()
            elif objtype == 'network':
                from rian.network import imports
                filetypes = imports.filetypes()
            elif objtype == 'system':
                from rian.system import imports
                filetypes = imports.filetypes()
            elif objtype == 'model':
                from rian.model import imports
                filetypes = imports.filetypes()
            elif objtype == 'script':
                filetypes = ['py']

            # scan for files
            objregister = self._config['register'][objtype]
            for filepath in glob.iglob(filemask):
                filetype = env.fileext(filepath)
                if filetype not in filetypes:
                    continue
                basename = env.basename(filepath)
                filespace = self._get_workspace()
                filebase = self._get_base()
                fullname = '%s.%s.%s' % (filebase, filespace, basename)

                if fullname in objregister:
                    continue

                # register object configuration
                objregister[fullname] = {
                    'base': filebase,
                    'fullname': fullname,
                    'name': basename,
                    'path': filepath,
                    'type': objtype,
                    'workspace': filespace
                }

        # change to previous workspace if necessary
        if chdir:
            if current:
                self._set_workspace(current.get('name'),
                                    base=current.get('base'))
            else:
                self._set_workspace(None)

        return True
Esempio n. 6
0
    def load(self, path):
        """Get dataset configuration and dataset tables.

        Args:
            path (string): csv file containing dataset configuration and
                dataset table.

        """

        # Get instance of CSV-file
        file = csv.File(path)

        # Get configuration from CSV comment lines
        comment = file.comment

        scheme = {
            'name': str,
            'branch': str,
            'version': int,
            'about': str,
            'author': str,
            'email': str,
            'license': str,
            'filetype': str,
            'application': str,
            'preprocessing': dict,
            'type': str,
            'labelformat': str
        }

        config = ini.decode(comment, flat=True, scheme=scheme)

        if 'name' in config:
            name = config['name']
        else:
            name = env.basename(path)
            config['name'] = name
        if 'type' not in config:
            config['type'] = 'base.Dataset'

        # Add column and row filters
        config['colfilter'] = {'*': ['*:*']}
        config['rowfilter'] = {'*': ['*:*'], name: [name + ':*']}

        # Load data
        names = list(file.header)
        names[0] = 'label'
        data = array.from_tuples(file.read(), names=tuple(names))

        config['table'] = {name: config.copy()}
        config['table'][name]['fraction'] = 1.0
        config['columns'] = tuple()
        config['colmapping'] = {}
        config['table'][name]['columns'] = []
        for column in data.dtype.names:
            if column == 'label':
                continue
            config['columns'] += (('', column), )
            config['colmapping'][column] = column
            config['table'][name]['columns'].append(column)

        # Get data table from CSV data
        tables = {name: data}

        return {'config': config, 'tables': tables}
Esempio n. 7
0
    def _parse_layer_network(self, path):
        from hup.base import env
        from hup.io import ini

        scheme = {
            'network': {
                'name': str,
                'description': str,
                'branch': str,
                'version': str,
                'about': str,
                'author': str,
                'email': str,
                'license': str,
                'type': str,
                'layers': list,
                'directed': bool,
                'labelformat': str
            },
            'layer [0-9a-zA-Z]*': {
                'name': str,
                'function': str,
                'distribution': str,
                'type': str,
                'visible': bool,
                'file': str,
                'nodes': list,
                'size': int
            },
            'binding [0-9a-zA-Z]*-[0-9a-zA-Z]*': {
                '[0-9a-zA-Z]*': list
            }
        }

        ini_dict = ini.load(path, scheme=scheme)
        config = ini_dict['network'].copy()

        # layers
        if 'layers' not in config:
            raise Warning("""file '%s' does not
                contain parameter 'layers'.""" % path)
        config['layer'] = config['layers']
        del config['layers']

        # name
        if 'name' not in config:
            config['name'] = env.basename(path)

        # directed
        if 'directed' not in config:
            config['directed'] = True

        # node labelformat
        if 'labelformat' not in config:
            config['labelformat'] = 'generic:string'

        # init network dictionary
        config['nodes'] = {}
        config['edges'] = {}
        config['layers'] = {}

        visible_layer_ids = [0, len(config['layer']) - 1]

        # [layer *]
        for layer_id, layer in enumerate(config['layer']):

            layer_section = 'layer ' + layer
            if layer_section not in ini_dict:
                raise Warning("""could not import layer
                    network: file '%s' does not contain information
                    about layer '%s'.""" % (path, layer))

            sec_data = ini_dict[layer_section]
            config['layers'][layer] = {}
            lay_data = config['layers'][layer]

            # get name of layer
            lay_data['name'] = sec_data.get('name')

            # get visibility (observable, latent) of nodes in layer
            if 'visible' in sec_data:
                lay_data['visible'] = sec_data['visible']
            else:
                lay_data['visible'] = layer_id in visible_layer_ids

            # get type of layer nodes
            if 'type' in sec_data:
                lay_data['type'] = sec_data.get('type')

            # get function of layer nodes
            if 'function' in sec_data:
                lay_data['function'] = sec_data.get('function')

            # get distribution of layer nodes
            if 'distribution' in sec_data:
                lay_data['distribution'] = sec_data.get('distribution')

            # get nodes of layer from given list file ('file')
            # or from list ('nodes') or from given layer size ('size')
            if 'file' in sec_data:
                file_str = sec_data['file']
                list_file = rian.workspace._expand_path(file_str)
                if not os.path.exists(list_file):
                    raise ValueError("""listfile '%s'
                        does not exists!""" % list_file)
                with open(list_file, 'r') as list_file:
                    fileLines = list_file.readlines()
                node_list = [node.strip() for node in fileLines]
            elif 'nodes' in sec_data:
                node_list = sec_data['nodes']
            elif 'size' in sec_data:
                node_list = ['n%s' % (n) \
                    for n in range(1, sec_data['size'] + 1)]
            else:
                raise Warning("""could not import layer
                    network: layer '%s' does not contain valid node
                    information!""" % (layer))

            config['nodes'][layer] = []
            for node in node_list:
                node = node.strip()
                if node == '':
                    continue
                if node not in config['nodes'][layer]:
                    config['nodes'][layer].append(node)

        # parse '[binding *]' sections and add edges to network dict
        for i in range(len(config['layer']) - 1):
            src_layer = config['layer'][i]
            tgt_layer = config['layer'][i + 1]

            edge_layer = (src_layer, tgt_layer)
            config['edges'][edge_layer] = []
            edge_section = 'binding %s-%s' % (src_layer, tgt_layer)

            # create full binding between two layers if not specified
            if edge_section not in ini_dict:
                for src_node in config['nodes'][src_layer]:
                    for tgt_node in config['nodes'][tgt_layer]:
                        edge = (src_node, tgt_node)
                        config['edges'][edge_layer].append(edge)
                continue

            # get edges from '[binding *]' section
            for src_node in ini_dict[edge_section]:
                src_node = src_node.strip()
                if src_node == '':
                    continue
                if src_node not in config['nodes'][src_layer]:
                    continue
                for tgt_node in ini_dict[edge_section][src_node]:
                    tgt_node = tgt_node.strip()
                    if tgt_node == '':
                        continue
                    if tgt_node not in config['nodes'][tgt_layer]:
                        continue
                    edge = (src_node, tgt_node)
                    if edge in config['edges'][edge_layer]:
                        continue
                    config['edges'][edge_layer].append(edge)

        # check network binding
        for i in range(len(config['layer']) - 1):
            src_layer = config['layer'][i]
            tgt_layer = config['layer'][i + 1]

            edge_layer = (src_layer, tgt_layer)
            if config['edges'][edge_layer] == []:
                raise Warning("""layer '%s' and
                    layer '%s' are not connected!""" % (src_layer, tgt_layer))

        return {'config': config}