WirVsVirus 2020 hackathon participation

Introduction

Last weekend – 2020-03-20 ÷ 2020-03-22 – I participated in the (Germany-centric) hackathon WirVsVirus. (I friend of mine who lives in Germany asked me to team up and sign up. Participated together with Balint Badonfai and Diego Zviovich.)

Our idea proposal was accepted, listed in the dedicated overview table (see item 806). The title of our hackathon project is:

“Geo-spatial-temporal Economic Model for COVID-19 Propagation and Management in Germany”

Nearly a dozen of people enlisted to help. (We communicated through Slack.)

WebImage["https://devpost.com/software/geo-raumlich-zeitliches-\
wirtschaftsmodell-fur-covid-19"]

Multiple people helped with the discussion of ideas, directions where to find data, with actual data gathering, and related documented analysis. Of course, just discussing the proposed solutions was already a great help!

What was accomplished

Work plans

The following mind-map reflects pretty well what was planned and done:

There is also a related org-mode file with the work plan.

Data

I obtained Germany city data with Mathematica’s build-in functions and used it to heuristically derive a traveling patterns graph, [AA1].

Here is the data:

dsCityRecords = 
  ResourceFunction["ImportCSVToDataset"][
 "https://raw.githubusercontent.com/antononcube/SystemModeling/master/Data/dfGermanyCityRecords.csv"];
Dimensions[dsCityRecords]

(*{12538, 6}*)

Here is Geo-histogram of that data:

