Neuromast Regeneration in Zebrafish
Persistent Identifier
Use this permanent link to cite or share this Morpheus model:
Neuromast regeneration in zebrafish larvae with local control of cell proliferation following severe ablation
Introduction
Neuromasts of zebrafish (Danio rerio) larvae regenerate robustly after the loss of up to 90-95 % of their cells. Following severe laser-mediated ablation, the organ restores its radial architecture and proportional composition of hair cells, sustentacular cells, and mantle cells within seven days.
How cells sense tissue damage and terminate proliferation once the correct organ size is re-established remains an open question.
This model investigates whether neuromast regeneration can emerge from purely local cell-cell interactions without requiring global regulatory signals.
Description
We implemented a two-dimensional Cellular Potts Model (CPM) to represent the neuromast epithelium. The uninjured neuromast is modeled as a 2D disc of cells, respecting experimentally measured cell numbers, spatial organization, area, and perimeter for hair, sustentacular, and mantle cells.
Cell-cell adhesion energies ($J$ parameters) were calibrated to obtain a stable configuration reproducing the characteristic radial organization of the intact organ. Target area ($A_\text T$) and perimeter ($P_\text T$) values were estimated by averaging measurements from experimental images across all cells of the same type.
The Monte Carlo time scale was calibrated using experimental proliferation dynamics.
Regeneration simulations are initialized from experimentally reconstructed post-ablation configurations, reflecting the reduced number and spatial distribution of surviving cells.
Cell proliferation is implemented as a stochastic process with experimentally derived fate probabilities. Sustentacular cells generate sustentacular, hair, or mantle cells depending on their radial position, while mantle cells divide symmetrically to self-renew.
A key feature of the model is a cell-type specific proliferation switch:
- Sustentacular cells stop dividing when they reach three neighboring sustentacular cells.
- Mantle cells stop dividing when they reach one neighboring mantle cell.
To ensure smooth relaxation from the initial condition, Lagrange multipliers associated with area and perimeter constraints are introduced as time-dependent parameters. After an initial transient, these parameters converge to constant values and no longer influence long-term dynamics.
Model Hypothesis
The central hypothesis is that local feedback mediated by the number of homotypic neighbors is sufficient to regulate regenerative proliferation and restore organ proportionality.
Results
Simulations quantitatively and qualitatively reproduce key experimental observations, including:
- Transient regenerative proliferation
- Recovery of correct cell-type proportions
- Stabilization of organ size
- Isotropic regeneration after asymmetric ablation
- Neighborhood statistics prior to division
The model demonstrates that local negative feedback on proliferation is sufficient to generate robust organ-level regeneration.
model.xml demonstrating image-based initialization of a neuromast from experimental TIFF files
Reference
This model is the original used in the publication, up to technical updates:
N. G. Lavalle, J. Miranda-Rodríguez, E. C. Costa, A. Borges, O. Viader-Llargués, H. López-Schier, O. Chara: Local control of cellular proliferation underlies neuromast regeneration in zebrafish. J. Theor. Biol. 623: 112389, 2026.
Model
model.xml
XML Preview
<MorpheusModel version="4">
<Time>
<StartTime value="0"/>
<StopTime value="65000" symbol="stoptime"/>
<TimeSymbol symbol="time"/>
<RandomSeed value="76"/>
</Time>
<Description>
<Title>M4377 CPM model of neuromast regeneration in zebrafish with local control of cell proliferation starting with experimental TIFF</Title>
<Details>Model ID: https://identifiers.org/morpheus/M4377
Software: Morpheus (open source). Download from: https://morpheus.gitlab.io
Full title: Neuromast Regeneration in Zebrafish
Authors: N. G. Lavalle, J. Miranda-Rodríguez, E. C. Costa, A. Borges, O. Viader-Llargués, H. López-Schier, O. Chara
Submitter: N. G. Lavalle
Curator: D. Jahn
Date: 04.03.2026
Reference: This model is the original used in the publication, up to technical updates:
N. G. Lavalle, J. Miranda-Rodríguez, E. C. Costa, A. Borges, O. Viader-Llargués, H. López-Schier, O. Chara: Local control of cellular proliferation underlies neuromast regeneration in zebrafish. J. Theor. Biol. 623: 112389, 2026.
https://doi.org/10.1016/j.jtbi.2026.112389
Comment: This Morpheus XML model implements a 2D simulation based on the Cellular Potts Model (CPM) to study neuromast regeneration in Danio rerio (zebrafish) larvae following severe ablation. The simulation is initialized from experimentally acquired images, which define the initial spatial configuration and reduced number of surviving cells after ablation. Starting from this image-based initial condition, the model reproduces organ regeneration through divisions of sustentacular and mantle cells. The core mechanism of the model is a local control of proliferation based on cell neighborhood: each cell capable of dividing (sustentacular or mantle) halts its cell cycle when it reaches a critical number of neighboring cells of the same type. Specifically, sustentacular cells stop proliferating when they contact 3 neighboring sustentacular cells, while mantle cells do so when surrounded by 1 neighboring mantle cell. This mechanism reproduces both the regenerative dynamics and the spatial architecture of the organ observed experimentally.</Details>
</Description>
<Space>
<Lattice class="square">
<Size value="800,800,0" symbol="size"/>
<Neighborhood>
<Order>3</Order>
</Neighborhood>
</Lattice>
<SpaceSymbol symbol="space"/>
</Space>
<Global>
<Variable value="0.0" symbol="sum_cell_center_y"/>
<Variable value="0.0" symbol="sum_cell_center_x"/>
<Variable value="0" symbol="tau"/>
<Mapper>
<Input value="cell.center.y"/>
<Output mapping="sum" symbol-ref="sum_cell_center_y"/>
</Mapper>
<Mapper>
<Input value="cell.center.x"/>
<Output mapping="sum" symbol-ref="sum_cell_center_x"/>
</Mapper>
<Function symbol="mean_center_y">
<Expression>sum_cell_center_y/total_cells</Expression>
</Function>
<Function symbol="mean_center_x">
<Expression>sum_cell_center_x/total_cells</Expression>
</Function>
<Function symbol="total_cells">
<Expression>celltype.mantle.size+celltype.hair.size+celltype.sustentacular.size</Expression>
</Function>
<Variable value="0.0" symbol="NumberOfNeighbours"/>
<Variable value="0.0" symbol="Sustentacular_Neighbours"/>
<Variable value="0.0" symbol="HairCell_Neighbours"/>
<Variable value="0.0" symbol="Mantle_Neighbours"/>
<Variable value="30000" symbol="dia"/>
<Variable value="0.00015" symbol="ps"/>
<Variable value="0.0001" symbol="pm"/>
</Global>
<CellTypes>
<CellType name="mantle" class="biological">
<Property name="color" value="2" symbol="c"/>
<CellDivision division-plane="minor">
<Condition>tau*dia < time and rand_uni(0,1) < pm and Mantle_Neighbours < umbral</Condition>
<Triggers>
<Rule symbol-ref="umbral">
<Expression>1</Expression>
</Rule>
</Triggers>
</CellDivision>
<Property value="1" symbol="umbral"/>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.mantle.id"/>
<Output mapping="sum" symbol-ref="Mantle_Neighbours"/>
</NeighborhoodReporter>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.hair.id"/>
<Output mapping="sum" symbol-ref="HairCell_Neighbours"/>
</NeighborhoodReporter>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.sustentacular.id"/>
<Output mapping="sum" symbol-ref="Sustentacular_Neighbours"/>
</NeighborhoodReporter>
<Property value="0.0" symbol="Sustentacular_Neighbours"/>
<Property value="0.0" symbol="Mantle_Neighbours"/>
<Property value="0.0" symbol="HairCell_Neighbours"/>
<VolumeConstraint strength="time^2/(1000^2+time^2)" target="1643"/>
<SurfaceConstraint strength="time^2/(2000^2+time^2)" mode="surface" target="213"/>
</CellType>
<CellType name="sustentacular" class="biological">
<Property name="color" value="1" symbol="c"/>
<ChangeCellType newCellType="hair">
<Condition>p == 1</Condition>
<Triggers>
<Rule symbol-ref="c">
<Expression>0</Expression>
</Rule>
</Triggers>
</ChangeCellType>
<ChangeCellType newCellType="mantle">
<Condition>p == 2</Condition>
<Triggers>
<Rule symbol-ref="c">
<Expression>2</Expression>
</Rule>
<Rule symbol-ref="umbral">
<Expression>1</Expression>
</Rule>
</Triggers>
</ChangeCellType>
<ChangeCellType newCellType="mantle">
<Condition>p == 3 and s == 1</Condition>
<Triggers>
<Rule symbol-ref="c">
<Expression>2</Expression>
</Rule>
<Rule symbol-ref="umbral">
<Expression>1</Expression>
</Rule>
</Triggers>
</ChangeCellType>
<CellDivision division-plane="random">
<Condition>(tau*dia < time) and (rand_uni(0,1) < ps )and (Sustentacular_Neighbours < umbral) and (r<=a)</Condition>
<Triggers name="Division Sustentacular center">
<Rule symbol-ref="p">
<Expression>if(d<0.594,0,1) </Expression>
</Rule>
</Triggers>
</CellDivision>
<CellDivision division-plane="random" daughterID="daughter">
<Condition>(tau*dia < time) and (rand_uni(0,1) < ps ) and (Sustentacular_Neighbours < umbral) and (r>a)</Condition>
<Triggers>
<Rule symbol-ref="s">
<Expression>if(daughter == 1, 1, 0 )</Expression>
</Rule>
<Rule symbol-ref="p">
<Expression>if(d < 0.9,0,if((0.9<=d) and (d< 0.95),2,3))</Expression>
</Rule>
</Triggers>
</CellDivision>
<Function symbol="r">
<Expression>sqrt((cell.center.x-mean_center_x)^2+(cell.center.y-mean_center_y)^2)</Expression>
</Function>
<Constant value="95 " symbol="a"/>
<Property value="3" symbol="umbral"/>
<Property value="0.0" symbol="p"/>
<Property value="0" symbol="d"/>
<Property value="0.0" symbol="s"/>
<Property value="0.0" symbol="HairCell_Neighbours"/>
<Property value="0.0" symbol="Mantle_Neighbours"/>
<Property value="0.0" symbol="Sustentacular_Neighbours"/>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.sustentacular.id"/>
<Output mapping="sum" symbol-ref="Sustentacular_Neighbours"/>
</NeighborhoodReporter>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.hair.id"/>
<Output mapping="sum" symbol-ref="HairCell_Neighbours"/>
</NeighborhoodReporter>
<NeighborhoodReporter>
<Input scaling="cell" value="cell.type == celltype.mantle.id"/>
<Output mapping="sum" symbol-ref="Mantle_Neighbours"/>
</NeighborhoodReporter>
<System solver="Runge-Kutta [fixed, O(4)]" time-step="1.0">
<Rule symbol-ref="d">
<Expression>rand_uni(0,1)</Expression>
</Rule>
</System>
<VolumeConstraint strength="time^2/(1000^2+time^2)" target="1579"/>
<SurfaceConstraint strength="time^2/(2000^2+time^2)" mode="surface" target="177"/>
</CellType>
<CellType name="hair" class="biological">
<Property name="color" value="0" symbol="c"/>
<VolumeConstraint strength="time^2/(1000^2+time^2)" target="2597"/>
<SurfaceConstraint strength="time^2/(2000^2+time^2)" mode="surface" target="206"/>
</CellType>
<CellType name="medium" class="medium">
<Property value="0.5" symbol="z"/>
<Property value="0" symbol="count"/>
</CellType>
</CellTypes>
<CPM>
<MonteCarloSampler stepper="edgelist">
<MCSDuration value="1"/>
<MetropolisKinetics temperature="10"/>
<Neighborhood>
<Order>2</Order>
</Neighborhood>
</MonteCarloSampler>
<ShapeSurface scaling="norm">
<Neighborhood>
<Order>2</Order>
</Neighborhood>
</ShapeSurface>
<Interaction>
<Contact type2="sustentacular" type1="sustentacular" value="-38"/>
<Contact type2="mantle" type1="sustentacular" value="-36"/>
<Contact type2="hair" type1="sustentacular" value="-40"/>
<Contact type2="medium" type1="sustentacular" value="56"/>
<Contact type2="hair" type1="hair" value="-60"/>
<Contact type2="mantle" type1="hair" value="5"/>
<Contact type2="medium" type1="hair" value="80"/>
<Contact type2="mantle" type1="mantle" value="-45"/>
<Contact type2="medium" type1="mantle" value="-10"/>
</Interaction>
</CPM>
<Analysis>
<Gnuplotter time-step="1000" decorate="false">
<Terminal name="png"/>
<Plot>
<Cells min="0" value="c" max="2">
<ColorMap>
<Color color="magenta" value="2"/>
<Color color="spring-green" value="1"/>
<Color color="gold" value="0"/>
</ColorMap>
</Cells>
</Plot>
</Gnuplotter>
<ModelGraph format="dot" reduced="false" include-tags="#untagged"/>
<!-- <Disabled>
<Logger name="number_cell_vs_time" time-step="1">
<Input>
<Symbol symbol-ref="cell.type"/>
<Symbol symbol-ref="HairCell_Neighbours"/>
<Symbol symbol-ref="Sustentacular_Neighbours"/>
<Symbol symbol-ref="Mantle_Neighbours"/>
<Symbol symbol-ref="celltype.mantle.size"/>
<Symbol symbol-ref="celltype.sustentacular.size"/>
<Symbol symbol-ref="celltype.hair.size"/>
<Symbol symbol-ref="total_cells"/>
</Input>
<Output>
<TextOutput file-name="number_cell_vs_time" file-format="csv"/>
</Output>
</Logger>
</Disabled>
-->
</Analysis>
<CellPopulations>
<Population type="hair" size="1">
<TIFFReader filename="E07_Hair_cells-lbl-fillHoles.tif"/>
</Population>
<Population type="sustentacular" size="1">
<TIFFReader filename="E07_Support_cells-lbl-fillHoles.tif"/>
</Population>
<Population type="mantle" size="1">
<TIFFReader filename="E07_Mantle_cells-lbl-fillHoles.tif"/>
</Population>
</CellPopulations>
</MorpheusModel>
This model requires three external files:
Data Availability
A representative example (model.xml) demonstrating image-based initialization from experimental TIFF files is included in this repository.
All additional model variants corresponding to the experimental conditions analyzed in the study, together with their associated Python-based quantitative analysis pipelines and experimental datasets, are available at Zenodo.
Downloads
Files associated with this model: