Back to the student project listing page


powered by NetLogo

view/download model file: Transcription.nlogo

WHAT IS IT?

**What is this model doing?**

This model is loosely based off of transcription networks and the affect that transcription networks have on the life process of a cell. The model creates a random transcription network, applies rules mimicking cell life, and tests if the network can keep the cell alive past a time limit. If the network does not survive past the time limit, a new random network is generated and the process starts over. Once a network survives the time limit once, the robustness of the network is measured by recording how many times the cell survives ten repeated tests.

By looking at what kinds of networks survive and contrasting them against the other random networks generated we can hope to see trends in which networks are selected for and which networks are selected against.

**What are the nodes in the network?**

Each node represents both a protein and the gene that encodes that protein. So the two main properties of each node are the amount of protein present and the chance that more of that protein will be created. The amounts of each protein are shown on a graph, and the chance of transcription is represented by the size of each node.

**What are the edges in the network?**

(In this model, but not in biology) every protein is a potential transcription factor, which means that it influences the chance another protein is transcribed. Blue (or positive) edges are used to show which proteins increase the chance that another protein is transcribed. Red (or negative) edges show which proteins reduce that chance.

**What are the rules that mimic cell life?**

In this simplified cell, there are three types of proteins: life-critical, metabolism, and blank. The survival of the cell depends on how well it uses its metabolism to create new proteins and how well it balances the transcription chances for each kind of protein.

Every turn, each protein has an equal chance of being degraded. The cell dies if the amount of any life-critical protein drops to zero. The only way to create new proteins is by converting metabolites from one into the other. 'A' is converted into 'B' then into 'C' and then into a new protein. This conversion process is dependent on the amounts of each metabolism protein.


HOW IT WORKS

**Random Network Creation**

There is a fixed chance (chance-of-edge) that an edge will be created from any one node to another node. Whether the edge is either positive or negative is randomly selected based off of a fixed probability (chance-edge-positive).

**Creating new proteins (Cell Metabolism)**

There are three kinds of metabolites 'A', 'B' and 'C' and three metabolism proteins. One protein converts 'A' to 'B', another converts 'B' to 'C', and the last creates new proteins out of 'C'. Each step in this system is calculated in an identical manner.

The quantity of 'A' converted to 'B' in any tick depends on both the amount of metabolism protein and amount of 'A' present. The amount of protein determines how many tries the cell has to convert one 'A' to one 'B'. The amount of 'A' influences the chance that a conversion attempt will succeed.

The chance of conversion is determined by two variables Max-Conv-Chance and Conv-sensitivity.

The type of new protein created is determined by the chance of transcription.

**Calculating the Chance of Transcription**

Every node has a number, called the transcription-number, that is used to calculate the chance of transcription. Every time a protein is transcribed the amount of that protein is increased by one.


X = L + (A + B) * M

Where:
X = Transcription-number
L = transcription-basis
M = regulation-factor
A = The protein amount of all positive transcription factors (from positive inward edges)
B = The protein amount of all negative transcription factors (from negative inward edges)

L and M, the transcription-basis and regulation-factor can be changed from the interface.

Finally when a new protein is created, the chance of any given node transcribing the new protein is:

Y = ( X1 / Xt ) * 100%

Where:
Y = % Chance of transcription for node 1
X1 = Transcription-number for node 1
Xt = Sum of transcription-numbers from all nodes


HOW TO USE IT

Network Generation

- num-nodes - this changes the number of nodes in your network
- chance-of-edge - this changes the chance that a an edge will be going from any one node to another node
- chance-edge-positive - if a new edge is created, this determines the chance that the new edge will be positive

Run Options
General

- time-limit - this is how many ticks the cell needs to survive

- Repeats-Threshold - If the same network is tested 10 times, how many times must a network survive. If the Repeats-Threshold is not met, a new random network will be generated.

- Show-Notifications? - this displays user messages every time it finds a network that has survived.

Protein Options

- initial-protein-amt - this is the starting amount of each type of protein

- degrade-chance - this is the chance that any particular protein will degrade this tick

Metabolism

- feed-rate - how much metabolite 'A' is added every tick

For more information on max-conv-chance and conv-sensitivity, look in the How It Works section

- max-conv-chance - this is the maximum metabolism conversion chance. When there is an excess of 'A' present, each of the proteins that convert 'A' to 'B' will have this chance of converting one 'A' this tick.

