Epidemic Simulation Problem

Hi everyone,

I have been developing a simulation tool in grasshopper + python to simulate the spread of a disease in a city, for my architecture masters thesis project.

The model is made up of:
HOME points (where people live, leave and return to each day)
PLACE points (where people go to and come back from each day)
PATH network (curves/polylines connecting them together, representing pavements/sidewalks and paths).

The model works by generating “people” (points) on the HOME points, calculating their closest PLACE (closest point component) and figuring out the route to get there (shortest walk component), the route (curve) is then divided 200 times, and a python script counts from 0 to 2400 (24hrs), moving the point along the curve in 200 “steps” to the PLACE and back at specific times (E.g. 700=>900, 1500=>1700).

PROBLEM:
The problem I have is that the “person” is a new point instance at each step, instead of being the SAME point moving along the curve and back, so if the point gets INFECTED (python script evaluating proximity to an infected point), it doesn’t stay infected, as the next instance is a new point (i.e. noninfected).

Essentially I need a way of the points acting as agents with a state/characteristic which changes over time like:

NONINFECTED => INFECTED => IMMUNE.

So Problem is: I need Points as Agents that move, not copied as new instances

Sorry if this sounds really confusing, but I really hope someone can help me out!
Thanks in advance guys,

Henry

Resim T1.gh (78.7 KB)

1 Like

Hi.
You didn’t internalize your data… so it is impossible to try your definition.

But, more important: it seems you didn’t use any form of iteration!

For simulations like this one here, you’ll need to make iterations, “each minute” or such.
Without any kind of iteration, i’m not surprised it is not working.

I would suggest you trying a simpler case first.
Even a simple “billiard” with an infected ball that infect other balls as it touches them.

1 Like

Take a look at the Anenome plugin too. This might help as it can do loops and pass data back to the start of the loop.

2 Likes

on this epidemic simulation topic, here is a very nice script from the awesome Long Nguyen written in C# (GH definition is downloadable and inspectable, link in the video description)

3 Likes

Hi Riccardo, thank you for your response!
I have attached another version with the curves internalised, which is the only geometry it needs to simulate the points moving. This version is a test before the version I posted before.

The model uses a python script that cycles through the integers 0 → 2400 with each count taking 10ms, each 100 steps represent 60 mins - so these are the iterations I think you’re referring to?

Thank you!

Resim Internalised.gh (733.2 KB) Resim vertical.3dm (3.7 MB)

Hi Martyn, yeah I had a look at that a while back, but found it a little limiting as everything refreshes after each loop? I may be wrong, I’ll definitely have another go with it

Cheers!

1 Like

Hi! yeah I’ve had this downloaded and been referring back to it, although I’m not that great with C# haha.

With this model the points are in fixed locations and don’t move, the problem I have is that my points are moving from place to place, and so new instances are created each time, so if the point gets “infected” - it doesn’t stay infected. Maybe I am just missing something glarringly obvious at this point, I am only just getting to grips with python.

Thanks for the response though!

That is just creating a value that change over time, no different from a manual slider.
You need to have some place where to store information and then use that information on the next iteration. That, over and over.

Your definition is not iterative.

Again, I suggest you to try with something really simple first.
Anemone, if you want to do everything with grasshopper.
C# or python if you want to have the iteration happening inside the script.

Generally speaking, when modelling dynamic systems you need at least:

A) Some persistent variable mechanism (i.e. to manage the state of your system/agents)
B) Some update mechanism (i.e. to step the system into the next iteration)

In GHPython, problem A can be solved using at least two methods: Notably the component local if "foo" not in globals() method, and the Rhino global sticky method. Both are covered in this old thread, and I’d recommend using the former, unless you need to read the system from outside the component where you iterate it. Problem B can of course be solved using a timer/trigger, or by scripting the component to update itself (recent example here).

I wrote some more notes in this topic here:

And I’d highly recommend going through @diff-arch’s excellent learning example provided here:

4 Likes

Thank you! :heart_eyes:

1 Like

Here a mini example of storing values with c#:
mini epidemic


mini epidemic.gh (11.0 KB)

In this case it doesn’t iterate, but the c# simply re-calculates every time the input changes (the points moving) and check for distances and update “infected” statuses if in infection occurs.

Code:

private void RunScript(List<Point3d> Person, List<bool> Initial_status, double Infection_dist, bool Reset, ref object Statuses)
  {
    if(Reset){
      statuses = Initial_status;
      return;
    }
    for(int i = 0;i < Person.Count;i++){
      if(statuses[i]){ // if true it means that the person people[i] is infected! So let's search for people to infect!
        for(int j = 0;j < Person.Count;j++){ // now we search between all people for adjacency, anyone near enough will become infected
          if(i != j){ // skipping if testing a person on itself
            double dist = Person[i].DistanceTo(Person[j]);
            if(dist < Infection_dist){
              statuses[j] = true;
            }
          }
        }
      }
    }
    Statuses = statuses;
  }

  // <Custom additional code> 
  public List<bool> statuses;
  // </Custom additional code> 
}
6 Likes

