<jupyter_start><jupyter_text>4 - Network Simulation II In this tutorial I show how we can combine several simulation iterations in order to find out what would have been the most likely paths.  imports<jupyter_code>import netsim.generate as ng
import netsim.utils as utils
import netsim.path_tools as ptools
import netsim.simulate as ns
import geopandas as gpd
import pandas as pd
import numpy as np
import rasterio as ro<jupyter_output><empty_output><jupyter_text>Reading files  *Read DEM*<jupyter_code>fn = r'..\data\sample\sampleDEM.tif'
dem, profile = utils.read_raster(fn)
#find the cellsize of the dem
cellsize = profile['transform'].a<jupyter_output><empty_output><jupyter_text>*Read shapefile into a geopandas dataframe*<jupyter_code>fn = r'..\data\sample\sample5.shp'<jupyter_output><empty_output><jupyter_text>read and make a copy of original dataframe<jupyter_code>df_temp = gpd.read_file(fn)

# make a copy
df = df_temp.copy(deep=True)
df<jupyter_output><empty_output><jupyter_text>Preliminaries  *Convert point coordinates into rows and column and add to dataframe*<jupyter_code>df['r'], df['c'] = utils.pt2rc(df['geometry'], profile)
df
# check values
df = ng.check(df)<jupyter_output>No corrections or errors !!<jupyter_text>*Plot locations*<jupyter_code>hillshade = utils.calculate_hillshade(dem)
utils.plot_map(raster = {'ras':dem, 'profile':profile, 'bground': hillshade},
               loc= {'df':df, 'label': 'id'},
               title='SampleDEM')<jupyter_output><empty_output><jupyter_text>create network generator<jupyter_code># create network generator
netgentor, net_info, total_iterations = ng.create_network_generator(df)<jupyter_output>iteration broken per group....

   group  num_loc  num_iter iter_type
0      1        6       100    sample

 total number of iterations.... 100<jupyter_text>Setup Simulation  *find coefficients for gradient to cost function*<jupyter_code># vertical factor table
vftfn = r'..\data\iwdt\grad2cost.csv'

# read file slope (tan) to cost
vft = np.genfromtxt(vftfn, delimiter=',')
# fit values to 4th degree polynomial and return coefficients
coef = np.polyfit(np.tan(np.radians(vft[: , 0])), vft[:,1], deg=4)
coef<jupyter_output><empty_output><jupyter_text>Set up cost dictionary<jupyter_code>cost_dict={
    'dem': dem,
    'netcost': np.zeros_like(dem),
    'cellsize': cellsize,
    'weight': 0.5,
    'coef': coef
}<jupyter_output><empty_output><jupyter_text>*calculate decay factor $\alpha$ for given $d_0$ and $NC_0$*We shall specify that at a distance of $d_0$=10m the network cost (i.e. the effect of the existing network) will decrease to $\frac{1}{2} $.<jupyter_code>from math import log

d0 = 10 # distance @ which 
NC0 = 0.5  # cost reduces to 50%
alpha = d0 / log(1- NC0)<jupyter_output><empty_output><jupyter_text>Set up netsim dictionary<jupyter_code>netsim_dict= {
    'i': 1.0,      # path impact
    'Gmax': 5.0,   # path saturation
    'T': 10,       # residuality 
    'alpha': alpha # decay factor 
    }<jupyter_output><empty_output><jupyter_text>Run *nsim* simulations<jupyter_code>progress = lambda i, n=10: print ('Processing: '+str(i//n), end = "") if i % n == 0 else print('.', end = "")
# number of iterations 
nsim = 5<jupyter_output><empty_output><jupyter_text>initialize variables<jupyter_code>all_path_lst = []
all_paths = np.zeros_like(dem)#, dtype=np.float64)
prev_id = 0
save_flag = False # Change to True if you want to save the result as an image
save_fn =  './all_paths'<jupyter_output><empty_output><jupyter_text>run simulations<jupyter_code>for isim in range(nsim):
    
    # progress
    progress(isim)
    
    # generate network iteration
    net_iteration = list(next(netgentor))
    
    # create path network layout for current iteration
    df_net = ng.network_layout(df, net_iteration, isim, opt='decentral')
    
    # simulate network
    _, paths, path_lst = ns.simulation(df, df_net, cost_dict, netsim_dict)
    
    # add current iteration path list to that of previous iterations 
    for pth in path_lst:
        pth['id'] += len(all_path_lst)
    all_path_lst += path_lst
    
    # generate dataframe output
    df_paths = pd.DataFrame(all_path_lst, columns=['id', 'origin','destination', 'track'])
    
    # add current path network to path networks from previous iterations
    all_paths += paths
    
    if save_flag:
        df_paths.to_pickle(save_fn)
        with ro.open( save_fn+'.tif', 'w', **profile) as ras:
            ras.write(all_paths, 1)<jupyter_output>Processing: 0....<jupyter_text>number of paths generated?<jupyter_code>len(df_paths)<jupyter_output><empty_output><jupyter_text>Plot the sum of all simulations i.e. 'all_paths'<jupyter_code>utils.plot_map(raster = {'ras':dem, 'profile':profile, 'paths': all_paths},
               loc= {'df' : df, 'label': 'id'},
               title= 'All Paths',
               cmap= 'inferno_r')<jupyter_output><empty_output><jupyter_text>Show the tracks of all paths generated<jupyter_code>df_paths<jupyter_output><empty_output><jupyter_text>For each path, sum values extracted from the 'all_paths'<jupyter_code># the default in paths_stats() is the sum() function 
df_paths = ptools.path_stats(df_paths, all_paths, df)<jupyter_output><empty_output><jupyter_text>For each pairing, select those paths that maximize the `sum()`Out of each of the five paths that have been generated for each pairing, we want the one for which the sum along its track of the values found in 'all_path' is the largest. This path would correspond to a path that goes along a well trodden area.<jupyter_code>df_max_paths = df_paths.loc[df_paths.groupby(['path_ids'])['sum'].idxmax()]
df_max_paths<jupyter_output><empty_output><jupyter_text>Plot resultsInstead of plotting all paths generated from all the simulations, we are plotting those that for each pairing, maximize the sum of the values found along each track.<jupyter_code>import matplotlib.pyplot as plt
import matplotlib as mpl

# calculate extension
bounds = profile['bounds']
extent = [bounds.left, bounds.right, bounds.bottom, bounds.top]

# plot image
cmap = mpl.cm.get_cmap('inferno_r')
fig, ax = plt.subplots(ncols= 1, figsize= (5,5))
im = ax.contourf(dem, 6, extent=extent, origin= 'upper', cmap= cmap, alpha=0.5)
for i, path in df_max_paths.iterrows():

    X = [pt[0] for pt in utils.rc2pt(path['track'], profile)]
    Y = [pt[1] for pt in utils.rc2pt(path['track'], profile)]
    ax.plot (X, Y, 'k-', alpha= 0.25)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11638330757341576, 'fraction_numerical': 0.010046367851622875, 'mean_word_length': 4.877384196185286, 'pattern_counts': {'":': 0, '<': 78, '<?xml version=': 0, '>': 78, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '79610', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2294, 'n_tokens_neox': 2216, 'n_words': 597, 'path': 'notebooks/4 - Network Simulation II.ipynb', 'repo_name': 'arokem/netsim', 'size': '6470'}