- conv-sensitivity - This variable determines how sensitive the conversion chance is to the amount of metabolite. Specifically, this number is the amount of metabolite that will have a conversion chance that is half the size of the maximum conversion chance.

Example:
max-conv-chance = 80%
conv-sensitivity = 10

If there is 100 'A' present, the conversion chance will be close to 80%
If there is 10 'A' present, the conversion chance will be 40%
If there is 1 'A' present, the conversion chance will be close to 2%

Transcription

For more information on regulation-factor and transcription-basis, look in the How It Works section. Both of these variables play a role in how much affect the transcription factors have on the chance of transcription.

- regulation-factor - This controls how strong the regulation from positive and negative edges will be.

- transcription-basis - This controls how easily a node is influenced by regulation from positive and negative edges.


THINGS TO NOTICE

Every aspect of this model depends on random chance to the point where it is often difficult to show any striking trends without running lots of repetitions, recording the results, and analyzing them.

Robust networks typically have repeated fluctuations in the Protein-Amounts Graph.

By looking at the levels of different metabolites, you can tell which metabolism protein was limiting the production of at which part of the simulation. Example: If the levels of 'B' increased, but 'C' stayed consistently low. Than the protein that converted 'B' to 'C' was limiting step in the metabolism.


THINGS TO TRY

By looking at how many tries the model takes to create a stable network,

Change number of nodes. Can you notice a difference in the number of tries the model needs to generate a stable network? How about if you change the regulation factor?

Increasing the number of nodes decreases the chance that a new protein will be a life-critical or a metabolism protein.

By increasing the strength of the regulation factor it should take more tries to create a stable network. This is because most randomly generated networks have a negative effect on survival. By increasing the strength of the edges, you are increasing the negative effects.


EXTENDING THE MODEL

Most of the features I wish I could add have to do with analysis. I would have liked to look at more network properties.

Another great feature would be to create more graph friendly output.


NETLOGO FEATURES

create-temporary-plot-pens


CREDITS AND REFERENCES

By Peter Winter


PROCEDURES

globals
[
  ; variables used to keep track of metabolism in cell
  fooda
  foodb
  foodc
  newprot
  
  ; variables used to keep 
  protein-pens ; a list of all the temporary plot pens
  tries        ; how many attempts the model has made to reach a stable setup.
  
  ; variables used for network analysis
  av-clustering-coef
  component-size          ;; number of turtles explored so far in the current component
  ;giant-component-size    ;; number of turtles in the giant component
  ;giant-start-node        ;; node from where we started exploring the giant component
  
  
  ; for feed forward analysis
  number-of-ff-loops
  number-of-fb-loops
  types-of-ff-loops
  who-in-ff-loops
  who-in-fb-loops
  two-node-ps-feedback
  two-node-ng-feedback
  two-node-dn-feedback
  
  ; to test for robustness
  repeats
  repeats-survived
  try-repeats
]

turtles-own
[
  ;; this is used to mark turtles we have already visited
  ;explored?
  transcription-number
  metabolism
  life-critical
  protein-amt
  check
  clustering-coef
]

 directed-link-breed [positive-edges  positive-edge] ; sjfs
 directed-link-breed [negative-edges  negative-edge] ; dfs

;;;;;;;;;;;;;;;;;;;;;;;;
;;; Setup Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  ca
  set tries 1
  set repeats 1
  set repeats-survived 0
  set try-repeats false
  another-try
end

to another-try
  make-metabolites
  make-turtles
  specialize-turtles
  ;repeat num-edges [make-edges]
  make-edges3
  set protein-pens []
  make-protein-pens
  plot-protein-amount 
end


to make-metabolites
  set fooda 20
  set foodb 30
  set foodc 40
  set newprot 0
  plot-metabolites
end

to make-turtles
  set-default-shape turtles "circle"
  ;set-default-shape links "myarrow"
  crt num-nodes
  [
    set color white
    set protein-amt initial-protein-amt
    set metabolism 0
    set life-critical 0
    set check 0
  ]
  layout-circle turtles max-pxcor - 1
end

to specialize-turtles
  ask turtle 1 [set metabolism 1 set color orange]
  ask turtle 2 [set metabolism 2 set color orange]
  ask turtle 3 [set metabolism 3 set color orange]
  ask turtle 4 [set life-critical 1 set color yellow]
  ask turtle 5 [set life-critical 1 set color yellow]
  ask turtle 6 [set life-critical 1 set color yellow]
end