Hi Riccardo, sorry it’s taken me a while, you’re absolutely right. I went back to the drawing board a little (with my deadline looming, I thought I needed a simpler strategy).

So I ended up not making it a “simulation” at all, as the people had rigid daily routines - I realised I was able to just plot their “journeys” with time in the z axis, similar to a Marey Chart. Where the intersections of each curve (each curve = person) being where interactions take place, therefore potentially = infections.

I’m actually posting a new problem that I’ve run into, I would love your help on that, as I need to now record the infections per day cycle in a more simpler way.

Thanks for your help though, much appreciated.

This is a really interesting method, so thank you, just wish I could code in C# a bit better haha.

Hey @henrygeorgebaker.96,

I post my script here, because it’s more appropriate than in the other thread, where you asked something different!

It’s a simple pandemic simulation written in GhPython, where each dot is an agent and its color informs about its general health: light green (mediocre) to bright green (great), and yellow (bad) to red (even worse).

2021-04-17 13-31-12.2021-04-17 13_33_50

There’s a system of predefined routes (polylines) within a line network (roads, ways, etc.) and initial positions (route start points).
Each agent walks its route from from to back. Many routes intersect and overlap where agents can meet and transmit diseases.

Sick movers have a certain radius (social distancing) proportional to their bad health. If a healthy agent gets within that radius, and it has only mediocre health the risk of infection is high. If it however has good or great health, its immune system only takes a hit, but an infection doesn’t happen.

After the simulation is done, you can display which mover has infected which agents.

Feel free to take it for a spin. :slight_smile:

pan_sim.gh (33.4 KB)

2 Likes

Hey,

I really don’t know what to say! - This in incredible, this is pretty much exactly what we envisaged at the start of the project but due to our skill level with gh+python - weren’t really able to achieve it.

Thank you, your script is ideal for me to go through and learn from, I have spent some time going through it and the python side is particularly interesting, although very complex.

The method of different health states is great although wouldn’t it still be possible for a very healthy person to still catch the virus? Otherwise, I think the only problem is my computer not being able to run it on a large site model haha.

I know this probably a really stupid question but the colours don’t seem to show up when I run it - do you know why that mght be?

No idea, I’m an architect, not a virologist! :wink: I just thought it would make sense to make movers with a very good health, immune to some degree, like it turned out to be with COVID. Some people caught the virus, but didn’t manifest any symptoms - up to now at least -, whereas others got servilely ill, and many unfortunately even died from it.

Your observation is also not exactly right. Even very healthy agents take a hit each time they encounter an infected one, to be exact 5% of there health is deducted. This means that if an healthy agent repetitively comes into contact with infect ones, it will eventually get sick, too. In reality, immune people probably can never get sick from the virus strain they are resistant to, unless it mutates.

Depends on the scale, but millions of agents won’t be possible in Rhino (in my opinion).
Currently the nearest neighbour searches that establish closest, healthy movers for the infected ones to contaminate, are probably the slowest operations.
They could however be sped up quite a bit by using a fast algorithm - like r-tree - instead of checking all agents for all agents, like I currently do.
How big are we talking?

No idea? I re-downloaded the file I uploaded earlier, but it works fine for me.
What do you see? Do you see anything? Are you using Rhino 7? What’s your document scale (mine is in mm)? Do you have “preview only selected” on in Grasshopper?

These three components should be turned on. To view the colored particles and the infection radii of the contaminated ones.

Have you reset (button) the Python simulation component before running it for the first time?

Here’s another one. So fun! I love me some particles in the evening!

Wow, this really shows - even-though it’s not a super scientific simulation - why social distancing, lockdown measures, curfews, masks, increased hygiene, and all of these measures are absurdly necessary!

Screenshot 2021-04-17 at 20.16.33 Screenshot 2021-04-17 at 20.18.00

For a population of 125 agents, a single, infected one managed to contaminate 43.2% of the healthy population!

Turns out 12 infected (9.6%) is enough to contaminate nearly the entire population (96.0%).

Screenshot 2021-04-17 at 20.29.02 Screenshot 2021-04-17 at 20.31.10

Here’s version 2 of the pandemic simulation GHPython script.

What’s new?

  • r-tree nearest neighbour search is now implemented and should make everything faster and support more movers
  • 1% of the mover population is now considered immune (can’t be infected) and is displayed in blue

pandemic_sim_V2.gh (211.4 KB)

1 Like

Hey, sorry I haven’t responded sooner, had a tricky week with things outside this project. The population size for our site has to reach 15,000, although our model is achieving nearer 20,000.

I just realised I was using a different display style, that I don’t shows material colour, that’s all haha my bad.

Otherwise, again, I am super greatful for this, it is really interesting seeing how many different ways there are to tackling the same problem. This one being really intuitive!