Example #1
0
def create_modified_census(census):
    """
    This creates a cell census, with modifications, that is suitable
    for use as input to `simulate_water_quality`.

    For every type of cell that undergoes modification, the
    modifications are indicated with a sub-distribution under that
    cell type.
    """
    mod = copy.deepcopy(census)
    mod.pop('modifications', None)

    for (cell, subcensus) in mod['distribution'].items():
        n = subcensus['cell_count']

        changes = {
            'distribution': {
                cell: {
                    'distribution': {
                        cell: {
                            'cell_count': n
                        }
                    }
                }
            }
        }

        mod = dict_plus(mod, changes)

    for modification in (census.get('modifications') or []):
        for (orig_cell, subcensus) in modification['distribution'].items():
            n = subcensus['cell_count']
            soil1, land1 = orig_cell.split(':')
            soil2, land2, bmp = modification['change'].split(':')
            changed_cell = '%s:%s:%s' % (soil2 or soil1, land2 or land1, bmp)

            changes = {
                'distribution': {
                    orig_cell: {
                        'distribution': {
                            orig_cell: {
                                'cell_count': -n
                            },
                            changed_cell: {
                                'cell_count': n
                            }
                        }
                    }
                }
            }

            mod = dict_plus(mod, changes)

    return mod
Example #2
0
def create_modified_census(census):
    """
    This creates a cell census, with modifications, that is suitable
    for use as input to `simulate_water_quality`.

    For every type of cell that undergoes modification, the
    modifications are indicated with a sub-distribution under that
    cell type.
    """
    mod = copy.deepcopy(census)
    mod.pop('modifications', None)

    for (cell, subcensus) in mod['distribution'].items():
        n = subcensus['cell_count']

        changes = {
            'distribution': {
                cell: {
                    'distribution': {
                        cell: {'cell_count': n}
                    }
                }
            }
        }

        mod = dict_plus(mod, changes)

    for modification in (census.get('modifications') or []):
        for (orig_cell, subcensus) in modification['distribution'].items():
            n = subcensus['cell_count']
            soil1, land1 = orig_cell.split(':')
            soil2, land2, bmp = modification['change'].split(':')
            changed_cell = '%s:%s:%s' % (soil2 or soil1, land2 or land1, bmp)

            changes = {
                'distribution': {
                    orig_cell: {
                        'distribution': {
                            orig_cell: {'cell_count': -n},
                            changed_cell: {'cell_count': n}
                        }
                    }
                }
            }

            mod = dict_plus(mod, changes)

    return mod
Example #3
0
File: model.py Project: lliss/tr-55
def simulate_cell_year(cell, cell_count):
    """
    Simulate a cell-type for an entire year using sample precipitation and
    evapotranspiration data.

    The `cell` parameter is a string with the soil type and land use
    separated by a colon.

    The `cell_count` parameter is the number of cells of this type.

    If the `precolumbian` parameter is true, then the cell is
    simulated under Pre-Columbian circumstances (anything other than
    water, woody wetland, and herbaceous wetland becomes mixed
    forest).
    """
    split = cell.split(':')
    if (len(split) == 2):
        split.append('')
    land_use = split[1]
    bmp = split[2]

    retval = {}
    for day in range(365):
        (precip, evaptrans) = lookup_pet(day, bmp or land_use)
        result = simulate_cell_day(precip, evaptrans, cell, cell_count)
        retval = dict_plus(retval, result)
    return retval
Example #4
0
 def test_plus_3(self):
     """
     Test dictionary arithmetic.
     """
     a = {'x': {'y': {'z': {'a': 2, 'c': 13}, 'n': 144}}}
     b = {'x': {'y': None}}
     self.assertEqual(dict_plus(a, b), a)
Example #5
0
 def test_plus_3(self):
     """
     Test dictionary arithmetic.
     """
     a = {'x': {'y': {'z': {'a': 2, 'c': 13}, 'n': 144}}}
     b = {'x': {'y': None}}
     self.assertEqual(dict_plus(a, b), a)
