Back to the student project listing page


powered by NetLogo

view/download model file: Cornea_Patch_Formation.nlogo

WHAT IS IT?

This is a work-in-progress that seeks to understand how mosaic patches in mouse corneas arrange themselves into spirals. In part, it seeks to demonstrate the limitations of the current "stem-cell model", which argues that the pattern results from preferential placement of stem cells at the periphery, coupled to centripetal migration.

The yellow represents the parts of the mouse cornea that do not contain labeled clones, i.e., there are cells there but they are not visible. The white ring around the periphery is the limbus, a putative stem cell niche. The dark blue circles within the ring represent stem cells that serve as the sole provider of new "mosaic cells" (leaf shape, a representative cluster of ~16 cells) that ultimately migrate towards the center. Pacemaker cells have the same shape but they are red and have independent adjustable controllers. The cells move based on their ability to respond to a chemical that are secreted periodically by the population. Their rhythm can be entrained but only during a window when they are not secreting.

The rules were inspired by coupled-oscillator and Dictyostelium literature.


HOW IT WORKS

Cells are assigned an intrinsic energy variable (energy-level) that decreases with each tick according to the age-rate. Once that number reaches 0, the cell disappears/dies. Cells are replenished only through a constant stream of new daughters provided by stem cells.

The migration direction is initially recognized by mosaic cells through a patch value that is coupled to the chemical value secreted by both mosaics and pacemakers.

Mosaic cells move based on three parameters: sniff-angle, value-threshold and sniff-distance. Sniff-angle represents the angle the mosaic cell can sense a value. Value-threshold represents the amount necessary to respond. Sniff-distance is the number of patches ahead the mosaic cell can sense.

The primary difference between mosaics and pacemakers is that they have independent adjustable parameters for cycle and secretion length. Although there is no restriction in this model, pacemakers are generally believed to have a faster cycle.


HOW TO USE IT

NUMBER: sets the number of initial mosaic population

STEM-NUMBER: sets the number of initial stemcells population

SNIFF-ANGLE: sets the degree cone-angle with respect to current heading moving cells detect chemical. Also determines the angle the cell will turn after it determines the
highest concentration value.

SNIFF-DISTANCE: sets the point distance from current position cell can detect chemical

ENERGY-LEVEL: sets the initial amount of energy cells possess. This number is spread out over a range so that cells don't die all at once.

AGE-RATE: sets the rate at which cells lose energy.

DRAW-FRAME: draws a wire-frame for assigning positions

CLEAR-FRAME: clears drawings

PARALLELS: sets the number of parallel wires to be drawn

MERIDIANS: sets the number of meridian lines to be drawn

DRAW-SQUARE-FRAME: draws square vertical and horizontal tangents to parallel lines for estimating fractal dimension using a box counting method.

CHEMICAL-CONCENTRATION: sets the amount of chemical secreted with each tick

EVAP-RATE: sets the rate at which chemical is lost

SNIFF-THRESHOLD: sets the amount of chemical required to attract cell movement

FLASHES-TO-RESET: sets the minimum number of secreting neighboring cells required to reset the clock

CYCLE-LENGTH: sets the length of one period

FLASH-LENGTH: sets the duration during cycle in which cells are secreting, which is also the time in which they are refractory to resetting of their cycle.

COUNT-BOXES: reports the number of boxes that cover the periphery.

PACEMKR-RATIO: sets a proportional value with respect to the NUMBER slider to genereate pacemakers cells from the extant mosaic population.

PACEMAKER-LENGTH: sets the period of the pacemaker cell

PACEMAKER-FLASH: sets the duration a pacemaker is secreting

ON-OFF SHOW-CELLS?: gives choice as to whether you want the cells to be visible.

TOTAL-CELL-CLUSTERS: gives a report of how many cell clusters are present.


THINGS TO NOTICE

How do cells behave at the periphery?
How do cells behave near the center?


THINGS TO TRY

Try different values to synchronize flashes. How do combinations affect the turtles' movement, formation and shape of clumps?

