User Tools

Site Tools


02_user_tutorials:from_photosynthesis_to_transport

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
02_user_tutorials:from_photosynthesis_to_transport [2026/09/27 15:54] – barley196502_user_tutorials:from_photosynthesis_to_transport [2026/09/28 09:48] (current) – removed barley1965
Line 1: Line 1:
-====== Exercise: Sources, sinks and assimilate transport in a virtual plant ====== 
- 
-//Master 2 BV, specialties "SEPPRO&SPP" and "Santé des Plantes - PHP". Duration: about 2 hours. You may work alone or in pairs.// 
- 
-===== Learning objectives ===== 
- 
-At the end of this session you should be able to: 
-  * explain how a functional–structural plant model (FSPM) links **light interception → photosynthesis → transport → growth of sinks**; 
-  * identify, in real model code, where each of these processes is computed and which organs act as **sources** or **sinks**; 
-  * explain the difference between the **potential** growth of an organ and its **actual** growth when sugar is limiting; 
-  * run a model experiment rigorously: **predict, run, observe, explain**; 
-  * modify the model to represent a situation from your own field (a pest or disease, or fruit and seed set); 
-  * critically judge what a model does and does not represent. 
- 
-You do **not** need to be a programmer. Every code change you are asked to make is given or guided step by step. 
- 
-===== Schedule ===== 
- 
-^ Part ^ Content ^ Time ^ 
-| 0 | Setup: open and start the model | 10 min | 
-| 1 | The biology in brief | 10 min | 
-| 2 | The model at a glance | 15 min | 
-| 3 | Observe the reference run | 15 min | 
-| 4 | Reading the code: production, transport, use | 25 min | 
-| 5 | Virtual experiments | 25 min | 
-| 6 | Your specialty: plant health **or** seed science | 15 min | 
-| 7 | Synthesis | 5 min | 
-| (Bonus) | Let organs catch up: developmental plasticity | for fast groups | 
- 
----- 
- 
-===== Part 0 – Setup (10 min) ===== 
- 
-  - Start GroIMP and open the project ''Transport.gsz'' (//File → Open//). 
-  - The model code is in the file ''Example1.rgg''that you see on the right in the jEdit window. 
-  - In the toolbar of the 3D view you will find buttons for the **public** methods of the model. Here there is one: ''grow''. Each click on ''grow'' = **one time step = one hour** of simulated time (This is, of course, a simplification: we have accelerated development about sixfold, so one step actually corresponds to 6 hours, and a run of 600 steps would correspond to about 150 days). 
-  - To reset the plant to its initial state, use the reset button (this executes the ''init()'' method). **Every time you save the code (Ctrl+S), the model is also recompiled and reset.** 
-  - Click ''grow'' a few times, then **start a long run** (run/loop button). Let it run to about **step 600** (≈ 150 days) while you work on Parts 1 and 2. You will need the result in Part 3. 
- 
-Four charts open automatically: 
-^ Chart ^ What it shows ^ 
-| //Light intercepted by canopy// | total light absorbed by all leaves during the last hour | 
-| //Canopy photosynthesis// | total amount of sugar **stored** in all leaves, in mg (a stock, not the hourly production!) | 
-| //Fruit growth// | size of every fruit over time (one series per fruit) | 
-| //Distribution of sugar in the internodes// | sugar content (mg) of every internode at the current step, plotted against its rank | 
- 
-**Colour code in the 3D view** (false colours, for display only): 
-  * Leaves: colour depends on the light they absorbed. 
-  * Internodes: colour depends on their sugar content. 
-  * The brown floor is made of light-absorbing tiles; bright tiles receive more light. 
- 
-**The XL Console.** Messages from the model appear here. You can also type queries into it, for example: 
-<code java> 
-((* Example1.Fruit *)[size])      // size of every fruit 
-((* Example1.Fruit *)[as])        // sugar stock of every fruit 
-count((* Example1.Fruit *))       // number of fruits 
-</code> 
- 
-===== Part 1 – The biology in brief (10 min) ===== 
- 
-Plants produce sugars (assimilates) in **source** organs – mainly mature leaves – and use them in **sink** organs – young leaves, stems, roots, flowers, fruits and seeds. Sugars travel through the **phloem**. In the widely accepted Münch model, sugar loading at the source raises the osmotic pressure there, unloading at the sink lowers it, and the resulting pressure difference drives a mass flow from source to sink. A young leaf is first a sink and becomes a source when it reaches roughly a third to half of its final size (**sink–source transition**). 
- 
-**Questions (answer in 2–3 lines each):** 
-  - **Q1.** Name three sources and three sinks in a tomato plant bearing fruit. 
-  - **Q2.** Give one example of a pest or pathogen that changes the source–sink balance of a crop, and state whether it mainly reduces the source, adds a sink, or blocks transport. 
-  - **Q3.** In a seed crop, why can the number of fruits/seeds set early in the season limit the final seed size? 
- 
-===== Part 2 – The model at a glance (15 min) ===== 
- 
-==== 2.1 The organs (modules) ==== 
- 
-^ Module ^ Role ^ Important attributes ^ 
-| ''Bud'' | apical meristem; produces new metamers | ''rank'' (position on the axis), ''phyllo'' (countdown until next metamer), ''order'' (1 = main stem, 2 = branch, 3 = dormant bud) | 
-| ''Internode'' | stem segment; **transport pathway and sink** | ''length'', ''age'', ''rank'', ''as'' (assimilate content, mg) | 
-| ''Node'' | attachment point of a leaf and a lateral bud | – | 
-| ''Leaf'' | **source** (and sink while young) | ''length'', ''width'', ''al'' (absorbed light), ''age'', ''as'' (assimilate content, mg) | 
-| ''Flower'' | becomes a fruit if enough sugar is available, otherwise it is shed | ''age'', ''max_age'' | 
-| ''Fruit'' | **main sink** | ''size'', ''age'', ''as'', ''no'' (fruit number) | 
-| ''Tile'' | light-absorbing ground | ''al'' | 
-| ''MyLight'' | a 200 W spotlight 50 units above the plant | – | 
- 
-==== 2.2 What happens during one call of grow() ==== 
- 
-<code java> 
-public void grow () { 
-    run();            // 1. architecture: new metamers, flowers, fruit set, leaf death 
-    lm.compute();     // 2. light model: ray tracing of the whole scene 
-    absorbAndGrow();  // 3. light absorption, photosynthesis, organ growth 
-    //if(time % 24 == 0) { 
-        //for(int hour = 0; hour < 24; hour++) { 
-            transport();   // 4. one round of transport per hour 
-       // } 
-    //} 
-    updateChart();    // 5. charts 
-    time++; 
-} 
-</code> 
- 
-**Q4.** In an earlier version of the model, the lines now commented out were active: transport happened 24 times in a row, but only once every 24 steps. A young leaf is a sink only during its first ~13 hours. What problem did this cause? Why is it important that the time step of transport matches the time scale of the processes it feeds? 
- 
-==== 2.3 How the plant is built ==== 
- 
-The rule that makes a bud produce a new metamer is: 
- 
-<code java> 
-Bud(r, p, o), (r < 10 && p == 0 && o < 3) ==> 
-    RV(-0.1) Internode(0.1, 1, r, (r==1 && o==1) ? 0.2 : 0.0) Node 
-    [ RL(BRANCH_ANGLE) Bud(r, PHYLLOCHRON, o+1) ]   // lateral bud -> branch 
-    [ LFA(1) Leaf(0.1, 0.07, 0, 1, 0, r) ]          // leaf 
-    RH(GOLDEN_ANGLE) RV(-0.1) Internode(0.1, 1, r, (r==1 && o==1) ? 0.1 : 0.0) 
-    Bud(r+1, PHYLLOCHRON, o);                       // the apex continues 
-</code> 
- 
-**Q5.** Draw (on paper) one metamer as produced by this rule: which organs, in which order, and what is inside the square brackets ''[ ]''? 
- 
-**Q6.** When ''rank'' reaches 10, the bud turns into a ''Flower''. How many flowers do you expect on the plant? (Hint: look at the condition ''o < 3'' and at the order given to the main stem in ''init()''.) 
- 
-**Q7.** Only the first two internodes of the main stem (''r==1 && o==1'') start with some sugar; all other new organs start empty. What does this initial sugar represent biologically? Why is it a good idea not to give every new organ a "start capital"? 
- 
-===== Part 3 – Observe the reference run (15 min) ===== 
- 
-Look at your run (about 600 steps). Use the 3D view, the charts and the console queries. 
- 
-Fill in: 
-^ Observation ^ Your answer ^ 
-| Step at which the first flower appears | | 
-| Step at which the first fruit appears | | 
-| Number of flowers / number of fruits | | 
-| Final size of each fruit (console query) | | 
-| Shape of the fruit growth curves (linear? S-shaped? all the same?) | | 
-| Sugar distribution in the internodes: at which ranks is it highest? | | 
-| Which leaves absorb the most light? | | 
- 
-**Q8.** The internode sugar chart shows the highest sugar content in the **middle** ranks, not at the base or at the top. Propose an explanation. (Think about which leaves are mature and well lit, and which organs at the top are consuming sugar.) 
- 
-===== Part 4 – Reading the code: production, transport, use (25 min) ===== 
- 
-We now follow a sugar molecule from where it is made to where it is used. 
- 
-==== 4.1 Production: the light response curve ==== 
- 
-<code java> 
-float calculateCER(float ppfd) { 
-    return ((FMAX + DARK_RESPIRATION_RATE) * PHOTO_EFFICIENCY * ppfd) 
-         / (PHOTO_EFFICIENCY * ppfd + FMAX + DARK_RESPIRATION_RATE) 
-         - DARK_RESPIRATION_RATE; 
-} 
-</code> 
- 
-''ppfd'' is the photon flux density received by the leaf (µmol photons m⁻² s⁻¹), CER is the CO₂ exchange rate (µmol CO₂ m⁻² s⁻¹). ''FMAX'' = 20, ''DARK_RESPIRATION_RATE'' = 0.5, ''PHOTO_EFFICIENCY'' = 0.85. 
- 
-  * **Q9.** What is the value of CER in darkness (ppfd = 0)? What does a negative value mean for the leaf? 
-  * **Q10.** What value does CER approach when ppfd becomes very large? Sketch the curve. 
-  * **Q11.** The function ''calculatePS'' converts CER into milligrams of glucose produced by one leaf in one hour. Which quantities is CER multiplied by? (Look at the code.) 
- 
-In ''absorbAndGrow()'', every leaf adds its production to its own stock: ''lf[as] += calculatePS(...)''. 
- 
-==== 4.2 Transport ==== 
- 
-The method ''transport()'' contains three rules. The rate constants are defined at the top of the file: 
- 
-<code java> 
-const float LEAF_EXPORT  = 0.05;  // fraction of leaf stock exported per hour 
-const float D_PHLOEM     = 0.2;   // exchange between adjacent internodes 
-const float FRUIT_UNLOAD = 0.1;   // unloading into the fruit per hour 
-</code> 
- 
-**Rule 1 – between a leaf and the internode that carries it** 
-<code java> 
-lf:Leaf -ancestor-> itn:Internode ::> { 
-    boolean sink = lf[length] < 1.0;   // about 1/3 of final length 
-    if (!sink && lf[as] > 0.001) {            // mature leaf: EXPORT 
-        float r = LEAF_EXPORT * lf[as]; 
-        lf[as] -= r;  itn[as] += r; 
-    } 
-    else if (sink && itn[as] > 0.001) {       // young leaf: IMPORT 
-        float r = LEAF_EXPORT * itn[as]; 
-        lf[as] += r;  itn[as] -= r; 
-    } 
-} 
-</code> 
- 
-**Rule 2 – between two successive internodes** 
-<code java> 
-i_top:Internode -ancestor-> i_bottom:Internode ::> { 
-    float r = D_PHLOEM * (i_top[as] - i_bottom[as]); 
-    i_bottom[as] :+= r; 
-    i_top[as]    :-= r; 
-} 
-</code> 
- 
-**Rule 3 – from an internode into the fruit it carries** 
-<code java> 
-itn:Internode -successor-> fr:Fruit ::> { 
-    float r = FRUIT_UNLOAD * Math.max(0, itn[as] - fr[as]); 
-    itn[as] :-= r; 
-    fr[as]  :+= r; 
-} 
-</code> 
- 
-//Reading tips:// ''a -ancestor-> b:Internode'' means "starting from a, go **down** towards the base and take the first Internode you meet". ''a -successor-> b'' means "b follows a directly". The operators '':+='' and '':-='' collect all changes and apply them together at the end of the step, so the result does not depend on the order in which the rules are applied. 
- 
-  * **Q12.** When does a leaf switch from sink to source in this model? Why is a criterion based on leaf **size** closer to the biology than one based on leaf **age**? 
-  * **Q13.** In Rule 2, can sugar move **upwards** as well as **downwards**? What decides the direction? Which physical process does this rule resemble (hint: Fick's law)? 
-  * **Q14.** Does the export of a mature leaf (Rule 1) depend on how much sugar is already in the internode? Is that consistent with the Münch model? 
-  * **Q15.** In Rule 3, the flux into the fruit depends on the **difference** between the internode and the fruit. What happens to the flux when a fruit uses its sugar quickly? What does this tell you about what makes a sink "strong"? 
- 
-==== 4.3 Use: potential and actual growth ==== 
- 
-Internodes and fruits grow with the same logic. Here is the internode version: 
- 
-<code java> 
-itn:Internode ::> { 
-    itn[age]++; 
-    itn[as] *= (1 - MR);                                     // maintenance respiration 
-    float potential = logistic(INT_MAX_LENGTH, itn[age], 20, 0.2); // growth if sugar were unlimited 
-    float demand = potential * GROWTH_COST;                  // sugar needed for that growth 
-    float f = (demand > 0) ? Math.min(1.0, itn[as] / demand) : 0;  // fraction of demand satisfied 
-    itn[length] += potential * f;                            // actual growth 
-    itn[as]     -= demand * f;                               // sugar consumed 
-} 
-</code> 
- 
-The fruit block is identical, with ''FRUIT_MAX_SIZE'' and ''FRUIT_COST''. 
- 
-  * **Q16.** Explain in your own words what ''potential'', ''demand'' and ''f'' are. What is the value of ''f'' when the organ has more sugar than it needs? When it has none? 
-  * **Q17.** The potential growth depends only on the organ's **age**. If an internode receives no sugar during its first 40 hours, can it catch up later? Is this realistic? 
-  * **Q18.** Growth **consumes** sugar (last line). Using your answer to Q15, explain why this consumption is what makes sugar flow towards growing organs. 
-  * **Q19.** An internode needs ''INT_MAX_LENGTH × GROWTH_COST'' = 1.5 mg of sugar for its whole growth. Compare with the values in the internode sugar chart. Is this plant limited by its **sources** or by its **sinks**? 
-  * **Q20.** Does **leaf** growth depend on the amount of sugar in the leaf? (Read the comment in the code, then the code itself.) 
- 
-==== 4.4 Fruit set ==== 
- 
-<code java> 
-fl:Flower(t, m)(* -ancestor-> itn:Internode *), (t >= m && t < m+2) ==> 
-    { float sugar = itn[as]; println("flower sugar: " + sugar); } 
-    if (sugar > FRUIT_SET_THRESHOLD) ( {noFrts++;} Fruit(0.01, 1, 0.1, noFrts) ); 
-</code> 
- 
-**Q21.** In words: under which condition does a flower become a fruit? Where is the sugar measured? What happens to a flower when the condition is not met? (Hint: what is on the right-hand side of the rule in that case?) 
- 
-===== Part 5 – Virtual experiments (25 min) ===== 
- 
-Method, for **each** experiment: 
-  - Write your **prediction** //before// running (effect on fruit number, fruit size, internode length, sugar distribution). 
-  - Change **one** value only, save (the model resets), run to step 600. 
-  - Record the result, then **restore the original value**. 
- 
-A run takes several minutes, so the experiments are shared out between the pairs. Your teacher will tell you which ones to do; the results are pooled at the end. 
- 
-^ Exp. ^ What to change ^ Question behind it ^ 
-| E1 | ''D_PHLOEM'': 0.2 → 0.02 | How far can sugar travel in the stem? | 
-| E2 | ''MR'': 0.002 → 0.02 | What does respiration cost the plant? | 
-| E3 | ''LEAF_EXPORT'': 0.05 → 0.01 | What if leaves keep their sugar? | 
-| E4 | Lamp power: ''setPower(200.0)'' → 100.0 (module ''MyLamp'') | Source limitation | 
-| E5 | ''FRUIT_COST'': 250 → 500 | A more demanding sink | 
-| E6 | Sink–source transition: ''lf[length] < 1.0'' → ''< 2.0'' (Rule 1) | Longer sink phase of young leaves | 
-| E7 | ''FRUIT_SET_THRESHOLD'': 3.5 → 1.0, then → 10 | Fruit set vs. abortion | 
- 
-Results table (one line per run): 
-^ Exp. ^ Value ^ Prediction ^ Nb fruits ^ Mean fruit size ^ Internode sugar profile ^ Plant height / internode length ^ Explanation ^ 
-| Ref | – | – | | | | | | 
-| | | | | | | | | 
-| | | | | | | | | 
- 
-**Q22.** Which experiments changed **fruit size**, and which changed **fruit number**? Why are these two responses controlled by different parts of the model? 
- 
-**Q23.** Was any result the opposite of your prediction? Explain it using the code. 
- 
-===== Part 6 – Your specialty (15 min) ===== 
- 
-Choose **one** track and do at least one task. 
- 
-==== Track A – Plant Health ==== 
- 
-**A1. Aphids: a new phloem sink.** Aphids feed directly on phloem sap. Add a colony on the internodes of rank 3, starting at step 100. 
- 
-At the top of the file, next to the other constants, add: 
-<code java> 
-const float APHID_RATE = 0.02;   // fraction of internode sugar taken per hour 
-float aphidSugar = 0;            // total sugar taken by the aphids 
-</code> 
- 
-Inside ''transport()'', add a fourth rule (before the closing '']''): 
-<code java> 
-itn:Internode, (itn[rank] == 3 && time > 100) ::> { 
-    float r = APHID_RATE * itn[as]; 
-    itn[as] :-= r; 
-    aphidSugar += r; 
-} 
-</code> 
- 
-Print the total at each step: add ''println("aphids: " + aphidSugar);'' in ''grow()''. Compare with the reference run. Then move the colony to rank 9, just below the flowers. 
- 
-**A2. Defoliation by a leaf disease.** Remove all leaves of rank ≤ 4 at step 200. Add this rule in ''run()'': 
-<code java> 
-lf:Leaf, (time == 200 && lf[rank] <= 4) ==> ; 
-</code> 
- 
-**A3. A pathogen that lowers photosynthetic capacity** (e.g. a leaf spot or a virus): reduce ''FMAX'' from 20 to 10. 
- 
-**Questions:** 
-  * **QA1.** Which intervention reduced fruit number or fruit size the most? Was the position of the aphid colony important? Why? 
-  * **QA2.** Which of A1, A2, A3 reduces the //source//, which adds a //sink//? Why is it useful for a plant pathologist to make this distinction? 
-  * **QA3.** What would you need to add to the model to represent an aphid population that grows over time? 
- 
-==== Track B – Seed Science and Plant Propagation ==== 
- 
-**B1. Fruit thinning.** Remove every second fruit at step 360. Add this rule in ''run()'': 
-<code java> 
-fr:Fruit, (time == 360 && fr[no] % 2 == 0) ==> ; 
-</code> 
-Compare the final size of the remaining fruits with the reference run. 
- 
-**B2. Fruit set threshold.** Run experiment E7 if nobody else has. How do the number of fruits and the mean fruit size change together? 
- 
-**B3. Variable developmental speed.** In the reference plant, all branches develop in step, so all fruits have almost the same age. Make development less regular: in the metamer rule (Part 2.3), replace **both** occurrences of ''PHYLLOCHRON'' by ''irandom(PHYLLOCHRON-8, PHYLLOCHRON+8)''. Run the model twice and compare the spread of fruit sizes (largest minus smallest) with the reference run. 
- 
-**Questions:** 
-  * **QB1.** Is there a trade-off between the number and the size of fruits? Show it with your results. 
-  * **QB2.** In B3, do early-set or late-set fruits end up larger? Why? What are the consequences for seed-lot uniformity? 
-  * **QB3.** A seed producer wants large, uniform seeds. Based on the model, what would you advise, and what is missing from the model to give a reliable answer? 
- 
-===== Part 7 – Synthesis (5 min) ===== 
- 
-  * **Q24.** Draw a diagram (boxes and arrows) of the sugar flows in the model: production → stocks → transport → use. Mark every place where sugar enters or leaves the system. 
-  * **Q25.** List two strengths and two limitations of this model for studying source–sink relations. 
- 
-===== Bonus – Let organs catch up: developmental plasticity ===== 
- 
-For fast groups. At present an internode's potential growth depends on its calendar age (Q17): if it is starved during its growth window, the loss is permanent. Real organs can often delay their development instead. 
- 
-Hints: 
-  - Give ''Internode'' a new variable for its **developmental age**: change the module declaration to ''module Internode(super.length, int age, int rank, float as) extends Cylinder(length, 0.1) { float dev; }''. 
-  - In the internode block, use ''itn[dev]'' instead of ''itn[age]'' to compute the potential. 
-  - At the end of the block, let development advance only as fast as growth is satisfied: ''itn[dev] += f;'' 
-  - The function ''logistic'' expects an ''int'' for time. Change its declaration to ''float time''. 
- 
-Compare the internode lengths along the main stem with the reference run. Where does the change have the largest effect? 
- 
-===== Before the exam ===== 
- 
-This exercise is not handed in, but the questions above cover the kind of reasoning expected in the exam: explaining source–sink relations, reading a simple model rule, and predicting and interpreting the outcome of a virtual experiment. Keep your answers and tables as revision notes.