├── inst ├── figures │ ├── schema.png │ ├── schema2.png │ └── reddy_showcase.png ├── manual │ └── Reddy-manual.pdf └── data-handling │ └── ghg-data-handling.R ├── .Rbuildignore ├── man ├── g.Rd ├── M_H2O.Rd ├── Rd.Rd ├── M_CH4.Rd ├── Rv.Rd ├── clight.Rd ├── csound.Rd ├── M_CO2.Rd ├── cp.Rd ├── rhoAir.Rd ├── R_earth.Rd ├── karman.Rd ├── sigma.Rd ├── Runiversal.Rd ├── Lv.Rd ├── alpha.Rd ├── cpcv.Rd ├── Ts2T.Rd ├── sos2Ts.Rd ├── calc_coriolis.Rd ├── cov2cf.Rd ├── cov2lh.Rd ├── cov2sh.Rd ├── calc_windSpeed2D.Rd ├── calc_Pr.Rd ├── calc_ef.Rd ├── calc_windDirection.Rd ├── calc_xstar.Rd ├── calc_br.Rd ├── calc_gustfactor.Rd ├── calc_windSpeed3D.Rd ├── calc_Km.Rd ├── calc_N2.Rd ├── calc_theta.Rd ├── fftfreq.Rd ├── rh2ah.Rd ├── ah2rh.Rd ├── calc_Kh.Rd ├── scale_phih.Rd ├── df_dx.Rd ├── df_dy.Rd ├── scale_phiw.Rd ├── scale_phiu.Rd ├── calc_cov.Rd ├── calc_ustar.Rd ├── calc_Tv.Rd ├── calc_iw.Rd ├── calc_vpd.Rd ├── Reddy-package.Rd ├── calc_circular_mean.Rd ├── calc_k2d.Rd ├── calc_satvaporpressure.Rd ├── rh2q.Rd ├── lh2et.Rd ├── scale_phiT.Rd ├── calc_phix.Rd ├── scale_phim.Rd ├── calc_zeta.Rd ├── calc_dshear.Rd ├── calc_phim.Rd ├── calc_ri.Rd ├── sigma2height.Rd ├── ustar2z0.Rd ├── calc_tke.Rd ├── calc_L.Rd ├── calc_csi.Rd ├── calc_ozmidov_scale.Rd ├── calc_ti.Rd ├── deaccumulate1h.Rd ├── plot_mrd.Rd ├── calc_vtke.Rd ├── calc_phit.Rd ├── calc_decoupling_metric.Rd ├── calc_ekman_layer_depth.Rd ├── calc_var.Rd ├── calc_distance.Rd ├── rotate_double.Rd ├── pres2height.Rd ├── calc_spectrum.Rd ├── plot_flux_footprint.Rd ├── calc_rif.Rd ├── flag_w.Rd ├── RTcorrection.Rd ├── ppt2rho.Rd ├── binning.Rd ├── averaging.Rd ├── shift2maxccf.Rd ├── gapfilling.Rd ├── rotate_planar.Rd ├── flag_most.Rd ├── plot_barycentric_map.Rd ├── calc_helmholtz_decomposition.Rd ├── calc_mrd.Rd ├── calc_flux_intermittency.Rd ├── despiking.Rd ├── WPLcorrection.Rd ├── flag_stationarity.Rd ├── flag_distortion.Rd ├── SNDcorrection.Rd ├── plot_quadrant_analysis.Rd ├── plot_seb.Rd ├── calc_anisotropy.Rd ├── calc_spectrum1D.Rd ├── calc_windprofile.Rd ├── calc_spectrum2D.Rd ├── calc_flux_footprint.Rd ├── calc_quadrant_analysis.Rd ├── apply_quality_control.Rd └── ECprocessing.Rd ├── Reddy.Rproj ├── DESCRIPTION ├── .gitignore ├── R ├── surface-energy-balance.R ├── constants.R ├── model-utils.R ├── multiresolution-decomposition.R ├── anisotropy.R ├── auxilliary.R ├── quadrant-analysis.R ├── diagnostics-meteorology.R ├── flux-footprint.R ├── spectrum.R ├── diagnostics-turbulence.R ├── bulk-closures.R ├── ec-processing.R └── ec-processing-routine.R ├── NAMESPACE └── README.md /inst/figures/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhujiedong/Reddy/main/inst/figures/schema.png -------------------------------------------------------------------------------- /inst/figures/schema2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhujiedong/Reddy/main/inst/figures/schema2.png -------------------------------------------------------------------------------- /inst/manual/Reddy-manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhujiedong/Reddy/main/inst/manual/Reddy-manual.pdf -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | run_tests.r 4 | ./R/dev 5 | build.sh 6 | ^\.covrignore$ 7 | -------------------------------------------------------------------------------- /inst/figures/reddy_showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhujiedong/Reddy/main/inst/figures/reddy_showcase.png -------------------------------------------------------------------------------- /man/g.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{g} 4 | \alias{g} 5 | \title{g} 6 | \usage{ 7 | g() 8 | } 9 | \description{ 10 | gravitational accelaration [m/s^2] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/M_H2O.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{M_H2O} 4 | \alias{M_H2O} 5 | \title{M_H2O} 6 | \usage{ 7 | M_H2O() 8 | } 9 | \description{ 10 | Molar mass of water 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/Rd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{Rd} 4 | \alias{Rd} 5 | \title{Rd} 6 | \usage{ 7 | Rd() 8 | } 9 | \description{ 10 | gas constant for dry air [J/(kg*K)] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/M_CH4.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{M_CH4} 4 | \alias{M_CH4} 5 | \title{M_CH4} 6 | \usage{ 7 | M_CH4() 8 | } 9 | \description{ 10 | Molar mass of methane 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/Rv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{Rv} 4 | \alias{Rv} 5 | \title{Rv} 6 | \usage{ 7 | Rv() 8 | } 9 | \description{ 10 | gas constant for water vapor [J/(kg*K)] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/clight.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{clight} 4 | \alias{clight} 5 | \title{clight} 6 | \usage{ 7 | clight() 8 | } 9 | \description{ 10 | speed of light [m/s] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/csound.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{csound} 4 | \alias{csound} 5 | \title{csound} 6 | \usage{ 7 | csound() 8 | } 9 | \description{ 10 | speed of sound [m/s] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/M_CO2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{M_CO2} 4 | \alias{M_CO2} 5 | \title{M_CO2} 6 | \usage{ 7 | M_CO2() 8 | } 9 | \description{ 10 | Molar mass of carbon dioxide 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/cp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{cp} 4 | \alias{cp} 5 | \title{cp} 6 | \usage{ 7 | cp() 8 | } 9 | \description{ 10 | heat capacity, constant pressure [J/(kg*K)] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/rhoAir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{rhoAir} 4 | \alias{rhoAir} 5 | \title{rhoAir} 6 | \usage{ 7 | rhoAir() 8 | } 9 | \description{ 10 | density of air [kg/m^3] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/R_earth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{R_earth} 4 | \alias{R_earth} 5 | \title{Earth's radius} 6 | \usage{ 7 | R_earth() 8 | } 9 | \description{ 10 | Earth's radius 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/karman.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{karman} 4 | \alias{karman} 5 | \title{von Karman constant} 6 | \usage{ 7 | karman() 8 | } 9 | \description{ 10 | von Karman constant 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/sigma.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{sigma} 4 | \alias{sigma} 5 | \title{sigma} 6 | \usage{ 7 | sigma() 8 | } 9 | \description{ 10 | Stefan-Boltzmann constant [W/m^2/K^4] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/Runiversal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{Runiversal} 4 | \alias{Runiversal} 5 | \title{R} 6 | \usage{ 7 | Runiversal() 8 | } 9 | \description{ 10 | ideal gas constant [J/(mol*K)] 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/Lv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{Lv} 4 | \alias{Lv} 5 | \title{Lv} 6 | \usage{ 7 | Lv(temp = NULL) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K] (optional)} 11 | } 12 | \description{ 13 | latent heat of vaporization [J/kg] 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/alpha.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{alpha} 4 | \alias{alpha} 5 | \title{Charnock constant (alpha)} 6 | \usage{ 7 | alpha() 8 | } 9 | \description{ 10 | Charnock constant (alpha) used to convert friction velocity to surface roughness length 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/cpcv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/constants.R 3 | \name{cpcv} 4 | \alias{cpcv} 5 | \title{gamma (ratio cp/cv)} 6 | \usage{ 7 | cpcv() 8 | } 9 | \description{ 10 | ratio of specific heat at constant pressure to that at constant volume (i.e. cp/cv = 1004 / 717 = 1.4) 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /Reddy.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /man/Ts2T.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{Ts2T} 4 | \alias{Ts2T} 5 | \title{Ts2T} 6 | \usage{ 7 | Ts2T(Ts, q) 8 | } 9 | \arguments{ 10 | \item{Ts}{sonic temperature [K] (similar as virtual temperature)} 11 | 12 | \item{q}{specific humidity [kg/kg]} 13 | } 14 | \value{ 15 | temperature [K] 16 | } 17 | \description{ 18 | Converts sonic temperature Ts to temperature T 19 | } 20 | -------------------------------------------------------------------------------- /man/sos2Ts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{sos2Ts} 4 | \alias{sos2Ts} 5 | \title{Converts speed of sound (sos) to sonic temperature} 6 | \usage{ 7 | sos2Ts(sos) 8 | } 9 | \arguments{ 10 | \item{sos}{speed of sound [m/s]} 11 | } 12 | \value{ 13 | sonic temperature (virtual temperature) [K] 14 | } 15 | \description{ 16 | Converts speed of sound (sos) to sonic temperature 17 | } 18 | -------------------------------------------------------------------------------- /man/calc_coriolis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_coriolis} 4 | \alias{calc_coriolis} 5 | \title{Coriolis parameter} 6 | \usage{ 7 | calc_coriolis(phi) 8 | } 9 | \arguments{ 10 | \item{phi}{latitude [deg]} 11 | } 12 | \value{ 13 | Coriolis parameter [1/s] 14 | } 15 | \description{ 16 | Calculates Coriolis parameter from latitude 17 | } 18 | \examples{ 19 | calc_coriolis(45) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/cov2cf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{cov2cf} 4 | \alias{cov2cf} 5 | \title{Converts cov(co2,w) to CO2 flux} 6 | \usage{ 7 | cov2cf(cov_co2w, rho = NULL) 8 | } 9 | \arguments{ 10 | \item{cov_co2w}{covariance cov(co2,w) [m/s]} 11 | 12 | \item{rho}{density of air [kg/m^3] (optional)} 13 | } 14 | \value{ 15 | CO2 flux [kg/(m^2*s)] 16 | } 17 | \description{ 18 | Converts cov(co2,w) to CO2 flux 19 | } 20 | -------------------------------------------------------------------------------- /man/cov2lh.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{cov2lh} 4 | \alias{cov2lh} 5 | \title{Converts cov(w,q) to latent heat flux LH} 6 | \usage{ 7 | cov2lh(cov_wq, rho = NULL) 8 | } 9 | \arguments{ 10 | \item{cov_wq}{covariance cov(w,q) [m/s]} 11 | 12 | \item{rho}{density of air [kg/m^3] (optional)} 13 | } 14 | \value{ 15 | latent heat flux [W/m^2] 16 | } 17 | \description{ 18 | Converts cov(w,q) to latent heat flux LH 19 | } 20 | -------------------------------------------------------------------------------- /man/cov2sh.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{cov2sh} 4 | \alias{cov2sh} 5 | \title{Converts cov(w,T) to sensible heat flux SH} 6 | \usage{ 7 | cov2sh(cov_wT, rho = NULL) 8 | } 9 | \arguments{ 10 | \item{cov_wT}{covariance cov(w,T) [K m/s]} 11 | 12 | \item{rho}{density of air [kg/m^3] (optional)} 13 | } 14 | \value{ 15 | sensible heat flux [W/m^2] 16 | } 17 | \description{ 18 | Converts cov(T,w) to sensible heat flux SH 19 | } 20 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: Reddy 2 | Type: Package 3 | Title: An open-source package for analyzing eddy-covariance measurements 4 | Version: 0.0.0.9000 5 | Author: Laura Mack 6 | Maintainer: Laura Mack 7 | Description: The package Reddy provides functions from post-processing over analyzing to plotting turbulence data from eddy-covariance measurements. 8 | Imports: pracma, MASS, RcppRoll, gsignal, fields 9 | License: GPL-3 10 | Encoding: UTF-8 11 | LazyData: true 12 | RoxygenNote: 7.2.3 13 | -------------------------------------------------------------------------------- /man/calc_windSpeed2D.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_windSpeed2D} 4 | \alias{calc_windSpeed2D} 5 | \title{Horizontal Wind Speed} 6 | \usage{ 7 | calc_windSpeed2D(u, v) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind [m/s]} 11 | 12 | \item{v}{v-wind [m/s]} 13 | } 14 | \value{ 15 | wind speed [m/s] 16 | } 17 | \description{ 18 | Calculates horizontal wind speed 19 | } 20 | \examples{ 21 | calc_windSpeed2D(3,3) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_Pr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_Pr} 4 | \alias{calc_Pr} 5 | \title{Calculates turbulent Prandtl number Pr = K_m/K_h} 6 | \usage{ 7 | calc_Pr(K_m, K_h) 8 | } 9 | \arguments{ 10 | \item{K_m}{eddy viscosity [m^2/s]} 11 | 12 | \item{K_h}{eddy conductivity [m^2/s]} 13 | } 14 | \value{ 15 | Prandtl number [-] 16 | } 17 | \description{ 18 | Calculates turbulent Prandtl number Pr 19 | } 20 | \examples{ 21 | calc_Pr(0.4,0.6) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_ef.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_ef} 4 | \alias{calc_ef} 5 | \title{Evaporative fraction} 6 | \usage{ 7 | calc_ef(sh, lh) 8 | } 9 | \arguments{ 10 | \item{sh}{sensible heat flux [W/m^2]} 11 | 12 | \item{lh}{latent heat flux [W/m^2]} 13 | } 14 | \value{ 15 | evaporative fraction [-] 16 | } 17 | \description{ 18 | Calculates the evaporative fraction EF := LH/(SH+LH) 19 | } 20 | \examples{ 21 | calc_ef(50,20) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_windDirection.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_windDirection} 4 | \alias{calc_windDirection} 5 | \title{Wind Direction} 6 | \usage{ 7 | calc_windDirection(u, v) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind [m/s]} 11 | 12 | \item{v}{v-wind [m/s]} 13 | } 14 | \value{ 15 | wind direction [deg] 16 | } 17 | \description{ 18 | Calculates (horizontal) wind direction 19 | } 20 | \examples{ 21 | calc_windDirection(3,3) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_xstar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_xstar} 4 | \alias{calc_xstar} 5 | \title{Calculates xstar (denominator for general flux-variance relation)} 6 | \usage{ 7 | calc_xstar(x, ustar) 8 | } 9 | \arguments{ 10 | \item{x}{variable that should be scaled} 11 | 12 | \item{ustar}{friction velocity [m/s]} 13 | } 14 | \value{ 15 | xstar = x/ustar 16 | } 17 | \description{ 18 | calculates xstar = x/ustar (for general flux-variance relation) 19 | } 20 | -------------------------------------------------------------------------------- /man/calc_br.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_br} 4 | \alias{calc_br} 5 | \title{Bowen ratio BR} 6 | \usage{ 7 | calc_br(sh, lh) 8 | } 9 | \arguments{ 10 | \item{sh}{sensible heat flux [W/m^2]} 11 | 12 | \item{lh}{latent heat flux [W/m^2]} 13 | } 14 | \value{ 15 | Bowen ratio [-] 16 | } 17 | \description{ 18 | Calculates the Bowen ratio as ratio of sensible and latent heat flux, i.e., BR := SH/LH 19 | } 20 | \examples{ 21 | calc_br(50,20) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_gustfactor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_gustfactor} 4 | \alias{calc_gustfactor} 5 | \title{Gust Factor} 6 | \usage{ 7 | calc_gustfactor(ws_max, ws_mean) 8 | } 9 | \arguments{ 10 | \item{ws_max}{wind speed [m/s]} 11 | 12 | \item{ws_mean}{wind speed maximum [m/s]} 13 | } 14 | \value{ 15 | gust factor [-] 16 | } 17 | \description{ 18 | Calculates gust factor G := ws_max/ws_mean 19 | } 20 | \examples{ 21 | calc_gustfactor(6,3) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_windSpeed3D.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_windSpeed3D} 4 | \alias{calc_windSpeed3D} 5 | \title{Wind Speed (3D)} 6 | \usage{ 7 | calc_windSpeed3D(u, v, w) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind [m/s]} 11 | 12 | \item{v}{v-wind [m/s]} 13 | 14 | \item{w}{w-wind [m/s]} 15 | } 16 | \value{ 17 | wind speed (3D) [m/s] 18 | } 19 | \description{ 20 | Calculates wind speed (3D) 21 | } 22 | \examples{ 23 | calc_windSpeed3D(3,3,0.1) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_Km.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_Km} 4 | \alias{calc_Km} 5 | \title{Calculates eddy viscosity K_m = -cov(u,w)/(du/dz)} 6 | \usage{ 7 | calc_Km(cov_uw, du_dz) 8 | } 9 | \arguments{ 10 | \item{cov_uw}{covariance cov(u,w) [m^2/s^2]} 11 | 12 | \item{du_dz}{vertical wind speed gradient [1/s]} 13 | } 14 | \value{ 15 | eddy viscosity K_m [m^2/s] 16 | } 17 | \description{ 18 | Calculates eddy viscosity K_m 19 | } 20 | \examples{ 21 | calc_Km(-0.2,2) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_N2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_N2} 4 | \alias{calc_N2} 5 | \title{Brunt-Vaisala frequency squared} 6 | \usage{ 7 | calc_N2(T1, T2, dz) 8 | } 9 | \arguments{ 10 | \item{T1}{temperature at the lower level [K]} 11 | 12 | \item{T2}{temperature at the upper level [K]} 13 | 14 | \item{dz}{height difference of the two measurements [m]} 15 | } 16 | \value{ 17 | N2 [1/s^2] 18 | } 19 | \description{ 20 | calculates Brunt-Vaisala frequency squared (N^2) 21 | } 22 | -------------------------------------------------------------------------------- /man/calc_theta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_theta} 4 | \alias{calc_theta} 5 | \title{Potential temperature} 6 | \usage{ 7 | calc_theta(temp, pres) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K]} 11 | 12 | \item{pres}{pressure [Pa]} 13 | } 14 | \value{ 15 | potential temperature [K] 16 | } 17 | \description{ 18 | Calculates potential temperature for given temperature and pressure 19 | } 20 | \examples{ 21 | calc_theta(273,70000) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/fftfreq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{fftfreq} 4 | \alias{fftfreq} 5 | \title{FFT frequency} 6 | \usage{ 7 | fftfreq(n, res = 1) 8 | } 9 | \arguments{ 10 | \item{n}{length} 11 | 12 | \item{res}{spatial resolution (default: \code{res=1})} 13 | } 14 | \value{ 15 | vector of length n containing FFT frequencies 16 | } 17 | \description{ 18 | Returns FFT sampling frequencies (R version of the function fft.fftfreq in numpy) 19 | } 20 | \examples{ 21 | fftfreq(10) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/rh2ah.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{rh2ah} 4 | \alias{rh2ah} 5 | \title{Converts relative humidity to absolute humidity} 6 | \usage{ 7 | rh2ah(rh, temp) 8 | } 9 | \arguments{ 10 | \item{rh}{relative humidity [percent]} 11 | 12 | \item{temp}{temperature [K]} 13 | } 14 | \value{ 15 | absolute humidity [kg/m^3] 16 | } 17 | \description{ 18 | Calculates absolute humidity from relative humidity and temperature 19 | } 20 | \examples{ 21 | rh2ah(70,273) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/ah2rh.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{ah2rh} 4 | \alias{ah2rh} 5 | \title{Converts absolute humidity to relative humidity} 6 | \usage{ 7 | ah2rh(ah, temp) 8 | } 9 | \arguments{ 10 | \item{ah}{absolute humidity [kg/m^3]} 11 | 12 | \item{temp}{temperature [K]} 13 | } 14 | \value{ 15 | relative humidity [percent] 16 | } 17 | \description{ 18 | Calculates absolute humidity from relative humidity and temperature 19 | } 20 | \examples{ 21 | ah2rh(0.005,273) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_Kh.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_Kh} 4 | \alias{calc_Kh} 5 | \title{Calculates eddy conductivity K_h = -cov(w,T)/(dT/dz)} 6 | \usage{ 7 | calc_Kh(cov_wT, dT_dz) 8 | } 9 | \arguments{ 10 | \item{cov_wT}{covariance cov(w,T) [K m/s]} 11 | 12 | \item{dT_dz}{vertical temperature gradient [K/m]} 13 | } 14 | \value{ 15 | eddy conductivity K_h [m^2/s] 16 | } 17 | \description{ 18 | Calculates eddy conductivity K_h 19 | } 20 | \examples{ 21 | calc_Kh(0.2,-1) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/scale_phih.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{scale_phih} 4 | \alias{scale_phih} 5 | \title{Scaling function for heat Phi_h} 6 | \usage{ 7 | scale_phih(zeta, method = "BD") 8 | } 9 | \arguments{ 10 | \item{zeta}{stability parameter [-]} 11 | 12 | \item{method}{defining from which paper the scaling function should be used, default \code{method="ecmwf"} for for the ones used in ECMWF-IFS} 13 | } 14 | \value{ 15 | Phi_h 16 | } 17 | \description{ 18 | scaling function Phi_h 19 | } 20 | -------------------------------------------------------------------------------- /man/df_dx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model-utils.R 3 | \name{df_dx} 4 | \alias{df_dx} 5 | \title{df_dx} 6 | \usage{ 7 | df_dx(fld, xres = 1) 8 | } 9 | \arguments{ 10 | \item{fld}{input field with dimension (x,y)} 11 | 12 | \item{xres}{resolution in x-direction} 13 | } 14 | \value{ 15 | x-derivative of fld (same dimensions) 16 | } 17 | \description{ 18 | Calculates x-derivative for equidistant grid 19 | } 20 | \examples{ 21 | set.seed(5) 22 | field=matrix(rnorm(16),ncol=4) 23 | df_dx(field,10) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/df_dy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model-utils.R 3 | \name{df_dy} 4 | \alias{df_dy} 5 | \title{df_dy} 6 | \usage{ 7 | df_dy(fld, yres = 1) 8 | } 9 | \arguments{ 10 | \item{fld}{input field with dimension (x,y)} 11 | 12 | \item{yres}{resolution in y-direction} 13 | } 14 | \value{ 15 | y-derivative of fld (same dimensions) 16 | } 17 | \description{ 18 | Calculates y-derivative for equidistant grid 19 | } 20 | \examples{ 21 | set.seed(5) 22 | field=matrix(rnorm(16),ncol=4) 23 | df_dy(field,10) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/scale_phiw.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{scale_phiw} 4 | \alias{scale_phiw} 5 | \title{Scaling function for vertical windspeed Phi_w} 6 | \usage{ 7 | scale_phiw(zeta, method = "PD1984") 8 | } 9 | \arguments{ 10 | \item{zeta}{stability parameter [-]} 11 | 12 | \item{method}{defining from which paper the scaling function is used, default \code{method="PD1984"} for Panofsky and Dutton, 1984} 13 | } 14 | \value{ 15 | Phi_w 16 | } 17 | \description{ 18 | scaling function Phi_w 19 | } 20 | -------------------------------------------------------------------------------- /man/scale_phiu.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{scale_phiu} 4 | \alias{scale_phiu} 5 | \title{Scaling function for horizontal windspeed Phi_u} 6 | \usage{ 7 | scale_phiu(zeta, method = "PD1984") 8 | } 9 | \arguments{ 10 | \item{zeta}{stability parameter [-]} 11 | 12 | \item{method}{defining from which paper the scaling function is used, default \code{method="PD1984"} for Panofsky and Dutton, 1984} 13 | } 14 | \value{ 15 | Phi_u 16 | } 17 | \description{ 18 | scaling function Phi_u 19 | } 20 | -------------------------------------------------------------------------------- /man/calc_cov.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{calc_cov} 4 | \alias{calc_cov} 5 | \title{Calculates covariance of two timeseries using pair-wise complete observations} 6 | \usage{ 7 | calc_cov(x, y) 8 | } 9 | \arguments{ 10 | \item{x}{timeseries 1} 11 | 12 | \item{y}{timeseries 2} 13 | } 14 | \value{ 15 | cov(x,y) 16 | } 17 | \description{ 18 | Calculates cov(x,y) 19 | } 20 | \examples{ 21 | set.seed(5) 22 | x=rnorm(100) 23 | y=rnorm(100) 24 | y[1:10]=NA 25 | cov_xy=calc_cov(x,y) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/calc_ustar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_ustar} 4 | \alias{calc_ustar} 5 | \title{Friction Velocity} 6 | \usage{ 7 | calc_ustar(cov_uw, cov_vw) 8 | } 9 | \arguments{ 10 | \item{cov_uw}{covariance cov(u,w) [m^2/s^2]} 11 | 12 | \item{cov_vw}{covariance cov(v,w) [m^2/s^2]} 13 | } 14 | \value{ 15 | friction velocity [m/s] 16 | } 17 | \description{ 18 | Calculates friction velocity from the covariances cov(u,w) and cov(v,w) 19 | } 20 | \examples{ 21 | calc_ustar(1,1) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_Tv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_Tv} 4 | \alias{calc_Tv} 5 | \title{Virtual temperature} 6 | \usage{ 7 | calc_Tv(temp, q) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K]} 11 | 12 | \item{q}{specific humidity [kg/kg]} 13 | } 14 | \value{ 15 | virtual temperature [K] 16 | } 17 | \description{ 18 | Calculates virtual temperature for given temperature and specific humidity (mixing ratio) 19 | } 20 | \examples{ 21 | calc_Tv(273,0) #no difference 22 | calc_Tv(273,0.1) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/calc_iw.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_iw} 4 | \alias{calc_iw} 5 | \title{Vertical Turbulence Intensity Iw} 6 | \usage{ 7 | calc_iw(w_sd, ws_mean) 8 | } 9 | \arguments{ 10 | \item{w_sd}{standard deviation of vertical wind (w-wind)} 11 | 12 | \item{ws_mean}{horizontal wind speed} 13 | } 14 | \value{ 15 | vertical turbulence intensity [-] 16 | } 17 | \description{ 18 | Calculates vertical turbulence intensity \code{Iw = w_sd/ws_mean} 19 | } 20 | \examples{ 21 | calc_iw(1,3) #unstable 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_vpd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_vpd} 4 | \alias{calc_vpd} 5 | \title{Vapor pressure deficit (VPD)} 6 | \usage{ 7 | calc_vpd(temp, rh) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K]} 11 | 12 | \item{rh}{relative humidity [percent]} 13 | } 14 | \value{ 15 | VPD, vapor pressure deficit [Pa] 16 | } 17 | \description{ 18 | Calculates vapor pressure deficit (VPD) from temperature and relative humidity using Arrhenius formula 19 | } 20 | \examples{ 21 | calc_vpd(273,70) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/Reddy-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package-description.R 3 | \docType{package} 4 | \name{Reddy package} 5 | \alias{Reddy package} 6 | \title{Introduction} 7 | \description{ 8 | EC postprocessing and analysis 9 | } 10 | \details{ 11 | to be detailed 12 | } 13 | \references{ 14 | \itemize{ 15 | \item Mack, L., Berntsen, T.K., Vercauteren, N., Pirk, N. (2024). Transfer Efficiency and Organization in Turbulent Transport over Alpine Tundra. Boundary-Layer Meteorology 190, 38. doi: https://doi.org/10.1007/s10546-024-00879-5 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /man/calc_circular_mean.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/auxilliary.R 3 | \name{calc_circular_mean} 4 | \alias{calc_circular_mean} 5 | \title{calculates circular mean} 6 | \usage{ 7 | calc_circular_mean(x, na.rm = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{input vector, e.g. wind directions [degree]} 11 | 12 | \item{na.rm}{should NA values be removed? default \code{TRUE}} 13 | } 14 | \value{ 15 | circular mean of x values 16 | } 17 | \description{ 18 | calculates circular mean 19 | } 20 | \examples{ 21 | wd=c(280,90) 22 | calc_circular_mean(wd) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/calc_k2d.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{calc_k2d} 4 | \alias{calc_k2d} 5 | \title{Calculates 2d (horizontal) wavenumber matrix from kx, ky} 6 | \usage{ 7 | calc_k2d(kx, ky) 8 | } 9 | \arguments{ 10 | \item{kx}{wavenumber in x-direction} 11 | 12 | \item{ky}{wavenumber in y-direction} 13 | } 14 | \value{ 15 | total spatial (horizontal) wavenumber k 16 | } 17 | \description{ 18 | Calculates 2d (horizontal) wavenumber matrix from kx, ky 19 | } 20 | \examples{ 21 | kx=c(1:10)/10 22 | ky=c(1:8)/8 23 | k=calc_k2d(kx,ky) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_satvaporpressure.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_satvaporpressure} 4 | \alias{calc_satvaporpressure} 5 | \title{Saturation vapor pressure over water} 6 | \usage{ 7 | calc_satvaporpressure(temp) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K]} 11 | } 12 | \value{ 13 | E_s, saturation vapor pressure over water [Pa] 14 | } 15 | \description{ 16 | Calculates the saturation vapor pressure over water for given temperature and pressure 17 | } 18 | \examples{ 19 | calc_satvaporpressure(273) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/rh2q.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{rh2q} 4 | \alias{rh2q} 5 | \title{Converts relative humidity to specific humidity} 6 | \usage{ 7 | rh2q(rh, temp, pres) 8 | } 9 | \arguments{ 10 | \item{rh}{relative humidity [percent]} 11 | 12 | \item{temp}{temperature [K]} 13 | 14 | \item{pres}{pressure [Pa]} 15 | } 16 | \value{ 17 | specific humidity [kg/kg] 18 | } 19 | \description{ 20 | Calculates specific humidity from relative humidity, temperature and pressure 21 | } 22 | \examples{ 23 | rh2q(70,273,101300) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/lh2et.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{lh2et} 4 | \alias{lh2et} 5 | \title{Evapotranspiration} 6 | \usage{ 7 | lh2et(lh, temp = NULL) 8 | } 9 | \arguments{ 10 | \item{lh}{latent heat flux [W/m^2]} 11 | 12 | \item{temp}{temperature [K] (optional), if provided, the latent heat of vaporization is calculated temperature-dependent} 13 | } 14 | \value{ 15 | evapotranspiration [kg/(s*m^2)] 16 | } 17 | \description{ 18 | Converts latent heat flux to evaporation 19 | } 20 | \examples{ 21 | lh2et(20) 22 | lh2et(20,273) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/scale_phiT.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{scale_phiT} 4 | \alias{scale_phiT} 5 | \title{Scaling function for temperature Phi_T} 6 | \usage{ 7 | scale_phiT(zeta, method = "K1994") 8 | } 9 | \arguments{ 10 | \item{zeta}{stability parameter [-]} 11 | 12 | \item{method}{defining from which paper the scaling function should be used, default \code{method="K1994"} for Katul, 1994, other option \code{method="SC2018"} for Stiperski and Calaf, 2018} 13 | } 14 | \value{ 15 | Phi_T 16 | } 17 | \description{ 18 | scaling function Phi_T 19 | } 20 | -------------------------------------------------------------------------------- /man/calc_phix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_phix} 4 | \alias{calc_phix} 5 | \title{Calculates Phi_x (general flux-variance relation)} 6 | \usage{ 7 | calc_phix(sigma_x, x, ustar) 8 | } 9 | \arguments{ 10 | \item{sigma_x}{standard deviation of x} 11 | 12 | \item{x}{variable that should be scaled, e.g. vertical flux of x with x = T or x = q} 13 | 14 | \item{ustar}{friction velocity [m/s]} 15 | } 16 | \value{ 17 | Phi_x = sigma_x/xstar 18 | } 19 | \description{ 20 | calculates Phi_x = sigma_x/xstar (for general flux-variance relation) 21 | } 22 | -------------------------------------------------------------------------------- /man/scale_phim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{scale_phim} 4 | \alias{scale_phim} 5 | \title{Scaling function for momentum Phi_m} 6 | \usage{ 7 | scale_phim(zeta, method = "ecmwf") 8 | } 9 | \arguments{ 10 | \item{zeta}{stability parameter [-]} 11 | 12 | \item{method}{defining from which paper the scaling function should be used, default \code{method="ecmwf"} for the ones used in ECMWF-IFS, other option \code{method="BD"} for the linear Businger-Dyer relations} 13 | } 14 | \value{ 15 | Phi_m 16 | } 17 | \description{ 18 | scaling function Phi_m 19 | } 20 | -------------------------------------------------------------------------------- /man/calc_zeta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_zeta} 4 | \alias{calc_zeta} 5 | \title{Stability Parameter} 6 | \usage{ 7 | calc_zeta(z, L) 8 | } 9 | \arguments{ 10 | \item{z}{measurement height [m]} 11 | 12 | \item{L}{Obukhov length [m] (e.g., from \code{calc_L})} 13 | } 14 | \value{ 15 | stability parameter [-] 16 | } 17 | \description{ 18 | Calculates dimensionless stability parameter from Obukhov length and measurement height, i.e. \code{zeta = z/L} 19 | } 20 | \examples{ 21 | calc_zeta(2,-1) #unstable 22 | calc_zeta(2,1) #stable 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/calc_dshear.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_dshear} 4 | \alias{calc_dshear} 5 | \title{Directional Shear} 6 | \usage{ 7 | calc_dshear(cov_uw, cov_vw) 8 | } 9 | \arguments{ 10 | \item{cov_uw}{covariance cov(u,w)} 11 | 12 | \item{cov_vw}{covariance cov(v,w)} 13 | } 14 | \value{ 15 | angle that describes the impact of directional shear [deg] 16 | } 17 | \description{ 18 | Calculates a measure for directional shear alpha_uw = arctan(cov(v,w)/cov(u,w)) 19 | } 20 | \examples{ 21 | calc_dshear(-0.5,0) #no shear 22 | calc_dshear(-0.5,-0.1) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/calc_phim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_phim} 4 | \alias{calc_phim} 5 | \title{Calculates Phi_m} 6 | \usage{ 7 | calc_phim(U1, U2, ustar, zm, dz) 8 | } 9 | \arguments{ 10 | \item{U1}{wind speed at the lower level [m/s]} 11 | 12 | \item{U2}{wind speed at the upper level [m/s]} 13 | 14 | \item{ustar}{friction velocity [m/s]} 15 | 16 | \item{zm}{measurement/scaling height [m]} 17 | 18 | \item{dz}{height difference of the two measurements [m]} 19 | } 20 | \value{ 21 | Phi_m 22 | } 23 | \description{ 24 | calculates scaling function Phi_m (for momentum) 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_ri.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_ri} 4 | \alias{calc_ri} 5 | \title{Calculates bulk Richardson number Ri} 6 | \usage{ 7 | calc_ri(T1, T2, U1, U2, dz) 8 | } 9 | \arguments{ 10 | \item{T1}{temperature at the lower level [K]} 11 | 12 | \item{T2}{temperature at the upper level [K]} 13 | 14 | \item{U1}{wind speed at the lower level [m/s]} 15 | 16 | \item{U2}{wind speed at the upper level [m/s]} 17 | 18 | \item{dz}{height difference of the two measurements [m]} 19 | } 20 | \value{ 21 | Ri [-] 22 | } 23 | \description{ 24 | calculates Richardson number Ri 25 | } 26 | -------------------------------------------------------------------------------- /man/sigma2height.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model-utils.R 3 | \name{sigma2height} 4 | \alias{sigma2height} 5 | \title{Converts hybrid (terrain-following) sigma levels to physical heights} 6 | \usage{ 7 | sigma2height(hybrid, Tv = 273.15) 8 | } 9 | \arguments{ 10 | \item{hybrid}{scalar or vector, hybrid sigma levels} 11 | 12 | \item{Tv}{virtual temperature} 13 | } 14 | \value{ 15 | hybrid levels converted to physical height [m] 16 | } 17 | \description{ 18 | Converts hybrid (terrain-following) sigma levels to physical heights 19 | } 20 | \examples{ 21 | sigma2height(0.1) 22 | sigma2height(0.1,288) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/ustar2z0.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{ustar2z0} 4 | \alias{ustar2z0} 5 | \title{Calculates surface roughness length z0 from friction velocity using the simple estimate from Charnock, 1955} 6 | \usage{ 7 | ustar2z0(ustar) 8 | } 9 | \arguments{ 10 | \item{ustar}{friction velocity [m/s]} 11 | } 12 | \value{ 13 | surface roughness length [m] 14 | } 15 | \description{ 16 | Calculates surface roughness z0 from friction velocity using the simple estimate from Charnock, 1955: z0 = alpha*ustar^2/g with alpha=0.016 and g=9.81 m/s^2 17 | } 18 | \examples{ 19 | ustar2z0(0.2) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/calc_tke.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_tke} 4 | \alias{calc_tke} 5 | \title{Turbulent Kinetic Energy TKE} 6 | \usage{ 7 | calc_tke(u_sd, v_sd, w_sd) 8 | } 9 | \arguments{ 10 | \item{u_sd}{standard deviation of u-wind [m/s]} 11 | 12 | \item{v_sd}{standard deviation of v-wind [m/s]} 13 | 14 | \item{w_sd}{standard deviation of w-wind [m/s]} 15 | } 16 | \value{ 17 | turbulent kinetic energy TKE [m^2/s^2] 18 | } 19 | \description{ 20 | Calculates turbulent kinetic energy (TKE) from \code{u_sd}, \code{v_sd} and \code{w_sd} 21 | } 22 | \examples{ 23 | calc_tke(1,1,1) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_L.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_L} 4 | \alias{calc_L} 5 | \title{Obukhov length} 6 | \usage{ 7 | calc_L(ustar, T_mean, cov_wT) 8 | } 9 | \arguments{ 10 | \item{ustar}{friction velocity (e.g., from \code{calc_ustar}) [m/s]} 11 | 12 | \item{T_mean}{mean temperature [K]} 13 | 14 | \item{cov_wT}{covariance cov(w,T) [m/s K]} 15 | } 16 | \value{ 17 | Obukhov length [m] 18 | } 19 | \description{ 20 | Calculates Obukhov length from friction velocity, mean temperature and cov(T,w) 21 | } 22 | \examples{ 23 | calc_L(0.2,273,0.1) #unstable 24 | calc_L(0.2,273,-0.1) #stable 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/calc_csi.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{calc_csi} 4 | \alias{calc_csi} 5 | \title{Clear Sky Index (CSI)} 6 | \usage{ 7 | calc_csi(temp, lw_in, rh = NULL, e = NULL) 8 | } 9 | \arguments{ 10 | \item{temp}{temperature [K]} 11 | 12 | \item{lw_in}{longwave incoming radiation [W/m^2]} 13 | 14 | \item{rh}{relative humidity [percent]} 15 | 16 | \item{e}{vapor pressure [Pa] (either rh or e have to be given)} 17 | } 18 | \value{ 19 | CSI, clear sky index 20 | } 21 | \description{ 22 | Calculates clear sky index 23 | } 24 | \examples{ 25 | calc_csi(273,230,70) #with relative humidity 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/calc_ozmidov_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_ozmidov_scale} 4 | \alias{calc_ozmidov_scale} 5 | \title{Ozmidov scale (L_OZ)} 6 | \usage{ 7 | calc_ozmidov_scale(epsilon, N) 8 | } 9 | \arguments{ 10 | \item{epsilon}{dissipation rate of TKE or w [m*s]} 11 | 12 | \item{N}{Brunt-Vaisala frequency [1/s]} 13 | } 14 | \value{ 15 | Ozmidov length scale [m] 16 | } 17 | \description{ 18 | Calculates the Ozmidov length scale L_OZ = sqrt(epsilon/N^3), with epsilon: TKE dissipation rate, and N: Brunt-Vaisala frequency 19 | } 20 | \examples{ 21 | calc_ozmidov_scale(-5/3,1*10^-4) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_ti.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_ti} 4 | \alias{calc_ti} 5 | \title{Horizontal Turbulence Intensity TI} 6 | \usage{ 7 | calc_ti(u_sd, v_sd, ws_mean) 8 | } 9 | \arguments{ 10 | \item{u_sd}{standard deviation of streamwise wind (u-wind)} 11 | 12 | \item{v_sd}{standard deviation of crosswise wind (v-wind)} 13 | 14 | \item{ws_mean}{horizontal wind speed} 15 | } 16 | \value{ 17 | horizontal turbulence intensity [-] 18 | } 19 | \description{ 20 | Calculates horizontal turbulence intensity \code{TI = sqrt(u_sd^2+v_sd^2)/ws_mean} 21 | } 22 | \examples{ 23 | calc_ti(1,1,3) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/deaccumulate1h.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model-utils.R 3 | \name{deaccumulate1h} 4 | \alias{deaccumulate1h} 5 | \title{deaccumulation} 6 | \usage{ 7 | deaccumulate1h(dat, factor = -1/3600) 8 | } 9 | \arguments{ 10 | \item{dat}{vector (with dimension time) or array (with dimension x, y, time)} 11 | 12 | \item{factor}{factor for unit and sign conversion, default: \code{factor = -1/3600} for converting hour to seconds and adapting the sign convention} 13 | } 14 | \value{ 15 | vector or array hourly deaccumulated (same dimension as input) 16 | } 17 | \description{ 18 | hourly deaccumulation, e.g. for fluxes from model output 19 | } 20 | -------------------------------------------------------------------------------- /man/plot_mrd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/multiresolution-decomposition.R 3 | \name{plot_mrd} 4 | \alias{plot_mrd} 5 | \title{Plotting Multiresolution Decomposition} 6 | \usage{ 7 | plot_mrd(mrd_out, ...) 8 | } 9 | \arguments{ 10 | \item{mrd_out}{an object returned from \code{calc_mrd}} 11 | 12 | \item{...}{parameters passed to plot function} 13 | } 14 | \value{ 15 | creates a plot of MRD with logarithmic time scale (no return) 16 | } 17 | \description{ 18 | Plots multiresolution decomposition (MRD) 19 | } 20 | \examples{ 21 | set.seed(5) 22 | series=rnorm(2^10) 23 | mrd_test=calc_mrd(c(series)) 24 | plot_mrd(mrd_test) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/calc_vtke.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_vtke} 4 | \alias{calc_vtke} 5 | \title{Turbulent Kinetic Energy Velocity Scale} 6 | \usage{ 7 | calc_vtke(u_sd, v_sd, w_sd) 8 | } 9 | \arguments{ 10 | \item{u_sd}{standard deviation of u-wind [m/s]} 11 | 12 | \item{v_sd}{standard deviation of v-wind [m/s]} 13 | 14 | \item{w_sd}{standard deviation of w-wind [m/s]} 15 | } 16 | \value{ 17 | turbulent kinetic energy velocity scale [m/s] 18 | } 19 | \description{ 20 | Calculates the velocity scale of turbulent kinetic energy (TKE): \code{Vtke = sqrt(TKE)} 21 | } 22 | \examples{ 23 | calc_vtke(1,1,1) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_phit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_phit} 4 | \alias{calc_phit} 5 | \title{Calculates Phi_t} 6 | \usage{ 7 | calc_phit(T1, T2, cov_wT, ustar, zm, dz) 8 | } 9 | \arguments{ 10 | \item{T1}{temperature at the lower level [K]} 11 | 12 | \item{T2}{temperature at the upper level [K]} 13 | 14 | \item{cov_wT}{covariance cov(w,T) [K m/s]} 15 | 16 | \item{ustar}{friction velocity [m/s]} 17 | 18 | \item{zm}{measurement/scaling height [m]} 19 | 20 | \item{dz}{height difference of the two measurements [m]} 21 | } 22 | \value{ 23 | Phi_t 24 | } 25 | \description{ 26 | calculate scaling function Phi_t (for heat) 27 | } 28 | -------------------------------------------------------------------------------- /man/calc_decoupling_metric.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_decoupling_metric} 4 | \alias{calc_decoupling_metric} 5 | \title{Decoupling metric (Omega)} 6 | \usage{ 7 | calc_decoupling_metric(w_sd, N, z = 2) 8 | } 9 | \arguments{ 10 | \item{w_sd}{standard deviation of vertical velocity [m/s]} 11 | 12 | \item{N}{Brunt-Vaisala frequency [1/s]} 13 | 14 | \item{z}{measurement height [m]} 15 | } 16 | \value{ 17 | decoupling metric (Omega) [-] 18 | } 19 | \description{ 20 | Calculates the decoupling metric (Omega) from Peltola et al., 2021 (without vegetation) 21 | } 22 | \examples{ 23 | calc_decoupling_metric(1,1) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/calc_ekman_layer_depth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_ekman_layer_depth} 4 | \alias{calc_ekman_layer_depth} 5 | \title{Ekman layer thickness} 6 | \usage{ 7 | calc_ekman_layer_depth(Km, f) 8 | } 9 | \arguments{ 10 | \item{Km}{eddy diffusivity [m^2/s]} 11 | 12 | \item{f}{Coriolis parameter [1/s] (e.g. from \code{calc_coriolis})} 13 | } 14 | \value{ 15 | Ekman layer thickness [m] (derived from boundary layer equations) 16 | } 17 | \description{ 18 | Calculates Ekman layer thickness from eddy diffusivity and Coriolis parameter sqrt(2*Km/abs(f)) 19 | } 20 | \examples{ 21 | calc_ekman_layer_depth(0.1,10^(-4)) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/calc_var.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_var} 4 | \alias{calc_var} 5 | \title{Velocity Aspect Ratio (VAR)} 6 | \usage{ 7 | calc_var(u_sd, v_sd, w_sd) 8 | } 9 | \arguments{ 10 | \item{u_sd}{standard deviation of streamwise wind (u-wind)} 11 | 12 | \item{v_sd}{standard deviation of crosswise wind (v-wind)} 13 | 14 | \item{w_sd}{standard deviation of vertical wind (w-wind)} 15 | } 16 | \value{ 17 | velocity aspect ratio [-] 18 | } 19 | \description{ 20 | Calculates the velocity aspect ratio: \code{VAR = sqrt(2)*w_sd/sqrt(u_sd^2+v_sd^2)} 21 | } 22 | \examples{ 23 | calc_var(1,1,1) #"isotropic" 24 | calc_var(1,1,2) #not isotropic 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/calc_distance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model-utils.R 3 | \name{calc_distance} 4 | \alias{calc_distance} 5 | \title{Calculates distance between two points given in lon,lat} 6 | \usage{ 7 | calc_distance(lon1, lat1, lon2, lat2) 8 | } 9 | \arguments{ 10 | \item{lon1}{longitude location 1 [deg]} 11 | 12 | \item{lat1}{latitude location 1 [deg]} 13 | 14 | \item{lon2}{longitude location 2 [deg]} 15 | 16 | \item{lat2}{latitude location 2 [deg]} 17 | } 18 | \value{ 19 | distance between two points [m] 20 | } 21 | \description{ 22 | Calculates y-derivative for equidistant grid 23 | } 24 | \examples{ 25 | set.seed(5) 26 | field=matrix(rnorm(16),ncol=4) 27 | df_dy(field,10) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/rotate_double.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{rotate_double} 4 | \alias{rotate_double} 5 | \title{Double rotation} 6 | \usage{ 7 | rotate_double(u, v, w) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind (levelled sonic)} 11 | 12 | \item{v}{v-wind (levelled sonic)} 13 | 14 | \item{w}{w-wind (levelled sonic)} 15 | } 16 | \value{ 17 | list containing the wind in a natural coordinate system (streamwise, crosswise, vertical) and the two rotation angles theta and phi 18 | } 19 | \description{ 20 | Double rotation (i.e., sonic coordinate system will be aligned with streamlines) 21 | } 22 | \examples{ 23 | wind_rotated=rotate_double(4,3,1) #double rotation can be applied instantenously 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/pres2height.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-meteorology.R 3 | \name{pres2height} 4 | \alias{pres2height} 5 | \title{Converts pressure to height (using barometric formula)} 6 | \usage{ 7 | pres2height(pres, pres0 = 101315, temp0 = 288.15) 8 | } 9 | \arguments{ 10 | \item{pres}{pressure [Pa]} 11 | 12 | \item{pres0}{reference pressure, scalar [Pa], default \code{pres0=101315}} 13 | 14 | \item{temp0}{reference temperature, scalar [K], default \code{temp0=288.15}} 15 | } 16 | \value{ 17 | height [m] 18 | } 19 | \description{ 20 | Calculates height from pressure 21 | } 22 | \examples{ 23 | pres2height(60000) #using default surface values 24 | pres2height(60000,95000,265) #adapted surface values 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/calc_spectrum.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{calc_spectrum} 4 | \alias{calc_spectrum} 5 | \title{Spectrum of timeseries by wrapping rbase::spectrum()} 6 | \usage{ 7 | calc_spectrum(ts, nbins = 100, plot = TRUE) 8 | } 9 | \arguments{ 10 | \item{ts}{timeseries} 11 | 12 | \item{nbins}{number of bins used to average the spectrum, default \code{nbins=100}} 13 | 14 | \item{plot}{should the spectrum be plotted? default \code{plot=TRUE}} 15 | } 16 | \value{ 17 | binned spectrum 18 | } 19 | \description{ 20 | Calculates and plots the averaged turbulence spectrum (as wrapper of rbase::spectrum) 21 | } 22 | \examples{ 23 | set.seed(5) 24 | ts=rnorm(1000) 25 | calc_spectrum(ts,nbins=100,plot=FALSE) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/plot_flux_footprint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/flux-footprint.R 3 | \name{plot_flux_footprint} 4 | \alias{plot_flux_footprint} 5 | \title{Plot Flux-Footprint} 6 | \usage{ 7 | plot_flux_footprint(ffp, levels = c(0, 10^seq(-6, -3, 0.1))) 8 | } 9 | \arguments{ 10 | \item{ffp}{an object returned from \code{calc_flux_footprint}} 11 | 12 | \item{levels}{levels used for filled contour plot of footprint, default \code{levels=c(0,10^seq(-6,-3,0.1))}} 13 | } 14 | \value{ 15 | no return 16 | } 17 | \description{ 18 | Plots Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015 19 | } 20 | \examples{ 21 | ffp=calc_flux_footprint(zm=5,ws_mean=5,blh=700,L=-1.3,v_sd=1.2,ustar=0.35) 22 | plot_flux_footprint(ffp) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/calc_rif.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_rif} 4 | \alias{calc_rif} 5 | \title{Calculates flux Richardson number Ri_f} 6 | \usage{ 7 | calc_rif(cov_wT, cov_uw, U1, U2, dz, T_mean = NULL) 8 | } 9 | \arguments{ 10 | \item{cov_wT}{covariance cov(w,T) [K m/s]} 11 | 12 | \item{cov_uw}{covariance cov(u,w) [m^2/s^2]} 13 | 14 | \item{U1}{wind speed at the lower level [m/s]} 15 | 16 | \item{U2}{wind speed at the upper level [m/s]} 17 | 18 | \item{dz}{height difference of the two measurements [m]} 19 | 20 | \item{T_mean}{mean temperature [K] (optional, used instead of T0=273.15)} 21 | } 22 | \value{ 23 | Ri_f [-] 24 | } 25 | \description{ 26 | calculates flux Richardson number Ri_f = g/T_mean*cov(w,T)/(cov(u,w)*du/dz) 27 | } 28 | -------------------------------------------------------------------------------- /man/flag_w.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{flag_w} 4 | \alias{flag_w} 5 | \title{Vertical Velocity Flag} 6 | \usage{ 7 | flag_w(w, thresholds_w = c(0.1, 0.15)) 8 | } 9 | \arguments{ 10 | \item{w}{vertical velocity} 11 | 12 | \item{thresholds_w}{vector containing 2 elements to distinguish between flag=0 and flag=1, as well as flag=1 and flag=2, default: \code{c(0.1,0.15)}} 13 | } 14 | \value{ 15 | vertical velocity flags (0: in full agreement with the criterion ... 2: does not fulfill the criterion) 16 | } 17 | \description{ 18 | Vertical velocity flag according to Mauder et al., 2013: After rotation the vertical velocity should vanish, this flag flags high remaining vertical velocities. 19 | } 20 | \examples{ 21 | flag_w(0.01) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /man/RTcorrection.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{RTcorrection} 4 | \alias{RTcorrection} 5 | \title{Response-time correction factor (spectral correction)} 6 | \usage{ 7 | RTcorrection(cospectrum, freq, tau = 1) 8 | } 9 | \arguments{ 10 | \item{cospectrum}{cospectrum} 11 | 12 | \item{freq}{frequency [Hz], corresponding to the cospectrum, i.e. same length} 13 | 14 | \item{tau}{response time of the instrument [s] (has to be determined first by comparison with another instrument, that samples faster)} 15 | } 16 | \value{ 17 | response-time correction factor (which then can be used to correct the covariance and fluxes by multiplication) 18 | } 19 | \description{ 20 | Calculates the response-time correction factor from cospectrum, e.g. Peltola et al., 2021 21 | } 22 | -------------------------------------------------------------------------------- /man/ppt2rho.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{ppt2rho} 4 | \alias{ppt2rho} 5 | \title{Unit conversion of "parts-per" to density (for closed-path gas analyzer)} 6 | \usage{ 7 | ppt2rho(ppt, T_mean = 288.15, pres = 101325, e = 0, gas = "H2O") 8 | } 9 | \arguments{ 10 | \item{ppt}{measurement in parts per thousand [ppt]} 11 | 12 | \item{T_mean}{temperature [K]} 13 | 14 | \item{pres}{pressure [Pa]} 15 | 16 | \item{e}{water vapor pressure [Pa]} 17 | 18 | \item{gas}{which gas? can be either \code{H2O}, \code{CO2}, \code{CH4} (if \code{CO2}/\code{CH4} is selected, make sure that it's still in ppt and not ppm as usual)} 19 | } 20 | \value{ 21 | density of the gas [kg/m^3] 22 | } 23 | \description{ 24 | Unit conversion of "parts-per" to density (for closed-path gas analyzer) 25 | } 26 | -------------------------------------------------------------------------------- /man/binning.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/auxilliary.R 3 | \name{binning} 4 | \alias{binning} 5 | \title{discrete binning} 6 | \usage{ 7 | binning(var1, var2, bins) 8 | } 9 | \arguments{ 10 | \item{var1}{vector, variable that should be binned} 11 | 12 | \item{var2}{vector, variable used for the binning} 13 | 14 | \item{bins}{vector, providing the intervals of the bins of \code{var2}} 15 | } 16 | \value{ 17 | matrix of dimension (\code{length(bins)-1,4}) with columns representing mean, median, q25, q75 18 | } 19 | \description{ 20 | discrete binning of a variable \code{var1} based on another variable \code{var2} (e.g., the stability parameter \code{zeta}) 21 | } 22 | \examples{ 23 | zeta_bins=c(-10^(3:-3),10^(-3:3)) 24 | zeta_vals=rnorm(1000) 25 | vals=runif(1000) 26 | binned=binning(vals,zeta_vals,zeta_bins) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /man/averaging.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/auxilliary.R 3 | \name{averaging} 4 | \alias{averaging} 5 | \title{accumulating / averaging} 6 | \usage{ 7 | averaging(var, tres1 = 0.05, tres2 = c(1, 10, 30) * 60) 8 | } 9 | \arguments{ 10 | \item{var}{timeseries} 11 | 12 | \item{tres1}{time resolution [s] of the given timeseries \code{var}, default \code{tres1 = 0.05} (for 20 Hz)} 13 | 14 | \item{tres2}{desired time resolution(s) [s] of the averaged timeseries (scalar or vector), default \code{tres2 = c(1,10,30)*60} (for 1, 10 and 30 minutes)} 15 | } 16 | \value{ 17 | list containing mean and standard deviation of the timeseries for the desired time interval(s) 18 | } 19 | \description{ 20 | averaging of a timeseries 21 | } 22 | \examples{ 23 | ts=rnorm(30*60*20) #30 minutes of 20 Hz measurements 24 | averaging(ts) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/shift2maxccf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/auxilliary.R 3 | \name{shift2maxccf} 4 | \alias{shift2maxccf} 5 | \title{Shifting two timeseries to match maximum cross-correlation} 6 | \usage{ 7 | shift2maxccf(var1, var2, plot = TRUE) 8 | } 9 | \arguments{ 10 | \item{var1}{vector, first timeseries} 11 | 12 | \item{var2}{vector, second timeseries} 13 | 14 | \item{plot}{logical, should the cross-correlation be plotted? default \code{plot = TRUE}} 15 | } 16 | \value{ 17 | a matrix cotaining timeseries \code{var1} and \code{var2} as columns after shifting to the maximum cross-correlation 18 | } 19 | \description{ 20 | Shifts two timeseries to match their maximum cross-correlation (can be used e.g. for lag-time correction) 21 | } 22 | \examples{ 23 | ts1=runif(10) 24 | ts2=c(1,1,ts1) 25 | shifted=shift2maxccf(ts1,ts2) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/gapfilling.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/auxilliary.R 3 | \name{gapfilling} 4 | \alias{gapfilling} 5 | \title{gap-filling} 6 | \usage{ 7 | gapfilling(var, nmissing = 4, method = "linear") 8 | } 9 | \arguments{ 10 | \item{var}{timeseries, where NA indicates missing values that should be filled} 11 | 12 | \item{nmissing}{number of allowed missing values, default \code{nmissing = 4}} 13 | 14 | \item{method}{interpolation method, can be either \code{method = "linear"} for linear interpolation (default) or \code{method = "constant"} for constant interpolation} 15 | } 16 | \value{ 17 | gap-filled timeseries 18 | } 19 | \description{ 20 | gap-filling of a timeseries based on linear or constant interpolation 21 | } 22 | \examples{ 23 | ts1=c(1,2,NA,0) 24 | gapfilling(ts1) #1,2,1,0 25 | gapfilling(ts1,method="constant") #1,2,2,0 26 | gapfilling(ts1,nmissing=0) #too many missing values 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | .RDataTmp 8 | 9 | # User-specific files 10 | .Ruserdata 11 | 12 | # Example code in package build process 13 | *-Ex.R 14 | 15 | # Output files from R CMD build 16 | /*.tar.gz 17 | 18 | # Output files from R CMD check 19 | /*.Rcheck/ 20 | 21 | # RStudio files 22 | .Rproj.user/ 23 | 24 | # produced vignettes 25 | vignettes/*.html 26 | vignettes/*.pdf 27 | 28 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 29 | .httr-oauth 30 | 31 | # knitr and R markdown default cache directories 32 | *_cache/ 33 | /cache/ 34 | 35 | # Temporary files created by R markdown 36 | *.utf8.md 37 | *.knit.md 38 | 39 | # R Environment Variables 40 | .Renviron 41 | 42 | # pkgdown site 43 | docs/ 44 | 45 | # translation temp files 46 | po/*~ 47 | 48 | # RStudio Connect folder 49 | rsconnect/ 50 | 51 | # development 52 | R/dev/* 53 | 54 | *package-description.R -------------------------------------------------------------------------------- /man/rotate_planar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{rotate_planar} 4 | \alias{rotate_planar} 5 | \title{Planar fit rotation} 6 | \usage{ 7 | rotate_planar(u, v, w, bias = c(0, 0, 0)) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind (levelled sonic)} 11 | 12 | \item{v}{v-wind (levelled sonic)} 13 | 14 | \item{w}{w-wind (levelled sonic)} 15 | 16 | \item{bias}{a three-dimensional correction vector containing the offsets of u-, v-, w-wind} 17 | } 18 | \value{ 19 | list containing u, v, w after planar fit rotation as well as the rotation angles alpha, beta and gamma and the fitted offset c3 20 | } 21 | \description{ 22 | Planar fit rotation (i.e., sonic coordinate system will be aligned with the mean streamlines resulting in vanishing of w_mean) 23 | } 24 | \examples{ 25 | u=rnorm(1000) 26 | v=rnorm(1000) 27 | w=rnorm(1000) 28 | wind_rotated=rotate_planar(u,v,w) #for planar fit a timeseries is required 29 | 30 | } 31 | -------------------------------------------------------------------------------- /man/flag_most.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{flag_most} 4 | \alias{flag_most} 5 | \title{Integral Turbulence Characteristics Flag} 6 | \usage{ 7 | flag_most(w_sd, ustar, zeta, thresholds_most = c(0.3, 0.8)) 8 | } 9 | \arguments{ 10 | \item{w_sd}{standard deviation of vertical velocity} 11 | 12 | \item{ustar}{friction velocity} 13 | 14 | \item{zeta}{stability parameter \code{zeta = z/L}} 15 | 16 | \item{thresholds_most}{vector containing 2 elements to distinguish between flag=0 and flag=1, as well as flag=1 and flag=2, default: \code{c(0.3,0.8)}} 17 | } 18 | \value{ 19 | integral turbulence characteristics flags (0: in full agreement with the criterion ... 2: does not fulfill the criterion) 20 | } 21 | \description{ 22 | Integral Turbulence Characteristics Flag: Tests the consistency with Monin-Obukhov similarity theory using the scaling functions from Panofsky and Dutton, 1984. 23 | } 24 | \examples{ 25 | itc_flag=flag_most(0.2,0.4,-0.3) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/plot_barycentric_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/anisotropy.R 3 | \name{plot_barycentric_map} 4 | \alias{plot_barycentric_map} 5 | \title{Plot in barycentric map} 6 | \usage{ 7 | plot_barycentric_map(xb, yb, contours = c(5, 10, 20)) 8 | } 9 | \arguments{ 10 | \item{xb}{xb coordinate (e.g., from \code{calc_anisotropy})} 11 | 12 | \item{yb}{yb coordinate (e.g., from \code{calc_anisotropy})} 13 | 14 | \item{contours}{vector containing levels of contour lines for 2d kernel density estimation, default: \code{contours=c(5,10,20)}} 15 | } 16 | \value{ 17 | plots (xb, yb) in barycentric map with 2d kernel density estimation (no return) 18 | } 19 | \description{ 20 | Plots \code{(xb, yb)} from invariant analysis of Reynolds stress tensor (\code{calc_anisotropy}) in barycentric map 21 | } 22 | \examples{ 23 | set.seed(5) 24 | nm=100 25 | example1=calc_anisotropy(rep(1,nm),rep(0,nm),runif(nm,0,1), 26 | rep(1,nm),rep(0,nm),runif(nm,1,1.5)) 27 | plot_barycentric_map(example1$xb,example1$yb) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/calc_helmholtz_decomposition.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{calc_helmholtz_decomposition} 4 | \alias{calc_helmholtz_decomposition} 5 | \title{Helmholtz-Hodge decomposition} 6 | \usage{ 7 | calc_helmholtz_decomposition(u, v, res = 1) 8 | } 9 | \arguments{ 10 | \item{u}{zonal wind field with dimension (x,y)} 11 | 12 | \item{v}{meridional wind field with dimension (x,y)} 13 | 14 | \item{res}{spatial resolution (assuming equidistant grid)} 15 | } 16 | \value{ 17 | list containing u_div, v_div, u_rot, v_rot 18 | } 19 | \description{ 20 | Calculates Helmholtz-Hodge decomposition of horizontal wind using a spectral FFT-based method: decomposition of horizontal wind in rotational and divergent part: (u,v) = (u_rot,v_rot) + (u_div,v_div) 21 | } 22 | \details{ 23 | The implementation is based on the Python version from https://github.com/shixun22/helmholtz. 24 | } 25 | \examples{ 26 | set.seed(5) 27 | u=matrix(rnorm(100),ncol=10) 28 | v=matrix(rnorm(100),ncol=10) 29 | hd=calc_helmholtz_decomposition(u,v,100) 30 | 31 | } 32 | -------------------------------------------------------------------------------- /man/calc_mrd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/multiresolution-decomposition.R 3 | \name{calc_mrd} 4 | \alias{calc_mrd} 5 | \title{Multiresolution Decomposition (MRD) according to Vickers and Mahrt, 2003} 6 | \usage{ 7 | calc_mrd(var1, var2 = NULL, time_res = 0.05, plot = TRUE) 8 | } 9 | \arguments{ 10 | \item{var1}{timeseries of a variable} 11 | 12 | \item{var2}{timeseries of another variable to calculate the cospectrum of \code{var1} and \code{var2}, optional (default is \code{NULL})} 13 | 14 | \item{time_res}{time resolution of the given timeseries in seconds (e.g., \code{time_res = 0.05} for 20 Hz)} 15 | 16 | \item{plot}{logical, should the MRD spectrum be plotted? default \code{plot=TRUE}} 17 | } 18 | \value{ 19 | MRD in form of a data frame containing the columns: index, scale, time, mean, median, q25, q75 20 | } 21 | \description{ 22 | Calculates multiresolution decomposition (MRD) according to Vickers and Mahrt, 2003 23 | } 24 | \examples{ 25 | series=c(1,3,2,5,1,2,1,3) #example used in Vickers and Mahrt, 2003 26 | calc_mrd(series) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /man/calc_flux_intermittency.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics-turbulence.R 3 | \name{calc_flux_intermittency} 4 | \alias{calc_flux_intermittency} 5 | \title{Flux intermittency} 6 | \usage{ 7 | calc_flux_intermittency(ts1, ts2 = NULL, nsub = 6000) 8 | } 9 | \arguments{ 10 | \item{ts1}{timeseries 1} 11 | 12 | \item{ts2}{timeseries 2 (optional), if the flux should be calculated based on \code{ts1*ts2} (default \code{ts2=NULL}, i.e. \code{ts2} is not used)} 13 | 14 | \item{nsub}{number of elements used for subsampling, default \code{nsub=6000}, which corrosponds to 5 minutes of measurements from 20 Hz sampled half-hour (containing 30*60*20 = 36000 measurements)} 15 | } 16 | \value{ 17 | flux intermittency [-] 18 | } 19 | \description{ 20 | Calculates flux intermittency FI = flux_sd/flux (flux_sd: sd of subsampled fluxes) following Mahrt, 1998 (similar to stationarity flag \code{flag_stationarity}) 21 | } 22 | \examples{ 23 | set.seed(5) 24 | ts1=rnorm(30) 25 | ts2=rnorm(30) 26 | calc_flux_intermittency(ts1,ts2,nsub=6) #as product 27 | calc_flux_intermittency(ts1*ts2,nsub=6) #the same from one variable 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/despiking.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{despiking} 4 | \alias{despiking} 5 | \title{Despiking} 6 | \usage{ 7 | despiking( 8 | ts, 9 | thresholds = c(NA, NA), 10 | mad_factor = 10, 11 | threshold_skewness = 2, 12 | threshold_kurtosis = 8 13 | ) 14 | } 15 | \arguments{ 16 | \item{ts}{timeseries that shall be despiked} 17 | 18 | \item{thresholds}{vector with two elements representing lower and upper bounds for despiking (pre-defined thresholds), \code{NA} means that the respective bound is not used} 19 | 20 | \item{mad_factor}{factor for the MAD test, default \code{mad_factor = 10}} 21 | 22 | \item{threshold_skewness}{threshold for skewness test, default \code{threshold_skewness = 2}} 23 | 24 | \item{threshold_kurtosis}{threshold for kurtosis test, default \code{threshold_kurtosis = 8}} 25 | } 26 | \value{ 27 | despiked timeseries 28 | } 29 | \description{ 30 | Applies (up to) three despiking methods based on (1) pre-defined thresholds, (2) median deviation (MAD) test and (3) skewness and kurtosis 31 | } 32 | \examples{ 33 | set.seed(5) 34 | ts1=rnorm(100) 35 | despiking(ts1,thresholds=c(-1,1)) 36 | 37 | ts2=rexp(1000) 38 | despiking(ts2) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /man/WPLcorrection.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{WPLcorrection} 4 | \alias{WPLcorrection} 5 | \title{WPL correction} 6 | \usage{ 7 | WPLcorrection( 8 | Ts_mean, 9 | q_mean, 10 | cov_wTs, 11 | rhow_mean, 12 | cov_wrhow, 13 | rhoc_mean = NULL, 14 | cov_wrhoc = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{Ts_mean}{temperature [K] (sonic temperature or corrected temperature)} 19 | 20 | \item{q_mean}{specific humidity [kg/kg] (if measured, default \code{NULL})} 21 | 22 | \item{cov_wTs}{covariance cov(w,Ts) [m/s*K]} 23 | 24 | \item{rhow_mean}{measured water vapor density [kg/m^3]} 25 | 26 | \item{cov_wrhow}{covariance cov (w,rhow) [m/s*kg/m^3]} 27 | 28 | \item{rhoc_mean}{measured trace gas density [kg/m^3] (only if WPL-correction should be applied to another flux, e.g. CO2 flux, default \code{NULL})} 29 | 30 | \item{cov_wrhoc}{covariance cov (w,rhoc) [m/s*kg/m^3] (only if WPL-correction should be applied to another flux, e.g. CO2 flux, default \code{NULL})} 31 | } 32 | \value{ 33 | WPL correction of respective flux 34 | } 35 | \description{ 36 | WPL correction: density correction for trace gas fluxes (i.e., converts volume- to mass-related quantity) 37 | } 38 | -------------------------------------------------------------------------------- /man/flag_stationarity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{flag_stationarity} 4 | \alias{flag_stationarity} 5 | \title{Stationarity Flag} 6 | \usage{ 7 | flag_stationarity(var1, var2, nsub = 3000, thresholds_stationarity = c(0.3, 1)) 8 | } 9 | \arguments{ 10 | \item{var1}{variable 1} 11 | 12 | \item{var2}{variable 2 (same length as \code{var1}, usually either \code{var1} or \code{var2} represent vertical velocity)} 13 | 14 | \item{nsub}{number of elements used for subsampling (\code{nsub < length(var1)})} 15 | 16 | \item{thresholds_stationarity}{vector containing 2 elements to distinguish between flag=0 and flag=1, as well as flag=1 and flag=2, default: \code{c(0.3,1)}} 17 | } 18 | \value{ 19 | stationarity flags (0: in full agreement with the criterion ... 2: does not fulfill the criterion) 20 | } 21 | \description{ 22 | Stationarity Flag according to Foken and Wichura, 1996 based on the assumption that the covariance of two variables (\code{var1} and \code{var2}, one usually representing vertical velocity) calculated for blocks (of length \code{nsub}) does not differ to much from the total covariance 23 | } 24 | \examples{ 25 | set.seed(5) 26 | ts1=rnorm(30) 27 | ts2=rnorm(30) 28 | flag_stationarity(ts1,ts2,nsub=6) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /man/flag_distortion.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{flag_distortion} 4 | \alias{flag_distortion} 5 | \title{Flow Distortion Flag and Wind Constancy Ratio} 6 | \usage{ 7 | flag_distortion(u, v, dir_blocked, threshold_cr = 0.9) 8 | } 9 | \arguments{ 10 | \item{u}{u-wind (levelled sonic)} 11 | 12 | \item{v}{v-wind (levelled sonic)} 13 | 14 | \item{dir_blocked}{vector containing the lower and upper bound of the blocked wind sector in degrees (e.g., \code{dir_blocked = c(30,60)})} 15 | 16 | \item{threshold_cr}{threshold for constancy ratio (default \code{threshold_cr = 0.9}, may be adapted to used data set)} 17 | } 18 | \value{ 19 | distortion flags (0: in full agreement with the criterion ... 2: does not fulfill the criterion) 20 | } 21 | \description{ 22 | Flow Distortion Flag according to Mauder et al., 2013: Wind coming from (pre-defined) directions blocked by the measurement device is flaged with 2 (for wind speeds greater than 0.1 assuming that during calm wind the wind direction is not well-defined). The wind constancy ratio is calculated to quantify the variability of horizontal wind direction according to Mahrt, 1999. 23 | } 24 | \examples{ 25 | flag_distortion(1,1,dir_blocked=c(30,60)) 26 | flag_distortion(1,1,dir_blocked=c(180,360)) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /man/SNDcorrection.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing.R 3 | \name{SNDcorrection} 4 | \alias{SNDcorrection} 5 | \title{SND and cross-wind correction of sensible heat flux} 6 | \usage{ 7 | SNDcorrection( 8 | Ts_mean, 9 | u_mean, 10 | v_mean, 11 | cov_uw, 12 | cov_vw, 13 | cov_wTs, 14 | cov_qw = NULL, 15 | A = 7/8, 16 | B = 7/8, 17 | sos = csound() 18 | ) 19 | } 20 | \arguments{ 21 | \item{Ts_mean}{sonic temperature [K] (averaged)} 22 | 23 | \item{u_mean}{u-wind [m/s] (averaged)} 24 | 25 | \item{v_mean}{v-wind [m/s] (averaged)} 26 | 27 | \item{cov_uw}{cov(u,w) [m^2/s^2]} 28 | 29 | \item{cov_vw}{cov(v,w) [m^2/s^2]} 30 | 31 | \item{cov_wTs}{cov(Ts,w) [K*m/s] (buoyancy flux)} 32 | 33 | \item{cov_qw}{cov(q,w) [kg/kg*m/s] (optional)} 34 | 35 | \item{A}{constant used in cross-wind correction, default \code{A = 7/8} for CSAT3} 36 | 37 | \item{B}{constant used in cross-wind correction, default \code{B = 7/8} for CSAT3} 38 | 39 | \item{sos}{speed of sound [m/s], default \code{sos = csound()} corresponding to 343 m/s} 40 | } 41 | \value{ 42 | SND correction of sensible heat flux 43 | } 44 | \description{ 45 | SND and cross-wind correction of sensible heat flux: converts the buoyancy flux cov(w,Ts) (based on sonic temperature Ts) to sensible heat flux 46 | } 47 | -------------------------------------------------------------------------------- /man/plot_quadrant_analysis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/quadrant-analysis.R 3 | \name{plot_quadrant_analysis} 4 | \alias{plot_quadrant_analysis} 5 | \title{Plotting Quadrant Analysis} 6 | \usage{ 7 | plot_quadrant_analysis( 8 | xval, 9 | yval, 10 | do_normalization = TRUE, 11 | hole_sizes = c(1, 2), 12 | contours = 10^(-3:3), 13 | print_fit = TRUE, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{xval}{values of x variable (vector)} 19 | 20 | \item{yval}{values of y variable (vector)} 21 | 22 | \item{do_normalization}{should the values be normalized? i.e. \code{(x-mean(x))/sd(x)}, default: \code{do_normalization=TRUE}} 23 | 24 | \item{hole_sizes}{vector containing desired hole sizes (integers >= 0), default: \code{hole_sizes=c(1,2)}} 25 | 26 | \item{contours}{vector containing levels of contour lines for 2d kernel density estimation, default: \code{contours=10^(-3:3)}} 27 | 28 | \item{print_fit}{should the fit summary from the linear regression be printed? default: \code{print_fit=TRUE}} 29 | 30 | \item{...}{arguments passed to plot function} 31 | } 32 | \value{ 33 | no return 34 | } 35 | \description{ 36 | Plots two vectors in the framework of quadrant analysis with 2d kernel density estimation 37 | } 38 | \examples{ 39 | a=rnorm(100) 40 | b=rnorm(100) 41 | plot_quadrant_analysis(a,b) 42 | 43 | } 44 | -------------------------------------------------------------------------------- /man/plot_seb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/surface-energy-balance.R 3 | \name{plot_seb} 4 | \alias{plot_seb} 5 | \title{Plotting of surface energy balance and calculation of surface energy balance unclosure} 6 | \usage{ 7 | plot_seb( 8 | sw_in, 9 | sw_out, 10 | lw_in, 11 | lw_out, 12 | sh = NULL, 13 | lh = NULL, 14 | gh = NULL, 15 | time_vector = NULL, 16 | print_fit = TRUE, 17 | ... 18 | ) 19 | } 20 | \arguments{ 21 | \item{sw_in}{incoming shortwave radiation [W/m^2] (as vector of time)} 22 | 23 | \item{sw_out}{outgoing shortwave radiation [W/m^2] (as vector of time)} 24 | 25 | \item{lw_in}{incoming longwave radiation [W/m^2] (as vector of time)} 26 | 27 | \item{lw_out}{outgoing longwave radiation [W/m^2] (as vector of time)} 28 | 29 | \item{sh}{sensible heat flux [W/m^2] (as vector of time) -- if measured} 30 | 31 | \item{lh}{latent heat flux [W/m^2] (as vector of time) -- if measured} 32 | 33 | \item{gh}{ground heat flux [W/m^2] (as vector of time) -- if measured} 34 | 35 | \item{time_vector}{times used as x-axis labels (optional)} 36 | 37 | \item{print_fit}{should the fit summary be printed? default: \code{print_fit=TRUE}} 38 | 39 | \item{...}{optional plot parameters} 40 | } 41 | \value{ 42 | no return 43 | } 44 | \description{ 45 | Plotting of surface energy balance and calculation of surface energy balance unclosure as residual flux and closure ratio 46 | } 47 | -------------------------------------------------------------------------------- /man/calc_anisotropy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/anisotropy.R 3 | \name{calc_anisotropy} 4 | \alias{calc_anisotropy} 5 | \title{Invariant analysis of Reynolds stress tensor} 6 | \usage{ 7 | calc_anisotropy(a11, a12, a13, a22, a23, a33, plot = FALSE) 8 | } 9 | \arguments{ 10 | \item{a11}{R11 element of Reynolds stress tensor: \code{u_sd^2} (scalar or vector)} 11 | 12 | \item{a12}{R12 element of Reynolds stress tensor: \code{cov(u,v)} (scalar or vector)} 13 | 14 | \item{a13}{R13 element of Reynolds stress tensor: \code{cov(u,w)} (scalar or vector)} 15 | 16 | \item{a22}{R22 element of Reynolds stress tensor: \code{v_sd^2} (scalar or vector)} 17 | 18 | \item{a23}{R23 element of Reynolds stress tensor: \code{cov(v,w)} (scalar or vector)} 19 | 20 | \item{a33}{R33 element of Reynolds stress tensor: \code{w_sd^2} (scalar or vector)} 21 | 22 | \item{plot}{should the barycentric map be plotted? default \code{plot=FALSE}} 23 | } 24 | \value{ 25 | list containing \code{xb}, \code{yb}, \code{eta}, \code{xi}, all eigenvalues and eigenvectors (\code{eta}, \code{xi} are the coordinates of the Lumley triangle and \code{xb}, \code{yb} the coordinates of the barycentric map) 26 | } 27 | \description{ 28 | Invariant analysis of Reynolds stress tensor, calculation of Lumley and barycentric map coordinates and anisotropy 29 | } 30 | \examples{ 31 | calc_anisotropy(1,0,0,1,0,1) #isotropic 32 | calc_anisotropy(1,0,1,1,0,1) #some anisotropy 33 | 34 | } 35 | -------------------------------------------------------------------------------- /man/calc_spectrum1D.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{calc_spectrum1D} 4 | \alias{calc_spectrum1D} 5 | \title{Frequency spectrum (1D)} 6 | \usage{ 7 | calc_spectrum1D( 8 | ts, 9 | tres = 0.05, 10 | nbins = NULL, 11 | method = "fft", 12 | na.rm = TRUE, 13 | plot = TRUE, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{ts}{timeseries of the variable for which the spectrum should be calculated} 19 | 20 | \item{tres}{time resolution [s] of the given timeseries, default \code{tres=0.05} for 20 Hz} 21 | 22 | \item{nbins}{number of bins used to average the spectrum, default \code{nbins=NULL}, i.e. no further binning is applied (means number of bins equals half of length of input timeseries)} 23 | 24 | \item{method}{method used to calculate the spectrum, can be either FFT (fast Fourier transform) or DCT (discrete cosine transform), default FFT} 25 | 26 | \item{na.rm}{should NA values be removed from the timeseries? default \code{na.rm=TRUE}} 27 | 28 | \item{plot}{should the spectrum be plotted? default \code{plot=TRUE}} 29 | 30 | \item{...}{further arguments passed to plot function} 31 | } 32 | \value{ 33 | binned frequency spectrum from 1D FFT 34 | } 35 | \description{ 36 | Calculates and plots turbulence spectrum (in time) calculated using FFT (and optionally bins it) 37 | } 38 | \examples{ 39 | set.seed(5) 40 | ts=rnorm(1000) 41 | calc_spectrum1D(ts) #no binning 42 | calc_spectrum1D(ts,nbins=100) #binning 43 | 44 | } 45 | -------------------------------------------------------------------------------- /man/calc_windprofile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bulk-closures.R 3 | \name{calc_windprofile} 4 | \alias{calc_windprofile} 5 | \title{Wind profile from Monin-Obukhov similarity theory} 6 | \usage{ 7 | calc_windprofile(zs, ustar, z0 = 0, d = 0, zeta = 0, method = "ecmwf") 8 | } 9 | \arguments{ 10 | \item{zs}{scalar or vector, heights [m] at which the horizontal wind speed should be calculate} 11 | 12 | \item{ustar}{friction velocity [m/s]} 13 | 14 | \item{z0}{surface roughness length [m], default \code{z0=0} (note: it could be an option to calculate z0 from ustar with \code{ustar2z0()})} 15 | 16 | \item{d}{displacement height [m], optional, default \code{d=0} (i.e. no displacement)} 17 | 18 | \item{zeta}{stability parameter [-] to correct for stability effects, default \code{zeta=0} (i.e. no stability correction, resulting in classical logarithmic wind profile)} 19 | 20 | \item{method}{"method" for calculating stability correction function (only relevant if zeta is non-zero), default \code{method="ecmwf"} for using Phi_m from ECMWF-IFS} 21 | } 22 | \value{ 23 | data frame containing the requested heights \code{zs} and the calculated wind speed [m/s] there 24 | } 25 | \description{ 26 | Calculates vertical profile of horizontal wind speed following Monin-Obukhov similarity theory 27 | } 28 | \examples{ 29 | zs=seq(1,100) 30 | ustar=0.2 31 | u_neutral=calc_windprofile(zs,ustar) 32 | u_unstable=calc_windprofile(zs,ustar,zeta=-0.2) 33 | u_stable=calc_windprofile(zs,ustar,zeta=0.2) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /man/calc_spectrum2D.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/spectrum.R 3 | \name{calc_spectrum2D} 4 | \alias{calc_spectrum2D} 5 | \title{Spatial spectrum (2D)} 6 | \usage{ 7 | calc_spectrum2D( 8 | field, 9 | xres = 1000, 10 | yres = NULL, 11 | nbins = NULL, 12 | method = "fft", 13 | plot = TRUE, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{field}{two-dimensional input field} 19 | 20 | \item{xres}{spatial resolution in x-direction} 21 | 22 | \item{yres}{spatial resolution in y-direction, default \code{yres=NULL} meaning that the field is equidistant and \code{yres=xres} is used} 23 | 24 | \item{nbins}{number of bins used to average the spectrum, default \code{nbins=NULL}, i.e. no further binning is applied (means number of bins equals half of length of input timeseries)} 25 | 26 | \item{method}{method used to calculate the spectrum, can be either FFT (fast Fourier transform) or DCT (discrete cosine transform), default FFT} 27 | 28 | \item{plot}{should the spectrum be plotted? default \code{plot=TRUE}} 29 | 30 | \item{...}{further arguments passed to plot function} 31 | } 32 | \value{ 33 | binned wavenumber spectrum from 2D FFT or DCT 34 | } 35 | \description{ 36 | Calculates and plots turbulence spectrum (in space) calculated using FFT or DCT (and optionally bins it) 37 | } 38 | \examples{ 39 | set.seed(5) 40 | field=matrix(rnorm(10000),nrow=100) 41 | calc_spectrum2D(field,xres=100) #equidistant grid, no binning, fft 42 | calc_spectrum2D(field,xres=100,yres=200) #non-equidistant grid, no binning, fft 43 | calc_spectrum2D(field,xres=100,nbins=1000) #equidistant grid, binning, fft 44 | calc_spectrum2D(field,xres=100,nbins=1000,method="dct") #equidistant grid, binning, dct 45 | 46 | } 47 | -------------------------------------------------------------------------------- /man/calc_flux_footprint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/flux-footprint.R 3 | \name{calc_flux_footprint} 4 | \alias{calc_flux_footprint} 5 | \title{Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015} 6 | \usage{ 7 | calc_flux_footprint( 8 | zm, 9 | ws_mean = NA, 10 | wd_mean = NA, 11 | blh, 12 | L, 13 | v_sd, 14 | ustar, 15 | z0 = NA, 16 | contours = seq(0.9, 0.1, -0.1), 17 | nres = 1000, 18 | plot = TRUE 19 | ) 20 | } 21 | \arguments{ 22 | \item{zm}{measurement height [m]} 23 | 24 | \item{ws_mean}{mean horizontal wind speed [m/s] (alternatively you can also use \code{z0})} 25 | 26 | \item{wd_mean}{mean wind direction [deg] (used to rotate flux footprint, optional)} 27 | 28 | \item{blh}{boundary-layer height [m]} 29 | 30 | \item{L}{Obukhov length [m]} 31 | 32 | \item{v_sd}{standard deviation of crosswind [m/s]} 33 | 34 | \item{ustar}{friction velocity [m/s]} 35 | 36 | \item{z0}{roughness length [m] (either \code{ws_mean} or \code{z0} have to be given)} 37 | 38 | \item{contours}{which contour lines should be calculated? default: \code{contours=seq(0.9,0.1,-0.1)}} 39 | 40 | \item{nres}{resolution (default: \code{nres=1000})} 41 | 42 | \item{plot}{logical, should the flux footprint be plotted? default \code{plot=TRUE}} 43 | } 44 | \value{ 45 | list containing all relevant flux footprint information 46 | } 47 | \description{ 48 | Calculates the Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015 49 | } 50 | \examples{ 51 | #unrotated (i.e. if wind direction not given): 52 | ffp=calc_flux_footprint(zm=20,ws_mean=2,blh=200,L=-1.5,v_sd=0.6,ustar=0.4,contours=0.8) 53 | #rotated (i.e. given wind direction): 54 | ffp=calc_flux_footprint(zm=20,ws_mean=2,wd_mean=80,blh=200,L=-1.5,v_sd=0.6,ustar=0.4,contours=0.8) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /man/calc_quadrant_analysis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/quadrant-analysis.R 3 | \name{calc_quadrant_analysis} 4 | \alias{calc_quadrant_analysis} 5 | \title{Calculating Coherent Structures following Quadrant Analysis} 6 | \usage{ 7 | calc_quadrant_analysis( 8 | xval, 9 | yval, 10 | do_normalization = TRUE, 11 | hole_sizes = seq(0, 10), 12 | orient = "+", 13 | plot = TRUE, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{xval}{values of x variable (vector)} 19 | 20 | \item{yval}{values of y variable (vector)} 21 | 22 | \item{do_normalization}{should the values be normalized? i.e. \code{(x-mean(x))/sd(x)}, default: \code{do_normalization=TRUE}} 23 | 24 | \item{hole_sizes}{vector containing desired hole sizes (integers >= 0)} 25 | 26 | \item{orient}{only relevant for exuberance and organization ratio: if down-gradient flux corresponds to positive values, use \code{orient="+"} (for sensible and latent heat flux), if down-gradient flux corresponds to negative values, use \code{orient="-"} (for momentum flux and CO2 flux)} 27 | 28 | \item{plot}{logical, should the quadrant analysis be plotted? default \code{plot=TRUE}} 29 | 30 | \item{...}{arguments passed to \code{plot_quadrant_analysis}} 31 | } 32 | \value{ 33 | list containing occurrence fraction and strength (calculated based on product and covariance) for all four quadrants (mathematical orientation) as well as the therefrom derived measures exuberance and organization ratio, i.e. the ratio of the strength (or occurrence frequency, respectively) of disorganized to organized structures 34 | } 35 | \description{ 36 | Calculates occurrence fraction and strength of the four quadrants in the framework of quadrant analysis 37 | } 38 | \examples{ 39 | a=rnorm(100) 40 | b=rnorm(100) 41 | qa_ab=calc_quadrant_analysis(a,b) 42 | 43 | } 44 | -------------------------------------------------------------------------------- /inst/data-handling/ghg-data-handling.R: -------------------------------------------------------------------------------- 1 | #' unzip directory containing .ghg files 2 | #' 3 | #'@description unzips .ghg files from input directory (\code{dir_in}) to output directory (\code{dir_out}) 4 | #'@param dir_in input directory path (character) 5 | #'@param dir_out output directory path (character) 6 | #' 7 | #'@return no return 8 | #'@export 9 | #' 10 | unzip_dir = function(dir_in,dir_out) { 11 | files=list.files(dir_in,pattern="ghg",full.names=TRUE) 12 | nf=length(files) 13 | for (i in 1:nf) unzip(files[i],exdir=dir_out) 14 | #maybe add: remove .status and .metadata files in dir_out, such that only .data files remain 15 | } 16 | 17 | 18 | #' read ghg data (unzipped) 19 | #' 20 | #'@description reads unzipped ghg-files (.data) and transforms them into a dataframe containing: time, u, v, w, Ts, q, co2, pressure 21 | #'@param file file (as character, extension .data) after unzipping (with \code{unzip_ghg()}) 22 | #'@param do_h2o logical, read H2O as well? default \code{do_h2o=FALSE} 23 | #'@param do_co2 logical, read CO2 as well? default \code{do_co2=FALSE} 24 | #'@param do_ch4 logical, read CH4 as well? default \code{do_ch4=FALSE} 25 | #' 26 | #'@return dataframe, with: time [beginn of measurement], Ts [K], u [m/s], v [m/s], w [m/s], pressure [Pa], h2o -- if measured [original unit, usually milli mol], co2 -- if measured [original unit, usually mikro mol], ch4 -- if measured [original unit, usually mikro mol] 27 | #'@export 28 | #' 29 | read_ghg_data = function(file,do_h2o=FALSE,do_co2=FALSE,do_ch4=FALSE) { 30 | dat=read.table(file,sep="\t",skip=7,header=T) 31 | tryCatch({ 32 | date=as.character(dat$Date) 33 | time=substr(as.character(dat$Time),1,12) 34 | out=data.frame( 35 | #naming in finse files: 36 | "Ts"=dat$Aux.4...SOS..m.s., #sos 37 | "u"=dat$Aux.1...U..m.s., 38 | "v"=dat$Aux.2...V..m.s., 39 | "w"=dat$Aux.3...W..m.s., 40 | #naming in iskoras files: 41 | #"Ts"=dat$SOS..m.s., #sos 42 | #"u"=dat$U..m.s., 43 | #"v"=dat$V..m.s., 44 | #"w"=dat$W..m.s., 45 | "pressure"=dat$Total.Pressure..kPa.*1000) 46 | if (do_h2o) out$h2o=dat$H2O.dry.mmol.mol. #milli mol (name depends on device) 47 | if (do_co2) out$co2=dat$CO2.dry.umol.mol. #mikro mol 48 | if (do_ch4) out$ch4=dat$CH4..umol.mol. #mikro mol 49 | out$Ts=sos2Ts(out$Ts) #speed of sound to sonic temperature 50 | out$date=date 51 | out$time=time 52 | return(out) 53 | }, error = function(e) { 54 | message("An error occurred while reading the file -- this could e.g. be caused by an incomplete file.") 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /R/surface-energy-balance.R: -------------------------------------------------------------------------------- 1 | #' Plotting of surface energy balance and calculation of surface energy balance unclosure 2 | #' 3 | #'@description Plotting of surface energy balance and calculation of surface energy balance unclosure as residual flux and closure ratio 4 | #'@param sw_in incoming shortwave radiation [W/m^2] (as vector of time) 5 | #'@param sw_out outgoing shortwave radiation [W/m^2] (as vector of time) 6 | #'@param lw_in incoming longwave radiation [W/m^2] (as vector of time) 7 | #'@param lw_out outgoing longwave radiation [W/m^2] (as vector of time) 8 | #'@param sh sensible heat flux [W/m^2] (as vector of time) -- if measured 9 | #'@param lh latent heat flux [W/m^2] (as vector of time) -- if measured 10 | #'@param gh ground heat flux [W/m^2] (as vector of time) -- if measured 11 | #'@param time_vector times used as x-axis labels (optional) 12 | #'@param print_fit should the fit summary be printed? default: \code{print_fit=TRUE} 13 | #'@param ... optional plot parameters 14 | #' 15 | #'@return no return 16 | #'@export 17 | #' 18 | plot_seb = function(sw_in,sw_out,lw_in,lw_out,sh=NULL,lh=NULL,gh=NULL,time_vector=NULL,print_fit=TRUE,...) { 19 | #check which fluxes are given 20 | if (is.null(sh)) sh = 0 21 | if (is.null(lh)) lh = 0 22 | if (is.null(gh)) gh = 0 23 | #balances 24 | rad_balance = sw_in-sw_out+lw_in-lw_out #radiation balance 25 | seb_balance = rad_balance-gh-sh-lh #surface energy balance (residual flux) 26 | cr = (rad_balance-gh)/(sh+lh) #closure ratio 27 | #plot 28 | n=length(rad_balance) 29 | if (is.null(time_vector)) time_vector = 1:n 30 | if (!exists("ylim")) ylim=c(-100,500) 31 | if (!exists("pch")) pch=20 32 | if (!exists("cex")) cex=2 33 | plot(time_vector,rad_balance,type="l",lwd=2,col="gray50",main="Surface Energy Balance",ylim=ylim,ylab="surface energy balance fluxes",xlab="index",...) 34 | points(time_vector,seb_balance,type="l",lwd=3,col=1) 35 | points(time_vector,sh,type="l",lwd=2,col="orangered") 36 | points(time_vector,lh,type="l",lwd=2,col="blue3") 37 | points(time_vector,gh,type="l",lwd=2,col="brown") 38 | legend("topright",legend=c("R","GH","SH","LH","Res"),col=c("gray50","brown","orangered","blue3",1),lwd=c(2,2,2,2,3),lty=1,bg="white") 39 | plot(rad_balance-gh,sh+lh,col=rgb(0,0,0,0.4),pch=pch,cex=cex,main="Surface Energy Balance Closure",xlab="R-G",ylab="SH+LH",...) 40 | y=sh+lh 41 | x=rad_balance-gh 42 | fit=lm(y ~ x) 43 | if (print_fit==TRUE) print(summary(fit)) 44 | abline(fit,lwd=2,col=2,lty=2) 45 | abline(0,1,lwd=2,lty=1) 46 | grid() 47 | #if (print_fit==TRUE) print(paste("mean closure ratio: ", mean(cr,na.rm=TRUE))) 48 | #if (print_fit==TRUE) print(paste("mean residual flux: ", mean(seb_balance,na.rm=TRUE))) 49 | } -------------------------------------------------------------------------------- /R/constants.R: -------------------------------------------------------------------------------- 1 | #### Constants ##### 2 | #' sigma 3 | #' 4 | #' Stefan-Boltzmann constant [W/m^2/K^4] 5 | #' @keywords internal 6 | sigma=function(){ 7 | return(5.67*10^(-8)) 8 | } 9 | 10 | #' cp 11 | #' 12 | #' heat capacity, constant pressure [J/(kg*K)] 13 | #' @keywords internal 14 | cp=function(){ 15 | return(1005.7) 16 | } 17 | 18 | #' g 19 | #' 20 | #' gravitational accelaration [m/s^2] 21 | #' @keywords internal 22 | g=function(){ 23 | return(9.8062) 24 | } 25 | 26 | #' clight 27 | #' 28 | #' speed of light [m/s] 29 | #' @keywords internal 30 | clight=function(){ 31 | return(299792458) 32 | } 33 | 34 | #' csound 35 | #' 36 | #' speed of sound [m/s] 37 | #' @keywords internal 38 | csound=function(){ 39 | return(343) 40 | } 41 | 42 | #' von Karman constant 43 | #' 44 | #' @keywords internal 45 | karman=function() { 46 | return(0.4) 47 | } 48 | 49 | #' R 50 | #' 51 | #' ideal gas constant [J/(mol*K)] 52 | #' @keywords internal 53 | Runiversal = function() { 54 | return(8.31451) 55 | } 56 | 57 | #' Rd 58 | #' 59 | #' gas constant for dry air [J/(kg*K)] 60 | #' @keywords internal 61 | Rd = function() { 62 | return(287.05) 63 | } 64 | 65 | #' Rv 66 | #' 67 | #' gas constant for water vapor [J/(kg*K)] 68 | #' @keywords internal 69 | Rv = function() { 70 | return(461.52) 71 | } 72 | 73 | #' gamma (ratio cp/cv) 74 | #' 75 | #' ratio of specific heat at constant pressure to that at constant volume (i.e. cp/cv = 1004 / 717 = 1.4) 76 | #' @keywords internal 77 | cpcv = function() { 78 | return(1.4) 79 | } 80 | 81 | #' rhoAir 82 | #' 83 | #' density of air [kg/m^3] 84 | #' @keywords internal 85 | rhoAir = function() { 86 | return(1.225) #at surface with p0 = 1013.25 hPa and T0 = 288 K 87 | } 88 | 89 | #' Lv 90 | #' 91 | #' latent heat of vaporization [J/kg] 92 | #' @param temp temperature [K] (optional) 93 | #' @keywords internal 94 | Lv = function(temp=NULL) { 95 | if (is.null(temp)) { 96 | return(2264.705*1000) 97 | } else { 98 | return((3147.5-2.37*temp)*1000) #Lv temperature dependence 99 | } 100 | 101 | } 102 | 103 | #' M_H2O 104 | #' 105 | #' Molar mass of water 106 | #' @keywords internal 107 | M_H2O = function() { 108 | return(0.01802) 109 | } 110 | 111 | #' M_CO2 112 | #' 113 | #' Molar mass of carbon dioxide 114 | #' @keywords internal 115 | M_CO2 = function() { 116 | return(0.044) 117 | } 118 | 119 | #' M_CH4 120 | #' 121 | #' Molar mass of methane 122 | #' @keywords internal 123 | M_CH4 = function() { 124 | return(0.01604) 125 | } 126 | 127 | #' Charnock constant (alpha) 128 | #' 129 | #' Charnock constant (alpha) used to convert friction velocity to surface roughness length 130 | #' @keywords internal 131 | alpha = function() { 132 | return(0.016) 133 | } 134 | 135 | #' Earth's radius 136 | #' 137 | #' Earth's radius 138 | #' @keywords internal 139 | R_earth = function() { 140 | return(6378137) 141 | } -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(ECprocessing) 4 | export(RTcorrection) 5 | export(SNDcorrection) 6 | export(Ts2T) 7 | export(WPLcorrection) 8 | export(ah2rh) 9 | export(apply_quality_control) 10 | export(averaging) 11 | export(binning) 12 | export(calc_Kh) 13 | export(calc_Km) 14 | export(calc_L) 15 | export(calc_N2) 16 | export(calc_Pr) 17 | export(calc_Tv) 18 | export(calc_anisotropy) 19 | export(calc_br) 20 | export(calc_circular_mean) 21 | export(calc_coriolis) 22 | export(calc_cov) 23 | export(calc_csi) 24 | export(calc_decoupling_metric) 25 | export(calc_distance) 26 | export(calc_dshear) 27 | export(calc_ef) 28 | export(calc_ekman_layer_depth) 29 | export(calc_flux_footprint) 30 | export(calc_flux_intermittency) 31 | export(calc_gustfactor) 32 | export(calc_helmholtz_decomposition) 33 | export(calc_iw) 34 | export(calc_k2d) 35 | export(calc_mrd) 36 | export(calc_ozmidov_scale) 37 | export(calc_phim) 38 | export(calc_phit) 39 | export(calc_phix) 40 | export(calc_quadrant_analysis) 41 | export(calc_ri) 42 | export(calc_rif) 43 | export(calc_satvaporpressure) 44 | export(calc_spectrum) 45 | export(calc_spectrum1D) 46 | export(calc_spectrum2D) 47 | export(calc_theta) 48 | export(calc_ti) 49 | export(calc_tke) 50 | export(calc_ustar) 51 | export(calc_var) 52 | export(calc_vpd) 53 | export(calc_vtke) 54 | export(calc_windDirection) 55 | export(calc_windSpeed2D) 56 | export(calc_windSpeed3D) 57 | export(calc_windprofile) 58 | export(calc_xstar) 59 | export(calc_zeta) 60 | export(cov2cf) 61 | export(cov2lh) 62 | export(cov2sh) 63 | export(deaccumulate1h) 64 | export(despiking) 65 | export(df_dx) 66 | export(df_dy) 67 | export(fftfreq) 68 | export(flag_distortion) 69 | export(flag_most) 70 | export(flag_stationarity) 71 | export(flag_w) 72 | export(gapfilling) 73 | export(lh2et) 74 | export(plot_barycentric_map) 75 | export(plot_flux_footprint) 76 | export(plot_mrd) 77 | export(plot_quadrant_analysis) 78 | export(plot_seb) 79 | export(ppt2rho) 80 | export(pres2height) 81 | export(rh2ah) 82 | export(rh2q) 83 | export(rotate_double) 84 | export(rotate_planar) 85 | export(scale_phiT) 86 | export(scale_phih) 87 | export(scale_phim) 88 | export(scale_phiu) 89 | export(scale_phiw) 90 | export(shift2maxccf) 91 | export(sigma2height) 92 | export(sos2Ts) 93 | export(ustar2z0) 94 | importFrom(MASS,kde2d) 95 | importFrom(RcppRoll,roll_max) 96 | importFrom(RcppRoll,roll_mean) 97 | importFrom(RcppRoll,roll_sd) 98 | importFrom(fields,image.plot) 99 | importFrom(grDevices,colorRampPalette) 100 | importFrom(grDevices,contourLines) 101 | importFrom(grDevices,rgb) 102 | importFrom(graphics,.filled.contour) 103 | importFrom(graphics,abline) 104 | importFrom(graphics,arrows) 105 | importFrom(graphics,axis) 106 | importFrom(gsignal,dct) 107 | importFrom(gsignal,dct2) 108 | importFrom(gsignal,fftshift) 109 | importFrom(pracma,detrend) 110 | importFrom(stats,approx) 111 | importFrom(stats,ccf) 112 | importFrom(stats,cor) 113 | importFrom(stats,cov) 114 | importFrom(stats,lm) 115 | importFrom(stats,median) 116 | importFrom(stats,quantile) 117 | importFrom(stats,sd) 118 | -------------------------------------------------------------------------------- /man/apply_quality_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing-routine.R 3 | \name{apply_quality_control} 4 | \alias{apply_quality_control} 5 | \title{Apply quality control} 6 | \usage{ 7 | apply_quality_control( 8 | u, 9 | v, 10 | w, 11 | temp, 12 | h2o = NULL, 13 | co2 = NULL, 14 | ch4 = NULL, 15 | do_despiking = TRUE, 16 | despike_u = c(-15, 15, 10, 2, 8), 17 | despike_v = c(-15, 15, 10, 2, 8), 18 | despike_w = c(-4, 4, 10, 2, 8), 19 | despike_temp = c(230, 300, 10, 2, 8), 20 | despike_h2o = c(0, 12, 10, 2, 8), 21 | despike_co2 = c(300, 500, 10, 4, 10), 22 | despike_ch4 = c(0, 12, 10, 2, 8), 23 | do_double_rotation = TRUE, 24 | do_planar_fit = FALSE, 25 | do_detrending = FALSE, 26 | do_flagging = TRUE 27 | ) 28 | } 29 | \arguments{ 30 | \item{u}{u-wind [m/s] (sonic)} 31 | 32 | \item{v}{v-wind [m/s] (sonic)} 33 | 34 | \item{w}{w-wind [m/s] (sonic)} 35 | 36 | \item{temp}{temperature [K] (sonic)} 37 | 38 | \item{h2o}{H2O mixing ratio (gas analyzer, optional)} 39 | 40 | \item{co2}{CO2 mixing ratio (gas analyzer, optional)} 41 | 42 | \item{ch4}{CH4 mixing ratio (gas analyzer, optional)} 43 | 44 | \item{do_despiking}{logical, should the data be despiked? default \code{TRUE}} 45 | 46 | \item{despike_u}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_u=c(-15,15,10,2,8)}} 47 | 48 | \item{despike_v}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_v=c(-15,15,10,2,8)}} 49 | 50 | \item{despike_w}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_w=c(-4,4,10,2,8)}} 51 | 52 | \item{despike_temp}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_temp=c(230,300,10,2,8)}} 53 | 54 | \item{despike_h2o}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_h2o=c(0,12,10,2,8)}} 55 | 56 | \item{despike_co2}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_co2=c(0,12,10,2,8)}} 57 | 58 | \item{despike_ch4}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_ch4=c(0,12,10,2,8)}} 59 | 60 | \item{do_double_rotation}{logical, should the wind data be double rotated? default \code{TRUE}} 61 | 62 | \item{do_planar_fit}{logical, should the data be rotated with planar fit? default \code{FALSE} (either double rotation or planar fit can be \code{TRUE})} 63 | 64 | \item{do_detrending}{logical, should the data be linearly detrended? default \code{FALSE}} 65 | 66 | \item{do_flagging}{logical, should the data be flagged? default \code{TRUE}, i.e. several flags are calculated, but no data is removed, can be used for quality analysis} 67 | } 68 | \value{ 69 | quality checked data in the same dimensions as the input variables 70 | } 71 | \description{ 72 | An example for an eddy-covariance post-processing routine utilizing the functions from ec_processing.R 73 | } 74 | -------------------------------------------------------------------------------- /R/model-utils.R: -------------------------------------------------------------------------------- 1 | #' deaccumulation 2 | #' 3 | #'@description hourly deaccumulation, e.g. for fluxes from model output 4 | #'@param dat vector (with dimension time) or array (with dimension x, y, time) 5 | #'@param factor factor for unit and sign conversion, default: \code{factor = -1/3600} for converting hour to seconds and adapting the sign convention 6 | #'@return vector or array hourly deaccumulated (same dimension as input) 7 | #'@export 8 | #' 9 | deaccumulate1h=function(dat,factor=-1/3600) { 10 | if (is.vector(dat)) { 11 | n=length(dat) 12 | out=dat 13 | for (i in 2:n) { 14 | out[i]=dat[i]-dat[i-1] #deaccumulate hourly 15 | } 16 | } else { 17 | dims=dim(dat) 18 | n=dims[3] 19 | field_out=dat 20 | for (i in 2:n) { 21 | out[,,i]=dat[,,i]-dat[,,i-1] #deaccumulate hourly 22 | } 23 | } 24 | return(out*factor) #time unit conversion 25 | } 26 | 27 | 28 | #' Converts hybrid (terrain-following) sigma levels to physical heights 29 | #' 30 | #'@description Converts hybrid (terrain-following) sigma levels to physical heights 31 | #'@param hybrid scalar or vector, hybrid sigma levels 32 | #'@param Tv virtual temperature 33 | #'@return hybrid levels converted to physical height [m] 34 | #'@export 35 | #' 36 | #'@examples 37 | #'sigma2height(0.1) 38 | #'sigma2height(0.1,288) 39 | #' 40 | sigma2height=function(hybrid,Tv=273.15) { 41 | return(-Rd()*Tv/g()*log(hybrid)) 42 | } 43 | 44 | 45 | ###################### derivatives ########################### 46 | 47 | #' df_dx 48 | #' 49 | #'@description Calculates x-derivative for equidistant grid 50 | #'@param fld input field with dimension (x,y) 51 | #'@param xres resolution in x-direction 52 | #'@return x-derivative of fld (same dimensions) 53 | #'@export 54 | #' 55 | #'@examples 56 | #'set.seed(5) 57 | #'field=matrix(rnorm(16),ncol=4) 58 | #'df_dx(field,10) 59 | #' 60 | df_dx=function(fld,xres=1) { 61 | nx=dim(fld)[1] 62 | ny=dim(fld)[2] 63 | df_dx=array(NA,dim=c(nx,ny)) 64 | df_dx[1,]=(fld[2,]-fld[1,])/xres #left boundary 65 | df_dx[nx,]=(fld[nx,]-fld[nx-1,])/xres #right boundary 66 | for (i in 2:(nx-1)) { 67 | df_dx[i,]=(fld[i+1,]-fld[i-1,])/(2*xres) #interior 68 | } 69 | return(df_dx) 70 | } 71 | 72 | #' df_dy 73 | #' 74 | #'@description Calculates y-derivative for equidistant grid 75 | #'@param fld input field with dimension (x,y) 76 | #'@param yres resolution in y-direction 77 | #'@return y-derivative of fld (same dimensions) 78 | #'@export 79 | #' 80 | #'@examples 81 | #'set.seed(5) 82 | #'field=matrix(rnorm(16),ncol=4) 83 | #'df_dy(field,10) 84 | #' 85 | df_dy=function(fld,yres=1) { 86 | nx=dim(fld)[1] 87 | ny=dim(fld)[2] 88 | df_dy=array(NA,dim=c(nx,ny)) 89 | df_dy[,1]=(fld[,2]-fld[,1])/yres #lower boundary 90 | df_dy[,ny]=(fld[,ny]-fld[,ny-1])/yres #upper boundary 91 | for (i in 2:(ny-1)) { 92 | df_dy[,i]=(fld[,i+1]-fld[,i-1])/(2*yres) #interior 93 | } 94 | return(df_dy) 95 | } 96 | 97 | 98 | #' Calculates distance between two points given in lon,lat 99 | #' 100 | #'@description Calculates y-derivative for equidistant grid 101 | #'@param lon1 longitude location 1 [deg] 102 | #'@param lat1 latitude location 1 [deg] 103 | #'@param lon2 longitude location 2 [deg] 104 | #'@param lat2 latitude location 2 [deg] 105 | #'@return distance between two points [m] 106 | #'@export 107 | #' 108 | #'@examples 109 | #'set.seed(5) 110 | #'field=matrix(rnorm(16),ncol=4) 111 | #'df_dy(field,10) 112 | #' 113 | calc_distance=function(lon1,lat1,lon2,lat2) { 114 | lon1=lon1*pi/180 115 | lat1=lat1*pi/180 116 | lon2=lon2*pi/180 117 | lat2=lat2*pi/180 118 | dlon=lon2-lon1 119 | dlat=lat2-lat1 120 | h1=sin(dlat/2)^2+cos(lat1)*cos(lat2)*sin(dlon/2)^2 121 | h2=2*atan2(sqrt(h1),sqrt(1-h1)) 122 | return(R_earth()*h2) 123 | } -------------------------------------------------------------------------------- /R/multiresolution-decomposition.R: -------------------------------------------------------------------------------- 1 | #' Multiresolution Decomposition (MRD) according to Vickers and Mahrt, 2003 2 | #' 3 | #'@description Calculates multiresolution decomposition (MRD) according to Vickers and Mahrt, 2003 4 | #'@param var1 timeseries of a variable 5 | #'@param var2 timeseries of another variable to calculate the cospectrum of \code{var1} and \code{var2}, optional (default is \code{NULL}) 6 | #'@param time_res time resolution of the given timeseries in seconds (e.g., \code{time_res = 0.05} for 20 Hz) 7 | #'@return MRD in form of a data frame containing the columns: index, scale, time, mean, median, q25, q75 8 | #'@param plot logical, should the MRD spectrum be plotted? default \code{plot=TRUE} 9 | #'@export 10 | #' 11 | #'@examples 12 | #'series=c(1,3,2,5,1,2,1,3) #example used in Vickers and Mahrt, 2003 13 | #'calc_mrd(series) 14 | #' 15 | calc_mrd = function(var1,var2=NULL,time_res=0.05,plot=TRUE) { 16 | nf=length(var1) 17 | #calc exponent M 18 | pot=2^(0:100) 19 | M=log(pot[sum(pot<=nf)],2) 20 | #interpolate on new length 2^M 21 | var1=approx(var1,n=2^M)$y 22 | if (!is.null(var2)) var2=approx(var2,n=2^M)$y 23 | #just reducing size of vector 24 | #var1=var1[1:2^M] 25 | #if (!is.null(var2)) var2=var2[1:2^M] 26 | #allocate output 27 | mrd_mean=array(NA,dim=M+1) 28 | mrd_median=array(NA,dim=M+1) 29 | mrd_q25=array(NA,dim=M+1) 30 | mrd_q75=array(NA,dim=M+1) 31 | mrd_sd=array(NA,dim=M+1) 32 | #mrd 33 | ms=M:0 34 | seg_mean=as.numeric(lapply(var1,mean,na.rm=TRUE)) 35 | var1=var1-mean(var1,na.rm=TRUE) 36 | if (!is.null(var2)) var2=var2-mean(var2,na.rm=TRUE) 37 | for (i in 0:M) { 38 | if (is.null(var2)) { 39 | var1=matrix(var1,ncol=2^(M-i),byrow=TRUE) 40 | wn = apply(var1,1,mean,na.rm=TRUE) 41 | mrd_mean[M-i+1]=mean(wn^2,na.rm=TRUE) 42 | mrd_median[M-i+1]=median(wn^2,na.rm=TRUE) 43 | mrd_q25[M-i+1]=quantile(wn^2,0.25,na.rm=TRUE) 44 | mrd_q75[M-i+1]=quantile(wn^2,0.75,na.rm=TRUE) 45 | mrd_sd[M-i+1]=sd(wn^2,na.rm=T) 46 | var1=c(t(var1-wn)) 47 | } else { 48 | var1=matrix(var1,ncol=2^(M-i),byrow=TRUE) 49 | wn = apply(var1,1,mean,na.rm=TRUE) 50 | var2=matrix(var2,ncol=2^(M-i),byrow=TRUE) 51 | wn2 = apply(var2,1,mean,na.rm=TRUE) 52 | mrd_mean[M-i+1]=mean(wn*wn2,na.rm=TRUE) 53 | mrd_median[M-i+1]=median(wn*wn2,na.rm=TRUE) 54 | mrd_q25[M-i+1]=quantile(wn*wn2,0.25,na.rm=TRUE) 55 | mrd_q75[M-i+1]=quantile(wn*wn2,0.75,na.rm=TRUE) 56 | mrd_sd[M-i+1]=sd(wn*wn2,na.rm=TRUE) 57 | var1=c(t(var1-wn)) 58 | var2=c(t(var2-wn2)) 59 | } 60 | } 61 | out=data.frame("index"=1:(M+1),"m"=M:0,"scale"=2^(M:0),"time"=time_res*(2^(M:0)),"mean"=mrd_mean,"median"=mrd_median,"q25"=mrd_q25,"q75"=mrd_q75) 62 | if (plot==TRUE) plot_mrd(out) 63 | return(out) 64 | } 65 | 66 | 67 | #' Plotting Multiresolution Decomposition 68 | #' 69 | #'@description Plots multiresolution decomposition (MRD) 70 | #'@param mrd_out an object returned from \code{calc_mrd} 71 | #'@param ... parameters passed to plot function 72 | #'@return creates a plot of MRD with logarithmic time scale (no return) 73 | #'@export 74 | #' 75 | #'@examples 76 | #'set.seed(5) 77 | #'series=rnorm(2^10) 78 | #'mrd_test=calc_mrd(c(series)) 79 | #'plot_mrd(mrd_test) 80 | #' 81 | plot_mrd=function(mrd_out,...) { 82 | if (!exists("ylab")) { ylab="MRD" } 83 | if (!exists("xlab")) { xlab="averaging time [s]"} 84 | if (!exists("ylim")) { ylim=c(min(mrd_out$q25[!is.na(mrd_out$q25)]),max(mrd_out$q75[!is.na(mrd_out$q75)])) } 85 | plot(log10(mrd_out$time),mrd_out$median,lwd=2,pch=3,col=4,xlab=xlab,ylab=ylab,ylim=ylim,xaxt="n",type="b",...) 86 | suppressWarnings({ 87 | arrows(log10(mrd_out$time),mrd_out$median,log10(mrd_out$time),mrd_out$q75,lwd=1,col=4,angle=90,length=0.05) 88 | arrows(log10(mrd_out$time),mrd_out$median,log10(mrd_out$time),mrd_out$q25,lwd=1,col=4,angle=90,length=0.05) 89 | }) 90 | points(log10(mrd_out$time),mrd_out$mean,lwd=2,col=1,type="b") 91 | axis(1,at=-1:4,labels=10^(-1:4)) 92 | legend("topleft",legend=c("mean","median"),col=c(1,4),lty=0,pch=c(1,3),lwd=2) 93 | abline(v=log10(60),lty=3) 94 | abline(v=log10(60*30),lty=3) 95 | abline(h=0,lty=3) 96 | } -------------------------------------------------------------------------------- /R/anisotropy.R: -------------------------------------------------------------------------------- 1 | #' Invariant analysis of Reynolds stress tensor 2 | #' 3 | #'@description Invariant analysis of Reynolds stress tensor, calculation of Lumley and barycentric map coordinates and anisotropy 4 | #'@param a11 R11 element of Reynolds stress tensor: \code{u_sd^2} (scalar or vector) 5 | #'@param a12 R12 element of Reynolds stress tensor: \code{cov(u,v)} (scalar or vector) 6 | #'@param a13 R13 element of Reynolds stress tensor: \code{cov(u,w)} (scalar or vector) 7 | #'@param a22 R22 element of Reynolds stress tensor: \code{v_sd^2} (scalar or vector) 8 | #'@param a23 R23 element of Reynolds stress tensor: \code{cov(v,w)} (scalar or vector) 9 | #'@param a33 R33 element of Reynolds stress tensor: \code{w_sd^2} (scalar or vector) 10 | #'@param plot should the barycentric map be plotted? default \code{plot=FALSE} 11 | #' 12 | #'@return list containing \code{xb}, \code{yb}, \code{eta}, \code{xi}, all eigenvalues and eigenvectors (\code{eta}, \code{xi} are the coordinates of the Lumley triangle and \code{xb}, \code{yb} the coordinates of the barycentric map) 13 | #'@export 14 | #' 15 | #'@examples 16 | #'calc_anisotropy(1,0,0,1,0,1) #isotropic 17 | #'calc_anisotropy(1,0,1,1,0,1) #some anisotropy 18 | #' 19 | calc_anisotropy = function(a11,a12,a13,a22,a23,a33,plot=FALSE) { 20 | if (length(unique(sapply(list(a11,a12,a13,a22,a23,a33),length)))>1) { 21 | warning("The given elements of the Reynolds stress tensor are not of equal length.") 22 | } 23 | n=length(a11) 24 | #unit matrix / Kronecker delta 25 | delta=matrix(c(1,0,0,0,1,0,0,0,1), ncol=3,nrow=3) 26 | #initialize 27 | eta=numeric(n) 28 | xi=numeric(n) 29 | xb=numeric(n) 30 | yb=numeric(n) 31 | evals=array(NA,dim=c(n,3)) 32 | evecs=array(NA,dim=c(n,3,3)) 33 | #symmetry 34 | a21=a12 35 | a31=a13 36 | a32=a23 37 | for (i in 1:n) { 38 | rey=matrix(c(a11[i],a12[i],a13[i],a21[i], a22[i],a23[i],a31[i],a32[i],a33[i]),nrow=3,ncol=3) 39 | #cat("\n",i,rey) 40 | if (!any(is.na(rey))) { 41 | if (sum(diag(rey))!=0) { 42 | B = rey/sum(diag(rey))-1/3*delta 43 | #diagonalize the anisotropy matrix (calculate the eigenvalues) 44 | inv=eigen(B) #invariant analysis 45 | ev=inv$values #eigenvalues 46 | Bdiag=ev*delta 47 | evs_sort=rev(sort(ev)) 48 | eta[i] = (1/3*(evs_sort[1]^2 + evs_sort[1]*evs_sort[2] + evs_sort[2]^2))^(1/2) 49 | dummyX=evs_sort[1]*evs_sort[2]*(evs_sort[1]+evs_sort[2]) 50 | xi[i] = -sign(dummyX)*(1/2*abs(dummyX))^(1/3) 51 | #barycentric map 52 | C1c = evs_sort[1]-evs_sort[2] 53 | C2c = 2*(evs_sort[2]-evs_sort[3]) 54 | C3c = 3*(evs_sort[3]) + 1 55 | #coordinates 56 | xb[i] = C1c + 0.5*C3c 57 | yb[i] = C3c*sqrt(3)/2 58 | #store 59 | evals[i,]=ev 60 | evecs[i,,]=inv$vectors 61 | } 62 | } 63 | } 64 | out=list("xb"=xb,"yb"=yb,"eta"=eta,"xi"=xi,"eigenvalues"=evals,"eigenvectors"=evecs) 65 | if (plot==TRUE) plot_barycentric_map(out$xb,out$yb) 66 | return(out) 67 | } 68 | 69 | 70 | #' Plot in barycentric map 71 | #' 72 | #'@description Plots \code{(xb, yb)} from invariant analysis of Reynolds stress tensor (\code{calc_anisotropy}) in barycentric map 73 | #'@param xb xb coordinate (e.g., from \code{calc_anisotropy}) 74 | #'@param yb yb coordinate (e.g., from \code{calc_anisotropy}) 75 | #'@param contours vector containing levels of contour lines for 2d kernel density estimation, default: \code{contours=c(5,10,20)} 76 | #' 77 | #'@return plots (xb, yb) in barycentric map with 2d kernel density estimation (no return) 78 | #'@export 79 | #' 80 | #'@importFrom MASS kde2d 81 | #' 82 | #'@examples 83 | #'set.seed(5) 84 | #'nm=100 85 | #'example1=calc_anisotropy(rep(1,nm),rep(0,nm),runif(nm,0,1), 86 | #' rep(1,nm),rep(0,nm),runif(nm,1,1.5)) 87 | #'plot_barycentric_map(example1$xb,example1$yb) 88 | #' 89 | plot_barycentric_map = function(xb,yb,contours=c(5,10,20)) { 90 | plot(xb,yb,pch=20,col=rgb(0,0,0,0.1),xlim=c(0,1),ylim=c(0,sqrt(3)/2),asp=1,xlab="x",ylab="y",main="Barycentric Map") 91 | segments(0,0,1,0,lwd=2) 92 | segments(0,0,0.5,sqrt(3)/2,lwd=2) 93 | segments(1,0,0.5,sqrt(3)/2,lwd=2) 94 | points(0.5,sqrt(3)/6,pch=3,lwd=2) 95 | points(0,0,pch=20,cex=3) 96 | points(1,0,pch=20,cex=3) 97 | points(0.5,sqrt(3)/2,pch=20,cex=3) 98 | #2d kde 99 | nc=length(contours) 100 | lab=colorRampPalette(c("blue3","red3"), space = "Lab") 101 | kde=MASS::kde2d(xb,yb) 102 | contour(kde$x,kde$y,kde$z,levels=contours,col=lab(nc)[1:nc],add=TRUE,lwd=2,drawlabels=FALSE) 103 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reddy: A toolbox for analyzing eddy-covariance measurements 2 | 4 | [![doc](https://img.shields.io/badge/Reddy-documentation-blue)](https://noctiluc3nt.github.io/ec_analyze/) 5 | [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) 6 | [![Last Commit](https://img.shields.io/github/last-commit/noctiluc3nt/Reddy)](https://github.com/noctiluc3nt/Reddy) 7 | 9 | 10 | 11 | ## Installation 12 | The package Reddy can be installed directly from github: 13 | ``` 14 | devtools::install_git("https://github.com/noctiluc3nt/Reddy") 15 | ``` 16 | 17 | ## Documentation, Examples and Usage 18 | The [manual](https://github.com/noctiluc3nt/Reddy/tree/main/inst/manual/Reddy-manual.pdf) describes all functions and the [gitbook](https://noctiluc3nt.github.io/ec_analyze/) provides background information and examples how to execute the core functions of this package. The examples are also provided as [jupyter notebooks](https://github.com/noctiluc3nt/ec_analyze/tree/main/notebooks) (based on [example data](https://github.com/noctiluc3nt/ec_analyze/tree/main/data)). 19 | 20 | ## Functionality and Scripts 21 | The Reddy package provides functions for the post-processing, analysis and evaluation of eddy-covariance measurements, which are described in the [manual](https://github.com/noctiluc3nt/Reddy/tree/main/inst/manual/Reddy-manual.pdf) and are divided into the following scripts: 22 | - `anisotropy.R`: invariant analysis of the Reynolds stress tensor, calculation of turbulence anisotropy and visualization in a barycentric map 23 | - `auxilliary.R`: collection of some useful generic functions for the evaluation (e.g., discrete binning, cross-correlation maximization) 24 | - `bulk_closures.R`: collection of functions used to calculated bulk closures, flux-profile and flux-variance relations (e.g. Richardson number, eddy viscosity, eddy conductivity, scaling functions) 25 | - `constants.R`: constants used for calculations (internal) 26 | - `diagnostics-meteorology.R`: calculation of "background-meteorology" quantities (e.g., clear-sky index, vapor pressure deficit, unit conversions of moisture variables) 27 | - `diagnostics-turbulence.R`: calculation of some standard turbulence diagnostics (e.g., friction velocity, TKE, turbulence intensity, stability parameter) 28 | - `ec-processing.R`: collection of functions for post-processing and quality control of eddy-covariance measurements 29 | - `ec-processing-routine.R`: an example for a post-processing and quality control routine of eddy-covariance measurements utilizing the functions in `ec-processing.R` with storing the final averaged output data in an external file 30 | - `flux-footprint.R`: calculation and visualization of 2D flux footprint (FFP, Kljun et al., 2015) 31 | - `model-utils.R`: collection of function to post-process NWP model output (e.g. flux deaccumulation, conversion of sigma levels to physical height) 32 | - `multiresolution-decomposition.R`: calculation and visualization of multiresolution decomposition (MRD, Vickers and Mahrt, 2003) 33 | - `quadrant-analysis.R`: calculation and visualization of quadrant analysis to study coherent structures and their organization 34 | - `spectrum.R`: calculation and visualization of frequency (temporal) and wavenumber (spatial) spectra, possibility to bin them to compare them with theoretically expected slopes 35 | - `surface-energy-balance.R`: visualization of surface energy balance, residual flux and closure ratio 36 | 37 | 47 | 48 | **Any issues or comments?** Create an issue [here](https://github.com/noctiluc3nt/Reddy/issues). 49 | 50 | ## Literature 51 | - Foken, T. (2017). Micrometeorology, Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-642-25440-6. 52 | - Kljun, N., Calanca, P., Rotach, M. W., Schmid, H. P. (2015). A simple two-dimensional parameterisation for Flux Footprint 53 | Prediction (FFP), Geoscientific Model Development, 8, 3695-3713. DOI: https://doi.org/10.5194/gmd-8-3695-2015 54 | - Mack, L., Berntsen, T.K., Vercauteren, N., Pirk, N. (2024). Transfer Efficiency and Organization in Turbulent Transport over Alpine Tundra. Boundary-Layer Meteorology 190, 38. DOI: https://doi.org/10.1007/s10546-024-00879-5 55 | - Vickers, D., Mahrt, L. (2003). The Cospectral Gap and Turbulent Flux Calculations. Journal of Atmospheric and Oceanic Technology, 20:660-672. DOI: 56 | [https://doi.org/10.1175/1520-0426(2003)20<660:TCGATF>2.0.CO;2](https://doi.org/10.1175/1520-0426(2003)20<660:TCGATF>2.0.CO;2) 57 | 58 | 59 | -------------------------------------------------------------------------------- /man/ECprocessing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ec-processing-routine.R 3 | \name{ECprocessing} 4 | \alias{ECprocessing} 5 | \title{Eddy-covariance post-processing} 6 | \usage{ 7 | ECprocessing( 8 | u, 9 | v, 10 | w, 11 | temp, 12 | h2o = NULL, 13 | co2 = NULL, 14 | ch4 = NULL, 15 | time_resolution = 0.05, 16 | time_averaging = 30, 17 | measurement_height = 1, 18 | do_despiking = TRUE, 19 | despike_u = c(-15, 15, 10, 2, 8), 20 | despike_v = c(-15, 15, 10, 2, 8), 21 | despike_w = c(-4, 4, 10, 2, 8), 22 | despike_temp = c(230, 300, 10, 2, 8), 23 | despike_h2o = c(0, 12, 10, 2, 8), 24 | despike_co2 = c(300, 500, 10, 4, 10), 25 | despike_ch4 = c(0, 12, 10, 2, 8), 26 | do_detrending = FALSE, 27 | do_double_rotation = TRUE, 28 | do_planar_fit = FALSE, 29 | do_flagging = TRUE, 30 | dir_blocked = c(0, 0), 31 | do_SNDcorrection = TRUE, 32 | A = 7/8, 33 | B = 7/8, 34 | store = TRUE, 35 | format_out = "txt", 36 | filename = NULL, 37 | meta = TRUE 38 | ) 39 | } 40 | \arguments{ 41 | \item{u}{u-wind [m/s] (sonic)} 42 | 43 | \item{v}{v-wind [m/s] (sonic)} 44 | 45 | \item{w}{w-wind [m/s] (sonic)} 46 | 47 | \item{temp}{temperature [K] (sonic)} 48 | 49 | \item{h2o}{H2O mixing ratio (gas analyzer, optional)} 50 | 51 | \item{co2}{CO2 mixing ratio (gas analyzer, optional)} 52 | 53 | \item{ch4}{CH4 mixing ratio (gas analyzer, optional)} 54 | 55 | \item{time_resolution}{time resolution of the measurements [s], default 20 Hz = 0.05 s} 56 | 57 | \item{time_averaging}{desired time averaging for flux calculations [min], default 30 minutes} 58 | 59 | \item{measurement_height}{measurement height [m], only used for calculation of the stability parameter \code{zeta}} 60 | 61 | \item{do_despiking}{logical, should the data be despiked? default \code{TRUE}} 62 | 63 | \item{despike_u}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_u=c(-15,15,10,2,8)}} 64 | 65 | \item{despike_v}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_v=c(-15,15,10,2,8)}} 66 | 67 | \item{despike_w}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_w=c(-4,4,10,2,8)}} 68 | 69 | \item{despike_temp}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_temp=c(230,300,10,2,8)}} 70 | 71 | \item{despike_h2o}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_h2o=c(0,12,10,2,8)}} 72 | 73 | \item{despike_co2}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_co2=c(0,12,10,2,8)}} 74 | 75 | \item{despike_ch4}{vector containing 5 elements: lower and upper bound, MAD factor, threshold skewness, threshold kurtosis. Details see \code{?despiking}. Default \code{despike_ch4=c(0,12,10,2,8)}} 76 | 77 | \item{do_detrending}{logical, should the data be linearly detrended? default \code{FALSE}} 78 | 79 | \item{do_double_rotation}{logical, should the wind data be double rotated? default \code{TRUE}} 80 | 81 | \item{do_planar_fit}{logical, should the data be rotated with planar fit? default \code{FALSE} (either double rotation or planar fit can be \code{TRUE})} 82 | 83 | \item{do_flagging}{logical, should the data be flagged? default \code{TRUE}, i.e. several flags are calculated, but no data is removed, can be used for quality analysis} 84 | 85 | \item{dir_blocked}{vector containing 2 elements: wind directions blocked through mast or tower, used in flow distortion flag only} 86 | 87 | \item{do_SNDcorrection}{logical, should SND correction be applied to the buoyancy flux? default \code{TRUE}} 88 | 89 | \item{A}{constant used in SND correction, default \code{A=7/8} for CSAT3 sonic} 90 | 91 | \item{B}{constant used in SND correction, default \code{A=7/8} for CSAT3 sonic} 92 | 93 | \item{store}{logical, should the output be stored? default \code{TRUE}} 94 | 95 | \item{format_out}{file format of the output, can be either \code{txt} or \code{rds} (for netcdf, see separate function), only used if \code{store=TRUE}} 96 | 97 | \item{filename}{desired output filename, default \code{NULL}, the date and time of the run will be used to create a filename, only used if \code{store=TRUE}} 98 | 99 | \item{meta}{logical, should meta data be stored? default \code{TRUE}} 100 | } 101 | \value{ 102 | data frame of post-processed eddy-covariance data (that is also stored in the output file by default) 103 | } 104 | \description{ 105 | An example for an eddy-covariance post-processing routine utilizing the functions from ec_processing.R 106 | } 107 | -------------------------------------------------------------------------------- /R/auxilliary.R: -------------------------------------------------------------------------------- 1 | #' discrete binning 2 | #' 3 | #'@description discrete binning of a variable \code{var1} based on another variable \code{var2} (e.g., the stability parameter \code{zeta}) 4 | #'@param var1 vector, variable that should be binned 5 | #'@param var2 vector, variable used for the binning 6 | #'@param bins vector, providing the intervals of the bins of \code{var2} 7 | #'@return matrix of dimension (\code{length(bins)-1,4}) with columns representing mean, median, q25, q75 8 | #'@export 9 | #' 10 | #'@examples 11 | #'zeta_bins=c(-10^(3:-3),10^(-3:3)) 12 | #'zeta_vals=rnorm(1000) 13 | #'vals=runif(1000) 14 | #'binned=binning(vals,zeta_vals,zeta_bins) 15 | #' 16 | binning=function(var1,var2,bins) { 17 | if (length(var1)!=length(var2)) { 18 | stop("var1 and var2 have to have the same length.") 19 | } else { 20 | nbins=length(bins) 21 | out=array(NA,dim=c(nbins-1,4)) 22 | for (i in 2:nbins) { 23 | sub=var1[var2>bins[i-1] & var20) { #positive lag = var1 leads var2 75 | mat[,1]=c(var1,rep(NA,lag)) 76 | mat[,2]=c(rep(NA,lag),var2[1:n]) 77 | } else { #negative lag = var2 leads var1 78 | mat[,1]=c(rep(NA,abs(lag)),var1[1:n]) 79 | mat[,2]=c(var2,rep(NA,abs(lag))) 80 | } 81 | return(mat) 82 | } 83 | 84 | 85 | #' gap-filling 86 | #' 87 | #'@description gap-filling of a timeseries based on linear or constant interpolation 88 | #'@param var timeseries, where NA indicates missing values that should be filled 89 | #'@param method interpolation method, can be either \code{method = "linear"} for linear interpolation (default) or \code{method = "constant"} for constant interpolation 90 | #'@param nmissing number of allowed missing values, default \code{nmissing = 4} 91 | #'@return gap-filled timeseries 92 | #'@export 93 | #' 94 | #'@examples 95 | #'ts1=c(1,2,NA,0) 96 | #'gapfilling(ts1) #1,2,1,0 97 | #'gapfilling(ts1,method="constant") #1,2,2,0 98 | #'gapfilling(ts1,nmissing=0) #too many missing values 99 | #' 100 | gapfilling=function(var,nmissing=4,method="linear") { 101 | n=length(var) 102 | nm=sum(is.na(var)) 103 | if (nm <= nmissing) { 104 | var_interpolated = approx(1:n,var,xout=1:n,method=method) 105 | return(var_interpolated$y) 106 | } else { 107 | warning("The timeseries contains more missing values than desired (specified in nmissing).") 108 | } 109 | } 110 | 111 | 112 | #' accumulating / averaging 113 | #' 114 | #'@description averaging of a timeseries 115 | #'@param var timeseries 116 | #'@param tres1 time resolution [s] of the given timeseries \code{var}, default \code{tres1 = 0.05} (for 20 Hz) 117 | #'@param tres2 desired time resolution(s) [s] of the averaged timeseries (scalar or vector), default \code{tres2 = c(1,10,30)*60} (for 1, 10 and 30 minutes) 118 | #'@return list containing mean and standard deviation of the timeseries for the desired time interval(s) 119 | #'@export 120 | #'@importFrom RcppRoll roll_mean roll_sd roll_max 121 | #' 122 | #'@examples 123 | #'ts=rnorm(30*60*20) #30 minutes of 20 Hz measurements 124 | #'averaging(ts) 125 | #' 126 | averaging=function(var,tres1=0.05,tres2=c(1,10,30)*60) { 127 | n=length(var) 128 | nt=length(tres2) 129 | maxt=max(tres2) 130 | if (n<(maxt/tres1)) warning("The timeseries is not long enough for the desired (maximum) averaging time.") 131 | nav=tres2/tres1 #number of values to be averaged 132 | averaged_mean=list() 133 | averaged_sd=list() 134 | averaged_max=list() 135 | for (i in 1:nt) { 136 | vari=RcppRoll::roll_mean(var,nav[i],na.rm=TRUE)[seq(1,n,nav[i])] 137 | averaged_mean[[i]]=vari 138 | vari=RcppRoll::roll_sd(var,nav[i],na.rm=TRUE)[seq(1,n,nav[i])] 139 | averaged_sd[[i]]=vari 140 | vari=RcppRoll::roll_max(var,nav[i],na.rm=TRUE)[seq(1,n,nav[i])] 141 | averaged_max[[i]]=vari 142 | } 143 | averaged=list("mean"=averaged_mean,"sd"=averaged_sd,"max"=averaged_max) 144 | averaged$averaging_time_min=tres2/60 145 | averaged$number_of_averaged_values=nav 146 | return(averaged) 147 | } 148 | 149 | 150 | #' calculates circular mean 151 | #' 152 | #'@description calculates circular mean 153 | #'@param x input vector, e.g. wind directions [degree] 154 | #'@param na.rm should NA values be removed? default \code{TRUE} 155 | #'@return circular mean of x values 156 | #'@export 157 | #' 158 | #'@examples 159 | #'wd=c(280,90) 160 | #'calc_circular_mean(wd) 161 | #' 162 | calc_circular_mean=function(x,na.rm=TRUE) { 163 | x=x*pi/180 164 | if (na.rm==TRUE) return((atan2(sum(sin(x),na.rm=TRUE),sum(cos(x),na.rm=TRUE))*180/pi)%%360) 165 | if (na.rm==FALSE) return((atan2(sum(sin(x)),sum(cos(x)))*180/pi)%%360) 166 | } 167 | -------------------------------------------------------------------------------- /R/quadrant-analysis.R: -------------------------------------------------------------------------------- 1 | #' Calculating Coherent Structures following Quadrant Analysis 2 | #' 3 | #'@description Calculates occurrence fraction and strength of the four quadrants in the framework of quadrant analysis 4 | #'@param xval values of x variable (vector) 5 | #'@param yval values of y variable (vector) 6 | #'@param do_normalization should the values be normalized? i.e. \code{(x-mean(x))/sd(x)}, default: \code{do_normalization=TRUE} 7 | #'@param hole_sizes vector containing desired hole sizes (integers >= 0) 8 | #'@param orient only relevant for exuberance and organization ratio: if down-gradient flux corresponds to positive values, use \code{orient="+"} (for sensible and latent heat flux), if down-gradient flux corresponds to negative values, use \code{orient="-"} (for momentum flux and CO2 flux) 9 | #'@param plot logical, should the quadrant analysis be plotted? default \code{plot=TRUE} 10 | #'@param ... arguments passed to \code{plot_quadrant_analysis} 11 | #' 12 | #'@return list containing occurrence fraction and strength (calculated based on product and covariance) for all four quadrants (mathematical orientation) as well as the therefrom derived measures exuberance and organization ratio, i.e. the ratio of the strength (or occurrence frequency, respectively) of disorganized to organized structures 13 | #'@export 14 | #' 15 | #'@examples 16 | #'a=rnorm(100) 17 | #'b=rnorm(100) 18 | #'qa_ab=calc_quadrant_analysis(a,b) 19 | #' 20 | calc_quadrant_analysis=function(xval,yval,do_normalization=TRUE,hole_sizes=seq(0,10),orient="+",plot=TRUE,...) { 21 | covariance_total=cov(xval,yval,use="pairwise.complete.obs") 22 | correlation_total=cor(xval,yval,use="pairwise.complete.obs") 23 | if (do_normalization==TRUE) { 24 | xval = (xval-mean(xval,na.rm=TRUE))/sd(xval,na.rm=TRUE) 25 | yval = (yval-mean(yval,na.rm=TRUE))/sd(yval,na.rm=TRUE) 26 | } 27 | nh = length(hole_sizes) 28 | occurrence = array(NA,dim=c(4,nh)) 29 | product = array(NA,dim=c(4,nh)) 30 | covariance = array(NA,dim=c(4,nh)) 31 | for (i in 1:nh) { 32 | #q1 33 | is.q1 = (xval>(hole_sizes[i]/xval) & yval>(-hole_sizes[i]/yval)) 34 | occurrence[1,i] = sum(is.q1,na.rm=TRUE) 35 | product[1,i] = mean(xval[is.q1] * yval[is.q1],na.rm=TRUE) 36 | covariance[1,i] = cov(xval[is.q1],yval[is.q1]) 37 | #q2 38 | is.q2 = (xval<(-hole_sizes[i]/xval) & yval>(-hole_sizes[i]/xval)) 39 | occurrence[2,i] = sum(is.q2,na.rm=TRUE) 40 | product[2,i] = mean(xval[is.q2] * yval[is.q2],na.rm=TRUE) 41 | covariance[2,i] = cov(xval[is.q2],yval[is.q2]) 42 | #q3 43 | is.q3 = (xval<(hole_sizes[i]/xval) & yval<(hole_sizes[i]/yval)) 44 | occurrence[3,i] = sum(is.q3,na.rm=TRUE) 45 | product[3,i] = mean(xval[is.q3] * yval[is.q3],na.rm=TRUE) 46 | covariance[3,i] = cov(xval[is.q3],yval[is.q3]) 47 | #q4 48 | is.q4 = (xval>(-hole_sizes[i]/xval) & yval<(-hole_sizes[i]/xval)) 49 | occurrence[4,i] = sum(is.q4,na.rm=TRUE) 50 | product[4,i] = mean(xval[is.q4] * yval[is.q4],rm=TRUE) 51 | covariance[4,i] = cov(xval[is.q4],yval[is.q4]) 52 | } 53 | #exuberance and organization ratio 54 | if (orient == "-") { 55 | exub=(product[1,]+product[3,])/(product[2,]+product[4,]) 56 | or=(occurrence[1,]+occurrence[3,])/(occurrence[2,]+occurrence[4,]) 57 | } else if (orient == "+") { 58 | exub=(product[2,]+product[4,])/(product[1,]+product[3,]) 59 | or=(occurrence[2,]+occurrence[4,])/(occurrence[1,]+occurrence[3,]) 60 | } else { 61 | warning("The orientation has to be either + or -.") 62 | } 63 | qa_out=list("hole_sizes"=hole_sizes, 64 | "occurrence"=occurrence, 65 | "product"=product, 66 | "covariance"=covariance, 67 | "covariance_total"=covariance_total, 68 | "correlation_total"=correlation_total, 69 | "exuberance"=exub, 70 | "organization_ratio"=or, 71 | "meta"="Output format: rows represent the quadrants Q1, Q2, Q3, Q4 -- columns represent selected hole sizes") 72 | if (plot==TRUE) { 73 | plot_quadrant_analysis(xval,yval,do_normalization=FALSE,...) 74 | print(qa_out) 75 | } 76 | return(qa_out) 77 | } 78 | 79 | #' Plotting Quadrant Analysis 80 | #' 81 | #'@description Plots two vectors in the framework of quadrant analysis with 2d kernel density estimation 82 | #'@param xval values of x variable (vector) 83 | #'@param yval values of y variable (vector) 84 | #'@param do_normalization should the values be normalized? i.e. \code{(x-mean(x))/sd(x)}, default: \code{do_normalization=TRUE} 85 | #'@param hole_sizes vector containing desired hole sizes (integers >= 0), default: \code{hole_sizes=c(1,2)} 86 | #'@param contours vector containing levels of contour lines for 2d kernel density estimation, default: \code{contours=10^(-3:3)} 87 | #'@param print_fit should the fit summary from the linear regression be printed? default: \code{print_fit=TRUE} 88 | #'@param ... arguments passed to plot function 89 | #'@return no return 90 | #'@export 91 | #' 92 | #'@importFrom MASS kde2d 93 | #' 94 | #'@examples 95 | #'a=rnorm(100) 96 | #'b=rnorm(100) 97 | #'plot_quadrant_analysis(a,b) 98 | #' 99 | plot_quadrant_analysis=function(xval,yval,do_normalization=TRUE,hole_sizes=c(1,2),contours=10^(-3:3),print_fit=TRUE,...) { 100 | if (do_normalization) { 101 | xval=(xval-mean(xval,na.rm=TRUE))/sd(xval) 102 | yval=(yval-mean(yval,na.rm=TRUE))/sd(yval) 103 | } 104 | if (!exists("pch")) pch = 20 105 | if (typeof(col)=="closure") col = rgb(0.6,0.6,0.6,0.1) 106 | plot(xval,yval,col=col,pch=pch,...) 107 | abline(h=0,lty=2,col=1,lwd=2) 108 | abline(v=0,lty=2,col=1,lwd=2) 109 | #linear regression 110 | fit=lm(yval~xval) 111 | if (print_fit==TRUE) print(summary(fit)) 112 | abline(fit,lwd=3,col="red4") 113 | #2d kde 114 | nc=length(contours) 115 | lab=colorRampPalette(c("blue3","red3"), space = "Lab") 116 | kde=MASS::kde2d(xval,yval) 117 | contour(kde$x,kde$y,kde$z,levels=contours,col=lab(nc)[1:nc],add=TRUE,lwd=2,drawlabels=FALSE) 118 | #draw holes 119 | xs=seq(-10,10,0.1) 120 | for (h in hole_sizes) { 121 | points(xs,h/xs,col=1,type="l",lty=2,lwd=1,pch=pch) 122 | points(xs,-h/xs,col=1,type="l",lty=2,lwd=1,pch=pch) 123 | } 124 | } 125 | 126 | 127 | -------------------------------------------------------------------------------- /R/diagnostics-meteorology.R: -------------------------------------------------------------------------------- 1 | #' Saturation vapor pressure over water 2 | #' 3 | #'@description Calculates the saturation vapor pressure over water for given temperature and pressure 4 | #'@param temp temperature [K] 5 | #'@return E_s, saturation vapor pressure over water [Pa] 6 | #'@export 7 | #' 8 | #'@examples 9 | #'calc_satvaporpressure(273) 10 | #' 11 | calc_satvaporpressure = function(temp) { 12 | a=0.61094 13 | b=17.625 14 | c=243.04 15 | temp=temp-273.15 #K to deg C 16 | return(a*exp(b*temp/(temp+c))*1000) 17 | } 18 | 19 | #' Vapor pressure deficit (VPD) 20 | #' 21 | #'@description Calculates vapor pressure deficit (VPD) from temperature and relative humidity using Arrhenius formula 22 | #'@param temp temperature [K] 23 | #'@param rh relative humidity [percent] 24 | #'@return VPD, vapor pressure deficit [Pa] 25 | #'@export 26 | #' 27 | #'@examples 28 | #'calc_vpd(273,70) 29 | #' 30 | calc_vpd = function(temp,rh) { 31 | #calculate saturation pressure here using Arrhenius formula 32 | a=-1.0440397*10^4 33 | b=-11.29465 34 | c=-2.7022355*10^-2 35 | d=1.289036*10^-5 36 | e=-2.4780681*10^-9 37 | f=6.5459673 38 | temp=temp*5/9 #K to deg R (Rankine scale) 39 | es=exp(a/temp+b+c*temp+d*temp^2+e*temp^3+f*log(temp)) 40 | return(es*(1-rh/100)) 41 | } 42 | 43 | #' Potential temperature 44 | #' 45 | #'@description Calculates potential temperature for given temperature and pressure 46 | #'@param temp temperature [K] 47 | #'@param pres pressure [Pa] 48 | #'@return potential temperature [K] 49 | #'@export 50 | #' 51 | #'@examples 52 | #'calc_theta(273,70000) 53 | #' 54 | calc_theta = function(temp,pres) { 55 | return(temp*(100000/pres)^(Rd()/cp())) 56 | } 57 | 58 | #' Virtual temperature 59 | #' 60 | #'@description Calculates virtual temperature for given temperature and specific humidity (mixing ratio) 61 | #'@param temp temperature [K] 62 | #'@param q specific humidity [kg/kg] 63 | #'@return virtual temperature [K] 64 | #'@export 65 | #' 66 | #'@examples 67 | #'calc_Tv(273,0) #no difference 68 | #'calc_Tv(273,0.1) 69 | #' 70 | calc_Tv = function(temp,q) { 71 | return(temp*(1+Rd()/Rv()*q)) 72 | } 73 | 74 | #' Converts pressure to height (using barometric formula) 75 | #' 76 | #'@description Calculates height from pressure 77 | #'@param pres pressure [Pa] 78 | #'@param pres0 reference pressure, scalar [Pa], default \code{pres0=101315} 79 | #'@param temp0 reference temperature, scalar [K], default \code{temp0=288.15} 80 | #'@return height [m] 81 | #'@export 82 | #' 83 | #'@examples 84 | #'pres2height(60000) #using default surface values 85 | #'pres2height(60000,95000,265) #adapted surface values 86 | #' 87 | pres2height = function(pres,pres0=101315,temp0=288.15) { 88 | return(temp0/0.0065*(1-(pres/pres0)^(1/5.255))) 89 | } 90 | 91 | #' Converts relative humidity to specific humidity 92 | #' 93 | #'@description Calculates specific humidity from relative humidity, temperature and pressure 94 | #'@param rh relative humidity [percent] 95 | #'@param temp temperature [K] 96 | #'@param pres pressure [Pa] 97 | #'@return specific humidity [kg/kg] 98 | #'@export 99 | #' 100 | #'@examples 101 | #'rh2q(70,273,101300) 102 | #' 103 | rh2q = function(rh,temp,pres) { 104 | es=calc_satvaporpressure(temp) #saturation vapor pressure [Pa] 105 | e=rh*es/100 #vapor pressure [Pa] 106 | w=e*Rd()/(Rv()*(pres-e)) 107 | return(w/(w+1)) 108 | } 109 | 110 | #' Converts relative humidity to absolute humidity 111 | #' 112 | #'@description Calculates absolute humidity from relative humidity and temperature 113 | #'@param rh relative humidity [percent] 114 | #'@param temp temperature [K] 115 | #'@return absolute humidity [kg/m^3] 116 | #'@export 117 | #' 118 | #'@examples 119 | #'rh2ah(70,273) 120 | #' 121 | rh2ah = function(rh,temp) { 122 | es=calc_satvaporpressure(temp)/100 #saturation vapor pressure [hPa, here] 123 | return(es*rh*2.1674/temp/1000) 124 | } 125 | 126 | #' Converts absolute humidity to relative humidity 127 | #' 128 | #'@description Calculates absolute humidity from relative humidity and temperature 129 | #'@param ah absolute humidity [kg/m^3] 130 | #'@param temp temperature [K] 131 | #'@return relative humidity [percent] 132 | #'@export 133 | #' 134 | #'@examples 135 | #'ah2rh(0.005,273) 136 | #' 137 | ah2rh = function(ah,temp) { 138 | es=calc_satvaporpressure(temp)/100 #saturation vapor pressure [hPa, here] 139 | return(ah/(2.1674*es)*temp*1000) 140 | } 141 | 142 | #' Clear Sky Index (CSI) 143 | #' 144 | #'@description Calculates clear sky index 145 | #'@param temp temperature [K] 146 | #'@param lw_in longwave incoming radiation [W/m^2] 147 | #'@param rh relative humidity [percent] 148 | #'@param e vapor pressure [Pa] (either rh or e have to be given) 149 | #'@return CSI, clear sky index 150 | #'@export 151 | #' 152 | #'@examples 153 | #'calc_csi(273,230,70) #with relative humidity 154 | #' 155 | calc_csi = function(temp,lw_in,rh=NULL,e=NULL) { 156 | if (is.null(rh) & is.null(e)) { 157 | stop("Either relative humidity rh or vapor pressure e have to be given.") 158 | } 159 | if (!is.null(rh)) { #calculate vapor pressure 160 | es = calc_satvaporpressure(temp) 161 | e = rh * es/100 162 | } 163 | sigma=5.67*10^(-8) 164 | epsilon_A = lw_in/(sigma*temp^4) #actual atmospheric emissivity 165 | epsilon = 0.23 + 0.47*(100*e/temp)^(1/8) #(theoretical) clear sky emissivity, Marty and Philiponna, 2002 166 | return(epsilon_A/epsilon) 167 | } 168 | 169 | 170 | ### wind basics ### 171 | #' Wind Direction 172 | #' 173 | #'@description Calculates (horizontal) wind direction 174 | #'@param u u-wind [m/s] 175 | #'@param v v-wind [m/s] 176 | #' 177 | #'@return wind direction [deg] 178 | #'@export 179 | #' 180 | #'@examples 181 | #'calc_windDirection(3,3) 182 | #' 183 | calc_windDirection = function(u,v) { 184 | return((180+180/pi*atan2(v,u))%%360) #from ERA5 doc: https://confluence.ecmwf.int/pages/viewpage.action?pageId=133262398 185 | } 186 | 187 | #' Horizontal Wind Speed 188 | #' 189 | #'@description Calculates horizontal wind speed 190 | #'@param u u-wind [m/s] 191 | #'@param v v-wind [m/s] 192 | #' 193 | #'@return wind speed [m/s] 194 | #'@export 195 | #' 196 | #'@examples 197 | #'calc_windSpeed2D(3,3) 198 | #' 199 | calc_windSpeed2D = function(u,v) { 200 | return(sqrt(u^2+v^2)) 201 | } 202 | 203 | #' Wind Speed (3D) 204 | #' 205 | #'@description Calculates wind speed (3D) 206 | #'@param u u-wind [m/s] 207 | #'@param v v-wind [m/s] 208 | #'@param w w-wind [m/s] 209 | #' 210 | #'@return wind speed (3D) [m/s] 211 | #'@export 212 | #' 213 | #'@examples 214 | #'calc_windSpeed3D(3,3,0.1) 215 | #' 216 | calc_windSpeed3D = function(u,v,w) { 217 | return(sqrt(u^2+v^2+w^2)) 218 | } 219 | 220 | #' Gust Factor 221 | #' 222 | #'@description Calculates gust factor G := ws_max/ws_mean 223 | #'@param ws_max wind speed [m/s] 224 | #'@param ws_mean wind speed maximum [m/s] 225 | #' 226 | #'@return gust factor [-] 227 | #'@export 228 | #' 229 | #'@examples 230 | #'calc_gustfactor(6,3) 231 | #' 232 | calc_gustfactor = function(ws_max,ws_mean) { 233 | return(ws_max/ws_mean) 234 | } 235 | -------------------------------------------------------------------------------- /R/flux-footprint.R: -------------------------------------------------------------------------------- 1 | #' Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015 2 | #' 3 | #'@description Calculates the Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015 4 | #'@param zm measurement height [m] 5 | #'@param ws_mean mean horizontal wind speed [m/s] (alternatively you can also use \code{z0}) 6 | #'@param wd_mean mean wind direction [deg] (used to rotate flux footprint, optional) 7 | #'@param blh boundary-layer height [m] 8 | #'@param L Obukhov length [m] 9 | #'@param v_sd standard deviation of crosswind [m/s] 10 | #'@param ustar friction velocity [m/s] 11 | #'@param z0 roughness length [m] (either \code{ws_mean} or \code{z0} have to be given) 12 | #'@param contours which contour lines should be calculated? default: \code{contours=seq(0.9,0.1,-0.1)} 13 | #'@param nres resolution (default: \code{nres=1000}) 14 | #'@param plot logical, should the flux footprint be plotted? default \code{plot=TRUE} 15 | #' 16 | #'@return list containing all relevant flux footprint information 17 | #'@export 18 | #' 19 | #'@examples 20 | #'#unrotated (i.e. if wind direction not given): 21 | #'ffp=calc_flux_footprint(zm=20,ws_mean=2,blh=200,L=-1.5,v_sd=0.6,ustar=0.4,contours=0.8) 22 | #'#rotated (i.e. given wind direction): 23 | #'ffp=calc_flux_footprint(zm=20,ws_mean=2,wd_mean=80,blh=200,L=-1.5,v_sd=0.6,ustar=0.4,contours=0.8) 24 | #' 25 | calc_flux_footprint = function(zm, ws_mean=NA, wd_mean = NA, blh, L, v_sd, ustar, z0=NA,contours=seq(0.9,0.1,-0.1),nres=1000,plot=TRUE) { 26 | #fitting parameters for crosswind-integrated footprint, see (Kljun et al., 2015) eq. 17 27 | a=1.452 28 | b=-1.991 29 | c=1.462 30 | d=0.136 31 | xstarmax=-c/b+d #eq. 20 32 | #fitting parameters for crosswind footprint, see (Kljun et al., 2015) eq. 19 33 | ac=2.17 34 | bc=1.66 35 | cc=20 36 | #prepare non-dimensional upwind distance 37 | xstar=seq(d,30,length=nres)[-1] 38 | #calculate crosswind-integrated footprint 39 | fstar=a*(xstar-d)^b*exp(-c/(xstar-d)) #eq. 14 40 | #calculate standard deviation of crosswind distance 41 | sigmay_star=ac*sqrt(bc*xstar^2/(1+cc*xstar)) #eq. 18 42 | #calculate real scale footprint and maximum location 43 | if (!is.na(ws_mean)) { #use ws_mean if given 44 | aux1=zm/(1-zm/blh)*ws_mean/ustar*karman() 45 | x=xstar*aux1 #eq. 21 for all xstar 46 | fy_mean=fstar/aux1 #eq. 8 inverted 47 | xmax=xstarmax*aux1 48 | } else if (!is.na(z0)) { 49 | #uses eq. 5, stability correction function for diabatic wind profiles following Hogstroem, 1996 50 | if (L<=0) { #unstable or neutral conditions 51 | xi=(1-19*zm/L)^0.25 52 | psim=log((1+xi^2)/2) + 2*log((1+xi)/2) - 2*atan(xi)+pi/2 53 | } else { #stable conditions 54 | psim=-5.3*zm/L 55 | } 56 | aux2=zm/(1-zm/blh)*(log(zm/z0)-psim) 57 | x=xstar*aux2 #eq. 22 58 | xmax=xstarmax*aux2 59 | if ((log(zm/z0)-psim)>0) { 60 | fy_mean=fstar/aux2 #eq. 9 61 | } else { 62 | error = -1 63 | } 64 | } else { 65 | stop("You have to know either ws_mean or z0.") 66 | } 67 | #calculate real scale y_sd 68 | ps1=min(1,abs(1/(zm/L))*1E-5 + ifelse(L<=0,0.8,0.55)) 69 | sigmay=sigmay_star/ps1*zm*v_sd/ustar #eq. 13 inverted 70 | #calculate real scale f(x,y) 71 | dx=x[3]-x[2] 72 | ypos=seq(0,length(x)/2*dx*1.5,dx) 73 | fpos=matrix(NA,nrow=length(fy_mean),ncol=length(ypos)) 74 | for (i in 1:length(fy_mean)) { 75 | fpos[i,]=fy_mean[i]/(sqrt(2*pi)*sigmay[i])*exp(-ypos^2/(2*sigmay[i]^2)) #eq. 10 76 | } 77 | #footprint 2d 78 | n1=1 79 | n2=length(ypos) 80 | nf=nrow(fpos) 81 | fmat=array(NA,dim=c(nf,2*n2-1)) 82 | fmat[,1:(n2-1)]=fpos[,n2:2] #symmetry 83 | fmat[,n2:(2*n2-1)]=fpos 84 | nx=length(x) 85 | y=c(-rev(ypos),ypos[2:n2]) 86 | ny=length(y) 87 | xmat=matrix(rep(x,ny),nrow=ny,ncol=nx,byrow=TRUE) 88 | ymat=matrix(rep(y,nx),nrow=ny,ncol=nx) 89 | #footprint contours 90 | nc=length(contours) 91 | fsort=rev(sort(c(fmat))) 92 | fsort=fsort[!is.na(fsort)] 93 | fint=cumsum(fsort)*dx^2 94 | ffp_cont=list() 95 | for (i in 1:nc) { 96 | fdiff=abs(fint-contours[i]) 97 | ind=which.min(fdiff) 98 | fr=fsort[ind] 99 | cont=contourLines(x,y,fmat,levels=fr) 100 | ffp_cont$xcont[[i]]=cont[[1]]$x 101 | ffp_cont$ycont[[i]]=cont[[1]]$y 102 | } 103 | #rotate flux footprint 104 | xcont_rot=list() 105 | ycont_rot=list() 106 | if (!is.na(wd_mean)) { 107 | #rotate area (2d data) using polar coordinates 108 | wd_mean=ifelse(wd_mean<180,wd_mean+180,wd_mean-180) 109 | wd=wd_mean*pi/180 110 | angle=atan2(ymat,xmat) 111 | dist=sqrt(xmat^2+ymat^2) 112 | xmat_rot=dist*sin(wd-angle) 113 | ymat_rot=dist*cos(wd-angle) 114 | #rotate contours 115 | for (i in 1:length(contours)) { 116 | angle=atan2(ffp_cont$ycont[[i]],ffp_cont$xcont[[i]]) 117 | dist=sqrt(ffp_cont$xcont[[i]]^2+ffp_cont$ycont[[i]]^2) 118 | xcont_rot[[i]]=dist*sin(wd-angle) 119 | ycont_rot[[i]]=dist*cos(wd-angle) 120 | } 121 | } 122 | #output 123 | ffp=list() 124 | ffp$xmax=xmax 125 | ffp$x=x 126 | ffp$fy_mean=fy_mean 127 | ffp$f2d=t(fmat) 128 | if (!is.na(wd_mean)) { #rotated 129 | ffp$x2d=xmat_rot 130 | ffp$y2d=ymat_rot 131 | ffp$xcontour=xcont_rot 132 | ffp$ycontour=ycont_rot 133 | } else { #unrotated 134 | ffp$x2d=xmat 135 | ffp$y2d=ymat 136 | ffp$xcontour=ffp_cont$xcont 137 | ffp$ycontour=ffp_cont$ycont 138 | } 139 | ffp$contour_levels=contours 140 | tryCatch({ 141 | if (plot==TRUE) plot_flux_footprint(ffp) 142 | }, warning = function(w) { 143 | message("An error occurred when plotting the flux footprint.") 144 | }) 145 | return(ffp) 146 | } 147 | 148 | 149 | #' Plot Flux-Footprint 150 | #' 151 | #'@description Plots Flux-Footprint Parametrization (FFP) according to Kljun et al., 2015 152 | #'@param ffp an object returned from \code{calc_flux_footprint} 153 | #'@param levels levels used for filled contour plot of footprint, default \code{levels=c(0,10^seq(-6,-3,0.1))} 154 | #' 155 | #'@return no return 156 | #'@importFrom grDevices colorRampPalette contourLines rgb 157 | #'@importFrom graphics .filled.contour abline arrows axis 158 | #'@importFrom stats approx ccf cor cov lm median quantile sd 159 | #'@importFrom fields image.plot 160 | #'@export 161 | #' 162 | #'@examples 163 | #'ffp=calc_flux_footprint(zm=5,ws_mean=5,blh=700,L=-1.3,v_sd=1.2,ustar=0.35) 164 | #'plot_flux_footprint(ffp) 165 | #' 166 | plot_flux_footprint = function(ffp,levels=c(0,10^seq(-6,-3,0.1))) { 167 | if (!exists("xlim")) xlim=c(-500,500) 168 | if (!exists("ylim")) ylim=c(-500,500) 169 | #plot crosswind-integrated footprint 170 | plot(ffp$x,ffp$fy_mean,type="l",xlim=xlim,lwd=2,xlab="x [m]",ylab="crosswind-integrated footprint",main="Crosswind-Integrated Flux Footprint") 171 | abline(v=ffp$xmax,col=2,lwd=2,lty=2) 172 | legend("topright",legend="footprint peak location",col=2,lwd=2,lty=2) 173 | #filled contour plot with contour lines 174 | lab=colorRampPalette(c("white","blue3","yellow","orange","red3"), space = "Lab") 175 | nlev=length(levels) 176 | #plot(NA,xlim=xlim,ylim=ylim,main="2D Flux Footprint",xlab="x [m]",ylab="y [m]") 177 | #.filled.contour(ffp$x2d[1,],ffp$y2d[,1],ffp$f2d,levels=levels,col=lab(nlev)) 178 | fields::image.plot(ffp$x2d,ffp$y2d,ffp$f2d*100,xlim=xlim,ylim=ylim,xlab="x [m]",ylab="y [m]",main="Flux Footprint") 179 | for (i in 1:length(ffp$xcontour)) { 180 | lines(ffp$xcontour[[i]],ffp$ycontour[[i]],type="l",lwd=1) 181 | } 182 | #3d perspective plot 183 | #nmid=as.integer(length(ffp$x2d[,1])/2) 184 | #xselect=(nmid-200):(nmid+200) 185 | #persp(ffp$x2d[1,xselect],ffp$y2d[xselect,1],ffp$f2d[xselect,xselect],main="2d flux footprint as 3d plot",xlab=xlab,ylab=ylab,zlab="footprint",theta = 30, phi = 30, expand = 0.5, col = "lightblue",ltheta = 120, shade = 0.2,nticks=5) 186 | } 187 | 188 | -------------------------------------------------------------------------------- /R/spectrum.R: -------------------------------------------------------------------------------- 1 | #' Spectrum of timeseries by wrapping rbase::spectrum() 2 | #' 3 | #'@description Calculates and plots the averaged turbulence spectrum (as wrapper of rbase::spectrum) 4 | #'@param ts timeseries 5 | #'@param nbins number of bins used to average the spectrum, default \code{nbins=100} 6 | #'@param plot should the spectrum be plotted? default \code{plot=TRUE} 7 | #' 8 | #'@return binned spectrum 9 | #'@export 10 | #' 11 | #'@examples 12 | #'set.seed(5) 13 | #'ts=rnorm(1000) 14 | #'calc_spectrum(ts,nbins=100,plot=FALSE) 15 | #' 16 | calc_spectrum = function(ts,nbins=100,plot=TRUE) { 17 | s=spectrum(ts,plot=FALSE) 18 | bins=seq(log(min(s$freq,na.rm=TRUE)),log(max(s$freq,na.rm=TRUE)),length.out=nbins) 19 | sbin=binning(s$spec,s$freq,10^bins) 20 | if (plot==TRUE) { 21 | plot(bins[2:nbins],log(sbin[,2]),pch=20,main="Spectrum",xlab="frequency",ylab="spectrum",xlim=range(bins[2:nbins][!is.na(sbin[,2])],na.rm=TRUE),xaxt="n",yaxt="n") 22 | axis(1,at=(-10):0,10^(-10:0)) 23 | axis(2,at=(-10):10,10^(-10:10)) 24 | fit=lm(log(sbin[,2]) ~ bins[2:nbins]) 25 | print(summary(fit)) 26 | #par(new=TRUE) 27 | #plot(bins,bins*(-5/3),type="l",col=4,lwd=2,lty=2,xlab="",ylab="",xaxt="n",yaxt="n",ylim=range(log(sbin[,2]),na.rm=TRUE)) 28 | #legend("bottomleft",legend="-5/3 slope",col=4,lwd=2,lty=2) 29 | } 30 | return(cbind(bins[2:nbins],sbin[,2])) 31 | } 32 | 33 | 34 | #' Frequency spectrum (1D) 35 | #' 36 | #'@description Calculates and plots turbulence spectrum (in time) calculated using FFT (and optionally bins it) 37 | #'@param ts timeseries of the variable for which the spectrum should be calculated 38 | #'@param tres time resolution [s] of the given timeseries, default \code{tres=0.05} for 20 Hz 39 | #'@param nbins number of bins used to average the spectrum, default \code{nbins=NULL}, i.e. no further binning is applied (means number of bins equals half of length of input timeseries) 40 | #'@param method method used to calculate the spectrum, can be either FFT (fast Fourier transform) or DCT (discrete cosine transform), default FFT 41 | #'@param na.rm should NA values be removed from the timeseries? default \code{na.rm=TRUE} 42 | #'@param plot should the spectrum be plotted? default \code{plot=TRUE} 43 | #'@param ... further arguments passed to plot function 44 | #' 45 | #'@importFrom gsignal dct 46 | #' 47 | #'@return binned frequency spectrum from 1D FFT 48 | #'@export 49 | #' 50 | #'@examples 51 | #'set.seed(5) 52 | #'ts=rnorm(1000) 53 | #'calc_spectrum1D(ts) #no binning 54 | #'calc_spectrum1D(ts,nbins=100) #binning 55 | #' 56 | calc_spectrum1D = function(ts,tres=0.05,nbins=NULL,method="fft",na.rm=TRUE,plot=TRUE,...) { 57 | if (na.rm==TRUE) ts=ts[!is.na(ts)] 58 | nt=length(ts) #length of time series 59 | #sr=1/tres #sampling rate 60 | #t=seq(0,(nt-1)*tres,tres) #time vector 61 | if (method=="fft" | method=="FFT") { #fft and frequencies 62 | spec=fft(ts) 63 | ssb=spec[1:(nt/2)] #single side band 64 | ssb[2:(nt/2)]=2*ssb[2:(nt/2)] 65 | spec=abs(ssb)*2/nt 66 | freq=seq(0,(nt/2)-1)*tres/nt #frequencies 67 | out=data.frame("frequency"=freq,"spectrum"=spec) 68 | } else if (method=="dct" | method=="DCT") { #dct and frequencies 69 | spec=abs(dct(ts)) 70 | freq=seq(0,(nt)-1)*tres/nt #frequencies 71 | out=data.frame("frequency"=freq,"spectrum"=spec) 72 | } 73 | #binning 74 | #if (nbins>nt) warning("You request more bins than there are measurements available.") 75 | if (!is.null(nbins)) { 76 | fbins=exp(seq(log(min(freq[-1])),log(max(freq)),length.out=nbins)) 77 | xbinned=binning(spec,freq,fbins) 78 | fmid=(fbins[2:nbins]+fbins[1:(nbins-1)])/2 79 | out=data.frame("frequency"=fmid,"spectrum"=xbinned[,2]) 80 | } 81 | if (plot==TRUE) { 82 | plot(out$frequency,out$spectrum,pch=20,log="xy",xlab="frequency [1/s]",...) 83 | #points(out$frequency,out$frequency^(-5/3),type="l",lty=2) 84 | #fit=lm(log(out$spectrum) ~ log(out$frequency)) 85 | #print(summary(fit)) 86 | #abline(exp(fit$coefficients[1]),exp(fit$coefficients[2]),col=2,lwd=2) 87 | #points(freq,freq^fit$coefficients[2]+exp(fit$coefficients[1]),col=2,type="l") 88 | } 89 | return(out) 90 | } 91 | 92 | 93 | #' Spatial spectrum (2D) 94 | #' 95 | #'@description Calculates and plots turbulence spectrum (in space) calculated using FFT or DCT (and optionally bins it) 96 | #'@param field two-dimensional input field 97 | #'@param xres spatial resolution in x-direction 98 | #'@param yres spatial resolution in y-direction, default \code{yres=NULL} meaning that the field is equidistant and \code{yres=xres} is used 99 | #'@param method method used to calculate the spectrum, can be either FFT (fast Fourier transform) or DCT (discrete cosine transform), default FFT 100 | #'@param nbins number of bins used to average the spectrum, default \code{nbins=NULL}, i.e. no further binning is applied (means number of bins equals half of length of input timeseries) 101 | #'@param plot should the spectrum be plotted? default \code{plot=TRUE} 102 | #'@param ... further arguments passed to plot function 103 | #' 104 | #'@importFrom gsignal dct2 fftshift 105 | #' 106 | #'@return binned wavenumber spectrum from 2D FFT or DCT 107 | #'@export 108 | #' 109 | #'@examples 110 | #'set.seed(5) 111 | #'field=matrix(rnorm(10000),nrow=100) 112 | #'calc_spectrum2D(field,xres=100) #equidistant grid, no binning, fft 113 | #'calc_spectrum2D(field,xres=100,yres=200) #non-equidistant grid, no binning, fft 114 | #'calc_spectrum2D(field,xres=100,nbins=1000) #equidistant grid, binning, fft 115 | #'calc_spectrum2D(field,xres=100,nbins=1000,method="dct") #equidistant grid, binning, dct 116 | #' 117 | calc_spectrum2D = function(field,xres=1000,yres=NULL,nbins=NULL,method="fft",plot=TRUE,...) { 118 | nx=dim(field)[1] 119 | ny=dim(field)[2] 120 | if (is.null(yres)) yres=xres 121 | #calc 2D spectrum 122 | if (method=="fft" | method=="FFT") { 123 | kx=seq(-nx/2,nx/2-1)/(nx*xres) #fftfreq(nx,xres) 124 | ky=seq(-ny/2,ny/2-1)/(ny*yres) #fftfreq(ny,yres) 125 | k=calc_k2d(kx,ky) 126 | spec=abs(fft(field)) #fft() automatically calculates 2D fft for 2D input array 127 | spec=gsignal::fftshift(spec,MARGIN=c(1,2)) #fftshift 128 | } else if (method=="dct" | method=="DCT") { 129 | kx=seq(0,nx-1)/(nx*xres) 130 | ky=seq(0,ny-1)/(ny*yres) 131 | k=calc_k2d(kx,ky) 132 | spec=abs(gsignal::dct2(field)) 133 | } 134 | #binning 135 | if (is.null(nbins)) nbins=min(nx,ny) 136 | kbins=exp(seq(log(min(k[which(k>0,arr.ind=TRUE)])),log(max(k[which(is.finite(k),arr.ind=TRUE)])),length.out=nbins)) 137 | xbinned=binning(c(spec),c(k),kbins) 138 | kmid=(kbins[2:nbins]+kbins[1:(nbins-1)])/2 139 | out=data.frame("wavenumber"=kmid,"spectrum"=xbinned[,2]) 140 | if (plot==TRUE) { 141 | plot(out$wavenumber,out$spectrum,pch=16,log="xy",xlab="wavenumber [1/m]",ylab="spectrum",...) 142 | } 143 | return(out) 144 | } 145 | 146 | 147 | #' FFT frequency 148 | #' 149 | #'@description Returns FFT sampling frequencies (R version of the function fft.fftfreq in numpy) 150 | #'@param n length 151 | #'@param res spatial resolution (default: \code{res=1}) 152 | #' 153 | #'@return vector of length n containing FFT frequencies 154 | #'@export 155 | #' 156 | #'@examples 157 | #'fftfreq(10) 158 | #' 159 | fftfreq=function(n,res=1) { 160 | if (n%%2==0) { 161 | freq=c(seq(0,(n/2-1)),seq((-n/2),-1))/(res*n) 162 | } else { 163 | freq=c(seq(0,((n-1)/2)),seq(-(n-1)/2,-1))/(res*n) 164 | } 165 | return(freq) 166 | } 167 | 168 | #' Calculates 2d (horizontal) wavenumber matrix from kx, ky 169 | #' 170 | #'@description Calculates 2d (horizontal) wavenumber matrix from kx, ky 171 | #'@param kx wavenumber in x-direction 172 | #'@param ky wavenumber in y-direction 173 | #' 174 | #'@return total spatial (horizontal) wavenumber k 175 | #'@export 176 | #' 177 | #'@examples 178 | #'kx=c(1:10)/10 179 | #'ky=c(1:8)/8 180 | #'k=calc_k2d(kx,ky) 181 | #' 182 | calc_k2d=function(kx,ky) { 183 | nx=length(kx) 184 | ny=length(ky) 185 | mat=array(NA,dim=c(nx,ny)) 186 | for (i in 1:nx) { 187 | for (j in 1:ny) { 188 | mat[i,j]=(kx[i])^2+(ky[j])^2 189 | } 190 | } 191 | return(sqrt(mat)) 192 | } 193 | 194 | 195 | #' Helmholtz-Hodge decomposition 196 | #' 197 | #'@description Calculates Helmholtz-Hodge decomposition of horizontal wind using a spectral FFT-based method: decomposition of horizontal wind in rotational and divergent part: (u,v) = (u_rot,v_rot) + (u_div,v_div) 198 | #'@details The implementation is based on the Python version from https://github.com/shixun22/helmholtz. 199 | #'@param u zonal wind field with dimension (x,y) 200 | #'@param v meridional wind field with dimension (x,y) 201 | #'@param res spatial resolution (assuming equidistant grid) 202 | #' 203 | #'@return list containing u_div, v_div, u_rot, v_rot 204 | #'@export 205 | #' 206 | #'@examples 207 | #'set.seed(5) 208 | #'u=matrix(rnorm(100),ncol=10) 209 | #'v=matrix(rnorm(100),ncol=10) 210 | #'hd=calc_helmholtz_decomposition(u,v,100) 211 | #' 212 | calc_helmholtz_decomposition = function(u,v,res=1) { 213 | nx=dim(u)[1] 214 | ny=dim(u)[2] 215 | #fft 216 | ufft=fft(u) 217 | vfft=fft(v) 218 | #wave numbers 219 | kx=fftfreq(nx,res) 220 | ky=fftfreq(ny,res) 221 | k2=calc_k2d(kx,ky)^2 222 | k2[1,1]=1 223 | kx2=matrix(rep(kx,ny),nrow=nx,ncol=ny,byrow=F) 224 | ky2=matrix(rep(ky,nx),nrow=nx,ncol=ny,byrow=T) 225 | #decomposition 226 | div=ufft*kx2 + vfft*ky2 227 | u_div=gsignal::ifft(div/k2*kx2) 228 | v_div=gsignal::ifft(div/k2*ky2) 229 | u_rot=u-u_div 230 | v_rot=v-v_div 231 | return(list("u_div"=u_div,"v_div"=v_div,"u_rot"=u_rot,"v_rot"=v_rot)) 232 | } -------------------------------------------------------------------------------- /R/diagnostics-turbulence.R: -------------------------------------------------------------------------------- 1 | ### turbulence quantities ### 2 | 3 | #' Turbulent Kinetic Energy TKE 4 | #' 5 | #'@description Calculates turbulent kinetic energy (TKE) from \code{u_sd}, \code{v_sd} and \code{w_sd} 6 | #'@param u_sd standard deviation of u-wind [m/s] 7 | #'@param v_sd standard deviation of v-wind [m/s] 8 | #'@param w_sd standard deviation of w-wind [m/s] 9 | #' 10 | #'@return turbulent kinetic energy TKE [m^2/s^2] 11 | #'@export 12 | #' 13 | #'@examples 14 | #'calc_tke(1,1,1) 15 | #' 16 | calc_tke = function(u_sd,v_sd,w_sd) { 17 | return(1/2*(u_sd^2+v_sd^2+w_sd^2)) 18 | } 19 | 20 | 21 | #' Turbulent Kinetic Energy Velocity Scale 22 | #' 23 | #'@description Calculates the velocity scale of turbulent kinetic energy (TKE): \code{Vtke = sqrt(TKE)} 24 | #'@param u_sd standard deviation of u-wind [m/s] 25 | #'@param v_sd standard deviation of v-wind [m/s] 26 | #'@param w_sd standard deviation of w-wind [m/s] 27 | #' 28 | #'@return turbulent kinetic energy velocity scale [m/s] 29 | #'@export 30 | #' 31 | #'@examples 32 | #'calc_vtke(1,1,1) 33 | #' 34 | calc_vtke = function(u_sd,v_sd,w_sd) { 35 | tke=calc_tke(u_sd,v_sd,w_sd) 36 | return(sqrt(tke)) 37 | } 38 | 39 | 40 | #' Friction Velocity 41 | #' 42 | #'@description Calculates friction velocity from the covariances cov(u,w) and cov(v,w) 43 | #'@param cov_uw covariance cov(u,w) [m^2/s^2] 44 | #'@param cov_vw covariance cov(v,w) [m^2/s^2] 45 | #' 46 | #'@return friction velocity [m/s] 47 | #'@export 48 | #' 49 | #'@examples 50 | #'calc_ustar(1,1) 51 | #' 52 | calc_ustar = function(cov_uw,cov_vw) { 53 | return((cov_uw^2+cov_vw^2)^(1/4)) 54 | } 55 | 56 | #' Obukhov length 57 | #' 58 | #'@description Calculates Obukhov length from friction velocity, mean temperature and cov(T,w) 59 | #'@param ustar friction velocity (e.g., from \code{calc_ustar}) [m/s] 60 | #'@param T_mean mean temperature [K] 61 | #'@param cov_wT covariance cov(w,T) [m/s K] 62 | #' 63 | #'@return Obukhov length [m] 64 | #'@export 65 | #' 66 | #'@examples 67 | #'calc_L(0.2,273,0.1) #unstable 68 | #'calc_L(0.2,273,-0.1) #stable 69 | #' 70 | calc_L = function(ustar,T_mean,cov_wT) { 71 | return(-abs(ustar^3)*T_mean/(karman()*g()*cov_wT)) 72 | } 73 | 74 | 75 | #' Stability Parameter 76 | #' 77 | #'@description Calculates dimensionless stability parameter from Obukhov length and measurement height, i.e. \code{zeta = z/L} 78 | #'@param z measurement height [m] 79 | #'@param L Obukhov length [m] (e.g., from \code{calc_L}) 80 | #' 81 | #'@return stability parameter [-] 82 | #'@export 83 | #' 84 | #'@examples 85 | #'calc_zeta(2,-1) #unstable 86 | #'calc_zeta(2,1) #stable 87 | #' 88 | calc_zeta = function(z,L) { 89 | return(z/L) 90 | } 91 | 92 | 93 | #' Horizontal Turbulence Intensity TI 94 | #' 95 | #'@description Calculates horizontal turbulence intensity \code{TI = sqrt(u_sd^2+v_sd^2)/ws_mean} 96 | #'@param u_sd standard deviation of streamwise wind (u-wind) 97 | #'@param v_sd standard deviation of crosswise wind (v-wind) 98 | #'@param ws_mean horizontal wind speed 99 | #' 100 | #'@return horizontal turbulence intensity [-] 101 | #'@export 102 | #' 103 | #'@examples 104 | #'calc_ti(1,1,3) 105 | #' 106 | calc_ti = function(u_sd,v_sd,ws_mean) { 107 | return(sqrt(u_sd^2+v_sd^2)/ws_mean) 108 | } 109 | 110 | #' Vertical Turbulence Intensity Iw 111 | #' 112 | #'@description Calculates vertical turbulence intensity \code{Iw = w_sd/ws_mean} 113 | #'@param w_sd standard deviation of vertical wind (w-wind) 114 | #'@param ws_mean horizontal wind speed 115 | #' 116 | #'@return vertical turbulence intensity [-] 117 | #'@export 118 | #' 119 | #'@examples 120 | #'calc_iw(1,3) #unstable 121 | #' 122 | calc_iw = function(w_sd,ws_mean) { 123 | return(w_sd/ws_mean) 124 | } 125 | 126 | #' Velocity Aspect Ratio (VAR) 127 | #' 128 | #'@description Calculates the velocity aspect ratio: \code{VAR = sqrt(2)*w_sd/sqrt(u_sd^2+v_sd^2)} 129 | #'@param u_sd standard deviation of streamwise wind (u-wind) 130 | #'@param v_sd standard deviation of crosswise wind (v-wind) 131 | #'@param w_sd standard deviation of vertical wind (w-wind) 132 | #' 133 | #'@return velocity aspect ratio [-] 134 | #'@export 135 | #' 136 | #'@examples 137 | #'calc_var(1,1,1) #"isotropic" 138 | #'calc_var(1,1,2) #not isotropic 139 | #' 140 | calc_var = function(u_sd,v_sd,w_sd) { 141 | return(sqrt(2)*w_sd/sqrt(u_sd^2+v_sd^2)) 142 | } 143 | 144 | #' Directional Shear 145 | #' 146 | #'@description Calculates a measure for directional shear alpha_uw = arctan(cov(v,w)/cov(u,w)) 147 | #'@param cov_uw covariance cov(u,w) 148 | #'@param cov_vw covariance cov(v,w) 149 | #' 150 | #'@return angle that describes the impact of directional shear [deg] 151 | #'@export 152 | #' 153 | #'@examples 154 | #'calc_dshear(-0.5,0) #no shear 155 | #'calc_dshear(-0.5,-0.1) 156 | #' 157 | calc_dshear = function(cov_uw,cov_vw) { 158 | return((atan2(cov_vw,cov_uw)*180/pi+360)%%360) 159 | } 160 | 161 | #' Decoupling metric (Omega) 162 | #' 163 | #'@description Calculates the decoupling metric (Omega) from Peltola et al., 2021 (without vegetation) 164 | #'@param w_sd standard deviation of vertical velocity [m/s] 165 | #'@param N Brunt-Vaisala frequency [1/s] 166 | #'@param z measurement height [m] 167 | #' 168 | #'@return decoupling metric (Omega) [-] 169 | #'@export 170 | #' 171 | #'@examples 172 | #'calc_decoupling_metric(1,1) 173 | #' 174 | calc_decoupling_metric = function(w_sd,N,z=2) { 175 | LB=w_sd/N #buoyancy length scale 176 | return(LB/(sqrt(2)*z)) #Peltola et al, 2021: eq 6 177 | } 178 | 179 | #' Ozmidov scale (L_OZ) 180 | #' 181 | #'@description Calculates the Ozmidov length scale L_OZ = sqrt(epsilon/N^3), with epsilon: TKE dissipation rate, and N: Brunt-Vaisala frequency 182 | #'@param epsilon dissipation rate of TKE or w [m*s] 183 | #'@param N Brunt-Vaisala frequency [1/s] 184 | #' 185 | #'@return Ozmidov length scale [m] 186 | #'@export 187 | #' 188 | #'@examples 189 | #'calc_ozmidov_scale(-5/3,1*10^-4) 190 | #' 191 | calc_ozmidov_scale = function(epsilon,N) { 192 | return(sqrt(epsilon/N^3)) 193 | } 194 | 195 | ### intermittency indicator ### 196 | 197 | #' Flux intermittency 198 | #' 199 | #'@description Calculates flux intermittency FI = flux_sd/flux (flux_sd: sd of subsampled fluxes) following Mahrt, 1998 (similar to stationarity flag \code{flag_stationarity}) 200 | #'@param ts1 timeseries 1 201 | #'@param ts2 timeseries 2 (optional), if the flux should be calculated based on \code{ts1*ts2} (default \code{ts2=NULL}, i.e. \code{ts2} is not used) 202 | #'@param nsub number of elements used for subsampling, default \code{nsub=6000}, which corrosponds to 5 minutes of measurements from 20 Hz sampled half-hour (containing 30*60*20 = 36000 measurements) 203 | #' 204 | #'@return flux intermittency [-] 205 | #'@export 206 | #' 207 | #'@examples 208 | #'set.seed(5) 209 | #'ts1=rnorm(30) 210 | #'ts2=rnorm(30) 211 | #'calc_flux_intermittency(ts1,ts2,nsub=6) #as product 212 | #'calc_flux_intermittency(ts1*ts2,nsub=6) #the same from one variable 213 | #' 214 | calc_flux_intermittency = function(ts1,ts2=NULL,nsub=6000) { 215 | n=length(ts1) 216 | nint=n%/%nsub 217 | if (nint<=1) { 218 | warning("nsub is chosen to large.") 219 | } 220 | cov_subs=array(NA,dim=nint) 221 | if (!is.null(ts2)) { 222 | cov_complete=cov(ts1,ts2,use="pairwise.complete.obs") 223 | } else { 224 | cov_complete=mean(ts1,na.rm=TRUE) 225 | } 226 | for (i in 1:nint) { 227 | isub=((i-1)*nsub+1):(i*nsub) 228 | if (!is.null(ts2)) cov_sub=cov(ts1[isub],ts1[isub],use="pairwise.complete.obs") 229 | if (is.null(ts2)) cov_sub=mean(ts1[isub],na.rm=TRUE) 230 | cov_subs[i]=cov_sub 231 | } 232 | return(sd(cov_subs)/cov_complete) 233 | } 234 | 235 | 236 | ### hydrological measures ### 237 | #' Bowen ratio BR 238 | #' 239 | #'@description Calculates the Bowen ratio as ratio of sensible and latent heat flux, i.e., BR := SH/LH 240 | #'@param sh sensible heat flux [W/m^2] 241 | #'@param lh latent heat flux [W/m^2] 242 | #' 243 | #'@return Bowen ratio [-] 244 | #'@export 245 | #' 246 | #'@examples 247 | #'calc_br(50,20) 248 | #' 249 | calc_br = function(sh,lh) { 250 | return(sh/abs(lh)) 251 | } 252 | 253 | #' Evaporative fraction 254 | #' 255 | #'@description Calculates the evaporative fraction EF := LH/(SH+LH) 256 | #'@param sh sensible heat flux [W/m^2] 257 | #'@param lh latent heat flux [W/m^2] 258 | #' 259 | #'@return evaporative fraction [-] 260 | #'@export 261 | #' 262 | #'@examples 263 | #'calc_ef(50,20) 264 | #' 265 | calc_ef = function(sh,lh) { 266 | return(lh/(sh+lh)) 267 | } 268 | 269 | #' Evapotranspiration 270 | #' 271 | #'@description Converts latent heat flux to evaporation 272 | #'@param lh latent heat flux [W/m^2] 273 | #'@param temp temperature [K] (optional), if provided, the latent heat of vaporization is calculated temperature-dependent 274 | #' 275 | #'@return evapotranspiration [kg/(s*m^2)] 276 | #'@export 277 | #' 278 | #'@examples 279 | #'lh2et(20) 280 | #'lh2et(20,273) 281 | #' 282 | lh2et = function(lh,temp=NULL) { 283 | lv=Lv(temp) 284 | return(lh/lv) 285 | } 286 | 287 | 288 | ### surface roughness and related concepts ### 289 | 290 | #' Calculates surface roughness length z0 from friction velocity using the simple estimate from Charnock, 1955 291 | #' 292 | #'@description Calculates surface roughness z0 from friction velocity using the simple estimate from Charnock, 1955: z0 = alpha*ustar^2/g with alpha=0.016 and g=9.81 m/s^2 293 | #'@param ustar friction velocity [m/s] 294 | #' 295 | #'@return surface roughness length [m] 296 | #'@export 297 | #' 298 | #'@examples 299 | #'ustar2z0(0.2) 300 | #' 301 | ustar2z0 = function(ustar) { 302 | return(alpha()*ustar^2/g()) 303 | } 304 | 305 | 306 | 307 | ### Ekman layer 308 | 309 | #' Coriolis parameter 310 | #' 311 | #'@description Calculates Coriolis parameter from latitude 312 | #'@param phi latitude [deg] 313 | #' 314 | #'@return Coriolis parameter [1/s] 315 | #'@export 316 | #' 317 | #'@examples 318 | #'calc_coriolis(45) 319 | #' 320 | calc_coriolis = function(phi) { 321 | return(2*pi*sin(phi*pi/180)) 322 | } 323 | 324 | #' Ekman layer thickness 325 | #' 326 | #'@description Calculates Ekman layer thickness from eddy diffusivity and Coriolis parameter sqrt(2*Km/abs(f)) 327 | #'@param Km eddy diffusivity [m^2/s] 328 | #'@param f Coriolis parameter [1/s] (e.g. from \code{calc_coriolis}) 329 | #' 330 | #'@return Ekman layer thickness [m] (derived from boundary layer equations) 331 | #'@export 332 | #' 333 | #'@examples 334 | #'calc_ekman_layer_depth(0.1,10^(-4)) 335 | #' 336 | calc_ekman_layer_depth = function(Km,f) { 337 | return(sqrt(2*Km/abs(f))) 338 | } -------------------------------------------------------------------------------- /R/bulk-closures.R: -------------------------------------------------------------------------------- 1 | ### scaling functions used for flux-variance relations ### 2 | 3 | #' Scaling function for horizontal windspeed Phi_u 4 | #' 5 | #'@description scaling function Phi_u 6 | #'@param zeta stability parameter [-] 7 | #'@param method defining from which paper the scaling function is used, default \code{method="PD1984"} for Panofsky and Dutton, 1984 8 | #' 9 | #'@return Phi_u 10 | #'@export 11 | #' 12 | scale_phiu = function(zeta,method="PD1984") { 13 | if (method=="PD1984") { 14 | if (zeta<=0) { #unstable 15 | return(2.55*(1-3*zeta)^(1/3)) 16 | } else { #stable 17 | return(2.55*(1+3*zeta)^(1/3)) 18 | } 19 | } 20 | } 21 | 22 | #' Scaling function for vertical windspeed Phi_w 23 | #' 24 | #'@description scaling function Phi_w 25 | #'@param zeta stability parameter [-] 26 | #'@param method defining from which paper the scaling function is used, default \code{method="PD1984"} for Panofsky and Dutton, 1984 27 | #' 28 | #'@return Phi_w 29 | #'@export 30 | #' 31 | scale_phiw = function(zeta,method="PD1984") { 32 | if (method=="PD1984") { 33 | if (zeta<=0) { #unstable 34 | return(1.25*(1-3*zeta)^(1/3)) 35 | } else { #stable 36 | return(1.25*(1+3*zeta)^(1/3)) 37 | } 38 | } 39 | } 40 | 41 | #' Scaling function for temperature Phi_T 42 | #' 43 | #'@description scaling function Phi_T 44 | #'@param zeta stability parameter [-] 45 | #'@param method defining from which paper the scaling function should be used, default \code{method="K1994"} for Katul, 1994, other option \code{method="SC2018"} for Stiperski and Calaf, 2018 46 | #' 47 | #'@return Phi_T 48 | #'@export 49 | #' 50 | scale_phiT = function(zeta,method="K1994") { 51 | if (method=="K1994") { 52 | if (zeta<=0) { #unstable 53 | return(0.95*(-zeta)^(-1/3)) 54 | } else { #stable 55 | return(0.95*(zeta)^(-1/3)) 56 | } 57 | } else if (method=="SC2018") { 58 | if (zeta<=0) { #unstable 59 | return(0.99*(0.067-zeta)^(-1/3)) 60 | } else { #stable 61 | return(1.76+0.15*(zeta)^(-1)) 62 | } 63 | } 64 | } 65 | 66 | 67 | 68 | ### Scaling functions for flux-profile relations ### 69 | 70 | #' Scaling function for momentum Phi_m 71 | #' 72 | #'@description scaling function Phi_m 73 | #'@param zeta stability parameter [-] 74 | #'@param method defining from which paper the scaling function should be used, default \code{method="ecmwf"} for the ones used in ECMWF-IFS, other option \code{method="BD"} for the linear Businger-Dyer relations 75 | #' 76 | #'@return Phi_m 77 | #'@export 78 | #' 79 | scale_phim = function(zeta,method="ecmwf") { 80 | if (method=="ecmwf") { 81 | if (zeta<=0) { #unstable 82 | return((1-16*zeta)^(-1/4)) 83 | } else { #stable 84 | return(1+5*zeta) 85 | } 86 | } 87 | if (method=="BD") { 88 | if (zeta<=0) { #unstable 89 | return(2-zeta) 90 | } else { #stable 91 | return(1+5*zeta) 92 | } 93 | } 94 | } 95 | 96 | #' Scaling function for heat Phi_h 97 | #' 98 | #'@description scaling function Phi_h 99 | #'@param zeta stability parameter [-] 100 | #'@param method defining from which paper the scaling function should be used, default \code{method="ecmwf"} for for the ones used in ECMWF-IFS 101 | #' 102 | #'@return Phi_h 103 | #'@export 104 | #' 105 | scale_phih = function(zeta,method="BD") { 106 | if (method=="ecmwf") { 107 | if (zeta<=0) { #unstable 108 | return((1-16*zeta)^(-1/2)) 109 | } else { #stable 110 | return((1+4*zeta)^2) 111 | } 112 | } 113 | } 114 | 115 | 116 | 117 | ### calculate scaling parameters for flux-profile relations ### 118 | 119 | #' Calculates Phi_m 120 | #' 121 | #'@description calculates scaling function Phi_m (for momentum) 122 | #'@param U1 wind speed at the lower level [m/s] 123 | #'@param U2 wind speed at the upper level [m/s] 124 | #'@param ustar friction velocity [m/s] 125 | #'@param zm measurement/scaling height [m] 126 | #'@param dz height difference of the two measurements [m] 127 | #' 128 | #'@return Phi_m 129 | #'@export 130 | #' 131 | calc_phim = function(U1,U2,ustar,zm,dz) { 132 | dUbar_dz=(U2-U1)/dz 133 | phi=karman()*zm*abs(dUbar_dz)/ustar 134 | return(phi) 135 | } 136 | 137 | #' Calculates Phi_t 138 | #' 139 | #'@description calculate scaling function Phi_t (for heat) 140 | #'@param T1 temperature at the lower level [K] 141 | #'@param T2 temperature at the upper level [K] 142 | #'@param cov_wT covariance cov(w,T) [K m/s] 143 | #'@param ustar friction velocity [m/s] 144 | #'@param zm measurement/scaling height [m] 145 | #'@param dz height difference of the two measurements [m] 146 | #' 147 | #'@return Phi_t 148 | #'@export 149 | #' 150 | calc_phit = function(T1,T2,cov_wT,ustar,zm,dz) { 151 | tstar=calc_xstar(cov_wT,ustar) 152 | dTbar_dz=(T2-T1)/dz 153 | phi=karman()*zm*abs(dTbar_dz)/tstar 154 | return(phi) 155 | } 156 | 157 | #' Brunt-Vaisala frequency squared 158 | #' 159 | #'@description calculates Brunt-Vaisala frequency squared (N^2) 160 | #'@param T1 temperature at the lower level [K] 161 | #'@param T2 temperature at the upper level [K] 162 | #'@param dz height difference of the two measurements [m] 163 | #' 164 | #'@return N2 [1/s^2] 165 | #'@export 166 | #' 167 | calc_N2 = function(T1,T2,dz) { 168 | T0=(T1+T2)/2 169 | dT_dz=(T2-T1)/dz 170 | return(T0/g()*dT_dz) 171 | } 172 | 173 | #' Calculates bulk Richardson number Ri 174 | #' 175 | #'@description calculates Richardson number Ri 176 | #'@param U1 wind speed at the lower level [m/s] 177 | #'@param U2 wind speed at the upper level [m/s] 178 | #'@param T1 temperature at the lower level [K] 179 | #'@param T2 temperature at the upper level [K] 180 | #'@param dz height difference of the two measurements [m] 181 | #' 182 | #'@return Ri [-] 183 | #'@export 184 | #' 185 | calc_ri = function(T1,T2,U1,U2,dz) { 186 | T0=(T1+T2)/2 187 | dT_dz=(T2-T1)/dz 188 | dUbar_dz=(U2-U1)/dz 189 | ri=g()/T0*dT_dz/(dUbar_dz^2) 190 | return(ri) 191 | } 192 | 193 | #' Calculates flux Richardson number Ri_f 194 | #' 195 | #'@description calculates flux Richardson number Ri_f = g/T_mean*cov(w,T)/(cov(u,w)*du/dz) 196 | #'@param cov_wT covariance cov(w,T) [K m/s] 197 | #'@param cov_uw covariance cov(u,w) [m^2/s^2] 198 | #'@param U1 wind speed at the lower level [m/s] 199 | #'@param U2 wind speed at the upper level [m/s] 200 | #'@param dz height difference of the two measurements [m] 201 | #'@param T_mean mean temperature [K] (optional, used instead of T0=273.15) 202 | #' 203 | #'@return Ri_f [-] 204 | #'@export 205 | #' 206 | calc_rif = function(cov_wT,cov_uw,U1,U2,dz,T_mean=NULL) { 207 | T0=ifelse(is.null(T_mean),273.15,T_mean) 208 | dUbar_dz=(U2-U1)/dz 209 | rif=g()/T0*cov_wT/(cov_uw*dUbar_dz) 210 | return(rif) 211 | } 212 | 213 | #' Calculates xstar (denominator for general flux-variance relation) 214 | #' 215 | #'@description calculates xstar = x/ustar (for general flux-variance relation) 216 | #'@param x variable that should be scaled 217 | #'@param ustar friction velocity [m/s] 218 | #' 219 | #'@return xstar = x/ustar 220 | #'@export 221 | #' 222 | calc_xstar = function(x,ustar) { 223 | return(x/ustar) 224 | } 225 | 226 | 227 | #' Calculates Phi_x (general flux-variance relation) 228 | #' 229 | #'@description calculates Phi_x = sigma_x/xstar (for general flux-variance relation) 230 | #'@param sigma_x standard deviation of x 231 | #'@param x variable that should be scaled, e.g. vertical flux of x with x = T or x = q 232 | #'@param ustar friction velocity [m/s] 233 | #' 234 | #'@return Phi_x = sigma_x/xstar 235 | #'@export 236 | #' 237 | calc_phix = function(sigma_x,x,ustar) { 238 | xstar=calc_xstar(x,ustar) 239 | return(sigma_x/xstar) 240 | } 241 | 242 | 243 | #' Wind profile from Monin-Obukhov similarity theory 244 | #' 245 | #'@description Calculates vertical profile of horizontal wind speed following Monin-Obukhov similarity theory 246 | #'@param zs scalar or vector, heights [m] at which the horizontal wind speed should be calculate 247 | #'@param ustar friction velocity [m/s] 248 | #'@param z0 surface roughness length [m], default \code{z0=0} (note: it could be an option to calculate z0 from ustar with \code{ustar2z0()}) 249 | #'@param d displacement height [m], optional, default \code{d=0} (i.e. no displacement) 250 | #'@param zeta stability parameter [-] to correct for stability effects, default \code{zeta=0} (i.e. no stability correction, resulting in classical logarithmic wind profile) 251 | #'@param method "method" for calculating stability correction function (only relevant if zeta is non-zero), default \code{method="ecmwf"} for using Phi_m from ECMWF-IFS 252 | #' 253 | #'@return data frame containing the requested heights \code{zs} and the calculated wind speed [m/s] there 254 | #'@export 255 | #' 256 | #'@examples 257 | #'zs=seq(1,100) 258 | #'ustar=0.2 259 | #'u_neutral=calc_windprofile(zs,ustar) 260 | #'u_unstable=calc_windprofile(zs,ustar,zeta=-0.2) 261 | #'u_stable=calc_windprofile(zs,ustar,zeta=0.2) 262 | #' 263 | calc_windprofile = function(zs,ustar,z0=0,d=0,zeta=0,method="ecmwf") { 264 | Phi=scale_phim(zeta,method) 265 | if (z0==0) { 266 | uz=ustar/karman()*(log(zs-d)+Phi) 267 | } else { 268 | uz=ustar/karman()*log((zs-d)/z0+Phi) 269 | } 270 | return(data.frame("height"=zs,"windspeed"=uz)) 271 | } 272 | 273 | 274 | 275 | ### eddy viscosity and conductivity, Prandtl number 276 | 277 | #' Calculates eddy viscosity K_m = -cov(u,w)/(du/dz) 278 | #' 279 | #'@description Calculates eddy viscosity K_m 280 | #'@param cov_uw covariance cov(u,w) [m^2/s^2] 281 | #'@param du_dz vertical wind speed gradient [1/s] 282 | #' 283 | #'@return eddy viscosity K_m [m^2/s] 284 | #'@export 285 | #' 286 | #'@examples 287 | #'calc_Km(-0.2,2) 288 | #' 289 | calc_Km = function(cov_uw,du_dz) { 290 | return(-cov_uw/du_dz) 291 | } 292 | 293 | #' Calculates eddy conductivity K_h = -cov(w,T)/(dT/dz) 294 | #' 295 | #'@description Calculates eddy conductivity K_h 296 | #'@param cov_wT covariance cov(w,T) [K m/s] 297 | #'@param dT_dz vertical temperature gradient [K/m] 298 | #' 299 | #'@return eddy conductivity K_h [m^2/s] 300 | #'@export 301 | #' 302 | #'@examples 303 | #'calc_Kh(0.2,-1) 304 | #' 305 | calc_Kh = function(cov_wT,dT_dz) { 306 | return(-cov_wT/dT_dz) 307 | } 308 | 309 | #' Calculates turbulent Prandtl number Pr = K_m/K_h 310 | #' 311 | #'@description Calculates turbulent Prandtl number Pr 312 | #'@param K_m eddy viscosity [m^2/s] 313 | #'@param K_h eddy conductivity [m^2/s] 314 | #' 315 | #'@return Prandtl number [-] 316 | #'@export 317 | #' 318 | #'@examples 319 | #'calc_Pr(0.4,0.6) 320 | #' 321 | calc_Pr = function(K_m,K_h) { 322 | return(K_m/K_h) 323 | } -------------------------------------------------------------------------------- /R/ec-processing.R: -------------------------------------------------------------------------------- 1 | #' Despiking 2 | #' 3 | #'@description Applies (up to) three despiking methods based on (1) pre-defined thresholds, (2) median deviation (MAD) test and (3) skewness and kurtosis 4 | #'@param ts timeseries that shall be despiked 5 | #'@param thresholds vector with two elements representing lower and upper bounds for despiking (pre-defined thresholds), \code{NA} means that the respective bound is not used 6 | #'@param mad_factor factor for the MAD test, default \code{mad_factor = 10} 7 | #'@param threshold_skewness threshold for skewness test, default \code{threshold_skewness = 2} 8 | #'@param threshold_kurtosis threshold for kurtosis test, default \code{threshold_kurtosis = 8} 9 | #' 10 | #'@return despiked timeseries 11 | #'@export 12 | #' 13 | #'@importFrom pracma detrend 14 | #' 15 | #'@examples 16 | #'set.seed(5) 17 | #'ts1=rnorm(100) 18 | #'despiking(ts1,thresholds=c(-1,1)) 19 | #' 20 | #'ts2=rexp(1000) 21 | #'despiking(ts2) 22 | #' 23 | despiking = function(ts,thresholds=c(NA,NA),mad_factor=10,threshold_skewness=2,threshold_kurtosis=8) { 24 | #despiking based on predefined limits 25 | if (sum(is.na(thresholds))==0) { 26 | pass = (ts>thresholds[1] & tsthresholds[1]) 33 | ts[!pass] = NA 34 | } 35 | #despiking based on median deviation test 36 | med=median(ts,na.rm=TRUE) 37 | mad=median(abs(ts-med),na.rm=TRUE) 38 | pass=(abs(ts-med) <= mad_factor*mad) #pass criterion 39 | ts[!pass] = NA 40 | #despiking based on skewness and kurtosis for entire block 41 | tryCatch({ 42 | seriesLDT=pracma::detrend(ts,tt="linear") #linear detrending to eliminate trends (departures from stationarity) -> would influnece higher moments 43 | skewness=mean(seriesLDT^3,na.rm=T)/sd(seriesLDT,na.rm=T)^3 44 | kurtosis=mean(seriesLDT^4,na.rm=T)/sd(seriesLDT,na.rm=T)^4 45 | pass=(abs(skewness)0.1 & cr>threshold_cr) { 217 | wd=median(calc_windDirection(u,v)) 218 | flag=ifelse(wd>=dir_blocked[1] & wd<=dir_blocked[2],2,0) 219 | } else { 220 | flag=0 221 | } 222 | } else { 223 | flag=2 224 | } 225 | return(flag) 226 | } 227 | 228 | #' Integral Turbulence Characteristics Flag 229 | #' 230 | #'@description Integral Turbulence Characteristics Flag: Tests the consistency with Monin-Obukhov similarity theory using the scaling functions from Panofsky and Dutton, 1984. 231 | #'@param w_sd standard deviation of vertical velocity 232 | #'@param ustar friction velocity 233 | #'@param zeta stability parameter \code{zeta = z/L} 234 | #'@param thresholds_most vector containing 2 elements to distinguish between flag=0 and flag=1, as well as flag=1 and flag=2, default: \code{c(0.3,0.8)} 235 | #' 236 | #'@return integral turbulence characteristics flags (0: in full agreement with the criterion ... 2: does not fulfill the criterion) 237 | #'@export 238 | #' 239 | #'@examples 240 | #'itc_flag=flag_most(0.2,0.4,-0.3) 241 | #' 242 | flag_most = function(w_sd,ustar,zeta,thresholds_most=c(0.3,0.8)) { 243 | if (length(thresholds_most)!=2) { 244 | stop("thresholds_most has to be a vector of length 2.") 245 | } 246 | parameterized=1.3*(1+2*abs(zeta))^(1/3) #w_sd/ustar parametrized according to scaling function based on zeta 247 | itc=abs((w_sd/ustar-parameterized)/parameterized) 248 | flag=ifelse(itc