cellRadius = Quantity[70, "Kilometers"];
aCoordsToPopulations = AssociationThread[Values /@ Normal[dsCityRecords[All, {"Lat", "Lon"}]], Normal[dsCityRecords[All, "Population"]]];
GeoHistogram[aCoordsToPopulations, cellRadius, ColorFunction -> (Opacity[#, Blue] &), PlotLegends -> Automatic]

We considered a fair amount of other data. But because of the time limitations of the hackathon we had to use only the one above.

Single-site models

During the development phase I used the model SEI2R, but since we wanted to have a “geo-spatial-temporal epidemiological economics model” I productized the implementation of SEI2HR-Econ, [AAp1].

Here are the stocks, rates, and equations of SEI2HR-Econ:

Magnify[ModelGridTableForm[SEI2HREconModel[t]], 0.85]

Multi-site SEI2R (SEI2HR-Econ) over a hexagonal grid graph

I managed to follow through with a large part of the work plan for the hackathon and make multi-site scaled model that “follows the money”, [AA1]. Here is a diagram that shows the travelling patterns graph and solutions at one of the nodes:

Here is an interactive interface for studying and investigating the solution results:

For more details see the notebook [AA1]. Different parameters can be set in the “Parameters” section. Especially of interest are the quarantine related parameters: start, duration, effect on contact rates and traffic patterns.

I also put simulations results code and programmed visualization routines in R, [AA2]. (In order other members of team to be able to explore the results.)

References

[DP1] 47_wirtschaftliche Auswirkung_Geo-spatial-temp-econ-modell, DevPost.

[WRI1] Wolfram Research, Inc., Germany city data records, (2020), SystemModeling at GitHub.

[AA1] Anton Antonov, “WirVsVirus hackathon multi-site SEI2R over a hexagonal grid graph”, (2020), SystemModeling at GitHub.

[AA2] Anton Antonov, “WirVsVirus-Hackathon in R”, (2020), SystemModeling at GitHub.

[AAp1] Anton Antonov, “Epidemiology models Mathematica package”, (2020), SystemsModeling at GitHub.

WirVsVirus-hackathon-Multi-site-SEI2R-over-a-hexagonal-grid-graph.nb (168 KB)

7 Likes

Absolute amazing work! Thanks for sharing.
The animation shows a second wave of infected people. Is that because of a relaxation in quaratine/travel bans?

Ideas:

  • we could add non-constant number of hospital beds. Do we have the data geometry-wise?
  • it would be nice to overlay the real-data on the individual cell predictions
  • tooltips with the area identifier (city/region/Landkreis) would be neat)
2 Likes

Thanks for your comments, Markus!

we could add non-constant number of hospital beds. Do we have the data geometry-wise?

Yes, that is the most important “next task” in my opinion. And Germany’s governmental sites provide very good, detailed information about hospital beds and workers. (One of our team members, who lives in Germany, demonstrated that to us.)

it would be nice to overlay the real-data on the individual cell predictions

Calibration is important, and it is a lot of work. At this point I want to make a better simulation tool, not (personally) spent that much time on calibration. Of course, with a better tool calibration and scenario play-out experiments are much easier.

tooltips with the area identifier (city/region/Landkreis) would be neat)

Ah, yes of course. That is in the next wave of work…

The animation shows a second wave of infected people. Is that because of a relaxation in quarantine/travel bans?

I think the second wave in the animation is “an illusion” – when I plot the individual animation slides the second wave is not seen. (The animation in the notebook is done by-vertex normalization, just to demonstrate model’s spatial propagation simulation abilities.)

1 Like

Here is my naive attempt to ome up with informative tooltips:

Tooltips

Following the definitions from the Notebook

lsCells = 
      Cases[grHist[[1]], 
       Tooltip[h_Polygon /; MatrixQ[h[[1]]], 
         pop_ /; NumberQ[pop] && pop > 3] :> <|"Cell" -> h, 
         "Population" -> pop|>, \[Infinity]];
 lsCells = 
      Map[Append[#, "Center" -> Mean[PolygonCoordinates[#["Cell"]]]] &, 
       lsCells];

And extrakting the plot dimensions and scaling:

absOps = AbsoluteOptions[grHist[1]];

We now have to scale between Geographic coordinates

GeoRange /. absOps

(* {{47.0295, 55.4005}, {5.5195, 15.4305}} *)

and GeoGridPositions

GeoGridRange /. absOps

(* {{5.5195, 15.4305}, {53.4218, 66.8345}} *)

The idea is to select largest cities from each bin (Polygon) and sow them together with their distance from the bin center. For this we need to scale between the coordinates and the geo grid used in the plot.

nlist = (Values /@ Normal[dsCityRecords]) /. {"Germany", b_, c_, d_, 
    e_, f_} :> {"Germany", b, c, d, Lon2X[f], Lat2Y[e]}

xyRange = GeoGridRange /. absOps
lonlatRange = Reverse[GeoRange /. absOps]
lonRescale[lon_] := Rescale[lon, xyRange[[1]], lonlatRange[[1]]]
latRescale[lon_] := Rescale[lon, xyRange[[2]], lonlatRange[[2]]]
rescaleLonLat[{lon_, lat_}] := {lonRescale[lon], latRescale[lat]}
X2Lon[x_] := Rescale[x, xyRange[[1]], lonlatRange[[1]]]
Y2Lat[y_] := Rescale[y, xyRange[[2]], lonlatRange[[2]]]
Lon2X[x_] := Rescale[x, lonlatRange[[1]], xyRange[[1]]]
Lat2Y[y_] := Rescale[y, lonlatRange[[2]], xyRange[[2]]]
LatLon2XY[{x_, y_}] := {Lon2X[y], Lat2Y[x]}

Let’s create the tooltips

tooltip = Table[
   numCities = 5;
   rmf = RegionMember[lsCells[[i]]["Cell"]];
   sel = Select[nlist, rmf[#[[-2 ;; -1]]] &];
   len = Min[{Length[sel], numCities}];
   selTake = Take[sel, len];
   dist = 
    Round@GeoDistance[XY2LatLon[lsCells[[i]]["Center"]], 
        XY2LatLon[#[[-2 ;; -1]]]] & /@ selTake;
   If[sel != {},
    Panel[
     TableForm[
      Flatten /@ Transpose[{selTake[[All, {2, 3, 4}]], dist}], 
      TableHeadings -> {None, {"Federal State", "City", "Population", 
         "Distance to ctr."}}]],
    Panel[
     TableForm[{{"", "", "", ""}}, 
      TableHeadings -> {None, {"Federal State", "City", "Population", 
         "Distance to ctr."}}]]], {i, 1, Length[lsCells]}];

and put them in an Association for easier replacement later

ttasoc = Association@
   Table[{lsCells[[i]]["Population"] -> 
      Panel[tooltip[[i]], 
       Style[lsCells[[i]]["Population"], Red, Bold], Top]}, {i, 1, 
     Length[lsCells]}];

Now we can jst replace the Tooltip from the original figure:

grHist /. Tooltip[p_Polygon, pop_?NumberQ] :> Tooltip[p, ttasoc[pop]]

This is not perfect. If you move over the hexagon belonging to the Berlin area we note, that Berlin is not within the Polygon.

The reason is most likely my simple-minded rescaling of the geo positions but I couldn’t figure out a better transformation. Maybe some GeoGraphics experts can help here

2 Likes

There is one type in the city csv file. Lline 7226 should read:

“Germany”,“RheinlandPalatinate”,“GemundenRheinlandPfalz”,1080,50.558889, 8.017778

Thanks for finding out this! Fixed now.

I noticed that outlier, that is why in the computation notebook I have code that removes outliers.

news-congrads-kkluyshnik-02-04-19.jpg – you have earned Featured Contributor Badge 2015-11-02_10-07-11.png

Your exceptional post has been selected for our editorial column Staff Picks http://wolfr.am/StaffPicks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you!

This post has been listed in the main resource-hub COVID-19 thread: https://wolfr.am/coronavirus in the section Computational Publications. Please feel free to add your own comment on that discussion pointing to this post ( WirVsVirus 2020 hackathon participation ) so many more interested readers will become aware of your excellent work. Thank you for your contribution!