nee2gpp

nee2gppEstimates photosynthesis (GPP) and ecosystem respiration (RECO)

from Eddy covariance CO2 flux data.

This module was written by Matthias Cuntz while at Department of Computational Hydrosystems, Helmholtz Centre for Environmental Research - UFZ, Leipzig, Germany, and continued while at Institut National de Recherche pour l’Agriculture, l’Alimentation et l’Environnement (INRAE), Nancy, France.

Copyright (c) 2012-2020 Matthias Cuntz - mc (at) macu (dot) de Released under the MIT License; see LICENSE file for details.

  • Written 2012 by Matthias Cuntz - mc (at) macu (dot) de

  • Set default undef to NaN, Mar 2012, Arndt Piayda

  • Add wrapper nee2gpp for individual routines, Nov 2012, Matthias Cuntz

  • Ported to Python 3, Feb 2013, Matthias Cuntz

  • Use generel cost function cost_abs from functions module, May 2013, Matthias Cuntz

  • Use fmin_tnc to allow params < 0, Aug 2014, Arndt Piayda

  • Keyword nogppnight, Aug 2014, Arndt Piayda

  • Add wrapper nee2gpp for individual routines, Nov 2012, Matthias Cuntz

  • Add wrapper nee2gpp for individual routines, Nov 2012, Matthias Cuntz

  • Input can be pandas Dataframe or numpy array(s), Apr 2020, Matthias Cuntz

  • Using numpy docstring format, May 2020, Matthias Cuntz

  • Removed np.float and np.int, Jun 2024, Matthias Cuntz

The following functions are provided

nee2gpp(dfin[, flag, isday, date, ...])

Calculate photosynthesis (GPP) and ecosystem respiration (RECO) from Eddy covariance CO2 flux data.

nee2gpp(dfin, flag=None, isday=None, date=None, timeformat='%Y-%m-%d %H:%M:%S', colhead=None, undef=-9999, method='reichstein', nogppnight=False, swthr=10.0)[source]

Calculate photosynthesis (GPP) and ecosystem respiration (RECO) from Eddy covariance CO2 flux data.

It uses either

  1. a fit of Reco vs. temperature to all nighttime data [1] (method=’falge’), or

  2. several fits over the season of Reco vs. temperature as in Reichstein et al. (2005) [2] (method=’reichstein’), or

  3. the daytime method of Lasslop et al. (2010) [3] (method=’lasslop’),

in order to calculate Reco and then GPP = Reco - NEE.

Parameters:
  • dfin (pandas.Dataframe or numpy.array) –

    time series of CO2 fluxes and air temperature, and possibly incoming shortwave radiation and air vapour pressure deficit.

    dfin can be a pandas.Dataframe with the columns ‘FC’ or ‘NEE’ (or starting with ‘FC_’ or ‘NEE_’) for observed CO2 flux [umol(CO2) m-2 s-1] ‘TA’ (or starting with ‘TA_’) for air temperature [K]

    method=’lasslop’ or method=’day’ needs also ‘SW_IN’ (or starting with ‘SW_IN’) for incoming short-wave radiation [W m-2] ‘VPD’ (or starting with ‘VPD’) for air vapour deficit [Pa] The index is taken as date variable.

    dfin can also me a numpy array with the same columns. In this case colhead, date, and possibly dateformat must be given.

  • flag (pandas.Dataframe or numpy.array, optional) –

    flag Dataframe or array has the same shape as dfin. Non-zero values in flag will be treated as missing values in dfin.

    flag must follow the same rules as dfin if pandas.Dataframe.

    If flag is numpy array, df.columns.values will be used as column heads and the index of dfin will be copied to flag.

  • isday (array_like of bool, optional) –

    True when it is day, False when night. Must have the same length as dfin.shape[0].

    If isday is not given, dfin must have a column with head ‘SW_IN’ or starting with ‘SW_IN’. isday will then be dfin[‘SW_IN’] > swthr.

  • date (array_like of string, optional) –

    1D-array_like of calendar dates in format given in timeformat.

    date must be given if dfin is numpy array.

  • timeformat (str, optional) – Format of dates in date, if given (default: ‘%Y-%m-%d %H:%M:%S’). See strftime documentation of Python’s datetime module: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior

  • colhed (array_like of str, optional) – column names if dfin is numpy array. See dfin for mandatory column names.

  • undef (float, optional) – values having undef value are treated as missing values in dfin (default: -9999)

  • method (str, optional) –

    method to use for partitioning. Possible values are:

    ’global’ or ‘falge’: fit of Reco vs. temperature to all nighttime

    data

    ’local’ of ‘reichstein’: several fits over the season of Reco vs.

    temperature as in Reichstein et al. (2005) (default)

    ’day’ or ‘lasslop’: method of Lasslop et al. (2010) fitting a

    light-response curve

  • nogppnight (float, optional) – GPP will be set to zero at night. RECO will then equal NEE at night (default: False)

  • swthr (float, optional) – Threshold to determine daytime from incoming shortwave radiation if isday not given (default: 10).

