Create a histogram of agent attributes¶

Author: Lukas Breitwieser
In this tutorial we will show how to create a histogram of all agent diameters in the simulation and fit a function to the data.

Let's start by setting up BioDynaMo notebooks.

In [1]:
%jsroot on
gROOT->LoadMacro("${BDMSYS}/etc/rootlogon.C");
INFO: Created simulation object 'simulation' with UniqueName='simulation'.

We want to define a function that creates a cell at a certain position with diameters drawn from a gaussian distribution with μ=20μ=20 and σ=5σ=5. The smallest diameter should be larger then 2.02.0.

In [2]:
simulation.GetResourceManager()->ClearAgents();
auto rng = simulation.GetRandom()->GetGausRng(20, 5);
auto create_cell = [&](const Real3& position) {
  Cell* cell = new Cell(position);
  real_t diameter = std::max(2.0, rng.Sample());
  cell->SetDiameter(diameter);
  return cell;
};

Now that we defined create_cell we can use it to create 400 cells on a plane with z=0z=0, xmin=ymin=−200xmin=ymin=−200, xmax=ymax=200xmax=ymax=200, and spacing = 20 in both dimensions.

In [3]:
auto f = [](const real_t* x, const real_t* params) { return 0.0; };
ModelInitializer::CreateAgentsOnSurface(f, {}, -200, 200, 20, -200, 200, 20, 
                                        create_cell);
simulation.GetScheduler()->FinalizeInitialization();
VisualizeInNotebook(300, 300);
ROOT canvasToggle tool buttonsCreate PNG (keyshortcut Ctrl PrintScreen)Access context menusEnlarge canvasToggle GedToggle Status

The next step is to create a histogram object with 100 bins in the interval [2, 40].
The second line creates a function which fills the histogram with the diameter of the given agent.
The third line calls the function fill for each agent, thus adding all diameters to the histogram.

In [4]:
TH1F h("myHisto","Agent Diameter Histogram;Diameter;Count", 100, 2, 40);
auto fill = L2F([&](Agent* a, AgentHandle){ h.Fill(a->GetDiameter()); });
simulation.GetResourceManager()->ForEachAgent(fill);
input_line_117:3:1: warning: 'fill' shadows a declaration with the same name in the 'std' namespace; use '::fill' to reference this declaration
auto fill = L2F([&](Agent* a, AgentHandle){ h.Fill(a->GetDiameter()); });
^

Let's draw the final histogram.
Before we have to create a TCanvas object in order to display the result in this notebook.
We also modify the default color and create a grid.

In [5]:
TCanvas c("", "", 400, 300);
h.SetFillColor(kBlue - 10);
c.SetGrid();
h.Draw();
c.Draw();
ROOT canvas510152025303540Diameter024681012141618CountmyHistoEntries 400Mean 19.83Std Dev 5.197Agent Diameter HistogramToggle tool buttonsCreate PNG (keyshortcut Ctrl PrintScreen)Access context menusEnlarge canvasToggle GedToggle StatusToggle between unzoom and autozoom-in (keyshortcut Ctrl *)Toggle log x (keyshortcut PageDown)Toggle log y (keyshortcut PageUp)Toggle stat box

Finally, we can try to fit a function to the data in the histogram.
Since we drew samples from a gaussian random number generator when we created our cells, we expect that a gaussian will fit our data.

In [6]:
h.Fit("gaus", "S");
h.Draw();
c.Draw();
ROOT canvas510152025303540Diameter024681012141618CountmyHistoEntries 400Mean 19.83Std Dev 5.197Agent Diameter HistogramToggle tool buttonsCreate PNG (keyshortcut Ctrl PrintScreen)Access context menusEnlarge canvasToggle GedToggle StatusToggle between unzoom and autozoom-in (keyshortcut Ctrl *)Toggle log x (keyshortcut PageDown)Toggle log y (keyshortcut PageUp)Toggle stat box
****************************************
Minimizer is Minuit2 / Migrad
Chi2                      =      73.1872
NDf                       =           63
Edm                       =  3.38341e-08
NCalls                    =           79
Constant                  =      9.50544   +/-   0.709907    
Mean                      =      19.7314   +/-   0.323457    
Sigma                     =      5.40166   +/-   0.317423     	 (limited)