Try to figure out a way to change the shape of the chemical concentration curve near the center. How does this affect the shape of cell clusters.

What effect does sniff-angle have?

What effect does lowering chemical concentration to 0 have?


EXTENDING THE MODEL

Try adding some adhesion rules. What effect will this have?
How about changing the shape of the cornea (changing value)?


RELATED MODELS

Ants use a similar idea of creatures that both drop chemical and follow the gradient of the chemical.

Synchrony and movement algorithms were borrowed from the Firefly model.


CREDITS AND REFERENCES

This model was developed at the MIT Media Lab using CM StarLogo. See Resnick, M. (1994) "Turtles, Termites and Traffic Jams: Explorations in Massively Parallel Microworlds." Cambridge, MA: MIT Press. Adapted to StarLogoT, 1997, as part of the Connected Mathematics Project. Adapted to NetLogo, 2000, as part of the Participatory Simulations Project.

To refer to this model in academic publications, please use: Wilensky, U. (1997). NetLogo Slime model. http://ccl.northwestern.edu/netlogo/models/Slime. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.

In other publications, please use: Copyright 1997 Uri Wilensky. All rights reserved. See http://ccl.northwestern.edu/netlogo/models/Slime for terms of use.

Goodwin BC, Cohen MH. (1969). A phase-shift model for the spatial and temporal organization of developing systems. J Theor Biol. 25(1):49-107.

Dallon JC, Othmer HG. (1997). A discrete cell model with adaptive signalling for aggregation of Dictyostelium discoideum. Philos Trans R Soc Lond B Biol Sci. 352(1351):391-417.

Buck, John. (1988). Synchronous Rhythmic Flashing of Fireflies. The Quarterly Review of Biology, September 1988, 265 - 286.


PROCEDURES

breed [apex]
breed [stemcells stemcell ]
breed [mosaics mosaic ]
breed [pacemakers pacemaker]
patches-own [ chemical value ]
globals [radius totals secreting]
breed [ drawers drawer ]
drawers-own [amount-to-move]
breed [liners]
;breed [slougher]
mosaics-own
[ energy
  clock        ;; each cell's clock
  threshold    ;; the clock tick at which the cell stops secreting
  reset-level  ;; the clock tick a cell will reset to when it is triggered by other secretions
  window       ;; a cell can't reset its cycle if (clock <= window)
]
pacemakers-own [clock threshold energy reset-level window ]

to setup
  ca
  ;;to draw the cornea with mosaic cells on it...
   create-apex 1 [setxy 0 0 set color yellow  ]
  ask apex
  [ ask n-of number patches in-radius 40
      [sprout-mosaics 1 ] ]
  ask mosaics [
    initialize-mosaic 
    ]
  ;; Give some proportional value to cornea with respect to distance from center.
  ;; This is largely responsible for centripetal migration but I couldn't get the majority
  ;; of cells to move to the middle without it.
 ask patches    
  [ let center distancexy 0 0 set value (scale-color yellow center 40 -20) * ( 1 / 20)] 
  ;;   color background of cornea (this region has cells that are not visible)
  ask patches
        [ let center distancexy 0 0 set pcolor scale-color yellow center 40 -10 ] 
  ;; Generate stemcells at the limbus...
  set radius max-pxcor - 10
  create-ordered-stemcells stem-number 
 ask stemcells [ set color 88 fd radius set size 3 set shape "circle" 
   ]
 ask n-of ( 0.4 * stem-number ) stemcells [set color 101 ]
 ;; Create a boundary so that cells don't fly off into space
 ask patches with [distancexy 0 0 > max-pxcor - 10] [ set pcolor grey]
 update-plots
 ask apex [die] 
   system-dynamics-setup
  system-dynamics-do-plot
end

  ;;  Give some characters to mosaics...
to initialize-mosaic
  set energy random 200 + energy-level
  let center distancexy 0 0 set color scale-color 101 center 50 -10  
  set size 3 set shape "leaf" 
  ;; give them a timing property
  set clock random (round cycle-length)
  ;; and assign a boundary under which they can secrete chemical and over which 
  ;; they are sensitive to clock resetting.  (These are borrowed from "Firefly" model.)
  set threshold flash-length
  set reset-level threshold
  set window -1