Returns:

pandas.Dataframe with two columns ‘GPP’ and ‘RECO’ with estimated photosynthesis and ecosystem respiration, or two numpy arrays [GPP, RECO].

Return type:

pandas.Dataframe or numpy arrays

Notes

Negative respiration possible at night if GPP is forced to 0 with nogppnight=True.

References

[1]

Falge et al. (2001) Gap filling strategies for defensible annual sums of net ecosystem exchange, Acricultural and Forest Meteorology 107, 43-69

[2]

Reichstein et al. (2005) On the separation of net ecosystem exchange into assimilation and ecosystem respiration: review and improved algorithm, Global Change Biology 11, 1424-1439

[3]

Lasslop et al. (2010) Separation of net ecosystem exchange into assimilation and respiration using a light response curve approach: critical issues and global evaluation, Global Change Biology 16, 187-208

Examples

>>> from fread import fread
>>> from date2dec import date2dec
>>> from dec2date import dec2date
>>> ifile = 'test_nee2gpp.csv'
>>> undef = -9999.
>>> dat   = fread(ifile, skip=2, transpose=True)
>>> ndat  = dat.shape[1]
>>> head  = fread(ifile, skip=2, header=True)
>>> head1 = head[0]
>>> # date
>>> jdate = date2dec(dy=dat[0,:], mo=dat[1,:], yr=dat[2,:], hr=dat[3,:], mi=dat[4,:])
>>> adate = dec2date(jdate, eng=True)
>>> # colhead
>>> idx   = []
>>> for i in head1:
...     if i in ['NEE', 'rg', 'Tair', 'VPD']: idx.append(head1.index(i))
>>> colhead = ['FC', 'SW_IN', 'TA', 'VPD']
>>> # data
>>> dfin = dat[idx,:]
>>> dfin[2,:] = np.where(dfin[2,:] == undef, undef, dfin[2,:]+273.15)
>>> dfin[3,:] = np.where(dfin[3,:] == undef, undef, dfin[3,:]*100.)
>>> # flag
>>> flag = np.where(dfin == undef, 2, 0)
>>> # partition
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='local')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  4.40606871e+00
  8.31942152e+00  1.06242542e+01  8.49245664e+00  1.12381973e+01]
>>> print(Reco[1120:1128])
[1.68311981 1.81012431 1.9874173  2.17108871 2.38759152 2.64372415
 2.90076664 3.18592735]
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='local')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  4.40606871e+00
  8.31942152e+00  1.06242542e+01  8.49245664e+00  1.12381973e+01]
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='global')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  4.33166157e+00
  8.18228013e+00  1.04092252e+01  8.19395317e+00  1.08427448e+01]
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='Reichstein')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  4.40606871e+00
  8.31942152e+00  1.06242542e+01  8.49245664e+00  1.12381973e+01]
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='reichstein')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  4.40606871e+00
  8.31942152e+00  1.06242542e+01  8.49245664e+00  1.12381973e+01]
>>> GPP, Reco = nee2gpp(dfin, flag=flag, date=adate, colhead=colhead,
...                     undef=undef, method='day')
>>> print(GPP[1120:1128])
[-9.99900000e+03 -9.99900000e+03 -9.99900000e+03  2.78457540e+00
  6.63212545e+00  8.88902165e+00  6.74243873e+00  9.51364527e+00]
>>> print(Reco[1120:1128])
[0.28786696 0.34594516 0.43893276 0.5495954  0.70029545 0.90849165
 1.15074873 1.46137527]