to rerun-this-setup
    reset-ticks
    ;set tries 1
    set-current-plot "Metabolites"
    clear-plot    
    set-current-plot "Protein-Amounts"
    clear-plot
    set-current-plot "Metabolite-Conversion-Chance"
    clear-plot
    ask turtles [set protein-amt initial-protein-amt]
    set protein-pens []
    make-metabolites
    make-protein-pens
    
end

;;;;;;;;;;;;;;;;;;;;;;
;;; Main Procedure ;;;
;;;;;;;;;;;;;;;;;;;;;;

to go
  ; stop if you've repeated enough
  if tries > 1000
  [
      display
      user-message ( word  "No networks meet your requirements for robustness")
      stop
  ]    
  
  if repeats > 10
  [
        if Show-Notifications? = True
        [
          display
          user-message ( word  "Network survived " repeats-survived " of 10 repeated trials.")
        ]
        
        ; If the network survived a sufficient number of repeats, then stop. If not make new network and try again.
        ifelse repeats-survived >= Repeats-Threshold
        [ stop ]
        [
          reset-ticks
          set-current-plot "Metabolites"
          clear-plot    
          set-current-plot "Protein-Amounts"
          clear-plot
          set-current-plot "Metabolite-Conversion-Chance"
          clear-plot
          clear-links 
          clear-turtles  
          set tries ( tries + 1)
          set repeats 1
          set repeats-survived 0
          set try-repeats false
          another-try
        ]
  ]  
  
  ; time limit check
  if ticks > time-limit
  [
    ; if this is the first time this network survived the time limit, prepare for repeated trials
    ifelse try-repeats = false
    [
      set try-repeats true
      ; since we do 10 trials, there are 9 repeats after the initial sucess.
      ; so I start my repeats counter at 2 and go until it reaches 10
      set repeats 2
      set repeats-survived 1
      ; if the user wants notifications tell him a network survived the time limit.
      if Show-Notifications? = True
      [
        display
        user-message ( word  tries " tries untill network survived. Now checking robustness.")
      ]
      rerun-this-setup
    ]
    ; if this is one of the repeated trials, record sucess, carry on.
    [    
      set repeats (repeats + 1)
      set repeats-survived (repeats-survived + 1)
    ]
  ]

 ; kills the cell if there aren't any life-critical proteins
 if ([protein-amt] of turtle 4) <= 0 or ([protein-amt] of turtle 5) <= 0 or ([protein-amt] of turtle 6) <= 0
 [
    reset-ticks
    set-current-plot "Metabolites"
    clear-plot    
    set-current-plot "Protein-Amounts"
    clear-plot
    set-current-plot "Metabolite-Conversion-Chance"
    clear-plot
    
    ; if this wasn't a repeated trial, try a new network
    if try-repeats = false 
    [
      clear-links 
      clear-turtles  
      set tries ( tries + 1)
      another-try
    ]
    ; if this was a repeated trial, don't record sucess, carry on.
    if try-repeats = true 
    [
      set repeats ( repeats + 1 ) 
      rerun-this-setup
    ]
  ]
    
  ;fooda ( or Metabolite 'A' ) is added
  set fooda (fooda + feed-rate)
  run-metabolism ; this is where all the conversions between metabolites takes place
  plot-metabolites
  plot-protein-amount
  degrade-protein
  ; turtles raise or lower each others transcription chance, degrade some proteins, missing: plot their protein concentrations, 
  ; turtles adjust their size in relation to transcription chance
  ; transcribe-protein. all in this subroutine:
  node-specific-operation
  tick
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Subroutines for Main Procedure ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; every protein from every node rolls a dice to see if it dies.
to degrade-protein
  ask turtles
  [
     let i 0
     ; every protein has the same chance to degrade, so repeat this for every protein
     repeat protein-amt 
     [ 
         if random 100 < degrade-chance 
         [ 
             set i (i + 1) 
             set protein-amt (protein-amt - i)
         ]
     ]
     if protein-amt < 0 [set protein-amt 0]
  ]
  
end