end

;;  ____________________________________________________________________________________________________________________________________

to go
  ask mosaics [move reset rechemical kill-crowd camouflage recolor-mosaics ]
    diffuse chemical 1
  ;; To allow emergence of pacemakers from mosaics to represent the result of change in excitability
  ask (n-of (pacemkr-ratio * 100) mosaics )
  [ if random 100 < 10
  [ hatch 1 [ set breed pacemakers set color red initialize-pacemaker ]]]
  ask pacemakers [ move reset rechemical kill-crowd camouflage recolor ]
  check
  ;; Scale evaporation according to distance from center.  This is a scaling due to 
  ;; the fact that the view is curved and so there appears to be more cells at the periphery
  ;; when they should be equally dispersed.  
  ask patches [ifelse distancexy 0 0 != 0 [set chemical chemical * evap-rate * (1 / sqrt distancexy 0 0)]
                                     [set chemical chemical * evap-rate ]]   ;; evaporate chemical]
  ask patches [ set-boundaries]
  diffuse chemical 1
  set totals count mosaics
  update-plots
  ;; Comment out "color-patches-by-chemical" for different view
  color-patches-by-chemical
    system-dynamics-go
  system-dynamics-do-plot
  tick
end

to initialize-pacemaker
  set shape "leaf" set size 3 set color red
    let center distancexy 0 0 set color scale-color red center 50 -10 
  move
  set clock random (round pacemaker-length) 
  set energy random energy-level + 200
  set threshold pacemaker-flash
  set reset-level threshold
  set window -1
end

 ;  To show distributions of chemicals...
to color-patches-by-chemical
  let max-chemical 2 ; max [chemical] of patches
  let min-chemical 0 ;min [chemical] of patches 
   ask patch 0 0
  [ ask patches in-radius radius
     [
       set pcolor scale-color yellow chemical (min-chemical - 0.0001) (max-chemical + 0.0001)
     ]
  ]
end


to move ;; both mosaics and pacemakers do this...  
          if value > 0.1          
       [ turn-toward-value
         ifelse ( distancexy 0 0 ) != 0 [fd ((1 / 3) * (1 / sqrt distancexy 0 0))  ] [fd 1]] 
     if chemical > sniff-threshold                  ;; ignore pheromone unless there's enough here
      [ turn-toward-chemical 
        ifelse ( distancexy 0 0 ) != 0 [fd ((1 / 3) * (1 / sqrt distancexy 0 0))  ] [fd 1 / 3]]
     if neighbors = grey 
       [ facexy 0 0 rt random sniff-angle lt random sniff-angle fd ((1 / 3) * (1 / sqrt distancexy 0 0))  ]
     set energy energy - age-rate
     if energy <= 0 [ die ]
     if distancexy 0 0 > radius [ die ] 
end


to reset  ;;  turtle procedure to allow resetting of clocks
    if (clock < threshold)
    [ set secreting 10  
      set chemical chemical + chemical-concentration * (1 / sqrt distancexy 0 0) ] 
      if ( (clock > window) and (clock >= threshold) )
      [ look ]
          if (clock >= threshold) [ set secreting 0 ]
    increment-clock
end


to look ; turtle procedure
  if count turtles in-radius 1 with [ secreting = 10 ] >= flashes-to-reset
    [ set clock reset-level ]
end
 
;to slough
;   let density = [count turtles in-radius 1] 
;  if density > 4 [ set breed slougher set color green ]
;end

to camouflage
  ;; To see only the gradient...
  ifelse show-cells? 
  [st]
  [ht]
end

to recolor
  let pale distancexy 0 0 
  set color scale-color red pale 50 -10
end

to recolor-mosaics
  let center distancexy 0 0 set color scale-color 101 center 50 -10 
end

to increment-clock ; turtle procedure
  set clock (clock + 1)
  if clock = cycle-length
    [ set clock 0 ]
end

to set-boundaries
  if pcolor = grey [set chemical chemical * 0]