Example #6
0
def simulate_cell_year(cell, cell_count, precolumbian):
    """
    Simulate a cell-type for an entire year using sample precipitation and
    evapotranspiration data.

    The `cell` parameter is a string with the soil type and land use
    separated by a colon.

    The `cell_count` parameter is the number of cells of this type.

    If the `precolumbian` parameter is true, then the cell is
    simulated under Pre-Columbian circumstances (anything other than
    water, woody wetland, and herbaceous wetland becomes mixed
    forest).
    """
    (soil_type, land_use) = cell.split(':')

    if precolumbian:
        land_use = make_precolumbian(land_use)
        cell = soil_type + ':' + land_use

    retval = {}
    for day in range(365):
        pet = lookup_pet(day, land_use)
        retval = dict_plus(retval, simulate_cell_day(pet, cell, cell_count))
    return retval
Example #7
0
 def test_plus_2(self):
     """
     Test dictionary arithmetic.
     """
     a = {'x': {'y': {'z': {'a': 2, 'c': 13}, 'n': 144}}}
     b = {'x': {'y': {'z': {'b': 8, 'c': 21}, 'm': 610}}}
     c = {'x': {'y': {'z': {'a': 2, 'b': 8, 'c': 34}, 'n': 144, 'm': 610}}}
     self.assertEqual(dict_plus(a, b), c)
Example #8
0
 def test_plus_2(self):
     """
     Test dictionary arithmetic.
     """
     a = {'x': {'y': {'z': {'a': 2, 'c': 13}, 'n': 144}}}
     b = {'x': {'y': {'z': {'b': 8, 'c': 21}, 'm': 610}}}
     c = {'x': {'y': {'z': {'a': 2, 'b': 8, 'c': 34}, 'n': 144, 'm': 610}}}
     self.assertEqual(dict_plus(a, b), c)
Example #9
0
File: model.py Project: lliss/tr-55
def simulate_water_quality(tree, cell_res, fn,
                           current_cell=None, precolumbian=False):
    """
    Perform a water quality simulation by doing simulations on each of
    the cell types (leaves), then adding them together by summing the
    values of a node's subtrees and storing them at that node.

    `tree` is the (sub)tree of cell distributions that is currently
    under consideration.

    `cell_res` is the size of each cell (used for turning inches of
    water into volumes of water).

    `fn` is a function that takes a cell type and a number of cells
    and returns a dictionary containing runoff, et, and inf as
    volumes.

    `current_cell` is the cell type for the present node.
    """
    # Internal node.
    if 'cell_count' in tree and 'distribution' in tree:
        n = tree['cell_count']

        # simulate subtrees
        if n != 0:
            tally = {}
            for cell, subtree in tree['distribution'].items():
                simulate_water_quality(subtree, cell_res, fn,
                                       cell, precolumbian)
                subtree_ex_dist = subtree.copy()
                subtree_ex_dist.pop('distribution', None)
                tally = dict_plus(tally, subtree_ex_dist)
                tree.update(tally)  # update this node

        # effectively a leaf
        elif n == 0:
            for pol in get_pollutants():
                tree[pol] = 0.0

    # Leaf node.
    elif 'cell_count' in tree and 'distribution' not in tree:
        n = tree['cell_count']
        split = current_cell.split(':')
        if (len(split) == 2):
            split.append('')
        if precolumbian:
            split[1] = make_precolumbian(split[1])

        result = fn('%s:%s:%s' % tuple(split), n)  # runoff, et, inf
        tree.update(result)

        # water quality
        if n != 0:
            soil_type, land_use, bmp = split
            runoff = result['runoff-vol'] / n
            liters = get_volume_of_runoff(runoff, n, cell_res)
            for pol in get_pollutants():
                tree[pol] = get_pollutant_load(land_use, pol, liters)