; turtles raise or lower each others transcription chance, degrade some proteins, missing: plot their protein concentrations, 
; turtles adjust their size in relation to transcription chance
; transcribe-protein. all in this subroutine:
to node-specific-operation
  
  ; normalize-to is the sum of all the transcription numbers from every node
  let normalize-to 0
  ; this adjusts chance of transcription
  ask turtles 
  [ 
      let baseline Transcription-Basis
      let j baseline
   
      ask in-positive-edge-neighbors [ set j ( j + (protein-amt  * Regulation-Factor)) ] 
      ask in-negative-edge-neighbors [ set j (j - (protein-amt * Regulation-Factor)) ] 
      if j < 1 [set j 1]
      
      set transcription-number j; not normalized transcription chance not 1 in 100
      set normalize-to (normalize-to + j)
  ]
  
  let l 0
  ; newprot is the number of new proteins that will be created this turn.
  ; for each new protein one node is chosen (based off of transcription chance)
  repeat newprot
  [
    let i 0
    ; choose a random number between 0 and normalize-to. 
    ; then see which node won a  brand new protein 
    let k (random normalize-to)
    while [k > 0]
    [
      set k ( k - ([transcription-number] of turtle i) )
      if k <= 0 [ask turtle i [set protein-amt ( protein-amt + 1 )] ]
      set i (i + 1)
      
    ]
  ]
  set newprot 0
  
  ; this adjusts the size of each node to be proportional to it's chance of transcription
  ask turtles 
  [
     set size 0.1 + num-nodes * 5 * (transcription-number / normalize-to)
  ]
end

to run-metabolism
  let K ( Max-Conv-Chance / 100 ) ;this is production rate at saturation it is set to 90%
  let kp ( 1 / Conv-Sensitivity ) ; this is (1/amt of food) required to have 50% of max conversion. right now it's set to 10
  
  if (fooda < 0 or foodb < 0 or foodc < 0)
  [
    display
    user-message (word "fooda:" fooda " ca:"([protein-amt] of turtle 1) " atob:" floor (K * kp * fooda * 100 / ( 1 + (kp * fooda) )) 
                       " foodb:" foodb " btoc:" floor (K * kp * foodb * 100 / ( 1 + (kp * foodb) ))
                       " foodc:" foodc " ctop:" floor (K * kp * foodc * 100 / ( 1 + (kp * foodc) )))
    stop
  ] 
;  if [protein-amt] of turtle 1 > 0
;  [
      repeat ([protein-amt] of turtle 1)
      [
        if random 100 < floor (K * kp * fooda * 100 / ( 1 + (kp * fooda) ))
        [
           set fooda (fooda - 1)
           set foodb (foodb + 1)    
        ]  
      ]
  ;]
  repeat ([protein-amt] of turtle 2)
  [
    if random 100 < floor (K * kp * foodb * 100 / ( 1 + (kp * foodb) ))
    [
       set foodb (foodb - 1)
       set foodc (foodc + 1)  
    ]  
  ]
  
  repeat ([protein-amt] of turtle 3)
  [
    if random 100 < floor (K * kp * foodc * 100 / ( 1 + (kp * foodc) ))
    [
       set foodc (foodc - 1)
       set newprot (newprot + 1)  
    ]  
  ]
  
  set-current-plot "Metabolite-Conversion-Chance"
  set-current-plot-pen "A to B"
  plot floor (K * kp * fooda * 100 / ( 1 + (kp * fooda) )) 
  set-current-plot-pen "B to C"
  plot floor (K * kp * foodb * 100 / ( 1 + (kp * foodb) )) 
  set-current-plot-pen "C to D"
  plot floor (K * kp * foodc * 100 / ( 1 + (kp * foodc) )) 
  
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Plotting and Visuals ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; THIS IS TAKEN FROM DIFFUSION ON A DIRECTED NETWORK. MAYBE ADD SOMETHING LIKE THIS TO LOOK COOL.
;to update-link-appearance ; link procedure
;  ; scale color to be brighter when more value is flowing through it
;  set color scale-color gray (current-flow / (2 * mean-flow + 0.00001)) -0.4 1
;end

to make-protein-pens
  set-current-plot "Protein-Amounts"
  let i 0
  ask turtles 
  [ 
    
    create-temporary-plot-pen ( word "protein-" i )
    set protein-pens lput ( word "protein-" i ) protein-pens
    set i ( i + 1 )
    if i >= 2 and i <= 4 [set-plot-pen-color orange]
    if i >= 5 and i <= 7 [set-plot-pen-color yellow]
  ]
  
end

to plot-protein-amount
  let amt-index []
  let i 0
  repeat num-nodes
  [ 
      ask turtle i
     [
         set amt-index lput ( protein-amt ) amt-index
     ]
     set i ( i + 1)
  ]  
  ;show amt-index ;to check if working properly
  
  set i 0
  repeat num-nodes
  [        
         set-current-plot "Protein-Amounts"
         set-current-plot-pen (item i protein-pens)
         plot (item i amt-index)
         ;plot-pen-reset
         set i ( i + 1)
  ]
