<jupyter_start><jupyter_text>Table of Contents1&nbsp;&nbsp;Intro2&nbsp;&nbsp;Run Test Simulation2.1&nbsp;&nbsp;Performances Profiling3&nbsp;&nbsp;Parameters Grid Search  Intro This notebook explores slime mold simulation and visualization. For an introduction to the phenomenon and method see [this sagejenson post](https://sagejenson.com/physarum)<jupyter_code>import numpy as np
import cupy as cp
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from collections import namedtuple
from itertools import starmap, product
import tqdm

import os
import sys
from pathlib import Path

%matplotlib inline

%load_ext autoreload
%autoreload 2

import Physarum as physarum
from Physarum import Physarum

from ds_utils.video_utils import generate_video, imageio_generate_video<jupyter_output><empty_output><jupyter_text>Run Test Simulation<jupyter_code>width = 400
height = 400
system_shape = (width, height)
init_fun_perlin=lambda shape: physarum.get_perlin_init(shape=shape, n=int(30e4), scale=380)
init_fun_circle=lambda shape: physarum.get_filled_circle_init(n=int(10e4), center=(shape[0]//2,shape[1]//2), 
                                             radius=100)
def combined_init(shape):
    pop_01 = physarum.get_filled_circle_init(n=int(10e4), center=(shape[0]//2,shape[1]//2), radius=100)
    pop_02 = physarum.get_perlin_init(shape=shape, n=int(30e4), scale=80)
    return np.concatenate([pop_01, pop_02])
species_a = Physarum(shape=system_shape, horizon_walk=1, horizon_sense=9,
                    theta_walk=15, theta_sense=10., walk_range=1.,
                    social_behaviour=0, trace_strength=1,
                    init_fun=combined_init)


species_b = Physarum(shape=system_shape, horizon_walk=1,horizon_sense=9,
                    theta_walk=15, theta_sense=10., walk_range=1.2,
                    social_behaviour=-16,trace_strength=1,
                    init_fun=init_fun_circle)
simulation_steps = 10
images = physarum.run_physarum_simulation(populations=[species_a], steps=simulation_steps)
out_path = Path.home() / 'Documents/graphics/generative_art_output/physarum/test_01'
out_path.mkdir(exist_ok=True, parents=True)
imageio_generate_video(str(out_path/"test_02.mp4"), images, fps=20, format="mp4", loop=False)
generate_video(str(out_path/"tmp.mp4"), (width, height),
               frame_gen_fun = lambda i: np.array(images[i])[:,:,:3],
               nb_frames = len(images))<jupyter_output><empty_output><jupyter_text>Performances Profiling<jupyter_code>%%prun -s cumulative -l 30 -r
# We profile the cell, sort the report by "cumulative
# time", limit it to 30 lines

simulation_steps = 50
images = physarum.run_physarum_simulation(populations=[species_b], steps=simulation_steps)<jupyter_output><empty_output><jupyter_text>Parameters Grid Search<jupyter_code>def named_configs(items):
    Config = namedtuple('Config', items.keys())
    return starmap(Config, product(*items.values()))
out_path = Path.home() /  'generative_art_output/physarum/grid_search'
NB_VALS = 3
grid_search_params = {
    'horizon_walk': np.linspace(1., 3., NB_VALS).round(2), # higher more spread, chaos
    'horizon_sense': np.linspace(10., 25., NB_VALS).round(2),
    'theta_sense': np.linspace(10., 25., NB_VALS).round(2), # the smaller, the more narrow paths they create
    'theta_walk': np.linspace(5., 15., NB_VALS).round(2), # should be close to theta_sense, if way bigger, they disappear or constrain to concentrated areas
    'walk_range': [1.],
    'social_behaviour': [0],
    'trace_strength': [1],
    'decay': [0.8], #np.linspace(.6, .9, NB_VALS)
}
configs = list(named_configs(grid_search_params))
import math
system_shape = (1000, 1000)
render_dir = out_path / f"gs_continuous_{system_shape[0]}"
nb_frames = 90

render_dir.mkdir(exist_ok=True, parents=True)

#init_setup = physarum.get_perlin_init(shape=system_shape, n=int(60e4), scale=150)
#init_setup = physarum.get_filled_circle_init(n=int(20e5), center=(system_shape[0]//2,system_shape[1]//2), radius=150)
def combined_init(shape):
    pop_01 = physarum.get_filled_circle_init(n=int(80e4), center=(shape[0]//2,shape[1]//2), radius=150)
    pop_02 = physarum.get_perlin_init(shape=shape, n=int(10e4), scale=200)
    #pop_01 = physarum.get_gaussian_gradient(n=int(10e4), center=(system_shape[0]//2,system_shape[1]//2), sigma=200)
    #pop_02 = physarum.get_circle_init(n=int(5e4), center=(shape[0]//2,shape[1]//2), radius=100, width=30)
    return cp.concatenate([pop_01, pop_02])
#init_setup = combined_init(system_shape)
init_setup = physarum.get_gaussian_gradient(n=int(50e5), center=(system_shape[0]//2,system_shape[1]//2), sigma=40)

imgs_path = "MAYBE_DUPLICATES/flat_hexa_logo/19"
#mask = physarum.get_image_mask(list(Path(img_path).glob('*.png'))[np.random.randint(15)], system_shape, threshold=0.5)

with open(str(render_dir / "logs.txt"), 'w+') as f:
    config = configs[0]
    system = Physarum(shape=system_shape, 
                  horizon_walk=config.horizon_walk,
                  horizon_sense=config.horizon_sense,
                  theta_walk=config.theta_walk,
                  theta_sense=config.theta_sense,
                  walk_range=config.walk_range,
                  social_behaviour=config.social_behaviour,
                  trace_strength=config.trace_strength,
                  init_fun=lambda shape: init_setup,
                  template=None, template_strength=0)
    for run, config in tqdm.tqdm_notebook(enumerate(configs)):
        imgs_path = f"MAYBE_DUPLICATES/flat_hexa_logo/{np.random.randint(5, 19)}"
        imgs_path = list(Path(imgs_path).glob('*.png'))
        img_path = imgs_path[np.random.randint(len(imgs_path))]
        #init_setup = physarum.get_image_init_positions(img_path, system_shape, int(80e4), invert=True)
        template = physarum.get_image_mask(img_path, system_shape, invert=False)
        template_strength = 1
        
        #config = config._replace(theta_walk = config.theta_sense-5)
        
        f.write(str(config)+"\n")
        SYSTEM_CONFIG = config._asdict()

        system.horizon_walk=config.horizon_walk
        system.horizon_sense=config.horizon_sense
        system.theta_walk=math.radians(config.theta_walk)
        system.theta_sense=math.radians(config.theta_sense)
        system.template_strength = template_strength
        system.template = cp.asarray(template)
        
        images = physarum.run_physarum_simulation(populations=[system], diffusion='median',
                                                  steps=nb_frames, decay=config.decay, mask=None, mask_factor=.5)
        
       
        # get array from cupy to numpy
        fix_images = cp.asnumpy(images)
        #fix_images = np.sqrt(fix_images + 0.1) - np.sqrt(0.1)
        #fix_images = np.log(fix_images + 1)
        res_images = np.uint8((fix_images / np.max(fix_images)) * 255)
        
        out = render_dir / f'run_{run}.mp4'
        #imageio_generate_video(str(out), images, fps=30, format="mp4", loop=False)
        
        #np.save(render_dir / f'run_{run}.npy', fix_images)
        
        generate_video(str(out), (system_shape[1], system_shape[0]),
               frame_gen_fun = lambda i: res_images[i],
               nb_frames = len(res_images), is_color=False, disable_tqdm=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12248253185367859, 'fraction_numerical': 0.03164817098232635, 'mean_word_length': 3.989747095010253, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '57048', 'license': 'Apache-2.0', 'n_tokens_mistral': 2691, 'n_tokens_neox': 2472, 'n_words': 417, 'path': 'graphics/physarum/Physarum.ipynb', 'repo_name': 'sugatoray/data-science-learning', 'size': '7299'}