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)
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!
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:
Thank you!
Here a mini example of storing values with c#:
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>
}
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).
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.
pan_sim.gh (33.4 KB)
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! 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!
For a population of 125 agents, a single, infected one managed to contaminate 43.2% of the healthy population!
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)
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!
This is so cool! You can definitely tell how much faster it is when you ramp it up to about 1000 agents haha.
A have a few questions, out of curiosity, if thats ok?
How long have you been using gy/python to get to this level? As seeing how effective this is at tackling this problem, it is something I would love to keep learning.
I tried to test this out with polyline routes that are also in the z axis; our model has agents starting at their home points - which could be in a flat in a tower block, i.e. at say 100m elevation. To which the tool then generates a line vertically downwards to start the route. However, when doing this the script crashes - I’m guessing it just wasn’t meant to be used in 3D?
Ooo actually another question - I tried editing the scipt a little so that each agent starts their journey at different times, so that it represents a day cycle with each person having a set routine. (and therefore a set destination, and set departure time e.g. +500 “steps”). But got nowhere haha - how would you go about achieving this?
I’ve started learning Python maybe 6 to 7 six years ago. It’s hard to exactly pinpoint when.
I didn’t start in Rhino though, but rather because I was interested in learning how to program. At that time I had only very little experience (and incentive). Only some HTML and CSS, because my friends and I liked to do homepages for fun in high school.
The first couple of years, I remember doing exercises and tutorials here and there from time to time, but I didn’t take it too seriously. I did like the idea of knowing how to program, but really had no idea what to do as a project. Thus progress was really slow.
Later at university, I was often times confronted with geometrical problems related to experimental architecture that weren’t easy to do with vanilla Grasshopper, Maya, or other software, and that rekindled my interest in Python, Processing, and later C++.
Eh, I would have to check, but theoretically everything should be fit for 3d. Maybe the GHPython component that computes the routes doesn’t work in a three-dimensional context? Could you upload an example?
Yes, the particle system could for instance have a steps counter attribute that gets incremented each time that it gets updated (maybe it has already?). Each mover now should get a delay attribute that you can set randomly, when it is first created.
Then when updating the particle system, you can check for each mover, whether its delay is bigger than the particle systems general steps count, and only update it then.
This should do the trick!