end

to plot-metabolites
  set-current-plot "Metabolites"
  set-current-plot-pen "A"
  plot fooda
  set-current-plot-pen "B"
  plot foodb
  set-current-plot-pen "C"
  plot foodc
  set-current-plot-pen "P"
  plot newprot
  
end


;;;;;;;;;;;;;;;;;;;;;;;
;;; Edge Operations ;;;
;;;;;;;;;;;;;;;;;;;;;;;

;; pick a random missing edge and create it
;to make-edges
;    let node1 one-of turtles
;    let node2 one-of turtles
;    ifelse node1 = node2  ;or out-link-neighbor? node2
;     [ make-edges ]
;     [
;        ifelse random 100 < %positive-regulation
;        [
;          ask node1 
;          [ 
;            ifelse out-link-neighbor? node2 [make-edges]
;            [create-positive-edge-to node2 [set color green]]
;          ]
;        ]
;          [
;          ask node1
;          [ 
;            ifelse out-link-neighbor? node2 [make-edges]
;            [create-negative-edge-to node2 [set color red]]
;          ]
;        ]
;     ]  
;    find-clustering
;end
;to make-edges2
;  let i 0
;  let j 0
;  let node2 one-of turtles
;  repeat (num-nodes - 1) ; last node doesn't need to look for nodes to link to. 
;  [
;     set j 0
;     repeat (num-nodes - i - 1) ; since the node index starts at 0, num-nodes is one larger than the highest index. ie. turtle9 is last turtle for num-nodes = 10.
;     [
;        ask turtle i 
;        [
;            set node2 turtle (num-nodes - j - 1)
;            ;show (word node2 )
;            if random 100 < chance-of-edge
;            [ 
;              ifelse random 100 < %positive-regulation 
;              [create-positive-edge-to node2 [set color blue]]
;              [create-negative-edge-to node2 [set color red ]]
;            ]
;        ]
;        set j (j + 1)
;     ]
;     set i (i + 1)
;     find-clustering
;  ]
;  
;end

to make-edges3
  let i 0
  let j 0
  let node2 one-of turtles
  set-default-shape links "Myarrow"
  repeat (num-nodes - 1 ) ; last node doesn't need to look for nodes to link to. 
  [
     set j 0
     repeat (num-nodes - 1) ; since the node index starts at 0, num-nodes is one larger than the highest index. ie. turtle9 is last turtle for num-nodes = 10.
     [
        if i != j 
        [
            ask turtle i 
            [
                set node2 turtle j
                ;show (word node2 )
                if random 100 < chance-of-edge
                [ 
                  ifelse random 100 < chance-edge-positive 
                  [create-positive-edge-to node2 [set color blue set thickness .1]]
                  [create-negative-edge-to node2 [set color red set thickness .1]]
                ]
            ]
        ]
        set j (j + 1)
     ]
     set i (i + 1)
  ]
  find-clustering
  motif-check
end

;;;;;;;;;;;;;;;;;;;;;;;;
;;; Network Analysis ;;;
;;;;;;;;;;;;;;;;;;;;;;;;
to find-clustering
  let i 0
  let clustering 0
  repeat num-nodes
  [  
     ask turtle i
     [
        ;ask out-link-neighbors [set check 1]  
        ask out-link-neighbors [set clustering count my-out-links]        
        set clustering-coef (clustering / ( num-nodes * ( num-nodes - 1 ) ) )
     ] 
     set i (i + 1)
  ]
end


to motif-check
  check-two-node-regulation
  ; the following two are for three node motifs
  check-for-ff-loops 
  check-for-fb-loops
end

to check-two-node-regulation
   ;all three types of two node feedback
   let i 0
   set two-node-ps-feedback 0
   set two-node-ng-feedback 0
   set two-node-dn-feedback 0
   repeat num-nodes
   [
      ask turtle i 
      [
        set check 1
        ask out-positive-edge-neighbors 
        [ 
          ask out-positive-edge-neighbors with [check = 1] [set two-node-ps-feedback (two-node-ps-feedback + 1)]; show "two-node-ps-feedback"]
          ask out-negative-edge-neighbors with [check = 1] [set two-node-ng-feedback (two-node-ng-feedback + 1)]; show "two-node-ng-feedback"]
        ]
        ask out-negative-edge-neighbors
        [ 
          ask out-positive-edge-neighbors with [check = 1] [set two-node-ng-feedback (two-node-ng-feedback + 1)]; show "two-node-ng-feedback"]
          ask out-negative-edge-neighbors with [check = 1] [set two-node-dn-feedback (two-node-dn-feedback + 1)]; show "two-node-dn-feedback"]
        ]
      ]
      set i ( i + 1 )
      ask turtles [set check 0]
   ]
   set two-node-ps-feedback (two-node-ps-feedback / 2)
   set two-node-ng-feedback (two-node-ng-feedback / 2)
   set two-node-dn-feedback (two-node-dn-feedback / 2)   
