-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: count_ratio on non overlapping partitions (#886)
* fix: count_ratio on non overlapping partitions * fix: parallel array placement with offset #889 * docs: add first round of documentation on Placement and Indicators based on #858 * fix: re implement the original count_ratio strategy as a new local one.
- Loading branch information
Showing
9 changed files
with
525 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
========= | ||
Placement | ||
========= | ||
This block in the configuration is responsible for placing cells into partitions. | ||
All placement strategies derive from the :class:`~.placement.strategy.PlacementStrategy` class, | ||
and should provide functions to define the positions of each ``CellType`` within a ``Partition`` volume. | ||
|
||
BSB offers several built-in strategies (here is a :doc:`list </placement/placement-strategies>`), | ||
or you can implement your own. | ||
The placement data is stored in :doc:`PlacementSets </placement/placement-set>` for each cell type. | ||
|
||
Add a placement strategy | ||
======================== | ||
|
||
In the ``placement`` block, all placement strategies are defined. For each strategy, | ||
it is necessary to specify the references to their related :guilabel:`partitions` and :guilabel:`cell_types` | ||
with the corresponding attributes. | ||
|
||
.. tab-set-code:: | ||
|
||
.. code-block:: json | ||
"placement": { | ||
"place_A_in_my_layer": { | ||
"strategy": "bsb.placement.RandomPlacement", | ||
"partitions": [ | ||
"my_layer" | ||
], | ||
"cell_types": [ | ||
"A_type" | ||
] | ||
} | ||
} | ||
.. code-block:: python | ||
config.placement.add( | ||
"place_A_in_my_layer", | ||
strategy="bsb.placement.RandomPlacement", | ||
partitions=["my_layer"], | ||
cell_types=["A_type"], | ||
) | ||
Use indications | ||
=============== | ||
|
||
When a cell type is created, it is possible to define spatial attributes called | ||
:doc:`placement indications</placement/placement-indicators>`. | ||
These attributes are used by the placement strategy to determine the distribution of cells within the volume. | ||
|
||
.. tab-set-code:: | ||
|
||
.. code-block:: json | ||
"cell_types": { | ||
"A_type": { | ||
"spatial": { | ||
"density": 0.005, | ||
"radius": 2.5 | ||
} | ||
}, | ||
"B_type": { | ||
"spatial": { | ||
"count": 50, | ||
"radius": 5 | ||
} | ||
} | ||
} | ||
"placement": { | ||
"place_A_and_B_in_my_layer": { | ||
"strategy": "bsb.placement.RandomPlacement", | ||
"partitions": [ | ||
"my_layer" | ||
], | ||
"cell_types": [ | ||
"A_type","B_type" | ||
] | ||
} | ||
} | ||
.. code-block:: python | ||
config.cell_types.add( | ||
"A_type", | ||
spatial=dict(radius=2.5, density=0.005) | ||
) | ||
config.cell_types.add( | ||
"B_type", | ||
spatial=dict(radius=5, count=50) | ||
) | ||
config.placement.add( | ||
"place_A_and_B_in_my_layer", | ||
strategy="bsb.placement.RandomPlacement", | ||
partitions=["my_layer"], | ||
cell_types=["A_type","B_type"], | ||
) | ||
In this example, type A cells are placed with a density of 0.005 cells/µm^3, | ||
while we place 50 type B cells with a radius of 5 µm. | ||
|
||
|
||
Add dependencies to Placement Strategies | ||
======================================== | ||
|
||
It may be necessary to place a set of cells only after specific strategies have been executed. | ||
In such cases, you can define a list of strategies as dependencies. | ||
For example, you can create a :guilabel:`secondary_placement` that is executed only after the | ||
:guilabel:`place_A_and_B_in_my_layer` placement has been completed. | ||
|
||
|
||
.. tab-set-code:: | ||
|
||
.. code-block:: json | ||
"placement": { | ||
"secondary_placement": { | ||
"strategy": "bsb.placement.RandomPlacement", | ||
"partitions": [ | ||
"my_layer" | ||
], | ||
"cell_types": [ | ||
"C_type" | ||
], | ||
"depends_on": ["place_A_and_B_in_my_layer"] | ||
} | ||
} | ||
.. code-block:: python | ||
config.placement.add( | ||
"secondary_placement", | ||
strategy="bsb.placement.RandomPlacement", | ||
partitions=["my_layer"], | ||
cell_types=["C_type"], | ||
depends_on=["place_A_and_B_in_my_layer"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
##################### | ||
Placement Indications | ||
##################### | ||
|
||
`Placement indications` are a subpart of the a ``CellType`` configuration (attribute ``spatial`` of :doc:`/cells/intro`) | ||
and is leveraged to specify properties during `placement strategies` (see :doc:`/placement/placement-strategies`). | ||
These indications can be either related to the cell type itself (e.g. its soma radius) or | ||
allow for the estimation of the number of cells to place in their respective partitions. | ||
|
||
|
||
General cell properties | ||
----------------------- | ||
These attributes are related to the ``CellType``; among them, only ``radius`` is mandatory: | ||
|
||
* :guilabel:`radius`: The radius of the sphere used to approximate cell soma volume. | ||
* :guilabel:`geometry`: dict = config.dict(type=types.any_()) | ||
* :guilabel:`morphologies`: List of morphologies references. | ||
|
||
Cell counts estimation properties | ||
--------------------------------- | ||
The following attributes allow you to set the strategy used to estimate the counts of cell to place in each partition. | ||
You can choose either to compute the counts independently or with respect to another placement counts. | ||
|
||
.. warning:: | ||
BSB rounds the number of cells to place in each partition's chunk. The rounding is stochastic, therefore you | ||
might not get the same counts of cells for two similar reconstructions. | ||
|
||
Independent counts estimation strategies | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
You can choose one of the following attributes to estimate the number of cells to place in its partition(s). | ||
|
||
* :guilabel:`count`: Set directly the number of cells to place. | ||
* :guilabel:`density`: Use a density of cell per unit of volume (in cell/um^-3). This will be converted to counts | ||
based on the partition(s) total volume. | ||
* :guilabel:`planar_density`: Use a density of cell along the `xy` plane per unit of area (in cell/um^-2). Here too, | ||
density is converted to counts thanks to the partition(s) area along the `xy` plane. | ||
* :guilabel:`density_key`: Leverage a density file, defined here with a reference to a `partitions.keys` | ||
(see `Voxels` section in :doc:`/topology/partitions`). The number of cells is derived from this volumetric density | ||
file for each of its voxels. | ||
|
||
Relative counts estimation strategies | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
These strategies derives the counts of cells to place from on another ``CellType`` placement. You would need therefore | ||
to specify the cell name as a reference: | ||
|
||
* :guilabel:`relative_to`: Reference to a ``CellType``. | ||
|
||
And then, you can choose one of the following attributes: | ||
|
||
* :guilabel:`count_ratio`: Compute the number of cells to place from the ratio between the current cell type | ||
and a reference cell type. | ||
* :guilabel:`local_count_ratio`: Same as ``count_ratio`` but applied only on chunks that the current cell type and the | ||
reference cell type have in common. | ||
* :guilabel:`density_ratio`: Similar to ``count_ratio`` but use density instead of cell count. | ||
|
||
.. note:: | ||
You can mix counts and densities: | ||
For instance, you can have a cell A which counts is relative to the one of another cell type B, and B being defined | ||
from a density value. | ||
|
||
|
||
Full example | ||
~~~~~~~~~~~~ | ||
|
||
.. tab-set-code:: | ||
|
||
.. code-block:: json | ||
"regions": { | ||
"my_region": { | ||
"type": "stack", | ||
"children": ["my_layer", "my_second_layer"], | ||
} | ||
} | ||
"partitions": { | ||
"my_layer": { | ||
"thickness": 100 | ||
}, | ||
"my_second_layer": { | ||
"thickness": 200 | ||
}, | ||
} | ||
"cell_types": { | ||
"A": { | ||
"spatial": { | ||
"count": 10, | ||
"radius": 2 | ||
} | ||
}, | ||
"B": { | ||
"spatial": { | ||
"relative_to": "A", | ||
"density_ratio": 1.5, | ||
"radius": 3 | ||
} | ||
} | ||
}, | ||
"placement": { | ||
"place_A":{ | ||
"strategy": "bsb.placement.RandomPlacement", | ||
"partitions": ["my_layer"], | ||
"cell_types": ["A"], | ||
}, | ||
"place_B":{ | ||
"strategy": "bsb.placement.RandomPlacement", | ||
"partitions": ["my_second_layer"], | ||
"cell_types": ["B"], | ||
} | ||
}, | ||
.. code-block:: python | ||
config.partitions.add("my_layer", type="layer", thickness=100) | ||
config.partitions.add("my_second_layer", type="layer", thickness=200) | ||
config.regions.add( | ||
"my_region", | ||
type="stack", | ||
children=["my_layer", "my_second_layer"] | ||
) | ||
config.cell_types.add( | ||
"A", | ||
spatial=dict(radius=2, count=10) | ||
) | ||
config.cell_types.add( | ||
"B", | ||
spatial=dict(radius=3, relative_to="A", density_ratio=1.5) | ||
) | ||
config.placement.add( | ||
"place_A", | ||
strategy="bsb.placement.RandomPlacement", | ||
partitions=["my_layer"], | ||
cell_types=["A"], | ||
) | ||
config.placement.add( | ||
"place_B", | ||
strategy="bsb.placement.RandomPlacement", | ||
partitions=["my_second_layer"], | ||
cell_types=["B"], | ||
) | ||
The example configuration above creates two Layer partitions (``my_layer`` and ``my_second_layer``) | ||
and assigns a random position to ``A`` and ``B`` within their respective layer. | ||
Assuming that ``my_layer`` is big enough to contains both cells | ||
(see :doc:`RandomPlacement strategy</placement/placement-strategies>`), this will place 10 ``A`` and 30 | ||
``B`` because the volume of ``my_second_layer`` :math:`v_2` is twice the one of ``my_layer`` :math:`v_1` | ||
and so: | ||
|
||
.. math:: | ||
\begin{split} | ||
counts_{B} & = density_{A} \cdot 1.5 \cdot v_2 \\ | ||
& = \dfrac{10}{v_1} \cdot 1.5 \cdot 2 \cdot v_1 \\ | ||
& = 10 \cdot 1.5 \cdot 2 \\ | ||
& = 30 | ||
\end{split} |
Oops, something went wrong.