Example #10
0
def simulate_water_quality(tree, cell_res, fn,
                           parent_cell=None, current_cell=None):
    """
    Perform a water quality simulation by doing simulations on each
    type of cells (leaves), then adding them together going upward
    (summing the values of a node's subtrees and storing them at that
    node).

    `parent_cell` is the cell type (a string with a soil type and land
    use separated by a colon) of the parent of the present node in
    tree.

    `current_cell` is the cell type for the present node.

    `cell_res` is the size of each cell (used for turning inches of
    water into volumes of water).

    `tree` is the (sub)tree of cell distributions that is currently
    under consideration.

    `fn` is a function that takes a cell type and a number of cells
    and returns a dictionary containing runoff, et, and inf as
    volumes.  This typically just calls `simulate_cell_year`, but can
    be set to something else if e.g. a simulation over a different
    time-scale is desired.
    """
    # Internal node.
    if 'cell_count' in tree and 'distribution' in tree:
        # simulate subtrees
        tally = {}
        for cell, subtree in tree['distribution'].items():
            simulate_water_quality(subtree, cell_res, fn, current_cell, cell)
            subtree_ex_dist = subtree.copy()
            subtree_ex_dist.pop('distribution', None)
            tally = dict_plus(tally, subtree_ex_dist)

        # update this node
        tree.update(tally)

    # Leaf node.
    elif 'cell_count' in tree and 'distribution' not in tree:
        # runoff, et, inf
        n = tree['cell_count']
        result = fn(current_cell, n)
        tree.update(result)

        # water quality
        if n != 0:
            runoff = result['runoff-vol'] / n
            liters = get_volume_of_runoff(runoff, n, cell_res)
            land_use = current_cell.split(':')[1]
            if is_bmp(land_use) or land_use == 'no_till' or \
               land_use == 'cluster_housing':
                land_use = parent_cell.split(':')[1]
            for pol in get_pollutants():
                tree[pol] = get_pollutant_load(land_use, pol, liters)
Example #11
0
def simulate_water_quality(tree, cell_res, fn,
                           pct=1.0, current_cell=None, precolumbian=False):
    """
    Perform a water quality simulation by doing simulations on each of
    the cell types (leaves), then adding them together by summing the
    values of a node's subtrees and storing them at that node.

    `tree` is the (sub)tree of cell distributions that is currently
    under consideration.

    `pct` is the percentage of calculated water volume to retain.

    `cell_res` is the size of each cell (used for turning inches of
    water into volumes of water).

    `fn` is a function that takes a cell type and a number of cells
    and returns a dictionary containing runoff, et, and inf as
    volumes.

    `current_cell` is the cell type for the present node.
    """
    # Internal node.
    if 'cell_count' in tree and 'distribution' in tree:
        n = tree['cell_count']

        # simulate subtrees
        if n != 0:
            tally = {}
            for cell, subtree in tree['distribution'].items():
                simulate_water_quality(subtree, cell_res, fn,
                                       pct, cell, precolumbian)
                subtree_ex_dist = subtree.copy()
                subtree_ex_dist.pop('distribution', None)
                tally = dict_plus(tally, subtree_ex_dist)
            tree.update(tally)  # update this node

        # effectively a leaf
        elif n == 0:
            for pol in get_pollutants():
                tree[pol] = 0.0

    # Leaf node.
    elif 'cell_count' in tree and 'distribution' not in tree:
        # the number of cells covered by this leaf
        n = tree['cell_count']

        # canonicalize the current_cell string
        split = current_cell.split(':')
        if (len(split) == 2):
            split.append('')
        if precolumbian:
            split[1] = make_precolumbian(split[1])
        current_cell = '%s:%s:%s' % tuple(split)

        # run the runoff model on this leaf
        result = fn(current_cell, n)  # runoff, et, inf
        runoff_adjustment = result['runoff-vol'] - (result['runoff-vol'] * pct)
        result['runoff-vol'] -= runoff_adjustment
        result['inf-vol'] += runoff_adjustment
        tree.update(result)

        # perform water quality calculation
        if n != 0:
            soil_type, land_use, bmp = split
            runoff_per_cell = result['runoff-vol'] / n
            liters = get_volume_of_runoff(runoff_per_cell, n, cell_res)
            for pol in get_pollutants():
                tree[pol] = get_pollutant_load(land_use, pol, liters)