end

to check-for-ff-loops ;three node
   ;Feed Forward
   let i 0
   let x 0
   let y 0
   set number-of-ff-loops 0
   set types-of-ff-loops []
   set who-in-ff-loops []
   repeat num-nodes
   [
      let j 0
      ask turtle i 
      [
        ask out-positive-edge-neighbors [set check 1 ]
        ask out-negative-edge-neighbors [set check 2 ]
        set x [who] of self
        ask out-positive-edge-neighbors 
        [ 
            set y [who] of self
            ask out-positive-edge-neighbors with [check = 1] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 1 types-of-ff-loops
                ]
            ask out-negative-edge-neighbors with [check = 1] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 2 types-of-ff-loops
                ]
            ask out-positive-edge-neighbors with [check = 2] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 3 types-of-ff-loops
                ]
            ask out-negative-edge-neighbors with [check = 2] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 4 types-of-ff-loops
                ]
        ]
        ask out-negative-edge-neighbors
        [
            set y [who] of self
            ask out-positive-edge-neighbors with [check = 1] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 5 types-of-ff-loops
                ]
            ask out-negative-edge-neighbors with [check = 1] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 6 types-of-ff-loops
                ]
            ask out-positive-edge-neighbors with [check = 2] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 7 types-of-ff-loops
                ]
            ask out-negative-edge-neighbors with [check = 2] 
                [
                  set j (j + 1) 
                  set who-in-ff-loops fput (word x "-" y "-" [who] of self) who-in-ff-loops
                  set types-of-ff-loops fput 8 types-of-ff-loops
                ]
        ]
        ;show j 
        set number-of-ff-loops (number-of-ff-loops + j)
      ]
      ;ask turtle i [if (check != 0) [set color blue]]
      set i ( i + 1 )
      ask turtles [set check 0]
   ]
end

to check-for-fb-loops ;three node
   ;Feedback
   let i 0
   let x 0
   let y 0
   set number-of-fb-loops 0
   ;set types-of-fb-loops [b
   set who-in-fb-loops []
   repeat num-nodes
   [
      let j 0
      ask turtle i 
      [
        ask in-positive-edge-neighbors [set check 1]
        ask in-negative-edge-neighbors [set check 2]
        set x [who] of self
        ask out-positive-edge-neighbors 
        [ 
            set y [who] of self
            ask out-positive-edge-neighbors with [check = 1] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-negative-edge-neighbors with [check = 1] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-positive-edge-neighbors with [check = 2] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-negative-edge-neighbors with [check = 2] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
        ]
        ask out-negative-edge-neighbors
        [
            set y [who] of self
            ask out-positive-edge-neighbors with [check = 1] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-negative-edge-neighbors with [check = 1] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-positive-edge-neighbors with [check = 2] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
            ask out-negative-edge-neighbors with [check = 2] [set j (j + 1) set who-in-fb-loops fput (word x "-" y "-" [who] of self) who-in-fb-loops]
        ]
        ;show j 
        set number-of-fb-loops (number-of-fb-loops + j)
      ]
      set i ( i + 1 )
      ask turtles [set check 0]
   ]
   set number-of-fb-loops (number-of-fb-loops / 3) ; I think they always get counted three times

   ;print who-in-fb-loops 
end

to print-analysis
   print ( word "two-node-ps-feedback:" two-node-ps-feedback )
   print ( word "two-node-ng-feedback:" two-node-ng-feedback )
   print ( word "two-node-dn-feedback:" two-node-dn-feedback )
   
   print ( word "number-of-fb-loops:" number-of-fb-loops )
   print ( word "number-of-ff-loops:" number-of-ff-loops )
   print types-of-ff-loops
   print who-in-ff-loops
end

;two-node-ps-feedback
;two-node-ng-feedback
;two-node-dn-feedback
;number-of-fb-loops
;number-of-ff-loops