Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/analyze_etr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Analyze Electron Transport Rate

Estimate mean and median electron transport rate (ETR).
Calculates `(Fq’/Fm’) * AlphaL * PSI/PSIIratio * Actinic_light`. This requires [calculating alphaL](analyze_alphaL.md) and [calculating Fq'/Fm'](analyze_yii.md) before ETR can be calculated.

**plantcv.analyze.etr**(*actinic_light, psi_psii_ratio=0.5*)

**returns** None

- **Parameters:**
- actinic_light - Light intensity in PAR
- psi_psii_ratio - Light absorption ratio between photosynthesis 1 and 2. Defaults to 0.5.

- **Context:**
- Used to calculate ETR after YII and AlphaL are calculated. This requires APH frames and the frames input to [`analyze.yii`](analyze_yii.md).

- **Example use:**
- Below

- **Output data stored:** Data (mean_etr, median_etr) are stored to the [`Outputs` class](outputs.md) when this function is run.

```python
from plantcv import plantcv as pcv

# calculate ETR
pcv.analyze.etr(actinic_light=10)
# check results
pcv.outputs.observations["plant_1"]["mean_etr"]["values"]

```
5 changes: 5 additions & 0 deletions docs/updating.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ pages for more details on the input and output variable types.
* pre v4.2.1: NA
* post v4.2.1: dist_chart = **plantcv.analyze.distribution**(*labeled_mask, n_labels=1, direction="down", bin_size=100, hist_range="absolute", label=None*)

#### plantcv.analyze.etr

* pre v5.0: NA
* post v5.0: _ = **plantcv.analyze.etr**(*actinic_light, psi_psii_ratio=0.5*)

#### plantcv.analyze.grayscale

* pre v4.0: (see plantcv.analyze_nir_intensity)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ nav:
- 'Analyze Spectral Index': analyze_spectral_index.md
- 'Analyze YII': analyze_yii.md
- 'Analyze NPQ': analyze_npq.md
- 'Analyze ETR': analyze_etr.md
- 'Annotation Tools':
- 'Points': Points.md
- 'Apply Mask': apply_mask.md
Expand Down
3 changes: 2 additions & 1 deletion plantcv/plantcv/analyze/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
from plantcv.plantcv.analyze.yii import yii
from plantcv.plantcv.analyze.npq import npq
from plantcv.plantcv.analyze.alphaL import alphaL
from plantcv.plantcv.analyze.etr import etr
from plantcv.plantcv.analyze.distribution import distribution
from plantcv.plantcv.analyze.texture import texture

__all__ = ["color", "bound_horizontal", "bound_vertical", "grayscale", "size", "thermal", "spectral_reflectance",
"spectral_index", "yii", "npq", "alphaL", "distribution", "texture"]
"spectral_index", "yii", "npq", "alphaL", "etr", "distribution", "texture"]
2 changes: 1 addition & 1 deletion plantcv/plantcv/analyze/alphaL.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,4 @@ def _analyze_alphaL(img, mask, label, min_bin, max_bin, red, farred):
value=hist_df['proportion of pixels (%)'].values.tolist(),
label=np.around(hist_df["counts"].values.tolist(), decimals=2).tolist())

return np.where(mask > 0, alphaL_mat, img)
return img + alphaL_mat
50 changes: 50 additions & 0 deletions plantcv/plantcv/analyze/etr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Analyze electron transport rate"""

import re
from plantcv.plantcv._globals import outputs
from plantcv.plantcv.fatal_error import fatal_error


def etr(actinic_light, psi_psii_ratio=0.5):
"""Calculate electron transport rate from yii and alphaL outputs and add to outputs.

Parameters
----------
actinic_light = int or float,
Light intensity in PAR
psi_psii_ratio = float,
PSI/PSII ratio. This should generally be left as 0.5

Returns
-------
None, etr values are added to outputs
"""
obs = outputs.observations
for label, _ in obs.items():
labs = [label2 for label2, _ in obs[label].items() if re.search("yii_mean.*[fqfm|t1]$", label2)]
labs2 = [label2 for label2, _ in obs[label].items() if re.search("yii_median.*[fqfm|t1]$", label2)]
Comment on lines +24 to +25
aph_labs = [label3 for label3, _ in obs[label].items() if re.search("alphaL", label3)]
if len(labs) < 1:
fatal_error("YII mean data must be present in outputs," +
"run plantcv.plantcv.analyze.yii before plantcv.plantcv.analyze.etr.")
yii_mean_val = obs[label][labs[0]]["value"]
yii_median_val = obs[label][labs2[0]]["value"]
if not bool(aph_labs):
fatal_error("AlphaL mean data must be present in outputs," +
"run plantcv.plantcv.analyze.alphaL before plantcv.plantcv.analyze.etr.")
alphaL_mean_val = obs[label]["alphaL_mean"]["value"]
alphaL_median_val = obs[label]["alphaL_median"]["value"]
# calculate ETR
etr_mean_val = yii_mean_val * alphaL_mean_val * psi_psii_ratio * actinic_light
etr_median_val = yii_median_val * alphaL_median_val * psi_psii_ratio * actinic_light
# store outputs
outputs.add_observation(sample=label,
variable='mean_etr', trait='mean electron transport rate',
method='plantcv.plantcv.analyze.etr',
scale='none', datatype=float,
value=etr_mean_val, label='none')
outputs.add_observation(sample=label,
variable='median_etr', trait='median electron transport rate',
method='plantcv.plantcv.analyze.etr',
scale='none', datatype=float,
value=etr_median_val, label='none')
72 changes: 72 additions & 0 deletions tests/plantcv/analyze/test_etr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import pytest
from plantcv.plantcv._globals import outputs
from plantcv.plantcv.analyze.etr import etr


def test_etr():
"""Test for PlantCV."""
outputs.clear()
outputs.add_observation(sample="label1",
variable = 'yii_mean_t1',
trait='dummy yii',
method='dummy.method',
scale='none', datatype=float,
value=10, label='none')
outputs.add_observation(sample="label1",
variable = 'alphaL_mean',
trait='dummy alpha',
method='dummy.alpha.method',
scale='none', datatype=float,
value=5, label='none')
outputs.add_observation(sample="label1",
variable = 'yii_median_t1',
trait='dummy yii',
method='dummy.method',
scale='none', datatype=float,
value=10, label='none')
outputs.add_observation(sample="label1",
variable = 'alphaL_median',
trait='dummy alpha',
method='dummy.alpha.method',
scale='none', datatype=float,
value=5, label='none')
etr(10)
assert outputs.observations["label1"]["mean_etr"]["value"] == 250


def test_etr_no_yii():
"""Test for PlantCV."""
outputs.clear()
outputs.add_observation(sample="label1",
variable = 'alphaL_mean',
trait='dummy alpha',
method='dummy.alpha.method',
scale='none', datatype=float,
value=5, label='none')
outputs.add_observation(sample="label1",
variable = 'alphaL_median',
trait='dummy alpha',
method='dummy.alpha.method',
scale='none', datatype=float,
value=5, label='none')
with pytest.raises(RuntimeError):
etr(10)


def test_etr_no_alphaL():
"""Test for PlantCV."""
outputs.clear()
outputs.add_observation(sample="label1",
variable = 'yii_mean_t1',
trait='dummy yii',
method='dummy.method',
scale='none', datatype=float,
value=10, label='none')
outputs.add_observation(sample="label1",
variable = 'yii_median_t1',
trait='dummy yii',
method='dummy.method',
scale='none', datatype=float,
value=10, label='none')
with pytest.raises(RuntimeError):
etr(10)
Loading