end

to-report crowding
  report count turtles in-radius 1
end

to kill-crowd
   if crowding > 10 [ die ]
end


to rechemical
    if (clock < threshold)
    [ 
      set chemical chemical + chemical-concentration * (1 / sqrt distancexy 0 0) ] 
end

to check
  ask n-of 30 stemcells with [ color = 101 ] 
  [  hatch-mosaics 1 [ 
      initialize-mosaic
        let center distancexy 0 0 set color scale-color 101 center 50 -10
      facexy 0 0 rt random 90 lt random 90 fd ((1 / 3) * (1 / sqrt distancexy 0 0)) 
      ] 
  ]
  diffuse chemical 1
end

  to turn-toward-chemical  ;; turtle procedure
  ;; examine the patch ahead of you and two nearby patches;
  ;; turn in the direction of greatest chemical
  let ahead 0
  let myright 0
  let myleft 0
  let sniffed-patch patch-ahead sniff-distance
  if sniffed-patch != nobody [
    set ahead [chemical] of sniffed-patch
  ]
  set sniffed-patch patch-right-and-ahead sniff-angle sniff-distance
  if sniffed-patch != nobody [
    set myright [chemical] of sniffed-patch
  ]
  set sniffed-patch patch-left-and-ahead sniff-angle sniff-distance
  if sniffed-patch != nobody [
    set myleft [chemical] of sniffed-patch
  ]
  ifelse (myright >= ahead) and (myright >= myleft)
  [ rt sniff-angle ]
  [ if myleft >= ahead
    [ lt sniff-angle ] ]
end

  to turn-toward-value  ;; turtle procedure
  ;; examine the patch ahead of you and two nearby patches;
  ;; turn in the direction of greatest chemical
  let ahead 0
  let myright 0
  let myleft 0
  let sniffed-patch patch-ahead 1
  if sniffed-patch != nobody [
    set ahead [value] of sniffed-patch
  ]
  set sniffed-patch patch-right-and-ahead sniff-angle sniff-distance
  if sniffed-patch != nobody [
    set myright [value] of sniffed-patch
  ]
  set sniffed-patch patch-left-and-ahead sniff-angle sniff-distance
  if sniffed-patch != nobody [
    set myleft [value] of sniffed-patch
  ]
  ifelse (myright >= ahead) and (myright >= myleft)
  [ rt sniff-angle / 2 ]
  [ if myleft >= ahead
    [ lt sniff-angle / 2 ] ]
end

to update-plots 
  set-current-plot "total-cell-clusters"
  set-current-plot-pen "mosaics"
  plot count mosaics 
  set-current-plot-pen "pacemakers"
  plot count pacemakers
end


to draw-frame
  let num-drawers parallels
  let polygon-num-sides 60
  create-drawers num-drawers [
    set heading 90
    set color white
  ]
  let i 0
  foreach sort drawers [
    ask ? [
      set ycor scale-it i
    ]
    set i i + 1
  ]
  ask drawers [
    pd
  ]
  ask drawers [
    set amount-to-move 2 * distancexy 0 0 * (tan ((360 / polygon-num-sides) / 2))
  ]
  ask drawers [
    back amount-to-move / 2
  ]
  ask drawers [
    repeat polygon-num-sides [
      fd amount-to-move
      rt 360 / polygon-num-sides
    ]
  ]
    create-ordered-liners meridians [fd 3]
  ask liners [pd set color white]
  ask liners [fd radius - 2]
  ask liners [die]
  ask drawers [ die ]
end

to draw-square-frame
  let num-drawers 2 * parallels
  create-drawers num-drawers [
    set heading 90
    set color white
  ]
  let i 0 - parallels
  foreach sort drawers [
    ask ? [
      set ycor scale-it i
    ]
    set i i + 1
  ]  
  ask drawers [
    pd
    bk 100
    fd 100
  ]
  ask drawers [ set heading 0 ]
  set i 0 - parallels
  foreach sort drawers [
    ask ? [
      set xcor scale-it i
    ]
    set i i + 1
  ]  
  ask drawers [
    pd
    bk 100
    fd 100
  ]
  ask drawers [die]
