From 5829a8b3afef6e750c2acc6ae72623543d8497a4 Mon Sep 17 00:00:00 2001 From: Kwabena N Amponsah Date: Tue, 28 Nov 2023 03:00:52 +0000 Subject: [PATCH 1/3] Fix markdown and jupyter generation --- doc/tutorials/TestCellSortingTutorial.ipynb | 105 +- doc/tutorials/TestCellSortingTutorial.md | 13 +- .../TestCellSortingTutorial.nbconvert.ipynb | 327 +++++++ ...shBasedCellSimulationsPythonTutorial.ipynb | 55 +- ...tMeshBasedCellSimulationsPythonTutorial.md | 13 +- ...lSimulationsPythonTutorial.nbconvert.ipynb | 578 +++++++++++ ...deBasedCellSimulationsPythonTutorial.ipynb | 97 +- ...tNodeBasedCellSimulationsPythonTutorial.md | 63 +- ...lSimulationsPythonTutorial.nbconvert.ipynb | 780 +++++++++++++++ ...tsBasedCellSimulationsPythonTutorial.ipynb | 86 +- ...PottsBasedCellSimulationsPythonTutorial.md | 13 +- ...lSimulationsPythonTutorial.nbconvert.ipynb | 905 ++++++++++++++++++ doc/tutorials/TestScratchAssayTutorial.ipynb | 32 +- doc/tutorials/TestScratchAssayTutorial.md | 13 +- .../TestScratchAssayTutorial.nbconvert.ipynb | 392 ++++++++ doc/tutorials/TestSpheroidTutorial.ipynb | 39 +- doc/tutorials/TestSpheroidTutorial.md | 13 +- .../TestSpheroidTutorial.nbconvert.ipynb | 403 ++++++++ doc/tutorials/TestTensileTestTutorial.ipynb | 37 +- doc/tutorials/TestTensileTestTutorial.md | 27 +- .../TestTensileTestTutorial.nbconvert.ipynb | 323 +++++++ ...exBasedCellSimulationsPythonTutorial.ipynb | 97 +- ...ertexBasedCellSimulationsPythonTutorial.md | 70 +- ...lSimulationsPythonTutorial.nbconvert.ipynb | 585 +++++++++++ infra/CreateJupyterNotebookTutorial.py | 2 - infra/CreateMarkdownTutorial.py | 25 +- infra/GenerateWikiPages.py | 21 +- 27 files changed, 4854 insertions(+), 260 deletions(-) create mode 100644 doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb create mode 100644 doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb diff --git a/doc/tutorials/TestCellSortingTutorial.ipynb b/doc/tutorials/TestCellSortingTutorial.ipynb index 35a78214..5e83ab81 100644 --- a/doc/tutorials/TestCellSortingTutorial.ipynb +++ b/doc/tutorials/TestCellSortingTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "5e20c6f8", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestCellSortingTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestCellSortingTutorial.py.\n", "\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, + "id": "bbb0d35b", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "f35ee21c", "metadata": {}, "source": [ "\n", @@ -37,7 +40,8 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, + "id": "e799e1ff", "metadata": {}, "outputs": [], "source": [ @@ -52,6 +56,7 @@ }, { "cell_type": "markdown", + "id": "fc92979c", "metadata": {}, "source": [ "## Test 1 - Cell sorting\n", @@ -62,7 +67,8 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, + "id": "74ed5bea", "metadata": {}, "outputs": [], "source": [ @@ -72,6 +78,7 @@ }, { "cell_type": "markdown", + "id": "cc82f214", "metadata": {}, "source": [ "First, we generate a `Potts` mesh. To create a `PottsMesh`, we can use the `PottsMeshGenerator`.\n", @@ -82,7 +89,8 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, + "id": "4f11a779", "metadata": {}, "outputs": [], "source": [ @@ -92,6 +100,7 @@ }, { "cell_type": "markdown", + "id": "1d268b5f", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we the `CellsGenerator` helper class,\n", @@ -101,7 +110,8 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, + "id": "44155fe5", "metadata": {}, "outputs": [], "source": [ @@ -112,6 +122,7 @@ }, { "cell_type": "markdown", + "id": "f9af144b", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -120,7 +131,8 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, + "id": "5c623dbf", "metadata": {}, "outputs": [], "source": [ @@ -132,6 +144,7 @@ }, { "cell_type": "markdown", + "id": "55e259f6", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -140,7 +153,8 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, + "id": "99595a86", "metadata": {}, "outputs": [], "source": [ @@ -149,6 +163,7 @@ }, { "cell_type": "markdown", + "id": "c1e1d793", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -157,7 +172,8 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, + "id": "02402f5d", "metadata": {}, "outputs": [], "source": [ @@ -166,6 +182,7 @@ }, { "cell_type": "markdown", + "id": "13d55a5d", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a VtkScene so that we can\n", @@ -175,7 +192,8 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, + "id": "74aac9f9", "metadata": {}, "outputs": [], "source": [ @@ -183,11 +201,12 @@ "scene.SetCellPopulation(cell_population)\n", "scene.GetCellPopulationActorGenerator().SetShowPottsMeshEdges(True)\n", "nb_manager = chaste.visualization.JupyterNotebookManager()\n", - "#nb_manager.vtk_show(scene, height=600)" + "nb_manager.vtk_show(scene, height=600)" ] }, { "cell_type": "markdown", + "id": "ed38349c", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -196,7 +215,8 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, + "id": "0860691b", "metadata": {}, "outputs": [], "source": [ @@ -208,6 +228,7 @@ }, { "cell_type": "markdown", + "id": "469b27f0", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -219,7 +240,8 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, + "id": "add6d2da", "metadata": {}, "outputs": [], "source": [ @@ -231,6 +253,7 @@ }, { "cell_type": "markdown", + "id": "a77c25d6", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -239,7 +262,8 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, + "id": "1b4f58bf", "metadata": {}, "outputs": [], "source": [ @@ -254,6 +278,7 @@ }, { "cell_type": "markdown", + "id": "7623f5fa", "metadata": {}, "source": [ "Set up plotting\n", @@ -262,7 +287,8 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, + "id": "633de4b6", "metadata": {}, "outputs": [], "source": [ @@ -274,6 +300,7 @@ }, { "cell_type": "markdown", + "id": "e3f26e6c", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -282,57 +309,19 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, + "id": "431f0fcb", "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "Unable to convert function return value to a Python type! The signature was\n\t(self: chaste.visualization._chaste_project_PyChaste_visualization.VtkScene2) -> vtkSmartPointer", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mscene\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mStart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0msimulator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# Tear down the test\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mchaste\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcell_based\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTearDownNotebookTest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Code/chaste-build/projects/PyChaste/python/chaste/visualization/fortests.py\u001b[0m in \u001b[0;36mUpdateAtEndOfTimeStep\u001b[0;34m(self, cell_population)\u001b[0m\n\u001b[1;32m 179\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 180\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutput_format\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'png'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 181\u001b[0;31m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplotting_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvtk_show\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGetVtkScene\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput_format\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutput_format\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 182\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplotting_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvtk_show\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGetVtkScene\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput_format\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutput_format\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Code/chaste-build/projects/PyChaste/python/chaste/visualization/fortests.py\u001b[0m in \u001b[0;36mvtk_show\u001b[0;34m(self, scene, width, height, output_format, increment)\u001b[0m\n\u001b[1;32m 132\u001b[0m \u001b[0mrenderWindow\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvtk\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvtkRenderWindow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 133\u001b[0m \u001b[0mrenderWindow\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSetOffScreenRendering\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 134\u001b[0;31m \u001b[0mrenderWindow\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mAddRenderer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mscene\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGetRenderer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 135\u001b[0m \u001b[0mrenderWindow\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSetSize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheight\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 136\u001b[0m \u001b[0mrenderWindow\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mRender\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: Unable to convert function return value to a Python type! The signature was\n\t(self: chaste.visualization._chaste_project_PyChaste_visualization.VtkScene2) -> vtkSmartPointer" - ] - } - ], + "outputs": [], "source": [ "scene.Start()\n", "simulator.Solve()\n", "# Tear down the test \n", "chaste.cell_based.TearDownNotebookTest()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, + "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestCellSortingTutorial.md b/doc/tutorials/TestCellSortingTutorial.md index ca58a7cb..e73f6d08 100644 --- a/doc/tutorials/TestCellSortingTutorial.md +++ b/doc/tutorials/TestCellSortingTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Cell Sorting Tutorial +title : "Test Cell Sorting Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestCellSortingTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestCellSortingTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestCellSortingTutorial.py . Note that the code is given in full at the bottom of the page. diff --git a/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb b/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb new file mode 100644 index 00000000..5e83ab81 --- /dev/null +++ b/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb @@ -0,0 +1,327 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5e20c6f8", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestCellSortingTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbb0d35b", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "f35ee21c", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "This test is a demonstration of cell sorting using a Cellular Potts based framework.\n", + "It shows:\n", + " * How to set up a Potts simulation\n", + " * Working with labels\n", + " \n", + "## The Test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e799e1ff", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt # Plotting\n", + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "chaste.init() # Set up MPI\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.visualization # Visualization tools" + ] + }, + { + "cell_type": "markdown", + "id": "fc92979c", + "metadata": {}, + "source": [ + "## Test 1 - Cell sorting\n", + "The next test generates a collection of cells, there are two types of cells, labelled ones and non labelled ones,\n", + "there is differential adhesion between the cell types. For the parameters specified, the cells sort into separate types.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74ed5bea", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "cc82f214", + "metadata": {}, + "source": [ + "First, we generate a `Potts` mesh. To create a `PottsMesh`, we can use the `PottsMeshGenerator`.\n", + "This generates a regular square-shaped mesh, in which all elements are the same size.\n", + "We have chosen an 8 by 8 block of elements each consisting of 4 by 4 ( = 16) lattice sites.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f11a779", + "metadata": {}, + "outputs": [], + "source": [ + "generator = chaste.mesh.PottsMeshGenerator2(50, 8, 4, 50, 8, 4)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "1d268b5f", + "metadata": {}, + "source": [ + "Having created a mesh, we now create some cells. To do this, we the `CellsGenerator` helper class,\n", + "as before but this time the third argument is set to make all cells non-proliferative.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44155fe5", + "metadata": {}, + "outputs": [], + "source": [ + "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), differentiated_type)" + ] + }, + { + "cell_type": "markdown", + "id": "f9af144b", + "metadata": {}, + "source": [ + "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c623dbf", + "metadata": {}, + "outputs": [], + "source": [ + "label = chaste.cell_based.CellLabel()\n", + "for eachCell in cells:\n", + " if(chaste.core.RandomNumberGenerator.Instance().ranf()<0.5):\n", + " eachCell.AddCellProperty(label)" + ] + }, + { + "cell_type": "markdown", + "id": "55e259f6", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99595a86", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.PottsBasedCellPopulation2(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "c1e1d793", + "metadata": {}, + "source": [ + "In order to visualize labelled cells we need to use the following command.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02402f5d", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddCellWriterCellLabelWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "13d55a5d", + "metadata": {}, + "source": [ + "PyChaste can do simple 3D rendering with VTK. We set up a VtkScene so that we can\n", + "see the population evovle in real time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74aac9f9", + "metadata": {}, + "outputs": [], + "source": [ + "scene= chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "scene.GetCellPopulationActorGenerator().SetShowPottsMeshEdges(True)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "ed38349c", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0860691b", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OnLatticeSimulation2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestCellSorting\")\n", + "simulator.SetEndTime(20.0)\n", + "simulator.SetSamplingTimestepMultiple(10)" + ] + }, + { + "cell_type": "markdown", + "id": "469b27f0", + "metadata": {}, + "source": [ + "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", + "For this test, we use two update rules based upon a volume constraint (`VolumeConstraintPottsUpdateRule`) and\n", + "differential adhesion between cells (`DifferentialAdhesionPottsUpdateRule`), set appropriate parameters, and\n", + "pass them to the `OnLatticeSimulation`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "add6d2da", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule = chaste.cell_based.VolumeConstraintPottsUpdateRule2()\n", + "volume_constraint_update_rule.SetMatureCellTargetVolume(16)\n", + "volume_constraint_update_rule.SetDeformationEnergyParameter(0.2)\n", + "simulator.AddUpdateRule(volume_constraint_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "a77c25d6", + "metadata": {}, + "source": [ + "We repeat the process for any other update rules.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b4f58bf", + "metadata": {}, + "outputs": [], + "source": [ + "differential_adhesion_update_rule = chaste.cell_based.DifferentialAdhesionPottsUpdateRule2()\n", + "differential_adhesion_update_rule.SetLabelledCellLabelledCellAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetLabelledCellCellAdhesionEnergyParameter(0.11)\n", + "differential_adhesion_update_rule.SetCellCellAdhesionEnergyParameter(0.02)\n", + "differential_adhesion_update_rule.SetLabelledCellBoundaryAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetCellBoundaryAdhesionEnergyParameter(0.16)\n", + "simulator.AddUpdateRule(differential_adhesion_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "7623f5fa", + "metadata": {}, + "source": [ + "Set up plotting\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "633de4b6", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(1000)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "e3f26e6c", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "431f0fcb", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb index 27df954c..acd897ca 100644 --- a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "6cf38449", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "78a54faf", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "0fdfa329", "metadata": {}, "source": [ "\n", @@ -36,6 +39,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ff1ee8e0", "metadata": {}, "outputs": [], "source": [ @@ -50,6 +54,7 @@ }, { "cell_type": "markdown", + "id": "c2491c88", "metadata": {}, "source": [ "## Test 1 - a basic mesh-based simulation\n", @@ -61,6 +66,7 @@ { "cell_type": "code", "execution_count": null, + "id": "210ebf6d", "metadata": {}, "outputs": [], "source": [ @@ -70,6 +76,7 @@ }, { "cell_type": "markdown", + "id": "3f4f3522", "metadata": {}, "source": [ "Next, we generate a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator`.\n", @@ -81,6 +88,7 @@ { "cell_type": "code", "execution_count": null, + "id": "5ab92270", "metadata": {}, "outputs": [], "source": [ @@ -91,6 +99,7 @@ }, { "cell_type": "markdown", + "id": "cbeca5d9", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class,\n", @@ -106,6 +115,7 @@ { "cell_type": "code", "execution_count": null, + "id": "5b8c2617", "metadata": {}, "outputs": [], "source": [ @@ -117,6 +127,7 @@ }, { "cell_type": "markdown", + "id": "8a1dcbc0", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -128,6 +139,7 @@ { "cell_type": "code", "execution_count": null, + "id": "620e351c", "metadata": {}, "outputs": [], "source": [ @@ -137,6 +149,7 @@ }, { "cell_type": "markdown", + "id": "147c533d", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly\n", @@ -147,6 +160,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8589369f", "metadata": {}, "outputs": [], "source": [ @@ -155,6 +169,7 @@ }, { "cell_type": "markdown", + "id": "3a4dcab5", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -164,6 +179,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c0f77f6b", "metadata": {}, "outputs": [], "source": [ @@ -175,6 +191,7 @@ }, { "cell_type": "markdown", + "id": "b276615a", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -184,6 +201,7 @@ { "cell_type": "code", "execution_count": null, + "id": "bc525e8b", "metadata": {}, "outputs": [], "source": [ @@ -194,6 +212,7 @@ }, { "cell_type": "markdown", + "id": "946a0a4c", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step. In this case we can use the following method,\n", @@ -205,6 +224,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ef73deac", "metadata": {}, "outputs": [], "source": [ @@ -213,6 +233,7 @@ }, { "cell_type": "markdown", + "id": "2dac6feb", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the centres of each cell in a cell population.\n", @@ -225,6 +246,7 @@ { "cell_type": "code", "execution_count": null, + "id": "931523c7", "metadata": {}, "outputs": [], "source": [ @@ -234,6 +256,7 @@ }, { "cell_type": "markdown", + "id": "11448f81", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -243,6 +266,7 @@ { "cell_type": "code", "execution_count": null, + "id": "affdc54e", "metadata": {}, "outputs": [], "source": [ @@ -254,6 +278,7 @@ }, { "cell_type": "markdown", + "id": "560a1728", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -263,6 +288,7 @@ { "cell_type": "code", "execution_count": null, + "id": "95fa8575", "metadata": {}, "outputs": [], "source": [ @@ -275,6 +301,7 @@ }, { "cell_type": "markdown", + "id": "255d0f3b", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", @@ -288,6 +315,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9686d4c8", "metadata": {}, "outputs": [], "source": [ @@ -297,6 +325,7 @@ }, { "cell_type": "markdown", + "id": "f7426d6e", "metadata": {}, "source": [ "We start by generating a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator` as before.\n", @@ -308,6 +337,7 @@ { "cell_type": "code", "execution_count": null, + "id": "88275ef3", "metadata": {}, "outputs": [], "source": [ @@ -318,6 +348,7 @@ }, { "cell_type": "markdown", + "id": "1a9c80ca", "metadata": {}, "source": [ "We only want to create cells to attach to real nodes, so we use the method `GetCellLocationIndices` to get the\n", @@ -328,6 +359,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e6493fe9", "metadata": {}, "outputs": [], "source": [ @@ -336,6 +368,7 @@ }, { "cell_type": "markdown", + "id": "d1e1597a", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class again.\n", @@ -347,6 +380,7 @@ { "cell_type": "code", "execution_count": null, + "id": "20888bc0", "metadata": {}, "outputs": [], "source": [ @@ -358,6 +392,7 @@ }, { "cell_type": "markdown", + "id": "2607ea2f", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -371,6 +406,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1937cc88", "metadata": {}, "outputs": [], "source": [ @@ -381,6 +417,7 @@ }, { "cell_type": "markdown", + "id": "869b73d9", "metadata": {}, "source": [ "Again Paraview output is explicitly requested.\n", @@ -390,6 +427,7 @@ { "cell_type": "code", "execution_count": null, + "id": "06c453ce", "metadata": {}, "outputs": [], "source": [ @@ -398,6 +436,7 @@ }, { "cell_type": "markdown", + "id": "2a788286", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -407,6 +446,7 @@ { "cell_type": "code", "execution_count": null, + "id": "6575394a", "metadata": {}, "outputs": [], "source": [ @@ -418,6 +458,7 @@ }, { "cell_type": "markdown", + "id": "487429d4", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time.\n", @@ -427,6 +468,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2e95fa6e", "metadata": {}, "outputs": [], "source": [ @@ -438,6 +480,7 @@ }, { "cell_type": "markdown", + "id": "03d7f873", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -447,6 +490,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e791fda8", "metadata": {}, "outputs": [], "source": [ @@ -458,6 +502,7 @@ }, { "cell_type": "markdown", + "id": "311f5e5f", "metadata": {}, "source": [ "Again we create a force law, and pass it to the `OffLatticeSimulation`.\n", @@ -468,6 +513,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2b71eeed", "metadata": {}, "outputs": [], "source": [ @@ -477,6 +523,7 @@ }, { "cell_type": "markdown", + "id": "bb87dfbe", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -486,6 +533,7 @@ { "cell_type": "code", "execution_count": null, + "id": "492e478b", "metadata": {}, "outputs": [], "source": [ @@ -495,6 +543,7 @@ }, { "cell_type": "markdown", + "id": "1ff18229", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -505,6 +554,7 @@ { "cell_type": "code", "execution_count": null, + "id": "78eeef35", "metadata": {}, "outputs": [], "source": [ @@ -514,6 +564,7 @@ }, { "cell_type": "markdown", + "id": "2f61c37c", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", @@ -523,5 +574,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.md b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.md index 4cc9879d..e54cd5b9 100644 --- a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.md +++ b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Mesh Based Cell Simulations Python Tutorial +title : "Test Mesh Based Cell Simulations Python Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestMeshBasedCellSimulationsPythonTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py . Note that the code is given in full at the bottom of the page. diff --git a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb new file mode 100644 index 00000000..acd897ca --- /dev/null +++ b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -0,0 +1,578 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6cf38449", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78a54faf", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "0fdfa329", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "In this tutorial we show how Chaste can be used to create, run and visualize mesh-based simulations.\n", + "Full details of the mathematical model can be found in van Leeuwen et al. (2009) [doi:10.1111/j.1365-2184.2009.00627.x].\n", + "\n", + "## Imports and Setup\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ff1ee8e0", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt # Plotting\n", + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "chaste.init() # Set up MPI\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.visualization # Visualization tools" + ] + }, + { + "cell_type": "markdown", + "id": "c2491c88", + "metadata": {}, + "source": [ + "## Test 1 - a basic mesh-based simulation\n", + "In the first test, we run a simple mesh-based simulation,\n", + "in which we create a monolayer of cells, using a mutable mesh. Each cell is assigned a stochastic cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "210ebf6d", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "3f4f3522", + "metadata": {}, + "source": [ + "Next, we generate a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator`.\n", + "This generates a honeycomb-shaped mesh, in which all nodes are equidistant. Here the first and second arguments define the size of the mesh -\n", + "we have chosen a mesh that is 4 nodes (i.e. cells) wide, and 4 nodes high.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ab92270", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestMeshBasedCellSimulationsTutorial\")\n", + "generator = chaste.mesh.HoneycombMeshGenerator(4, 4)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "cbeca5d9", + "metadata": {}, + "source": [ + "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class,\n", + "which is specialized by the type of cell cycle model required (here `UniformCellCycleModel`) and the dimension.\n", + "For a list of possible cell cycle models see subclasses of `AbstractCellCycleModel`.\n", + "Note that some of these models will require information on the surrounding medium such as Oxygen concentration to work,\n", + "see specific class documentation for details. We create an empty vector of cells and pass this into the method along with the mesh.\n", + "The second argument represents the size of that the list of cells should become - one cell for each node,\n", + "the third argument specifies the proliferative type of the cell.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b8c2617", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(),\n", + " transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "8a1dcbc0", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", + "In general, this class associates a collection of cells with a mesh. For this test, because we have a `MutableMesh`,\n", + "we use a particular type of cell population called a `MeshBasedCellPopulation`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "620e351c", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.MeshBasedCellPopulation2_2(mesh,\n", + " cells)" + ] + }, + { + "cell_type": "markdown", + "id": "147c533d", + "metadata": {}, + "source": [ + "To view the results of this and the next test in Paraview it is necessary to explicitly\n", + "generate the required .vtu files.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8589369f", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddPopulationWriterVoronoiDataWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "3a4dcab5", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0f77f6b", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "b276615a", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc525e8b", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestMeshBasedCellSimulationsTutorial\")\n", + "simulator.SetEndTime(10.0)" + ] + }, + { + "cell_type": "markdown", + "id": "946a0a4c", + "metadata": {}, + "source": [ + "For longer simulations, we may not want to output the results every time step. In this case we can use the following method,\n", + "to print results every 12 time steps instead. As the default time step used by the simulator is 30 seconds,\n", + "this method will cause the simulator to print results every 6 minutes (or 0.1 hours).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef73deac", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.SetSamplingTimestepMultiple(12)" + ] + }, + { + "cell_type": "markdown", + "id": "2dac6feb", + "metadata": {}, + "source": [ + "We must now create one or more force laws, which determine the mechanics of the centres of each cell in a cell population.\n", + "For this test, we use one force law, based on the spring based model, and pass it to the `OffLatticeSimulation`.\n", + "For a list of possible forces see subclasses of `AbstractForce`. Note that some of these forces are not compatible with mesh-based simulations,\n", + "see the specific class documentation for details. If you try to use an incompatible class then you will receive a warning.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "931523c7", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce2_2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "11448f81", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "affdc54e", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "560a1728", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95fa8575", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "scene.End()\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "255d0f3b", + "metadata": {}, + "source": [ + "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", + "\n", + "## Test 2 - a basic mesh-based simulation with ghost nodes\n", + "In the second test, we run a simple mesh-based simulation with ghost nodes, in which we create a monolayer of cells, using a mutable mesh.\n", + "Each cell is assigned a stochastic cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9686d4c8", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "f7426d6e", + "metadata": {}, + "source": [ + "We start by generating a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator` as before.\n", + "Here the first and second arguments define the size of the mesh - we have chosen a mesh that is 2 nodes (i.e. cells) wide,\n", + "and 2 nodes high. The third argument specifies the number of layers of ghost nodes to make.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88275ef3", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestMeshBasedCellPopulationWithGhostNodes\")\n", + "generator = chaste.mesh.HoneycombMeshGenerator(5, 5, 2)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "1a9c80ca", + "metadata": {}, + "source": [ + "We only want to create cells to attach to real nodes, so we use the method `GetCellLocationIndices` to get the\n", + "indices of the real nodes in the mesh. This will be passed in to the cell population later on.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6493fe9", + "metadata": {}, + "outputs": [], + "source": [ + "locs = generator.GetCellLocationIndices()" + ] + }, + { + "cell_type": "markdown", + "id": "d1e1597a", + "metadata": {}, + "source": [ + "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class again.\n", + "This time the second argument is different and is the number of real nodes in the mesh.\n", + "As before all cells have `TransitCellProliferativeType`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20888bc0", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(len(locs),\n", + " transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "2607ea2f", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", + "In general, this class associates a collection of cells with a set of elements or a mesh.\n", + "For this test, because we have a `MutableMesh`, and ghost nodes we use a particular type of cell population called\n", + "a `MeshBasedCellPopulationWithGhostNodes`. The third argument of the constructor takes a vector of the indices of the real nodes\n", + "and should be the same length as the vector of cell pointers.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1937cc88", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.MeshBasedCellPopulationWithGhostNodes2(mesh,\n", + " cells,\n", + " locs)" + ] + }, + { + "cell_type": "markdown", + "id": "869b73d9", + "metadata": {}, + "source": [ + "Again Paraview output is explicitly requested.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06c453ce", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddPopulationWriterVoronoiDataWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "2a788286", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6575394a", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "scene.GetCellPopulationActorGenerator().SetShowVoronoiMeshEdges(True)\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "487429d4", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e95fa6e", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestMeshBasedCellPopulationWithGhostNodes\")\n", + "simulator.SetEndTime(10.0)\n", + "simulator.SetSamplingTimestepMultiple(12)" + ] + }, + { + "cell_type": "markdown", + "id": "03d7f873", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e791fda8", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(300)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "311f5e5f", + "metadata": {}, + "source": [ + "Again we create a force law, and pass it to the `OffLatticeSimulation`.\n", + "This force law ensures that ghost nodes don't exert forces on real nodes but real nodes exert forces on ghost nodes.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b71eeed", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce2_2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "bb87dfbe", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "492e478b", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()" + ] + }, + { + "cell_type": "markdown", + "id": "1ff18229", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78eeef35", + "metadata": {}, + "outputs": [], + "source": [ + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "2f61c37c", + "metadata": {}, + "source": [ + "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", + "\n" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb index 07f3621f..0253e618 100644 --- a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "c1be3946", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "dcd83472", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "f4d7e6dd", "metadata": {}, "source": [ "\n", @@ -36,6 +39,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8d34a397", "metadata": {}, "outputs": [], "source": [ @@ -49,6 +53,7 @@ }, { "cell_type": "markdown", + "id": "37286ec9", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -60,6 +65,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b7077ffc", "metadata": {}, "outputs": [], "source": [ @@ -69,6 +75,7 @@ }, { "cell_type": "markdown", + "id": "c3cfec3f", "metadata": {}, "source": [ "The first thing we do is generate a nodes only mesh. To do this we first create a `MutableMesh` to use as a generating mesh.\n", @@ -80,6 +87,7 @@ { "cell_type": "code", "execution_count": null, + "id": "85578e5e", "metadata": {}, "outputs": [], "source": [ @@ -90,6 +98,7 @@ }, { "cell_type": "markdown", + "id": "99336452", "metadata": {}, "source": [ "Once we have a MutableMesh we can generate a NodesOnlyMesh from it using the following commands.\n", @@ -100,6 +109,7 @@ { "cell_type": "code", "execution_count": null, + "id": "31fa8c51", "metadata": {}, "outputs": [], "source": [ @@ -108,6 +118,7 @@ }, { "cell_type": "markdown", + "id": "3d20db6a", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in `ConstructNodesWithoutMesh`),\n", @@ -118,6 +129,7 @@ { "cell_type": "code", "execution_count": null, + "id": "5ae2bd30", "metadata": {}, "outputs": [], "source": [ @@ -126,6 +138,7 @@ }, { "cell_type": "markdown", + "id": "5efc27fe", "metadata": {}, "source": [ "Having created a mesh, we now create a (wrapped) vector of CellPtrs. To do this, we use the `CellsGenerator` helper class,\n", @@ -139,17 +152,18 @@ { "cell_type": "code", "execution_count": null, + "id": "e2ecc8c4", "metadata": {}, "outputs": [], "source": [ "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(),\n", - " transit_type)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)" ] }, { "cell_type": "markdown", + "id": "3b05d4ca", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -161,15 +175,16 @@ { "cell_type": "code", "execution_count": null, + "id": "43e339e8", "metadata": {}, "outputs": [], "source": [ - "cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh,\n", - " cells)" + "cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, cells)" ] }, { "cell_type": "markdown", + "id": "614090ff", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -179,6 +194,7 @@ { "cell_type": "code", "execution_count": null, + "id": "d441f8b7", "metadata": {}, "outputs": [], "source": [ @@ -190,6 +206,7 @@ }, { "cell_type": "markdown", + "id": "2f461c92", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -199,6 +216,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2e257f3f", "metadata": {}, "outputs": [], "source": [ @@ -210,6 +228,7 @@ }, { "cell_type": "markdown", + "id": "858b1279", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -219,6 +238,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8b6a8e65", "metadata": {}, "outputs": [], "source": [ @@ -228,6 +248,7 @@ }, { "cell_type": "markdown", + "id": "1b3cde60", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -237,6 +258,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4370d079", "metadata": {}, "outputs": [], "source": [ @@ -248,6 +270,7 @@ }, { "cell_type": "markdown", + "id": "9cb5a9fd", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -257,6 +280,7 @@ { "cell_type": "code", "execution_count": null, + "id": "24b5bfa0", "metadata": {}, "outputs": [], "source": [ @@ -267,6 +291,7 @@ }, { "cell_type": "markdown", + "id": "98637fcb", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -277,6 +302,7 @@ { "cell_type": "code", "execution_count": null, + "id": "095ce225", "metadata": {}, "outputs": [], "source": [ @@ -286,6 +312,7 @@ }, { "cell_type": "markdown", + "id": "2597efaf", "metadata": {}, "source": [ "## Test 2 - a basic node-based simulation in 3D\n", @@ -297,6 +324,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4f8f6402", "metadata": {}, "outputs": [], "source": [ @@ -306,6 +334,7 @@ }, { "cell_type": "markdown", + "id": "ec16c4f5", "metadata": {}, "source": [ "First, we generate a nodes only mesh. This time we specify the nodes manually by first creating a vector of nodes\n", @@ -315,6 +344,7 @@ { "cell_type": "code", "execution_count": null, + "id": "3662e0e2", "metadata": {}, "outputs": [], "source": [ @@ -328,6 +358,7 @@ }, { "cell_type": "markdown", + "id": "7ef828a0", "metadata": {}, "source": [ "Finally a NodesOnlyMesh is created and the vector of nodes is passed to the ConstructNodesWithoutMesh method.\n", @@ -337,6 +368,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9029d2d0", "metadata": {}, "outputs": [], "source": [ @@ -345,6 +377,7 @@ }, { "cell_type": "markdown", + "id": "e95300f5", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -355,6 +388,7 @@ { "cell_type": "code", "execution_count": null, + "id": "61f4f064", "metadata": {}, "outputs": [], "source": [ @@ -363,6 +397,7 @@ }, { "cell_type": "markdown", + "id": "7cbd6d28", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs.\n", @@ -373,17 +408,18 @@ { "cell_type": "code", "execution_count": null, + "id": "e94362a4", "metadata": {}, "outputs": [], "source": [ "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(),\n", - " transit_type)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)" ] }, { "cell_type": "markdown", + "id": "b4b198bd", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -395,15 +431,16 @@ { "cell_type": "code", "execution_count": null, + "id": "3cad7ba8", "metadata": {}, "outputs": [], "source": [ - "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh,\n", - " cells)" + "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells)" ] }, { "cell_type": "markdown", + "id": "fd9c6232", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -413,6 +450,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8ef252ff", "metadata": {}, "outputs": [], "source": [ @@ -423,6 +461,7 @@ }, { "cell_type": "markdown", + "id": "376f3387", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -432,6 +471,7 @@ { "cell_type": "code", "execution_count": null, + "id": "0546c735", "metadata": {}, "outputs": [], "source": [ @@ -443,6 +483,7 @@ }, { "cell_type": "markdown", + "id": "edb6a531", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -452,6 +493,7 @@ { "cell_type": "code", "execution_count": null, + "id": "04b02d89", "metadata": {}, "outputs": [], "source": [ @@ -461,6 +503,7 @@ }, { "cell_type": "markdown", + "id": "a183d74c", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -470,6 +513,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e532a662", "metadata": {}, "outputs": [], "source": [ @@ -481,6 +525,7 @@ }, { "cell_type": "markdown", + "id": "b1a59ff5", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -490,6 +535,7 @@ { "cell_type": "code", "execution_count": null, + "id": "5b1aa5d2", "metadata": {}, "outputs": [], "source": [ @@ -500,6 +546,7 @@ }, { "cell_type": "markdown", + "id": "1db1e70a", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -510,16 +557,17 @@ { "cell_type": "code", "execution_count": null, + "id": "cbcccf30", "metadata": {}, "outputs": [], "source": [ - " 10.0, 6)\n", "# Tear down the test \n", "chaste.cell_based.TearDownNotebookTest()" ] }, { "cell_type": "markdown", + "id": "8b718848", "metadata": {}, "source": [ "## Test 3 - a node-based simulation on a restricted geometry\n", @@ -531,6 +579,7 @@ { "cell_type": "code", "execution_count": null, + "id": "107c3c95", "metadata": {}, "outputs": [], "source": [ @@ -540,6 +589,7 @@ }, { "cell_type": "markdown", + "id": "36e7797a", "metadata": {}, "source": [ "In the third test we run a node-based simulation restricted to the surface of a sphere.\n", @@ -549,6 +599,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4432292d", "metadata": {}, "outputs": [], "source": [ @@ -563,6 +614,7 @@ }, { "cell_type": "markdown", + "id": "56119cfe", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -573,20 +625,20 @@ { "cell_type": "code", "execution_count": null, + "id": "10c19934", "metadata": {}, "outputs": [], "source": [ "mesh.ConstructNodesWithoutMesh(nodes, 1.5)\n", "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(),\n", - " transit_type)\n", - "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh,\n", - " cells)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)\n", + "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells)" ] }, { "cell_type": "markdown", + "id": "e4330483", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -596,6 +648,7 @@ { "cell_type": "code", "execution_count": null, + "id": "11237f3b", "metadata": {}, "outputs": [], "source": [ @@ -610,6 +663,7 @@ }, { "cell_type": "markdown", + "id": "f69e6f1e", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -619,6 +673,7 @@ { "cell_type": "code", "execution_count": null, + "id": "44951122", "metadata": {}, "outputs": [], "source": [ @@ -628,6 +683,7 @@ }, { "cell_type": "markdown", + "id": "75ca15e7", "metadata": {}, "source": [ "This time we create a CellPopulationBoundaryCondition and pass this to the OffLatticeSimulation.\n", @@ -642,20 +698,20 @@ { "cell_type": "code", "execution_count": null, + "id": "7d11a078", "metadata": {}, "outputs": [], "source": [ "centre = np.array([0.0, 0.0, 1.0])\n", "radius = 5.0\n", "point2 = chaste.mesh.ChastePoint3(centre)\n", - "boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population,\n", - " point2.rGetLocation(),\n", - " radius)\n", + "boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, point2.rGetLocation(), radius)\n", "simulator.AddCellPopulationBoundaryCondition(boundary_condition)" ] }, { "cell_type": "markdown", + "id": "f87548ae", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -665,6 +721,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1cdf1e8d", "metadata": {}, "outputs": [], "source": [ @@ -675,6 +732,7 @@ }, { "cell_type": "markdown", + "id": "3df3c0f2", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -684,6 +742,7 @@ { "cell_type": "code", "execution_count": null, + "id": "00c65de2", "metadata": {}, "outputs": [], "source": [ @@ -694,6 +753,7 @@ }, { "cell_type": "markdown", + "id": "49b04bcc", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -704,6 +764,7 @@ { "cell_type": "code", "execution_count": null, + "id": "49ae6fc6", "metadata": {}, "outputs": [], "source": [ @@ -715,5 +776,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.md b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.md index c2ab5290..510fc1de 100644 --- a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.md +++ b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Node Based Cell Simulations Python Tutorial +title : "Test Node Based Cell Simulations Python Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestNodeBasedCellSimulationsPythonTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py . Note that the code is given in full at the bottom of the page. @@ -68,8 +73,7 @@ the third argument specifies the proliferative type of the cell. ```python transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) ``` Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`. @@ -77,8 +81,7 @@ In general, this class associates a collection of cells with a mesh. For this te because we have a `NodesOnlyMesh`, we use a particular type of cell population called a `NodeBasedCellPopulation`. ```python - cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, cells) ``` We can set up a `VtkScene` to do a quick visualization of the population before running the analysis. @@ -173,8 +176,7 @@ As before, we do this with the CellsGenerator helper class (this time with dimen ```python transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) ``` Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`. @@ -182,8 +184,7 @@ In general, this class associates a collection of cells with a mesh. For this te because we have a `NodesOnlyMesh`, we use a particular type of cell population called a `NodeBasedCellPopulation`. ```python - cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, - cells) + cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells) ``` We can set up a `VtkScene` to do a quick visualization of the population before running the analysis. @@ -232,8 +233,7 @@ If different simulation input parameters are being explored the lines should be ```python self.assertEqual(cell_population.GetNumRealCells(), 8) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 10.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 10.0, 6) # JUPYTER_TEARDOWN @@ -268,10 +268,8 @@ which defines the connectivity of the nodes by defining a radius of interaction. transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) - cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, - cells) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) + cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells) ``` We can set up a `VtkScene` to do a quick visualization of the population before running the analysis. @@ -305,9 +303,7 @@ First we set the centre (0,0,1) and radius of the sphere (1). centre = np.array([0.0, 0.0, 1.0]) radius = 5.0 point2 = chaste.mesh.ChastePoint3(centre) - boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, - point2.rGetLocation(), - radius) + boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, point2.rGetLocation(), radius) simulator.AddCellPopulationBoundaryCondition(boundary_condition) ``` @@ -373,11 +369,9 @@ class TestRunningNodeBasedSimulationsTutorial(chaste.cell_based.AbstractCellBase transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) - cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, cells) scene = chaste.visualization.VtkScene2() scene.SetCellPopulation(cell_population) @@ -423,11 +417,9 @@ class TestRunningNodeBasedSimulationsTutorial(chaste.cell_based.AbstractCellBase transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) - cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, - cells) + cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells) scene = chaste.visualization.VtkScene3() scene.SetCellPopulation(cell_population) @@ -451,8 +443,7 @@ class TestRunningNodeBasedSimulationsTutorial(chaste.cell_based.AbstractCellBase scene.End() self.assertEqual(cell_population.GetNumRealCells(), 8) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 10.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 10.0, 6) # JUPYTER_TEARDOWN @@ -472,10 +463,8 @@ class TestRunningNodeBasedSimulationsTutorial(chaste.cell_based.AbstractCellBase transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), - transit_type) - cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, - cells) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type) + cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells) scene = chaste.visualization.VtkScene3() scene.SetCellPopulation(cell_population) @@ -492,9 +481,7 @@ class TestRunningNodeBasedSimulationsTutorial(chaste.cell_based.AbstractCellBase centre = np.array([0.0, 0.0, 1.0]) radius = 5.0 point2 = chaste.mesh.ChastePoint3(centre) - boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, - point2.rGetLocation(), - radius) + boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, point2.rGetLocation(), radius) simulator.AddCellPopulationBoundaryCondition(boundary_condition) scene_modifier.SetVtkScene(scene) diff --git a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb new file mode 100644 index 00000000..0253e618 --- /dev/null +++ b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -0,0 +1,780 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c1be3946", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dcd83472", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "f4d7e6dd", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "In this tutorial we show how Chaste can be used to create, run and visualize node-based simulations. Full details of the mechanical model can be found in Pathamathan et\n", + "al \"A computational study of discrete mechanical tissue models\", Physical Biology. Vol. 6. No. 3. 2009.. DOI (10.1088/1478-3975/6/3/036001).\n", + "\n", + "## The Test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d34a397", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.visualization # Visualization tools\n", + "chaste.init() # Set up MPI" + ] + }, + { + "cell_type": "markdown", + "id": "37286ec9", + "metadata": {}, + "source": [ + "## Test 1 - A basic node-based simulation\n", + "In the first test, we run a simple node-based simulation, in which we create a monolayer of cells,\n", + "using a nodes only mesh. Each cell is assigned a uniform cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7077ffc", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "c3cfec3f", + "metadata": {}, + "source": [ + "The first thing we do is generate a nodes only mesh. To do this we first create a `MutableMesh` to use as a generating mesh.\n", + "To do this we can use the `HoneycombMeshGenerator`. This generates a honeycomb-shaped mesh, in which all nodes are equidistant.\n", + "Here the first and second arguments define the size of the mesh - we have chosen a mesh that is 2 nodes (i.e. cells) wide, and 2 nodes high.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85578e5e", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestNodeBasedCellSimulationsTutorial\")\n", + "generator = chaste.mesh.HoneycombMeshGenerator(2, 2)\n", + "generating_mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "99336452", + "metadata": {}, + "source": [ + "Once we have a MutableMesh we can generate a NodesOnlyMesh from it using the following commands.\n", + "Note you can also generate the NodesOnlyMesh from a collection of nodes.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31fa8c51", + "metadata": {}, + "outputs": [], + "source": [ + "mesh = chaste.mesh.NodesOnlyMesh2()" + ] + }, + { + "cell_type": "markdown", + "id": "3d20db6a", + "metadata": {}, + "source": [ + "To run node-based simulations you need to define a cut off length (second argument in `ConstructNodesWithoutMesh`),\n", + "which defines the connectivity of the nodes by defining a radius of interaction.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ae2bd30", + "metadata": {}, + "outputs": [], + "source": [ + "mesh.ConstructNodesWithoutMesh(generating_mesh, 1.5)" + ] + }, + { + "cell_type": "markdown", + "id": "5efc27fe", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a (wrapped) vector of CellPtrs. To do this, we use the `CellsGenerator` helper class,\n", + "which is specialized for the type of cell model required (here `UniformCellCycleModel`) and the dimension.\n", + "We create an empty vector of cells and pass this into the method along with the mesh.\n", + "The second argument represents the size of that the vector cells should become - one cell for each node,\n", + "the third argument specifies the proliferative type of the cell.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2ecc8c4", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "3b05d4ca", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", + "In general, this class associates a collection of cells with a mesh. For this test,\n", + "because we have a `NodesOnlyMesh`, we use a particular type of cell population called a `NodeBasedCellPopulation`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e339e8", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.NodeBasedCellPopulation2(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "614090ff", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d441f8b7", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "2f461c92", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e257f3f", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestNodeBasedCellSimulationsTutorial\")\n", + "simulator.SetSamplingTimestepMultiple(100)\n", + "simulator.SetEndTime(10.0)" + ] + }, + { + "cell_type": "markdown", + "id": "858b1279", + "metadata": {}, + "source": [ + "We now pass a force law to the simulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b6a8e65", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce2_2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "1b3cde60", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4370d079", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "9cb5a9fd", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24b5bfa0", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "scene.End()" + ] + }, + { + "cell_type": "markdown", + "id": "98637fcb", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "095ce225", + "metadata": {}, + "outputs": [], + "source": [ + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "2597efaf", + "metadata": {}, + "source": [ + "## Test 2 - a basic node-based simulation in 3D\n", + "In the second test we run a simple node-based simulation in 3D. This is very similar to the 2D test with the dimension changed from 2 to 3 and\n", + "instead of using a mesh generator we generate the nodes directly.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f8f6402", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "ec16c4f5", + "metadata": {}, + "source": [ + "First, we generate a nodes only mesh. This time we specify the nodes manually by first creating a vector of nodes\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3662e0e2", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestNodeBasedCellSimulationsSpheroidTutorial\")\n", + "nodes = []\n", + "nodes.append(chaste.mesh.Node3(0, False, 0.5, 0.0, 0.0))\n", + "nodes.append(chaste.mesh.Node3(1, False, -0.5, 0.0, 0.0))\n", + "nodes.append(chaste.mesh.Node3(2, False, 0.0, 0.5, 0.0))\n", + "nodes.append(chaste.mesh.Node3(3, False, 0.0, -0.5, 0.0))" + ] + }, + { + "cell_type": "markdown", + "id": "7ef828a0", + "metadata": {}, + "source": [ + "Finally a NodesOnlyMesh is created and the vector of nodes is passed to the ConstructNodesWithoutMesh method.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9029d2d0", + "metadata": {}, + "outputs": [], + "source": [ + "mesh = chaste.mesh.NodesOnlyMesh3()" + ] + }, + { + "cell_type": "markdown", + "id": "e95300f5", + "metadata": {}, + "source": [ + "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", + "which defines the connectivity of the nodes by defining a radius of interaction.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61f4f064", + "metadata": {}, + "outputs": [], + "source": [ + "mesh.ConstructNodesWithoutMesh(nodes, 1.5)" + ] + }, + { + "cell_type": "markdown", + "id": "7cbd6d28", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a std::vector of CellPtrs.\n", + "As before, we do this with the CellsGenerator helper class (this time with dimension 3).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e94362a4", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "b4b198bd", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", + "In general, this class associates a collection of cells with a mesh. For this test,\n", + "because we have a `NodesOnlyMesh`, we use a particular type of cell population called a `NodeBasedCellPopulation`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3cad7ba8", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "fd9c6232", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ef252ff", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene3()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "376f3387", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0546c735", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation3_3(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestNodeBasedCellSimulationsSpheroidTutorial\")\n", + "simulator.SetSamplingTimestepMultiple(12)\n", + "simulator.SetEndTime(10.0)" + ] + }, + { + "cell_type": "markdown", + "id": "edb6a531", + "metadata": {}, + "source": [ + "We now pass a force law to the simulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04b02d89", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce3_3()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "a183d74c", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e532a662", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier3(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "b1a59ff5", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b1aa5d2", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "scene.End()" + ] + }, + { + "cell_type": "markdown", + "id": "1db1e70a", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbcccf30", + "metadata": {}, + "outputs": [], + "source": [ + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "8b718848", + "metadata": {}, + "source": [ + "## Test 3 - a node-based simulation on a restricted geometry\n", + "In the second test we run a simple node-based simulation in 3D. This is very similar to the 2D test with the dimension changed from 2 to 3 and\n", + "instead of using a mesh generator we generate the nodes directly.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "107c3c95", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "36e7797a", + "metadata": {}, + "source": [ + "In the third test we run a node-based simulation restricted to the surface of a sphere.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4432292d", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestNodeBasedCellSimulationsRestrictedSpheroidTutorial\")\n", + "nodes = []\n", + "nodes.append(chaste.mesh.Node3(0, False, 0.5, 0.0, 0.0))\n", + "nodes.append(chaste.mesh.Node3(1, False, -0.5, 0.0, 0.0))\n", + "nodes.append(chaste.mesh.Node3(2, False, 0.0, 0.5, 0.0))\n", + "nodes.append(chaste.mesh.Node3(3, False, 0.0, -0.5, 0.0))\n", + "mesh = chaste.mesh.NodesOnlyMesh3()" + ] + }, + { + "cell_type": "markdown", + "id": "56119cfe", + "metadata": {}, + "source": [ + "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", + "which defines the connectivity of the nodes by defining a radius of interaction.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10c19934", + "metadata": {}, + "outputs": [], + "source": [ + "mesh.ConstructNodesWithoutMesh(nodes, 1.5)\n", + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), transit_type)\n", + "cell_population = chaste.cell_based.NodeBasedCellPopulation3(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "e4330483", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11237f3b", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene3()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager.vtk_show(scene, height=600)\n", + "simulator = chaste.cell_based.OffLatticeSimulation3_3(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestNodeBasedCellSimulationsRestrictedSpheroidTutorial\")\n", + "simulator.SetSamplingTimestepMultiple(12)\n", + "simulator.SetEndTime(10.0)" + ] + }, + { + "cell_type": "markdown", + "id": "f69e6f1e", + "metadata": {}, + "source": [ + "We now pass a force law to the simulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44951122", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce3_3()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "75ca15e7", + "metadata": {}, + "source": [ + "This time we create a CellPopulationBoundaryCondition and pass this to the OffLatticeSimulation.\n", + "Here we use a SphereGeometryBoundaryCondition which restricts cells to lie on a sphere (in 3D) or circle (in 2D).\n", + "For a list of possible boundary conditions see subclasses of AbstractCellPopulationBoundaryCondition.\n", + "Note that some of these boundary conditions are not compatible with node-based simulations see the specific class documentation\n", + "for details, if you try to use an incompatible class then you will receive a warning.\n", + "First we set the centre (0,0,1) and radius of the sphere (1).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d11a078", + "metadata": {}, + "outputs": [], + "source": [ + "centre = np.array([0.0, 0.0, 1.0])\n", + "radius = 5.0\n", + "point2 = chaste.mesh.ChastePoint3(centre)\n", + "boundary_condition = chaste.cell_based.SphereGeometryBoundaryCondition3(cell_population, point2.rGetLocation(), radius)\n", + "simulator.AddCellPopulationBoundaryCondition(boundary_condition)" + ] + }, + { + "cell_type": "markdown", + "id": "f87548ae", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "scene_modifier = chaste.cell_based.VtkSceneModifier3()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cdf1e8d", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "3df3c0f2", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00c65de2", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "scene.End()" + ] + }, + { + "cell_type": "markdown", + "id": "49b04bcc", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49ae6fc6", + "metadata": {}, + "outputs": [], + "source": [ + " 10.0, 6)\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb index 63b8d1c5..bc98dd2e 100644 --- a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "fe26027f", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "722137ac", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "7c983357", "metadata": {}, "source": [ "\n", @@ -36,6 +39,7 @@ { "cell_type": "code", "execution_count": null, + "id": "6e28e95b", "metadata": {}, "outputs": [], "source": [ @@ -48,6 +52,7 @@ }, { "cell_type": "markdown", + "id": "1750572a", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -59,6 +64,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9934f251", "metadata": {}, "outputs": [], "source": [ @@ -68,6 +74,7 @@ }, { "cell_type": "markdown", + "id": "bbfa49bf", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -81,6 +88,7 @@ { "cell_type": "code", "execution_count": null, + "id": "55f38d19", "metadata": {}, "outputs": [], "source": [ @@ -92,6 +100,7 @@ }, { "cell_type": "markdown", + "id": "a91fdb20", "metadata": {}, "source": [ "Having created a mesh, we now create a vector of CellPtrs. To do this, we the CellsGenerator helper class,\n", @@ -105,6 +114,7 @@ { "cell_type": "code", "execution_count": null, + "id": "33614632", "metadata": {}, "outputs": [], "source": [ @@ -114,6 +124,7 @@ }, { "cell_type": "markdown", + "id": "627977c0", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -125,6 +136,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c6f33a23", "metadata": {}, "outputs": [], "source": [ @@ -134,6 +146,7 @@ }, { "cell_type": "markdown", + "id": "605a945a", "metadata": {}, "source": [ "We can set the \"Temperature\" to be used in the Potts Simulation using the optional command below. The default value is 0.1.\n", @@ -143,6 +156,7 @@ { "cell_type": "code", "execution_count": null, + "id": "cb238e68", "metadata": {}, "outputs": [], "source": [ @@ -151,6 +165,7 @@ }, { "cell_type": "markdown", + "id": "be5535e5", "metadata": {}, "source": [ "By default the Potts simulation will make 1 sweep over the whole domain per timestep.\n", @@ -161,6 +176,7 @@ { "cell_type": "code", "execution_count": null, + "id": "6389e49a", "metadata": {}, "outputs": [], "source": [ @@ -169,6 +185,7 @@ }, { "cell_type": "markdown", + "id": "c3ee1f4c", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -178,6 +195,7 @@ { "cell_type": "code", "execution_count": null, + "id": "d4c65850", "metadata": {}, "outputs": [], "source": [ @@ -190,6 +208,7 @@ }, { "cell_type": "markdown", + "id": "698d2c01", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -199,6 +218,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ef1a7d77", "metadata": {}, "outputs": [], "source": [ @@ -209,6 +229,7 @@ }, { "cell_type": "markdown", + "id": "56b04ad7", "metadata": {}, "source": [ "The default timestep is 0.1, but can be changed using the below command. The timestep is used in conjunction with the \"Temperature\"\n", @@ -220,6 +241,7 @@ { "cell_type": "code", "execution_count": null, + "id": "34458dba", "metadata": {}, "outputs": [], "source": [ @@ -229,6 +251,7 @@ }, { "cell_type": "markdown", + "id": "42596e10", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -241,6 +264,7 @@ { "cell_type": "code", "execution_count": null, + "id": "fab5817f", "metadata": {}, "outputs": [], "source": [ @@ -249,6 +273,7 @@ }, { "cell_type": "markdown", + "id": "1e8391b6", "metadata": {}, "source": [ "Set an appropriate target volume in number of lattice sites. Here we use the default value of 16 lattice sites.\n", @@ -258,6 +283,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e72fb371", "metadata": {}, "outputs": [], "source": [ @@ -266,6 +292,7 @@ }, { "cell_type": "markdown", + "id": "a90457d0", "metadata": {}, "source": [ "You can also vary the deformation energy parameter.\n", @@ -276,6 +303,7 @@ { "cell_type": "code", "execution_count": null, + "id": "69cd75e6", "metadata": {}, "outputs": [], "source": [ @@ -284,6 +312,7 @@ }, { "cell_type": "markdown", + "id": "cf085a6a", "metadata": {}, "source": [ "Finally we add the update rule to the simulator.\n", @@ -293,6 +322,7 @@ { "cell_type": "code", "execution_count": null, + "id": "556817c8", "metadata": {}, "outputs": [], "source": [ @@ -301,6 +331,7 @@ }, { "cell_type": "markdown", + "id": "7da26bd8", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -310,6 +341,7 @@ { "cell_type": "code", "execution_count": null, + "id": "96f3a915", "metadata": {}, "outputs": [], "source": [ @@ -319,6 +351,7 @@ }, { "cell_type": "markdown", + "id": "c20c081f", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -328,6 +361,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b8e965f1", "metadata": {}, "outputs": [], "source": [ @@ -339,6 +373,7 @@ }, { "cell_type": "markdown", + "id": "6e0d622d", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -348,6 +383,7 @@ { "cell_type": "code", "execution_count": null, + "id": "abfa1220", "metadata": {}, "outputs": [], "source": [ @@ -357,6 +393,7 @@ }, { "cell_type": "markdown", + "id": "7e621647", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -367,6 +404,7 @@ { "cell_type": "code", "execution_count": null, + "id": "de9ee328", "metadata": {}, "outputs": [], "source": [ @@ -377,6 +415,7 @@ }, { "cell_type": "markdown", + "id": "1decbf79", "metadata": {}, "source": [ "## Test 2 - Cell sorting\n", @@ -388,6 +427,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4658f560", "metadata": {}, "outputs": [], "source": [ @@ -397,6 +437,7 @@ }, { "cell_type": "markdown", + "id": "22d91700", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -408,6 +449,7 @@ { "cell_type": "code", "execution_count": null, + "id": "91f401bb", "metadata": {}, "outputs": [], "source": [ @@ -418,6 +460,7 @@ }, { "cell_type": "markdown", + "id": "461297ca", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -428,6 +471,7 @@ { "cell_type": "code", "execution_count": null, + "id": "d2fb425e", "metadata": {}, "outputs": [], "source": [ @@ -439,6 +483,7 @@ }, { "cell_type": "markdown", + "id": "0ad517b0", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -448,6 +493,7 @@ { "cell_type": "code", "execution_count": null, + "id": "15815e4f", "metadata": {}, "outputs": [], "source": [ @@ -459,6 +505,7 @@ }, { "cell_type": "markdown", + "id": "659d8e43", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -468,6 +515,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8a7dc842", "metadata": {}, "outputs": [], "source": [ @@ -477,6 +525,7 @@ }, { "cell_type": "markdown", + "id": "c13baf5d", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -486,6 +535,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2d9b2419", "metadata": {}, "outputs": [], "source": [ @@ -494,6 +544,7 @@ }, { "cell_type": "markdown", + "id": "08c38fbb", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -503,6 +554,7 @@ { "cell_type": "code", "execution_count": null, + "id": "aed04eba", "metadata": {}, "outputs": [], "source": [ @@ -514,6 +566,7 @@ }, { "cell_type": "markdown", + "id": "80e2d404", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -526,6 +579,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8f0204dc", "metadata": {}, "outputs": [], "source": [ @@ -537,6 +591,7 @@ }, { "cell_type": "markdown", + "id": "9a7d93e8", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -546,6 +601,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2ec888ed", "metadata": {}, "outputs": [], "source": [ @@ -560,6 +616,7 @@ }, { "cell_type": "markdown", + "id": "90188a5e", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -569,6 +626,7 @@ { "cell_type": "code", "execution_count": null, + "id": "63b404af", "metadata": {}, "outputs": [], "source": [ @@ -577,6 +635,7 @@ }, { "cell_type": "markdown", + "id": "eb6ec287", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -587,6 +646,7 @@ { "cell_type": "code", "execution_count": null, + "id": "6225d338", "metadata": {}, "outputs": [], "source": [ @@ -597,6 +657,7 @@ }, { "cell_type": "markdown", + "id": "9471f9fd", "metadata": {}, "source": [ "## Test 3 - 3D Cell Sorting\n", @@ -607,6 +668,7 @@ { "cell_type": "code", "execution_count": null, + "id": "7a665cfc", "metadata": {}, "outputs": [], "source": [ @@ -616,6 +678,7 @@ }, { "cell_type": "markdown", + "id": "00647aea", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -630,6 +693,7 @@ { "cell_type": "code", "execution_count": null, + "id": "261b8586", "metadata": {}, "outputs": [], "source": [ @@ -641,6 +705,7 @@ }, { "cell_type": "markdown", + "id": "b6e31280", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -651,6 +716,7 @@ { "cell_type": "code", "execution_count": null, + "id": "47c643c7", "metadata": {}, "outputs": [], "source": [ @@ -662,6 +728,7 @@ }, { "cell_type": "markdown", + "id": "c415abaf", "metadata": {}, "source": [ "As for the 2D case before we make a CellPopulation we make a pointer to a cell label and then assign this label to some randomly chosen cells.\n", @@ -671,6 +738,7 @@ { "cell_type": "code", "execution_count": null, + "id": "fc267e74", "metadata": {}, "outputs": [], "source": [ @@ -682,6 +750,7 @@ }, { "cell_type": "markdown", + "id": "618691c5", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -691,6 +760,7 @@ { "cell_type": "code", "execution_count": null, + "id": "d2c7fcbc", "metadata": {}, "outputs": [], "source": [ @@ -700,6 +770,7 @@ }, { "cell_type": "markdown", + "id": "dc3c8739", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -709,6 +780,7 @@ { "cell_type": "code", "execution_count": null, + "id": "401d5a8e", "metadata": {}, "outputs": [], "source": [ @@ -717,6 +789,7 @@ }, { "cell_type": "markdown", + "id": "8eb40125", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -726,6 +799,7 @@ { "cell_type": "code", "execution_count": null, + "id": "95b77b57", "metadata": {}, "outputs": [], "source": [ @@ -737,6 +811,7 @@ }, { "cell_type": "markdown", + "id": "8fe58ca4", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -747,6 +822,7 @@ { "cell_type": "code", "execution_count": null, + "id": "98315238", "metadata": {}, "outputs": [], "source": [ @@ -758,6 +834,7 @@ }, { "cell_type": "markdown", + "id": "e66a5118", "metadata": {}, "source": [ "We use the same differential adhesion parameters as in the 2D case.\n", @@ -767,6 +844,7 @@ { "cell_type": "code", "execution_count": null, + "id": "eb89094c", "metadata": {}, "outputs": [], "source": [ @@ -781,6 +859,7 @@ }, { "cell_type": "markdown", + "id": "73a41c30", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -790,6 +869,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ab765b87", "metadata": {}, "outputs": [], "source": [ @@ -798,6 +878,7 @@ }, { "cell_type": "markdown", + "id": "5a35c7df", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -808,6 +889,7 @@ { "cell_type": "code", "execution_count": null, + "id": "56d9c1bf", "metadata": {}, "outputs": [], "source": [ @@ -819,5 +901,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.md b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.md index f3cae677..b14a20ba 100644 --- a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.md +++ b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Potts Based Cell Simulations Python Tutorial +title : "Test Potts Based Cell Simulations Python Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestPottsBasedCellSimulationsPythonTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py . Note that the code is given in full at the bottom of the page. diff --git a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb new file mode 100644 index 00000000..bc98dd2e --- /dev/null +++ b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -0,0 +1,905 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fe26027f", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "722137ac", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "7c983357", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "In this tutorial we show how Chaste can be used to create, run and visualize Potts-based simulations.\n", + "Full details of the mathematical model can be found in Graner, F. and Glazier, J. A. (1992).\n", + "\n", + "## The Test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e28e95b", + "metadata": {}, + "outputs": [], + "source": [ + "import chaste # The PyChaste module\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.visualization # Visualization tools\n", + "chaste.init() # Set up MPI" + ] + }, + { + "cell_type": "markdown", + "id": "1750572a", + "metadata": {}, + "source": [ + "## Test 1 - A basic node-based simulation\n", + "In the first test, we run a simple Potts-based simulation, in which we create a monolayer of cells, using a Potts mesh.\n", + "Each cell is assigned a stochastic cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9934f251", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "bbfa49bf", + "metadata": {}, + "source": [ + "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", + "This generates a regular square-shaped mesh, in which all elements are the same size.\n", + "Here the first three arguments specify the domain width; the number of elements across; and the width of elements.\n", + "The second set of three arguments specify the domain height; the number of elements up; and the height of individual elements.\n", + "We have chosen a 2 by 2 block of elements, each consisting of 4 by 4 ( = 16) lattice sites.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55f38d19", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestPottsBasedCellSimulationsTutorial\")\n", + "generator = chaste.mesh.PottsMeshGenerator2(50, 2, 4,\n", + " 50, 2, 4)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "a91fdb20", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a vector of CellPtrs. To do this, we the CellsGenerator helper class,\n", + "which is templated over the type of cell model required and the dimension.\n", + "We create an empty vector of cells and pass this into the method along with the mesh.\n", + "The second argument represents the size of that the vector cells should become - one cell for each element.\n", + "Third argument makes all cells proliferate.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33614632", + "metadata": {}, + "outputs": [], + "source": [ + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasic(mesh.GetNumElements())" + ] + }, + { + "cell_type": "markdown", + "id": "627977c0", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", + "In general, this class associates a collection of cells with a mesh. For this test, because we have a PottsMesh,\n", + "we use a particular type of cell population called a PottsBasedCellPopulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6f33a23", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.PottsBasedCellPopulation2(mesh,\n", + " cells)" + ] + }, + { + "cell_type": "markdown", + "id": "605a945a", + "metadata": {}, + "source": [ + "We can set the \"Temperature\" to be used in the Potts Simulation using the optional command below. The default value is 0.1.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb238e68", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.SetTemperature(0.1)" + ] + }, + { + "cell_type": "markdown", + "id": "be5535e5", + "metadata": {}, + "source": [ + "By default the Potts simulation will make 1 sweep over the whole domain per timestep.\n", + "To use a different number of sweeps per timestep use the command.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6389e49a", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.SetNumSweepsPerTimestep(1)" + ] + }, + { + "cell_type": "markdown", + "id": "c3ee1f4c", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4c65850", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "scene.GetCellPopulationActorGenerator().SetShowPottsMeshEdges(True)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "698d2c01", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef1a7d77", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OnLatticeSimulation2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestPottsBasedCellSimulationsTutorial\")\n", + "simulator.SetEndTime(50.0)" + ] + }, + { + "cell_type": "markdown", + "id": "56b04ad7", + "metadata": {}, + "source": [ + "The default timestep is 0.1, but can be changed using the below command. The timestep is used in conjunction with the \"Temperature\"\n", + "and number of sweeps per timestep to specify the relationship between cell movement and proliferation.\n", + "We also set the simulation to only output every 10 steps i.e. once per hour.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34458dba", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.SetDt(0.1)\n", + "simulator.SetSamplingTimestepMultiple(10)" + ] + }, + { + "cell_type": "markdown", + "id": "42596e10", + "metadata": {}, + "source": [ + "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", + "For this test, we use two update rules based upon a volume constraint (VolumeConstraintPottsUpdateRule)\n", + "and adhesion between cells (AdhesionPottsUpdateRule) and pass them to the OnLatticeSimulation.\n", + "For a list of possible update rules see subclasses of AbstractPottsUpdateRule.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fab5817f", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule = chaste.cell_based.VolumeConstraintPottsUpdateRule2()" + ] + }, + { + "cell_type": "markdown", + "id": "1e8391b6", + "metadata": {}, + "source": [ + "Set an appropriate target volume in number of lattice sites. Here we use the default value of 16 lattice sites.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e72fb371", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule.SetMatureCellTargetVolume(16)" + ] + }, + { + "cell_type": "markdown", + "id": "a90457d0", + "metadata": {}, + "source": [ + "You can also vary the deformation energy parameter.\n", + "The larger the parameter the more cells will try to maintain target volume. Here we use the default value of 0.2.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69cd75e6", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule.SetDeformationEnergyParameter(0.2)" + ] + }, + { + "cell_type": "markdown", + "id": "cf085a6a", + "metadata": {}, + "source": [ + "Finally we add the update rule to the simulator.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "556817c8", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.AddUpdateRule(volume_constraint_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "7da26bd8", + "metadata": {}, + "source": [ + "We repeat the process for any other update rules.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96f3a915", + "metadata": {}, + "outputs": [], + "source": [ + "adhesion_update_rule = chaste.cell_based.AdhesionPottsUpdateRule2()\n", + "simulator.AddUpdateRule(adhesion_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "c20c081f", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8e965f1", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "6e0d622d", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "abfa1220", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()" + ] + }, + { + "cell_type": "markdown", + "id": "7e621647", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de9ee328", + "metadata": {}, + "outputs": [], + "source": [ + " 50.0, 6)\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "1decbf79", + "metadata": {}, + "source": [ + "## Test 2 - Cell sorting\n", + "The next test generates a collection of cells, there are two types of cells, labelled ones and non labelled ones,\n", + "there is differential adhesion between the cell types. For the parameters specified, the cells sort into separate types.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4658f560", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "22d91700", + "metadata": {}, + "source": [ + "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", + "This generates a regular square-shaped mesh, in which all elements are the same size.\n", + "We have chosen an 8 by 8 block of elements each consisting of 4 by 4 ( = 16) lattice sites.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91f401bb", + "metadata": {}, + "outputs": [], + "source": [ + "generator = chaste.mesh.PottsMeshGenerator2(50, 8, 4,\n", + " 50, 8, 4)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "461297ca", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", + "as before but this time the third argument is set to make all cells non-proliferative.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2fb425e", + "metadata": {}, + "outputs": [], + "source": [ + "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(),\n", + " differentiated_type)" + ] + }, + { + "cell_type": "markdown", + "id": "0ad517b0", + "metadata": {}, + "source": [ + "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15815e4f", + "metadata": {}, + "outputs": [], + "source": [ + "label = chaste.cell_based.CellLabel()\n", + "for eachCell in cells:\n", + " if(chaste.core.RandomNumberGenerator.Instance().ranf() < 0.5):\n", + " eachCell.AddCellProperty(label)" + ] + }, + { + "cell_type": "markdown", + "id": "659d8e43", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a7dc842", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.PottsBasedCellPopulation2(mesh,\n", + " cells)" + ] + }, + { + "cell_type": "markdown", + "id": "c13baf5d", + "metadata": {}, + "source": [ + "In order to visualize labelled cells we need to use the following command.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d9b2419", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddCellWriterCellLabelWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "08c38fbb", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aed04eba", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OnLatticeSimulation2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestPottsBasedCellSorting\")\n", + "simulator.SetEndTime(20.0)\n", + "simulator.SetSamplingTimestepMultiple(10)" + ] + }, + { + "cell_type": "markdown", + "id": "80e2d404", + "metadata": {}, + "source": [ + "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", + "For this test, we use two update rules based upon a volume constraint (VolumeConstraintPottsUpdateRule) and\n", + "differential adhesion between cells (DifferentialAdhesionPottsUpdateRule), set appropriate parameters, and\n", + "pass them to the OnLatticeSimulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f0204dc", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule = chaste.cell_based.VolumeConstraintPottsUpdateRule2()\n", + "volume_constraint_update_rule.SetMatureCellTargetVolume(16)\n", + "volume_constraint_update_rule.SetDeformationEnergyParameter(0.2)\n", + "simulator.AddUpdateRule(volume_constraint_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "9a7d93e8", + "metadata": {}, + "source": [ + "We repeat the process for any other update rules.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ec888ed", + "metadata": {}, + "outputs": [], + "source": [ + "differential_adhesion_update_rule = chaste.cell_based.DifferentialAdhesionPottsUpdateRule2()\n", + "differential_adhesion_update_rule.SetLabelledCellLabelledCellAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetLabelledCellCellAdhesionEnergyParameter(0.11)\n", + "differential_adhesion_update_rule.SetCellCellAdhesionEnergyParameter(0.02)\n", + "differential_adhesion_update_rule.SetLabelledCellBoundaryAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetCellBoundaryAdhesionEnergyParameter(0.16)\n", + "simulator.AddUpdateRule(differential_adhesion_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "90188a5e", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "63b404af", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.Solve()" + ] + }, + { + "cell_type": "markdown", + "id": "eb6ec287", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6225d338", + "metadata": {}, + "outputs": [], + "source": [ + " 20.0, 6)\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "9471f9fd", + "metadata": {}, + "source": [ + "## Test 3 - 3D Cell Sorting\n", + "The next test extends the previous example to three dimensions.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a665cfc", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "00647aea", + "metadata": {}, + "source": [ + "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", + "This generates a regular square-shaped mesh, in which all elements are the same size.\n", + "Here the first three arguments specify the domain width; the number of elements across; and the width of elements.\n", + "The second set of three arguments specify the domain height; the number of elements up; and the height of individual elements.\n", + "The third set of three arguments specify the domain depth; the number of elements deep; and the depth of individual elements.\n", + "We have chosen an 4 by 4 by 4 ( = 64) block of elements each consisting of 2 by 2 by 2 ( = 8) lattice sites.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "261b8586", + "metadata": {}, + "outputs": [], + "source": [ + "generator = chaste.mesh.PottsMeshGenerator3(10, 4, 2,\n", + " 10, 4, 2,\n", + " 10, 4, 2)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "b6e31280", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", + "as before but this time the third argument is set to make all cells non-proliferative.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47c643c7", + "metadata": {}, + "outputs": [], + "source": [ + "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformCellCycleModel_3()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(),\n", + " differentiated_type)" + ] + }, + { + "cell_type": "markdown", + "id": "c415abaf", + "metadata": {}, + "source": [ + "As for the 2D case before we make a CellPopulation we make a pointer to a cell label and then assign this label to some randomly chosen cells.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc267e74", + "metadata": {}, + "outputs": [], + "source": [ + "label = chaste.cell_based.CellLabel()\n", + "for eachCell in cells:\n", + " if(chaste.core.RandomNumberGenerator.Instance().ranf() < 0.5):\n", + " eachCell.AddCellProperty(label)" + ] + }, + { + "cell_type": "markdown", + "id": "618691c5", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2c7fcbc", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.PottsBasedCellPopulation3(mesh,\n", + " cells)" + ] + }, + { + "cell_type": "markdown", + "id": "dc3c8739", + "metadata": {}, + "source": [ + "In order to visualize labelled cells we need to use the following command.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "401d5a8e", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddCellWriterCellLabelWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "8eb40125", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95b77b57", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OnLatticeSimulation3(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestPottsBasedCellSorting3D\")\n", + "simulator.SetEndTime(20.0)\n", + "simulator.SetSamplingTimestepMultiple(10)" + ] + }, + { + "cell_type": "markdown", + "id": "8fe58ca4", + "metadata": {}, + "source": [ + "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", + "Now set the target volume to be appropriate for this 3D simulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98315238", + "metadata": {}, + "outputs": [], + "source": [ + "volume_constraint_update_rule = chaste.cell_based.VolumeConstraintPottsUpdateRule3()\n", + "volume_constraint_update_rule.SetMatureCellTargetVolume(8)\n", + "volume_constraint_update_rule.SetDeformationEnergyParameter(0.2)\n", + "simulator.AddUpdateRule(volume_constraint_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "e66a5118", + "metadata": {}, + "source": [ + "We use the same differential adhesion parameters as in the 2D case.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb89094c", + "metadata": {}, + "outputs": [], + "source": [ + "differential_adhesion_update_rule = chaste.cell_based.DifferentialAdhesionPottsUpdateRule3()\n", + "differential_adhesion_update_rule.SetLabelledCellLabelledCellAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetLabelledCellCellAdhesionEnergyParameter(0.11)\n", + "differential_adhesion_update_rule.SetCellCellAdhesionEnergyParameter(0.02)\n", + "differential_adhesion_update_rule.SetLabelledCellBoundaryAdhesionEnergyParameter(0.16)\n", + "differential_adhesion_update_rule.SetCellBoundaryAdhesionEnergyParameter(0.16)\n", + "simulator.AddUpdateRule(differential_adhesion_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "73a41c30", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab765b87", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.Solve()" + ] + }, + { + "cell_type": "markdown", + "id": "5a35c7df", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56d9c1bf", + "metadata": {}, + "outputs": [], + "source": [ + " 20.0, 6)\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestScratchAssayTutorial.ipynb b/doc/tutorials/TestScratchAssayTutorial.ipynb index 941be958..0de64af4 100644 --- a/doc/tutorials/TestScratchAssayTutorial.ipynb +++ b/doc/tutorials/TestScratchAssayTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "7f5aad40", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestScratchAssayTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestScratchAssayTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "31b11251", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "1132d347", "metadata": {}, "source": [ "\n", @@ -41,6 +44,7 @@ { "cell_type": "code", "execution_count": null, + "id": "3188078b", "metadata": {}, "outputs": [], "source": [ @@ -55,6 +59,7 @@ }, { "cell_type": "markdown", + "id": "55f09b2a", "metadata": {}, "source": [ "## Test 1 - Scratch Assay\n", @@ -66,6 +71,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1835f6a7", "metadata": {}, "outputs": [], "source": [ @@ -75,6 +81,7 @@ }, { "cell_type": "markdown", + "id": "6ca0bc5c", "metadata": {}, "source": [ "Chaste is based on the concept of `Cells` and `Meshes`. 'Cells' do not store their position in space,\n", @@ -89,6 +96,7 @@ { "cell_type": "code", "execution_count": null, + "id": "95eeca2c", "metadata": {}, "outputs": [], "source": [ @@ -100,6 +108,7 @@ }, { "cell_type": "markdown", + "id": "0ecb6c54", "metadata": {}, "source": [ "Note that we are using a `PottsMeshGenerator2` to set up the grid and we are setting some terms to 0. Chaste\n", @@ -119,6 +128,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8549652b", "metadata": {}, "outputs": [], "source": [ @@ -128,6 +138,7 @@ }, { "cell_type": "markdown", + "id": "32c71fee", "metadata": {}, "source": [ "We are not interested in cell cycling so we specialize the generator to NoCellCycleModel.\n", @@ -137,6 +148,7 @@ { "cell_type": "code", "execution_count": null, + "id": "eddb0b29", "metadata": {}, "outputs": [], "source": [ @@ -145,6 +157,7 @@ }, { "cell_type": "markdown", + "id": "ddad4e69", "metadata": {}, "source": [ "We want two sets of cells, starting on opposite sides of the mesh. We use `location_indices` to map cells onto\n", @@ -156,6 +169,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b20c1098", "metadata": {}, "outputs": [], "source": [ @@ -171,6 +185,7 @@ }, { "cell_type": "markdown", + "id": "68c97925", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -180,6 +195,7 @@ { "cell_type": "code", "execution_count": null, + "id": "467d5255", "metadata": {}, "outputs": [], "source": [ @@ -190,6 +206,7 @@ }, { "cell_type": "markdown", + "id": "43211f16", "metadata": {}, "source": [ "Next, we set up an `OffLatticeSimulation` which will manage the solver. We need to add some custom rules to\n", @@ -200,6 +217,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b2c12e4d", "metadata": {}, "outputs": [], "source": [ @@ -212,6 +230,7 @@ }, { "cell_type": "markdown", + "id": "d15b1b80", "metadata": {}, "source": [ "We must now create a rule for cell migration. We will use an existing diffusion type rule.\n", @@ -221,6 +240,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1ab3666f", "metadata": {}, "outputs": [], "source": [ @@ -230,6 +250,7 @@ }, { "cell_type": "markdown", + "id": "761aa121", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -240,6 +261,7 @@ { "cell_type": "code", "execution_count": null, + "id": "cb42c762", "metadata": {}, "outputs": [], "source": [ @@ -252,6 +274,7 @@ }, { "cell_type": "markdown", + "id": "c4057d3d", "metadata": {}, "source": [ "We add the scene to the simulation for real-time updating using a `VtkSceneModifier`. Such\n", @@ -264,6 +287,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8e16d6e6", "metadata": {}, "outputs": [], "source": [ @@ -275,6 +299,7 @@ }, { "cell_type": "markdown", + "id": "b7831aa4", "metadata": {}, "source": [ "Chaste and PyChaste use object oriented programming. This may require some background reading,\n", @@ -290,6 +315,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4c86f52a", "metadata": {}, "outputs": [], "source": [ @@ -336,6 +362,7 @@ }, { "cell_type": "markdown", + "id": "43ef8599", "metadata": {}, "source": [ "To run the simulation, we call `Solve()` and optionally set up interactive plotting. We will see the cells\n", @@ -346,6 +373,7 @@ { "cell_type": "code", "execution_count": null, + "id": "f907c915", "metadata": {}, "outputs": [], "source": [ @@ -360,5 +388,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestScratchAssayTutorial.md b/doc/tutorials/TestScratchAssayTutorial.md index 8e252622..ad6c0727 100644 --- a/doc/tutorials/TestScratchAssayTutorial.md +++ b/doc/tutorials/TestScratchAssayTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Scratch Assay Tutorial +title : "Test Scratch Assay Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestScratchAssayTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestScratchAssayTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestScratchAssayTutorial.py . Note that the code is given in full at the bottom of the page. diff --git a/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb b/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb new file mode 100644 index 00000000..0de64af4 --- /dev/null +++ b/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb @@ -0,0 +1,392 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7f5aad40", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestScratchAssayTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31b11251", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "1132d347", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "This tutorial is an example of modelling a scratch assay using a simple cellular automaton\n", + "representation of cells. It will cover the following techniques:\n", + "\n", + " * Setting up a regular mesh (or lattice)\n", + " * Visualizing the mesh\n", + " * Working with file-based output\n", + " * Generating cells and adding them to the mesh\n", + " * Simulating cell migration on the mesh\n", + " * Real-time visualization of the cell population and plotting of population statistics\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3188078b", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt # Plotting\n", + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "chaste.init() # Set up MPI\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.visualization # Visualization tools" + ] + }, + { + "cell_type": "markdown", + "id": "55f09b2a", + "metadata": {}, + "source": [ + "## Test 1 - Scratch Assay\n", + "In this test we will create a scratch along the middle of a domain and quantify the migration\n", + "of cells into the region. Cells will migrate by random walk on the their regular mesh (lattice).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1835f6a7", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "6ca0bc5c", + "metadata": {}, + "source": [ + "Chaste is based on the concept of `Cells` and `Meshes`. 'Cells' do not store their position in space,\n", + "or connectivity, these are managed by a `Mesh`. The first step in most Chaste simulations is to\n", + "set up a mesh, on which we can locate cells. A collection of `Cells` and a `Mesh` are a `CellPopulation`\n", + "in Chaste terminology. The most simple `CellPopulation` is the `CaBasedCellPopulation` which corresponds\n", + "to cells occupying discrete locations on a regular mesh (lattice). Our first step is to set up the mesh.\n", + "Here we set up a 2D lattice.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95eeca2c", + "metadata": {}, + "outputs": [], + "source": [ + "num_points_in_x = 100\n", + "num_points_in_y = 12\n", + "generator = chaste.mesh.PottsMeshGenerator2(num_points_in_x, 0, 0, num_points_in_y, 0, 0)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "0ecb6c54", + "metadata": {}, + "source": [ + "Note that we are using a `PottsMeshGenerator2` to set up the grid and we are setting some terms to 0. Chaste\n", + "design is based on re-use of components, the `PottsMeshGenerator` can be used to set up other types of\n", + "cell population which require these extra terms. Note also the '2' at the end of the class name. This\n", + "tells us that we are working in 2D. Most Chaste classes are specialized (templated) for spatial dimension,\n", + "so we need to make sure we are consistent in the dimensionality of the classes we are using.\n", + "\n", + "Next we set up some cells. We create and empty container `VectorSharedPtrCell` (which will behave like a Python list)\n", + "and will fill it with cells of our chosen type. In Chaste cells can be assinged a number of proliferative types\n", + "(Default, Differentiated, Stem, Transit or User Defined). These types will define how cells behave in certain\n", + "simulations, for example whether they will proliferate. We just want our cells to migrate in this example, so\n", + "we set a DifferentiatedCellProliferativeType.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8549652b", + "metadata": {}, + "outputs": [], + "source": [ + "cells = []\n", + "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()" + ] + }, + { + "cell_type": "markdown", + "id": "32c71fee", + "metadata": {}, + "source": [ + "We are not interested in cell cycling so we specialize the generator to NoCellCycleModel.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eddb0b29", + "metadata": {}, + "outputs": [], + "source": [ + "cell_generator = chaste.cell_based.CellsGeneratorNoCellCycleModel_2()" + ] + }, + { + "cell_type": "markdown", + "id": "ddad4e69", + "metadata": {}, + "source": [ + "We want two sets of cells, starting on opposite sides of the mesh. We use `location_indices` to map cells onto\n", + "locations (or Nodes) on the mesh. For our regular mesh the Node indices increase fastest in x, then y. We will\n", + "add four layers of cells to each side of the mesh.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b20c1098", + "metadata": {}, + "outputs": [], + "source": [ + "num_cell_layers = 4\n", + "bottom_location_indices = list(range(num_cell_layers*num_points_in_x))\n", + "num_grid_points = num_points_in_x*num_points_in_y\n", + "top_location_indices = list(range(num_grid_points-1, num_grid_points -\n", + " num_cell_layers*num_points_in_x-1, -1))\n", + "cells = cell_generator.GenerateGivenLocationIndices(\n", + " bottom_location_indices + top_location_indices,\n", + " differentiated_type)" + ] + }, + { + "cell_type": "markdown", + "id": "68c97925", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "467d5255", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.CaBasedCellPopulation2(mesh, cells,\n", + " bottom_location_indices +\n", + " top_location_indices)" + ] + }, + { + "cell_type": "markdown", + "id": "43211f16", + "metadata": {}, + "source": [ + "Next, we set up an `OffLatticeSimulation` which will manage the solver. We need to add some custom rules to\n", + "this solver to specify how we want the cells to migrate.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2c12e4d", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OnLatticeSimulation2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestScratchAssayTutorial\")\n", + "simulator.SetEndTime(10.0)\n", + "simulator.SetDt(0.1)\n", + "simulator.SetSamplingTimestepMultiple(1)" + ] + }, + { + "cell_type": "markdown", + "id": "d15b1b80", + "metadata": {}, + "source": [ + "We must now create a rule for cell migration. We will use an existing diffusion type rule.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ab3666f", + "metadata": {}, + "outputs": [], + "source": [ + "diffusion_update_rule = chaste.cell_based.DiffusionCaUpdateRule2()\n", + "simulator.AddUpdateRule(diffusion_update_rule)" + ] + }, + { + "cell_type": "markdown", + "id": "761aa121", + "metadata": {}, + "source": [ + "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", + "evovle in real time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb42c762", + "metadata": {}, + "outputs": [], + "source": [ + "scene= chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "scene.GetCellPopulationActorGenerator().SetShowCellCentres(True)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "c4057d3d", + "metadata": {}, + "source": [ + "We add the scene to the simulation for real-time updating using a `VtkSceneModifier`. Such\n", + "modifiers are called by the simulator at regular periods during the main time loop and\n", + "have access to the cell population. We will use a similar idea in a moment to record cell\n", + "positions for real time plotting.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e16d6e6", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(10)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "b7831aa4", + "metadata": {}, + "source": [ + "Chaste and PyChaste use object oriented programming. This may require some background reading,\n", + "but allows for great flexibility in terms of modifying existing functionality. In\n", + "order to pull the data we want out of the simulation as it runs we will create our own\n", + "simulation modifier class and use it for real time plotting. This Python class over-rides\n", + "one of the built-in classes, giving us access to the quantities we want during the simulation.\n", + "Usually we would define such a class in a different module and import it, it is placed\n", + "here for the purposes of the tutorial.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c86f52a", + "metadata": {}, + "outputs": [], + "source": [ + "class PlottingModifier(chaste.cell_based.PythonSimulationModifier2):\n", + " \"\"\" Class for real time plotting of cell numbers using Matplotlib\n", + " \"\"\"\n", + " def __init__(self, num_points_in_x, num_points_in_y):\n", + " super(PlottingModifier, self).__init__()\n", + " # Set up a figure for plotting\n", + " plt.ioff()\n", + " self.fig = plt.figure()\n", + " self.fig.ax = self.fig.add_subplot(111)\n", + " self.fig.ax.set_xlabel(\"y - Position (Cell Lengths)\")\n", + " self.fig.ax.set_ylabel(\"Number Of Cells\")\n", + " self.plot_frequency = 10 # only plot every 10 steps\n", + " self.num_points_in_x = num_points_in_x\n", + " self.num_points_in_y = num_points_in_y\n", + " def UpdateAtEndOfTimeStep(self, cell_population):\n", + " \"\"\" Plot the number of cells at each lattice point and time-point\n", + " Use the SimulationTime singleton to determine when to plot.\n", + " \"\"\"\n", + " num_increments = chaste.cell_based.SimulationTime.Instance().GetTimeStepsElapsed()\n", + " if num_increments % self.plot_frequency == 0:\n", + " y_locations = np.linspace(0, num_points_in_y, num_points_in_y)\n", + " num_cells = []\n", + " for idx in range(num_points_in_y):\n", + " counter = 0\n", + " for jdx in range(num_points_in_x):\n", + " if cell_population.IsCellAttachedToLocationIndex(jdx +\n", + " idx*num_points_in_x):\n", + " counter +=1\n", + " num_cells.append(counter)\n", + " self.fig.ax.plot(y_locations, num_cells, color='black')\n", + " self.fig.canvas.draw()\n", + " #display.display(self.fig)\n", + " #display.clear_output(wait=True)\n", + " def SetupSolve(self, cell_population, output_directory):\n", + " \"\"\" Ensure the cell population is in the correct state at the start of the simulation\n", + " \"\"\"\n", + " cell_population.Update()\n", + "plotting_modifier = PlottingModifier(num_points_in_x, num_points_in_y)\n", + "simulator.AddSimulationModifier(plotting_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "43ef8599", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()` and optionally set up interactive plotting. We will see the cells\n", + "migrate and the population distribution gradually become more uniform.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f907c915", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "plt.ion()\n", + "plt.show()\n", + "simulator.Solve()\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestSpheroidTutorial.ipynb b/doc/tutorials/TestSpheroidTutorial.ipynb index d1af2a8a..20862e4e 100644 --- a/doc/tutorials/TestSpheroidTutorial.ipynb +++ b/doc/tutorials/TestSpheroidTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "7d953825", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestSpheroidTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestSpheroidTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "28001f1c", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "c01108e5", "metadata": {}, "source": [ "\n", @@ -39,6 +42,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1cb48bf2", "metadata": {}, "outputs": [], "source": [ @@ -54,6 +58,7 @@ }, { "cell_type": "markdown", + "id": "f9056e76", "metadata": {}, "source": [ "## Test 1 - a 2D mesh-based spheroid\n", @@ -65,6 +70,7 @@ { "cell_type": "code", "execution_count": null, + "id": "036baef6", "metadata": {}, "outputs": [], "source": [ @@ -74,6 +80,7 @@ }, { "cell_type": "markdown", + "id": "e84e12d3", "metadata": {}, "source": [ "This time we will use on off-lattice `MeshBased` cell population. Cell centres are joined with\n", @@ -90,6 +97,7 @@ { "cell_type": "code", "execution_count": null, + "id": "f5a2550f", "metadata": {}, "outputs": [], "source": [ @@ -100,6 +108,7 @@ }, { "cell_type": "markdown", + "id": "cab30cb5", "metadata": {}, "source": [ "We create some cells next, with a stem-like proliferative type. This means they will continually\n", @@ -110,6 +119,7 @@ { "cell_type": "code", "execution_count": null, + "id": "32ae9dc1", "metadata": {}, "outputs": [], "source": [ @@ -120,6 +130,7 @@ }, { "cell_type": "markdown", + "id": "a8d9e316", "metadata": {}, "source": [ "Define when cells become apoptotic\n", @@ -129,6 +140,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c0a8ede5", "metadata": {}, "outputs": [], "source": [ @@ -149,6 +161,7 @@ }, { "cell_type": "markdown", + "id": "542c7805", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation` as before.\n", @@ -158,6 +171,7 @@ { "cell_type": "code", "execution_count": null, + "id": "26c2bdb7", "metadata": {}, "outputs": [], "source": [ @@ -166,6 +180,7 @@ }, { "cell_type": "markdown", + "id": "d14c5bc6", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly generate the required .vtu files.\n", @@ -175,6 +190,7 @@ { "cell_type": "code", "execution_count": null, + "id": "1a79e3e5", "metadata": {}, "outputs": [], "source": [ @@ -183,6 +199,7 @@ }, { "cell_type": "markdown", + "id": "2d30ffa6", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -192,6 +209,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ddd98115", "metadata": {}, "outputs": [], "source": [ @@ -202,6 +220,7 @@ }, { "cell_type": "markdown", + "id": "4ec5e761", "metadata": {}, "source": [ "We ask for output every 12 increments\n", @@ -211,6 +230,7 @@ { "cell_type": "code", "execution_count": null, + "id": "28a96497", "metadata": {}, "outputs": [], "source": [ @@ -219,6 +239,7 @@ }, { "cell_type": "markdown", + "id": "b2e29299", "metadata": {}, "source": [ "We define how the springs between cells behave using a force law.\n", @@ -228,6 +249,7 @@ { "cell_type": "code", "execution_count": null, + "id": "68bac92a", "metadata": {}, "outputs": [], "source": [ @@ -237,6 +259,7 @@ }, { "cell_type": "markdown", + "id": "6242379d", "metadata": {}, "source": [ "We set up a PDE for oxygen diffusion and consumption by cells, setting the rate of consumption to 0.1\n", @@ -246,6 +269,7 @@ { "cell_type": "code", "execution_count": null, + "id": "705b8b8b", "metadata": {}, "outputs": [], "source": [ @@ -254,6 +278,7 @@ }, { "cell_type": "markdown", + "id": "8a44cf04", "metadata": {}, "source": [ "We set a constant amount of oxygen on the edge of the spheroid\n", @@ -263,6 +288,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ca02d747", "metadata": {}, "outputs": [], "source": [ @@ -272,6 +298,7 @@ }, { "cell_type": "markdown", + "id": "79ebdc8b", "metadata": {}, "source": [ "Set up a pde modifier to solve the PDE at each simulation time step\n", @@ -281,6 +308,7 @@ { "cell_type": "code", "execution_count": null, + "id": "64493e57", "metadata": {}, "outputs": [], "source": [ @@ -290,6 +318,7 @@ }, { "cell_type": "markdown", + "id": "e1ee68a4", "metadata": {}, "source": [ "As before, we set up a scene modifier for real-time visualization\n", @@ -299,6 +328,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4543c5ba", "metadata": {}, "outputs": [], "source": [ @@ -317,6 +347,7 @@ }, { "cell_type": "markdown", + "id": "54fb894b", "metadata": {}, "source": [ "Eventually remove apoptotic cells\n", @@ -326,6 +357,7 @@ { "cell_type": "code", "execution_count": null, + "id": "239312fd", "metadata": {}, "outputs": [], "source": [ @@ -335,6 +367,7 @@ }, { "cell_type": "markdown", + "id": "799be0a3", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -344,6 +377,7 @@ { "cell_type": "code", "execution_count": null, + "id": "bce6762b", "metadata": {}, "outputs": [], "source": [ @@ -355,6 +389,7 @@ }, { "cell_type": "markdown", + "id": "d956368f", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", @@ -364,5 +399,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestSpheroidTutorial.md b/doc/tutorials/TestSpheroidTutorial.md index dc0a7a1f..e3fa4b8e 100644 --- a/doc/tutorials/TestSpheroidTutorial.md +++ b/doc/tutorials/TestSpheroidTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Spheroid Tutorial +title : "Test Spheroid Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestSpheroidTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestSpheroidTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestSpheroidTutorial.py . Note that the code is given in full at the bottom of the page. diff --git a/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb b/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb new file mode 100644 index 00000000..20862e4e --- /dev/null +++ b/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb @@ -0,0 +1,403 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d953825", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestSpheroidTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28001f1c", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "c01108e5", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "This tutorial is an example of modelling spheroid growth with a nutrient.\n", + "It covers:\n", + " * Setting up an off-lattice cell population\n", + " * Setting up a cell cycle model with oxygen dependence\n", + " * Setting up and solving an oxygen transport PDE\n", + " * Setting up a cell killer\n", + " ## Imports and Setup\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cb48bf2", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt # Plotting\n", + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.pde # PDEs\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.visualization # Visualization tools\n", + "chaste.init() # Set up MPI" + ] + }, + { + "cell_type": "markdown", + "id": "f9056e76", + "metadata": {}, + "source": [ + "## Test 1 - a 2D mesh-based spheroid\n", + "In this test we set up a spheroid with a plentiful supply of oxygen on the boundary and watch it grow\n", + "over time. Cells can gradually become apoptotic if the oxygen tension is too low.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "036baef6", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "e84e12d3", + "metadata": {}, + "source": [ + "This time we will use on off-lattice `MeshBased` cell population. Cell centres are joined with\n", + "springs with a Delauney Triangulation used to identify neighbours. Cell area is given by the dual\n", + "(Voronoi Tesselation). We start off with a small number of cells. We use a `MutableMesh` which\n", + "can change connectivity over time and a `HoneycombMeshGenerator` to set it up with a simple\n", + "honeycomb pattern. Here the first and second arguments define the size of the mesh -\n", + "we have chosen a mesh that is 5 nodes (i.e. cells) wide, and 5 nodes high. The extra '2' argument puts\n", + "two layers of non-cell elements around the mesh, which help to form a nicer voronoi tesselation\n", + "for area calculations.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5a2550f", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestSpheroidTutorial\")\n", + "generator = chaste.mesh.HoneycombMeshGenerator(5, 5)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "cab30cb5", + "metadata": {}, + "source": [ + "We create some cells next, with a stem-like proliferative type. This means they will continually\n", + "proliferate if there is enough oxygen, similar to how a tumour spheroid may behave.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32ae9dc1", + "metadata": {}, + "outputs": [], + "source": [ + "stem_type = chaste.cell_based.StemCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorSimpleOxygenBasedCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumNodes(), stem_type)" + ] + }, + { + "cell_type": "markdown", + "id": "a8d9e316", + "metadata": {}, + "source": [ + "Define when cells become apoptotic\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0a8ede5", + "metadata": {}, + "outputs": [], + "source": [ + "for eachCell in cells:\n", + " cell_cycle_model = eachCell.GetCellCycleModel()\n", + " eachCell.GetCellData().SetItem(\"oxygen\", 30.0)\n", + " cell_cycle_model.SetDimension(2)\n", + " cell_cycle_model.SetStemCellG1Duration(4.0)\n", + " cell_cycle_model.SetHypoxicConcentration(0.1)\n", + " cell_cycle_model.SetQuiescentConcentration(0.3)\n", + " cell_cycle_model.SetCriticalHypoxicDuration(8)\n", + " g1_duration = cell_cycle_model.GetStemCellG1Duration()\n", + " sg2m_duration = cell_cycle_model.GetSG2MDuration()\n", + " rnum = chaste.core.RandomNumberGenerator.Instance().ranf()\n", + " birth_time = -rnum * (g1_duration + sg2m_duration)\n", + " eachCell.SetBirthTime(birth_time)" + ] + }, + { + "cell_type": "markdown", + "id": "542c7805", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation` as before.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26c2bdb7", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.MeshBasedCellPopulation2_2(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "d14c5bc6", + "metadata": {}, + "source": [ + "To view the results of this and the next test in Paraview it is necessary to explicitly generate the required .vtu files.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a79e3e5", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population.AddPopulationWriterVoronoiDataWriter()" + ] + }, + { + "cell_type": "markdown", + "id": "2d30ffa6", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ddd98115", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestSpheroidTutorial\")\n", + "simulator.SetEndTime(5.0)" + ] + }, + { + "cell_type": "markdown", + "id": "4ec5e761", + "metadata": {}, + "source": [ + "We ask for output every 12 increments\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28a96497", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.SetSamplingTimestepMultiple(100)" + ] + }, + { + "cell_type": "markdown", + "id": "b2e29299", + "metadata": {}, + "source": [ + "We define how the springs between cells behave using a force law.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68bac92a", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.GeneralisedLinearSpringForce2_2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "6242379d", + "metadata": {}, + "source": [ + "We set up a PDE for oxygen diffusion and consumption by cells, setting the rate of consumption to 0.1\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "705b8b8b", + "metadata": {}, + "outputs": [], + "source": [ + "pde = chaste.cell_based.CellwiseSourceEllipticPde2(cell_population, -0.5)" + ] + }, + { + "cell_type": "markdown", + "id": "8a44cf04", + "metadata": {}, + "source": [ + "We set a constant amount of oxygen on the edge of the spheroid\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca02d747", + "metadata": {}, + "outputs": [], + "source": [ + "bc = chaste.pde.ConstBoundaryCondition2(1.0)\n", + "is_neumann_bc = False" + ] + }, + { + "cell_type": "markdown", + "id": "79ebdc8b", + "metadata": {}, + "source": [ + "Set up a pde modifier to solve the PDE at each simulation time step\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64493e57", + "metadata": {}, + "outputs": [], + "source": [ + "#pde_modifier.SetDependentVariableName(\"oxygen\")\n", + "#simulator.AddSimulationModifier(pde_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "e1ee68a4", + "metadata": {}, + "source": [ + "As before, we set up a scene modifier for real-time visualization\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4543c5ba", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "scene.GetCellPopulationActorGenerator().SetColorByCellData(True)\n", + "scene.GetCellPopulationActorGenerator().SetDataLabel(\"oxygen\")\n", + "scene.GetCellPopulationActorGenerator().SetShowCellCentres(True)\n", + "scene.GetCellPopulationActorGenerator().SetShowVoronoiMeshEdges(False)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "54fb894b", + "metadata": {}, + "source": [ + "Eventually remove apoptotic cells\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "239312fd", + "metadata": {}, + "outputs": [], + "source": [ + "killer = chaste.cell_based.ApoptoticCellKiller2(cell_population)\n", + "simulator.AddCellKiller(killer)" + ] + }, + { + "cell_type": "markdown", + "id": "799be0a3", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bce6762b", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "d956368f", + "metadata": {}, + "source": [ + "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", + "\n" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestTensileTestTutorial.ipynb b/doc/tutorials/TestTensileTestTutorial.ipynb index db569757..eae00892 100644 --- a/doc/tutorials/TestTensileTestTutorial.ipynb +++ b/doc/tutorials/TestTensileTestTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "e6433a58", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestTensileTestTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestTensileTestTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "9ab4e1c6", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "d641c612", "metadata": {}, "source": [ "\n", @@ -39,6 +42,7 @@ { "cell_type": "code", "execution_count": null, + "id": "834d3289", "metadata": {}, "outputs": [], "source": [ @@ -52,6 +56,7 @@ }, { "cell_type": "markdown", + "id": "d4fd421c", "metadata": {}, "source": [ "## Test 1 - A 2d test\n", @@ -61,6 +66,7 @@ { "cell_type": "code", "execution_count": null, + "id": "455f45d5", "metadata": {}, "outputs": [], "source": [ @@ -70,6 +76,7 @@ }, { "cell_type": "markdown", + "id": "36903a61", "metadata": {}, "source": [ "First, we generate a vertex mesh using a HoneycombVertexMeshGenerator.\n", @@ -79,6 +86,7 @@ { "cell_type": "code", "execution_count": null, + "id": "09185796", "metadata": {}, "outputs": [], "source": [ @@ -88,6 +96,7 @@ }, { "cell_type": "markdown", + "id": "4a4d26a0", "metadata": {}, "source": [ "Now set up the cells, again we want to avoid proliferation.\n", @@ -97,17 +106,18 @@ { "cell_type": "code", "execution_count": null, + "id": "f9224053", "metadata": {}, "outputs": [], "source": [ "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(),\n", - " differentiated_type)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), differentiated_type)" ] }, { "cell_type": "markdown", + "id": "6a9aa058", "metadata": {}, "source": [ "Next, create the cell population\n", @@ -117,6 +127,7 @@ { "cell_type": "code", "execution_count": null, + "id": "d2c219b7", "metadata": {}, "outputs": [], "source": [ @@ -126,6 +137,7 @@ }, { "cell_type": "markdown", + "id": "4a32a73a", "metadata": {}, "source": [ "Pass the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -135,6 +147,7 @@ { "cell_type": "code", "execution_count": null, + "id": "445e1929", "metadata": {}, "outputs": [], "source": [ @@ -146,6 +159,7 @@ }, { "cell_type": "markdown", + "id": "83eb82a2", "metadata": {}, "source": [ "Now create a force law\n", @@ -155,6 +169,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c07b5947", "metadata": {}, "outputs": [], "source": [ @@ -164,6 +179,7 @@ }, { "cell_type": "markdown", + "id": "49afd280", "metadata": {}, "source": [ "A `NagaiHondaForce` assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -176,6 +192,7 @@ { "cell_type": "code", "execution_count": null, + "id": "53c33b3a", "metadata": {}, "outputs": [], "source": [ @@ -185,6 +202,7 @@ }, { "cell_type": "markdown", + "id": "a6cf9ace", "metadata": {}, "source": [ "For our tensile test we will fix the bottom of the sheet and subject the top to an applied displacement. We neglect\n", @@ -195,6 +213,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c0a3f892", "metadata": {}, "outputs": [], "source": [ @@ -204,14 +223,13 @@ "simulator.AddCellPopulationBoundaryCondition(bc)\n", "point = np.array([0.0, 15.5])\n", "normal = np.array([0.0, -1.0])\n", - "bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population,\n", - " point,\n", - " normal)\n", + "bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, point, normal)\n", "simulator.AddCellPopulationBoundaryCondition(bc2)" ] }, { "cell_type": "markdown", + "id": "cb0d486e", "metadata": {}, "source": [ "We want to displace our top boundary over time. We could write a custom boundary condition class to do this.\n", @@ -223,6 +241,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c61730fa", "metadata": {}, "outputs": [], "source": [ @@ -251,6 +270,7 @@ }, { "cell_type": "markdown", + "id": "96a530b6", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -261,6 +281,7 @@ { "cell_type": "code", "execution_count": null, + "id": "59a5df37", "metadata": {}, "outputs": [], "source": [ @@ -275,6 +296,7 @@ }, { "cell_type": "markdown", + "id": "727a3df1", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -284,6 +306,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e99062df", "metadata": {}, "outputs": [], "source": [ @@ -296,5 +319,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestTensileTestTutorial.md b/doc/tutorials/TestTensileTestTutorial.md index db67497d..cd17c550 100644 --- a/doc/tutorials/TestTensileTestTutorial.md +++ b/doc/tutorials/TestTensileTestTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Tensile Test Tutorial +title : "Test Tensile Test Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestTensileTestTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestTensileTestTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestTensileTestTutorial.py . Note that the code is given in full at the bottom of the page. @@ -49,8 +54,7 @@ Now set up the cells, again we want to avoid proliferation. ```python differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - differentiated_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), differentiated_type) ``` Next, create the cell population @@ -96,9 +100,7 @@ fixing lateral degress of freedom for simplicity, since we are using an over-dam simulator.AddCellPopulationBoundaryCondition(bc) point = np.array([0.0, 15.5]) normal = np.array([0.0, -1.0]) - bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, - point, - normal) + bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, point, normal) simulator.AddCellPopulationBoundaryCondition(bc2) ``` @@ -193,8 +195,7 @@ class TestTensileTestTutorial(chaste.cell_based.AbstractCellBasedTestSuite): differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - differentiated_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), differentiated_type) cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells) @@ -216,9 +217,7 @@ class TestTensileTestTutorial(chaste.cell_based.AbstractCellBasedTestSuite): simulator.AddCellPopulationBoundaryCondition(bc) point = np.array([0.0, 15.5]) normal = np.array([0.0, -1.0]) - bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, - point, - normal) + bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, point, normal) simulator.AddCellPopulationBoundaryCondition(bc2) class BoundaryConditionModifier(chaste.cell_based.PythonSimulationModifier2): diff --git a/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb b/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb new file mode 100644 index 00000000..eae00892 --- /dev/null +++ b/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e6433a58", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestTensileTestTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ab4e1c6", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "d641c612", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "In this tutorial we will demonstrate a simulated tensile test on an epithelial sheet. This test\n", + "demonstrates:\n", + " * Working with vertex based off lattice populations\n", + " * Applying boundary conditions\n", + " * Working with forces\n", + " \n", + "## The Test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "834d3289", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.visualization # Visualization tools\n", + "chaste.init() # Set up MPI" + ] + }, + { + "cell_type": "markdown", + "id": "d4fd421c", + "metadata": {}, + "source": [ + "## Test 1 - A 2d test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "455f45d5", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "36903a61", + "metadata": {}, + "source": [ + "First, we generate a vertex mesh using a HoneycombVertexMeshGenerator.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09185796", + "metadata": {}, + "outputs": [], + "source": [ + "generator = chaste.mesh.HoneycombVertexMeshGenerator(5, 15)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "4a4d26a0", + "metadata": {}, + "source": [ + "Now set up the cells, again we want to avoid proliferation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9224053", + "metadata": {}, + "outputs": [], + "source": [ + "differentiated_type = chaste.cell_based.DifferentiatedCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), differentiated_type)" + ] + }, + { + "cell_type": "markdown", + "id": "6a9aa058", + "metadata": {}, + "source": [ + "Next, create the cell population\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2c219b7", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh,\n", + " cells)" + ] + }, + { + "cell_type": "markdown", + "id": "4a32a73a", + "metadata": {}, + "source": [ + "Pass the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "445e1929", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestTensileTest\")\n", + "simulator.SetEndTime(1.0)\n", + "simulator.SetSamplingTimestepMultiple(1000)" + ] + }, + { + "cell_type": "markdown", + "id": "83eb82a2", + "metadata": {}, + "source": [ + "Now create a force law\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c07b5947", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.NagaiHondaForce2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "49afd280", + "metadata": {}, + "source": [ + "A `NagaiHondaForce` assumes that each cell has a target area. The target areas of cells are used to determine\n", + "pressure forces on each vertex and eventually determine the size of each cell in the simulation.\n", + "In order to assign target areas to cells and update them in each time step we add a `SimpleTargetAreaModifier`\n", + "to the simulation, which inherits from `AbstractTargetAreaModifier`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53c33b3a", + "metadata": {}, + "outputs": [], + "source": [ + "growth_modifier = chaste.cell_based.SimpleTargetAreaModifier2()\n", + "simulator.AddSimulationModifier(growth_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "a6cf9ace", + "metadata": {}, + "source": [ + "For our tensile test we will fix the bottom of the sheet and subject the top to an applied displacement. We neglect\n", + "fixing lateral degress of freedom for simplicity, since we are using an over-damped mechanical model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0a3f892", + "metadata": {}, + "outputs": [], + "source": [ + "my_point = np.array([0.0, 0.0])\n", + "normal = np.array([0.0, -1.0])\n", + "bc = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, my_point, normal)\n", + "simulator.AddCellPopulationBoundaryCondition(bc)\n", + "point = np.array([0.0, 15.5])\n", + "normal = np.array([0.0, -1.0])\n", + "bc2 = chaste.cell_based.AttractingPlaneBoundaryCondition2_2(cell_population, point, normal)\n", + "simulator.AddCellPopulationBoundaryCondition(bc2)" + ] + }, + { + "cell_type": "markdown", + "id": "cb0d486e", + "metadata": {}, + "source": [ + "We want to displace our top boundary over time. We could write a custom boundary condition class to do this.\n", + "A more simple alternative is to modify the the position of the point describing our boundary plane in `bc2`\n", + "as the simulation progresses. As per earlier tutorials we make a new `SimulationModifier` class to do this.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c61730fa", + "metadata": {}, + "outputs": [], + "source": [ + "class BoundaryConditionModifier(chaste.cell_based.PythonSimulationModifier2):\n", + " \"\"\" Class for time varying boundary conditions\n", + " \"\"\"\n", + " def __init__(self, boundary_condition):\n", + " self.boundary_condition = boundary_condition\n", + " self.original_location = boundary_condition.rGetPointOnPlane()\n", + " self.velocity = 0.5 # cell lengths per time\n", + " super(BoundaryConditionModifier, self).__init__()\n", + " def UpdateAtEndOfTimeStep(self, cell_population):\n", + " \"\"\" Move the boundary upwards at the specified velocity\n", + " \"\"\"\n", + " total_time = chaste.cell_based.SimulationTime.Instance().GetTime()\n", + " new_location = [self.original_location[0],\n", + " self.original_location[1] + self.velocity*total_time]\n", + " self.boundary_condition.SetPointOnPlane(np.array(new_location))\n", + " def SetupSolve(self, cell_population, output_directory):\n", + " \"\"\" Make sure the cell population is in the correct state at the start of the simulation\n", + " \"\"\"\n", + " cell_population.Update()\n", + "bc_modifier = BoundaryConditionModifier(bc2)\n", + "simulator.AddSimulationModifier(bc_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "96a530b6", + "metadata": {}, + "source": [ + "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", + "evovle in real time.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59a5df37", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(1000)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "727a3df1", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e99062df", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb index 3bc310b3..fdcd628b 100644 --- a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb @@ -2,15 +2,17 @@ "cells": [ { "cell_type": "markdown", + "id": "4e4130d8", "metadata": {}, "source": [ - "This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py.\n", + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "a72b2908", "metadata": {}, "outputs": [], "source": [ @@ -22,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "8d3c3ea3", "metadata": {}, "source": [ "\n", @@ -37,6 +40,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8d340a4a", "metadata": {}, "outputs": [], "source": [ @@ -51,6 +55,7 @@ }, { "cell_type": "markdown", + "id": "6ae7842c", "metadata": {}, "source": [ "## Test 1 - A basic vertex-based simulation\n", @@ -62,6 +67,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e55a97b2", "metadata": {}, "outputs": [], "source": [ @@ -71,6 +77,7 @@ }, { "cell_type": "markdown", + "id": "827223e9", "metadata": {}, "source": [ "First, we generate a vertex mesh. To create a MutableVertexMesh, we can use the HoneycombVertexMeshGenerator.\n", @@ -82,6 +89,7 @@ { "cell_type": "code", "execution_count": null, + "id": "02f596e3", "metadata": {}, "outputs": [], "source": [ @@ -92,6 +100,7 @@ }, { "cell_type": "markdown", + "id": "91652a99", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs. To do this, we use the CellsGenerator helper class,\n", @@ -105,17 +114,18 @@ { "cell_type": "code", "execution_count": null, + "id": "09d8261a", "metadata": {}, "outputs": [], "source": [ "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(),\n", - " transit_type)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type)" ] }, { "cell_type": "markdown", + "id": "87974fdf", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -127,15 +137,16 @@ { "cell_type": "code", "execution_count": null, + "id": "197868dd", "metadata": {}, "outputs": [], "source": [ - "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh,\n", - " cells)" + "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells)" ] }, { "cell_type": "markdown", + "id": "857f081f", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -145,6 +156,7 @@ { "cell_type": "code", "execution_count": null, + "id": "54f51e69", "metadata": {}, "outputs": [], "source": [ @@ -156,6 +168,7 @@ }, { "cell_type": "markdown", + "id": "58a1ac86", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -165,6 +178,7 @@ { "cell_type": "code", "execution_count": null, + "id": "84c64de6", "metadata": {}, "outputs": [], "source": [ @@ -175,6 +189,7 @@ }, { "cell_type": "markdown", + "id": "16058604", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step.\n", @@ -187,6 +202,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c32926df", "metadata": {}, "outputs": [], "source": [ @@ -195,6 +211,7 @@ }, { "cell_type": "markdown", + "id": "d53a69e9", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the vertices of each cell in a cell population.\n", @@ -208,6 +225,7 @@ { "cell_type": "code", "execution_count": null, + "id": "6220bd60", "metadata": {}, "outputs": [], "source": [ @@ -217,6 +235,7 @@ }, { "cell_type": "markdown", + "id": "dfde3289", "metadata": {}, "source": [ "A NagaiHondaForce assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -229,6 +248,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e2f3e72c", "metadata": {}, "outputs": [], "source": [ @@ -238,6 +258,7 @@ }, { "cell_type": "markdown", + "id": "058f8346", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -247,6 +268,7 @@ { "cell_type": "code", "execution_count": null, + "id": "7542950b", "metadata": {}, "outputs": [], "source": [ @@ -258,6 +280,7 @@ }, { "cell_type": "markdown", + "id": "437539bc", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -267,6 +290,7 @@ { "cell_type": "code", "execution_count": null, + "id": "042bd9d4", "metadata": {}, "outputs": [], "source": [ @@ -277,6 +301,7 @@ }, { "cell_type": "markdown", + "id": "f4812e7c", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -287,16 +312,17 @@ { "cell_type": "code", "execution_count": null, + "id": "a5bff398", "metadata": {}, "outputs": [], "source": [ - " 5.0, 6)\n", "# Tear down the test \n", "chaste.cell_based.TearDownNotebookTest()" ] }, { "cell_type": "markdown", + "id": "5437ef57", "metadata": {}, "source": [ "## Test 2 - introducing periodicity, boundaries and cell killers\n", @@ -309,6 +335,7 @@ { "cell_type": "code", "execution_count": null, + "id": "bd3661ae", "metadata": {}, "outputs": [], "source": [ @@ -318,6 +345,7 @@ }, { "cell_type": "markdown", + "id": "54d0254e", "metadata": {}, "source": [ "First, we generate a periodic vertex mesh. To create a Cylindrical2dVertexMesh, we can use the CylindricalHoneycombVertexMeshGenerator.\n", @@ -330,6 +358,7 @@ { "cell_type": "code", "execution_count": null, + "id": "f5d124bc", "metadata": {}, "outputs": [], "source": [ @@ -339,6 +368,7 @@ }, { "cell_type": "markdown", + "id": "0ef448a1", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. This is exactly the same as the above test.\n", @@ -348,17 +378,18 @@ { "cell_type": "code", "execution_count": null, + "id": "4e891809", "metadata": {}, "outputs": [], "source": [ "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", - "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(),\n", - " transit_type)" + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type)" ] }, { "cell_type": "markdown", + "id": "35793e46", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. This is also the same as in the above test.\n", @@ -368,15 +399,16 @@ { "cell_type": "code", "execution_count": null, + "id": "cdeeacf0", "metadata": {}, "outputs": [], "source": [ - "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh,\n", - " cells)" + "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells)" ] }, { "cell_type": "markdown", + "id": "a848f459", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -386,6 +418,7 @@ { "cell_type": "code", "execution_count": null, + "id": "27c87582", "metadata": {}, "outputs": [], "source": [ @@ -397,6 +430,7 @@ }, { "cell_type": "markdown", + "id": "09f06c73", "metadata": {}, "source": [ "We now make a pointer to an appropriate force and pass it to the OffLatticeSimulation.\n", @@ -406,6 +440,7 @@ { "cell_type": "code", "execution_count": null, + "id": "53e730d8", "metadata": {}, "outputs": [], "source": [ @@ -415,6 +450,7 @@ }, { "cell_type": "markdown", + "id": "b593134f", "metadata": {}, "source": [ "We also make a pointer to the target area modifier and add it to the simulator.\n", @@ -424,6 +460,7 @@ { "cell_type": "code", "execution_count": null, + "id": "65a9a66b", "metadata": {}, "outputs": [], "source": [ @@ -433,6 +470,7 @@ }, { "cell_type": "markdown", + "id": "d12d2bb4", "metadata": {}, "source": [ "We now create one or more CellPopulationBoundaryConditions, which determine any conditions which each cell in a cell population must satisfy.\n", @@ -447,6 +485,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b1b39cf7", "metadata": {}, "outputs": [], "source": [ @@ -456,25 +495,26 @@ }, { "cell_type": "markdown", + "id": "8f1671db", "metadata": {}, "source": [ "We can now make a PlaneBoundaryCondition (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", - "bc = chaste.cell_based.PlaneBoundaryCondition2_2(cell_population,\n" + "bc = chaste.cell_based.PlaneBoundaryCondition2_2(cell_population, point, normal)\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "09c97391", "metadata": {}, "outputs": [], "source": [ - " point,\n", - " normal)\n", "simulator.AddCellPopulationBoundaryCondition(bc)" ] }, { "cell_type": "markdown", + "id": "03b9d30c", "metadata": {}, "source": [ "We now create one or more CellKillers, which determine how cells are removed from the simulation.\n", @@ -487,6 +527,7 @@ { "cell_type": "code", "execution_count": null, + "id": "98fb0f4e", "metadata": {}, "outputs": [], "source": [ @@ -496,45 +537,31 @@ }, { "cell_type": "markdown", + "id": "599aca20", "metadata": {}, "source": [ "Finally we now make a PlaneBasedCellKiller (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", - "\n" + "killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population, point, normal)\n" ] }, { "cell_type": "code", "execution_count": null, + "id": "d49f5d64", "metadata": {}, "outputs": [], "source": [ - "killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population,\n", - " point,\n", - " normal)\n", "simulator.AddCellKiller(killer)" ] }, { "cell_type": "markdown", + "id": "624ffd8e", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "simulator.Solve()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ + "simulator.Solve()\n", + "\n", "The next two lines are for test purposes only and are not part of this tutorial.\n", "If different simulation input parameters are being explored the lines should be removed.\n", "\n" @@ -543,10 +570,10 @@ { "cell_type": "code", "execution_count": null, + "id": "29ae9b5f", "metadata": {}, "outputs": [], "source": [ - " 1.0, 6)\n", "# Tear down the test \n", "chaste.cell_based.TearDownNotebookTest()" ] @@ -554,5 +581,5 @@ ], "metadata": {}, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.md b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.md index d1e43d30..69459502 100644 --- a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.md +++ b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.md @@ -1,9 +1,14 @@ + --- -layout: page-full-width -title: Test Vertex Based Cell Simulations Python Tutorial +title : "Test Vertex Based Cell Simulations Python Tutorial" +summary: "" +draft: false +images: [] +toc: true +layout: "single" --- -This tutorial is automatically generated from the file test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py. -[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/TestVertexBasedCellSimulationsPythonTutorial_nb.html) + +This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py . Note that the code is given in full at the bottom of the page. @@ -56,8 +61,7 @@ the third argument specifies the proliferative type of the cell. ```python transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type) ``` Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. @@ -65,8 +69,7 @@ In general, this class associates a collection of cells with a mesh. For this te we use a particular type of cell population called a VertexBasedCellPopulation. ```python - cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells) ``` We can set up a `VtkScene` to do a quick visualization of the population before running the analysis. @@ -138,8 +141,7 @@ If different simulation input parameters are being explored the lines should be ```python self.assertEqual(cell_population.GetNumRealCells(), 7) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 5.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 5.0, 6) # JUPYTER_TEARDOWN @@ -170,15 +172,13 @@ Having created a mesh, we now create a VectorSharedPtrCells. This is exactly the ```python transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type) ``` Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. This is also the same as in the above test. ```python - cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells) ``` We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time @@ -217,10 +217,8 @@ The first step is to define a point on the plane boundary and a normal to the pl ``` We can now make a PlaneBoundaryCondition (passing the point and normal to the plane) and pass it to the OffLatticeSimulation. -bc = chaste.cell_based.PlaneBoundaryCondition2_2(cell_population, +bc = chaste.cell_based.PlaneBoundaryCondition2_2(cell_population, point, normal) ```python - point, - normal) simulator.AddCellPopulationBoundaryCondition(bc) ``` @@ -235,27 +233,20 @@ The first step is to define a point on the plane boundary and a normal to the pl ``` Finally we now make a PlaneBasedCellKiller (passing the point and normal to the plane) and pass it to the OffLatticeSimulation. - +killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population, point, normal) ```python - killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population, - point, - normal) simulator.AddCellKiller(killer) ``` To run the simulation, we call `Solve()`. +simulator.Solve() -```python - simulator.Solve() - -``` The next two lines are for test purposes only and are not part of this tutorial. If different simulation input parameters are being explored the lines should be removed. ```python self.assertEqual(cell_population.GetNumRealCells(), 12) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 1.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 1.0, 6) # JUPYTER_TEARDOWN @@ -292,11 +283,9 @@ class TestRunningVertexBasedSimulationsTutorial(chaste.cell_based.AbstractCellBa transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type) - cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells) scene = chaste.visualization.VtkScene2() scene.SetCellPopulation(cell_population) @@ -325,8 +314,7 @@ class TestRunningVertexBasedSimulationsTutorial(chaste.cell_based.AbstractCellBa scene.End() self.assertEqual(cell_population.GetNumRealCells(), 7) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 5.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 5.0, 6) # JUPYTER_TEARDOWN @@ -339,11 +327,9 @@ class TestRunningVertexBasedSimulationsTutorial(chaste.cell_based.AbstractCellBa transit_type = chaste.cell_based.TransitCellProliferativeType() cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2() - cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), - transit_type) + cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type) - cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, - cells) + cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells) simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population) simulator.SetOutputDirectory("Python/TestPeriodicVertexBasedCellPopulation") @@ -359,23 +345,15 @@ class TestRunningVertexBasedSimulationsTutorial(chaste.cell_based.AbstractCellBa point = np.array([0.0, 0.0]) normal = np.array([0.0, -1.0]) - point, - normal) simulator.AddCellPopulationBoundaryCondition(bc) point = np.array([0.0, 3.0]) normal = np.array([0.0, 1.0]) - killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population, - point, - normal) simulator.AddCellKiller(killer) - simulator.Solve() - self.assertEqual(cell_population.GetNumRealCells(), 12) - self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), - 1.0, 6) + self.assertAlmostEqual(chaste.cell_based.SimulationTime.Instance().GetTime(), 1.0, 6) # JUPYTER_TEARDOWN diff --git a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb new file mode 100644 index 00000000..fdcd628b --- /dev/null +++ b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -0,0 +1,585 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4e4130d8", + "metadata": {}, + "source": [ + "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a72b2908", + "metadata": {}, + "outputs": [], + "source": [ + "# Jupyter notebook specific imports \n", + "import matplotlib as mpl \n", + "from IPython import display \n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "8d3c3ea3", + "metadata": {}, + "source": [ + "\n", + "# Introduction\n", + "In this tutorial we show how Chaste can be used to create, run and visualize vertex-based simulations.\n", + "Full details of the mechanical model proposed by T. Nagai and H. Honda (\"A dynamic cell model for the formation of epithelial tissues\",\n", + "Philosophical Magazine Part B 81:699-719).\n", + "\n", + "## The Test\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d340a4a", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt # Plotting\n", + "import numpy as np # Matrix tools\n", + "import chaste # The PyChaste module\n", + "import chaste.cell_based # Contains cell populations\n", + "import chaste.mesh # Contains meshes\n", + "import chaste.visualization # Visualization tools\n", + "chaste.init() # Set up MPI" + ] + }, + { + "cell_type": "markdown", + "id": "6ae7842c", + "metadata": {}, + "source": [ + "## Test 1 - A basic vertex-based simulation\n", + "In the first test, we run a simple vertex-based simulation, in which we create a monolayer of cells,\n", + "using a mutable vertex mesh. Each cell is assigned a stochastic cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e55a97b2", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "827223e9", + "metadata": {}, + "source": [ + "First, we generate a vertex mesh. To create a MutableVertexMesh, we can use the HoneycombVertexMeshGenerator.\n", + "This generates a honeycomb-shaped mesh, in which all nodes are equidistant. Here the first and second arguments\n", + "define the size of the mesh - we have chosen a mesh that is 2 elements (i.e. cells) wide, and 2 elements high.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02f596e3", + "metadata": {}, + "outputs": [], + "source": [ + "chaste.core.OutputFileHandler(\"Python/TestVertexBasedCellSimulationsTutorial\")\n", + "generator = chaste.mesh.HoneycombVertexMeshGenerator(2, 2)\n", + "mesh = generator.GetMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "91652a99", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a std::vector of CellPtrs. To do this, we use the CellsGenerator helper class,\n", + "which is templated over the type of cell model required\n", + "and the dimension. We create an empty vector of cells and pass this into the method along with the mesh.\n", + "The second argument represents the size of that the vector cells should become - one cell for each element,\n", + "the third argument specifies the proliferative type of the cell.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09d8261a", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "87974fdf", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", + "In general, this class associates a collection of cells with a mesh. For this test, because we have a MutableVertexMesh,\n", + "we use a particular type of cell population called a VertexBasedCellPopulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "197868dd", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "857f081f", + "metadata": {}, + "source": [ + "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54f51e69", + "metadata": {}, + "outputs": [], + "source": [ + "scene = chaste.visualization.VtkScene2()\n", + "scene.SetCellPopulation(cell_population)\n", + "nb_manager = chaste.visualization.JupyterNotebookManager()\n", + "nb_manager.vtk_show(scene, height=600)" + ] + }, + { + "cell_type": "markdown", + "id": "58a1ac86", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "84c64de6", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestVertexBasedCellSimulationsTutorial\")\n", + "simulator.SetEndTime(5.0)" + ] + }, + { + "cell_type": "markdown", + "id": "16058604", + "metadata": {}, + "source": [ + "For longer simulations, we may not want to output the results every time step.\n", + "In this case we can use the following method, to print results every 50 time steps instead.\n", + "As the default time step used by the simulator (for vertex based simulations), is 0.02 hours, this method\n", + "will cause the simulator to print results every 6 minutes (i.e. 0.1 hours).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c32926df", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.SetSamplingTimestepMultiple(50)" + ] + }, + { + "cell_type": "markdown", + "id": "d53a69e9", + "metadata": {}, + "source": [ + "We must now create one or more force laws, which determine the mechanics of the vertices of each cell in a cell population.\n", + "For this test, we use one force law, based on the Nagai-Honda mechanics, and pass it to the OffLatticeSimulation.\n", + "For a list of possible forces see subclasses of AbstractForce.\n", + "Note that some of these forces are not compatible with vertex-based simulations see the specific class documentation for details,\n", + "if you try to use an incompatible class then you will receive a warning.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6220bd60", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.NagaiHondaForce2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "dfde3289", + "metadata": {}, + "source": [ + "A NagaiHondaForce assumes that each cell has a target area. The target areas of cells are used to determine\n", + "pressure forces on each vertex and eventually determine the size of each cell in the simulation.\n", + "In order to assign target areas to cells and update them in each time step we add a SimpleTargetAreaModifier\n", + "to the simulation, which inherits from AbstractTargetAreaModifier.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2f3e72c", + "metadata": {}, + "outputs": [], + "source": [ + "growth_modifier = chaste.cell_based.SimpleTargetAreaModifier2()\n", + "simulator.AddSimulationModifier(growth_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "058f8346", + "metadata": {}, + "source": [ + "Save snapshot images of the population during the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7542950b", + "metadata": {}, + "outputs": [], + "source": [ + "scene_modifier = chaste.visualization.JupyterSceneModifier2(nb_manager)\n", + "scene_modifier.SetVtkScene(scene)\n", + "scene_modifier.SetUpdateFrequency(100)\n", + "simulator.AddSimulationModifier(scene_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "437539bc", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "042bd9d4", + "metadata": {}, + "outputs": [], + "source": [ + "scene.Start()\n", + "simulator.Solve()\n", + "scene.End()" + ] + }, + { + "cell_type": "markdown", + "id": "f4812e7c", + "metadata": {}, + "source": [ + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5bff398", + "metadata": {}, + "outputs": [], + "source": [ + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "5437ef57", + "metadata": {}, + "source": [ + "## Test 2 - introducing periodicity, boundaries and cell killers\n", + "In the second test, we run a simple vertex-based simulation, in which we create a monolayer of cells in a periodic geometry,\n", + "using a cylindrical vertex mesh. We also include a fixed boundary which cells can't pass through and a cell killer which removes\n", + "cells once they leave a region. As before each cell is assigned a stochastic cell-cycle model.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bd3661ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up the test \n", + "chaste.cell_based.SetupNotebookTest()" + ] + }, + { + "cell_type": "markdown", + "id": "54d0254e", + "metadata": {}, + "source": [ + "First, we generate a periodic vertex mesh. To create a Cylindrical2dVertexMesh, we can use the CylindricalHoneycombVertexMeshGenerator.\n", + "This generates a honeycomb-shaped mesh, in which all nodes are equidistant and the right hand side is associated with the left hand side.\n", + "Here the first and second arguments define the size of the mesh - we have chosen a mesh that is\n", + "4 elements (i.e. cells) wide, and 4 elements high.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5d124bc", + "metadata": {}, + "outputs": [], + "source": [ + "generator = chaste.mesh.CylindricalHoneycombVertexMeshGenerator(4, 4)\n", + "mesh = generator.GetCylindricalMesh()" + ] + }, + { + "cell_type": "markdown", + "id": "0ef448a1", + "metadata": {}, + "source": [ + "Having created a mesh, we now create a VectorSharedPtrCells. This is exactly the same as the above test.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e891809", + "metadata": {}, + "outputs": [], + "source": [ + "transit_type = chaste.cell_based.TransitCellProliferativeType()\n", + "cell_generator = chaste.cell_based.CellsGeneratorUniformG1GenerationalCellCycleModel_2()\n", + "cells = cell_generator.GenerateBasicRandom(mesh.GetNumElements(), transit_type)" + ] + }, + { + "cell_type": "markdown", + "id": "35793e46", + "metadata": {}, + "source": [ + "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. This is also the same as in the above test.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cdeeacf0", + "metadata": {}, + "outputs": [], + "source": [ + "cell_population = chaste.cell_based.VertexBasedCellPopulation2(mesh, cells)" + ] + }, + { + "cell_type": "markdown", + "id": "a848f459", + "metadata": {}, + "source": [ + "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27c87582", + "metadata": {}, + "outputs": [], + "source": [ + "simulator = chaste.cell_based.OffLatticeSimulation2_2(cell_population)\n", + "simulator.SetOutputDirectory(\"Python/TestPeriodicVertexBasedCellPopulation\")\n", + "simulator.SetEndTime(1.0)\n", + "simulator.SetSamplingTimestepMultiple(50)" + ] + }, + { + "cell_type": "markdown", + "id": "09f06c73", + "metadata": {}, + "source": [ + "We now make a pointer to an appropriate force and pass it to the OffLatticeSimulation.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53e730d8", + "metadata": {}, + "outputs": [], + "source": [ + "force = chaste.cell_based.NagaiHondaForce2()\n", + "simulator.AddForce(force)" + ] + }, + { + "cell_type": "markdown", + "id": "b593134f", + "metadata": {}, + "source": [ + "We also make a pointer to the target area modifier and add it to the simulator.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65a9a66b", + "metadata": {}, + "outputs": [], + "source": [ + "growth_modifier = chaste.cell_based.SimpleTargetAreaModifier2()\n", + "simulator.AddSimulationModifier(growth_modifier)" + ] + }, + { + "cell_type": "markdown", + "id": "d12d2bb4", + "metadata": {}, + "source": [ + "We now create one or more CellPopulationBoundaryConditions, which determine any conditions which each cell in a cell population must satisfy.\n", + "For this test, we use a PlaneBoundaryCondition, and pass it to the OffLatticeSimulation. For a list of possible boundary condition\n", + "see subclasses of AbstractCellPopulationBoundaryCondition.\n", + "Note that some of these boundary conditions are not compatible with vertex-based simulations see the specific class documentation\n", + "for details, if you try to use an incompatible class then you will receive a warning.\n", + "The first step is to define a point on the plane boundary and a normal to the plane.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1b39cf7", + "metadata": {}, + "outputs": [], + "source": [ + "point = np.array([0.0, 0.0])\n", + "normal = np.array([0.0, -1.0])" + ] + }, + { + "cell_type": "markdown", + "id": "8f1671db", + "metadata": {}, + "source": [ + "We can now make a PlaneBoundaryCondition (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", + "bc = chaste.cell_based.PlaneBoundaryCondition2_2(cell_population, point, normal)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09c97391", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.AddCellPopulationBoundaryCondition(bc)" + ] + }, + { + "cell_type": "markdown", + "id": "03b9d30c", + "metadata": {}, + "source": [ + "We now create one or more CellKillers, which determine how cells are removed from the simulation.\n", + "For this test, we use a PlaneBasedCellKiller, and pass it to the OffLatticeSimulation.\n", + "For a list of possible cell killers see subclasses of AbstractCellKiller.\n", + "The first step is to define a point on the plane boundary and a normal to the plane.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98fb0f4e", + "metadata": {}, + "outputs": [], + "source": [ + "point = np.array([0.0, 3.0])\n", + "normal = np.array([0.0, 1.0])" + ] + }, + { + "cell_type": "markdown", + "id": "599aca20", + "metadata": {}, + "source": [ + "Finally we now make a PlaneBasedCellKiller (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", + "killer = chaste.cell_based.PlaneBasedCellKiller2(cell_population, point, normal)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d49f5d64", + "metadata": {}, + "outputs": [], + "source": [ + "simulator.AddCellKiller(killer)" + ] + }, + { + "cell_type": "markdown", + "id": "624ffd8e", + "metadata": {}, + "source": [ + "To run the simulation, we call `Solve()`.\n", + "simulator.Solve()\n", + "\n", + "The next two lines are for test purposes only and are not part of this tutorial.\n", + "If different simulation input parameters are being explored the lines should be removed.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29ae9b5f", + "metadata": {}, + "outputs": [], + "source": [ + "# Tear down the test \n", + "chaste.cell_based.TearDownNotebookTest()" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/infra/CreateJupyterNotebookTutorial.py b/infra/CreateJupyterNotebookTutorial.py index 1a691acc..35f89143 100755 --- a/infra/CreateJupyterNotebookTutorial.py +++ b/infra/CreateJupyterNotebookTutorial.py @@ -244,7 +244,6 @@ def ConvertTutorialToJupyterNotebook(test_file_path, test_file, other_files, rev """ if revision: revision = ' at revision r' + str(revision) - nb = nbf.v4.new_notebook() nb['cells'] = [] @@ -307,7 +306,6 @@ def ParseOptions(): ## Some logging print ("Generating:" + out_file_name) - with open(out_file_name, 'w') as f: nbf.write(nb, f) diff --git a/infra/CreateMarkdownTutorial.py b/infra/CreateMarkdownTutorial.py index 085962a8..2565bb16 100755 --- a/infra/CreateMarkdownTutorial.py +++ b/infra/CreateMarkdownTutorial.py @@ -210,14 +210,27 @@ def ConvertTutorialToMarkdownText(test_file_path, test_file, other_files, revisi revision = ' at revision r' + str(revision) output = [] # Header - regex = re.compile(ur'(?!^)(?=[A-Z])', re.MULTILINE) + regex = re.compile(r'(?!^)(?=[A-Z])', re.MULTILINE) ugly_file_name = os.path.splitext(os.path.basename(test_file_path))[0] nice_file_name = re.sub(regex, " ", ugly_file_name) + + page_header = f""" +--- +title : "{nice_file_name}" +summary: "" +draft: false +images: [] +toc: true +layout: "single" +--- + +This tutorial is automatically generated from the file {test_file_path} {revision}. +Note that the code is given in full at the bottom of the page. + + +""" - output.append('---\nlayout: page-full-width \ntitle: ' + nice_file_name + '\n---\n') - output.append('This tutorial is automatically generated from the file ' + test_file_path + revision + '.\n') - output.append('[Go to the Jupyter Notebook version.]({{ site.baseurl}}/documentation/md_tutorials/'+ ugly_file_name + '_nb.html)\n') - output.append('Note that the code is given in full at the bottom of the page.\n\n\n') + output.append(page_header) # Convert each file in turn test_output, test_code = ConvertFileToMarkdownText(test_file, test_file_path) @@ -233,7 +246,7 @@ def ConvertTutorialToMarkdownText(test_file_path, test_file, other_files, revisi # Now output the C++ code for all files output.append('\n\n# Code \nThe full code is given below\n') AddCodeOutput(os.path.basename(test_file_path), test_code, output) - for filename, code in other_code.iteritems(): + for filename, code in other_code.items(): AddCodeOutput(filename, code, output) return ''.join(output) diff --git a/infra/GenerateWikiPages.py b/infra/GenerateWikiPages.py index 3c3086b4..10245fe9 100755 --- a/infra/GenerateWikiPages.py +++ b/infra/GenerateWikiPages.py @@ -44,34 +44,39 @@ import subprocess if __name__ == '__main__': + output_format = "" + + if len(sys.argv) > 1: + output_format = sys.argv[1] + + if output_format not in ["markdown", "jupyter"]: + output_format = "markdown" # Find all the tutorial files. tutorial_files = [] - for root, dirs, files in os.walk('test'): + for root, dirs, files in os.walk('../test'): for file in files: if fnmatch.fnmatch(file, 'Test*LiteratePaper*') or fnmatch.fnmatch(file, 'Test*Tutorial*'): if not fnmatch.fnmatch(file, '*.pyc'): tutorial_files.append([root, file]) - - output_format = "jupyter" if output_format == "markdown": # Generate the markdown for each for eachFile in tutorial_files: - outfile = " doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".md" + outfile = "../doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".md" inputfile = eachFile[0] + "/" + eachFile[1] - launch_string = "infra/CreateMarkdownTutorial.py " + inputfile + outfile + launch_string = f"../infra/CreateMarkdownTutorial.py {inputfile} {outfile}" os.system(launch_string) elif output_format == "jupyter": # Generate the jupyter notebooks for each for eachFile in tutorial_files: - outfile = " doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".ipynb" + outfile = "../doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".ipynb" inputfile = eachFile[0] + "/" + eachFile[1] - launch_string = "infra/CreateJupyterNotebookTutorial.py " + inputfile + outfile + launch_string = f"../infra/CreateJupyterNotebookTutorial.py {inputfile} {outfile}" os.system(launch_string) - subprocess.call("jupyter nbconvert " + outfile, shell=True) + subprocess.call(f"jupyter nbconvert --to notebook {outfile}", shell=True) From faf71eb95bb8268b983e03b03be7219e043d5a27 Mon Sep 17 00:00:00 2001 From: Kwabena N Amponsah Date: Tue, 28 Nov 2023 03:22:25 +0000 Subject: [PATCH 2/3] Use argparse in tutorial generation --- doc/tutorials/TestCellSortingTutorial.ipynb | 56 +++--- .../TestCellSortingTutorial.nbconvert.ipynb | 56 +++--- ...shBasedCellSimulationsPythonTutorial.ipynb | 102 +++++------ ...lSimulationsPythonTutorial.nbconvert.ipynb | 102 +++++------ ...deBasedCellSimulationsPythonTutorial.ipynb | 140 +++++++-------- ...lSimulationsPythonTutorial.nbconvert.ipynb | 140 +++++++-------- ...tsBasedCellSimulationsPythonTutorial.ipynb | 164 +++++++++--------- ...lSimulationsPythonTutorial.nbconvert.ipynb | 164 +++++++++--------- doc/tutorials/TestScratchAssayTutorial.ipynb | 56 +++--- .../TestScratchAssayTutorial.nbconvert.ipynb | 56 +++--- doc/tutorials/TestSpheroidTutorial.ipynb | 70 ++++---- .../TestSpheroidTutorial.nbconvert.ipynb | 70 ++++---- doc/tutorials/TestTensileTestTutorial.ipynb | 52 +++--- .../TestTensileTestTutorial.nbconvert.ipynb | 52 +++--- ...exBasedCellSimulationsPythonTutorial.ipynb | 104 +++++------ ...lSimulationsPythonTutorial.nbconvert.ipynb | 104 +++++------ infra/GenerateWikiPages.py | 61 ++++--- 17 files changed, 781 insertions(+), 768 deletions(-) diff --git a/doc/tutorials/TestCellSortingTutorial.ipynb b/doc/tutorials/TestCellSortingTutorial.ipynb index 5e83ab81..3b7c75e7 100644 --- a/doc/tutorials/TestCellSortingTutorial.ipynb +++ b/doc/tutorials/TestCellSortingTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "5e20c6f8", + "id": "296c5d00", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestCellSortingTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bbb0d35b", + "id": "85518493", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "f35ee21c", + "id": "425c7509", "metadata": {}, "source": [ "\n", @@ -41,7 +41,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e799e1ff", + "id": "ad3b4b3d", "metadata": {}, "outputs": [], "source": [ @@ -56,7 +56,7 @@ }, { "cell_type": "markdown", - "id": "fc92979c", + "id": "0859ed0f", "metadata": {}, "source": [ "## Test 1 - Cell sorting\n", @@ -68,7 +68,7 @@ { "cell_type": "code", "execution_count": null, - "id": "74ed5bea", + "id": "914c5dbe", "metadata": {}, "outputs": [], "source": [ @@ -78,7 +78,7 @@ }, { "cell_type": "markdown", - "id": "cc82f214", + "id": "6b89b200", "metadata": {}, "source": [ "First, we generate a `Potts` mesh. To create a `PottsMesh`, we can use the `PottsMeshGenerator`.\n", @@ -90,7 +90,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4f11a779", + "id": "53498c64", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "1d268b5f", + "id": "55826799", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we the `CellsGenerator` helper class,\n", @@ -111,7 +111,7 @@ { "cell_type": "code", "execution_count": null, - "id": "44155fe5", + "id": "83100d25", "metadata": {}, "outputs": [], "source": [ @@ -122,7 +122,7 @@ }, { "cell_type": "markdown", - "id": "f9af144b", + "id": "ab73135c", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -132,7 +132,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5c623dbf", + "id": "4c965778", "metadata": {}, "outputs": [], "source": [ @@ -144,7 +144,7 @@ }, { "cell_type": "markdown", - "id": "55e259f6", + "id": "63891d61", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -154,7 +154,7 @@ { "cell_type": "code", "execution_count": null, - "id": "99595a86", + "id": "56507a69", "metadata": {}, "outputs": [], "source": [ @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "c1e1d793", + "id": "84a90a0d", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -173,7 +173,7 @@ { "cell_type": "code", "execution_count": null, - "id": "02402f5d", + "id": "46963d23", "metadata": {}, "outputs": [], "source": [ @@ -182,7 +182,7 @@ }, { "cell_type": "markdown", - "id": "13d55a5d", + "id": "6571a038", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a VtkScene so that we can\n", @@ -193,7 +193,7 @@ { "cell_type": "code", "execution_count": null, - "id": "74aac9f9", + "id": "13078a02", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "ed38349c", + "id": "73bf51b5", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -216,7 +216,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0860691b", + "id": "4c4b7723", "metadata": {}, "outputs": [], "source": [ @@ -228,7 +228,7 @@ }, { "cell_type": "markdown", - "id": "469b27f0", + "id": "9a2f7393", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "add6d2da", + "id": "4e6905d0", "metadata": {}, "outputs": [], "source": [ @@ -253,7 +253,7 @@ }, { "cell_type": "markdown", - "id": "a77c25d6", + "id": "ce8333cb", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -263,7 +263,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1b4f58bf", + "id": "85b15aac", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "7623f5fa", + "id": "0c443ccd", "metadata": {}, "source": [ "Set up plotting\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "633de4b6", + "id": "0ccc598e", "metadata": {}, "outputs": [], "source": [ @@ -300,7 +300,7 @@ }, { "cell_type": "markdown", - "id": "e3f26e6c", + "id": "ac2f8034", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -310,7 +310,7 @@ { "cell_type": "code", "execution_count": null, - "id": "431f0fcb", + "id": "aad50aa1", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb b/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb index 5e83ab81..3b7c75e7 100644 --- a/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestCellSortingTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "5e20c6f8", + "id": "296c5d00", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestCellSortingTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bbb0d35b", + "id": "85518493", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "f35ee21c", + "id": "425c7509", "metadata": {}, "source": [ "\n", @@ -41,7 +41,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e799e1ff", + "id": "ad3b4b3d", "metadata": {}, "outputs": [], "source": [ @@ -56,7 +56,7 @@ }, { "cell_type": "markdown", - "id": "fc92979c", + "id": "0859ed0f", "metadata": {}, "source": [ "## Test 1 - Cell sorting\n", @@ -68,7 +68,7 @@ { "cell_type": "code", "execution_count": null, - "id": "74ed5bea", + "id": "914c5dbe", "metadata": {}, "outputs": [], "source": [ @@ -78,7 +78,7 @@ }, { "cell_type": "markdown", - "id": "cc82f214", + "id": "6b89b200", "metadata": {}, "source": [ "First, we generate a `Potts` mesh. To create a `PottsMesh`, we can use the `PottsMeshGenerator`.\n", @@ -90,7 +90,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4f11a779", + "id": "53498c64", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "1d268b5f", + "id": "55826799", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we the `CellsGenerator` helper class,\n", @@ -111,7 +111,7 @@ { "cell_type": "code", "execution_count": null, - "id": "44155fe5", + "id": "83100d25", "metadata": {}, "outputs": [], "source": [ @@ -122,7 +122,7 @@ }, { "cell_type": "markdown", - "id": "f9af144b", + "id": "ab73135c", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -132,7 +132,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5c623dbf", + "id": "4c965778", "metadata": {}, "outputs": [], "source": [ @@ -144,7 +144,7 @@ }, { "cell_type": "markdown", - "id": "55e259f6", + "id": "63891d61", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -154,7 +154,7 @@ { "cell_type": "code", "execution_count": null, - "id": "99595a86", + "id": "56507a69", "metadata": {}, "outputs": [], "source": [ @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "c1e1d793", + "id": "84a90a0d", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -173,7 +173,7 @@ { "cell_type": "code", "execution_count": null, - "id": "02402f5d", + "id": "46963d23", "metadata": {}, "outputs": [], "source": [ @@ -182,7 +182,7 @@ }, { "cell_type": "markdown", - "id": "13d55a5d", + "id": "6571a038", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a VtkScene so that we can\n", @@ -193,7 +193,7 @@ { "cell_type": "code", "execution_count": null, - "id": "74aac9f9", + "id": "13078a02", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "ed38349c", + "id": "73bf51b5", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -216,7 +216,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0860691b", + "id": "4c4b7723", "metadata": {}, "outputs": [], "source": [ @@ -228,7 +228,7 @@ }, { "cell_type": "markdown", - "id": "469b27f0", + "id": "9a2f7393", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "add6d2da", + "id": "4e6905d0", "metadata": {}, "outputs": [], "source": [ @@ -253,7 +253,7 @@ }, { "cell_type": "markdown", - "id": "a77c25d6", + "id": "ce8333cb", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -263,7 +263,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1b4f58bf", + "id": "85b15aac", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "7623f5fa", + "id": "0c443ccd", "metadata": {}, "source": [ "Set up plotting\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "633de4b6", + "id": "0ccc598e", "metadata": {}, "outputs": [], "source": [ @@ -300,7 +300,7 @@ }, { "cell_type": "markdown", - "id": "e3f26e6c", + "id": "ac2f8034", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -310,7 +310,7 @@ { "cell_type": "code", "execution_count": null, - "id": "431f0fcb", + "id": "aad50aa1", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb index acd897ca..6d825047 100644 --- a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "6cf38449", + "id": "91bf95f6", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "78a54faf", + "id": "4b6811ea", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "0fdfa329", + "id": "218fbe30", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ff1ee8e0", + "id": "d8cc5664", "metadata": {}, "outputs": [], "source": [ @@ -54,7 +54,7 @@ }, { "cell_type": "markdown", - "id": "c2491c88", + "id": "1559ec87", "metadata": {}, "source": [ "## Test 1 - a basic mesh-based simulation\n", @@ -66,7 +66,7 @@ { "cell_type": "code", "execution_count": null, - "id": "210ebf6d", + "id": "73fea897", "metadata": {}, "outputs": [], "source": [ @@ -76,7 +76,7 @@ }, { "cell_type": "markdown", - "id": "3f4f3522", + "id": "542e3991", "metadata": {}, "source": [ "Next, we generate a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator`.\n", @@ -88,7 +88,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5ab92270", + "id": "3c6457ec", "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "markdown", - "id": "cbeca5d9", + "id": "b320437c", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class,\n", @@ -115,7 +115,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5b8c2617", + "id": "63821a1e", "metadata": {}, "outputs": [], "source": [ @@ -127,7 +127,7 @@ }, { "cell_type": "markdown", - "id": "8a1dcbc0", + "id": "da78910f", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -139,7 +139,7 @@ { "cell_type": "code", "execution_count": null, - "id": "620e351c", + "id": "7d4eae36", "metadata": {}, "outputs": [], "source": [ @@ -149,7 +149,7 @@ }, { "cell_type": "markdown", - "id": "147c533d", + "id": "0d4578de", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly\n", @@ -160,7 +160,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8589369f", + "id": "2eff0fa5", "metadata": {}, "outputs": [], "source": [ @@ -169,7 +169,7 @@ }, { "cell_type": "markdown", - "id": "3a4dcab5", + "id": "94e159f7", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -179,7 +179,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0f77f6b", + "id": "f9b1c415", "metadata": {}, "outputs": [], "source": [ @@ -191,7 +191,7 @@ }, { "cell_type": "markdown", - "id": "b276615a", + "id": "a36000b5", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -201,7 +201,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bc525e8b", + "id": "3977141e", "metadata": {}, "outputs": [], "source": [ @@ -212,7 +212,7 @@ }, { "cell_type": "markdown", - "id": "946a0a4c", + "id": "4611308a", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step. In this case we can use the following method,\n", @@ -224,7 +224,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ef73deac", + "id": "bb5d898b", "metadata": {}, "outputs": [], "source": [ @@ -233,7 +233,7 @@ }, { "cell_type": "markdown", - "id": "2dac6feb", + "id": "c0d461f0", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the centres of each cell in a cell population.\n", @@ -246,7 +246,7 @@ { "cell_type": "code", "execution_count": null, - "id": "931523c7", + "id": "173e1110", "metadata": {}, "outputs": [], "source": [ @@ -256,7 +256,7 @@ }, { "cell_type": "markdown", - "id": "11448f81", + "id": "e6fcc6b2", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -266,7 +266,7 @@ { "cell_type": "code", "execution_count": null, - "id": "affdc54e", + "id": "5fe3edbf", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "560a1728", + "id": "179569e3", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95fa8575", + "id": "b42dcacc", "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "markdown", - "id": "255d0f3b", + "id": "78155c5d", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", @@ -315,7 +315,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9686d4c8", + "id": "1fd245e8", "metadata": {}, "outputs": [], "source": [ @@ -325,7 +325,7 @@ }, { "cell_type": "markdown", - "id": "f7426d6e", + "id": "95e70d26", "metadata": {}, "source": [ "We start by generating a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator` as before.\n", @@ -337,7 +337,7 @@ { "cell_type": "code", "execution_count": null, - "id": "88275ef3", + "id": "68560f1c", "metadata": {}, "outputs": [], "source": [ @@ -348,7 +348,7 @@ }, { "cell_type": "markdown", - "id": "1a9c80ca", + "id": "2d761a92", "metadata": {}, "source": [ "We only want to create cells to attach to real nodes, so we use the method `GetCellLocationIndices` to get the\n", @@ -359,7 +359,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e6493fe9", + "id": "120e5f8e", "metadata": {}, "outputs": [], "source": [ @@ -368,7 +368,7 @@ }, { "cell_type": "markdown", - "id": "d1e1597a", + "id": "d249e8fa", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class again.\n", @@ -380,7 +380,7 @@ { "cell_type": "code", "execution_count": null, - "id": "20888bc0", + "id": "10d6eb30", "metadata": {}, "outputs": [], "source": [ @@ -392,7 +392,7 @@ }, { "cell_type": "markdown", - "id": "2607ea2f", + "id": "2b2a347f", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -406,7 +406,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1937cc88", + "id": "97d7464b", "metadata": {}, "outputs": [], "source": [ @@ -417,7 +417,7 @@ }, { "cell_type": "markdown", - "id": "869b73d9", + "id": "a8d3d3ec", "metadata": {}, "source": [ "Again Paraview output is explicitly requested.\n", @@ -427,7 +427,7 @@ { "cell_type": "code", "execution_count": null, - "id": "06c453ce", + "id": "bb36fcce", "metadata": {}, "outputs": [], "source": [ @@ -436,7 +436,7 @@ }, { "cell_type": "markdown", - "id": "2a788286", + "id": "61e6cf6f", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -446,7 +446,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6575394a", + "id": "a69f8753", "metadata": {}, "outputs": [], "source": [ @@ -458,7 +458,7 @@ }, { "cell_type": "markdown", - "id": "487429d4", + "id": "f81867de", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time.\n", @@ -468,7 +468,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e95fa6e", + "id": "5a980c00", "metadata": {}, "outputs": [], "source": [ @@ -480,7 +480,7 @@ }, { "cell_type": "markdown", - "id": "03d7f873", + "id": "6fc2d3b8", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -490,7 +490,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e791fda8", + "id": "8e9a3827", "metadata": {}, "outputs": [], "source": [ @@ -502,7 +502,7 @@ }, { "cell_type": "markdown", - "id": "311f5e5f", + "id": "555e3e43", "metadata": {}, "source": [ "Again we create a force law, and pass it to the `OffLatticeSimulation`.\n", @@ -513,7 +513,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2b71eeed", + "id": "0422077e", "metadata": {}, "outputs": [], "source": [ @@ -523,7 +523,7 @@ }, { "cell_type": "markdown", - "id": "bb87dfbe", + "id": "4f463244", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -533,7 +533,7 @@ { "cell_type": "code", "execution_count": null, - "id": "492e478b", + "id": "3b41d339", "metadata": {}, "outputs": [], "source": [ @@ -543,7 +543,7 @@ }, { "cell_type": "markdown", - "id": "1ff18229", + "id": "5634e56f", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -554,7 +554,7 @@ { "cell_type": "code", "execution_count": null, - "id": "78eeef35", + "id": "11da50ec", "metadata": {}, "outputs": [], "source": [ @@ -564,7 +564,7 @@ }, { "cell_type": "markdown", - "id": "2f61c37c", + "id": "7cfc1fac", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", diff --git a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb index acd897ca..6d825047 100644 --- a/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestMeshBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "6cf38449", + "id": "91bf95f6", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestMeshBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "78a54faf", + "id": "4b6811ea", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "0fdfa329", + "id": "218fbe30", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ff1ee8e0", + "id": "d8cc5664", "metadata": {}, "outputs": [], "source": [ @@ -54,7 +54,7 @@ }, { "cell_type": "markdown", - "id": "c2491c88", + "id": "1559ec87", "metadata": {}, "source": [ "## Test 1 - a basic mesh-based simulation\n", @@ -66,7 +66,7 @@ { "cell_type": "code", "execution_count": null, - "id": "210ebf6d", + "id": "73fea897", "metadata": {}, "outputs": [], "source": [ @@ -76,7 +76,7 @@ }, { "cell_type": "markdown", - "id": "3f4f3522", + "id": "542e3991", "metadata": {}, "source": [ "Next, we generate a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator`.\n", @@ -88,7 +88,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5ab92270", + "id": "3c6457ec", "metadata": {}, "outputs": [], "source": [ @@ -99,7 +99,7 @@ }, { "cell_type": "markdown", - "id": "cbeca5d9", + "id": "b320437c", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class,\n", @@ -115,7 +115,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5b8c2617", + "id": "63821a1e", "metadata": {}, "outputs": [], "source": [ @@ -127,7 +127,7 @@ }, { "cell_type": "markdown", - "id": "8a1dcbc0", + "id": "da78910f", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -139,7 +139,7 @@ { "cell_type": "code", "execution_count": null, - "id": "620e351c", + "id": "7d4eae36", "metadata": {}, "outputs": [], "source": [ @@ -149,7 +149,7 @@ }, { "cell_type": "markdown", - "id": "147c533d", + "id": "0d4578de", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly\n", @@ -160,7 +160,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8589369f", + "id": "2eff0fa5", "metadata": {}, "outputs": [], "source": [ @@ -169,7 +169,7 @@ }, { "cell_type": "markdown", - "id": "3a4dcab5", + "id": "94e159f7", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -179,7 +179,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0f77f6b", + "id": "f9b1c415", "metadata": {}, "outputs": [], "source": [ @@ -191,7 +191,7 @@ }, { "cell_type": "markdown", - "id": "b276615a", + "id": "a36000b5", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -201,7 +201,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bc525e8b", + "id": "3977141e", "metadata": {}, "outputs": [], "source": [ @@ -212,7 +212,7 @@ }, { "cell_type": "markdown", - "id": "946a0a4c", + "id": "4611308a", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step. In this case we can use the following method,\n", @@ -224,7 +224,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ef73deac", + "id": "bb5d898b", "metadata": {}, "outputs": [], "source": [ @@ -233,7 +233,7 @@ }, { "cell_type": "markdown", - "id": "2dac6feb", + "id": "c0d461f0", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the centres of each cell in a cell population.\n", @@ -246,7 +246,7 @@ { "cell_type": "code", "execution_count": null, - "id": "931523c7", + "id": "173e1110", "metadata": {}, "outputs": [], "source": [ @@ -256,7 +256,7 @@ }, { "cell_type": "markdown", - "id": "11448f81", + "id": "e6fcc6b2", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -266,7 +266,7 @@ { "cell_type": "code", "execution_count": null, - "id": "affdc54e", + "id": "5fe3edbf", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "560a1728", + "id": "179569e3", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95fa8575", + "id": "b42dcacc", "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "markdown", - "id": "255d0f3b", + "id": "78155c5d", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", @@ -315,7 +315,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9686d4c8", + "id": "1fd245e8", "metadata": {}, "outputs": [], "source": [ @@ -325,7 +325,7 @@ }, { "cell_type": "markdown", - "id": "f7426d6e", + "id": "95e70d26", "metadata": {}, "source": [ "We start by generating a mutable mesh. To create a `MutableMesh`, we can use the `HoneycombMeshGenerator` as before.\n", @@ -337,7 +337,7 @@ { "cell_type": "code", "execution_count": null, - "id": "88275ef3", + "id": "68560f1c", "metadata": {}, "outputs": [], "source": [ @@ -348,7 +348,7 @@ }, { "cell_type": "markdown", - "id": "1a9c80ca", + "id": "2d761a92", "metadata": {}, "source": [ "We only want to create cells to attach to real nodes, so we use the method `GetCellLocationIndices` to get the\n", @@ -359,7 +359,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e6493fe9", + "id": "120e5f8e", "metadata": {}, "outputs": [], "source": [ @@ -368,7 +368,7 @@ }, { "cell_type": "markdown", - "id": "d1e1597a", + "id": "d249e8fa", "metadata": {}, "source": [ "Having created a mesh, we now create some cells. To do this, we use the `CellsGenerator` helper class again.\n", @@ -380,7 +380,7 @@ { "cell_type": "code", "execution_count": null, - "id": "20888bc0", + "id": "10d6eb30", "metadata": {}, "outputs": [], "source": [ @@ -392,7 +392,7 @@ }, { "cell_type": "markdown", - "id": "2607ea2f", + "id": "2b2a347f", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -406,7 +406,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1937cc88", + "id": "97d7464b", "metadata": {}, "outputs": [], "source": [ @@ -417,7 +417,7 @@ }, { "cell_type": "markdown", - "id": "869b73d9", + "id": "a8d3d3ec", "metadata": {}, "source": [ "Again Paraview output is explicitly requested.\n", @@ -427,7 +427,7 @@ { "cell_type": "code", "execution_count": null, - "id": "06c453ce", + "id": "bb36fcce", "metadata": {}, "outputs": [], "source": [ @@ -436,7 +436,7 @@ }, { "cell_type": "markdown", - "id": "2a788286", + "id": "61e6cf6f", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -446,7 +446,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6575394a", + "id": "a69f8753", "metadata": {}, "outputs": [], "source": [ @@ -458,7 +458,7 @@ }, { "cell_type": "markdown", - "id": "487429d4", + "id": "f81867de", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time.\n", @@ -468,7 +468,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e95fa6e", + "id": "5a980c00", "metadata": {}, "outputs": [], "source": [ @@ -480,7 +480,7 @@ }, { "cell_type": "markdown", - "id": "03d7f873", + "id": "6fc2d3b8", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -490,7 +490,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e791fda8", + "id": "8e9a3827", "metadata": {}, "outputs": [], "source": [ @@ -502,7 +502,7 @@ }, { "cell_type": "markdown", - "id": "311f5e5f", + "id": "555e3e43", "metadata": {}, "source": [ "Again we create a force law, and pass it to the `OffLatticeSimulation`.\n", @@ -513,7 +513,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2b71eeed", + "id": "0422077e", "metadata": {}, "outputs": [], "source": [ @@ -523,7 +523,7 @@ }, { "cell_type": "markdown", - "id": "bb87dfbe", + "id": "4f463244", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -533,7 +533,7 @@ { "cell_type": "code", "execution_count": null, - "id": "492e478b", + "id": "3b41d339", "metadata": {}, "outputs": [], "source": [ @@ -543,7 +543,7 @@ }, { "cell_type": "markdown", - "id": "1ff18229", + "id": "5634e56f", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -554,7 +554,7 @@ { "cell_type": "code", "execution_count": null, - "id": "78eeef35", + "id": "11da50ec", "metadata": {}, "outputs": [], "source": [ @@ -564,7 +564,7 @@ }, { "cell_type": "markdown", - "id": "2f61c37c", + "id": "7cfc1fac", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", diff --git a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb index 0253e618..9e52ec88 100644 --- a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "c1be3946", + "id": "77e70b3c", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "dcd83472", + "id": "52d0e910", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "f4d7e6dd", + "id": "57ab20c9", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8d34a397", + "id": "fda73917", "metadata": {}, "outputs": [], "source": [ @@ -53,7 +53,7 @@ }, { "cell_type": "markdown", - "id": "37286ec9", + "id": "92769e61", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -65,7 +65,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b7077ffc", + "id": "cb9550e8", "metadata": {}, "outputs": [], "source": [ @@ -75,7 +75,7 @@ }, { "cell_type": "markdown", - "id": "c3cfec3f", + "id": "35285203", "metadata": {}, "source": [ "The first thing we do is generate a nodes only mesh. To do this we first create a `MutableMesh` to use as a generating mesh.\n", @@ -87,7 +87,7 @@ { "cell_type": "code", "execution_count": null, - "id": "85578e5e", + "id": "e51780bb", "metadata": {}, "outputs": [], "source": [ @@ -98,7 +98,7 @@ }, { "cell_type": "markdown", - "id": "99336452", + "id": "24f331ad", "metadata": {}, "source": [ "Once we have a MutableMesh we can generate a NodesOnlyMesh from it using the following commands.\n", @@ -109,7 +109,7 @@ { "cell_type": "code", "execution_count": null, - "id": "31fa8c51", + "id": "d7038391", "metadata": {}, "outputs": [], "source": [ @@ -118,7 +118,7 @@ }, { "cell_type": "markdown", - "id": "3d20db6a", + "id": "8119355c", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in `ConstructNodesWithoutMesh`),\n", @@ -129,7 +129,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5ae2bd30", + "id": "917cb122", "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "markdown", - "id": "5efc27fe", + "id": "e796f6e5", "metadata": {}, "source": [ "Having created a mesh, we now create a (wrapped) vector of CellPtrs. To do this, we use the `CellsGenerator` helper class,\n", @@ -152,7 +152,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e2ecc8c4", + "id": "808fbbbd", "metadata": {}, "outputs": [], "source": [ @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "3b05d4ca", + "id": "3168b24b", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -175,7 +175,7 @@ { "cell_type": "code", "execution_count": null, - "id": "43e339e8", + "id": "7b4ed9b9", "metadata": {}, "outputs": [], "source": [ @@ -184,7 +184,7 @@ }, { "cell_type": "markdown", - "id": "614090ff", + "id": "02d07e5c", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -194,7 +194,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d441f8b7", + "id": "4bd3cab0", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "2f461c92", + "id": "9f9973a6", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -216,7 +216,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e257f3f", + "id": "3179c673", "metadata": {}, "outputs": [], "source": [ @@ -228,7 +228,7 @@ }, { "cell_type": "markdown", - "id": "858b1279", + "id": "5580aefb", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -238,7 +238,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8b6a8e65", + "id": "585ce23f", "metadata": {}, "outputs": [], "source": [ @@ -248,7 +248,7 @@ }, { "cell_type": "markdown", - "id": "1b3cde60", + "id": "72d98417", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -258,7 +258,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4370d079", + "id": "383346b9", "metadata": {}, "outputs": [], "source": [ @@ -270,7 +270,7 @@ }, { "cell_type": "markdown", - "id": "9cb5a9fd", + "id": "af92ab8b", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -280,7 +280,7 @@ { "cell_type": "code", "execution_count": null, - "id": "24b5bfa0", + "id": "53da8e15", "metadata": {}, "outputs": [], "source": [ @@ -291,7 +291,7 @@ }, { "cell_type": "markdown", - "id": "98637fcb", + "id": "9f0185e0", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -302,7 +302,7 @@ { "cell_type": "code", "execution_count": null, - "id": "095ce225", + "id": "e88ccc10", "metadata": {}, "outputs": [], "source": [ @@ -312,7 +312,7 @@ }, { "cell_type": "markdown", - "id": "2597efaf", + "id": "8a2b6027", "metadata": {}, "source": [ "## Test 2 - a basic node-based simulation in 3D\n", @@ -324,7 +324,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4f8f6402", + "id": "9f9ea318", "metadata": {}, "outputs": [], "source": [ @@ -334,7 +334,7 @@ }, { "cell_type": "markdown", - "id": "ec16c4f5", + "id": "731b0057", "metadata": {}, "source": [ "First, we generate a nodes only mesh. This time we specify the nodes manually by first creating a vector of nodes\n", @@ -344,7 +344,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3662e0e2", + "id": "9451df74", "metadata": {}, "outputs": [], "source": [ @@ -358,7 +358,7 @@ }, { "cell_type": "markdown", - "id": "7ef828a0", + "id": "601163f3", "metadata": {}, "source": [ "Finally a NodesOnlyMesh is created and the vector of nodes is passed to the ConstructNodesWithoutMesh method.\n", @@ -368,7 +368,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9029d2d0", + "id": "6a15344d", "metadata": {}, "outputs": [], "source": [ @@ -377,7 +377,7 @@ }, { "cell_type": "markdown", - "id": "e95300f5", + "id": "ec9d87c4", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -388,7 +388,7 @@ { "cell_type": "code", "execution_count": null, - "id": "61f4f064", + "id": "be7b899a", "metadata": {}, "outputs": [], "source": [ @@ -397,7 +397,7 @@ }, { "cell_type": "markdown", - "id": "7cbd6d28", + "id": "14129c6d", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs.\n", @@ -408,7 +408,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e94362a4", + "id": "a19b015a", "metadata": {}, "outputs": [], "source": [ @@ -419,7 +419,7 @@ }, { "cell_type": "markdown", - "id": "b4b198bd", + "id": "73409bc2", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -431,7 +431,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3cad7ba8", + "id": "37876a5f", "metadata": {}, "outputs": [], "source": [ @@ -440,7 +440,7 @@ }, { "cell_type": "markdown", - "id": "fd9c6232", + "id": "21c26dc2", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -450,7 +450,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8ef252ff", + "id": "5a273b33", "metadata": {}, "outputs": [], "source": [ @@ -461,7 +461,7 @@ }, { "cell_type": "markdown", - "id": "376f3387", + "id": "4afd1a22", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -471,7 +471,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0546c735", + "id": "e87be123", "metadata": {}, "outputs": [], "source": [ @@ -483,7 +483,7 @@ }, { "cell_type": "markdown", - "id": "edb6a531", + "id": "3e9aa750", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -493,7 +493,7 @@ { "cell_type": "code", "execution_count": null, - "id": "04b02d89", + "id": "76b09516", "metadata": {}, "outputs": [], "source": [ @@ -503,7 +503,7 @@ }, { "cell_type": "markdown", - "id": "a183d74c", + "id": "b275a15c", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -513,7 +513,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e532a662", + "id": "3143d3b0", "metadata": {}, "outputs": [], "source": [ @@ -525,7 +525,7 @@ }, { "cell_type": "markdown", - "id": "b1a59ff5", + "id": "b68d807a", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -535,7 +535,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5b1aa5d2", + "id": "9d869949", "metadata": {}, "outputs": [], "source": [ @@ -546,7 +546,7 @@ }, { "cell_type": "markdown", - "id": "1db1e70a", + "id": "a6e8e951", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -557,7 +557,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cbcccf30", + "id": "1fa74bdb", "metadata": {}, "outputs": [], "source": [ @@ -567,7 +567,7 @@ }, { "cell_type": "markdown", - "id": "8b718848", + "id": "8e043c5d", "metadata": {}, "source": [ "## Test 3 - a node-based simulation on a restricted geometry\n", @@ -579,7 +579,7 @@ { "cell_type": "code", "execution_count": null, - "id": "107c3c95", + "id": "50ceb577", "metadata": {}, "outputs": [], "source": [ @@ -589,7 +589,7 @@ }, { "cell_type": "markdown", - "id": "36e7797a", + "id": "17029d10", "metadata": {}, "source": [ "In the third test we run a node-based simulation restricted to the surface of a sphere.\n", @@ -599,7 +599,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4432292d", + "id": "76793e02", "metadata": {}, "outputs": [], "source": [ @@ -614,7 +614,7 @@ }, { "cell_type": "markdown", - "id": "56119cfe", + "id": "5393d13d", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -625,7 +625,7 @@ { "cell_type": "code", "execution_count": null, - "id": "10c19934", + "id": "05cc0ffe", "metadata": {}, "outputs": [], "source": [ @@ -638,7 +638,7 @@ }, { "cell_type": "markdown", - "id": "e4330483", + "id": "9dd8d022", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -648,7 +648,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11237f3b", + "id": "37e6c49c", "metadata": {}, "outputs": [], "source": [ @@ -663,7 +663,7 @@ }, { "cell_type": "markdown", - "id": "f69e6f1e", + "id": "f7f34f19", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -673,7 +673,7 @@ { "cell_type": "code", "execution_count": null, - "id": "44951122", + "id": "83933153", "metadata": {}, "outputs": [], "source": [ @@ -683,7 +683,7 @@ }, { "cell_type": "markdown", - "id": "75ca15e7", + "id": "570d8800", "metadata": {}, "source": [ "This time we create a CellPopulationBoundaryCondition and pass this to the OffLatticeSimulation.\n", @@ -698,7 +698,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7d11a078", + "id": "c13b64c5", "metadata": {}, "outputs": [], "source": [ @@ -711,7 +711,7 @@ }, { "cell_type": "markdown", - "id": "f87548ae", + "id": "bdf1db06", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -721,7 +721,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1cdf1e8d", + "id": "5ed9087d", "metadata": {}, "outputs": [], "source": [ @@ -732,7 +732,7 @@ }, { "cell_type": "markdown", - "id": "3df3c0f2", + "id": "3787ebeb", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -742,7 +742,7 @@ { "cell_type": "code", "execution_count": null, - "id": "00c65de2", + "id": "40df3af8", "metadata": {}, "outputs": [], "source": [ @@ -753,7 +753,7 @@ }, { "cell_type": "markdown", - "id": "49b04bcc", + "id": "8fda7129", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -764,7 +764,7 @@ { "cell_type": "code", "execution_count": null, - "id": "49ae6fc6", + "id": "7627d6d3", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb index 0253e618..9e52ec88 100644 --- a/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestNodeBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "c1be3946", + "id": "77e70b3c", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestNodeBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "dcd83472", + "id": "52d0e910", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "f4d7e6dd", + "id": "57ab20c9", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8d34a397", + "id": "fda73917", "metadata": {}, "outputs": [], "source": [ @@ -53,7 +53,7 @@ }, { "cell_type": "markdown", - "id": "37286ec9", + "id": "92769e61", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -65,7 +65,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b7077ffc", + "id": "cb9550e8", "metadata": {}, "outputs": [], "source": [ @@ -75,7 +75,7 @@ }, { "cell_type": "markdown", - "id": "c3cfec3f", + "id": "35285203", "metadata": {}, "source": [ "The first thing we do is generate a nodes only mesh. To do this we first create a `MutableMesh` to use as a generating mesh.\n", @@ -87,7 +87,7 @@ { "cell_type": "code", "execution_count": null, - "id": "85578e5e", + "id": "e51780bb", "metadata": {}, "outputs": [], "source": [ @@ -98,7 +98,7 @@ }, { "cell_type": "markdown", - "id": "99336452", + "id": "24f331ad", "metadata": {}, "source": [ "Once we have a MutableMesh we can generate a NodesOnlyMesh from it using the following commands.\n", @@ -109,7 +109,7 @@ { "cell_type": "code", "execution_count": null, - "id": "31fa8c51", + "id": "d7038391", "metadata": {}, "outputs": [], "source": [ @@ -118,7 +118,7 @@ }, { "cell_type": "markdown", - "id": "3d20db6a", + "id": "8119355c", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in `ConstructNodesWithoutMesh`),\n", @@ -129,7 +129,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5ae2bd30", + "id": "917cb122", "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "markdown", - "id": "5efc27fe", + "id": "e796f6e5", "metadata": {}, "source": [ "Having created a mesh, we now create a (wrapped) vector of CellPtrs. To do this, we use the `CellsGenerator` helper class,\n", @@ -152,7 +152,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e2ecc8c4", + "id": "808fbbbd", "metadata": {}, "outputs": [], "source": [ @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "3b05d4ca", + "id": "3168b24b", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -175,7 +175,7 @@ { "cell_type": "code", "execution_count": null, - "id": "43e339e8", + "id": "7b4ed9b9", "metadata": {}, "outputs": [], "source": [ @@ -184,7 +184,7 @@ }, { "cell_type": "markdown", - "id": "614090ff", + "id": "02d07e5c", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -194,7 +194,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d441f8b7", + "id": "4bd3cab0", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "2f461c92", + "id": "9f9973a6", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -216,7 +216,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e257f3f", + "id": "3179c673", "metadata": {}, "outputs": [], "source": [ @@ -228,7 +228,7 @@ }, { "cell_type": "markdown", - "id": "858b1279", + "id": "5580aefb", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -238,7 +238,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8b6a8e65", + "id": "585ce23f", "metadata": {}, "outputs": [], "source": [ @@ -248,7 +248,7 @@ }, { "cell_type": "markdown", - "id": "1b3cde60", + "id": "72d98417", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -258,7 +258,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4370d079", + "id": "383346b9", "metadata": {}, "outputs": [], "source": [ @@ -270,7 +270,7 @@ }, { "cell_type": "markdown", - "id": "9cb5a9fd", + "id": "af92ab8b", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -280,7 +280,7 @@ { "cell_type": "code", "execution_count": null, - "id": "24b5bfa0", + "id": "53da8e15", "metadata": {}, "outputs": [], "source": [ @@ -291,7 +291,7 @@ }, { "cell_type": "markdown", - "id": "98637fcb", + "id": "9f0185e0", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -302,7 +302,7 @@ { "cell_type": "code", "execution_count": null, - "id": "095ce225", + "id": "e88ccc10", "metadata": {}, "outputs": [], "source": [ @@ -312,7 +312,7 @@ }, { "cell_type": "markdown", - "id": "2597efaf", + "id": "8a2b6027", "metadata": {}, "source": [ "## Test 2 - a basic node-based simulation in 3D\n", @@ -324,7 +324,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4f8f6402", + "id": "9f9ea318", "metadata": {}, "outputs": [], "source": [ @@ -334,7 +334,7 @@ }, { "cell_type": "markdown", - "id": "ec16c4f5", + "id": "731b0057", "metadata": {}, "source": [ "First, we generate a nodes only mesh. This time we specify the nodes manually by first creating a vector of nodes\n", @@ -344,7 +344,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3662e0e2", + "id": "9451df74", "metadata": {}, "outputs": [], "source": [ @@ -358,7 +358,7 @@ }, { "cell_type": "markdown", - "id": "7ef828a0", + "id": "601163f3", "metadata": {}, "source": [ "Finally a NodesOnlyMesh is created and the vector of nodes is passed to the ConstructNodesWithoutMesh method.\n", @@ -368,7 +368,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9029d2d0", + "id": "6a15344d", "metadata": {}, "outputs": [], "source": [ @@ -377,7 +377,7 @@ }, { "cell_type": "markdown", - "id": "e95300f5", + "id": "ec9d87c4", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -388,7 +388,7 @@ { "cell_type": "code", "execution_count": null, - "id": "61f4f064", + "id": "be7b899a", "metadata": {}, "outputs": [], "source": [ @@ -397,7 +397,7 @@ }, { "cell_type": "markdown", - "id": "7cbd6d28", + "id": "14129c6d", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs.\n", @@ -408,7 +408,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e94362a4", + "id": "a19b015a", "metadata": {}, "outputs": [], "source": [ @@ -419,7 +419,7 @@ }, { "cell_type": "markdown", - "id": "b4b198bd", + "id": "73409bc2", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation`.\n", @@ -431,7 +431,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3cad7ba8", + "id": "37876a5f", "metadata": {}, "outputs": [], "source": [ @@ -440,7 +440,7 @@ }, { "cell_type": "markdown", - "id": "fd9c6232", + "id": "21c26dc2", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -450,7 +450,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8ef252ff", + "id": "5a273b33", "metadata": {}, "outputs": [], "source": [ @@ -461,7 +461,7 @@ }, { "cell_type": "markdown", - "id": "376f3387", + "id": "4afd1a22", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -471,7 +471,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0546c735", + "id": "e87be123", "metadata": {}, "outputs": [], "source": [ @@ -483,7 +483,7 @@ }, { "cell_type": "markdown", - "id": "edb6a531", + "id": "3e9aa750", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -493,7 +493,7 @@ { "cell_type": "code", "execution_count": null, - "id": "04b02d89", + "id": "76b09516", "metadata": {}, "outputs": [], "source": [ @@ -503,7 +503,7 @@ }, { "cell_type": "markdown", - "id": "a183d74c", + "id": "b275a15c", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -513,7 +513,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e532a662", + "id": "3143d3b0", "metadata": {}, "outputs": [], "source": [ @@ -525,7 +525,7 @@ }, { "cell_type": "markdown", - "id": "b1a59ff5", + "id": "b68d807a", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -535,7 +535,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5b1aa5d2", + "id": "9d869949", "metadata": {}, "outputs": [], "source": [ @@ -546,7 +546,7 @@ }, { "cell_type": "markdown", - "id": "1db1e70a", + "id": "a6e8e951", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -557,7 +557,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cbcccf30", + "id": "1fa74bdb", "metadata": {}, "outputs": [], "source": [ @@ -567,7 +567,7 @@ }, { "cell_type": "markdown", - "id": "8b718848", + "id": "8e043c5d", "metadata": {}, "source": [ "## Test 3 - a node-based simulation on a restricted geometry\n", @@ -579,7 +579,7 @@ { "cell_type": "code", "execution_count": null, - "id": "107c3c95", + "id": "50ceb577", "metadata": {}, "outputs": [], "source": [ @@ -589,7 +589,7 @@ }, { "cell_type": "markdown", - "id": "36e7797a", + "id": "17029d10", "metadata": {}, "source": [ "In the third test we run a node-based simulation restricted to the surface of a sphere.\n", @@ -599,7 +599,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4432292d", + "id": "76793e02", "metadata": {}, "outputs": [], "source": [ @@ -614,7 +614,7 @@ }, { "cell_type": "markdown", - "id": "56119cfe", + "id": "5393d13d", "metadata": {}, "source": [ "To run node-based simulations you need to define a cut off length (second argument in ConstructNodesWithoutMesh),\n", @@ -625,7 +625,7 @@ { "cell_type": "code", "execution_count": null, - "id": "10c19934", + "id": "05cc0ffe", "metadata": {}, "outputs": [], "source": [ @@ -638,7 +638,7 @@ }, { "cell_type": "markdown", - "id": "e4330483", + "id": "9dd8d022", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -648,7 +648,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11237f3b", + "id": "37e6c49c", "metadata": {}, "outputs": [], "source": [ @@ -663,7 +663,7 @@ }, { "cell_type": "markdown", - "id": "f69e6f1e", + "id": "f7f34f19", "metadata": {}, "source": [ "We now pass a force law to the simulation.\n", @@ -673,7 +673,7 @@ { "cell_type": "code", "execution_count": null, - "id": "44951122", + "id": "83933153", "metadata": {}, "outputs": [], "source": [ @@ -683,7 +683,7 @@ }, { "cell_type": "markdown", - "id": "75ca15e7", + "id": "570d8800", "metadata": {}, "source": [ "This time we create a CellPopulationBoundaryCondition and pass this to the OffLatticeSimulation.\n", @@ -698,7 +698,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7d11a078", + "id": "c13b64c5", "metadata": {}, "outputs": [], "source": [ @@ -711,7 +711,7 @@ }, { "cell_type": "markdown", - "id": "f87548ae", + "id": "bdf1db06", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -721,7 +721,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1cdf1e8d", + "id": "5ed9087d", "metadata": {}, "outputs": [], "source": [ @@ -732,7 +732,7 @@ }, { "cell_type": "markdown", - "id": "3df3c0f2", + "id": "3787ebeb", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -742,7 +742,7 @@ { "cell_type": "code", "execution_count": null, - "id": "00c65de2", + "id": "40df3af8", "metadata": {}, "outputs": [], "source": [ @@ -753,7 +753,7 @@ }, { "cell_type": "markdown", - "id": "49b04bcc", + "id": "8fda7129", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -764,7 +764,7 @@ { "cell_type": "code", "execution_count": null, - "id": "49ae6fc6", + "id": "7627d6d3", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb index bc98dd2e..9e3675eb 100644 --- a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "fe26027f", + "id": "19f2f0f9", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "722137ac", + "id": "32862ad6", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "7c983357", + "id": "cc57e771", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6e28e95b", + "id": "3d66baea", "metadata": {}, "outputs": [], "source": [ @@ -52,7 +52,7 @@ }, { "cell_type": "markdown", - "id": "1750572a", + "id": "b81ac981", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -64,7 +64,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9934f251", + "id": "bc00e31a", "metadata": {}, "outputs": [], "source": [ @@ -74,7 +74,7 @@ }, { "cell_type": "markdown", - "id": "bbfa49bf", + "id": "4e84f214", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -88,7 +88,7 @@ { "cell_type": "code", "execution_count": null, - "id": "55f38d19", + "id": "0ddcb8f1", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "a91fdb20", + "id": "83ed5d9d", "metadata": {}, "source": [ "Having created a mesh, we now create a vector of CellPtrs. To do this, we the CellsGenerator helper class,\n", @@ -114,7 +114,7 @@ { "cell_type": "code", "execution_count": null, - "id": "33614632", + "id": "4e8b891c", "metadata": {}, "outputs": [], "source": [ @@ -124,7 +124,7 @@ }, { "cell_type": "markdown", - "id": "627977c0", + "id": "e056ad92", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -136,7 +136,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c6f33a23", + "id": "c23592f7", "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "markdown", - "id": "605a945a", + "id": "6d71cf2c", "metadata": {}, "source": [ "We can set the \"Temperature\" to be used in the Potts Simulation using the optional command below. The default value is 0.1.\n", @@ -156,7 +156,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cb238e68", + "id": "c989327e", "metadata": {}, "outputs": [], "source": [ @@ -165,7 +165,7 @@ }, { "cell_type": "markdown", - "id": "be5535e5", + "id": "9113a155", "metadata": {}, "source": [ "By default the Potts simulation will make 1 sweep over the whole domain per timestep.\n", @@ -176,7 +176,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6389e49a", + "id": "8289feeb", "metadata": {}, "outputs": [], "source": [ @@ -185,7 +185,7 @@ }, { "cell_type": "markdown", - "id": "c3ee1f4c", + "id": "99e056fc", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -195,7 +195,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d4c65850", + "id": "7db9fc5b", "metadata": {}, "outputs": [], "source": [ @@ -208,7 +208,7 @@ }, { "cell_type": "markdown", - "id": "698d2c01", + "id": "528e59be", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -218,7 +218,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ef1a7d77", + "id": "7d750ce2", "metadata": {}, "outputs": [], "source": [ @@ -229,7 +229,7 @@ }, { "cell_type": "markdown", - "id": "56b04ad7", + "id": "e4d5c4aa", "metadata": {}, "source": [ "The default timestep is 0.1, but can be changed using the below command. The timestep is used in conjunction with the \"Temperature\"\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "34458dba", + "id": "0d507968", "metadata": {}, "outputs": [], "source": [ @@ -251,7 +251,7 @@ }, { "cell_type": "markdown", - "id": "42596e10", + "id": "2156ab5f", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -264,7 +264,7 @@ { "cell_type": "code", "execution_count": null, - "id": "fab5817f", + "id": "5695e258", "metadata": {}, "outputs": [], "source": [ @@ -273,7 +273,7 @@ }, { "cell_type": "markdown", - "id": "1e8391b6", + "id": "e61aafb8", "metadata": {}, "source": [ "Set an appropriate target volume in number of lattice sites. Here we use the default value of 16 lattice sites.\n", @@ -283,7 +283,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e72fb371", + "id": "92e25726", "metadata": {}, "outputs": [], "source": [ @@ -292,7 +292,7 @@ }, { "cell_type": "markdown", - "id": "a90457d0", + "id": "276fcdbd", "metadata": {}, "source": [ "You can also vary the deformation energy parameter.\n", @@ -303,7 +303,7 @@ { "cell_type": "code", "execution_count": null, - "id": "69cd75e6", + "id": "bddcb2b8", "metadata": {}, "outputs": [], "source": [ @@ -312,7 +312,7 @@ }, { "cell_type": "markdown", - "id": "cf085a6a", + "id": "f26aad41", "metadata": {}, "source": [ "Finally we add the update rule to the simulator.\n", @@ -322,7 +322,7 @@ { "cell_type": "code", "execution_count": null, - "id": "556817c8", + "id": "91deabd8", "metadata": {}, "outputs": [], "source": [ @@ -331,7 +331,7 @@ }, { "cell_type": "markdown", - "id": "7da26bd8", + "id": "e8177fd5", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -341,7 +341,7 @@ { "cell_type": "code", "execution_count": null, - "id": "96f3a915", + "id": "e78fe9c8", "metadata": {}, "outputs": [], "source": [ @@ -351,7 +351,7 @@ }, { "cell_type": "markdown", - "id": "c20c081f", + "id": "280b6408", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -361,7 +361,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b8e965f1", + "id": "6ba7bdda", "metadata": {}, "outputs": [], "source": [ @@ -373,7 +373,7 @@ }, { "cell_type": "markdown", - "id": "6e0d622d", + "id": "a7a40e12", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -383,7 +383,7 @@ { "cell_type": "code", "execution_count": null, - "id": "abfa1220", + "id": "ee54db29", "metadata": {}, "outputs": [], "source": [ @@ -393,7 +393,7 @@ }, { "cell_type": "markdown", - "id": "7e621647", + "id": "2631a8d8", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -404,7 +404,7 @@ { "cell_type": "code", "execution_count": null, - "id": "de9ee328", + "id": "9aedfa4f", "metadata": {}, "outputs": [], "source": [ @@ -415,7 +415,7 @@ }, { "cell_type": "markdown", - "id": "1decbf79", + "id": "8f0fb47a", "metadata": {}, "source": [ "## Test 2 - Cell sorting\n", @@ -427,7 +427,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4658f560", + "id": "6b02e3c2", "metadata": {}, "outputs": [], "source": [ @@ -437,7 +437,7 @@ }, { "cell_type": "markdown", - "id": "22d91700", + "id": "a5933986", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -449,7 +449,7 @@ { "cell_type": "code", "execution_count": null, - "id": "91f401bb", + "id": "0fbd8e4a", "metadata": {}, "outputs": [], "source": [ @@ -460,7 +460,7 @@ }, { "cell_type": "markdown", - "id": "461297ca", + "id": "415bd93e", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -471,7 +471,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2fb425e", + "id": "57803d88", "metadata": {}, "outputs": [], "source": [ @@ -483,7 +483,7 @@ }, { "cell_type": "markdown", - "id": "0ad517b0", + "id": "60e6297b", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -493,7 +493,7 @@ { "cell_type": "code", "execution_count": null, - "id": "15815e4f", + "id": "d197149c", "metadata": {}, "outputs": [], "source": [ @@ -505,7 +505,7 @@ }, { "cell_type": "markdown", - "id": "659d8e43", + "id": "1444786a", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -515,7 +515,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8a7dc842", + "id": "92b3b708", "metadata": {}, "outputs": [], "source": [ @@ -525,7 +525,7 @@ }, { "cell_type": "markdown", - "id": "c13baf5d", + "id": "02b97221", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -535,7 +535,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2d9b2419", + "id": "0577431b", "metadata": {}, "outputs": [], "source": [ @@ -544,7 +544,7 @@ }, { "cell_type": "markdown", - "id": "08c38fbb", + "id": "a280deb7", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -554,7 +554,7 @@ { "cell_type": "code", "execution_count": null, - "id": "aed04eba", + "id": "37dce360", "metadata": {}, "outputs": [], "source": [ @@ -566,7 +566,7 @@ }, { "cell_type": "markdown", - "id": "80e2d404", + "id": "55f2ef5e", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -579,7 +579,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8f0204dc", + "id": "98da52bc", "metadata": {}, "outputs": [], "source": [ @@ -591,7 +591,7 @@ }, { "cell_type": "markdown", - "id": "9a7d93e8", + "id": "1e372374", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -601,7 +601,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2ec888ed", + "id": "2c1e84b4", "metadata": {}, "outputs": [], "source": [ @@ -616,7 +616,7 @@ }, { "cell_type": "markdown", - "id": "90188a5e", + "id": "6c275247", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -626,7 +626,7 @@ { "cell_type": "code", "execution_count": null, - "id": "63b404af", + "id": "37549cdb", "metadata": {}, "outputs": [], "source": [ @@ -635,7 +635,7 @@ }, { "cell_type": "markdown", - "id": "eb6ec287", + "id": "9e41d672", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -646,7 +646,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6225d338", + "id": "169a61f8", "metadata": {}, "outputs": [], "source": [ @@ -657,7 +657,7 @@ }, { "cell_type": "markdown", - "id": "9471f9fd", + "id": "b7e6cb90", "metadata": {}, "source": [ "## Test 3 - 3D Cell Sorting\n", @@ -668,7 +668,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7a665cfc", + "id": "782c9629", "metadata": {}, "outputs": [], "source": [ @@ -678,7 +678,7 @@ }, { "cell_type": "markdown", - "id": "00647aea", + "id": "bc1b2f05", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -693,7 +693,7 @@ { "cell_type": "code", "execution_count": null, - "id": "261b8586", + "id": "3e099ae2", "metadata": {}, "outputs": [], "source": [ @@ -705,7 +705,7 @@ }, { "cell_type": "markdown", - "id": "b6e31280", + "id": "2a93a3f2", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -716,7 +716,7 @@ { "cell_type": "code", "execution_count": null, - "id": "47c643c7", + "id": "1b59f72b", "metadata": {}, "outputs": [], "source": [ @@ -728,7 +728,7 @@ }, { "cell_type": "markdown", - "id": "c415abaf", + "id": "56e31deb", "metadata": {}, "source": [ "As for the 2D case before we make a CellPopulation we make a pointer to a cell label and then assign this label to some randomly chosen cells.\n", @@ -738,7 +738,7 @@ { "cell_type": "code", "execution_count": null, - "id": "fc267e74", + "id": "78d8845c", "metadata": {}, "outputs": [], "source": [ @@ -750,7 +750,7 @@ }, { "cell_type": "markdown", - "id": "618691c5", + "id": "26a025de", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -760,7 +760,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2c7fcbc", + "id": "96bf7ba5", "metadata": {}, "outputs": [], "source": [ @@ -770,7 +770,7 @@ }, { "cell_type": "markdown", - "id": "dc3c8739", + "id": "97beee30", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -780,7 +780,7 @@ { "cell_type": "code", "execution_count": null, - "id": "401d5a8e", + "id": "7e88cf66", "metadata": {}, "outputs": [], "source": [ @@ -789,7 +789,7 @@ }, { "cell_type": "markdown", - "id": "8eb40125", + "id": "e5e15bd2", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -799,7 +799,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95b77b57", + "id": "5707e277", "metadata": {}, "outputs": [], "source": [ @@ -811,7 +811,7 @@ }, { "cell_type": "markdown", - "id": "8fe58ca4", + "id": "16f312dd", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -822,7 +822,7 @@ { "cell_type": "code", "execution_count": null, - "id": "98315238", + "id": "037e1d6b", "metadata": {}, "outputs": [], "source": [ @@ -834,7 +834,7 @@ }, { "cell_type": "markdown", - "id": "e66a5118", + "id": "6ce4b0a8", "metadata": {}, "source": [ "We use the same differential adhesion parameters as in the 2D case.\n", @@ -844,7 +844,7 @@ { "cell_type": "code", "execution_count": null, - "id": "eb89094c", + "id": "4e04b895", "metadata": {}, "outputs": [], "source": [ @@ -859,7 +859,7 @@ }, { "cell_type": "markdown", - "id": "73a41c30", + "id": "321efe1a", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -869,7 +869,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ab765b87", + "id": "f176a3bc", "metadata": {}, "outputs": [], "source": [ @@ -878,7 +878,7 @@ }, { "cell_type": "markdown", - "id": "5a35c7df", + "id": "1274cc35", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -889,7 +889,7 @@ { "cell_type": "code", "execution_count": null, - "id": "56d9c1bf", + "id": "81e55ee8", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb index bc98dd2e..9e3675eb 100644 --- a/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestPottsBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "fe26027f", + "id": "19f2f0f9", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestPottsBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "722137ac", + "id": "32862ad6", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "7c983357", + "id": "cc57e771", "metadata": {}, "source": [ "\n", @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6e28e95b", + "id": "3d66baea", "metadata": {}, "outputs": [], "source": [ @@ -52,7 +52,7 @@ }, { "cell_type": "markdown", - "id": "1750572a", + "id": "b81ac981", "metadata": {}, "source": [ "## Test 1 - A basic node-based simulation\n", @@ -64,7 +64,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9934f251", + "id": "bc00e31a", "metadata": {}, "outputs": [], "source": [ @@ -74,7 +74,7 @@ }, { "cell_type": "markdown", - "id": "bbfa49bf", + "id": "4e84f214", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -88,7 +88,7 @@ { "cell_type": "code", "execution_count": null, - "id": "55f38d19", + "id": "0ddcb8f1", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "a91fdb20", + "id": "83ed5d9d", "metadata": {}, "source": [ "Having created a mesh, we now create a vector of CellPtrs. To do this, we the CellsGenerator helper class,\n", @@ -114,7 +114,7 @@ { "cell_type": "code", "execution_count": null, - "id": "33614632", + "id": "4e8b891c", "metadata": {}, "outputs": [], "source": [ @@ -124,7 +124,7 @@ }, { "cell_type": "markdown", - "id": "627977c0", + "id": "e056ad92", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -136,7 +136,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c6f33a23", + "id": "c23592f7", "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "markdown", - "id": "605a945a", + "id": "6d71cf2c", "metadata": {}, "source": [ "We can set the \"Temperature\" to be used in the Potts Simulation using the optional command below. The default value is 0.1.\n", @@ -156,7 +156,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cb238e68", + "id": "c989327e", "metadata": {}, "outputs": [], "source": [ @@ -165,7 +165,7 @@ }, { "cell_type": "markdown", - "id": "be5535e5", + "id": "9113a155", "metadata": {}, "source": [ "By default the Potts simulation will make 1 sweep over the whole domain per timestep.\n", @@ -176,7 +176,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6389e49a", + "id": "8289feeb", "metadata": {}, "outputs": [], "source": [ @@ -185,7 +185,7 @@ }, { "cell_type": "markdown", - "id": "c3ee1f4c", + "id": "99e056fc", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -195,7 +195,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d4c65850", + "id": "7db9fc5b", "metadata": {}, "outputs": [], "source": [ @@ -208,7 +208,7 @@ }, { "cell_type": "markdown", - "id": "698d2c01", + "id": "528e59be", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -218,7 +218,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ef1a7d77", + "id": "7d750ce2", "metadata": {}, "outputs": [], "source": [ @@ -229,7 +229,7 @@ }, { "cell_type": "markdown", - "id": "56b04ad7", + "id": "e4d5c4aa", "metadata": {}, "source": [ "The default timestep is 0.1, but can be changed using the below command. The timestep is used in conjunction with the \"Temperature\"\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "34458dba", + "id": "0d507968", "metadata": {}, "outputs": [], "source": [ @@ -251,7 +251,7 @@ }, { "cell_type": "markdown", - "id": "42596e10", + "id": "2156ab5f", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -264,7 +264,7 @@ { "cell_type": "code", "execution_count": null, - "id": "fab5817f", + "id": "5695e258", "metadata": {}, "outputs": [], "source": [ @@ -273,7 +273,7 @@ }, { "cell_type": "markdown", - "id": "1e8391b6", + "id": "e61aafb8", "metadata": {}, "source": [ "Set an appropriate target volume in number of lattice sites. Here we use the default value of 16 lattice sites.\n", @@ -283,7 +283,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e72fb371", + "id": "92e25726", "metadata": {}, "outputs": [], "source": [ @@ -292,7 +292,7 @@ }, { "cell_type": "markdown", - "id": "a90457d0", + "id": "276fcdbd", "metadata": {}, "source": [ "You can also vary the deformation energy parameter.\n", @@ -303,7 +303,7 @@ { "cell_type": "code", "execution_count": null, - "id": "69cd75e6", + "id": "bddcb2b8", "metadata": {}, "outputs": [], "source": [ @@ -312,7 +312,7 @@ }, { "cell_type": "markdown", - "id": "cf085a6a", + "id": "f26aad41", "metadata": {}, "source": [ "Finally we add the update rule to the simulator.\n", @@ -322,7 +322,7 @@ { "cell_type": "code", "execution_count": null, - "id": "556817c8", + "id": "91deabd8", "metadata": {}, "outputs": [], "source": [ @@ -331,7 +331,7 @@ }, { "cell_type": "markdown", - "id": "7da26bd8", + "id": "e8177fd5", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -341,7 +341,7 @@ { "cell_type": "code", "execution_count": null, - "id": "96f3a915", + "id": "e78fe9c8", "metadata": {}, "outputs": [], "source": [ @@ -351,7 +351,7 @@ }, { "cell_type": "markdown", - "id": "c20c081f", + "id": "280b6408", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -361,7 +361,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b8e965f1", + "id": "6ba7bdda", "metadata": {}, "outputs": [], "source": [ @@ -373,7 +373,7 @@ }, { "cell_type": "markdown", - "id": "6e0d622d", + "id": "a7a40e12", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -383,7 +383,7 @@ { "cell_type": "code", "execution_count": null, - "id": "abfa1220", + "id": "ee54db29", "metadata": {}, "outputs": [], "source": [ @@ -393,7 +393,7 @@ }, { "cell_type": "markdown", - "id": "7e621647", + "id": "2631a8d8", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -404,7 +404,7 @@ { "cell_type": "code", "execution_count": null, - "id": "de9ee328", + "id": "9aedfa4f", "metadata": {}, "outputs": [], "source": [ @@ -415,7 +415,7 @@ }, { "cell_type": "markdown", - "id": "1decbf79", + "id": "8f0fb47a", "metadata": {}, "source": [ "## Test 2 - Cell sorting\n", @@ -427,7 +427,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4658f560", + "id": "6b02e3c2", "metadata": {}, "outputs": [], "source": [ @@ -437,7 +437,7 @@ }, { "cell_type": "markdown", - "id": "22d91700", + "id": "a5933986", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -449,7 +449,7 @@ { "cell_type": "code", "execution_count": null, - "id": "91f401bb", + "id": "0fbd8e4a", "metadata": {}, "outputs": [], "source": [ @@ -460,7 +460,7 @@ }, { "cell_type": "markdown", - "id": "461297ca", + "id": "415bd93e", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -471,7 +471,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2fb425e", + "id": "57803d88", "metadata": {}, "outputs": [], "source": [ @@ -483,7 +483,7 @@ }, { "cell_type": "markdown", - "id": "0ad517b0", + "id": "60e6297b", "metadata": {}, "source": [ "Before we make a CellPopulation we make a cell label and then assign this label to some randomly chosen cells.\n", @@ -493,7 +493,7 @@ { "cell_type": "code", "execution_count": null, - "id": "15815e4f", + "id": "d197149c", "metadata": {}, "outputs": [], "source": [ @@ -505,7 +505,7 @@ }, { "cell_type": "markdown", - "id": "659d8e43", + "id": "1444786a", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -515,7 +515,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8a7dc842", + "id": "92b3b708", "metadata": {}, "outputs": [], "source": [ @@ -525,7 +525,7 @@ }, { "cell_type": "markdown", - "id": "c13baf5d", + "id": "02b97221", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -535,7 +535,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2d9b2419", + "id": "0577431b", "metadata": {}, "outputs": [], "source": [ @@ -544,7 +544,7 @@ }, { "cell_type": "markdown", - "id": "08c38fbb", + "id": "a280deb7", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -554,7 +554,7 @@ { "cell_type": "code", "execution_count": null, - "id": "aed04eba", + "id": "37dce360", "metadata": {}, "outputs": [], "source": [ @@ -566,7 +566,7 @@ }, { "cell_type": "markdown", - "id": "80e2d404", + "id": "55f2ef5e", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -579,7 +579,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8f0204dc", + "id": "98da52bc", "metadata": {}, "outputs": [], "source": [ @@ -591,7 +591,7 @@ }, { "cell_type": "markdown", - "id": "9a7d93e8", + "id": "1e372374", "metadata": {}, "source": [ "We repeat the process for any other update rules.\n", @@ -601,7 +601,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2ec888ed", + "id": "2c1e84b4", "metadata": {}, "outputs": [], "source": [ @@ -616,7 +616,7 @@ }, { "cell_type": "markdown", - "id": "90188a5e", + "id": "6c275247", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -626,7 +626,7 @@ { "cell_type": "code", "execution_count": null, - "id": "63b404af", + "id": "37549cdb", "metadata": {}, "outputs": [], "source": [ @@ -635,7 +635,7 @@ }, { "cell_type": "markdown", - "id": "eb6ec287", + "id": "9e41d672", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -646,7 +646,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6225d338", + "id": "169a61f8", "metadata": {}, "outputs": [], "source": [ @@ -657,7 +657,7 @@ }, { "cell_type": "markdown", - "id": "9471f9fd", + "id": "b7e6cb90", "metadata": {}, "source": [ "## Test 3 - 3D Cell Sorting\n", @@ -668,7 +668,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7a665cfc", + "id": "782c9629", "metadata": {}, "outputs": [], "source": [ @@ -678,7 +678,7 @@ }, { "cell_type": "markdown", - "id": "00647aea", + "id": "bc1b2f05", "metadata": {}, "source": [ "First, we generate a Potts mesh. To create a PottsMesh, we can use the PottsMeshGenerator.\n", @@ -693,7 +693,7 @@ { "cell_type": "code", "execution_count": null, - "id": "261b8586", + "id": "3e099ae2", "metadata": {}, "outputs": [], "source": [ @@ -705,7 +705,7 @@ }, { "cell_type": "markdown", - "id": "b6e31280", + "id": "2a93a3f2", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. To do this, we the CellsGenerator helper class,\n", @@ -716,7 +716,7 @@ { "cell_type": "code", "execution_count": null, - "id": "47c643c7", + "id": "1b59f72b", "metadata": {}, "outputs": [], "source": [ @@ -728,7 +728,7 @@ }, { "cell_type": "markdown", - "id": "c415abaf", + "id": "56e31deb", "metadata": {}, "source": [ "As for the 2D case before we make a CellPopulation we make a pointer to a cell label and then assign this label to some randomly chosen cells.\n", @@ -738,7 +738,7 @@ { "cell_type": "code", "execution_count": null, - "id": "fc267e74", + "id": "78d8845c", "metadata": {}, "outputs": [], "source": [ @@ -750,7 +750,7 @@ }, { "cell_type": "markdown", - "id": "618691c5", + "id": "26a025de", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -760,7 +760,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2c7fcbc", + "id": "96bf7ba5", "metadata": {}, "outputs": [], "source": [ @@ -770,7 +770,7 @@ }, { "cell_type": "markdown", - "id": "dc3c8739", + "id": "97beee30", "metadata": {}, "source": [ "In order to visualize labelled cells we need to use the following command.\n", @@ -780,7 +780,7 @@ { "cell_type": "code", "execution_count": null, - "id": "401d5a8e", + "id": "7e88cf66", "metadata": {}, "outputs": [], "source": [ @@ -789,7 +789,7 @@ }, { "cell_type": "markdown", - "id": "8eb40125", + "id": "e5e15bd2", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time\n", @@ -799,7 +799,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95b77b57", + "id": "5707e277", "metadata": {}, "outputs": [], "source": [ @@ -811,7 +811,7 @@ }, { "cell_type": "markdown", - "id": "8fe58ca4", + "id": "16f312dd", "metadata": {}, "source": [ "We must now create one or more update rules, which determine the Hamiltonian in the Potts simulation.\n", @@ -822,7 +822,7 @@ { "cell_type": "code", "execution_count": null, - "id": "98315238", + "id": "037e1d6b", "metadata": {}, "outputs": [], "source": [ @@ -834,7 +834,7 @@ }, { "cell_type": "markdown", - "id": "e66a5118", + "id": "6ce4b0a8", "metadata": {}, "source": [ "We use the same differential adhesion parameters as in the 2D case.\n", @@ -844,7 +844,7 @@ { "cell_type": "code", "execution_count": null, - "id": "eb89094c", + "id": "4e04b895", "metadata": {}, "outputs": [], "source": [ @@ -859,7 +859,7 @@ }, { "cell_type": "markdown", - "id": "73a41c30", + "id": "321efe1a", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -869,7 +869,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ab765b87", + "id": "f176a3bc", "metadata": {}, "outputs": [], "source": [ @@ -878,7 +878,7 @@ }, { "cell_type": "markdown", - "id": "5a35c7df", + "id": "1274cc35", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -889,7 +889,7 @@ { "cell_type": "code", "execution_count": null, - "id": "56d9c1bf", + "id": "81e55ee8", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestScratchAssayTutorial.ipynb b/doc/tutorials/TestScratchAssayTutorial.ipynb index 0de64af4..afc87683 100644 --- a/doc/tutorials/TestScratchAssayTutorial.ipynb +++ b/doc/tutorials/TestScratchAssayTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "7f5aad40", + "id": "57d70ef8", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestScratchAssayTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "31b11251", + "id": "d2811228", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "1132d347", + "id": "1bfa3280", "metadata": {}, "source": [ "\n", @@ -44,7 +44,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3188078b", + "id": "9a6d4b17", "metadata": {}, "outputs": [], "source": [ @@ -59,7 +59,7 @@ }, { "cell_type": "markdown", - "id": "55f09b2a", + "id": "929c20cd", "metadata": {}, "source": [ "## Test 1 - Scratch Assay\n", @@ -71,7 +71,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1835f6a7", + "id": "adda7560", "metadata": {}, "outputs": [], "source": [ @@ -81,7 +81,7 @@ }, { "cell_type": "markdown", - "id": "6ca0bc5c", + "id": "b680daf4", "metadata": {}, "source": [ "Chaste is based on the concept of `Cells` and `Meshes`. 'Cells' do not store their position in space,\n", @@ -96,7 +96,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95eeca2c", + "id": "f6343803", "metadata": {}, "outputs": [], "source": [ @@ -108,7 +108,7 @@ }, { "cell_type": "markdown", - "id": "0ecb6c54", + "id": "07e82bd3", "metadata": {}, "source": [ "Note that we are using a `PottsMeshGenerator2` to set up the grid and we are setting some terms to 0. Chaste\n", @@ -128,7 +128,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8549652b", + "id": "60cc6275", "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "markdown", - "id": "32c71fee", + "id": "9336ce99", "metadata": {}, "source": [ "We are not interested in cell cycling so we specialize the generator to NoCellCycleModel.\n", @@ -148,7 +148,7 @@ { "cell_type": "code", "execution_count": null, - "id": "eddb0b29", + "id": "5aa3284c", "metadata": {}, "outputs": [], "source": [ @@ -157,7 +157,7 @@ }, { "cell_type": "markdown", - "id": "ddad4e69", + "id": "8837c17f", "metadata": {}, "source": [ "We want two sets of cells, starting on opposite sides of the mesh. We use `location_indices` to map cells onto\n", @@ -169,7 +169,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b20c1098", + "id": "743824ce", "metadata": {}, "outputs": [], "source": [ @@ -185,7 +185,7 @@ }, { "cell_type": "markdown", - "id": "68c97925", + "id": "b7b6348c", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -195,7 +195,7 @@ { "cell_type": "code", "execution_count": null, - "id": "467d5255", + "id": "dc362625", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "43211f16", + "id": "b72ee65e", "metadata": {}, "source": [ "Next, we set up an `OffLatticeSimulation` which will manage the solver. We need to add some custom rules to\n", @@ -217,7 +217,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b2c12e4d", + "id": "b02679a1", "metadata": {}, "outputs": [], "source": [ @@ -230,7 +230,7 @@ }, { "cell_type": "markdown", - "id": "d15b1b80", + "id": "f62ea6f9", "metadata": {}, "source": [ "We must now create a rule for cell migration. We will use an existing diffusion type rule.\n", @@ -240,7 +240,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1ab3666f", + "id": "a3436590", "metadata": {}, "outputs": [], "source": [ @@ -250,7 +250,7 @@ }, { "cell_type": "markdown", - "id": "761aa121", + "id": "94d375c8", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -261,7 +261,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cb42c762", + "id": "aace3b92", "metadata": {}, "outputs": [], "source": [ @@ -274,7 +274,7 @@ }, { "cell_type": "markdown", - "id": "c4057d3d", + "id": "9af898ef", "metadata": {}, "source": [ "We add the scene to the simulation for real-time updating using a `VtkSceneModifier`. Such\n", @@ -287,7 +287,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8e16d6e6", + "id": "7db25cdf", "metadata": {}, "outputs": [], "source": [ @@ -299,7 +299,7 @@ }, { "cell_type": "markdown", - "id": "b7831aa4", + "id": "31ed5688", "metadata": {}, "source": [ "Chaste and PyChaste use object oriented programming. This may require some background reading,\n", @@ -315,7 +315,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4c86f52a", + "id": "c7c43e8e", "metadata": {}, "outputs": [], "source": [ @@ -362,7 +362,7 @@ }, { "cell_type": "markdown", - "id": "43ef8599", + "id": "77624148", "metadata": {}, "source": [ "To run the simulation, we call `Solve()` and optionally set up interactive plotting. We will see the cells\n", @@ -373,7 +373,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f907c915", + "id": "a1747014", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb b/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb index 0de64af4..afc87683 100644 --- a/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestScratchAssayTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "7f5aad40", + "id": "57d70ef8", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestScratchAssayTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "31b11251", + "id": "d2811228", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "1132d347", + "id": "1bfa3280", "metadata": {}, "source": [ "\n", @@ -44,7 +44,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3188078b", + "id": "9a6d4b17", "metadata": {}, "outputs": [], "source": [ @@ -59,7 +59,7 @@ }, { "cell_type": "markdown", - "id": "55f09b2a", + "id": "929c20cd", "metadata": {}, "source": [ "## Test 1 - Scratch Assay\n", @@ -71,7 +71,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1835f6a7", + "id": "adda7560", "metadata": {}, "outputs": [], "source": [ @@ -81,7 +81,7 @@ }, { "cell_type": "markdown", - "id": "6ca0bc5c", + "id": "b680daf4", "metadata": {}, "source": [ "Chaste is based on the concept of `Cells` and `Meshes`. 'Cells' do not store their position in space,\n", @@ -96,7 +96,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95eeca2c", + "id": "f6343803", "metadata": {}, "outputs": [], "source": [ @@ -108,7 +108,7 @@ }, { "cell_type": "markdown", - "id": "0ecb6c54", + "id": "07e82bd3", "metadata": {}, "source": [ "Note that we are using a `PottsMeshGenerator2` to set up the grid and we are setting some terms to 0. Chaste\n", @@ -128,7 +128,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8549652b", + "id": "60cc6275", "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "markdown", - "id": "32c71fee", + "id": "9336ce99", "metadata": {}, "source": [ "We are not interested in cell cycling so we specialize the generator to NoCellCycleModel.\n", @@ -148,7 +148,7 @@ { "cell_type": "code", "execution_count": null, - "id": "eddb0b29", + "id": "5aa3284c", "metadata": {}, "outputs": [], "source": [ @@ -157,7 +157,7 @@ }, { "cell_type": "markdown", - "id": "ddad4e69", + "id": "8837c17f", "metadata": {}, "source": [ "We want two sets of cells, starting on opposite sides of the mesh. We use `location_indices` to map cells onto\n", @@ -169,7 +169,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b20c1098", + "id": "743824ce", "metadata": {}, "outputs": [], "source": [ @@ -185,7 +185,7 @@ }, { "cell_type": "markdown", - "id": "68c97925", + "id": "b7b6348c", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -195,7 +195,7 @@ { "cell_type": "code", "execution_count": null, - "id": "467d5255", + "id": "dc362625", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,7 @@ }, { "cell_type": "markdown", - "id": "43211f16", + "id": "b72ee65e", "metadata": {}, "source": [ "Next, we set up an `OffLatticeSimulation` which will manage the solver. We need to add some custom rules to\n", @@ -217,7 +217,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b2c12e4d", + "id": "b02679a1", "metadata": {}, "outputs": [], "source": [ @@ -230,7 +230,7 @@ }, { "cell_type": "markdown", - "id": "d15b1b80", + "id": "f62ea6f9", "metadata": {}, "source": [ "We must now create a rule for cell migration. We will use an existing diffusion type rule.\n", @@ -240,7 +240,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1ab3666f", + "id": "a3436590", "metadata": {}, "outputs": [], "source": [ @@ -250,7 +250,7 @@ }, { "cell_type": "markdown", - "id": "761aa121", + "id": "94d375c8", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -261,7 +261,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cb42c762", + "id": "aace3b92", "metadata": {}, "outputs": [], "source": [ @@ -274,7 +274,7 @@ }, { "cell_type": "markdown", - "id": "c4057d3d", + "id": "9af898ef", "metadata": {}, "source": [ "We add the scene to the simulation for real-time updating using a `VtkSceneModifier`. Such\n", @@ -287,7 +287,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8e16d6e6", + "id": "7db25cdf", "metadata": {}, "outputs": [], "source": [ @@ -299,7 +299,7 @@ }, { "cell_type": "markdown", - "id": "b7831aa4", + "id": "31ed5688", "metadata": {}, "source": [ "Chaste and PyChaste use object oriented programming. This may require some background reading,\n", @@ -315,7 +315,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4c86f52a", + "id": "c7c43e8e", "metadata": {}, "outputs": [], "source": [ @@ -362,7 +362,7 @@ }, { "cell_type": "markdown", - "id": "43ef8599", + "id": "77624148", "metadata": {}, "source": [ "To run the simulation, we call `Solve()` and optionally set up interactive plotting. We will see the cells\n", @@ -373,7 +373,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f907c915", + "id": "a1747014", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestSpheroidTutorial.ipynb b/doc/tutorials/TestSpheroidTutorial.ipynb index 20862e4e..5a11ebfc 100644 --- a/doc/tutorials/TestSpheroidTutorial.ipynb +++ b/doc/tutorials/TestSpheroidTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "7d953825", + "id": "235f3c80", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestSpheroidTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28001f1c", + "id": "9d938ef9", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "c01108e5", + "id": "f8c85ede", "metadata": {}, "source": [ "\n", @@ -42,7 +42,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1cb48bf2", + "id": "fb52493e", "metadata": {}, "outputs": [], "source": [ @@ -58,7 +58,7 @@ }, { "cell_type": "markdown", - "id": "f9056e76", + "id": "e855b4fc", "metadata": {}, "source": [ "## Test 1 - a 2D mesh-based spheroid\n", @@ -70,7 +70,7 @@ { "cell_type": "code", "execution_count": null, - "id": "036baef6", + "id": "eda7a4e9", "metadata": {}, "outputs": [], "source": [ @@ -80,7 +80,7 @@ }, { "cell_type": "markdown", - "id": "e84e12d3", + "id": "c626df14", "metadata": {}, "source": [ "This time we will use on off-lattice `MeshBased` cell population. Cell centres are joined with\n", @@ -97,7 +97,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f5a2550f", + "id": "896a0d68", "metadata": {}, "outputs": [], "source": [ @@ -108,7 +108,7 @@ }, { "cell_type": "markdown", - "id": "cab30cb5", + "id": "36af7ad1", "metadata": {}, "source": [ "We create some cells next, with a stem-like proliferative type. This means they will continually\n", @@ -119,7 +119,7 @@ { "cell_type": "code", "execution_count": null, - "id": "32ae9dc1", + "id": "c9188ddf", "metadata": {}, "outputs": [], "source": [ @@ -130,7 +130,7 @@ }, { "cell_type": "markdown", - "id": "a8d9e316", + "id": "2a04fdbb", "metadata": {}, "source": [ "Define when cells become apoptotic\n", @@ -140,7 +140,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0a8ede5", + "id": "91b0f870", "metadata": {}, "outputs": [], "source": [ @@ -161,7 +161,7 @@ }, { "cell_type": "markdown", - "id": "542c7805", + "id": "5b5c16c3", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation` as before.\n", @@ -171,7 +171,7 @@ { "cell_type": "code", "execution_count": null, - "id": "26c2bdb7", + "id": "6f448f12", "metadata": {}, "outputs": [], "source": [ @@ -180,7 +180,7 @@ }, { "cell_type": "markdown", - "id": "d14c5bc6", + "id": "57b8ba00", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly generate the required .vtu files.\n", @@ -190,7 +190,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1a79e3e5", + "id": "b03ee760", "metadata": {}, "outputs": [], "source": [ @@ -199,7 +199,7 @@ }, { "cell_type": "markdown", - "id": "2d30ffa6", + "id": "d994af36", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -209,7 +209,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ddd98115", + "id": "bd18cf80", "metadata": {}, "outputs": [], "source": [ @@ -220,7 +220,7 @@ }, { "cell_type": "markdown", - "id": "4ec5e761", + "id": "c21d30ab", "metadata": {}, "source": [ "We ask for output every 12 increments\n", @@ -230,7 +230,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28a96497", + "id": "1d1c3057", "metadata": {}, "outputs": [], "source": [ @@ -239,7 +239,7 @@ }, { "cell_type": "markdown", - "id": "b2e29299", + "id": "25416a78", "metadata": {}, "source": [ "We define how the springs between cells behave using a force law.\n", @@ -249,7 +249,7 @@ { "cell_type": "code", "execution_count": null, - "id": "68bac92a", + "id": "66025701", "metadata": {}, "outputs": [], "source": [ @@ -259,7 +259,7 @@ }, { "cell_type": "markdown", - "id": "6242379d", + "id": "e011d650", "metadata": {}, "source": [ "We set up a PDE for oxygen diffusion and consumption by cells, setting the rate of consumption to 0.1\n", @@ -269,7 +269,7 @@ { "cell_type": "code", "execution_count": null, - "id": "705b8b8b", + "id": "16a169b9", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "8a44cf04", + "id": "be361fbf", "metadata": {}, "source": [ "We set a constant amount of oxygen on the edge of the spheroid\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ca02d747", + "id": "86bac00d", "metadata": {}, "outputs": [], "source": [ @@ -298,7 +298,7 @@ }, { "cell_type": "markdown", - "id": "79ebdc8b", + "id": "56e57a8e", "metadata": {}, "source": [ "Set up a pde modifier to solve the PDE at each simulation time step\n", @@ -308,7 +308,7 @@ { "cell_type": "code", "execution_count": null, - "id": "64493e57", + "id": "a0938fd2", "metadata": {}, "outputs": [], "source": [ @@ -318,7 +318,7 @@ }, { "cell_type": "markdown", - "id": "e1ee68a4", + "id": "834cc15f", "metadata": {}, "source": [ "As before, we set up a scene modifier for real-time visualization\n", @@ -328,7 +328,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4543c5ba", + "id": "846a01a5", "metadata": {}, "outputs": [], "source": [ @@ -347,7 +347,7 @@ }, { "cell_type": "markdown", - "id": "54fb894b", + "id": "d850618f", "metadata": {}, "source": [ "Eventually remove apoptotic cells\n", @@ -357,7 +357,7 @@ { "cell_type": "code", "execution_count": null, - "id": "239312fd", + "id": "0557f3b9", "metadata": {}, "outputs": [], "source": [ @@ -367,7 +367,7 @@ }, { "cell_type": "markdown", - "id": "799be0a3", + "id": "a126f1fc", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -377,7 +377,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bce6762b", + "id": "2f8db77e", "metadata": {}, "outputs": [], "source": [ @@ -389,7 +389,7 @@ }, { "cell_type": "markdown", - "id": "d956368f", + "id": "e20112d6", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", diff --git a/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb b/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb index 20862e4e..5a11ebfc 100644 --- a/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestSpheroidTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "7d953825", + "id": "235f3c80", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestSpheroidTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28001f1c", + "id": "9d938ef9", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "c01108e5", + "id": "f8c85ede", "metadata": {}, "source": [ "\n", @@ -42,7 +42,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1cb48bf2", + "id": "fb52493e", "metadata": {}, "outputs": [], "source": [ @@ -58,7 +58,7 @@ }, { "cell_type": "markdown", - "id": "f9056e76", + "id": "e855b4fc", "metadata": {}, "source": [ "## Test 1 - a 2D mesh-based spheroid\n", @@ -70,7 +70,7 @@ { "cell_type": "code", "execution_count": null, - "id": "036baef6", + "id": "eda7a4e9", "metadata": {}, "outputs": [], "source": [ @@ -80,7 +80,7 @@ }, { "cell_type": "markdown", - "id": "e84e12d3", + "id": "c626df14", "metadata": {}, "source": [ "This time we will use on off-lattice `MeshBased` cell population. Cell centres are joined with\n", @@ -97,7 +97,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f5a2550f", + "id": "896a0d68", "metadata": {}, "outputs": [], "source": [ @@ -108,7 +108,7 @@ }, { "cell_type": "markdown", - "id": "cab30cb5", + "id": "36af7ad1", "metadata": {}, "source": [ "We create some cells next, with a stem-like proliferative type. This means they will continually\n", @@ -119,7 +119,7 @@ { "cell_type": "code", "execution_count": null, - "id": "32ae9dc1", + "id": "c9188ddf", "metadata": {}, "outputs": [], "source": [ @@ -130,7 +130,7 @@ }, { "cell_type": "markdown", - "id": "a8d9e316", + "id": "2a04fdbb", "metadata": {}, "source": [ "Define when cells become apoptotic\n", @@ -140,7 +140,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0a8ede5", + "id": "91b0f870", "metadata": {}, "outputs": [], "source": [ @@ -161,7 +161,7 @@ }, { "cell_type": "markdown", - "id": "542c7805", + "id": "5b5c16c3", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a `CellPopulation` as before.\n", @@ -171,7 +171,7 @@ { "cell_type": "code", "execution_count": null, - "id": "26c2bdb7", + "id": "6f448f12", "metadata": {}, "outputs": [], "source": [ @@ -180,7 +180,7 @@ }, { "cell_type": "markdown", - "id": "d14c5bc6", + "id": "57b8ba00", "metadata": {}, "source": [ "To view the results of this and the next test in Paraview it is necessary to explicitly generate the required .vtu files.\n", @@ -190,7 +190,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1a79e3e5", + "id": "b03ee760", "metadata": {}, "outputs": [], "source": [ @@ -199,7 +199,7 @@ }, { "cell_type": "markdown", - "id": "2d30ffa6", + "id": "d994af36", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory and end time.\n", @@ -209,7 +209,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ddd98115", + "id": "bd18cf80", "metadata": {}, "outputs": [], "source": [ @@ -220,7 +220,7 @@ }, { "cell_type": "markdown", - "id": "4ec5e761", + "id": "c21d30ab", "metadata": {}, "source": [ "We ask for output every 12 increments\n", @@ -230,7 +230,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28a96497", + "id": "1d1c3057", "metadata": {}, "outputs": [], "source": [ @@ -239,7 +239,7 @@ }, { "cell_type": "markdown", - "id": "b2e29299", + "id": "25416a78", "metadata": {}, "source": [ "We define how the springs between cells behave using a force law.\n", @@ -249,7 +249,7 @@ { "cell_type": "code", "execution_count": null, - "id": "68bac92a", + "id": "66025701", "metadata": {}, "outputs": [], "source": [ @@ -259,7 +259,7 @@ }, { "cell_type": "markdown", - "id": "6242379d", + "id": "e011d650", "metadata": {}, "source": [ "We set up a PDE for oxygen diffusion and consumption by cells, setting the rate of consumption to 0.1\n", @@ -269,7 +269,7 @@ { "cell_type": "code", "execution_count": null, - "id": "705b8b8b", + "id": "16a169b9", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ }, { "cell_type": "markdown", - "id": "8a44cf04", + "id": "be361fbf", "metadata": {}, "source": [ "We set a constant amount of oxygen on the edge of the spheroid\n", @@ -288,7 +288,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ca02d747", + "id": "86bac00d", "metadata": {}, "outputs": [], "source": [ @@ -298,7 +298,7 @@ }, { "cell_type": "markdown", - "id": "79ebdc8b", + "id": "56e57a8e", "metadata": {}, "source": [ "Set up a pde modifier to solve the PDE at each simulation time step\n", @@ -308,7 +308,7 @@ { "cell_type": "code", "execution_count": null, - "id": "64493e57", + "id": "a0938fd2", "metadata": {}, "outputs": [], "source": [ @@ -318,7 +318,7 @@ }, { "cell_type": "markdown", - "id": "e1ee68a4", + "id": "834cc15f", "metadata": {}, "source": [ "As before, we set up a scene modifier for real-time visualization\n", @@ -328,7 +328,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4543c5ba", + "id": "846a01a5", "metadata": {}, "outputs": [], "source": [ @@ -347,7 +347,7 @@ }, { "cell_type": "markdown", - "id": "54fb894b", + "id": "d850618f", "metadata": {}, "source": [ "Eventually remove apoptotic cells\n", @@ -357,7 +357,7 @@ { "cell_type": "code", "execution_count": null, - "id": "239312fd", + "id": "0557f3b9", "metadata": {}, "outputs": [], "source": [ @@ -367,7 +367,7 @@ }, { "cell_type": "markdown", - "id": "799be0a3", + "id": "a126f1fc", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -377,7 +377,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bce6762b", + "id": "2f8db77e", "metadata": {}, "outputs": [], "source": [ @@ -389,7 +389,7 @@ }, { "cell_type": "markdown", - "id": "d956368f", + "id": "e20112d6", "metadata": {}, "source": [ "Full results can be visualized in Paraview from the `file_handler.GetOutputDirectoryFullPath()` directory.\n", diff --git a/doc/tutorials/TestTensileTestTutorial.ipynb b/doc/tutorials/TestTensileTestTutorial.ipynb index eae00892..535d17a3 100644 --- a/doc/tutorials/TestTensileTestTutorial.ipynb +++ b/doc/tutorials/TestTensileTestTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "e6433a58", + "id": "58e6d7e5", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestTensileTestTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9ab4e1c6", + "id": "6997f647", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "d641c612", + "id": "9b512385", "metadata": {}, "source": [ "\n", @@ -42,7 +42,7 @@ { "cell_type": "code", "execution_count": null, - "id": "834d3289", + "id": "56881166", "metadata": {}, "outputs": [], "source": [ @@ -56,7 +56,7 @@ }, { "cell_type": "markdown", - "id": "d4fd421c", + "id": "fdbae083", "metadata": {}, "source": [ "## Test 1 - A 2d test\n", @@ -66,7 +66,7 @@ { "cell_type": "code", "execution_count": null, - "id": "455f45d5", + "id": "24523789", "metadata": {}, "outputs": [], "source": [ @@ -76,7 +76,7 @@ }, { "cell_type": "markdown", - "id": "36903a61", + "id": "781d5a0f", "metadata": {}, "source": [ "First, we generate a vertex mesh using a HoneycombVertexMeshGenerator.\n", @@ -86,7 +86,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09185796", + "id": "21cdd368", "metadata": {}, "outputs": [], "source": [ @@ -96,7 +96,7 @@ }, { "cell_type": "markdown", - "id": "4a4d26a0", + "id": "9e70f317", "metadata": {}, "source": [ "Now set up the cells, again we want to avoid proliferation.\n", @@ -106,7 +106,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f9224053", + "id": "e68edf48", "metadata": {}, "outputs": [], "source": [ @@ -117,7 +117,7 @@ }, { "cell_type": "markdown", - "id": "6a9aa058", + "id": "12bf2d05", "metadata": {}, "source": [ "Next, create the cell population\n", @@ -127,7 +127,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2c219b7", + "id": "17215522", "metadata": {}, "outputs": [], "source": [ @@ -137,7 +137,7 @@ }, { "cell_type": "markdown", - "id": "4a32a73a", + "id": "52887441", "metadata": {}, "source": [ "Pass the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -147,7 +147,7 @@ { "cell_type": "code", "execution_count": null, - "id": "445e1929", + "id": "771fe9fb", "metadata": {}, "outputs": [], "source": [ @@ -159,7 +159,7 @@ }, { "cell_type": "markdown", - "id": "83eb82a2", + "id": "9d8f01d1", "metadata": {}, "source": [ "Now create a force law\n", @@ -169,7 +169,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c07b5947", + "id": "a46fcaf0", "metadata": {}, "outputs": [], "source": [ @@ -179,7 +179,7 @@ }, { "cell_type": "markdown", - "id": "49afd280", + "id": "d8653f57", "metadata": {}, "source": [ "A `NagaiHondaForce` assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -192,7 +192,7 @@ { "cell_type": "code", "execution_count": null, - "id": "53c33b3a", + "id": "2bda9089", "metadata": {}, "outputs": [], "source": [ @@ -202,7 +202,7 @@ }, { "cell_type": "markdown", - "id": "a6cf9ace", + "id": "018cc1c1", "metadata": {}, "source": [ "For our tensile test we will fix the bottom of the sheet and subject the top to an applied displacement. We neglect\n", @@ -213,7 +213,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0a3f892", + "id": "e4515294", "metadata": {}, "outputs": [], "source": [ @@ -229,7 +229,7 @@ }, { "cell_type": "markdown", - "id": "cb0d486e", + "id": "9d5263fb", "metadata": {}, "source": [ "We want to displace our top boundary over time. We could write a custom boundary condition class to do this.\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c61730fa", + "id": "6424820f", "metadata": {}, "outputs": [], "source": [ @@ -270,7 +270,7 @@ }, { "cell_type": "markdown", - "id": "96a530b6", + "id": "05a43849", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -281,7 +281,7 @@ { "cell_type": "code", "execution_count": null, - "id": "59a5df37", + "id": "814afac4", "metadata": {}, "outputs": [], "source": [ @@ -296,7 +296,7 @@ }, { "cell_type": "markdown", - "id": "727a3df1", + "id": "4be588e8", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -306,7 +306,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e99062df", + "id": "e22ba1a4", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb b/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb index eae00892..535d17a3 100644 --- a/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestTensileTestTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "e6433a58", + "id": "58e6d7e5", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestTensileTestTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9ab4e1c6", + "id": "6997f647", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "d641c612", + "id": "9b512385", "metadata": {}, "source": [ "\n", @@ -42,7 +42,7 @@ { "cell_type": "code", "execution_count": null, - "id": "834d3289", + "id": "56881166", "metadata": {}, "outputs": [], "source": [ @@ -56,7 +56,7 @@ }, { "cell_type": "markdown", - "id": "d4fd421c", + "id": "fdbae083", "metadata": {}, "source": [ "## Test 1 - A 2d test\n", @@ -66,7 +66,7 @@ { "cell_type": "code", "execution_count": null, - "id": "455f45d5", + "id": "24523789", "metadata": {}, "outputs": [], "source": [ @@ -76,7 +76,7 @@ }, { "cell_type": "markdown", - "id": "36903a61", + "id": "781d5a0f", "metadata": {}, "source": [ "First, we generate a vertex mesh using a HoneycombVertexMeshGenerator.\n", @@ -86,7 +86,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09185796", + "id": "21cdd368", "metadata": {}, "outputs": [], "source": [ @@ -96,7 +96,7 @@ }, { "cell_type": "markdown", - "id": "4a4d26a0", + "id": "9e70f317", "metadata": {}, "source": [ "Now set up the cells, again we want to avoid proliferation.\n", @@ -106,7 +106,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f9224053", + "id": "e68edf48", "metadata": {}, "outputs": [], "source": [ @@ -117,7 +117,7 @@ }, { "cell_type": "markdown", - "id": "6a9aa058", + "id": "12bf2d05", "metadata": {}, "source": [ "Next, create the cell population\n", @@ -127,7 +127,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d2c219b7", + "id": "17215522", "metadata": {}, "outputs": [], "source": [ @@ -137,7 +137,7 @@ }, { "cell_type": "markdown", - "id": "4a32a73a", + "id": "52887441", "metadata": {}, "source": [ "Pass the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -147,7 +147,7 @@ { "cell_type": "code", "execution_count": null, - "id": "445e1929", + "id": "771fe9fb", "metadata": {}, "outputs": [], "source": [ @@ -159,7 +159,7 @@ }, { "cell_type": "markdown", - "id": "83eb82a2", + "id": "9d8f01d1", "metadata": {}, "source": [ "Now create a force law\n", @@ -169,7 +169,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c07b5947", + "id": "a46fcaf0", "metadata": {}, "outputs": [], "source": [ @@ -179,7 +179,7 @@ }, { "cell_type": "markdown", - "id": "49afd280", + "id": "d8653f57", "metadata": {}, "source": [ "A `NagaiHondaForce` assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -192,7 +192,7 @@ { "cell_type": "code", "execution_count": null, - "id": "53c33b3a", + "id": "2bda9089", "metadata": {}, "outputs": [], "source": [ @@ -202,7 +202,7 @@ }, { "cell_type": "markdown", - "id": "a6cf9ace", + "id": "018cc1c1", "metadata": {}, "source": [ "For our tensile test we will fix the bottom of the sheet and subject the top to an applied displacement. We neglect\n", @@ -213,7 +213,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c0a3f892", + "id": "e4515294", "metadata": {}, "outputs": [], "source": [ @@ -229,7 +229,7 @@ }, { "cell_type": "markdown", - "id": "cb0d486e", + "id": "9d5263fb", "metadata": {}, "source": [ "We want to displace our top boundary over time. We could write a custom boundary condition class to do this.\n", @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c61730fa", + "id": "6424820f", "metadata": {}, "outputs": [], "source": [ @@ -270,7 +270,7 @@ }, { "cell_type": "markdown", - "id": "96a530b6", + "id": "05a43849", "metadata": {}, "source": [ "PyChaste can do simple 3D rendering with VTK. We set up a `VtkScene` so that we can see the population\n", @@ -281,7 +281,7 @@ { "cell_type": "code", "execution_count": null, - "id": "59a5df37", + "id": "814afac4", "metadata": {}, "outputs": [], "source": [ @@ -296,7 +296,7 @@ }, { "cell_type": "markdown", - "id": "727a3df1", + "id": "4be588e8", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -306,7 +306,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e99062df", + "id": "e22ba1a4", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb index fdcd628b..f048dc5c 100644 --- a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb +++ b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "4e4130d8", + "id": "ce381363", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a72b2908", + "id": "7ac165c0", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "8d3c3ea3", + "id": "f797ee03", "metadata": {}, "source": [ "\n", @@ -40,7 +40,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8d340a4a", + "id": "fdd5942d", "metadata": {}, "outputs": [], "source": [ @@ -55,7 +55,7 @@ }, { "cell_type": "markdown", - "id": "6ae7842c", + "id": "05adc24b", "metadata": {}, "source": [ "## Test 1 - A basic vertex-based simulation\n", @@ -67,7 +67,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e55a97b2", + "id": "6aed13ce", "metadata": {}, "outputs": [], "source": [ @@ -77,7 +77,7 @@ }, { "cell_type": "markdown", - "id": "827223e9", + "id": "776ac8f8", "metadata": {}, "source": [ "First, we generate a vertex mesh. To create a MutableVertexMesh, we can use the HoneycombVertexMeshGenerator.\n", @@ -89,7 +89,7 @@ { "cell_type": "code", "execution_count": null, - "id": "02f596e3", + "id": "41535320", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "91652a99", + "id": "facdbabe", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs. To do this, we use the CellsGenerator helper class,\n", @@ -114,7 +114,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09d8261a", + "id": "c04d0a3f", "metadata": {}, "outputs": [], "source": [ @@ -125,7 +125,7 @@ }, { "cell_type": "markdown", - "id": "87974fdf", + "id": "a0740e83", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -137,7 +137,7 @@ { "cell_type": "code", "execution_count": null, - "id": "197868dd", + "id": "1b603f65", "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "markdown", - "id": "857f081f", + "id": "412e6f6c", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -156,7 +156,7 @@ { "cell_type": "code", "execution_count": null, - "id": "54f51e69", + "id": "40c7e03a", "metadata": {}, "outputs": [], "source": [ @@ -168,7 +168,7 @@ }, { "cell_type": "markdown", - "id": "58a1ac86", + "id": "d8d4b9c2", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -178,7 +178,7 @@ { "cell_type": "code", "execution_count": null, - "id": "84c64de6", + "id": "a0d75bbb", "metadata": {}, "outputs": [], "source": [ @@ -189,7 +189,7 @@ }, { "cell_type": "markdown", - "id": "16058604", + "id": "6b9c2009", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step.\n", @@ -202,7 +202,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c32926df", + "id": "2940206f", "metadata": {}, "outputs": [], "source": [ @@ -211,7 +211,7 @@ }, { "cell_type": "markdown", - "id": "d53a69e9", + "id": "7966a7f4", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the vertices of each cell in a cell population.\n", @@ -225,7 +225,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6220bd60", + "id": "26e4644a", "metadata": {}, "outputs": [], "source": [ @@ -235,7 +235,7 @@ }, { "cell_type": "markdown", - "id": "dfde3289", + "id": "00582593", "metadata": {}, "source": [ "A NagaiHondaForce assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -248,7 +248,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e2f3e72c", + "id": "fda8f3af", "metadata": {}, "outputs": [], "source": [ @@ -258,7 +258,7 @@ }, { "cell_type": "markdown", - "id": "058f8346", + "id": "05290bcb", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -268,7 +268,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7542950b", + "id": "88684fe0", "metadata": {}, "outputs": [], "source": [ @@ -280,7 +280,7 @@ }, { "cell_type": "markdown", - "id": "437539bc", + "id": "39dd07cd", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -290,7 +290,7 @@ { "cell_type": "code", "execution_count": null, - "id": "042bd9d4", + "id": "4c1b7bcd", "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "markdown", - "id": "f4812e7c", + "id": "5f4a930e", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -312,7 +312,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a5bff398", + "id": "94f90cd2", "metadata": {}, "outputs": [], "source": [ @@ -322,7 +322,7 @@ }, { "cell_type": "markdown", - "id": "5437ef57", + "id": "77383ca3", "metadata": {}, "source": [ "## Test 2 - introducing periodicity, boundaries and cell killers\n", @@ -335,7 +335,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bd3661ae", + "id": "41cef549", "metadata": {}, "outputs": [], "source": [ @@ -345,7 +345,7 @@ }, { "cell_type": "markdown", - "id": "54d0254e", + "id": "fc605cc4", "metadata": {}, "source": [ "First, we generate a periodic vertex mesh. To create a Cylindrical2dVertexMesh, we can use the CylindricalHoneycombVertexMeshGenerator.\n", @@ -358,7 +358,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f5d124bc", + "id": "3efea02c", "metadata": {}, "outputs": [], "source": [ @@ -368,7 +368,7 @@ }, { "cell_type": "markdown", - "id": "0ef448a1", + "id": "af27d734", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. This is exactly the same as the above test.\n", @@ -378,7 +378,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4e891809", + "id": "3caf01b6", "metadata": {}, "outputs": [], "source": [ @@ -389,7 +389,7 @@ }, { "cell_type": "markdown", - "id": "35793e46", + "id": "9b6ecbd5", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. This is also the same as in the above test.\n", @@ -399,7 +399,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cdeeacf0", + "id": "35beacb5", "metadata": {}, "outputs": [], "source": [ @@ -408,7 +408,7 @@ }, { "cell_type": "markdown", - "id": "a848f459", + "id": "15c0a487", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -418,7 +418,7 @@ { "cell_type": "code", "execution_count": null, - "id": "27c87582", + "id": "447ff9df", "metadata": {}, "outputs": [], "source": [ @@ -430,7 +430,7 @@ }, { "cell_type": "markdown", - "id": "09f06c73", + "id": "9b7db67d", "metadata": {}, "source": [ "We now make a pointer to an appropriate force and pass it to the OffLatticeSimulation.\n", @@ -440,7 +440,7 @@ { "cell_type": "code", "execution_count": null, - "id": "53e730d8", + "id": "2ad5f991", "metadata": {}, "outputs": [], "source": [ @@ -450,7 +450,7 @@ }, { "cell_type": "markdown", - "id": "b593134f", + "id": "a4989fa0", "metadata": {}, "source": [ "We also make a pointer to the target area modifier and add it to the simulator.\n", @@ -460,7 +460,7 @@ { "cell_type": "code", "execution_count": null, - "id": "65a9a66b", + "id": "31eab391", "metadata": {}, "outputs": [], "source": [ @@ -470,7 +470,7 @@ }, { "cell_type": "markdown", - "id": "d12d2bb4", + "id": "f4e62725", "metadata": {}, "source": [ "We now create one or more CellPopulationBoundaryConditions, which determine any conditions which each cell in a cell population must satisfy.\n", @@ -485,7 +485,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b1b39cf7", + "id": "b98ee25b", "metadata": {}, "outputs": [], "source": [ @@ -495,7 +495,7 @@ }, { "cell_type": "markdown", - "id": "8f1671db", + "id": "b45c6346", "metadata": {}, "source": [ "We can now make a PlaneBoundaryCondition (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", @@ -505,7 +505,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09c97391", + "id": "0ff6476a", "metadata": {}, "outputs": [], "source": [ @@ -514,7 +514,7 @@ }, { "cell_type": "markdown", - "id": "03b9d30c", + "id": "1c562b7d", "metadata": {}, "source": [ "We now create one or more CellKillers, which determine how cells are removed from the simulation.\n", @@ -527,7 +527,7 @@ { "cell_type": "code", "execution_count": null, - "id": "98fb0f4e", + "id": "5f9c419c", "metadata": {}, "outputs": [], "source": [ @@ -537,7 +537,7 @@ }, { "cell_type": "markdown", - "id": "599aca20", + "id": "ab554989", "metadata": {}, "source": [ "Finally we now make a PlaneBasedCellKiller (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", @@ -547,7 +547,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d49f5d64", + "id": "d2747096", "metadata": {}, "outputs": [], "source": [ @@ -556,7 +556,7 @@ }, { "cell_type": "markdown", - "id": "624ffd8e", + "id": "7bd62315", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -570,7 +570,7 @@ { "cell_type": "code", "execution_count": null, - "id": "29ae9b5f", + "id": "5c194b6b", "metadata": {}, "outputs": [], "source": [ diff --git a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb index fdcd628b..f048dc5c 100644 --- a/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb +++ b/doc/tutorials/TestVertexBasedCellSimulationsPythonTutorial.nbconvert.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "4e4130d8", + "id": "ce381363", "metadata": {}, "source": [ "This tutorial is automatically generated from the file ../test/python/cell_based/tutorials/TestVertexBasedCellSimulationsPythonTutorial.py.\n", @@ -12,7 +12,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a72b2908", + "id": "7ac165c0", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "markdown", - "id": "8d3c3ea3", + "id": "f797ee03", "metadata": {}, "source": [ "\n", @@ -40,7 +40,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8d340a4a", + "id": "fdd5942d", "metadata": {}, "outputs": [], "source": [ @@ -55,7 +55,7 @@ }, { "cell_type": "markdown", - "id": "6ae7842c", + "id": "05adc24b", "metadata": {}, "source": [ "## Test 1 - A basic vertex-based simulation\n", @@ -67,7 +67,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e55a97b2", + "id": "6aed13ce", "metadata": {}, "outputs": [], "source": [ @@ -77,7 +77,7 @@ }, { "cell_type": "markdown", - "id": "827223e9", + "id": "776ac8f8", "metadata": {}, "source": [ "First, we generate a vertex mesh. To create a MutableVertexMesh, we can use the HoneycombVertexMeshGenerator.\n", @@ -89,7 +89,7 @@ { "cell_type": "code", "execution_count": null, - "id": "02f596e3", + "id": "41535320", "metadata": {}, "outputs": [], "source": [ @@ -100,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "91652a99", + "id": "facdbabe", "metadata": {}, "source": [ "Having created a mesh, we now create a std::vector of CellPtrs. To do this, we use the CellsGenerator helper class,\n", @@ -114,7 +114,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09d8261a", + "id": "c04d0a3f", "metadata": {}, "outputs": [], "source": [ @@ -125,7 +125,7 @@ }, { "cell_type": "markdown", - "id": "87974fdf", + "id": "a0740e83", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation.\n", @@ -137,7 +137,7 @@ { "cell_type": "code", "execution_count": null, - "id": "197868dd", + "id": "1b603f65", "metadata": {}, "outputs": [], "source": [ @@ -146,7 +146,7 @@ }, { "cell_type": "markdown", - "id": "857f081f", + "id": "412e6f6c", "metadata": {}, "source": [ "We can set up a `VtkScene` to do a quick visualization of the population before running the analysis.\n", @@ -156,7 +156,7 @@ { "cell_type": "code", "execution_count": null, - "id": "54f51e69", + "id": "40c7e03a", "metadata": {}, "outputs": [], "source": [ @@ -168,7 +168,7 @@ }, { "cell_type": "markdown", - "id": "58a1ac86", + "id": "d8d4b9c2", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -178,7 +178,7 @@ { "cell_type": "code", "execution_count": null, - "id": "84c64de6", + "id": "a0d75bbb", "metadata": {}, "outputs": [], "source": [ @@ -189,7 +189,7 @@ }, { "cell_type": "markdown", - "id": "16058604", + "id": "6b9c2009", "metadata": {}, "source": [ "For longer simulations, we may not want to output the results every time step.\n", @@ -202,7 +202,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c32926df", + "id": "2940206f", "metadata": {}, "outputs": [], "source": [ @@ -211,7 +211,7 @@ }, { "cell_type": "markdown", - "id": "d53a69e9", + "id": "7966a7f4", "metadata": {}, "source": [ "We must now create one or more force laws, which determine the mechanics of the vertices of each cell in a cell population.\n", @@ -225,7 +225,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6220bd60", + "id": "26e4644a", "metadata": {}, "outputs": [], "source": [ @@ -235,7 +235,7 @@ }, { "cell_type": "markdown", - "id": "dfde3289", + "id": "00582593", "metadata": {}, "source": [ "A NagaiHondaForce assumes that each cell has a target area. The target areas of cells are used to determine\n", @@ -248,7 +248,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e2f3e72c", + "id": "fda8f3af", "metadata": {}, "outputs": [], "source": [ @@ -258,7 +258,7 @@ }, { "cell_type": "markdown", - "id": "058f8346", + "id": "05290bcb", "metadata": {}, "source": [ "Save snapshot images of the population during the simulation\n", @@ -268,7 +268,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7542950b", + "id": "88684fe0", "metadata": {}, "outputs": [], "source": [ @@ -280,7 +280,7 @@ }, { "cell_type": "markdown", - "id": "437539bc", + "id": "39dd07cd", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`. We can again do a quick rendering of the population at the end of the simulation\n", @@ -290,7 +290,7 @@ { "cell_type": "code", "execution_count": null, - "id": "042bd9d4", + "id": "4c1b7bcd", "metadata": {}, "outputs": [], "source": [ @@ -301,7 +301,7 @@ }, { "cell_type": "markdown", - "id": "f4812e7c", + "id": "5f4a930e", "metadata": {}, "source": [ "The next two lines are for test purposes only and are not part of this tutorial.\n", @@ -312,7 +312,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a5bff398", + "id": "94f90cd2", "metadata": {}, "outputs": [], "source": [ @@ -322,7 +322,7 @@ }, { "cell_type": "markdown", - "id": "5437ef57", + "id": "77383ca3", "metadata": {}, "source": [ "## Test 2 - introducing periodicity, boundaries and cell killers\n", @@ -335,7 +335,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bd3661ae", + "id": "41cef549", "metadata": {}, "outputs": [], "source": [ @@ -345,7 +345,7 @@ }, { "cell_type": "markdown", - "id": "54d0254e", + "id": "fc605cc4", "metadata": {}, "source": [ "First, we generate a periodic vertex mesh. To create a Cylindrical2dVertexMesh, we can use the CylindricalHoneycombVertexMeshGenerator.\n", @@ -358,7 +358,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f5d124bc", + "id": "3efea02c", "metadata": {}, "outputs": [], "source": [ @@ -368,7 +368,7 @@ }, { "cell_type": "markdown", - "id": "0ef448a1", + "id": "af27d734", "metadata": {}, "source": [ "Having created a mesh, we now create a VectorSharedPtrCells. This is exactly the same as the above test.\n", @@ -378,7 +378,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4e891809", + "id": "3caf01b6", "metadata": {}, "outputs": [], "source": [ @@ -389,7 +389,7 @@ }, { "cell_type": "markdown", - "id": "35793e46", + "id": "9b6ecbd5", "metadata": {}, "source": [ "Now we have a mesh and a set of cells to go with it, we can create a CellPopulation. This is also the same as in the above test.\n", @@ -399,7 +399,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cdeeacf0", + "id": "35beacb5", "metadata": {}, "outputs": [], "source": [ @@ -408,7 +408,7 @@ }, { "cell_type": "markdown", - "id": "a848f459", + "id": "15c0a487", "metadata": {}, "source": [ "We then pass in the cell population into an `OffLatticeSimulation`, and set the output directory, output multiple and end time\n", @@ -418,7 +418,7 @@ { "cell_type": "code", "execution_count": null, - "id": "27c87582", + "id": "447ff9df", "metadata": {}, "outputs": [], "source": [ @@ -430,7 +430,7 @@ }, { "cell_type": "markdown", - "id": "09f06c73", + "id": "9b7db67d", "metadata": {}, "source": [ "We now make a pointer to an appropriate force and pass it to the OffLatticeSimulation.\n", @@ -440,7 +440,7 @@ { "cell_type": "code", "execution_count": null, - "id": "53e730d8", + "id": "2ad5f991", "metadata": {}, "outputs": [], "source": [ @@ -450,7 +450,7 @@ }, { "cell_type": "markdown", - "id": "b593134f", + "id": "a4989fa0", "metadata": {}, "source": [ "We also make a pointer to the target area modifier and add it to the simulator.\n", @@ -460,7 +460,7 @@ { "cell_type": "code", "execution_count": null, - "id": "65a9a66b", + "id": "31eab391", "metadata": {}, "outputs": [], "source": [ @@ -470,7 +470,7 @@ }, { "cell_type": "markdown", - "id": "d12d2bb4", + "id": "f4e62725", "metadata": {}, "source": [ "We now create one or more CellPopulationBoundaryConditions, which determine any conditions which each cell in a cell population must satisfy.\n", @@ -485,7 +485,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b1b39cf7", + "id": "b98ee25b", "metadata": {}, "outputs": [], "source": [ @@ -495,7 +495,7 @@ }, { "cell_type": "markdown", - "id": "8f1671db", + "id": "b45c6346", "metadata": {}, "source": [ "We can now make a PlaneBoundaryCondition (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", @@ -505,7 +505,7 @@ { "cell_type": "code", "execution_count": null, - "id": "09c97391", + "id": "0ff6476a", "metadata": {}, "outputs": [], "source": [ @@ -514,7 +514,7 @@ }, { "cell_type": "markdown", - "id": "03b9d30c", + "id": "1c562b7d", "metadata": {}, "source": [ "We now create one or more CellKillers, which determine how cells are removed from the simulation.\n", @@ -527,7 +527,7 @@ { "cell_type": "code", "execution_count": null, - "id": "98fb0f4e", + "id": "5f9c419c", "metadata": {}, "outputs": [], "source": [ @@ -537,7 +537,7 @@ }, { "cell_type": "markdown", - "id": "599aca20", + "id": "ab554989", "metadata": {}, "source": [ "Finally we now make a PlaneBasedCellKiller (passing the point and normal to the plane) and pass it to the OffLatticeSimulation.\n", @@ -547,7 +547,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d49f5d64", + "id": "d2747096", "metadata": {}, "outputs": [], "source": [ @@ -556,7 +556,7 @@ }, { "cell_type": "markdown", - "id": "624ffd8e", + "id": "7bd62315", "metadata": {}, "source": [ "To run the simulation, we call `Solve()`.\n", @@ -570,7 +570,7 @@ { "cell_type": "code", "execution_count": null, - "id": "29ae9b5f", + "id": "5c194b6b", "metadata": {}, "outputs": [], "source": [ diff --git a/infra/GenerateWikiPages.py b/infra/GenerateWikiPages.py index 10245fe9..ec2ca546 100755 --- a/infra/GenerateWikiPages.py +++ b/infra/GenerateWikiPages.py @@ -37,46 +37,59 @@ This script converts Python tutorials to markdown and jupyter notebook formats for use on the PyChaste website. """ +import argparse import fnmatch -import os -import sys import ntpath +import os import subprocess -if __name__ == '__main__': - output_format = "" - - if len(sys.argv) > 1: - output_format = sys.argv[1] - - if output_format not in ["markdown", "jupyter"]: - output_format = "markdown" +if __name__ == "__main__": + parser = argparse.ArgumentParser(prog="GenerateWikiPages") + parser.add_argument( + "--format", + type=str, + choices=["markdown", "jupyter"], + default="markdown", + const="all", + nargs="?", + help="output format", + ) + args = parser.parse_args() # Find all the tutorial files. tutorial_files = [] - for root, dirs, files in os.walk('../test'): + for root, dirs, files in os.walk("../test"): for file in files: - if fnmatch.fnmatch(file, 'Test*LiteratePaper*') or fnmatch.fnmatch(file, 'Test*Tutorial*'): - if not fnmatch.fnmatch(file, '*.pyc'): + if fnmatch.fnmatch(file, "Test*LiteratePaper*") or fnmatch.fnmatch( + file, "Test*Tutorial*" + ): + if not fnmatch.fnmatch(file, "*.pyc"): tutorial_files.append([root, file]) - - if output_format == "markdown": - + + if args.format == "markdown": # Generate the markdown for each for eachFile in tutorial_files: - outfile = "../doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".md" + outfile = ( + "../doc/tutorials/" + + os.path.splitext(ntpath.basename(eachFile[1]))[0] + + ".md" + ) inputfile = eachFile[0] + "/" + eachFile[1] launch_string = f"../infra/CreateMarkdownTutorial.py {inputfile} {outfile}" os.system(launch_string) - - elif output_format == "jupyter": - + + elif args.format == "jupyter": # Generate the jupyter notebooks for each for eachFile in tutorial_files: - outfile = "../doc/tutorials/" + os.path.splitext(ntpath.basename(eachFile[1]))[0] +".ipynb" + outfile = ( + "../doc/tutorials/" + + os.path.splitext(ntpath.basename(eachFile[1]))[0] + + ".ipynb" + ) inputfile = eachFile[0] + "/" + eachFile[1] - launch_string = f"../infra/CreateJupyterNotebookTutorial.py {inputfile} {outfile}" + launch_string = ( + f"../infra/CreateJupyterNotebookTutorial.py {inputfile} {outfile}" + ) os.system(launch_string) - - subprocess.call(f"jupyter nbconvert --to notebook {outfile}", shell=True) + subprocess.call(f"jupyter nbconvert --to notebook {outfile}", shell=True) From c548be0d104731ed10eeca11c8c91849331d8cc6 Mon Sep 17 00:00:00 2001 From: Kwabena N Amponsah Date: Tue, 28 Nov 2023 03:55:38 +0000 Subject: [PATCH 3/3] Fix pychaste markdown artifact dl path --- .github/workflows/update-pychaste-tutorials.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-pychaste-tutorials.yml b/.github/workflows/update-pychaste-tutorials.yml index 3e224ce0..e20ee15f 100644 --- a/.github/workflows/update-pychaste-tutorials.yml +++ b/.github/workflows/update-pychaste-tutorials.yml @@ -44,10 +44,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Download pychaste-tutorials markdown + - name: Download pychaste-tutorials-markdown uses: actions/download-artifact@v3 with: - name: pychaste-tutorials markdown + name: pychaste-tutorials-markdown - name: Checkout website repository uses: actions/checkout@v4