end

to-report scale-it [ i ]
    report radius * sin (90 * i / parallels)
end
to-report inverse-scale-it [ x ]
  report asin (x / radius) * parallels / 90
end

to-report get-fractal-boxes-list 
  let boxlist []
  ask turtles [
    if (distancexy 0 0 < radius - 0.5)
    [
      let myposition (list (floor inverse-scale-it xcor) (floor inverse-scale-it ycor))
      set boxlist fput myposition boxlist 

; to check more points on the leaf (instead of just the center, as above), you can add more 
; points to the boxlist, with offsets from the xcor and ycor      
      set myposition (list (floor inverse-scale-it xcor) (floor inverse-scale-it (ycor + 0.5)))
      set boxlist fput myposition boxlist 

      set myposition (list (floor inverse-scale-it (xcor - 0.5)) (floor inverse-scale-it (ycor + 0.5)))
      set boxlist fput myposition boxlist 
      
      set myposition (list (floor inverse-scale-it (xcor + 0.5)) (floor inverse-scale-it (ycor + 0.5)))
      set boxlist fput myposition boxlist 
            
      set myposition (list (floor inverse-scale-it (xcor + 0.5)) (floor inverse-scale-it (ycor - 0.5)))
      set boxlist fput myposition boxlist
            
      set myposition (list (floor inverse-scale-it (xcor - 0.5)) (floor inverse-scale-it (ycor - 0.5)))
      set boxlist fput myposition boxlist
      
      set myposition (list (floor inverse-scale-it xcor) (floor inverse-scale-it (ycor + 0.25)))
      set boxlist fput myposition boxlist 

      set myposition (list (floor inverse-scale-it (xcor - 0.25)) (floor inverse-scale-it (ycor + 0.25)))
      set boxlist fput myposition boxlist 
      
      set myposition (list (floor inverse-scale-it (xcor + 0.25)) (floor inverse-scale-it (ycor + 0.25)))
      set boxlist fput myposition boxlist 
            
      set myposition (list (floor inverse-scale-it (xcor + 0.25)) (floor inverse-scale-it (ycor - 0.25)))
      set boxlist fput myposition boxlist
            
      set myposition (list (floor inverse-scale-it (xcor - 0.25)) (floor inverse-scale-it (ycor - 0.25)))
      set boxlist fput myposition boxlist
      
      set myposition (list (floor inverse-scale-it xcor) (floor inverse-scale-it (ycor + 0.1)))
      set boxlist fput myposition boxlist 

      set myposition (list (floor inverse-scale-it (xcor - 0.1)) (floor inverse-scale-it (ycor + 0.1)))
      set boxlist fput myposition boxlist 
      
      set myposition (list (floor inverse-scale-it (xcor + 0.1)) (floor inverse-scale-it (ycor + 0.1)))
      set boxlist fput myposition boxlist 
            
      set myposition (list (floor inverse-scale-it (xcor + 0.1)) (floor inverse-scale-it (ycor - 0.1)))
      set boxlist fput myposition boxlist
            
      set myposition (list (floor inverse-scale-it (xcor - 0.1)) (floor inverse-scale-it (ycor - 0.1)))
      set boxlist fput myposition boxlist
    ]
  ]
  report (remove-duplicates boxlist)
end

to-report count-boxes
  let oldboxlist get-fractal-boxes-list
  let newboxlist []
  foreach oldboxlist
  [
    let myx first ?
    let myy last ?
    let neighborcount 0
    foreach [ -1 0 1 ]
    [
      let xchange ?
      foreach [ -1 0 1 ]
      [
        let ychange ?
        if member? (list (myx + xchange) (myy + ychange)) oldboxlist [
          set neighborcount neighborcount + 1
        ]
      ]
    ]
    ;print (word ? " has " neighborcount " neighbors")
    if (neighborcount != 9)
    [
      set newboxlist fput ? newboxlist
    ]
  ]
  report length newboxlist 
end

to clear-frame
  clear-drawing
end